From 7806ff93441318ad1f724f0b586383b61c4af859 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Tue, 5 May 2015 12:30:14 +0000
Subject: Fixed a bug when creating natural execution flows.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@526 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                          |  14 ++++
 src/analysis/disass/disassembler.c |  30 ++++----
 src/analysis/disass/links.c        | 146 +------------------------------------
 src/analysis/disass/macro.c        |   9 ++-
 src/arch/link.c                    |  10 ++-
 5 files changed, 46 insertions(+), 163 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 7a1bd49..e18bb91 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+15-05-05  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/analysis/disass/disassembler.c:
+	Reorder the disassembling steps for more sanity.
+
+	* src/analysis/disass/links.c:
+	Fix a bug when creating natural execution flows.
+
+	* src/analysis/disass/macro.c:
+	Fix a bug when following the execution jumps to create basic blocks.
+
+	* src/arch/link.c:
+	Improve the content of debug messages.
+
 15-05-04  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/gtkext/graph/edge.c:
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index 7b6c63e..a779dd1 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -342,23 +342,9 @@ 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);
 
-    ///
 
-    // plugins //////////////////////////
-    process_disassembly_event(PGA_DISASSEMBLY_LOOPS, disass->binary);
-
-
-
-
-    /* Quatrième étape */
+    /* Troisième étape */
 
     id = gtk_extended_status_bar_push(statusbar, _("Establishing links..."), true);
 
@@ -388,6 +374,20 @@ G_BIN_FORMAT(g_loaded_binary_get_format(disass->binary)
 
 
 
+    /* Quatriè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);
+
+    ///
+
+    // plugins //////////////////////////
+    process_disassembly_event(PGA_DISASSEMBLY_LOOPS, disass->binary);
+
+
 
 
 
diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c
index 06b6b03..545afb1 100644
--- a/src/analysis/disass/links.c
+++ b/src/analysis/disass/links.c
@@ -176,7 +176,7 @@ static void establish_natural_link(GArchInstruction *instr, GArchInstruction *pr
         if (types[i] == ILT_LOOP) break;
     }
 
-    if (i < count) return;
+    if (count > 0 && i < count) return;
 
     /**
      * On vérifie que le lien n'existe pas déjà avant d'en créer un...
@@ -233,147 +233,3 @@ void establish_links_between_instructions(GArchInstruction *list, GBinFormat *fo
     }
 
 }
-
-
-
-
-
-
-
-
-
-
-
-
-#if 0
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : list      = ensemble d'instructions à relier.                *
-*                routines  = prototypes existants à insérer.                  *
-*                count     = quantité de ces prototypes.                      *
-*                statusbar = barre de statut avec progression à mettre à jour.*
-*                id        = identifiant du message affiché à l'utilisateur.  *
-*                                                                             *
-*  Description : Etablit les liens entres les différentes lignes de code.     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void establish_links_between_lines(GArchInstruction *list, 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              */
-    GArchInstruction *iter;                 /* Boucle de parcours          */
-    vmpa_t addr;                            /* Adresse référencée          */
-    InstructionLinkType type;               /* Type de référence           */
-    GArchInstruction *target;               /* Ligne visée par la référence*/
-    GArchInstruction *prev;                 /* Instruction précédente      */
-
-    for (i = 0; i < count; i++)
-    {
-        start = g_binary_routine_get_address(routines[i]);
-        end = start + g_binary_routine_get_size(routines[i]);
-
-        /* Définition de toutes les destinations */
-        for (iter = g_arch_instruction_find_by_address(list, start, true);
-             iter != NULL;
-             iter = g_arch_instruction_get_next_iter(list, iter, end))
-        {
-            type = g_arch_instruction_get_link(iter, &addr);
-
-            switch (type)
-            {
-                case ILT_NONE:
-                    break;
-
-                case ILT_JUMP:
-
-                    target = g_arch_instruction_find_by_address(list, addr, true);
-
-                    if (target != NULL)
-                        g_arch_instruction_link_with(iter, target, type);
-
-                    break;
-
-                case ILT_JUMP_IF_FALSE:
-                    break;
-
-                case ILT_JUMP_IF_TRUE:
-
-                    target = g_arch_instruction_find_by_address(list, addr, true);
-
-                    if (target != NULL)
-                    {
-                        g_arch_instruction_link_with(iter, target, type);
-
-                        target = g_arch_instruction_get_next_iter(list, iter, end);
-                        if (target != NULL)
-                            g_arch_instruction_link_with(iter, target, ILT_JUMP_IF_FALSE);
-
-                    }
-
-                    break;
-
-                case ILT_CALL:
-
-                    target = g_arch_instruction_find_by_address(list, addr, true);
-
-                    if (target != NULL)
-                        g_arch_instruction_link_with(iter, target, type);
-
-                    break;
-
-                default:
-                    /**
-                     * Note pour GCC : à ce stade du désassemblage, ILT_CASE_JUMP et
-                     * ILT_CATCH_EXCEPTION ne peuvent être présentes, car ne provenant
-                     * que de greffons. Pour ILT_EXEC_FLOW, sa seule insertion est ici, plus bas.
-                     */
-                    break;
-
-            }
-
-        }
-
-        /* Rattachement de deux blocs selon le flux normal */
-
-        iter = g_arch_instruction_find_by_address(list, start, true);
-
-        if (iter == NULL)
-            printf("no match for 0x%08llx\n", start);
-
-        if (iter != NULL)
-
-        for (iter = g_arch_instruction_get_next_iter(list, iter, end);
-             iter != NULL;
-             iter = g_arch_instruction_get_next_iter(list, iter, end))
-        {
-            if (!g_arch_instruction_has_sources(iter))
-                continue;
-
-            prev = g_arch_instruction_get_prev_iter(list, iter);
-
-            if (g_arch_instruction_is_return(prev))
-                continue;
-
-            if (!g_arch_instruction_has_destinations(prev))
-                g_arch_instruction_link_with(prev, iter, ILT_EXEC_FLOW);
-
-        }
-
-        gtk_extended_status_bar_update_activity(statusbar, id, (i + 1) * 1.0 / count);
-
-    }
-
-}
-
-
-
-
-#endif
- 
diff --git a/src/analysis/disass/macro.c b/src/analysis/disass/macro.c
index 9527457..b478c74 100644
--- a/src/analysis/disass/macro.c
+++ b/src/analysis/disass/macro.c
@@ -1276,8 +1276,13 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove
                 }
                     DELAYED_BLOCK_ADDING(result, result_cached, block);
 
-                    range = g_arch_instruction_get_range(iter);
-                    compute_mrange_end_addr(range, &next_addr);
+                    /**
+                     * La prochaine adresse d'analyse est celle visée par l'instruction !
+                     * Pour les sauts naturels, ça ne change rien ; ce n'est pas le cas
+                     * pour les sauts explicites.
+                     */
+                    range = g_arch_instruction_get_range(dests[i]);
+                    copy_vmpa(&next_addr, get_mrange_addr(range));
 
                     first = NULL;
 
diff --git a/src/arch/link.c b/src/arch/link.c
index 02cda22..3b74e5c 100644
--- a/src/arch/link.c
+++ b/src/arch/link.c
@@ -121,7 +121,7 @@ void handle_branch_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcC
 
         target = g_arch_processor_find_instr_by_address(proc, &addr);
 
-        printf(" @ 0x%08x BRANCH to 0x%08x -->> %p\n",
+        printf(" @ 0x%08x BRANCH true to 0x%08x -->> %p\n",
                (unsigned int)instr->range.addr.virtual, (unsigned int)virt, target);
 
         if (target != NULL)
@@ -132,6 +132,14 @@ void handle_branch_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcC
 
             target = g_arch_instruction_get_next_iter(list, instr, ~0);
 
+
+            if (target != NULL)
+                printf(" @ 0x%08x BRANCH false to 0x%08x -->> %p\n",
+                       (unsigned int)instr->range.addr.virtual,
+                       (unsigned int)g_arch_instruction_get_range(target)->addr.virtual,
+                       target);
+
+
             if (target != NULL)
                 g_arch_instruction_link_with(instr, target, ILT_JUMP_IF_FALSE);
 
-- 
cgit v0.11.2-87-g4458