diff options
Diffstat (limited to 'src/analysis')
-rw-r--r-- | src/analysis/disass/macro.c | 83 |
1 files changed, 75 insertions, 8 deletions
diff --git a/src/analysis/disass/macro.c b/src/analysis/disass/macro.c index 087f1ae..75032fa 100644 --- a/src/analysis/disass/macro.c +++ b/src/analysis/disass/macro.c @@ -42,6 +42,8 @@ typedef struct _code_coverage { mrange_t range; /* Couverture totale */ + vmpa2t start; /* Position butoir de début */ + vmpa2t *ends; /* Positions butoir de fin */ size_t ends_count; /* Quantité de fins possibles */ @@ -60,6 +62,9 @@ static code_coverage *dup_code_coverage(const code_coverage *, const vmpa2t *); /* Détruit des délimitations d'une zone de code. */ static void delete_code_coverage(code_coverage *); +/* Précise la position de départ courante pour une analyse. */ +static const vmpa2t *get_code_coverage_start_addr(const code_coverage *); + /* Indique si une adresse est hors zone ou non. */ static bool code_coverage_stop_here(const code_coverage *coverage, const vmpa2t *); @@ -83,6 +88,8 @@ typedef struct _branch_info vmpa2t *hops; /* Jalons de la branche */ size_t count; /* Quantité de ces jalons */ + vmpa2t entry; /* Valeur du jalon d'entrée */ + } branch_info; @@ -98,6 +105,9 @@ static bool is_addr_in_branch(const branch_info *, const vmpa2t *); /* Ajoute un nouveau jalon dans l'exécution d'une branche. */ static bool add_hop_into_branch(branch_info *, const vmpa2t *); +/* Retourne le premier point d'exécution d'une branche donnée. */ +static const vmpa2t *get_entry_to_branch(const branch_info *); + /* Identifie les différents points de passage d'une branche. */ static void find_next_hops(GArchInstruction *, const vmpa2t *, const code_coverage *, branch_info *); @@ -201,6 +211,8 @@ static code_coverage *create_code_coverage(const mrange_t *range) copy_mrange(&result->range, range); + copy_vmpa(&result->start, get_mrange_addr(range)); + result->ends = (vmpa2t *)calloc(1, sizeof(vmpa2t)); result->ends_count = 1; @@ -241,6 +253,8 @@ static code_coverage *dup_code_coverage(const code_coverage *src, const vmpa2t * copy_mrange(&result->range, &src->range); + copy_vmpa(&result->start, new); + result->ends = (vmpa2t *)calloc(src->ends_count, sizeof(vmpa2t)); result->ends_count = src->ends_count; @@ -283,6 +297,25 @@ static void delete_code_coverage(code_coverage *coverage) /****************************************************************************** * * * Paramètres : coverage = informations de couverture à consulter. * +* * +* Description : Précise la position de départ courante pour une analyse. * +* * +* Retour : Position de départ pour une analyse d'une portion de zone. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const vmpa2t *get_code_coverage_start_addr(const code_coverage *coverage) +{ + return &coverage->start; + +} + + +/****************************************************************************** +* * +* Paramètres : coverage = informations de couverture à consulter. * * addr = localisation à tester. * * * * Description : Indique si une adresse est hors zone ou non. * @@ -499,6 +532,9 @@ static bool add_hop_into_branch(branch_info *info, const vmpa2t *addr) if (result) { + if (info->count == 0) + copy_vmpa(&info->entry, addr); + info->hops = (vmpa2t *)realloc(info->hops, ++info->count * sizeof(vmpa2t)); copy_vmpa(&info->hops[info->count - 1], addr); @@ -514,6 +550,25 @@ static bool add_hop_into_branch(branch_info *info, const vmpa2t *addr) /****************************************************************************** * * +* Paramètres : info = informations de flot à consulter. * +* * +* Description : Retourne le premier point d'exécution d'une branche donnée. * +* * +* Retour : Point de départ d'une branche. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const vmpa2t *get_entry_to_branch(const branch_info *info) +{ + return &info->entry; + +} + + +/****************************************************************************** +* * * Paramètres : instrs = ensemble des instructions d'assemblage. * * start = position du début de bloc. * * coverage = liste des adresses de fin butoir. * @@ -874,12 +929,12 @@ static GInstrBlock *build_instruction_blocks_case(GArchInstruction *instrs, code for (i = 0; i < cases->count; i++) { - sub_coverage = dup_code_coverage(coverage, &cases->branches[i].hops[0]); + sub_coverage = dup_code_coverage(coverage, get_entry_to_branch(&cases->branches[i])); add_ending_address_code_coverage(sub_coverage, next); for (j = 0; j < cases->count; j++) - add_ending_address_code_coverage(sub_coverage, &cases->branches[j].hops[0]); + add_ending_address_code_coverage(sub_coverage, get_entry_to_branch(&cases->branches[j])); block = build_instruction_blocks(instrs, sub_coverage); @@ -942,12 +997,12 @@ static GInstrBlock *build_instruction_blocks_ite(GArchInstruction *instrs, code_ if (br0->count > 0) { - sub_coverage = dup_code_coverage(coverage, &br0->hops[0]); + sub_coverage = dup_code_coverage(coverage, get_entry_to_branch(br0)); add_ending_address_code_coverage(sub_coverage, next); if (br1->count > 0) - add_ending_address_code_coverage(sub_coverage, &br1->hops[0]); + add_ending_address_code_coverage(sub_coverage, get_entry_to_branch(br1)); result = build_instruction_blocks(instrs, sub_coverage); @@ -963,6 +1018,8 @@ static GInstrBlock *build_instruction_blocks_ite(GArchInstruction *instrs, code_ block = build_instr_block_bi(instrs, coverage, true_branch, false_branch, next); + printf("===> TRUE_BRANCH = %p\n", block); + if (block != NULL) g_virtual_block_add_child(G_VIRTUAL_BLOCK(result), block); @@ -970,6 +1027,8 @@ static GInstrBlock *build_instruction_blocks_ite(GArchInstruction *instrs, code_ block = build_instr_block_bi(instrs, coverage, false_branch, true_branch, next); + printf("===> FALSE_BRANCH = %p\n", block); + if (block != NULL) g_virtual_block_add_child(G_VIRTUAL_BLOCK(result), block); @@ -1016,7 +1075,7 @@ static void add_instruction_blocks_except(GInstrBlock **result, GInstrBlock **ca has_stop = compute_first_common_addr(main_branch, &exceptions->branches[i], &stop_addr); if (!has_stop) continue; - sub_coverage = dup_code_coverage(coverage, &exceptions->branches[i].hops[0]); + sub_coverage = dup_code_coverage(coverage, get_entry_to_branch(&exceptions->branches[i])); add_ending_address_code_coverage(sub_coverage, &stop_addr); block = build_instruction_blocks(instrs, sub_coverage); @@ -1075,9 +1134,17 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove last = NULL; init_branch_info(&main_branch); - find_next_hops(instrs, get_mrange_addr(&coverage->range), coverage, &main_branch); + find_next_hops(instrs, get_code_coverage_start_addr(coverage), coverage, &main_branch); + + + printf("//////////////////////////\n"); + printf("/// Cutting for 0x%08x -> %p\n", + get_code_coverage_start_addr(coverage)->virtual, + g_arch_instruction_find_by_address(instrs, get_code_coverage_start_addr(coverage), true)); + printf("//////////////////////////\n"); + - for (iter = g_arch_instruction_find_by_address(instrs, get_mrange_addr(&coverage->range), true); + for (iter = g_arch_instruction_find_by_address(instrs, get_code_coverage_start_addr(coverage), true); iter != NULL; ) { @@ -1347,7 +1414,7 @@ void group_routines_instructions(GArchInstruction *list, GBinRoutine **routines, break; case BVO_OUT: - (*indent)++; + (*indent)--; break; } |