From 18beadb4192144b00c06769645befb17ae1ce98e Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Tue, 13 Oct 2015 23:30:30 +0000
Subject: Kept all information about real addresses for routine symbols (ARM vs
 Thumb).

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@593 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                   | 14 +++++++++
 src/analysis/disass/fetch.c | 40 +++---------------------
 src/format/elf/helper_arm.c | 14 ++++++---
 src/format/elf/symbols.c    | 74 ++++++++++++++++++++++++++++++---------------
 src/format/format-int.h     |  8 +++++
 src/format/format.c         | 45 +++++++++++++++++++++++++++
 src/format/format.h         |  3 ++
 7 files changed, 133 insertions(+), 65 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index e36dd09..f594cba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+15-10-14  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/analysis/disass/fetch.c:
+	Update code.
+
+	* src/format/elf/helper_arm.c:
+	* src/format/elf/symbols.c:
+	Keep all information about real addresses for routine symbols (ARM vs Thumb).
+
+	* src/format/format.c:
+	* src/format/format.h:
+	* src/format/format-int.h:
+	Register all starting points for the disassembling process.
+
 15-10-13  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/analysis/binary.c:
diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c
index 9ebe231..67a6f3b 100644
--- a/src/analysis/disass/fetch.c
+++ b/src/analysis/disass/fetch.c
@@ -35,7 +35,7 @@
 
 
 /* Suit un flot d'exécution pour désassembler du code. */
-static void follow_execution_flow(const GLoadedBinary *, GProcContext *, mem_area **, size_t *, status_blob_info *, virt_t);
+static void follow_execution_flow(const GLoadedBinary *, GProcContext *, mem_area **, size_t *, status_blob_info *);
 
 /* S'assure que l'ensemble des aires est entièrement décodé. */
 static void ensure_all_mem_areas_are_filled(mem_area **, size_t *, const GLoadedBinary *, GProcContext *, status_blob_info *);
@@ -50,7 +50,6 @@ static void ensure_all_mem_areas_are_filled(mem_area **, size_t *, const GLoaded
 *                areas  = liste de zones contenant des données à traiter.     *
 *                count  = nombre de ces aires à disposition.                  *
 *                info   = informations liées à l'affichage de la progression. *
-*                virt   = adresse d'un point de départ d'un traitement.       *
 *                                                                             *
 *  Description : Suit un flot d'exécution pour désassembler du code.          *
 *                                                                             *
@@ -60,17 +59,13 @@ static void ensure_all_mem_areas_are_filled(mem_area **, size_t *, const GLoaded
 *                                                                             *
 ******************************************************************************/
 
-static void follow_execution_flow(const GLoadedBinary *binary, GProcContext *ctx, mem_area **areas, size_t *count, status_blob_info *info, virt_t virt)
+static void follow_execution_flow(const GLoadedBinary *binary, GProcContext *ctx, mem_area **areas, size_t *count, status_blob_info *info)
 {
+    virt_t virt;                            /* Adresse de départ dépilée   */
     vmpa2t addr;                            /* Conversion en pleine adresse*/
     GExeFormat *format;                     /* Format du fichier binaire   */
     size_t index;                           /* Zone trouvée à traiter      */
 
-    printf("-- follow 0x%08x\n", (unsigned int)virt);
-
-    if (virt == VMPA_NO_VIRTUAL)
-        g_proc_context_push_drop_point(ctx, virt);
-
     while (g_proc_context_has_drop_points(ctx))
     {
         virt = g_proc_context_pop_drop_point(ctx);
@@ -153,12 +148,6 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExt
     mem_area *areas;                        /* Zone de productions         */
     size_t count;                           /* Nombre de ces zones         */
     status_blob_info *info;                 /* Informations de progression */
-    virt_t virt;                            /* Point d'accroche virtuelle  */
-    GBinSymbol **symbols;                   /* Symboles à représenter      */
-    size_t sym_count;                       /* Qté de symboles présents    */
-    size_t i;                               /* Boucle de parcours          */
-    const mrange_t *range;                  /* Couverture d'un symbole     */
-    const vmpa2t *addr;                     /* Point de départ du symbole  */
     double done;                            /* Portion de travail accompli */
 
     format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
@@ -182,28 +171,7 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExt
                                   _("Disassembling following the execution flow..."),
                                   0, length);
 
-    /* Insertion des points de départ */
-
-    follow_execution_flow(binary, ctx, &areas, &count, info, VMPA_NO_VIRTUAL);
-
-    /* Symboles exécutables présents et passés à travers les mailles */
-
-    symbols = g_binary_format_get_symbols(format, &sym_count);
-
-    for (i = 0; i < sym_count; i++)
-    {
-        if (g_binary_symbol_get_target_type(symbols[i]) != STP_FUNCTION)
-            continue;
-
-        range = g_binary_symbol_get_range(symbols[i]);
-        addr = get_mrange_addr(range);
-        virt = get_virt_addr(addr);
-
-        follow_execution_flow(binary, ctx, &areas, &count, info, virt);
-
-    }
-
-    printf(" ------------------------------------------- follow done\n");
+    follow_execution_flow(binary, ctx, &areas, &count, info);
 
     done = get_current_progessive_status(info);
 
diff --git a/src/format/elf/helper_arm.c b/src/format/elf/helper_arm.c
index cd2d922..f47df5d 100644
--- a/src/format/elf/helper_arm.c
+++ b/src/format/elf/helper_arm.c
@@ -63,7 +63,9 @@ bool load_elf_arm_relocated_symbols(GElfFormat *format, const elf_shdr *relxxx,
 
 
 
-	virt_t virt;                            /* Adresse en mémoire virtuelle */
+    virt_t virt;                            /* Adresse en mémoire virtuelle*/
+    virt_t final_virt;                      /* Adresse virtuelle retenue   */
+    bool status;                            /* Bilan d'une opération       */
     vmpa2t addr;                            /* Localisation d'une routine  */
     mrange_t range;                         /* Couverture mémoire associée */
     GBinRoutine *routine;                   /* Nouvelle routine trouvée    */
@@ -100,14 +102,14 @@ bool load_elf_arm_relocated_symbols(GElfFormat *format, const elf_shdr *relxxx,
         {
             case R_ARM_JUMP_SLOT:
 
-
                 virt = ELF_SYM(format, sym, st_value);
-
-
                 if (virt == 0) continue;
 
+                final_virt = virt & ~0x1;
+
+                status = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), final_virt, &addr);
+                if (!status) continue;
 
-                init_vmpa(&addr, VMPA_NO_PHYSICAL, virt);
                 init_mrange(&range, &addr, 0);
 
                 routine = try_to_demangle_routine(name);
@@ -118,6 +120,8 @@ bool load_elf_arm_relocated_symbols(GElfFormat *format, const elf_shdr *relxxx,
                 g_binary_symbol_attach_routine(symbol, routine);
                 g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol);
 
+                /* Comptabilisation pour le désassemblage brut */
+                g_binary_format_register_code_point(G_BIN_FORMAT(format), virt, false);
 
 
                 /*
diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c
index c3c2ecd..fa7cb8f 100644
--- a/src/format/elf/symbols.c
+++ b/src/format/elf/symbols.c
@@ -168,26 +168,25 @@ bool load_elf_symbols(GElfFormat *format)
 
 static void register_elf_entry_point(GElfFormat *format, virt_t vaddr, phys_t len, GBinRoutine *routine)
 {
-    GBinFormat *base;                   /* Version basique de l'instance   */
-    vmpa2t addr;                        /* Localisation d'une routine  */
-    mrange_t range;                     /* Couverture mémoire associée */
-    GBinSymbol *symbol;                 /* Nouveau symbole construit   */
-
-    base = G_BIN_FORMAT(format);
+    GBinFormat *base;                       /* Version basique du format   */
+    virt_t final_vaddr;                     /* Adresse virtuelle retenue   */
+    bool status;                            /* Bilan d'une opération       */
+    vmpa2t addr;                            /* Localisation d'une routine  */
+    mrange_t range;                         /* Couverture mémoire associée */
+    GBinSymbol *symbol;                     /* Nouveau symbole construit   */
 
-    /* Comptabilisation pour le désassemblage brut */
+    /* Localisation complète du symbole */
 
-    base->entry_points = (virt_t *)realloc(base->entry_points, ++base->ep_count * sizeof(virt_t));
+	if (ELF_HDR(format, format->header, e_machine) == EM_ARM)
+		final_vaddr = vaddr & ~0x1;
+    else
+        final_vaddr = vaddr;
 
-    base->entry_points[base->ep_count - 1] = vaddr;
+    status = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), final_vaddr, &addr);
+    if (!status) return;
 
     /* Comptabilisation en tant que symbole */
 
-	if (ELF_HDR(format, format->header, e_machine) == EM_ARM)
-		vaddr &= ~0x1;
-
-	init_vmpa(&addr, VMPA_NO_PHYSICAL, vaddr);
-
     if (g_binary_format_find_symbol_at(G_BIN_FORMAT(format), &addr, &symbol))
     {
         g_object_unref(G_OBJECT(routine));
@@ -200,6 +199,8 @@ static void register_elf_entry_point(GElfFormat *format, virt_t vaddr, phys_t le
     }
     else
     {
+        base = G_BIN_FORMAT(format);
+
         init_mrange(&range, &addr, len);
 
         g_binary_routine_set_range(routine, &range);
@@ -208,6 +209,9 @@ static void register_elf_entry_point(GElfFormat *format, virt_t vaddr, phys_t le
         g_binary_symbol_attach_routine(symbol, routine);
         _g_binary_format_add_symbol(base, symbol, false);
 
+        /* Comptabilisation pour le désassemblage brut */
+        g_binary_format_register_code_point(base, vaddr, true);
+
     }
 
 }
@@ -513,6 +517,7 @@ static bool load_elf_internal_symbols(GElfFormat *format)
     /* Charge tous les symboles définis dans une section */
     bool add_all_symbols_from_section(GElfFormat *format, const elf_shdr *section, bool use_virt)
     {
+        GBinFormat *base;                   /* Version basique du format   */
         elf_shdr strtab;                    /* Section .strtab trouvée     */
         bool has_strtab;                    /* Présence de cette section   */
         phys_t start;                       /* Début de la zone à traiter  */
@@ -520,6 +525,7 @@ static bool load_elf_internal_symbols(GElfFormat *format)
         phys_t iter;                        /* Boucle de parcours          */
         elf_sym sym;                        /* Symbole aux infos visées    */
         virt_t virt;                        /* Adresse virtuelle           */
+        virt_t final_virt;                  /* Adresse virtuelle retenue   */
         vmpa2t addr;                        /* Localisation d'une routine  */
         mrange_t range;                     /* Couverture mémoire associée */
         const char *name;                   /* Nom du symbole trouvé       */
@@ -527,6 +533,8 @@ static bool load_elf_internal_symbols(GElfFormat *format)
         GBinRoutine *routine;               /* Nouvelle routine trouvée    */
         GBinSymbol *symbol;                 /* Nouveau symbole construit   */
 
+        base = G_BIN_FORMAT(format);
+
         has_strtab = find_elf_section_by_index(format, ELF_SHDR(format, *section, sh_link), &strtab);
 
         get_elf_section_content(format, section, &start, &size, NULL);
@@ -562,15 +570,6 @@ static bool load_elf_internal_symbols(GElfFormat *format)
 
             virt = ELF_SYM(format, sym, st_value);
 
-            if (ELF_HDR(format, format->header, e_machine) == EM_ARM)
-                virt &= ~0x1;
-
-            if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), virt, &addr))
-                continue;
-
-
-
-            init_mrange(&range, &addr, ELF_SYM(format, sym, st_size));
             //init_mrange(&range, &addr, 0);
 
 
@@ -586,6 +585,14 @@ static bool load_elf_internal_symbols(GElfFormat *format)
             {
                 case STT_OBJECT:
 
+                    /* Ajustement de la position */
+
+                    if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), virt, &addr))
+                    {
+                        symbol = NULL;
+                        break;
+                    }
+
                     /* Création d'un nom unique ? */
 
                     if (name != NULL)
@@ -609,6 +616,21 @@ static bool load_elf_internal_symbols(GElfFormat *format)
 
                 case STT_FUNC:
 
+                    /* Ajustement de la position */
+
+                    if (ELF_HDR(format, format->header, e_machine) == EM_ARM)
+                        final_virt = virt & ~0x1;
+                    else
+                        final_virt = virt;
+
+                    if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), final_virt, &addr))
+                    {
+                        symbol = NULL;
+                        break;
+                    }
+
+                    init_mrange(&range, &addr, ELF_SYM(format, sym, st_size));
+
                     /* Création d'un nom unique ? */
 
                     if (name != NULL)
@@ -635,6 +657,10 @@ static bool load_elf_internal_symbols(GElfFormat *format)
                     symbol = g_binary_symbol_new(STP_ROUTINE);
                     g_binary_symbol_attach_routine(symbol, routine);
 
+                    /* Comptabilisation pour le désassemblage brut */
+
+                    g_binary_format_register_code_point(base, virt, false);
+
                     break;
 
                 default:
@@ -644,7 +670,7 @@ static bool load_elf_internal_symbols(GElfFormat *format)
             }
 
             if (symbol != NULL)
-                _g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol, false);
+                _g_binary_format_add_symbol(base, symbol, false);
 
         }
 
diff --git a/src/format/format-int.h b/src/format/format-int.h
index 3e6ed9c..f97a4ad 100644
--- a/src/format/format-int.h
+++ b/src/format/format-int.h
@@ -36,6 +36,10 @@
 typedef void (* format_decompile_fc) (const GBinFormat *, GCodeBuffer *, const char *);
 
 
+/* Rythme des allocations pour les entrées de code */
+#define EXTRA_POINT_BLOCK 100
+
+
 /* Format binaire générique (instance) */
 struct _GBinFormat
 {
@@ -46,6 +50,10 @@ struct _GBinFormat
     virt_t *entry_points;                   /* Points d'entrée du code     */
     size_t ep_count;                        /* Nombre de ces points        */
 
+    virt_t *extra_points;                   /* Autres débuts de code       */
+    size_t xp_allocated;                    /* Taille d'inscription allouée*/
+    size_t xp_count;                        /* Nombre de points enregistrés*/
+
     GBinSymbol **symbols;                   /* Liste des symboles trouvés  */
     size_t symbols_count;                   /* Quantité de ces symboles    */
     GRWLock syms_lock;                      /* Accès à la liste de symboles*/
diff --git a/src/format/format.c b/src/format/format.c
index 6128c9a..9f03924 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -147,6 +147,48 @@ GBinContent *g_binary_format_get_content(const GBinFormat *format)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : format = description de l'exécutable à compléter.            *
+*                pt     = point de l'espace mémoire à considérer.             *
+*                entry  = nature du point fourni.                             *
+*                                                                             *
+*  Description : Enregistre une adresse comme début d'une zone de code.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_binary_format_register_code_point(GBinFormat *format, virt_t pt, bool entry)
+{
+    if (entry)
+    {
+        format->entry_points = (virt_t *)realloc(format->entry_points,
+                                                 ++format->ep_count * sizeof(virt_t));
+
+        format->entry_points[format->ep_count - 1] = pt;
+
+    }
+    else
+    {
+        if (format->xp_count == format->xp_allocated)
+        {
+            format->xp_allocated += EXTRA_POINT_BLOCK;
+
+            format->extra_points = (virt_t *)realloc(format->extra_points,
+                                                     format->xp_allocated * sizeof(virt_t));
+
+        }
+
+        format->extra_points[format->xp_count++] = pt;
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : format = description de l'exécutable à consulter.            *
 *                ctx    = contexte de désassemblage à préparer.               *
 *                                                                             *
@@ -165,6 +207,9 @@ void g_binary_format_setup_disassembling_context(const GBinFormat *format, GProc
     for (i = 0; i < format->ep_count; i++)
         g_proc_context_push_drop_point(ctx, format->entry_points[i]);
 
+    for (i = 0; i < format->xp_count; i++)
+        g_proc_context_push_drop_point(ctx, format->extra_points[i]);
+
 }
 
 
diff --git a/src/format/format.h b/src/format/format.h
index 8c06522..314306e 100644
--- a/src/format/format.h
+++ b/src/format/format.h
@@ -57,6 +57,9 @@ GType g_binary_format_get_type(void);
 /* Fournit une référence vers le contenu binaire analysé. */
 GBinContent *g_binary_format_get_content(const GBinFormat *);
 
+/* Enregistre une adresse comme début d'une zone de code. */
+void g_binary_format_register_code_point(GBinFormat *, virt_t, bool);
+
 /* Fournit un contexte initialisé pour un désassemblage. */
 void g_binary_format_setup_disassembling_context(const GBinFormat *, GProcContext *);
 
-- 
cgit v0.11.2-87-g4458