From 276ec9c9b8a3b283751c8d8c59f70c3fc88d5b0d Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 21 Mar 2015 15:06:14 +0000 Subject: Restored a limited but working version of basic blocks definitions. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@493 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 8 ++++ src/analysis/blocks/flow.c | 29 +++++++++----- src/analysis/blocks/flow.h | 2 +- src/analysis/disass/disassembler.c | 22 +++++++++++ src/analysis/disass/macro.c | 79 +++++++++++++++++++++++++++++++------- 5 files changed, 116 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index e491d22..64ba27d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +15-03-21 Cyrille Bagard + + * src/analysis/blocks/flow.c: + * src/analysis/blocks/flow.h: + * src/analysis/disass/disassembler.c: + * src/analysis/disass/macro.c: + Restore a limited but working version of basic blocks definitions. + 15-03-19 Cyrille Bagard * src/arch/raw.c: diff --git a/src/analysis/blocks/flow.c b/src/analysis/blocks/flow.c index cd435aa..7777623 100644 --- a/src/analysis/blocks/flow.c +++ b/src/analysis/blocks/flow.c @@ -70,7 +70,7 @@ static void g_flow_block_dispose(GFlowBlock *); static void g_flow_block_finalize(GFlowBlock *); /* Recherche le bloc contenant une adresse donnée. */ -static GInstrBlock *g_flow_block_find_by_addr(const GFlowBlock *, vmpa_t, bool); +static GInstrBlock *g_flow_block_find_by_addr(const GFlowBlock *, const vmpa2t *, bool); /* Parcourt le bloc d'instructions dans un ordre donné. */ static bool g_flow_block_visit(GFlowBlock *, instr_block_visitor_cb, void *); @@ -225,7 +225,7 @@ GInstrBlock *g_flow_block_new(GArchInstruction *instrs, GArchInstruction *first, g_object_ref(G_OBJECT(result->first)); g_object_ref(G_OBJECT(result->last)); - g_flow_block_compute_regs_access(result); + //g_flow_block_compute_regs_access(result); return G_INSTR_BLOCK(result); @@ -325,15 +325,18 @@ void g_flow_block_set_next_rank(GFlowBlock *block, unsigned int rank) * * ******************************************************************************/ -static GInstrBlock *g_flow_block_find_by_addr(const GFlowBlock *block, vmpa_t addr, bool final) +static GInstrBlock *g_flow_block_find_by_addr(const GFlowBlock *block, const vmpa2t *addr, bool final) { GInstrBlock *result; /* Resultat à retourner */ - vmpa_t start; /* Adresse de début du bloc */ - vmpa_t end; /* Adresse de fin du bloc */ + vmpa2t start; /* Adresse de début du bloc */ + vmpa2t end; /* Adresse de fin du bloc */ + mrange_t range; /* Couverture globale */ g_flow_block_get_boundary_addresses(block, &start, &end); - if (start <= addr && addr <= end) + init_mrange(&range, &start, compute_vmpa_diff(&start, &end)); + + if (mrange_contains_addr(&range, addr)) result = G_INSTR_BLOCK(block); else @@ -566,13 +569,21 @@ void g_flow_block_get_boundary(const GFlowBlock *block, GArchInstruction **first * * ******************************************************************************/ -void g_flow_block_get_boundary_addresses(const GFlowBlock *block, vmpa_t *start, vmpa_t *end) +void g_flow_block_get_boundary_addresses(const GFlowBlock *block, vmpa2t *start, vmpa2t *end) { + const mrange_t *range; /* Couverture d'instruction */ + if (start != NULL) - g_arch_instruction_get_location(block->first, NULL, NULL, start); + { + range = g_arch_instruction_get_range(block->first); + copy_vmpa(start, get_mrange_addr(range)); + } if (end != NULL) - g_arch_instruction_get_location(block->last, NULL, NULL, end); + { + range = g_arch_instruction_get_range(block->last); + copy_vmpa(end, get_mrange_addr(range)); + } } diff --git a/src/analysis/blocks/flow.h b/src/analysis/blocks/flow.h index a534a69..cc32834 100644 --- a/src/analysis/blocks/flow.h +++ b/src/analysis/blocks/flow.h @@ -89,7 +89,7 @@ GArchInstruction *g_flow_block_get_all_instructions_list(const GFlowBlock *); void g_flow_block_get_boundary(const GFlowBlock *, GArchInstruction **, GArchInstruction **); /* Fournit les adresses limites d'un bloc d'exécution. */ -void g_flow_block_get_boundary_addresses(const GFlowBlock *, vmpa_t *, vmpa_t *); +void g_flow_block_get_boundary_addresses(const GFlowBlock *, vmpa2t *, vmpa2t *); /* Détermine si un bloc peut conduire à un autre. */ bool g_flow_block_is_looping_to(GFlowBlock *, const GInstrBlock *, GFlowBlock *); diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c index 4b976c3..95d95d0 100644 --- a/src/analysis/disass/disassembler.c +++ b/src/analysis/disass/disassembler.c @@ -320,6 +320,28 @@ G_BIN_FORMAT(g_loaded_binary_get_format(disass->binary) + + + + /* Cinquième étape */ + + id = gtk_extended_status_bar_push(statusbar, _("Grouping routines instructions..."), true); + + //qsort(routines, routines_count, sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_rcompare); + + group_routines_instructions(*disass->instrs, routines, routines_count, statusbar, id); + + gtk_extended_status_bar_remove(statusbar, id); + + //run_plugins_on_binary(disass->binary, PGA_BINARY_GROUPED, true); + + + + + + + + /* Septième étape */ //id = gtk_extended_status_bar_push(statusbar, _("Printing disassembled code..."), true); diff --git a/src/analysis/disass/macro.c b/src/analysis/disass/macro.c index 1045eb2..218371b 100644 --- a/src/analysis/disass/macro.c +++ b/src/analysis/disass/macro.c @@ -40,13 +40,13 @@ /* Bornes d'une zone à couvrir */ typedef struct _code_coverage { - vmpa2t start; /* Position de départ */ + mrange_t range; /* Couverture totale */ vmpa2t *ends; /* Positions butoir de fin */ size_t ends_count; /* Quantité de fins possibles */ unsigned long *processed; /* Octets traités dans la zone */ - size_t length; /* Taille de la cartographie */ + size_t allocated; /* Taille de la cartographie */ } code_coverage; @@ -199,7 +199,7 @@ static code_coverage *create_code_coverage(const mrange_t *range) result = (code_coverage *)calloc(1, sizeof(code_coverage)); - copy_vmpa(&result->start, get_mrange_addr(range)); + copy_mrange(&result->range, range); result->ends = (vmpa2t *)calloc(1, sizeof(vmpa2t)); result->ends_count = 1; @@ -212,7 +212,7 @@ static code_coverage *create_code_coverage(const mrange_t *range) if (length % sizeof(unsigned long) != 0) requested++; result->processed = (unsigned long *)calloc(requested, sizeof(unsigned long)); - result->length = requested; + result->allocated = requested; return result; @@ -239,7 +239,7 @@ static code_coverage *dup_code_coverage(const code_coverage *src, const vmpa2t * result = (code_coverage *)calloc(1, sizeof(code_coverage)); - copy_vmpa(&result->start, &src->start); + copy_mrange(&result->range, &src->range); result->ends = (vmpa2t *)calloc(src->ends_count, sizeof(vmpa2t)); result->ends_count = src->ends_count; @@ -247,10 +247,10 @@ static code_coverage *dup_code_coverage(const code_coverage *src, const vmpa2t * for (i = 0; i < result->ends_count; i++) copy_vmpa(&result->ends[i], &src->ends[i]); - result->processed = (unsigned long *)calloc(src->length, sizeof(unsigned long)); - result->length = src->length; + result->processed = (unsigned long *)calloc(src->allocated, sizeof(unsigned long)); + result->allocated = src->allocated; - memcpy(result->processed, src->processed, src->length * sizeof(unsigned long)); + memcpy(result->processed, src->processed, src->allocated * sizeof(unsigned long)); return result; @@ -359,8 +359,8 @@ static bool is_range_processed_in_coverage(const code_coverage *coverage, const size_t index; /* Cellule de tableau visée */ unsigned int remaining; /* Nombre de bits restants */ - diff = compute_vmpa_diff(&coverage->start, get_mrange_addr(range)); - assert(diff < coverage->length); + diff = compute_vmpa_diff(get_mrange_addr(&coverage->range), get_mrange_addr(range)); + assert(diff < get_mrange_length(&coverage->range)); index = diff / (sizeof(unsigned long) * 8); remaining = diff % (sizeof(unsigned long) * 8); @@ -394,8 +394,8 @@ static void mark_range_as_processed_in_coverage(code_coverage *coverage, const G range = g_arch_instruction_get_range(instr); - diff = compute_vmpa_diff(&coverage->start, get_mrange_addr(range)); - assert(diff < coverage->length); + diff = compute_vmpa_diff(get_mrange_addr(&coverage->range), get_mrange_addr(range)); + assert(diff < get_mrange_length(&coverage->range)); index = diff / (sizeof(unsigned long) * 8); remaining = diff % (sizeof(unsigned long) * 8); @@ -1012,9 +1012,9 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove last = NULL; init_branch_info(&main_branch); - find_next_hops(instrs, &coverage->start, coverage, &main_branch); + find_next_hops(instrs, get_mrange_addr(&coverage->range), coverage, &main_branch); - for (iter = g_arch_instruction_find_by_address(instrs, &coverage->start, true); + for (iter = g_arch_instruction_find_by_address(instrs, get_mrange_addr(&coverage->range), true); iter != NULL; ) { @@ -1209,11 +1209,62 @@ void group_routines_instructions(GArchInstruction *list, GBinRoutine **routines, { range = g_binary_routine_get_range(routines[i]); + printf("===== BLOCK(S) for 0x%08x ======\n", range->addr.virtual); + coverage = create_code_coverage(range); block = build_instruction_blocks(list, coverage); g_binary_routine_set_basic_blocks(routines[i], block); + + bool visit_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", + (unsigned int)start.virtual, + (unsigned int)end.virtual); + + } + + printf("\n"); + + if (order == BVO_IN) (*indent)++; + break; + + case BVO_OUT: + (*indent)++; + break; + + } + + return true; + + } + + g_instr_block_visit(block, (instr_block_visitor_cb)visit_block, (int []){ 0 }); + + printf("\n"); + + + delete_code_coverage(coverage); gtk_extended_status_bar_update_activity(statusbar, id, (i + 1) * 1.0 / count); -- cgit v0.11.2-87-g4458