summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-10-07 21:18:39 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-10-07 21:18:39 (GMT)
commitfe3ac685849b69d87ad536e80d6f31d08c593eac (patch)
tree7522f5cf0a259656c6aff47a39b442001fd7911a
parentf9c4cfc72cd8d7eb08ded8287fc5af1497567f8b (diff)
Introduced code coverages to reduce search time.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@588 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
-rw-r--r--ChangeLog8
-rw-r--r--src/analysis/disass/loop.c26
-rw-r--r--src/arch/processor-int.h4
-rw-r--r--src/arch/processor.c66
-rw-r--r--src/arch/processor.h10
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 <nocbos@gmail.com>
+
+ * 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 <nocbos@gmail.com>
* 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 *);