From 04ca0756d59629113bd3f602565850a2910ac84e Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Mon, 1 Sep 2014 22:20:28 +0000
Subject: Loaded some ELF symbols from DYNSYM and SYMTAB sections.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@397 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                    |  28 ++++++++
 src/analysis/disass/fetch.c  |  27 +++++---
 src/analysis/disass/output.c |   2 +-
 src/analysis/routine.c       |  30 +++------
 src/analysis/routine.h       |   4 +-
 src/arch/vmpa.c              |   4 +-
 src/core/params.c            |   3 +
 src/core/params.h            |   1 +
 src/format/elf/symbols.c     | 150 ++++++++++++++++++++++++++++++++-----------
 src/format/format.h          |   2 +-
 src/format/symbol.c          |  24 +++----
 src/format/symbol.h          |   7 +-
 12 files changed, 194 insertions(+), 88 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index c759cf0..0837dfe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+14-09-02  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/analysis/disass/fetch.c:
+	* src/analysis/disass/output.c:
+	Update code.
+
+	* src/analysis/routine.c:
+	* src/analysis/routine.h:
+	Replace all vmpa_t by the new vmpa2t types.
+
+	* src/arch/vmpa.c:
+	Change the default behavior when printing addresses.
+
+	* src/core/params.c:
+	* src/core/params.h:
+	Add a new configuration parameter for choosing between physical and virtual
+	addresses when naming a symbol which has no name.
+
+	* src/format/elf/symbols.c:
+	Load some ELF symbols from DYNSYM and SYMTAB sections.
+
+	* src/format/format.h:
+	Mark g_binary_format_add_routine() as deprecated.
+
+	* src/format/symbol.c:
+	* src/format/symbol.h:
+	Support routines as symbols and provide the location of each kind of symbols.
+
 14-08-27  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/analysis/disass/fetch.c:
diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c
index 20128aa..55ea1d4 100644
--- a/src/analysis/disass/fetch.c
+++ b/src/analysis/disass/fetch.c
@@ -135,22 +135,26 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExt
 
 
 
+    vmpa2t *last;                           /* Dernière bordure rencontrée */
+
+
+
     GBinSymbol **symbols;                   /* Symboles à représenter      */
     size_t sym_count;                       /* Qté de symboles présents    */
 
 
     size_t i;                               /* Boucle de parcours          */
 
-    GArchInstruction *instr;                /* Instruction à insérer       */
-
-
-    vmpa2t *last;                           /* Dernière bordure rencontrée */
 
 
     const vmpa2t *border;                   /* Nouvelle bordure rencontrée */
     off_t length;                           /* Taille d'une partie traitée */
 
 
+    GArchInstruction *instr;                /* Instruction à insérer       */
+
+
+
     GArchInstruction *joint;                /* Jointure entre deux lots    */
 
 
@@ -179,19 +183,26 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExt
 
 
 
+        border = g_binary_symbol_get_location(symbols[i], &length);
 
         switch (g_binary_symbol_get_target_type(symbols[i]))
         {
             case STP_DATA:
                 instr = g_binary_symbol_get_instruction(symbols[i]);
                 g_object_ref(G_OBJECT(instr));
-                border = g_arch_instruction_get_location2(instr, &length);
-
-                // Utiliser : ???
-                // const vmpa2t *g_binary_symbol_get_address2(const GBinSymbol *symbol)
+                break;
 
+            case STP_ROUTINE:
+                instr = load_raw_binary(binary, border,
+                                        get_phy_addr(border) + length,
+                                        statusbar, id);
                 break;
 
+             default:
+                 printf("BADDD !\n");
+                 exit(0);
+                 break;
+
         }
 
         /* Traiter la diff */
diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c
index 927088f..f368796 100644
--- a/src/analysis/disass/output.c
+++ b/src/analysis/disass/output.c
@@ -130,7 +130,7 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form
         if (sym_index < sym_count)
         {
             iaddr = g_arch_instruction_get_location2(iter, NULL);
-            saddr = g_binary_symbol_get_address2(symbols[sym_index]);
+            saddr = g_binary_symbol_get_location(symbols[sym_index], NULL);
 
             if (cmp_vmpa_by_phy(iaddr, saddr) == 0)
             {
diff --git a/src/analysis/routine.c b/src/analysis/routine.c
index d97dfc7..eebcb69 100644
--- a/src/analysis/routine.c
+++ b/src/analysis/routine.c
@@ -38,7 +38,7 @@ struct _GBinRoutine
 {
     GObject parent;                         /* A laisser en premier        */
 
-    vmpa_t addr;                            /* Position physique/mémoire   */
+    vmpa2t addr;                           /* Position physique/mémoire   */
     off_t size;                             /* Taille du code associé      */
 
     RoutineType type;                       /* Type de routine             */
@@ -214,13 +214,7 @@ void g_binary_routine_finalize(GBinRoutine *routine)
 
 int g_binary_routine_compare(const GBinRoutine **a, const GBinRoutine **b)
 {
-    int result;                             /* Bilan à renvoyer            */
-
-    if ((*a)->addr < (*b)->addr) result = -1;
-    else if((*a)->addr > (*b)->addr) result = 1;
-    else result = 0;
-
-    return result;
+    return cmp_vmpa(&(*a)->addr, &(*b)->addr);
 
 }
 
@@ -232,7 +226,7 @@ int g_binary_routine_compare(const GBinRoutine **a, const GBinRoutine **b)
 *                                                                             *
 *  Description : Etablit la comparaison descendante entre deux routines.      *
 *                                                                             *
-*  Retour      : Bilan : -1 (a < b), 0 (a == b) ou 1 (a > b).                 *
+*  Retour      : Bilan : 1 (a < b), 0 (a == b) ou -1 (a > b).                 *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
@@ -240,13 +234,7 @@ int g_binary_routine_compare(const GBinRoutine **a, const GBinRoutine **b)
 
 int g_binary_routine_rcompare(const GBinRoutine **a, const GBinRoutine **b)
 {
-    int result;                             /* Bilan à renvoyer            */
-
-    if ((*a)->addr > (*b)->addr) result = -1;
-    else if((*a)->addr < (*b)->addr) result = 1;
-    else result = 0;
-
-    return result;
+    return (-1) * cmp_vmpa(&(*a)->addr, &(*b)->addr);
 
 }
 
@@ -264,9 +252,9 @@ int g_binary_routine_rcompare(const GBinRoutine **a, const GBinRoutine **b)
 *                                                                             *
 ******************************************************************************/
 
-void g_binary_routine_set_address(GBinRoutine *routine, vmpa_t addr)
+void g_binary_routine_set_address(GBinRoutine *routine, const vmpa2t *addr)
 {
-    routine->addr = addr;
+    copy_vmpa(&routine->addr, addr);
 
 }
 
@@ -283,9 +271,9 @@ void g_binary_routine_set_address(GBinRoutine *routine, vmpa_t addr)
 *                                                                             *
 ******************************************************************************/
 
-vmpa_t g_binary_routine_get_address(const GBinRoutine *routine)
+const vmpa2t *g_binary_routine_get_address(const GBinRoutine *routine)
 {
-    return routine->addr;
+    return &routine->addr;
 
 }
 
@@ -293,7 +281,7 @@ vmpa_t g_binary_routine_get_address(const GBinRoutine *routine)
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : routine = routine à mettre à jour.                           *
-*                addr    = taille du code associé.                            *
+*                size    = taille du code associé.                            *
 *                                                                             *
 *  Description : Définit la taille du code d'une routine.                     *
 *                                                                             *
diff --git a/src/analysis/routine.h b/src/analysis/routine.h
index de1b6ba..29f6e63 100644
--- a/src/analysis/routine.h
+++ b/src/analysis/routine.h
@@ -87,10 +87,10 @@ int g_binary_routine_compare(const GBinRoutine **, const GBinRoutine **);
 int g_binary_routine_rcompare(const GBinRoutine **, const GBinRoutine **);
 
 /* Définit la position physique / en mémoire d'une routine. */
-void g_binary_routine_set_address(GBinRoutine *, vmpa_t);
+void g_binary_routine_set_address(GBinRoutine *, const vmpa2t *);
 
 /* Fournit la position physique / en mémoire d'une routine. */
-vmpa_t g_binary_routine_get_address(const GBinRoutine *);
+const vmpa2t *g_binary_routine_get_address(const GBinRoutine *);
 
 /* Définit la taille du code d'une routine. */
 void g_binary_routine_set_size(GBinRoutine *, off_t);
diff --git a/src/arch/vmpa.c b/src/arch/vmpa.c
index 297a0ca..aa97eba 100644
--- a/src/arch/vmpa.c
+++ b/src/arch/vmpa.c
@@ -368,7 +368,7 @@ char *vmpa2_phys_to_string(const vmpa2t *addr, MemoryDataSize msize, char buffer
             break;
 
         default:
-            ret = snprintf(buffer, VMPA_MAX_SIZE, "???");
+            ret = snprintf(buffer, VMPA_MAX_SIZE, "0x%" PRIx64, addr->physical);
             break;
 
     }
@@ -419,7 +419,7 @@ char *vmpa2_virt_to_string(const vmpa2t *addr, MemoryDataSize msize, char buffer
             break;
 
         default:
-            ret = snprintf(buffer, VMPA_MAX_SIZE, "???");
+            ret = snprintf(buffer, VMPA_MAX_SIZE, "0x%" PRIx64, addr->virtual);
             break;
 
     }
diff --git a/src/core/params.c b/src/core/params.c
index 7bc1162..fdcbe3f 100644
--- a/src/core/params.c
+++ b/src/core/params.c
@@ -135,6 +135,9 @@ bool load_main_config_parameters(void)
     param = g_generic_config_create_param(config, MPK_SERVER_BACKLOG, CPT_INTEGER, 20);
     if (param == NULL) return false;
 
+    param = g_generic_config_create_param(config, MPK_FORMAT_NO_NAME, CPT_BOOLEAN, false);
+    if (param == NULL) return false;
+
     param = g_generic_config_create_param(config, MPK_LAST_PROJECT, CPT_STRING, NULL);
     if (param == NULL) return false;
 
diff --git a/src/core/params.h b/src/core/params.h
index db01d20..3e78945 100644
--- a/src/core/params.h
+++ b/src/core/params.h
@@ -39,6 +39,7 @@
 #define MPK_LOCAL_HOST          "cdb.network.local.server"
 #define MPK_LOCAL_PORT          "cdb.network.local.port"
 #define MPK_SERVER_BACKLOG      "cdb.network.server.backlog"
+#define MPK_FORMAT_NO_NAME      "format.symbols.use_phy_instead_of_virt"
 #define MPK_LAST_PROJECT        "gui.editor.last_project"
 #define MPK_ELLIPSIS_HEADER     "gui.editor.panels.ellipsis_header"
 #define MPK_ELLIPSIS_TAB        "gui.editor.panels.ellipsis_tab"
diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c
index dc3fbe0..06d7cab 100644
--- a/src/format/elf/symbols.c
+++ b/src/format/elf/symbols.c
@@ -37,6 +37,7 @@
 #include "../mangling/demangler.h"
 #include "../../arch/raw.h"
 #include "../../common/extstr.h"
+#include "../../core/params.h"
 #include "../../gui/panels/log.h"
 
 
@@ -123,6 +124,12 @@ bool load_elf_symbols(GElfFormat *format)
 
 
 
+    /* Symboles internes */
+    result = load_elf_internal_symbols(format);
+
+
+
+
     /* Symboles externes */
 
     if (find_elf_sections_by_type(format, SHT_DYNAMIC, &sections, &count))
@@ -137,7 +144,7 @@ bool load_elf_symbols(GElfFormat *format)
     else log_variadic_message(LMT_INFO, _("Binary is statically linked"));
 
     /* Symboles internes */
-    result &= load_elf_internal_symbols(format);
+    //result &= load_elf_internal_symbols(format);
 
     return result;
 
@@ -1272,70 +1279,137 @@ static bool annotate_elf_section_header_table(GElfFormat *format)
 static bool load_elf_internal_symbols(GElfFormat *format)
 {
     bool result;                            /* Bilan à retourner           */
-    elf_shdr *symtabs;                      /* Groupe de sections trouvées */
+    bool no_name;                           /* Choix de construction de nom*/
+    elf_shdr *sections;                      /* Groupe de sections trouvées */
     size_t count;                           /* Quantité de données         */
     size_t i;                               /* Boucle de parcours          */
-    elf_shdr strtab;                        /* Section .strtab trouvée     */
-    bool has_strtab;                        /* Présence de cette section   */
-    off_t sym_start;                        /* Début de la zone à traiter  */
-    off_t sym_size;                         /* Taille de cette même zone   */
-    off_t iter;                             /* Boucle de parcours          */
-    const char *name;                       /* Nom du symbole trouvé       */
-    elf_sym sym;                            /* Symbole aux infos visées    */
-    GBinRoutine *routine;                   /* Nouvelle routine trouvée    */
-    GBinSymbol *symbol;                     /* Nouveau symbole construit   */
 
     result = true;
 
-    if (find_elf_sections_by_type(format, SHT_SYMTAB, &symtabs, &count))
-        for (i = 0; i < count && result; i++)
+    /* Charge tous les symboles définis dans une section */
+    bool add_all_symbols_from_section(GElfFormat *format, const elf_shdr *section, bool use_virt)
+    {
+        elf_shdr strtab;                    /* Section .strtab trouvée     */
+        bool has_strtab;                    /* Présence de cette section   */
+        off_t start;                        /* Début de la zone à traiter  */
+        off_t size;                         /* Taille de cette même zone   */
+        off_t iter;                         /* Boucle de parcours          */
+        elf_sym sym;                        /* Symbole aux infos visées    */
+        vmpa2t addr;                        /* Localisation d'une routine  */
+        const char *name;                   /* Nom du symbole trouvé       */
+        char alt_name[5 + VMPA_MAX_LEN];    /* Nom abstrait de substitution*/
+        GBinRoutine *routine;               /* Nouvelle routine trouvée    */
+        GBinSymbol *symbol;                 /* Nouveau symbole construit   */
+
+        has_strtab = find_elf_section_by_index(format, ELF_SHDR(format, *section, sh_link), &strtab);
+
+        get_elf_section_content(format, section, &start, &size, NULL);
+
+        for (iter = start; iter < (start + size); )
         {
-            has_strtab = find_elf_section_by_index(format, ELF_SHDR(format, symtabs[i], sh_link), &strtab);
+            result = read_elf_symbol(format, &iter, &sym);
+            if (!result) break;
+
+            if (ELF_SYM(format, sym, st_value) == 0) continue;
+
+            /* Résolution précise d'adresse */
+
+
+            /* TODO */
+
+            init_vmpa(&addr, ELF_SYM(format, sym, st_value), VMPA_NO_VIRTUAL);
 
-            get_elf_section_content(format, &symtabs[i], &sym_start, &sym_size, NULL);
 
-            for (iter = sym_start; iter < (sym_start + sym_size); )
+
+            /* Première ébauche de nom */
+
+            if (!has_strtab) name = NULL;
+            else name = get_elf_symbol_name(format, section, &strtab,
+                                            ((iter - start) / ELF_SIZEOF_SYM(format)) - 1);
+
+            /* Traitements particuliers */
+
+            switch (ELF_ST_TYPE(format, sym))
             {
-                result = read_elf_symbol(format, &iter, &sym);
-                if (!result) break;
+                case STT_OBJECT:
 
-                if (ELF_SYM(format, sym, st_value) == 0) continue;
+                    /* Création d'un nom unique ? */
 
-                if (!(ELF_ST_TYPE(format, sym) == STT_FUNC)) continue;
+                    if (name != NULL)
+                    {
+                        strcpy(alt_name, "obj_");
 
-                if (!has_strtab) name = NULL;
-                else name = get_elf_symbol_name(format, &symtabs[i], &strtab,
-                                                ((iter - sym_start) / ELF_SIZEOF_SYM(format)) - 1);
+                        if (use_virt)
+                            vmpa2_virt_to_string(&addr, MDS_UNDEFINED, alt_name + 4, NULL);
+                        else
+                            vmpa2_phys_to_string(&addr, MDS_UNDEFINED, alt_name + 4, NULL);
 
-                if (name == NULL)
-                {
-                    /* FIXME */
-                    name = "unknown";
-                }
+                    }
+
+
+                    /* TODO */
+
+                    symbol = NULL;
 
-                /* Routine */
 
-                routine = try_to_demangle_routine(name);
+                    break;
+
+                case STT_FUNC:
+
+                    /* Création d'un nom unique ? */
+
+                    if (name != NULL)
+                    {
+                        strcpy(alt_name, "func_");
+
+                        if (use_virt)
+                            vmpa2_virt_to_string(&addr, MDS_UNDEFINED, alt_name + 5, NULL);
+                        else
+                            vmpa2_phys_to_string(&addr, MDS_UNDEFINED, alt_name + 5, NULL);
 
-                g_binary_routine_set_address(routine, ELF_SYM(format, sym, st_value));
-                g_binary_routine_set_size(routine, ELF_SYM(format, sym, st_size));
+                    }
+
+                    /* Routine */
+
+                    routine = try_to_demangle_routine(name);
 
-                ///// reactiver g_binary_format_add_routine(G_BIN_FORMAT(format), routine);
+                    g_binary_routine_set_address(routine, &addr);
+                    g_binary_routine_set_size(routine, ELF_SYM(format, sym, st_size));
 
-                /* Symbole uniquement */
+                    /* Symbole uniquement */
 
-                symbol = g_binary_symbol_new(STP_FUNCTION, name, ELF_SYM(format, sym, st_value));
+                    symbol = g_binary_symbol_new(STP_ROUTINE, name, ~0);
+                    g_binary_symbol_attach_routine(symbol, routine);
 
-                g_binary_symbol_attach_routine(symbol, routine);
+                    break;
 
-                ///// reactiver g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol);
+                default:
+                    symbol = NULL;
+                    break;
 
             }
 
+            if (symbol != NULL)
+                g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol);
 
         }
 
-    return true;
+        return true;
+
+    }
+
+    if (!g_generic_config_get_value(get_main_configuration(), MPK_FORMAT_NO_NAME, &no_name))
+        return false;
+
+    if (find_elf_sections_by_type(format, SHT_DYNSYM, &sections, &count))
+        for (i = 0; i < count && result; i++)
+            result = add_all_symbols_from_section(format, &sections[i], no_name);
+
+    if (find_elf_sections_by_type(format, SHT_SYMTAB, &sections, &count))
+        for (i = 0; i < count && result; i++)
+            result = add_all_symbols_from_section(format, &sections[i], no_name);
+
+    return result;
 
 }
 
diff --git a/src/format/format.h b/src/format/format.h
index d87735d..2eed669 100644
--- a/src/format/format.h
+++ b/src/format/format.h
@@ -65,7 +65,7 @@ void g_binary_format_add_symbol(GBinFormat *, GBinSymbol *);
 GBinSymbol **g_binary_format_get_symbols(const GBinFormat *, size_t *);
 
 /* Ajoute une routine à la collection du format binaire. */
-void g_binary_format_add_routine(GBinFormat *, GBinRoutine *);
+void g_binary_format_add_routine(GBinFormat *, GBinRoutine *) __attribute__ ((deprecated));
 
 /* Fournit le prototype de toutes les routines détectées. */
 GBinRoutine **g_binary_format_get_routines(const GBinFormat *, size_t *);
diff --git a/src/format/symbol.c b/src/format/symbol.c
index f1183cb..5b80555 100644
--- a/src/format/symbol.c
+++ b/src/format/symbol.c
@@ -192,8 +192,9 @@ vmpa_t g_binary_symbol_get_address(const GBinSymbol *symbol)
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : symbol = symbole à venir consulter.                          *
+*                length = taille de l'instruction ou NULL. [OUT]              *
 *                                                                             *
-*  Description : Fournit l'adresse associée à un symbole.                     *
+*  Description : Fournit l'emplacement où se situe un symbole.                *
 *                                                                             *
 *  Retour      : Adresse virtuelle ou physique associée.                      *
 *                                                                             *
@@ -201,7 +202,7 @@ vmpa_t g_binary_symbol_get_address(const GBinSymbol *symbol)
 *                                                                             *
 ******************************************************************************/
 
-const vmpa2t *g_binary_symbol_get_address2(const GBinSymbol *symbol)
+const vmpa2t *g_binary_symbol_get_location(const GBinSymbol *symbol, off_t *length)
 {
     const vmpa2t *result;                   /* Localisation à retourner    */
 
@@ -210,19 +211,20 @@ const vmpa2t *g_binary_symbol_get_address2(const GBinSymbol *symbol)
     switch (symbol->type)
     {
         case STP_DATA:
-            result = g_arch_instruction_get_location2(symbol->extra.instr, NULL);
+            result = g_arch_instruction_get_location2(symbol->extra.instr, length);
             break;
 
-    default:
-        result = NULL;
-        break;
-
-    }
-
+        case STP_ROUTINE:
+            result = g_binary_routine_get_address(symbol->extra.routine);
+            if (length != NULL)
+                *length = g_binary_routine_get_size(symbol->extra.routine);
+            break;
 
-    if (result == NULL)
-        printf("got addr=%p for symbol=%p (data=%d)\n", result, symbol, symbol->type == STP_DATA);
+        default:
+            result = NULL;
+            break;
 
+    }
 
     return result;
 
diff --git a/src/format/symbol.h b/src/format/symbol.h
index 407375f..8d27f97 100644
--- a/src/format/symbol.h
+++ b/src/format/symbol.h
@@ -37,6 +37,7 @@
 typedef enum _SymbolType
 {
     STP_DATA,                               /* Données brutes              */
+    STP_ROUTINE,                            /* Simple morceau de code      */
     STP_OBJECT,                             /* Objet quelconque            */
     STP_FUNCTION,                           /* Simple morceau de code      */
     STP_STRING                              /* Chaîne de caractères        */
@@ -73,10 +74,8 @@ const char *g_binary_symbol_to_string(const GBinSymbol *);
 /* Fournit l'adresse associée à un symbole. */
 vmpa_t g_binary_symbol_get_address(const GBinSymbol *);
 
-
-/* Fournit l'adresse associée à un symbole. */
-const vmpa2t *g_binary_symbol_get_address2(const GBinSymbol *);
-
+/* Fournit l'emplacement où se situe un symbole. */
+const vmpa2t *g_binary_symbol_get_location(const GBinSymbol *, off_t *);
 
 /* Fournit la taille officielle d'un symbole. */
 off_t g_binary_symbol_get_size(const GBinSymbol *);
-- 
cgit v0.11.2-87-g4458