diff options
Diffstat (limited to 'src/analysis/disass/rank.c')
-rw-r--r-- | src/analysis/disass/rank.c | 318 |
1 files changed, 17 insertions, 301 deletions
diff --git a/src/analysis/disass/rank.c b/src/analysis/disass/rank.c index 6e737a5..b4a8f92 100644 --- a/src/analysis/disass/rank.c +++ b/src/analysis/disass/rank.c @@ -24,270 +24,12 @@ #include "rank.h" - - -#if 0 - -#include <assert.h> -#include <sys/param.h> - - -#include "../blocks/flow.h" -#include "../blocks/virtual.h" - - - -/* 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 concerné par la visite. * -* order = indication quant au sens de visite. * -* list = ensemble des blocs basiques à parcourir. * -* * -* Description : Classe le contenu d'un bloc d'instructions exécutées. * -* * -* Retour : true pour continuer la visite. * -* * -* Remarques : - * -* * -******************************************************************************/ - -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*/ - size_t dcount; /* Nombre de liens de dest. */ - size_t i; /* Boucle de parcours */ - const instr_link_t *dest; /* Instr. visée par une autre */ - 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); - - g_arch_instruction_lock_dest(last); - dcount = g_arch_instruction_count_destinations(last); - - for (i = 0; i < dcount; i++) - { - dest = g_arch_instruction_get_destination(last, i); - - range = g_arch_instruction_get_range(dest->linked); - - switch (dest->type) - { - 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; - - 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 <call_gmon_start>: - * .... - * 8362: f7ff bfcf b.w 8304 <_init+0x38> - * .... - * - */ - /* assert(target != NULL);*/ - - break; - - 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: - - /** - * 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); - - break; - - default: - target = NULL; - break; - - } - - unref_instr_link(dest); - - if (target != NULL) - { - rank = MAX(next, g_flow_block_get_rank(target)); - - g_flow_block_set_rank(target, rank); - - } - - } - - g_arch_instruction_unlock_dest(last); - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : routine = routine regroupant les blocs à traiter. * -* * -* Description : Classe les blocs des routines. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void rank_routine_blocks(GBinRoutine *routine) -{ - GInstrBlock *main_block; /* Ensemble des blocs d'instr. */ - - main_block = g_binary_routine_get_basic_blocks(routine); - - - if (main_block == NULL) return; - - - g_instr_block_visit(main_block, (instr_block_visitor_cb)rank_flow_block, main_block); - - -#if 0 - - printf("===== BLOCK(S) xXXx ======\n"); - - - bool visit_ranked_block(GInstrBlock *blk, BlockVisitOrder order, int *indent) - { - int i; - - switch (order) - { - case BVO_IN: - case BVO_PENDING: - - for (i = 0; i < *indent; i++) - printf(" "); - - printf("%p '%s'", blk, G_OBJECT_TYPE_NAME(blk)); - - if (G_IS_FLOW_BLOCK(blk)) - { - vmpa2t start; - vmpa2t end; - - g_flow_block_get_boundary_addresses(G_FLOW_BLOCK(blk), &start, &end); - - printf(" 0x%08x -> 0x%08x (rank = %u)", - (unsigned int)start.virtual, - (unsigned int)end.virtual, - g_flow_block_get_rank(G_FLOW_BLOCK(blk))); - - } - - printf("\n"); - - if (order == BVO_IN) (*indent)++; - break; - - case BVO_OUT: - (*indent)--; - break; - - } - - return true; - - } - - g_instr_block_visit(main_block, (instr_block_visitor_cb)visit_ranked_block, (int []){ 0 }); - - printf("\n"); - - -#endif - - - - -} - - - -#endif - - - - - - - #include <assert.h> /* Classe les blocs basiques d'une routine. */ -void rank_routine_block(const GBlockList *, GBasicBlock *); - +void rank_routine_block(const GBlockList *, GCodeBlock *); @@ -304,27 +46,23 @@ void rank_routine_block(const GBlockList *, GBasicBlock *); * * ******************************************************************************/ -void rank_routine_block(const GBlockList *list, GBasicBlock *block) +void rank_routine_block(const GBlockList *list, GCodeBlock *block) { - unsigned int next; /* Rang suivant obtenu */ - GArchInstruction *last; /* Dernière instruction du bloc*/ + size_t next; /* Rang suivant obtenu */ size_t dcount; /* Nombre de liens de dest. */ size_t i; /* Boucle de parcours */ - const instr_link_t *dest; /* Instr. visée par une autre */ + const block_link_t *dest; /* Instr. visée par une autre */ InstructionLinkType type; /* Raccourci pour confort */ - GBasicBlock *target; /* Bloc ciblé par un lien */ unsigned int rank; /* Rang à constituer */ - next = g_basic_block_get_rank(block) + 1; - - g_basic_block_get_boundary(block, NULL, &last); + next = g_code_block_get_rank(block) + 1; - g_arch_instruction_lock_dest(last); - dcount = g_arch_instruction_count_destinations(last); + g_code_block_lock_dest(block); + dcount = g_code_block_count_destinations(block); for (i = 0; i < dcount; i++) { - dest = g_arch_instruction_get_destination(last, i); + dest = g_code_block_get_destination(block, i); type = dest->type; @@ -343,30 +81,13 @@ void rank_routine_block(const GBlockList *list, GBasicBlock *block) && type != ILT_JUMP_IF_FALSE) goto next_dest; - target = g_block_list_find_by_starting_instr(list, dest->linked); + rank = g_code_block_get_rank(dest->linked); - /** - * Les sauts ne se font pas toujours à l'intérieur d'une même fonction. - * Par exemple sous ARM : - * - * 00008358 <call_gmon_start>: - * .... - * 8362: f7ff bfcf b.w 8304 <_init+0x38> - * .... - * - */ - - if (target != NULL) + if (next > rank || rank == -1) { - rank = g_basic_block_get_rank(target); - - if (next > rank || rank == -1) - { - g_basic_block_set_rank(target, next); + g_code_block_set_rank(dest->linked, next); - rank_routine_block(list, target); - - } + rank_routine_block(list, dest->linked); } @@ -376,7 +97,7 @@ void rank_routine_block(const GBlockList *list, GBasicBlock *block) } - g_arch_instruction_unlock_dest(last); + g_code_block_unlock_dest(block); } @@ -396,22 +117,17 @@ void rank_routine_block(const GBlockList *list, GBasicBlock *block) void rank_routine_blocks(GBinRoutine *routine) { GBlockList *blocks; /* Ensemble des blocs d'instr. */ - GBasicBlock *start; /* Bloc basique de départ */ + GCodeBlock *start; /* Bloc basique de départ */ blocks = g_binary_routine_get_basic_blocks(routine); - start = g_block_list_get_block(blocks, 0 /* FIXME */); + start = g_block_list_get_block(blocks, 0); assert(start != NULL); - - g_basic_block_set_rank(start, 0); - + g_code_block_set_rank(start, 0); rank_routine_block(blocks, start); - - - - + g_object_unref(G_OBJECT(start)); } |