From fe3ac685849b69d87ad536e80d6f31d08c593eac Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Wed, 7 Oct 2015 21:18:39 +0000 Subject: Introduced code coverages to reduce search time. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@588 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 8 ++++++ src/analysis/disass/loop.c | 26 +++++++++++------- src/arch/processor-int.h | 4 +-- src/arch/processor.c | 66 ++++++++++++++++++++++++++-------------------- src/arch/processor.h | 10 +++++++ 5 files changed, 74 insertions(+), 40 deletions(-) diff --git a/ChangeLog b/ChangeLog index b98dfce..9f66771 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +15-10-07 Cyrille Bagard + + * src/analysis/disass/loop.c: + * src/arch/processor.c: + * src/arch/processor.h: + * src/arch/processor-int.h: + Introduce code coverages to reduce search time. + 15-10-06 Cyrille Bagard * src/arch/processor.c: diff --git a/src/analysis/disass/loop.c b/src/analysis/disass/loop.c index 30265c9..5f97981 100644 --- a/src/analysis/disass/loop.c +++ b/src/analysis/disass/loop.c @@ -34,16 +34,17 @@ /* Suit un flot d'exécution à la recherche de boucles. */ -static void track_loops_in_code(const GArchProcessor *, const mrange_t *, const vmpa2t *, memfield_t *); +static void track_loops_in_code(const GArchProcessor *, const instr_coverage *, const mrange_t *, const vmpa2t *, memfield_t *); /****************************************************************************** * * -* 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. * +* Paramètres : proc = ensemble d'instructions à parcourir. * +* coverage = zone de couverture où rechercher des instructions.* +* range = zone de couverture de la routine analysée. * +* start = adresse du début de l'analyse. * +* flow = ensemble des jalons de l'exécution du code. * * * * Description : Suit un flot d'exécution à la recherche de boucles. * * * @@ -53,7 +54,7 @@ static void track_loops_in_code(const GArchProcessor *, const mrange_t *, const * * ******************************************************************************/ -static void track_loops_in_code(const GArchProcessor *proc, const mrange_t *range, const vmpa2t *start, memfield_t *flow) +static void track_loops_in_code(const GArchProcessor *proc, const instr_coverage *coverage, const mrange_t *range, const vmpa2t *start, memfield_t *flow) { bool exit_track; /* Détermine la fin du parcours*/ GArchInstruction *iter; /* Boucle de parcours */ @@ -69,7 +70,7 @@ static void track_loops_in_code(const GArchProcessor *proc, const mrange_t *rang exit_track = false; - for (iter = g_arch_processor_find_instr_by_address(proc, start); + for (iter = g_arch_processor_find_covered_instr_by_address(proc, coverage, start); iter != NULL && !exit_track; iter = g_arch_instruction_get_next_iter(iter /* FIXME : list*/, iter, ~0)) { @@ -120,7 +121,7 @@ static void track_loops_in_code(const GArchProcessor *proc, const mrange_t *rang addr = get_mrange_addr(irange); next_flow = create_mem_field_from(flow); - track_loops_in_code(proc, range, addr, next_flow); + track_loops_in_code(proc, coverage, range, addr, next_flow); delete_mem_field(next_flow); break; @@ -150,7 +151,7 @@ static void track_loops_in_code(const GArchProcessor *proc, const mrange_t *rang else { next_flow = dup_mem_field(flow); - track_loops_in_code(proc, range, addr, next_flow); + track_loops_in_code(proc, coverage, range, addr, next_flow); delete_mem_field(next_flow); } @@ -186,14 +187,19 @@ void detect_loops_in_code(const GArchProcessor *proc, GBinRoutine **routines, si { size_t i; /* Boucle de parcours */ const mrange_t *range; /* Couverture d'une routine */ + const vmpa2t *start; /* Adresse de départ */ + const instr_coverage *coverage; /* Instructions couvertes */ memfield_t *flow; /* Flot d'exécution à suivre */ for (i = 0; i < count; i++) { range = g_binary_routine_get_range(routines[i]); + start = get_mrange_addr(range); + + coverage = g_arch_processor_find_coverage_by_address(proc, start); flow = create_mem_field(range); - track_loops_in_code(proc, range, get_mrange_addr(range), flow); + track_loops_in_code(proc, coverage, range, start, flow); delete_mem_field(flow); gtk_extended_status_bar_update_activity(statusbar, id, (i + 1) * 1.0 / count); diff --git a/src/arch/processor-int.h b/src/arch/processor-int.h index fcd7a52..19076a2 100644 --- a/src/arch/processor-int.h +++ b/src/arch/processor-int.h @@ -63,14 +63,14 @@ typedef GArchInstruction * (* disass_instr_fc) (const GArchProcessor *, GProcCon /* Couverture d'un groupe d'instructions */ -typedef struct _instr_coverage +struct _instr_coverage { mrange_t range; /* Couverture du groupement */ size_t start; /* Indice de départ */ size_t count; /* Quantité d'inclusions */ -} instr_coverage; +}; diff --git a/src/arch/processor.c b/src/arch/processor.c index c70d586..6b60c8c 100644 --- a/src/arch/processor.c +++ b/src/arch/processor.c @@ -72,9 +72,6 @@ static void g_arch_processor_add_new_coverage(GArchProcessor *, GArchInstruction /* Termine la définition d'un nouveau groupe d'instructions. */ static void g_arch_processor_finish_last_coverage(GArchProcessor *, GArchInstruction *, size_t); -/* Recherche un groupe d'instruction d'après son adresse. */ -static bool g_arch_processor_find_coverage_by_address(const GArchProcessor *, const vmpa2t *, size_t *, size_t *); - @@ -399,20 +396,18 @@ static void g_arch_processor_finish_last_coverage(GArchProcessor *proc, GArchIns * * * Paramètres : proc = processeur recensant diverses instructions. * * addr = position en mémoire ou physique à chercher. * -* start = indice de départ du groupe concerné trouvé. [OUT] * -* end = indice de fin du groupe d'instructions visées. [OUT] * * * * Description : Recherche un groupe d'instruction d'après son adresse. * * * -* Retour : Bilan de la recherche menée. * +* Retour : Couverture trouvée ou NULL si aucune. * * * * Remarques : - * * * ******************************************************************************/ -static bool g_arch_processor_find_coverage_by_address(const GArchProcessor *proc, const vmpa2t *addr, size_t *start, size_t *count) +const instr_coverage *g_arch_processor_find_coverage_by_address(const GArchProcessor *proc, const vmpa2t *addr) { - bool result; /* Bilan à retourner */ + instr_coverage *result; /* Trouvaille à retourner */ void *ptr; /* Résultat des recherches */ int search_for_coverage_by_addr(const vmpa2t *a, const instr_coverage *c) @@ -428,14 +423,7 @@ static bool g_arch_processor_find_coverage_by_address(const GArchProcessor *proc ptr = bsearch(addr, proc->coverages, proc->cov_count, sizeof(instr_coverage), (__compar_fn_t)search_for_coverage_by_addr); - if (ptr != NULL) - { - result = true; - *start = ((instr_coverage *)ptr)->start; - *count = ((instr_coverage *)ptr)->count; - } - else - result = false; + result = ((instr_coverage *)ptr); return result; @@ -543,8 +531,37 @@ GArchInstruction *g_arch_processor_get_disassembled_instructions(const GArchProc GArchInstruction *g_arch_processor_find_instr_by_address(const GArchProcessor *proc, const vmpa2t *addr) { GArchInstruction *result; /* Trouvaille à retourner */ - size_t cov_start; /* Début d'un groupe ciblé */ - size_t cov_count; /* Nombre d'éléments à tester */ + const instr_coverage *coverage; /* Couverture fine à fouiller */ + + coverage = g_arch_processor_find_coverage_by_address(proc, addr); + + if (coverage != NULL) + result = g_arch_processor_find_covered_instr_by_address(proc, coverage, addr); + else + result = NULL; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : proc = processeur recensant diverses instructions. * +* coverage = zone de couverture fine à fouiller. * +* addr = position en mémoire ou physique à chercher. * +* * +* Description : Recherche rapidement une instruction d'après son adresse. * +* * +* Retour : Instruction trouvée à l'adresse donnée, NULL si aucune. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *g_arch_processor_find_covered_instr_by_address(const GArchProcessor *proc, const instr_coverage *coverage, const vmpa2t *addr) +{ + GArchInstruction *result; /* Trouvaille à retourner */ void *ptr; /* Résultat des recherches */ int search_for_instr_by_addr(const vmpa2t *a, const GArchInstruction **b) @@ -557,17 +574,10 @@ GArchInstruction *g_arch_processor_find_instr_by_address(const GArchProcessor *p } + ptr = bsearch(addr, &proc->instructions[coverage->start], coverage->count, + sizeof(GArchInstruction *), (__compar_fn_t)search_for_instr_by_addr); - if (g_arch_processor_find_coverage_by_address(proc, addr, &cov_start, &cov_count)) - { - ptr = bsearch(addr, &proc->instructions[cov_start], cov_count, - sizeof(GArchInstruction *), (__compar_fn_t)search_for_instr_by_addr); - - result = (ptr != NULL ? *((GArchInstruction **)ptr) : NULL); - - } - else - result = NULL; + result = (ptr != NULL ? *((GArchInstruction **)ptr) : NULL); return result; diff --git a/src/arch/processor.h b/src/arch/processor.h index f7d474a..45b9012 100644 --- a/src/arch/processor.h +++ b/src/arch/processor.h @@ -81,15 +81,25 @@ GArchInstruction *g_arch_processor_disassemble(const GArchProcessor *, GProcCont /* ------------------ MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES ------------------ */ +/* Couverture d'un groupe d'instructions */ +typedef struct _instr_coverage instr_coverage; + + /* Note les instructions désassemblées avec une architecture. */ void g_arch_processor_set_disassembled_instructions(GArchProcessor *, GArchInstruction *); /* Fournit les instructions désassemblées pour une architecture. */ GArchInstruction *g_arch_processor_get_disassembled_instructions(const GArchProcessor *); +/* Recherche un groupe d'instruction d'après son adresse. */ +const instr_coverage *g_arch_processor_find_coverage_by_address(const GArchProcessor *, const vmpa2t *); + /* Recherche une instruction d'après son adresse. */ GArchInstruction *g_arch_processor_find_instr_by_address(const GArchProcessor *, const vmpa2t *); +/* Recherche rapidement une instruction d'après son adresse. */ +GArchInstruction *g_arch_processor_find_covered_instr_by_address(const GArchProcessor *, const instr_coverage *, const vmpa2t *); + /* Fournit l'instruction qui en précède une autre. */ GArchInstruction *g_arch_processor_get_prev_instr(const GArchProcessor *, const GArchInstruction *); -- cgit v0.11.2-87-g4458