From 46e46c2894ea92502734c7bbd1cbcc6cb2e46d17 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 4 Apr 2015 13:31:33 +0000 Subject: Updated the disassembling process order and defined ranks for basic routines. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@501 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 26 +++ src/analysis/block-int.h | 2 +- src/analysis/block.c | 2 +- src/analysis/block.h | 4 +- src/analysis/blocks/flow.c | 42 +--- src/analysis/blocks/flow.h | 6 - src/analysis/blocks/virtual.c | 7 +- src/analysis/disass/disassembler.c | 46 +++-- src/analysis/disass/limit.c | 12 +- src/analysis/disass/limit.h | 3 +- src/analysis/disass/rank.c | 414 ++++++++++--------------------------- src/analysis/disass/rank.h | 3 - 12 files changed, 180 insertions(+), 387 deletions(-) diff --git a/ChangeLog b/ChangeLog index fad37ce..0845512 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +15-04-04 Cyrille Bagard + + * src/analysis/block.c: + * src/analysis/block.h: + * src/analysis/block-int.h: + Fix the prototypes of functions looking for a block of a given address. + + * src/analysis/blocks/flow.c: + * src/analysis/blocks/flow.h: + Clean the code relative to ranks. + + * src/analysis/blocks/virtual.c: + Fix the prototypes of functions looking for a block of a given address. + Fix a bug when looking for the parent of such a block. + + * src/analysis/disass/disassembler.c: + Update the disassembling process order and define ranks for basic routines. + + * src/analysis/disass/limit.c: + * src/analysis/disass/limit.h: + Set the AIF_ROUTINE_START flag for the first instruction of all routines. + + * src/analysis/disass/rank.c: + * src/analysis/disass/rank.h: + Define ranks for basic routines. + 15-04-03 Cyrille Bagard * src/glibext/gcodebuffer.c: diff --git a/src/analysis/block-int.h b/src/analysis/block-int.h index 26319f8..18b1ce4 100644 --- a/src/analysis/block-int.h +++ b/src/analysis/block-int.h @@ -30,7 +30,7 @@ /* Recherche le bloc contenant une adresse donnée. */ -typedef GInstrBlock * (* find_by_addr_fc) (const GInstrBlock *, vmpa_t, bool); +typedef GInstrBlock * (* find_by_addr_fc) (const GInstrBlock *, const vmpa2t *, bool); /* Parcourt tous les blocs d'instructions dans un ordre donné. */ typedef bool (* visit_all_blocks_fc) (GInstrBlock *, instr_block_visitor_cb, void *); diff --git a/src/analysis/block.c b/src/analysis/block.c index fac3559..23fbfc5 100644 --- a/src/analysis/block.c +++ b/src/analysis/block.c @@ -151,7 +151,7 @@ static void g_instr_block_finalize(GInstrBlock *block) * * ******************************************************************************/ -GInstrBlock *g_instr_block_find_by_addr(const GInstrBlock *block, vmpa_t addr, bool final) +GInstrBlock *g_instr_block_find_by_addr(const GInstrBlock *block, const vmpa2t *addr, bool final) { return block->find_by_addr(block, addr, final); diff --git a/src/analysis/block.h b/src/analysis/block.h index 73ac8e7..bf35a7f 100644 --- a/src/analysis/block.h +++ b/src/analysis/block.h @@ -30,7 +30,7 @@ #include -#include "../arch/archbase.h" +#include "../arch/vmpa.h" @@ -66,7 +66,7 @@ typedef bool (* instr_block_visitor_cb) (GInstrBlock *, BlockVisitOrder, void *) GType g_instr_block_get_type(void); /* Recherche le bloc contenant une adresse donnée. */ -GInstrBlock *g_instr_block_find_by_addr(const GInstrBlock *, vmpa_t, bool); +GInstrBlock *g_instr_block_find_by_addr(const GInstrBlock *, const vmpa2t *, bool); /* Parcourt tous les blocs d'instructions dans un ordre donné. */ bool g_instr_block_visit(GInstrBlock *, instr_block_visitor_cb, void *); diff --git a/src/analysis/blocks/flow.c b/src/analysis/blocks/flow.c index 7777623..305dad0 100644 --- a/src/analysis/blocks/flow.c +++ b/src/analysis/blocks/flow.c @@ -266,47 +266,7 @@ unsigned int g_flow_block_get_rank(const GFlowBlock *block) void g_flow_block_set_rank(GFlowBlock *block, unsigned int rank) { - block->rank = MAX(block->rank, rank); - g_flow_block_set_next_rank(block, block->rank + 1); - -} - - -/****************************************************************************** -* * -* Paramètres : block = bloc d'instruction à consulter. * -* * -* Description : Fournit le rang minimal du bloc suivant pour l'exécution. * -* * -* Retour : Indice supérieur à zéro. * -* * -* Remarques : - * -* * -******************************************************************************/ - -unsigned int g_flow_block_get_next_rank(const GFlowBlock *block) -{ - return block->next_rank; - -} - - -/****************************************************************************** -* * -* Paramètres : block = bloc d'instruction à consulter. * -* rank = Indice supérieur à zéro à prendre en compte. * -* * -* Description : Définit le rang minimal du bloc suivant pour l'exécution. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_flow_block_set_next_rank(GFlowBlock *block, unsigned int rank) -{ - block->next_rank = MAX(block->next_rank, rank); + block->rank = rank; } diff --git a/src/analysis/blocks/flow.h b/src/analysis/blocks/flow.h index cc32834..cf8797b 100644 --- a/src/analysis/blocks/flow.h +++ b/src/analysis/blocks/flow.h @@ -76,12 +76,6 @@ unsigned int g_flow_block_get_rank(const GFlowBlock *); /* Définit le rang du bloc dans le flot d'exécution. */ void g_flow_block_set_rank(GFlowBlock *, unsigned int); -/* Fournit le rang minimal du bloc suivant pour l'exécution. */ -unsigned int g_flow_block_get_next_rank(const GFlowBlock *); - -/* Définit le rang minimal du bloc suivant pour l'exécution. */ -void g_flow_block_set_next_rank(GFlowBlock *, unsigned int); - /* Fournit la liste d'appartenance des instructions du bloc. */ GArchInstruction *g_flow_block_get_all_instructions_list(const GFlowBlock *); diff --git a/src/analysis/blocks/virtual.c b/src/analysis/blocks/virtual.c index 946445c..a3e1695 100644 --- a/src/analysis/blocks/virtual.c +++ b/src/analysis/blocks/virtual.c @@ -27,6 +27,7 @@ #include +#include "flow.h" #include "../block-int.h" @@ -71,7 +72,7 @@ static void g_virtual_block_dispose(GVirtualBlock *); static void g_virtual_block_finalize(GVirtualBlock *); /* Recherche le bloc contenant une adresse donnée. */ -static GInstrBlock *g_virtual_block_find_by_addr(const GVirtualBlock *, vmpa_t, bool); +static GInstrBlock *g_virtual_block_find_by_addr(const GVirtualBlock *, const vmpa2t *, bool); /* Parcourt le bloc d'instructions dans un ordre donné. */ static bool g_virtual_block_visit(GVirtualBlock *, instr_block_visitor_cb, void *); @@ -225,7 +226,7 @@ GInstrBlock *g_virtual_block_new(void) * * ******************************************************************************/ -static GInstrBlock *g_virtual_block_find_by_addr(const GVirtualBlock *block, vmpa_t addr, bool final) +static GInstrBlock *g_virtual_block_find_by_addr(const GVirtualBlock *block, const vmpa2t *addr, bool final) { GInstrBlock *result; /* Resultat à retourner */ size_t i; /* Boucle de parcours */ @@ -240,7 +241,7 @@ static GInstrBlock *g_virtual_block_find_by_addr(const GVirtualBlock *block, vmp if (ret != NULL) { if (final) result = ret; - else result = block->children[i]; + else result = (G_IS_FLOW_BLOCK(ret) ? G_INSTR_BLOCK(block) : ret); } } diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c index fcc41cb..50c71da 100644 --- a/src/analysis/disass/disassembler.c +++ b/src/analysis/disass/disassembler.c @@ -304,28 +304,24 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta */ + /* Seconde étape */ + routines = g_binary_format_get_routines(G_BIN_FORMAT(disass->format), &routines_count); - /* Seconde étape */ - id = gtk_extended_status_bar_push(statusbar, _("Establishing links..."), true); - /** - * - * Lequel choisir ??? + //id = gtk_extended_status_bar_push(statusbar, _("Finding remaining limits..."), true); -G_BIN_FORMAT(disass->format) -G_BIN_FORMAT(g_loaded_binary_get_format(disass->binary) + //qsort(routines, routines_count, sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_rcompare); - */ + limit_all_routines(disass->format, proc, routines, routines_count, statusbar, id); + //gtk_extended_status_bar_remove(statusbar, id); - establish_links_between_instructions(*disass->instrs, G_BIN_FORMAT(disass->format), statusbar, id); + //run_plugins_on_binary(disass->binary, PGA_BINARY_BOUNDED, true); - gtk_extended_status_bar_remove(statusbar, id); - //run_plugins_on_binary(disass->binary, PGA_BINARY_LINKED, true); @@ -334,20 +330,24 @@ G_BIN_FORMAT(g_loaded_binary_get_format(disass->binary) /* Troisième étape */ - routines = g_binary_format_get_routines(G_BIN_FORMAT(disass->format), &routines_count); + id = gtk_extended_status_bar_push(statusbar, _("Establishing links..."), true); + /** + * + * Lequel choisir ??? +G_BIN_FORMAT(disass->format) +G_BIN_FORMAT(g_loaded_binary_get_format(disass->binary) - //id = gtk_extended_status_bar_push(statusbar, _("Finding remaining limits..."), true); + */ - //qsort(routines, routines_count, sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_rcompare); - limit_all_routines(disass->format, routines, routines_count, statusbar, id); + establish_links_between_instructions(*disass->instrs, G_BIN_FORMAT(disass->format), statusbar, id); - //gtk_extended_status_bar_remove(statusbar, id); + gtk_extended_status_bar_remove(statusbar, id); - //run_plugins_on_binary(disass->binary, PGA_BINARY_BOUNDED, true); + //run_plugins_on_binary(disass->binary, PGA_BINARY_LINKED, true); @@ -372,6 +372,18 @@ G_BIN_FORMAT(g_loaded_binary_get_format(disass->binary) + /* Sixième étape */ + + id = gtk_extended_status_bar_push(statusbar, _("Ranking each instructions block..."), true); + + //qsort(routines, routines_count, sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_rcompare); + + rank_routines_blocks(routines, routines_count, statusbar, id); + + gtk_extended_status_bar_remove(statusbar, id); + + //run_plugins_on_binary(disass->binary, PGA_BINARY_GROUPED, true); + diff --git a/src/analysis/disass/limit.c b/src/analysis/disass/limit.c index 3810978..6705e1d 100644 --- a/src/analysis/disass/limit.c +++ b/src/analysis/disass/limit.c @@ -64,7 +64,8 @@ static const mrange_t *find_x_range_for_addr(const mrange_t *ranges, size_t coun /****************************************************************************** * * -* Paramètres : list = ensemble d'instructions désassemblées. * +* Paramètres : format = format du binaire concerné par la procédure. * +* proc = ensemble d'instructions désassemblées. * * routines = prototypes existants à insérer. * * count = quantité de ces prototypes. * * statusbar = barre de statut avec progression à mettre à jour.* @@ -78,13 +79,14 @@ static const mrange_t *find_x_range_for_addr(const mrange_t *ranges, size_t coun * * ******************************************************************************/ -void limit_all_routines(GExeFormat *format, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id) +void limit_all_routines(GExeFormat *format, const GArchProcessor *proc, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id) { mrange_t *exe_ranges; /* Liste de zones exécutables */ size_t exe_count; /* Nombre de ces zones */ size_t i; /* Boucle de parcours */ const mrange_t *range; /* Emplacement courant */ vmpa2t addr; /* Adresse à conserver */ + GArchInstruction *start; /* Première instruction */ phys_t diff; /* Taille définie par déduction*/ mrange_t new; /* Nouvel emplacement taillé */ @@ -99,6 +101,12 @@ void limit_all_routines(GExeFormat *format, GBinRoutine **routines, size_t count copy_vmpa(&addr, get_mrange_addr(range)); + /* Marquage de la première instruction */ + + start = g_arch_processor_find_instr_by_address(proc, &addr); + + g_arch_instruction_set_flag(start, AIF_ROUTINE_START); + /* Si on peut se raccrocher à la routine suivante... */ if ((i + 1) < count) { diff --git a/src/analysis/disass/limit.h b/src/analysis/disass/limit.h index 92c7df4..eeffc71 100644 --- a/src/analysis/disass/limit.h +++ b/src/analysis/disass/limit.h @@ -26,13 +26,14 @@ #include "../routine.h" +#include "../../arch/processor.h" #include "../../format/executable.h" #include "../../gtkext/gtkextstatusbar.h" /* S'assure que toutes les routines ont une taille définie. */ -void limit_all_routines(GExeFormat *, GBinRoutine **, size_t, GtkExtStatusBar *, bstatus_id_t); +void limit_all_routines(GExeFormat *, const GArchProcessor *, GBinRoutine **, size_t, GtkExtStatusBar *, bstatus_id_t); diff --git a/src/analysis/disass/rank.c b/src/analysis/disass/rank.c index 9dfdb42..94494d5 100644 --- a/src/analysis/disass/rank.c +++ b/src/analysis/disass/rank.c @@ -24,365 +24,153 @@ #include "rank.h" +#include +#include + + #include "../blocks/flow.h" #include "../blocks/virtual.h" -#if 0 -/* Marque la profondeur d'un bloc d'instructions. */ -static void rank_flow_block_content(GFlowBlock *, const GInstrBlock *); + +/* Classe le contenu d'un bloc d'instructions exécutées. */ +static bool rank_flow_block(GFlowBlock *, BlockVisitOrder, const GInstrBlock *); /****************************************************************************** * * -* Paramètres : block = bloc d'instructions démarrant la visite. * +* Paramètres : block = bloc d'instructions concerné par la visite. * +* order = indication quant au sens de visite. * * list = ensemble des blocs basiques à parcourir. * * * -* Description : Marque la profondeur d'un bloc d'instructions. * +* Description : Classe le contenu d'un bloc d'instructions exécutées. * * * -* Retour : - * +* Retour : true pour continuer la visite. * * * * Remarques : - * * * ******************************************************************************/ -static void rank_flow_block_content(GFlowBlock *block, const GInstrBlock *list) +static bool rank_flow_block(GFlowBlock *block, BlockVisitOrder order, const GInstrBlock *list) { + unsigned int next; /* Rang suivant obtenu */ + GInstrBlock *links; /* Blocs liés au bloc courant */ GArchInstruction *last; /* Dernière instruction du bloc*/ GArchInstruction **dests; /* Instr. visée par une autre */ InstructionLinkType *types; /* Type de lien entre lignes */ size_t dcount; /* Nombre de liens de dest. */ - size_t k; /* Boucle de parcours #1 */ - size_t i; /* Boucle de parcours #2 */ - vmpa_t addr; /* Adresse de la destination */ - GInstrBlock *next; /* Bloc suivant à visiter */ - bool loop; /* Détection de rebouclage */ - //unsigned int old_rank; /* Rang avant intervention */ - - g_flow_block_get_boundary(block, NULL, &last); - dcount = g_arch_instruction_get_destinations(last, &dests, &types, NULL); - - for (k = 0; k < 2; k++) - for (i = 0; i < dcount; i++) - switch (types[i]) - { - case ILT_EXEC_FLOW: - case ILT_JUMP: - case ILT_CASE_JUMP: - case ILT_JUMP_IF_TRUE: - case ILT_JUMP_IF_FALSE: - - g_arch_instruction_get_location(dests[i], NULL, NULL, &addr); - next = g_instr_block_find_by_addr(list, addr, true); - - /** - * On traite en premier les liens qui conduisent à un rebouclage, - * afin d'avoir des indices importants à offrir pour les autres liens - * par la suite. - */ - loop = g_flow_block_is_looping_to(G_FLOW_BLOCK(next), list, block); - //if (loop != (k == 0)) continue; - - if (loop) - printf("next :: %u (i=%zu k=%zu)\n", g_flow_block_get_next_rank(block), i, k); - - - if (loop == (k == 0)) - { - g_flow_block_set_rank(G_FLOW_BLOCK(next), g_flow_block_get_next_rank(block)); - - rank_flow_block_content(G_FLOW_BLOCK(next), list); - } - break; - - case ILT_LOOP: - g_arch_instruction_get_location(dests[i], NULL, NULL, &addr); - next = g_instr_block_find_by_addr(list, addr, true); - - - /** - * On traite en premier les liens qui conduisent à un rebouclage, - * afin d'avoir des indices importants à offrir pour les autres liens - * par la suite. - */ - loop = g_flow_block_is_looping_to(G_FLOW_BLOCK(next), list, block); - //if (loop != (k == 0)) continue; - - - if (loop == (k == 0)) - { - printf("loop next :: %u (i=%zu k=%zu)\n", g_flow_block_get_next_rank(block), i, k); - - - g_flow_block_set_next_rank(G_FLOW_BLOCK(next), - g_flow_block_get_next_rank(block)); - - } - - break; - - default: - break; - - } - - + size_t i; /* Boucle de parcours */ + const mrange_t *range; /* Emplacement d'une cible */ + GFlowBlock *target; /* Bloc ciblé par un lien */ + unsigned int rank; /* Rang à constituer */ + /* Si le bloc visité n'est pas basique... */ + if (order != BVO_PENDING) return true; + next = g_flow_block_get_rank(block) + 1; + links = g_instr_block_get_links_block(G_INSTR_BLOCK(block)); + g_flow_block_get_boundary(block, NULL, &last); + dcount = g_arch_instruction_get_destinations(last, &dests, &types, NULL); -#if 0 - /** - * Si un bloc contient un retour sur lui même, on définit l'indice pour les - * blocs suivants découlant de cette boucle avant de traiter ces blocs suivants. - */ for (i = 0; i < dcount; i++) + { + range = g_arch_instruction_get_range(dests[i]); + switch (types[i]) { - case ILT_LOOP: - g_arch_instruction_get_location(dests[i], NULL, NULL, &addr); - next = g_instr_block_find_by_addr(list, addr, true); - g_flow_block_set_next_rank(G_FLOW_BLOCK(next), g_flow_block_get_next_rank(block)); + case ILT_EXEC_FLOW: + case ILT_CATCH_EXCEPTION: + target = G_FLOW_BLOCK(g_instr_block_find_by_addr(list, get_mrange_addr(range), true)); + assert(target != NULL); break; - default: - break; + case ILT_JUMP: + target = G_FLOW_BLOCK(g_instr_block_find_by_addr(list, get_mrange_addr(range), true)); + + /** + * Les sauts ne se font pas toujours à l'intérieur d'une même fonction. + * Par exemple sous ARM : + * + * 00008358 : + * .... + * 8362: f7ff bfcf b.w 8304 <_init+0x38> + * .... + * + */ + /* assert(target != NULL);*/ - } + break; - for (i = 0; i < dcount; i++) - switch (types[i]) - { - case ILT_EXEC_FLOW: - case ILT_JUMP: case ILT_CASE_JUMP: + target = G_FLOW_BLOCK(g_instr_block_find_by_addr(links, get_mrange_addr(range), true)); + assert(target != NULL); + break; + case ILT_JUMP_IF_TRUE: case ILT_JUMP_IF_FALSE: - g_arch_instruction_get_location(dests[i], NULL, NULL, &addr); - next = g_instr_block_find_by_addr(list, addr, true); - - old_rank = g_flow_block_get_rank(G_FLOW_BLOCK(next)); - g_flow_block_set_rank(G_FLOW_BLOCK(next), g_flow_block_get_next_rank(block)); + /** + * Même dans les branches if/then/else, il n'y a pas forcément de groupe de blocs + * associé. C'est par exemple le cas dans des constructions telles que celle de + * la fonction __libc_csu_init() : + * + * if (...) + * do + * { + * ... + * } + * while (...) + * + * ... + * + * Le code final est étiquetté comme étant le 'else' de la première condition, + * donc au niveau de la condition de bouclage, il appartient déjà à un autre + * et n'est donc pas réattribué une seconde fois. + * + */ + + if (links != NULL) + target = G_FLOW_BLOCK(g_instr_block_find_by_addr(links, get_mrange_addr(range), true)); + else + target = NULL; + + /** + * Le bloc visé ne se trouve pas toujours dans les blocs attachés : + * + * { bloc IF } + * { bloc THEN } + * { block NEXT } + * + * Le bloc NEXT est ici à rechercher dans la liste globale. + */ + + if (target == NULL) + target = G_FLOW_BLOCK(g_instr_block_find_by_addr(list, get_mrange_addr(range), true)); + + assert(target != NULL); - /* Si un traitement n'a pas déjà été fait... */ - if (old_rank == 0 || 1) - rank_flow_block_content(G_FLOW_BLOCK(next), list); + break; default: + target = NULL; break; } -#endif - -} - -#endif - - - - -/* Classe le contenu d'un bloc d'instructions exécutées. */ -static unsigned int rank_flow_block(GFlowBlock *, const GInstrBlock *, unsigned int); - -/* Classe le contenu d'un bloc d'instructions virtuel. */ -static unsigned int rank_virtual_block(GVirtualBlock *, const GInstrBlock *, unsigned int); - -/* Classe le contenu d'un bloc d'instructions quelconque. */ -static unsigned int rank_instructions_block(GInstrBlock *, const GInstrBlock *, unsigned int); - - + if (target != NULL) + { + rank = MAX(next, g_flow_block_get_rank(target)); + g_flow_block_set_rank(target, rank); - -/****************************************************************************** -* * -* Paramètres : block = bloc d'instructions concerné par la visite. * -* list = ensemble des blocs basiques à parcourir. * -* rank = rang courant du classement en courant. * -* * -* Description : Classe le contenu d'un bloc d'instructions exécutées. * -* * -* Retour : Rang pour les blocs suivants. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static unsigned int rank_flow_block(GFlowBlock *block, const GInstrBlock *list, unsigned int rank) -{ - unsigned int result; /* Rang suivant à retourner */ - GInstrBlock *links; /* Blocs liés au bloc courant */ - GArchInstruction *last; /* Dernière instruction du bloc*/ - GArchInstruction **dests; /* Instr. visée par une autre */ - InstructionLinkType *types; /* Type de lien entre lignes */ - size_t dcount; /* Nombre de liens de dest. */ - size_t k; /* Boucle de parcours #1 */ - size_t i; /* Boucle de parcours #2 */ - vmpa_t addr; /* Adresse de la destination */ - GInstrBlock *next; /* Bloc suivant à visiter */ - bool loop; /* Détection de rebouclage */ - - /* On traite le bloc courant */ - - result = rank; - g_flow_block_set_rank(block, result++); - - /* Viennent ensuite les blocs rattachés */ - - links = g_instr_block_get_links_block(G_INSTR_BLOCK(block)); - - if (links != NULL) - { - g_flow_block_get_boundary(block, NULL, &last); - dcount = g_arch_instruction_get_destinations(last, &dests, &types, NULL); - - for (k = 0; k < 2; k++) - for (i = 0; i < dcount; i++) - switch (types[i]) - { - case ILT_CASE_JUMP: - case ILT_JUMP_IF_TRUE: - case ILT_JUMP_IF_FALSE: - - g_arch_instruction_get_location(dests[i], NULL, NULL, &addr); - - next = g_instr_block_find_by_addr(links, addr, true); - - /** - * En cas d'une branche unique, l'adresse peut ne pas être trouvée - * dans les sous-blocs ; logiquement, elle sera traitée plus tard, - * dans la continuité de ce bloc. - */ - if (next == NULL) break; - - /** - * On traite en premier les liens qui conduisent à un rebouclage, - * afin d'avoir des indices importants à offrir pour les autres liens - * par la suite. - */ - loop = g_flow_block_is_looping_to(G_FLOW_BLOCK(next), list, block); - if (loop != (k == 0)) continue; - - next = g_instr_block_find_by_addr(links, addr, false); - result = MAX(rank_instructions_block(next, list, rank + 1), result); - - break; - - default: - break; - - } - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : block = bloc d'instructions concerné par la visite. * -* list = ensemble des blocs basiques à parcourir. * -* rank = rang courant du classement en courant. * -* * -* Description : Classe le contenu d'un bloc d'instructions virtuel. * -* * -* Retour : Rang pour les blocs suivants. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static unsigned int rank_virtual_block(GVirtualBlock *block, const GInstrBlock *list, unsigned int rank) -{ - unsigned int result; /* Rang suivant à retourner */ - size_t max; /* Borne du parcours */ - size_t i; /* Boucle de parcours */ - GInstrBlock *child; /* Sous-bloc à traiter */ - - result = rank; - - max = g_virtual_block_count_children(block); - - for (i = 0; i < max; i++) - { - child = g_virtual_block_get_child(block, i); - if (!G_IS_FLOW_BLOCK(child)) continue; - - result = rank_instructions_block(child, list, result); + } } - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : block = bloc d'instructions concerné par la visite. * -* list = ensemble des blocs basiques à parcourir. * -* rank = rang courant du classement en courant. * -* * -* Description : Classe le contenu d'un bloc d'instructions quelconque. * -* * -* Retour : Rang pour les blocs suivants. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static unsigned int rank_instructions_block(GInstrBlock *block, const GInstrBlock *list, unsigned int rank) -{ - unsigned int result; /* Rang suivant à retourner */ - - if (G_IS_VIRTUAL_BLOCK(block)) - result = rank_virtual_block(G_VIRTUAL_BLOCK(block), list, rank); - - else if (G_FLOW_BLOCK(block)) - result = rank_flow_block(G_FLOW_BLOCK(block), list, rank); - - else - result = rank; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : routine = routine à traiter. * -* * -* Description : Classe les blocs d'une routine donnée. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void rank_routine_blocks(GBinRoutine *routine) -{ - GInstrBlock *list; /* Ensemble des blocs d'instr. */ - //vmpa_t start; /* Adresse de départ */ - //GFlowBlock *first; /* Premier bloc de la routine */ - - list = g_binary_routine_get_basic_blocks(routine); - - rank_instructions_block(list, list, 0); - - /* - start = g_binary_routine_get_address(routine); - first = G_FLOW_BLOCK(g_instr_block_find_by_addr(list, start, true)); - - rank_flow_block_content(first, list); - */ + return true; } @@ -406,8 +194,14 @@ void rank_routine_blocks(GBinRoutine *routine) void rank_routines_blocks(GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id) { size_t i; /* Boucle de parcours */ + GInstrBlock *main_block; /* Ensemble des blocs d'instr. */ for (i = 0; i < count; i++) - rank_routine_blocks(routines[i]); + { + main_block = g_binary_routine_get_basic_blocks(routines[i]); + + g_instr_block_visit(main_block, (instr_block_visitor_cb)rank_flow_block, main_block); + + } } diff --git a/src/analysis/disass/rank.h b/src/analysis/disass/rank.h index 4252272..a4c62bb 100644 --- a/src/analysis/disass/rank.h +++ b/src/analysis/disass/rank.h @@ -30,9 +30,6 @@ -/* Classe les blocs d'une routine donnée. */ -void rank_routine_blocks(GBinRoutine *); - /* Classe les blocs des routines. */ void rank_routines_blocks(GBinRoutine **, size_t, GtkExtStatusBar *, bstatus_id_t); -- cgit v0.11.2-87-g4458