diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2013-02-24 17:24:32 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2013-02-24 17:24:32 (GMT) |
commit | f95e0761e1284b7ab48244452f56d96803c48b87 (patch) | |
tree | 55189a8ea17b533ac368198e8a456fdad777916d /src/analysis/disass | |
parent | 02c2cf555953f335a825e34c869c9999668fd42c (diff) |
Fixed a bug in loops detection.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@341 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/analysis/disass')
-rw-r--r-- | src/analysis/disass/loop.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/src/analysis/disass/loop.c b/src/analysis/disass/loop.c index 301f084..6fd73f2 100644 --- a/src/analysis/disass/loop.c +++ b/src/analysis/disass/loop.c @@ -196,6 +196,7 @@ 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) { + bool exit_track; /* Détermine la fin du parcours*/ GArchInstruction *iter; /* Boucle de parcours */ GArchInstruction **dests; /* Instr. visée par une autre */ InstructionLinkType *types; /* Type de lien entre lignes */ @@ -206,16 +207,23 @@ static void track_loops_in_code(GArchInstruction *list, vmpa_t start, vmpa_t end add_step_into_exec_flow(flow, start); + exit_track = false; + for (iter = g_arch_instruction_find_by_address(list, start, true); - iter != NULL; + iter != NULL && !exit_track; iter = g_arch_instruction_get_next_iter(list, iter, end)) { dcount = g_arch_instruction_get_destinations(iter, &dests, &types, NULL); + if (dcount == 0) continue; for (i = 0; i < dcount; i++) switch (types[i]) { case ILT_LOOP: + /** + * On est déjà passé par là, donc on peut arrêter le parcours courant. + */ + exit_track = true; break; case ILT_CALL: @@ -223,6 +231,12 @@ static void track_loops_in_code(GArchInstruction *list, vmpa_t start, vmpa_t end break; default: + /** + * 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); if (!is_new_exec_flow(flow, addr)) |