From 7806ff93441318ad1f724f0b586383b61c4af859 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Tue, 5 May 2015 12:30:14 +0000 Subject: Fixed a bug when creating natural execution flows. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@526 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 14 ++++ src/analysis/disass/disassembler.c | 30 ++++---- src/analysis/disass/links.c | 146 +------------------------------------ src/analysis/disass/macro.c | 9 ++- src/arch/link.c | 10 ++- 5 files changed, 46 insertions(+), 163 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7a1bd49..e18bb91 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +15-05-05 Cyrille Bagard + + * src/analysis/disass/disassembler.c: + Reorder the disassembling steps for more sanity. + + * src/analysis/disass/links.c: + Fix a bug when creating natural execution flows. + + * src/analysis/disass/macro.c: + Fix a bug when following the execution jumps to create basic blocks. + + * src/arch/link.c: + Improve the content of debug messages. + 15-05-04 Cyrille Bagard * src/gtkext/graph/edge.c: diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c index 7b6c63e..a779dd1 100644 --- a/src/analysis/disass/disassembler.c +++ b/src/analysis/disass/disassembler.c @@ -342,23 +342,9 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta - /* Troisième étape */ - - id = gtk_extended_status_bar_push(statusbar, _("Detecting loops..."), true); - - detect_loops_in_code(proc, routines, routines_count, statusbar, id); - - gtk_extended_status_bar_remove(statusbar, id); - /// - // plugins ////////////////////////// - process_disassembly_event(PGA_DISASSEMBLY_LOOPS, disass->binary); - - - - - /* Quatrième étape */ + /* Troisième étape */ id = gtk_extended_status_bar_push(statusbar, _("Establishing links..."), true); @@ -388,6 +374,20 @@ G_BIN_FORMAT(g_loaded_binary_get_format(disass->binary) + /* Quatrième étape */ + + id = gtk_extended_status_bar_push(statusbar, _("Detecting loops..."), true); + + detect_loops_in_code(proc, routines, routines_count, statusbar, id); + + gtk_extended_status_bar_remove(statusbar, id); + + /// + + // plugins ////////////////////////// + process_disassembly_event(PGA_DISASSEMBLY_LOOPS, disass->binary); + + diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c index 06b6b03..545afb1 100644 --- a/src/analysis/disass/links.c +++ b/src/analysis/disass/links.c @@ -176,7 +176,7 @@ static void establish_natural_link(GArchInstruction *instr, GArchInstruction *pr if (types[i] == ILT_LOOP) break; } - if (i < count) return; + if (count > 0 && i < count) return; /** * On vérifie que le lien n'existe pas déjà avant d'en créer un... @@ -233,147 +233,3 @@ void establish_links_between_instructions(GArchInstruction *list, GBinFormat *fo } } - - - - - - - - - - - - -#if 0 - -/****************************************************************************** -* * -* Paramètres : list = ensemble d'instructions à relier. * -* routines = prototypes existants à insérer. * -* count = quantité de ces prototypes. * -* statusbar = barre de statut avec progression à mettre à jour.* -* id = identifiant du message affiché à l'utilisateur. * -* * -* Description : Etablit les liens entres les différentes lignes de code. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void establish_links_between_lines(GArchInstruction *list, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id) -{ - size_t i; /* Boucle de parcours */ - vmpa_t start; /* Adresse de départ */ - vmpa_t end; /* Adresse de fin */ - GArchInstruction *iter; /* Boucle de parcours */ - vmpa_t addr; /* Adresse référencée */ - InstructionLinkType type; /* Type de référence */ - GArchInstruction *target; /* Ligne visée par la référence*/ - GArchInstruction *prev; /* Instruction précédente */ - - for (i = 0; i < count; i++) - { - start = g_binary_routine_get_address(routines[i]); - end = start + g_binary_routine_get_size(routines[i]); - - /* Définition de toutes les destinations */ - for (iter = g_arch_instruction_find_by_address(list, start, true); - iter != NULL; - iter = g_arch_instruction_get_next_iter(list, iter, end)) - { - type = g_arch_instruction_get_link(iter, &addr); - - switch (type) - { - case ILT_NONE: - break; - - case ILT_JUMP: - - target = g_arch_instruction_find_by_address(list, addr, true); - - if (target != NULL) - g_arch_instruction_link_with(iter, target, type); - - break; - - case ILT_JUMP_IF_FALSE: - break; - - case ILT_JUMP_IF_TRUE: - - target = g_arch_instruction_find_by_address(list, addr, true); - - if (target != NULL) - { - g_arch_instruction_link_with(iter, target, type); - - target = g_arch_instruction_get_next_iter(list, iter, end); - if (target != NULL) - g_arch_instruction_link_with(iter, target, ILT_JUMP_IF_FALSE); - - } - - break; - - case ILT_CALL: - - target = g_arch_instruction_find_by_address(list, addr, true); - - if (target != NULL) - g_arch_instruction_link_with(iter, target, type); - - break; - - default: - /** - * Note pour GCC : à ce stade du désassemblage, ILT_CASE_JUMP et - * ILT_CATCH_EXCEPTION ne peuvent être présentes, car ne provenant - * que de greffons. Pour ILT_EXEC_FLOW, sa seule insertion est ici, plus bas. - */ - break; - - } - - } - - /* Rattachement de deux blocs selon le flux normal */ - - iter = g_arch_instruction_find_by_address(list, start, true); - - if (iter == NULL) - printf("no match for 0x%08llx\n", start); - - if (iter != NULL) - - for (iter = g_arch_instruction_get_next_iter(list, iter, end); - iter != NULL; - iter = g_arch_instruction_get_next_iter(list, iter, end)) - { - if (!g_arch_instruction_has_sources(iter)) - continue; - - prev = g_arch_instruction_get_prev_iter(list, iter); - - if (g_arch_instruction_is_return(prev)) - continue; - - if (!g_arch_instruction_has_destinations(prev)) - g_arch_instruction_link_with(prev, iter, ILT_EXEC_FLOW); - - } - - gtk_extended_status_bar_update_activity(statusbar, id, (i + 1) * 1.0 / count); - - } - -} - - - - -#endif - diff --git a/src/analysis/disass/macro.c b/src/analysis/disass/macro.c index 9527457..b478c74 100644 --- a/src/analysis/disass/macro.c +++ b/src/analysis/disass/macro.c @@ -1276,8 +1276,13 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove } DELAYED_BLOCK_ADDING(result, result_cached, block); - range = g_arch_instruction_get_range(iter); - compute_mrange_end_addr(range, &next_addr); + /** + * La prochaine adresse d'analyse est celle visée par l'instruction ! + * Pour les sauts naturels, ça ne change rien ; ce n'est pas le cas + * pour les sauts explicites. + */ + range = g_arch_instruction_get_range(dests[i]); + copy_vmpa(&next_addr, get_mrange_addr(range)); first = NULL; diff --git a/src/arch/link.c b/src/arch/link.c index 02cda22..3b74e5c 100644 --- a/src/arch/link.c +++ b/src/arch/link.c @@ -121,7 +121,7 @@ void handle_branch_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcC target = g_arch_processor_find_instr_by_address(proc, &addr); - printf(" @ 0x%08x BRANCH to 0x%08x -->> %p\n", + printf(" @ 0x%08x BRANCH true to 0x%08x -->> %p\n", (unsigned int)instr->range.addr.virtual, (unsigned int)virt, target); if (target != NULL) @@ -132,6 +132,14 @@ void handle_branch_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcC target = g_arch_instruction_get_next_iter(list, instr, ~0); + + if (target != NULL) + printf(" @ 0x%08x BRANCH false to 0x%08x -->> %p\n", + (unsigned int)instr->range.addr.virtual, + (unsigned int)g_arch_instruction_get_range(target)->addr.virtual, + target); + + if (target != NULL) g_arch_instruction_link_with(instr, target, ILT_JUMP_IF_FALSE); -- cgit v0.11.2-87-g4458