summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-04-04 17:35:53 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-04-04 17:35:53 (GMT)
commitc9391d0a1d42a05c72fd1c909a00774561ac9f81 (patch)
treeac19dc8ff1b7ca2aadd3a3af804e72897738806f
parent46e46c2894ea92502734c7bbd1cbcc6cb2e46d17 (diff)
Detected loops in disassembled instructions once again.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@502 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
-rw-r--r--ChangeLog12
-rw-r--r--src/analysis/disass/disassembler.c9
-rw-r--r--src/analysis/disass/loop.c91
-rw-r--r--src/analysis/disass/loop.h3
-rw-r--r--src/analysis/disass/rank.c63
5 files changed, 142 insertions, 36 deletions
diff --git a/ChangeLog b/ChangeLog
index 0845512..e961e22 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
15-04-04 Cyrille Bagard <nocbos@gmail.com>
+ * src/analysis/disass/disassembler.c:
+ Extend the disassembling process.
+
+ * src/analysis/disass/loop.c:
+ * src/analysis/disass/loop.h:
+ Detect loops in disassembled instructions once again.
+
+ * src/analysis/disass/rank.c:
+ Add debug code to display assigned ranks.
+
+15-04-04 Cyrille Bagard <nocbos@gmail.com>
+
* src/analysis/block.c:
* src/analysis/block.h:
* src/analysis/block-int.h:
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index 50c71da..1227e84 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -323,12 +323,19 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta
+ /* Troisième étape */
+ id = gtk_extended_status_bar_push(statusbar, _("Detecting loops..."), true);
+ detect_loops_in_code(proc, routines, routines_count, statusbar, id);
+ gtk_extended_status_bar_remove(statusbar, id);
+ ///
- /* Troisième étape */
+
+
+ /* Quatrième étape */
id = gtk_extended_status_bar_push(statusbar, _("Establishing links..."), true);
diff --git a/src/analysis/disass/loop.c b/src/analysis/disass/loop.c
index 0a06748..0cb346b 100644
--- a/src/analysis/disass/loop.c
+++ b/src/analysis/disass/loop.c
@@ -30,14 +30,10 @@
-#include "../../arch/instruction.h"
-
-
-
/* Suivi du flot d'exécution */
typedef struct _exec_flow
{
- vmpa_t *steps; /* Jalons dans l'exécution */
+ vmpa2t *steps; /* Jalons dans l'exécution */
size_t count; /* Quantité de ces points */
} exec_flow;
@@ -53,13 +49,13 @@ static exec_flow *dup_exec_flow(const exec_flow *);
static void delete_exec_flow(exec_flow *);
/* Recherche si le chemin d'exécution a déjà mené à une adresse. */
-static bool is_new_exec_flow(const exec_flow *, vmpa_t);
+static bool is_new_exec_flow(const exec_flow *, const vmpa2t *);
/* Ajoute une adresse jalon dans un flot d'exécution. */
-static void add_step_into_exec_flow(exec_flow *, vmpa_t);
+static void add_step_into_exec_flow(exec_flow *, const vmpa2t *);
/* Suit un flot d'exécution à la recherche de boucles. */
-static void track_loops_in_code(GArchInstruction *, vmpa_t, vmpa_t, exec_flow *);
+static void track_loops_in_code(const GArchProcessor *, const mrange_t *, const vmpa2t *, exec_flow *);
@@ -104,8 +100,8 @@ static exec_flow *dup_exec_flow(const exec_flow *src)
result = (exec_flow *)calloc(1, sizeof(exec_flow));
- result->steps = (vmpa_t *)malloc(src->count * sizeof(vmpa_t));
- memcpy(result->steps, src->steps, src->count * sizeof(vmpa_t));
+ result->steps = (vmpa2t *)malloc(src->count * sizeof(vmpa2t));
+ memcpy(result->steps, src->steps, src->count * sizeof(vmpa2t));
result->count = src->count;
@@ -128,7 +124,8 @@ static exec_flow *dup_exec_flow(const exec_flow *src)
static void delete_exec_flow(exec_flow *flow)
{
- free(flow->steps);
+ if (flow->steps != NULL)
+ free(flow->steps);
free(flow);
@@ -148,12 +145,12 @@ static void delete_exec_flow(exec_flow *flow)
* *
******************************************************************************/
-static bool is_new_exec_flow(const exec_flow *flow, vmpa_t addr)
+static bool is_new_exec_flow(const exec_flow *flow, const vmpa2t *addr)
{
void *ret; /* Conclusion d'une recherche */
- ret = bsearch(&addr, flow->steps, flow->count,
- sizeof(vmpa_t), (__compar_fn_t)compare_vmpa);
+ ret = bsearch(addr, flow->steps, flow->count,
+ sizeof(vmpa2t), (__compar_fn_t)cmp_vmpa);
return (ret == NULL);
@@ -173,19 +170,19 @@ static bool is_new_exec_flow(const exec_flow *flow, vmpa_t addr)
* *
******************************************************************************/
-static void add_step_into_exec_flow(exec_flow *flow, vmpa_t addr)
+static void add_step_into_exec_flow(exec_flow *flow, const vmpa2t *addr)
{
- flow->steps = (vmpa_t *)realloc(flow->steps, ++flow->count * sizeof(vmpa_t));
- flow->steps[flow->count - 1] = addr;
+ flow->steps = (vmpa2t *)realloc(flow->steps, ++flow->count * sizeof(vmpa2t));
+ copy_vmpa(&flow->steps[flow->count - 1], addr);
- qsort(flow->steps, flow->count, sizeof(vmpa_t), (__compar_fn_t)compare_vmpa);
+ qsort(flow->steps, flow->count, sizeof(vmpa2t), (__compar_fn_t)cmp_vmpa);
}
/******************************************************************************
* *
-* Paramètres : list = ensemble d'instructions à parcourir. *
+* 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. *
@@ -198,28 +195,40 @@ static void add_step_into_exec_flow(exec_flow *flow, vmpa_t addr)
* *
******************************************************************************/
-static void track_loops_in_code(GArchInstruction *list, vmpa_t start, vmpa_t end, exec_flow *flow)
+static void track_loops_in_code(const GArchProcessor *proc, const mrange_t *range, const vmpa2t *start, exec_flow *flow)
{
bool exit_track; /* Détermine la fin du parcours*/
GArchInstruction *iter; /* Boucle de parcours */
+ const mrange_t *irange; /* Emplacement d'instruction */
GArchInstruction **dests; /* Instr. visée par une autre */
InstructionLinkType *types; /* Type de lien entre lignes */
size_t dcount; /* Nombre de liens de dest. */
size_t i; /* Boucle de parcours */
- vmpa_t addr; /* Prochaine adresse de saut */
+ const vmpa2t *addr; /* Prochaine adresse de saut */
exec_flow *next_flow; /* Suite de l'exécution */
add_step_into_exec_flow(flow, start);
exit_track = false;
- for (iter = g_arch_instruction_find_by_address(list, start, true);
+ for (iter = g_arch_processor_find_instr_by_address(proc, start);
iter != NULL && !exit_track;
- iter = g_arch_instruction_get_next_iter(list, iter, end))
+ iter = g_arch_instruction_get_next_iter(iter /* FIXME : list*/, iter, ~0))
{
+ /* L'instruction sort-elle des clous ? */
+
+ irange = g_arch_instruction_get_range(iter);
+
+ if (!mrange_contains_mrange(range, irange))
+ break;
+
+ /* Fin de parcours ? */
+
if (g_arch_instruction_is_return(iter))
break;
+ /* Analyse des destinations */
+
dcount = g_arch_instruction_get_destinations(iter, &dests, &types, NULL);
if (dcount == 0) continue;
@@ -233,18 +242,31 @@ static void track_loops_in_code(GArchInstruction *list, vmpa_t start, vmpa_t end
exit_track = true;
break;
- case ILT_CALL:
case ILT_CATCH_EXCEPTION:
+
+ irange = g_arch_instruction_get_range(dests[i]);
+ addr = get_mrange_addr(irange);
+
+ next_flow = create_exec_flow();
+ track_loops_in_code(proc, range, addr, next_flow);
+ delete_exec_flow(next_flow);
+
break;
- default:
+ case ILT_EXEC_FLOW:
+ case ILT_JUMP:
+ case ILT_CASE_JUMP:
+ case ILT_JUMP_IF_TRUE:
+ case ILT_JUMP_IF_FALSE:
+
/**
* On se lance dans d'autres suivis qui vont parcourir le reste des
* instructions, donc on peut arrêter le parcours courant ici.
*/
exit_track = true;
- g_arch_instruction_get_location(dests[i], NULL, NULL, &addr);
+ irange = g_arch_instruction_get_range(dests[i]);
+ addr = get_mrange_addr(irange);
if (!is_new_exec_flow(flow, addr))
types[i] = ILT_LOOP;
@@ -252,12 +274,15 @@ static void track_loops_in_code(GArchInstruction *list, vmpa_t start, vmpa_t end
else
{
next_flow = dup_exec_flow(flow);
- track_loops_in_code(list, addr, end, next_flow);
+ track_loops_in_code(proc, range, addr, next_flow);
delete_exec_flow(next_flow);
}
break;
+ default:
+ break;
+
}
}
@@ -267,7 +292,7 @@ static void track_loops_in_code(GArchInstruction *list, vmpa_t start, vmpa_t end
/******************************************************************************
* *
-* Paramètres : list = ensemble d'instructions à relier. *
+* Paramètres : proc = ensemble d'instructions à relier. *
* routines = prototypes existants à insérer. *
* count = quantité de ces prototypes. *
* statusbar = barre de statut avec progression à mettre à jour.*
@@ -281,20 +306,18 @@ static void track_loops_in_code(GArchInstruction *list, vmpa_t start, vmpa_t end
* *
******************************************************************************/
-void detect_loops_in_code(GArchInstruction *list, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id)
+void detect_loops_in_code(const GArchProcessor *proc, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id)
{
size_t i; /* Boucle de parcours */
- vmpa_t start; /* Adresse de départ */
- vmpa_t end; /* Adresse de fin */
+ const mrange_t *range; /* Couverture d'une routine */
exec_flow *flow; /* Flot d'exécution à suivre */
for (i = 0; i < count; i++)
{
- start = g_binary_routine_get_address(routines[i]);
- end = start + g_binary_routine_get_size(routines[i]);
+ range = g_binary_routine_get_range(routines[i]);
flow = create_exec_flow();
- track_loops_in_code(list, start, end, flow);
+ track_loops_in_code(proc, range, get_mrange_addr(range), flow);
delete_exec_flow(flow);
gtk_extended_status_bar_update_activity(statusbar, id, (i + 1) * 1.0 / count);
diff --git a/src/analysis/disass/loop.h b/src/analysis/disass/loop.h
index 7c8d7b3..f4b05cf 100644
--- a/src/analysis/disass/loop.h
+++ b/src/analysis/disass/loop.h
@@ -26,12 +26,13 @@
#include "../routine.h"
+#include "../../arch/processor.h"
#include "../../gtkext/gtkextstatusbar.h"
/* Détecte les boucles dans du code machine. */
-void detect_loops_in_code(GArchInstruction *, GBinRoutine **, size_t, GtkExtStatusBar *, bstatus_id_t);
+void detect_loops_in_code(const GArchProcessor *, GBinRoutine **, size_t, GtkExtStatusBar *, bstatus_id_t);
diff --git a/src/analysis/disass/rank.c b/src/analysis/disass/rank.c
index 94494d5..758e15d 100644
--- a/src/analysis/disass/rank.c
+++ b/src/analysis/disass/rank.c
@@ -202,6 +202,69 @@ void rank_routines_blocks(GBinRoutine **routines, size_t count, GtkExtStatusBar
g_instr_block_visit(main_block, (instr_block_visitor_cb)rank_flow_block, main_block);
+
+
+ printf("===== BLOCK(S) xXXx ======\n");
+
+
+ bool visit_ranked_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 (rank = %u)",
+ (unsigned int)start.virtual,
+ (unsigned int)end.virtual,
+ g_flow_block_get_rank(G_FLOW_BLOCK(blk)));
+
+ }
+
+ printf("\n");
+
+ if (order == BVO_IN) (*indent)++;
+ break;
+
+ case BVO_OUT:
+ (*indent)--;
+ break;
+
+ }
+
+ return true;
+
+ }
+
+ g_instr_block_visit(main_block, (instr_block_visitor_cb)visit_ranked_block, (int []){ 0 });
+
+ printf("\n");
+
+
+
+
+
+
+
+
+
+
+
+
}
}