From 48726043e2f07874e7a09a866c4cc537a65a683c Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Wed, 14 Oct 2015 00:10:11 +0000 Subject: Forced the full definition of locations to fix the search of symbols. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@594 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 24 ++++++ src/analysis/disass/links.c | 150 +++++++++++++++++++------------------- src/arch/arm/v7/fetch.c | 13 +++- src/arch/arm/v7/opdefs/bl_A8825.d | 2 +- src/arch/arm/v7/post.c | 30 +++++--- src/arch/instruction.c | 10 ++- src/format/format.c | 24 +++++- src/format/symbol.c | 15 +--- 8 files changed, 157 insertions(+), 111 deletions(-) diff --git a/ChangeLog b/ChangeLog index f594cba..7eabc65 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,29 @@ 15-10-14 Cyrille Bagard + * src/analysis/disass/links.c: + Reorganize the code. + + * src/arch/arm/v7/fetch.c: + Fix a bug about switching between ARM and Thumb modes. Force the full + definition of locations. + + * src/arch/arm/v7/opdefs/bl_A8825.d: + Typo. + + * src/arch/arm/v7/post.c: + Force the full definition of locations. + + * src/arch/instruction.c: + Typo. + + * src/format/format.c: + Force the full definition of locations to fix the search of symbols. + + * src/format/symbol.c: + Fix the comparison of symbols. + +15-10-14 Cyrille Bagard + * src/analysis/disass/fetch.c: Update code. diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c index 43b7e6f..8d826c5 100644 --- a/src/analysis/disass/links.c +++ b/src/analysis/disass/links.c @@ -30,13 +30,86 @@ +/* Rétablit un lien naturel coupé par un autre lien. */ +static void establish_natural_link(GArchInstruction *, GArchInstruction *); + /* Complète un désassemblage accompli pour une instruction. */ static void convert_immediate_into_target(GArchInstruction *, size_t, GBinFormat *); -/* Rétablit un lien naturel coupé par un autre lien. */ -static void establish_natural_link(GArchInstruction *, GArchInstruction *); +/****************************************************************************** +* * +* Paramètres : instr = instruction désassemblée à traiter. * +* prev = instruction précédente. * +* * +* Description : Rétablit un lien naturel coupé par un autre lien. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev) +{ + GArchInstruction **others; /* Instructions diverses liées */ + InstructionLinkType *types; /* Types de lien existants */ + size_t count; /* Nbre de sources affichées */ + size_t i; /* Boucle de parcours */ + + /** + * Si rien ne vient séparer les deux instructions, + * on ne peut pas créer de lien plus naturel que l'existant. + */ + + if (!g_arch_instruction_has_sources(instr)) + return; + + /** + * Si on se trouve à une extrémité, on ne se lie pas + * avec le voisin. + */ + + if (g_arch_instruction_get_flags(prev) & AIF_RETURN_POINT) + return; + + if (g_arch_instruction_get_flags(instr) & AIF_ROUTINE_START) + return; + + /** + * On s'assure que le lien naturel est valide. + */ + + count = g_arch_instruction_get_destinations(prev, &others, &types, NULL); + + for (i = 0; i < count; i++) + { + if (types[i] == ILT_EXEC_FLOW) break; + if (types[i] == ILT_JUMP) break; + if (types[i] == ILT_CASE_JUMP) break; + if (types[i] == ILT_LOOP) break; + } + + if (count > 0 && i < count) return; + + /** + * On vérifie que le lien n'existe pas déjà avant d'en créer un... + */ + + count = g_arch_instruction_get_sources(instr, &others, &types); + + for (i = 0; i < count; i++) + { + if (others[i] == prev && types[i] == ILT_JUMP_IF_TRUE) break; + if (others[i] == prev && types[i] == ILT_JUMP_IF_FALSE) break; + } + + if (i == count) + g_arch_instruction_link_with(prev, instr, ILT_EXEC_FLOW); + +} + /****************************************************************************** * * @@ -125,79 +198,6 @@ static void establish_links_for_instruction(GArchInstruction *instr, GArchInstru /****************************************************************************** * * -* Paramètres : instr = instruction désassemblée à traiter. * -* prev = instruction précédente. * -* * -* Description : Rétablit un lien naturel coupé par un autre lien. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev) -{ - GArchInstruction **others; /* Instructions diverses liées */ - InstructionLinkType *types; /* Types de lien existants */ - size_t count; /* Nbre de sources affichées */ - size_t i; /* Boucle de parcours */ - - /** - * Si rien ne vient séparer les deux instructions, - * on ne peut pas créer de lien plus naturel que l'existant. - */ - - if (!g_arch_instruction_has_sources(instr)) - return; - - /** - * Si on se trouve à une extrémité, on ne se lie pas - * avec le voisin. - */ - - if (g_arch_instruction_get_flags(prev) & AIF_RETURN_POINT) - return; - - if (g_arch_instruction_get_flags(instr) & AIF_ROUTINE_START) - return; - - /** - * On s'assure que le lien naturel est valide. - */ - - count = g_arch_instruction_get_destinations(prev, &others, &types, NULL); - - for (i = 0; i < count; i++) - { - if (types[i] == ILT_EXEC_FLOW) break; - if (types[i] == ILT_JUMP) break; - if (types[i] == ILT_CASE_JUMP) break; - if (types[i] == ILT_LOOP) break; - } - - if (count > 0 && i < count) return; - - /** - * On vérifie que le lien n'existe pas déjà avant d'en créer un... - */ - - count = g_arch_instruction_get_sources(instr, &others, &types); - - for (i = 0; i < count; i++) - { - if (others[i] == prev && types[i] == ILT_JUMP_IF_TRUE) break; - if (others[i] == prev && types[i] == ILT_JUMP_IF_FALSE) break; - } - - if (i == count) - g_arch_instruction_link_with(prev, instr, ILT_EXEC_FLOW); - -} - - -/****************************************************************************** -* * * Paramètres : list = ensemble d'instructions à relier. * * format = accès aux données du binaire d'origine. * * statusbar = barre de statut avec progression à mettre à jour.* diff --git a/src/arch/arm/v7/fetch.c b/src/arch/arm/v7/fetch.c index 73cec6d..da83d15 100644 --- a/src/arch/arm/v7/fetch.c +++ b/src/arch/arm/v7/fetch.c @@ -353,7 +353,7 @@ void help_fetching_with_instruction_cb_n_z(GArchInstruction *instr, GArchProcess * proc = représentation de l'architecture utilisée. * * context = contexte associé à la phase de désassemblage. * * format = acès aux données du binaire d'origine. * -* iset = type de jeu d'instructions courant à inverser. * +* iset = type de jeu d'instructions courant. * * * * Description : Complète un désassemblage accompli pour une instruction. * * * @@ -429,7 +429,13 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst else val_offset = phys_pc - offset; - init_vmpa(&sym_addr, val_offset, VMPA_NO_VIRTUAL); + if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), val_offset, &sym_addr)) + { + assert(0); + return; + } + + //init_vmpa(&sym_addr, val_offset, VMPA_NO_VIRTUAL); init_mrange(&sym_range, &sym_addr, 4); @@ -502,6 +508,7 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst /// FIXME ?! if (target < 0x8000) return; + if (target > 0x6966c) return; new = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, target); @@ -517,7 +524,7 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst //target = pc + offset; //g_armv7_context_define_encoding(context, target, AV7IS_THUMB); - g_armv7_context_push_drop_point_ext(context, target, AV7IS_THUMB); + g_armv7_context_push_drop_point_ext(context, target, iset); //exit(0); diff --git a/src/arch/arm/v7/opdefs/bl_A8825.d b/src/arch/arm/v7/opdefs/bl_A8825.d index a9b395a..c2eb7bd 100644 --- a/src/arch/arm/v7/opdefs/bl_A8825.d +++ b/src/arch/arm/v7/opdefs/bl_A8825.d @@ -113,7 +113,7 @@ @encoding(A2) { - @word cond(4) 1 0 1 H(1) imm24(24) + @word 1 1 1 1 1 0 1 H(1) imm24(24) @syntax "blx" diff --git a/src/arch/arm/v7/post.c b/src/arch/arm/v7/post.c index e95bd66..e066bb0 100644 --- a/src/arch/arm/v7/post.c +++ b/src/arch/arm/v7/post.c @@ -24,9 +24,6 @@ #include "post.h" -#include - - #include "../../target.h" @@ -60,13 +57,13 @@ void post_process_branch_instructions(GArchInstruction *instr, GArchProcessor *p op = g_arch_instruction_get_operand(instr, 0); - if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr)) + if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr) + && g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), addr, &target)) { new = g_target_operand_new(MDS_32_BITS_UNSIGNED, addr); if (!g_target_operand_resolve(G_TARGET_OPERAND(new), format)) { - init_vmpa(&target, VMPA_NO_PHYSICAL, addr); init_mrange(&trange, &target, 0); vmpa2_virt_to_string(&target, MDS_UNDEFINED, loc, NULL); @@ -124,13 +121,23 @@ void post_process_branch_and_link_instructions(GArchInstruction *instr, GArchPro op = g_arch_instruction_get_operand(instr, 0); - if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr)) + if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr) + && g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), addr, &target)) { + + + /// FIXME (DUR) ?! + if (addr < 0x8000) return; + + if (addr > 0x6966c) return; + + + + new = g_target_operand_new(MDS_32_BITS_UNSIGNED, addr); if (!g_target_operand_resolve(G_TARGET_OPERAND(new), format)) { - init_vmpa(&target, VMPA_NO_PHYSICAL, addr); init_mrange(&trange, &target, 0); vmpa2_virt_to_string(&target, MDS_UNDEFINED, loc, NULL); @@ -188,13 +195,13 @@ void post_process_comp_and_branch_instructions(GArchInstruction *instr, GArchPro op = g_arch_instruction_get_operand(instr, 1); - if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr)) + if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr) + && g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), addr, &target)) { new = g_target_operand_new(MDS_32_BITS_UNSIGNED, addr); if (!g_target_operand_resolve(G_TARGET_OPERAND(new), format)) { - init_vmpa(&target, VMPA_NO_PHYSICAL, addr); init_mrange(&trange, &target, 0); vmpa2_virt_to_string(&target, MDS_UNDEFINED, loc, NULL); @@ -256,7 +263,8 @@ void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc if (!G_IS_IMM_OPERAND(op)) return; - if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr)) + if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr) + && g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), addr, &target)) { new = g_target_operand_new(MDS_32_BITS_UNSIGNED, addr); @@ -277,7 +285,6 @@ void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc } while (0); - init_vmpa(&target, VMPA_NO_PHYSICAL, addr); init_mrange(&trange, &target, 0); vmpa2_virt_to_string(&target, MDS_UNDEFINED, loc, NULL); @@ -317,6 +324,5 @@ void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc g_arch_instruction_replace_operand(instr, new, op); } - else assert(0); } diff --git a/src/arch/instruction.c b/src/arch/instruction.c index d9d7693..c3c32dc 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -663,7 +663,7 @@ bool g_arch_instruction_has_sources(const GArchInstruction *instr) /****************************************************************************** * * * Paramètres : instr = instruction dont les informations sont à consulter. * -* dests = liste des instructions de destination. [OUT] * +* srcs = liste des instructions d'origine. [OUT] * * types = liste des types de liens présents. [OUT] * * * * Description : Fournit les origines d'une instruction donnée. * @@ -674,9 +674,10 @@ bool g_arch_instruction_has_sources(const GArchInstruction *instr) * * ******************************************************************************/ -size_t g_arch_instruction_get_sources(const GArchInstruction *instr, GArchInstruction ***dests, InstructionLinkType **types) +size_t g_arch_instruction_get_sources(const GArchInstruction *instr, GArchInstruction ***srcs, InstructionLinkType **types) { - *dests = instr->from; + if (srcs != NULL) + *srcs = instr->from; if (types != NULL) *types = instr->from_types; @@ -724,7 +725,8 @@ bool g_arch_instruction_has_destinations(const GArchInstruction *instr) size_t g_arch_instruction_get_destinations(const GArchInstruction *instr, GArchInstruction ***dests, InstructionLinkType **types, link_extra_info **info) { - *dests = instr->to; + if (dests != NULL) + *dests = instr->to; if (types != NULL) *types = instr->to_types; diff --git a/src/format/format.c b/src/format/format.c index 9f03924..9c42508 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -221,7 +221,7 @@ void g_binary_format_setup_disassembling_context(const GBinFormat *format, GProc * * * Description : Ajoute un symbole à la collection du format binaire. * * * -* Retour : - * +* Retour : true si le symbole était bien localisé et a été inséré. * * * * Remarques : - * * * @@ -229,6 +229,26 @@ void g_binary_format_setup_disassembling_context(const GBinFormat *format, GProc void _g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol, bool sort) { + const mrange_t *range; /* Couverture du symbole */ + const vmpa2t *addr; /* Emplacement du symbole */ + + /** + * Lorsque les fonctions de recherche type g_binary_format_find_symbol_at() + * sont appelées avec une localisation, cette dernière peut reposer soit sur + * une position physique soit une adresse virtuelle uniquement. + * + * Pour que les comparaisons de positions puissent se réaliser, il faut donc + * pouvoir satisfaire les deux aspects : physiques et virtuels. + * + * On corrige donc le tir si besoin est ici. + */ + +#ifndef NDEBUG + range = g_binary_symbol_get_range(symbol); + addr = get_mrange_addr(range); + + assert(get_phy_addr(addr) != VMPA_NO_PHYSICAL && get_virt_addr(addr) != VMPA_NO_VIRTUAL); +#endif g_rw_lock_writer_lock(&format->syms_lock); @@ -628,7 +648,7 @@ bool g_binary_format_find_symbol_at(const GBinFormat *format, const vmpa2t *addr range = g_binary_symbol_get_range(*sym); - return cmp_vmpa_by_virt(addr, get_mrange_addr(range)); + return cmp_vmpa(addr, get_mrange_addr(range)); } diff --git a/src/format/symbol.c b/src/format/symbol.c index 70a1d24..2346c63 100644 --- a/src/format/symbol.c +++ b/src/format/symbol.c @@ -202,8 +202,6 @@ int g_binary_symbol_cmp(const GBinSymbol **a, const GBinSymbol **b) int result; /* Bilan à retourner */ const mrange_t *ra; /* Emplacement du symbole A */ const mrange_t *rb; /* Emplacement du symbole B */ - const vmpa2t *aa; /* Adresse du symbole A */ - const vmpa2t *ab; /* Adresse du symbole B */ ra = g_binary_symbol_get_range(*a); rb = g_binary_symbol_get_range(*b); @@ -218,18 +216,7 @@ int g_binary_symbol_cmp(const GBinSymbol **a, const GBinSymbol **b) result = -1; else - { - aa = get_mrange_addr(ra); - ab = get_mrange_addr(rb); - - result = cmp_vmpa_by_virt(aa, ab); - - //result = aa->virtual < ab->virtual ? -1 : (aa->virtual > ab->virtual ? 1 : 0); - ///result = cmp_mrange(ra, rb); - - //printf(" ?? 0x%08lx vs 0x%08lx -> %d\n", aa->virtual, ab->virtual, result); - - } + result = cmp_mrange(ra, rb); return result; -- cgit v0.11.2-87-g4458