diff options
Diffstat (limited to 'src/analysis/disass')
-rw-r--r-- | src/analysis/disass/disassembler.c | 9 | ||||
-rw-r--r-- | src/analysis/disass/loop.c | 91 | ||||
-rw-r--r-- | src/analysis/disass/loop.h | 3 | ||||
-rw-r--r-- | src/analysis/disass/rank.c | 63 |
4 files changed, 130 insertions, 36 deletions
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c index 50c71da..1227e84 100644 --- a/src/analysis/disass/disassembler.c +++ b/src/analysis/disass/disassembler.c @@ -323,12 +323,19 @@ 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); + /// - /* Troisième étape */ + + + /* Quatrième étape */ id = gtk_extended_status_bar_push(statusbar, _("Establishing links..."), true); diff --git a/src/analysis/disass/loop.c b/src/analysis/disass/loop.c index 0a06748..0cb346b 100644 --- a/src/analysis/disass/loop.c +++ b/src/analysis/disass/loop.c @@ -30,14 +30,10 @@ -#include "../../arch/instruction.h" - - - /* Suivi du flot d'exécution */ typedef struct _exec_flow { - vmpa_t *steps; /* Jalons dans l'exécution */ + vmpa2t *steps; /* Jalons dans l'exécution */ size_t count; /* Quantité de ces points */ } exec_flow; @@ -53,13 +49,13 @@ static exec_flow *dup_exec_flow(const exec_flow *); static void delete_exec_flow(exec_flow *); /* Recherche si le chemin d'exécution a déjà mené à une adresse. */ -static bool is_new_exec_flow(const exec_flow *, vmpa_t); +static bool is_new_exec_flow(const exec_flow *, const vmpa2t *); /* Ajoute une adresse jalon dans un flot d'exécution. */ -static void add_step_into_exec_flow(exec_flow *, vmpa_t); +static void add_step_into_exec_flow(exec_flow *, const vmpa2t *); /* Suit un flot d'exécution à la recherche de boucles. */ -static void track_loops_in_code(GArchInstruction *, vmpa_t, vmpa_t, exec_flow *); +static void track_loops_in_code(const GArchProcessor *, const mrange_t *, const vmpa2t *, exec_flow *); @@ -104,8 +100,8 @@ static exec_flow *dup_exec_flow(const exec_flow *src) result = (exec_flow *)calloc(1, sizeof(exec_flow)); - result->steps = (vmpa_t *)malloc(src->count * sizeof(vmpa_t)); - memcpy(result->steps, src->steps, src->count * sizeof(vmpa_t)); + result->steps = (vmpa2t *)malloc(src->count * sizeof(vmpa2t)); + memcpy(result->steps, src->steps, src->count * sizeof(vmpa2t)); result->count = src->count; @@ -128,7 +124,8 @@ static exec_flow *dup_exec_flow(const exec_flow *src) static void delete_exec_flow(exec_flow *flow) { - free(flow->steps); + if (flow->steps != NULL) + free(flow->steps); free(flow); @@ -148,12 +145,12 @@ static void delete_exec_flow(exec_flow *flow) * * ******************************************************************************/ -static bool is_new_exec_flow(const exec_flow *flow, vmpa_t addr) +static bool is_new_exec_flow(const exec_flow *flow, const vmpa2t *addr) { void *ret; /* Conclusion d'une recherche */ - ret = bsearch(&addr, flow->steps, flow->count, - sizeof(vmpa_t), (__compar_fn_t)compare_vmpa); + ret = bsearch(addr, flow->steps, flow->count, + sizeof(vmpa2t), (__compar_fn_t)cmp_vmpa); return (ret == NULL); @@ -173,19 +170,19 @@ static bool is_new_exec_flow(const exec_flow *flow, vmpa_t addr) * * ******************************************************************************/ -static void add_step_into_exec_flow(exec_flow *flow, vmpa_t addr) +static void add_step_into_exec_flow(exec_flow *flow, const vmpa2t *addr) { - flow->steps = (vmpa_t *)realloc(flow->steps, ++flow->count * sizeof(vmpa_t)); - flow->steps[flow->count - 1] = addr; + flow->steps = (vmpa2t *)realloc(flow->steps, ++flow->count * sizeof(vmpa2t)); + copy_vmpa(&flow->steps[flow->count - 1], addr); - qsort(flow->steps, flow->count, sizeof(vmpa_t), (__compar_fn_t)compare_vmpa); + qsort(flow->steps, flow->count, sizeof(vmpa2t), (__compar_fn_t)cmp_vmpa); } /****************************************************************************** * * -* Paramètres : list = ensemble d'instructions à parcourir. * +* Paramètres : proc = ensemble d'instructions à parcourir. * * start = adresse du début de l'analyse. * * end = adresse de fin de la routine traitée. * * flow = ensemble des jalons de l'exécution du code. * @@ -198,28 +195,40 @@ static void add_step_into_exec_flow(exec_flow *flow, vmpa_t addr) * * ******************************************************************************/ -static void track_loops_in_code(GArchInstruction *list, vmpa_t start, vmpa_t end, exec_flow *flow) +static void track_loops_in_code(const GArchProcessor *proc, const mrange_t *range, const vmpa2t *start, exec_flow *flow) { bool exit_track; /* Détermine la fin du parcours*/ GArchInstruction *iter; /* Boucle de parcours */ + const mrange_t *irange; /* Emplacement d'instruction */ 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 i; /* Boucle de parcours */ - vmpa_t addr; /* Prochaine adresse de saut */ + const vmpa2t *addr; /* Prochaine adresse de saut */ exec_flow *next_flow; /* Suite de l'exécution */ add_step_into_exec_flow(flow, start); exit_track = false; - for (iter = g_arch_instruction_find_by_address(list, start, true); + for (iter = g_arch_processor_find_instr_by_address(proc, start); iter != NULL && !exit_track; - iter = g_arch_instruction_get_next_iter(list, iter, end)) + iter = g_arch_instruction_get_next_iter(iter /* FIXME : list*/, iter, ~0)) { + /* L'instruction sort-elle des clous ? */ + + irange = g_arch_instruction_get_range(iter); + + if (!mrange_contains_mrange(range, irange)) + break; + + /* Fin de parcours ? */ + if (g_arch_instruction_is_return(iter)) break; + /* Analyse des destinations */ + dcount = g_arch_instruction_get_destinations(iter, &dests, &types, NULL); if (dcount == 0) continue; @@ -233,18 +242,31 @@ static void track_loops_in_code(GArchInstruction *list, vmpa_t start, vmpa_t end exit_track = true; break; - case ILT_CALL: case ILT_CATCH_EXCEPTION: + + irange = g_arch_instruction_get_range(dests[i]); + addr = get_mrange_addr(irange); + + next_flow = create_exec_flow(); + track_loops_in_code(proc, range, addr, next_flow); + delete_exec_flow(next_flow); + break; - default: + case ILT_EXEC_FLOW: + case ILT_JUMP: + case ILT_CASE_JUMP: + case ILT_JUMP_IF_TRUE: + case ILT_JUMP_IF_FALSE: + /** * On se lance dans d'autres suivis qui vont parcourir le reste des * instructions, donc on peut arrêter le parcours courant ici. */ exit_track = true; - g_arch_instruction_get_location(dests[i], NULL, NULL, &addr); + irange = g_arch_instruction_get_range(dests[i]); + addr = get_mrange_addr(irange); if (!is_new_exec_flow(flow, addr)) types[i] = ILT_LOOP; @@ -252,12 +274,15 @@ static void track_loops_in_code(GArchInstruction *list, vmpa_t start, vmpa_t end else { next_flow = dup_exec_flow(flow); - track_loops_in_code(list, addr, end, next_flow); + track_loops_in_code(proc, range, addr, next_flow); delete_exec_flow(next_flow); } break; + default: + break; + } } @@ -267,7 +292,7 @@ static void track_loops_in_code(GArchInstruction *list, vmpa_t start, vmpa_t end /****************************************************************************** * * -* Paramètres : list = ensemble d'instructions à relier. * +* Paramètres : proc = ensemble d'instructions à relier. * * routines = prototypes existants à insérer. * * count = quantité de ces prototypes. * * statusbar = barre de statut avec progression à mettre à jour.* @@ -281,20 +306,18 @@ static void track_loops_in_code(GArchInstruction *list, vmpa_t start, vmpa_t end * * ******************************************************************************/ -void detect_loops_in_code(GArchInstruction *list, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id) +void detect_loops_in_code(const GArchProcessor *proc, 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 */ + const mrange_t *range; /* Couverture d'une routine */ exec_flow *flow; /* Flot d'exécution à suivre */ for (i = 0; i < count; i++) { - start = g_binary_routine_get_address(routines[i]); - end = start + g_binary_routine_get_size(routines[i]); + range = g_binary_routine_get_range(routines[i]); flow = create_exec_flow(); - track_loops_in_code(list, start, end, flow); + track_loops_in_code(proc, range, get_mrange_addr(range), flow); delete_exec_flow(flow); gtk_extended_status_bar_update_activity(statusbar, id, (i + 1) * 1.0 / count); diff --git a/src/analysis/disass/loop.h b/src/analysis/disass/loop.h index 7c8d7b3..f4b05cf 100644 --- a/src/analysis/disass/loop.h +++ b/src/analysis/disass/loop.h @@ -26,12 +26,13 @@ #include "../routine.h" +#include "../../arch/processor.h" #include "../../gtkext/gtkextstatusbar.h" /* Détecte les boucles dans du code machine. */ -void detect_loops_in_code(GArchInstruction *, GBinRoutine **, size_t, GtkExtStatusBar *, bstatus_id_t); +void detect_loops_in_code(const GArchProcessor *, GBinRoutine **, size_t, GtkExtStatusBar *, bstatus_id_t); diff --git a/src/analysis/disass/rank.c b/src/analysis/disass/rank.c index 94494d5..758e15d 100644 --- a/src/analysis/disass/rank.c +++ b/src/analysis/disass/rank.c @@ -202,6 +202,69 @@ void rank_routines_blocks(GBinRoutine **routines, size_t count, GtkExtStatusBar g_instr_block_visit(main_block, (instr_block_visitor_cb)rank_flow_block, main_block); + + + 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"); + + + + + + + + + + + + } } |