diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2015-03-31 23:20:33 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2015-03-31 23:20:33 (GMT) |
commit | 5cc7bd39ae41af40a0c939acf98f90bf1375effd (patch) | |
tree | 4f7140e2c5a8d939c672fb941e66903300229e82 /src/analysis/disass | |
parent | 52e036040b5e0ad8acde3d467ac8d9ca43ed414c (diff) |
Saved some progress in the definition of basic blocks.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@497 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/analysis/disass')
-rw-r--r-- | src/analysis/disass/area.c | 2 | ||||
-rw-r--r-- | src/analysis/disass/disassembler.c | 37 | ||||
-rw-r--r-- | src/analysis/disass/links.c | 87 | ||||
-rw-r--r-- | src/analysis/disass/macro.c | 105 |
4 files changed, 219 insertions, 12 deletions
diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c index 90738be..3a23993 100644 --- a/src/analysis/disass/area.c +++ b/src/analysis/disass/area.c @@ -565,7 +565,7 @@ bool load_code_from_mem_area(mem_area **list, size_t *count, size_t *index, cons /* Eventuel renvoi vers d'autres adresses */ - g_arch_instruction_call_hook(instr, IPH_LINK, ctx, format); + g_arch_instruction_call_hook(instr, IPH_FETCH, proc, ctx, format); /* Progression dans les traitements */ diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c index 95d95d0..fcc41cb 100644 --- a/src/analysis/disass/disassembler.c +++ b/src/analysis/disass/disassembler.c @@ -186,6 +186,8 @@ static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GAr static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtStatusBar *statusbar) { + //GBinFormat *format; /* Format du fichier binaire */ + GArchProcessor *proc; /* Architecture du binaire */ unsigned int valid; /* Instructions traduites */ @@ -199,9 +201,12 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta bstatus_id_t id; /* Identifiant de statut */ - GArchProcessor *proc; /* Architecture du binaire */ + //GArchProcessor *proc; /* Architecture du binaire */ + //format = G_BIN_FORMAT(g_loaded_binary_get_format(binary)); + proc = g_loaded_binary_get_processor(disass->binary); + routines = g_binary_format_get_routines(G_BIN_FORMAT(disass->format), &routines_count); @@ -219,6 +224,8 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta *disass->instrs = disassemble_binary_content(disass->binary, statusbar); + g_arch_processor_set_disassembled_instructions(proc, *disass->instrs); + /* *disass->instrs = disassemble_binary_parts(disass->binary, disass->parts, disass->count, @@ -229,6 +236,32 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta + do + { + GBinFormat *format; /* Format du fichier binaire */ + GArchInstruction *iter; /* Boucle de parcours */ + + + + format = G_BIN_FORMAT(g_loaded_binary_get_format(disass->binary)); + + for (iter = *disass->instrs; + iter != NULL; + iter = g_arch_instruction_get_next_iter(*disass->instrs, iter, 0)) + { + + g_arch_instruction_call_hook(iter, IPH_LINK, proc, /*ctx*/NULL, format); + + + + } + + + + } while (0); + + + //gtk_extended_status_bar_remove(statusbar, id); @@ -250,7 +283,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta iter = g_arch_instruction_get_next_iter(*disass->instrs, iter, 0)) { - g_arch_instruction_call_hook(iter, IPH_POST, /*ctx*/NULL, format); + g_arch_instruction_call_hook(iter, IPH_POST, proc, /*ctx*/NULL, format); diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c index 022ace3..06b6b03 100644 --- a/src/analysis/disass/links.c +++ b/src/analysis/disass/links.c @@ -33,10 +33,8 @@ /* Complète un désassemblage accompli pour une instruction. */ static void convert_immediate_into_target(GArchInstruction *, size_t, GBinFormat *); - - - - +/* Rétablit un lien naturel coupé par un autre lien. */ +static void establish_natural_link(GArchInstruction *, GArchInstruction *); @@ -118,10 +116,83 @@ static void establish_links_for_instruction(GArchInstruction *instr, GArchInstru target = g_arch_instruction_find_by_address(list, &addr, true); if (target != NULL) - g_arch_instruction_link_with(instr, target, ILT_JUMP /* FIXME */); + g_arch_instruction_link_with(instr, target, ILT_REF); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction désassemblée à traiter. * +* prev = instruction précédente. * +* * +* Description : Rétablit un lien naturel coupé par un autre lien. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev) +{ + GArchInstruction **others; /* Instructions diverses liées */ + InstructionLinkType *types; /* Types de lien existants */ + size_t count; /* Nbre de sources affichées */ + size_t i; /* Boucle de parcours */ + + /** + * Si rien ne vient séparer les deux instructions, + * on ne peut pas créer de lien plus naturel que l'existant. + */ + + if (!g_arch_instruction_has_sources(instr)) + return; + + /** + * Si on se trouve à une extrémité, on ne se lie pas + * avec le voisin. + */ + + if (g_arch_instruction_is_return(prev)) + return; + + if (g_arch_instruction_get_flags(instr) & AIF_ROUTINE_START) + return; + + /** + * On s'assure que le lien naturel est valide. + */ + + count = g_arch_instruction_get_destinations(prev, &others, &types, NULL); + + for (i = 0; i < count; i++) + { + if (types[i] == ILT_EXEC_FLOW) break; + if (types[i] == ILT_JUMP) break; + if (types[i] == ILT_CASE_JUMP) break; + if (types[i] == ILT_LOOP) break; + } + + if (i < count) return; + + /** + * On vérifie que le lien n'existe pas déjà avant d'en créer un... + */ + count = g_arch_instruction_get_sources(instr, &others, &types); + + for (i = 0; i < count; i++) + { + if (others[i] == prev && types[i] == ILT_JUMP_IF_TRUE) break; + if (others[i] == prev && types[i] == ILT_JUMP_IF_FALSE) break; } + if (i == count) + g_arch_instruction_link_with(prev, instr, ILT_EXEC_FLOW); + } @@ -142,13 +213,19 @@ static void establish_links_for_instruction(GArchInstruction *instr, GArchInstru void establish_links_between_instructions(GArchInstruction *list, GBinFormat *format, GtkExtStatusBar *statusbar, bstatus_id_t id) { + GArchInstruction *prev; /* Itération précédente */ GArchInstruction *iter; /* Boucle de parcours */ + prev = NULL; + for (iter = list; iter != NULL; iter = g_arch_instruction_get_next_iter(list, iter, ~0/* FIXME */)) { + if (prev != NULL) + establish_natural_link(iter, prev); + prev = iter; establish_links_for_instruction(iter, list, format); diff --git a/src/analysis/disass/macro.c b/src/analysis/disass/macro.c index 218371b..087f1ae 100644 --- a/src/analysis/disass/macro.c +++ b/src/analysis/disass/macro.c @@ -297,6 +297,9 @@ static bool code_coverage_stop_here(const code_coverage *coverage, const vmpa2t { void *ptr; /* Résultat des recherches */ + if (!mrange_contains_addr(&coverage->range, addr)) + return true; + ptr = bsearch(addr, coverage->ends, coverage->ends_count, sizeof(vmpa2t), (__compar_fn_t)cmp_vmpa); @@ -532,10 +535,21 @@ static void find_next_hops(GArchInstruction *instrs, const vmpa2t *start, const InstructionLinkType *types; /* Type de lien entre lignes */ size_t dcount; /* Nombre de liens de dest. */ size_t i; /* Boucle de parcours #2 */ + size_t not_handled; /* Nombre d'éléments écartés */ + + printf(" ---- FN [ %p ] ---------------------------\n", info); + + + printf("CONTAINS ? %d\n", mrange_contains_addr(&coverage->range, start)); /* Si la position est déjà présente, on évite de boucler... */ if (!add_hop_into_branch(info, start)) + { + printf(" ++ !add 0x%08x\n", (unsigned int)start->virtual); return; + } + else + printf(" ++ add 0x%08x\n", (unsigned int)start->virtual); /* On suit le flot jusqu'à la prochaine bifurcation */ for (iter = g_arch_instruction_find_by_address(instrs, start, true); @@ -544,20 +558,43 @@ static void find_next_hops(GArchInstruction *instrs, const vmpa2t *start, const { range = g_arch_instruction_get_range(iter); + + if (code_coverage_stop_here(coverage, get_mrange_addr(range))) + printf(" ++ stop here 0x%08x\n", (unsigned int)range->addr.virtual); + if (code_coverage_stop_here(coverage, get_mrange_addr(range))) break; + + if (g_arch_instruction_has_sources(iter)) + add_hop_into_branch(info, get_mrange_addr(range)); + + + + if (g_arch_instruction_is_return(iter)) + printf(" ++ return 0x%08x\n", (unsigned int)range->addr.virtual); + if (g_arch_instruction_is_return(iter)) { iter = NULL; break; } + /* + if (!g_arch_instruction_has_destinations(iter)) + printf(" ++ no dest 0x%08x\n", (unsigned int)range->addr.virtual); + */ + if (!g_arch_instruction_has_destinations(iter)) continue; + + printf(" ++ dcount 0x%08x\n", (unsigned int)range->addr.virtual); + dcount = g_arch_instruction_get_destinations(iter, &dests, &types, NULL); + not_handled = 0; + for (i = 0; i < dcount; i++) { range = g_arch_instruction_get_range(dests[i]); @@ -577,19 +614,23 @@ static void find_next_hops(GArchInstruction *instrs, const vmpa2t *start, const break; default: + not_handled++; break; } } - break; + if (not_handled < dcount) + break; } /* Si on termine... */ if (iter != NULL) add_hop_into_branch(info, get_mrange_addr(range)); + printf(" ------- [ %p ] ---\n", info); + } @@ -614,6 +655,20 @@ static bool compute_first_common_addr(const branch_info *a, const branch_info *b result = false; + + printf("....................\n"); + + printf(" A :: "); + for (i = 0; i < a->count; i++) + printf("0x%08x ", a->hops[i].virtual); + printf("\n"); + + printf(" B :: "); + for (i = 0; i < b->count; i++) + printf("0x%08x ", b->hops[i].virtual); + printf("\n"); + + for (i = 0; i < a->count && !result; i++) if (is_addr_in_branch(b, &a->hops[i])) { @@ -621,6 +676,13 @@ static bool compute_first_common_addr(const branch_info *a, const branch_info *b copy_vmpa(c, &a->hops[i]); } + if (result) + printf(" N :: 0x%08x\n", (unsigned int)c->virtual); + else + printf(" N :: ----\n"); + + printf("....................\n"); + return result; } @@ -862,6 +924,7 @@ static GInstrBlock *build_instruction_blocks_ite(GArchInstruction *instrs, code_ GInstrBlock *block; /* Nouveau bloc mis en place */ has_common = compute_first_common_addr(true_branch, false_branch, next); + if (!has_common) printf(" === nothing in common\n"); if (!has_common) return NULL; result = g_virtual_block_new(); @@ -980,7 +1043,7 @@ static void add_instruction_blocks_except(GInstrBlock **result, GInstrBlock **ca * Remarques : - * * * ******************************************************************************/ - +#include "../../arch/instruction-int.h" static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_coverage *coverage) { GInstrBlock *result; /* Regroupement à retourner */ @@ -1059,11 +1122,25 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove case ILT_EXEC_FLOW: case ILT_JUMP: + + //break; + { + GArchInstruction *_saved0; + + _saved0 = first; + block = build_instruction_block_simple(instrs, coverage, &first, iter); + printf(" -- simple block JMP -- @ 0x%08x <-> 0x%08x\n", + (unsigned int)(_saved0 ? _saved0->range.addr.virtual : ~0), + (unsigned int)iter->range.addr.virtual); + fflush(NULL); + } DELAYED_BLOCK_ADDING(result, result_cached, block); range = g_arch_instruction_get_range(iter); - copy_vmpa(&next_addr, get_mrange_addr(range)); + compute_mrange_end_addr(range, &next_addr); + + first = NULL; break; @@ -1072,10 +1149,12 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove break; case ILT_JUMP_IF_TRUE: + printf("FIND TRUE BRANCH @ 0x%08x\n", (unsigned int)iter->range.addr.virtual); branch = &true_branch; break; case ILT_JUMP_IF_FALSE: + printf("FIND FALSE BRANCH @ 0x%08x\n", (unsigned int)iter->range.addr.virtual); branch = &false_branch; break; @@ -1097,10 +1176,13 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove /* Si on a une branche à compléter... */ if (branch != NULL) { - range = g_arch_instruction_get_range(iter); + range = g_arch_instruction_get_range(dests[i]); addr = get_mrange_addr(range); + printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); + printf("BUILD @ 0x%08x\n", (unsigned int)addr->virtual); find_next_hops(instrs, addr, coverage, branch); + printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n"); } @@ -1126,10 +1208,25 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove else if (true_branch.count > 0 || false_branch.count > 0) { block = build_instruction_block_simple(instrs, coverage, &first, iter); + + GArchInstruction *_saved1; + + _saved1 = first; + + + + printf(" -- branches -- %d vs %d\n", (int)true_branch.count, (int)false_branch.count); + + printf(" -- simple block ITE -- @ 0x%08x <-> 0x%08x\n", + (unsigned int)(_saved1 ? _saved1->range.addr.virtual : ~0), + (unsigned int)iter->range.addr.virtual); + fflush(NULL); DELAYED_BLOCK_ADDING(result, result_cached, block); group = build_instruction_blocks_ite(instrs, coverage, &true_branch, &false_branch, &next_addr); + printf(" --> group = %p - next = 0x%08x\n", group, next_addr.virtual); + if (group != NULL) { DELAYED_BLOCK_ADDING(result, result_cached, group); |