diff options
Diffstat (limited to 'src/analysis/disass')
-rw-r--r-- | src/analysis/disass/macro.c | 121 |
1 files changed, 69 insertions, 52 deletions
diff --git a/src/analysis/disass/macro.c b/src/analysis/disass/macro.c index 2e5c0ee..8652b27 100644 --- a/src/analysis/disass/macro.c +++ b/src/analysis/disass/macro.c @@ -288,6 +288,7 @@ static GInstrBlock *build_instruction_block(GArchInstruction *instrs, vmpa_t sta size_t dcount; /* Nombre de liens de dest. */ size_t i; /* Boucle de parcours #1 */ GInstrBlock *block; /* Nouveau bloc mis en place */ + GInstrBlock *parent; /* Mémorisation pour les liens */ GInstrBlock *group; /* Regroupement de blocs */ branch_info *cases_branches; /* Branches d'un aiguillage */ size_t cases_count; /* Nombre d'aiguillages */ @@ -375,7 +376,6 @@ static GInstrBlock *build_instruction_block(GArchInstruction *instrs, vmpa_t sta case ILT_EXEC_FLOW: case ILT_JUMP: - block = g_flow_block_new(instrs, first, iter); MACRO_MARK_AS_PROCESSED(first); first = NULL; @@ -428,21 +428,23 @@ static GInstrBlock *build_instruction_block(GArchInstruction *instrs, vmpa_t sta /* Post-traitements de ILT_CASE_JUMP */ if (cases_count > 0) { - if (first != NULL) - { - block = g_flow_block_new(instrs, first, iter); - MACRO_MARK_AS_PROCESSED(first); - first = NULL; - - DELAYED_BLOCK_ADDING(result, result_cached, block); + /** + * On doit clôturer le bloc renvoyant vers les branches de cas ici. + * Les sauts conditionnels sont normalement présents de façon exclusive, + * sauf pour les exceptions, qui sont traitées après. + */ + block = g_flow_block_new(instrs, first, iter); + MACRO_MARK_AS_PROCESSED(first); + first = NULL; - } + DELAYED_BLOCK_ADDING(result, result_cached, block); //printf(" --- cases --- start\n"); next_addr = compute_first_common_addr_in_group(cases_branches, cases_count); //printf(" stop :: 0x%08llx\n", next_addr); + parent = block; group = g_virtual_block_new(); for (j = 0; j < cases_count; j++) @@ -460,7 +462,10 @@ static GInstrBlock *build_instruction_block(GArchInstruction *instrs, vmpa_t sta } if (g_virtual_block_count_children(G_VIRTUAL_BLOCK(group)) > 0) + { DELAYED_BLOCK_ADDING(result, result_cached, group); + g_instr_block_set_links_block(parent, group); + } else g_object_unref(G_OBJECT(group)); @@ -471,38 +476,6 @@ static GInstrBlock *build_instruction_block(GArchInstruction *instrs, vmpa_t sta } - /* Post-traitements de ILT_CATCH_EXCEPTION */ - if (excep_count > 0) - { - if (first != NULL) - { - block = g_flow_block_new(instrs, first, iter); - MACRO_MARK_AS_PROCESSED(first); - first = NULL; - - DELAYED_BLOCK_ADDING(result, result_cached, block); - - } - - for (j = 0; j < excep_count; j++) - { - stop_addr = compute_first_common_addr(&main_branch, &excep_branches[j]); - //next_addr = MIN(next_addr, end); - - block = build_instruction_block(instrs, excep_branches[j].jumps[0], end, stop_addr); - - if (block != NULL) - - g_virtual_block_add_child(G_VIRTUAL_BLOCK(result), block); - - free(excep_branches[j].jumps); - - } - - free(excep_branches); - - } - if (next_addr == VMPA_MAX) { iter = g_arch_instruction_get_next_iter(instrs, iter, end); @@ -514,16 +487,18 @@ static GInstrBlock *build_instruction_block(GArchInstruction *instrs, vmpa_t sta next_addr = compute_first_common_addr(&true_branch, &false_branch); next_addr = MIN(next_addr, end); - if (first != NULL) - { - block = g_flow_block_new(instrs, first, iter); - MACRO_MARK_AS_PROCESSED(first); - first = NULL; - - DELAYED_BLOCK_ADDING(result, result_cached, block); + /** + * On doit clôturer le bloc renvoyant vers les branches 'true' et 'false' ici. + * Les sauts conditionnels sont normalement présents de façon exclusive, + * sauf pour les exceptions, qui sont traitées après. + */ + block = g_flow_block_new(instrs, first, iter); + MACRO_MARK_AS_PROCESSED(first); + first = NULL; - } + DELAYED_BLOCK_ADDING(result, result_cached, block); + parent = block; group = g_virtual_block_new(); block = build_instruction_block(instrs, true_branch.jumps[0], end, next_addr); @@ -535,7 +510,10 @@ static GInstrBlock *build_instruction_block(GArchInstruction *instrs, vmpa_t sta g_virtual_block_add_child(G_VIRTUAL_BLOCK(group), block); if (g_virtual_block_count_children(G_VIRTUAL_BLOCK(group)) > 0) + { DELAYED_BLOCK_ADDING(result, result_cached, group); + g_instr_block_set_links_block(parent, group); + } else g_object_unref(G_OBJECT(group)); @@ -546,6 +524,38 @@ static GInstrBlock *build_instruction_block(GArchInstruction *instrs, vmpa_t sta } + /* Post-traitements de ILT_CATCH_EXCEPTION */ + if (excep_count > 0) + { + if (first != NULL) + { + block = g_flow_block_new(instrs, first, iter); + MACRO_MARK_AS_PROCESSED(first); + first = NULL; + + DELAYED_BLOCK_ADDING(result, result_cached, block); + + } + + for (j = 0; j < excep_count; j++) + { + stop_addr = compute_first_common_addr(&main_branch, &excep_branches[j]); + //next_addr = MIN(next_addr, end); + + block = build_instruction_block(instrs, excep_branches[j].jumps[0], end, stop_addr); + + if (block != NULL) + + DELAYED_BLOCK_ADDING(result, result_cached, block); + + free(excep_branches[j].jumps); + + } + + free(excep_branches); + + } + /* Détermination du prochain point de chute */ iter = g_arch_instruction_find_by_address(instrs, next_addr, true); @@ -581,6 +591,7 @@ static bool print_blocks(GInstrBlock *blk, BlockVisitOrder order, int *pad) { int i; vmpa_t start, end; + GInstrBlock *links; if (order != BVO_OUT) for (i = 0; i < *pad; i++) @@ -589,7 +600,13 @@ static bool print_blocks(GInstrBlock *blk, BlockVisitOrder order, int *pad) if (G_IS_FLOW_BLOCK(blk)) { g_flow_block_get_boundary_addresses(G_FLOW_BLOCK(blk), &start, &end); - printf(" - flow %p : 0x%08lx -> 0x%08lx\n", blk, start, end); + links = g_instr_block_get_links_block(blk); + + if (links != NULL) + printf(" - flow %p : 0x%08lx -> 0x%08lx (links = %p)\n", blk, start, end, links); + else + printf(" - flow %p : 0x%08lx -> 0x%08lx\n", blk, start, end); + } else { @@ -638,14 +655,14 @@ void group_routines_instructions(GArchInstruction *list, GBinRoutine **routines, end = start + g_binary_routine_get_size(routines[i]); - //printf("==== %s ====\n", g_binary_routine_to_string(routines[i])); + printf("==== %s ====\n", g_binary_routine_to_string(routines[i])); block = build_instruction_block(list, start, end, VMPA_MAX); g_binary_routine_set_basic_blocks(routines[i], block); - //g_instr_block_visit(block, (instr_block_visitor_cb)print_blocks, (int []){ 0 }); + g_instr_block_visit(block, (instr_block_visitor_cb)print_blocks, (int []){ 0 }); gtk_extended_status_bar_update_activity(statusbar, id, (i + 1) * 1.0 / count); |