From 39116dce7d40dab310e929f92fdbfc865b5fac20 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Fri, 8 Dec 2017 21:50:56 +0100
Subject: Introduced the symbol visibility.

---
 ChangeLog                        | 20 ++++++++++++++
 plugins/elf/symbols.c            | 60 ++++++++++++++++++++++++----------------
 plugins/pychrysa/format/symbol.c | 36 ++++++++++++++++++++++++
 src/analysis/disass/output.c     | 27 +++++++++++-------
 src/analysis/disass/routines.c   |  7 +++++
 src/format/format.c              |  2 +-
 src/format/symbol-int.h          |  1 +
 src/format/symbol.c              | 41 +++++++++++++++++++++++++++
 src/format/symbol.h              | 18 ++++++++++++
 src/gui/panels/symbols.c         | 16 +++++++++--
 src/panels/strings.c             |  2 ++
 11 files changed, 192 insertions(+), 38 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 7cc6a93..07987e4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,25 @@
 17-12-08  Cyrille Bagard <nocbos@gmail.com>
 
+	* plugins/elf/symbols.c:
+	Load imported symbols.
+
+	* plugins/pychrysa/format/symbol.c:
+	* src/analysis/disass/output.c:
+	* src/analysis/disass/routines.c:
+	* src/format/format.c:
+	Update code.
+
+	* src/format/symbol-int.h:
+	* src/format/symbol.c:
+	* src/format/symbol.h:
+	Introduce the symbol visibility.
+
+	* src/gui/panels/symbols.c:
+	* src/panels/strings.c:
+	Update code.
+
+17-12-08  Cyrille Bagard <nocbos@gmail.com>
+
 	* plugins/pychrysa/arch/vmpa.c:
 	Update the comparison features for the Python bindings.
 
diff --git a/plugins/elf/symbols.c b/plugins/elf/symbols.c
index 292913b..b5dc2b8 100644
--- a/plugins/elf/symbols.c
+++ b/plugins/elf/symbols.c
@@ -521,6 +521,8 @@ static bool do_elf_internal_symbol_loading(GElfLoading *loading, GElfFormat *for
 {
     bool result;                            /* Bilan à retourner           */
     elf_sym sym;                            /* Symbole aux infos visées    */
+    SymbolStatus status;                    /* Visibilité du symbole       */
+    vmpa2t addr;                            /* Localisation d'un symbole   */
     virt_t virt;                            /* Adresse virtuelle           */
     const elf_shdr *section;                /* Groupe de sections trouvées */
     bool use_virt;                          /* Choix de construction de nom*/
@@ -529,7 +531,6 @@ static bool do_elf_internal_symbol_loading(GElfLoading *loading, GElfFormat *for
     phys_t first;                           /* Position du premier élément */
     const char *name;                       /* Nom du symbole trouvé       */
     GBinFormat *base;                       /* Version basique du format   */
-    vmpa2t addr;                            /* Localisation d'une routine  */
     GBinSymbol *symbol;                     /* Nouveau symbole construit   */
     char alt_name[6 + VMPA_MAX_LEN];        /* Nom abstrait de substitution*/
     virt_t final_virt;                      /* Adresse virtuelle retenue   */
@@ -539,23 +540,23 @@ static bool do_elf_internal_symbol_loading(GElfLoading *loading, GElfFormat *for
     result = read_elf_symbol(format, iter, &sym);
     if (!result) goto geslp_done;
 
-    /* On rejette les symboles qui ne sont pas définis au sein du binaire */
-
-    if (ELF_SYM(format, sym, st_shndx) == 0) goto geslp_done;
-
-    /* Résolution précise d'adresse */
-
-    virt = ELF_SYM(format, sym, st_value);
-    if (virt == 0) goto geslp_done;
+    /* Nature de la visibilité et adresse associée */
 
+    if (ELF_SYM(format, sym, st_shndx) == 0)
+    {
+        status = SSS_IMPORTED;
+        init_vmpa(&addr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL);
 
-    /* TODO */
-
-    //init_vmpa(&addr, VMPA_NO_PHYSICAL, ELF_SYM(format, sym, st_value));
+    }
 
+    else
+    {
+        status = SSS_EXPORTED;
 
-    //init_mrange(&range, &addr, 0);
+        virt = ELF_SYM(format, sym, st_value);
+        if (virt == 0) goto geslp_done;
 
+    }
 
     /* Première ébauche de nom */
 
@@ -611,18 +612,25 @@ static bool do_elf_internal_symbol_loading(GElfLoading *loading, GElfFormat *for
 
             /* Ajustement de la position */
 
-            if (ELF_HDR(format, format->header, e_machine) == EM_ARM)
-                final_virt = virt & ~0x1;
-            else
-                final_virt = virt;
+            if (status == SSS_IMPORTED)
+                init_mrange(&range, &addr, 0);
 
-            if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), final_virt, &addr))
+            else
             {
-                symbol = NULL;
-                break;
-            }
+                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));
 
-            init_mrange(&range, &addr, ELF_SYM(format, sym, st_size));
+            }
 
             /* Création d'un nom unique ? */
 
@@ -644,8 +652,6 @@ static bool do_elf_internal_symbol_loading(GElfLoading *loading, GElfFormat *for
             routine = try_to_demangle_routine(name);
             symbol = G_BIN_SYMBOL(routine);
 
-            g_binary_symbol_set_range(symbol, &range);
-
             /* Comptabilisation pour le désassemblage brut */
 
             g_binary_format_register_code_point(G_BIN_FORMAT(format), virt, false);
@@ -659,8 +665,14 @@ static bool do_elf_internal_symbol_loading(GElfLoading *loading, GElfFormat *for
     }
 
     if (symbol != NULL)
+    {
+        g_binary_symbol_set_range(symbol, &range);
+        g_binary_symbol_set_status(symbol, status);
+
         g_binary_format_add_symbol(base, symbol);
 
+    }
+
  geslp_done:
 
     return result;
diff --git a/plugins/pychrysa/format/symbol.c b/plugins/pychrysa/format/symbol.c
index b9ac13c..736a8d2 100644
--- a/plugins/pychrysa/format/symbol.c
+++ b/plugins/pychrysa/format/symbol.c
@@ -57,6 +57,9 @@ static PyObject *py_binary_symbol_get_label(PyObject *, void *);
 /* Fournit l'emplacement où se situe un symbole. */
 static PyObject *py_binary_symbol_get_range(PyObject *, void *);
 
+/* Fournit la visibilité du symbole. */
+static PyObject *py_binary_symbol_get_status(PyObject *, void *);
+
 /* Définit les constantes pour les symboles binaires. */
 static bool py_binary_symbol_define_constants(PyTypeObject *);
 
@@ -285,6 +288,35 @@ static PyObject *py_binary_symbol_get_range(PyObject *self, void *closure)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Fournit la visibilité du symbole.                            *
+*                                                                             *
+*  Retour      : Etat de la visibilité du symbole représenté.                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_binary_symbol_get_status(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Valeur à retourner          */
+    GBinSymbol *symbol;                     /* Elément à consulter         */
+    SymbolStatus status;                    /* Visibilité du symbole fourni*/
+
+    symbol = G_BIN_SYMBOL(pygobject_get(self));
+    status = g_binary_symbol_get_status(symbol);
+
+    result = PyLong_FromLong(status);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : obj_type = type dont le dictionnaire est à compléter.        *
 *                                                                             *
 *  Description : Définit les constantes pour les symboles binaires.           *
@@ -351,6 +383,10 @@ PyTypeObject *get_python_binary_symbol_type(void)
             "range", py_binary_symbol_get_range, NULL,
             "Range covered by the symbol.", NULL
         },
+        {
+            "status", py_binary_symbol_get_status, NULL,
+            "Status of the symbol's visibility.", NULL
+        },
         { NULL }
     };
 
diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c
index 8e74d1c..f9656cf 100644
--- a/src/analysis/disass/output.c
+++ b/src/analysis/disass/output.c
@@ -81,6 +81,7 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang,
     GBorderGenerator *border;               /* Délimitation de routine     */
     const vmpa2t *paddr;                    /* Adresse de portion          */
     GLineGenerator *generator;              /* Générateur de contenu ajouté*/
+    SymbolStatus sym_status;                /* Visibilité du symbole obtenu*/
     const vmpa2t *saddr;                    /* Adresse de symbole          */
     int compared;                           /* Bilan d'une comparaison     */
     char *errmsg;                           /* Description d'une erreur    */
@@ -210,13 +211,21 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang,
         else
         {
             iaddr = get_mrange_addr(g_arch_instruction_get_range(instr));
-            saddr = get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index]));
 
-            /* On écarte les symboles qu'on ne sait pas réintroduire */
-            for (compared = cmp_vmpa(iaddr, saddr);
-                 compared > 0;
-                 compared = cmp_vmpa(iaddr, saddr))
+            for ( ; sym_index < sym_count; sym_index++)
             {
+                sym_status = g_binary_symbol_get_status(symbols[sym_index]);
+
+                if (sym_status == SSS_IMPORTED)
+                    continue;
+
+                saddr = get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index]));
+
+                compared = cmp_vmpa(iaddr, saddr);
+
+                if (compared <= 0)
+                    break;
+
                 log_variadic_message(LMT_BAD_BINARY,
                                      _("Unable to find a proper location for symbol '%s' @ 0x%08x"),
                                      g_binary_symbol_get_label(symbols[sym_index]), get_phy_addr(saddr));
@@ -230,13 +239,11 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang,
 
                 _missing++;
 
-                if (++sym_index == sym_count)
-                    goto no_more_symbol_finally;
-
-                saddr = get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index]));
-
             }
 
+            if (sym_index == sym_count)
+                goto no_more_symbol_finally;
+
             if (compared == 0)
             {
                 /* Coupure pour une nouvelle routine */
diff --git a/src/analysis/disass/routines.c b/src/analysis/disass/routines.c
index 01a6e48..63a32cf 100644
--- a/src/analysis/disass/routines.c
+++ b/src/analysis/disass/routines.c
@@ -233,11 +233,18 @@ static void g_routines_study_process(GRoutinesStudy *study, GtkStatusStack *stat
 {
     size_t i;                               /* Boucle de parcours          */
     GBinSymbol *symbol;                     /* Commodité d'accès           */
+    SymbolStatus sym_status;                /* Visibilité du symbole obtenu*/
     SymbolType type;                        /* Type de symbole rencontré   */
 
     for (i = study->begin; i < study->end; i++)
     {
         symbol = study->symbols[i];
+
+        sym_status = g_binary_symbol_get_status(symbol);
+
+        if (sym_status == SSS_IMPORTED)
+            continue;
+
         type = g_binary_symbol_get_target_type(symbol);
 
         if (type == STP_ROUTINE || type == STP_ENTRY_POINT)
diff --git a/src/format/format.c b/src/format/format.c
index 8b1bf0a..ec8e5fb 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -407,7 +407,7 @@ bool g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol)
     range = g_binary_symbol_get_range(symbol);
     addr = get_mrange_addr(range);
 
-    assert(has_phys_addr(addr));
+    assert(has_phys_addr(addr) || g_binary_symbol_get_status(symbol) == SSS_IMPORTED);
 #endif
 
     g_rw_lock_writer_lock(&format->syms_lock);
diff --git a/src/format/symbol-int.h b/src/format/symbol-int.h
index 49a0b97..a0460c2 100644
--- a/src/format/symbol-int.h
+++ b/src/format/symbol-int.h
@@ -41,6 +41,7 @@ struct _GBinSymbol
 
     mrange_t range;                         /* Couverture mémoire          */
     SymbolType type;                        /* Type du symbole             */
+    SymbolStatus status;                    /* Visibilité du symbole       */
 
     char *alt;                              /* Nom alternatif              */
 
diff --git a/src/format/symbol.c b/src/format/symbol.c
index 0b300bd..099b764 100644
--- a/src/format/symbol.c
+++ b/src/format/symbol.c
@@ -123,6 +123,8 @@ static void g_binary_symbol_init(GBinSymbol *symbol)
 {
     g_binary_symbol_set_target_type(symbol, STP_COUNT);
 
+    g_binary_symbol_set_status(symbol, SSS_INTERNAL);
+
 }
 
 
@@ -345,6 +347,45 @@ SymbolType g_binary_symbol_get_target_type(const GBinSymbol *symbol)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : symbol = symbole à venir modifier.                           *
+*                status = état de la visibilité du symbole représenté.        *
+*                                                                             *
+*  Description : Définit la visibilité du symbole.                            *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_binary_symbol_set_status(GBinSymbol *symbol, SymbolStatus status)
+{
+    symbol->status = status;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : symbol = symbole à venir consulter.                          *
+*                                                                             *
+*  Description : Fournit la visibilité du symbole.                            *
+*                                                                             *
+*  Retour      : Etat de la visibilité du symbole représenté.                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+SymbolStatus g_binary_symbol_get_status(const GBinSymbol *symbol)
+{
+    return symbol->status;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : symbol = symbole à venir consulter.                          *
 *                                                                             *
 *  Description : Fournit une étiquette pour viser un symbole.                 *
diff --git a/src/format/symbol.h b/src/format/symbol.h
index da51262..8aabfdf 100644
--- a/src/format/symbol.h
+++ b/src/format/symbol.h
@@ -51,6 +51,18 @@ typedef enum _SymbolType
 } SymbolType;
 
 
+/* Visibilité du symbole */
+typedef enum _SymbolStatus
+{
+    SSS_INTERNAL,                           /* Visibilité nulle            */
+    SSS_EXPORTED,                           /* Disponibilité extérieure    */
+    SSS_IMPORTED,                           /* Besoin interne              */
+
+    SSS_COUNT
+
+} SymbolStatus;
+
+
 #define G_TYPE_BIN_SYMBOL               g_binary_symbol_get_type()
 #define G_BIN_SYMBOL(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_binary_symbol_get_type(), GBinSymbol))
 #define G_IS_BIN_SYMBOL(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_binary_symbol_get_type()))
@@ -90,6 +102,12 @@ void g_binary_symbol_set_target_type(GBinSymbol *, SymbolType);
 /* Fournit le type du symbole. */
 SymbolType g_binary_symbol_get_target_type(const GBinSymbol *);
 
+/* Définit la visibilité du symbole. */
+void g_binary_symbol_set_status(GBinSymbol *, SymbolStatus);
+
+/* Fournit la visibilité du symbole. */
+SymbolStatus g_binary_symbol_get_status(const GBinSymbol *);
+
 /* Fournit une étiquette pour viser un symbole. */
 const char *g_binary_symbol_get_label(GBinSymbol *);
 
diff --git a/src/gui/panels/symbols.c b/src/gui/panels/symbols.c
index 3b01f24..f64f087 100644
--- a/src/gui/panels/symbols.c
+++ b/src/gui/panels/symbols.c
@@ -1064,15 +1064,25 @@ static void do_filtering_on_symbols(GSymbolsPanel *panel)
 static bool is_symbol_matching(GSymbolsPanel *panel, const GBinSymbol *symbol, regmatch_t *match)
 {
     bool result;                            /* Bilan à retourner           */
+    SymbolStatus status;                    /* Visibilité du symbole obtenu*/
     SymbolType type;                        /* Type associé au symbole     */
 
-    type = g_binary_symbol_get_target_type(symbol);
+    status = g_binary_symbol_get_status(symbol);
 
-    if (type != STP_ROUTINE && type != STP_ENTRY_POINT && type != STP_OBJECT)
+    if (status == SSS_IMPORTED)
         result = false;
 
     else
-        result = is_content_matching(panel->filter, g_binary_symbol_get_label(symbol), match);
+    {
+        type = g_binary_symbol_get_target_type(symbol);
+
+        if (type != STP_ROUTINE && type != STP_ENTRY_POINT && type != STP_OBJECT)
+            result = false;
+
+        else
+            result = is_content_matching(panel->filter, g_binary_symbol_get_label(symbol), match);
+
+    }
 
     return result;
 
diff --git a/src/panels/strings.c b/src/panels/strings.c
index c7fd393..c60ef0a 100644
--- a/src/panels/strings.c
+++ b/src/panels/strings.c
@@ -135,6 +135,8 @@ void handle_new_exe_on_strings_panel(GtkWidget *panel, const GExeFormat *format)
 
     for (i = 0; i < count; i++)
     {
+        if (g_binary_symbol_get_status(symbols[i]) == SSS_IMPORTED) continue;
+
         if (g_binary_symbol_get_target_type(symbols[i]) != STP_STRING) continue;
 
         range = g_binary_symbol_get_range(symbols[i]);
-- 
cgit v0.11.2-87-g4458