From 0c638aecff9482b93621d77279ac77a8788584e9 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 1 Mar 2020 23:54:45 +0100
Subject: Given some priority to Elf PLT entries during the disassembly
 process.

---
 plugins/arm/v7/context.c              |  1 +
 plugins/elf/symbols.c                 | 37 +++++++++++++++---------
 plugins/mobicore/symbols.c            |  4 +--
 plugins/pychrysalide/arch/constants.c | 42 +++++++++++++++++++++++++++
 plugins/pychrysalide/arch/constants.h |  3 ++
 plugins/pychrysalide/arch/context.c   |  4 +++
 plugins/pychrysalide/format/format.c  |  6 ++--
 src/arch/context.h                    |  1 +
 src/format/executable.c               |  4 +--
 src/format/flat.c                     |  8 ++++--
 src/format/format-int.h               | 12 +++-----
 src/format/format.c                   | 54 ++++++++++++++---------------------
 src/format/format.h                   |  2 +-
 13 files changed, 113 insertions(+), 65 deletions(-)

diff --git a/plugins/arm/v7/context.c b/plugins/arm/v7/context.c
index ed9cf2f..f028f05 100644
--- a/plugins/arm/v7/context.c
+++ b/plugins/arm/v7/context.c
@@ -216,6 +216,7 @@ static void g_armv7_context_push_drop_point(GArmV7Context *ctx, DisassPriorityLe
     switch (level)
     {
         case DPL_ENTRY_POINT:
+        case DPL_FORMAT_POINT:
         case DPL_SYMBOL:
 
             if (addr & 0x1)
diff --git a/plugins/elf/symbols.c b/plugins/elf/symbols.c
index 2a164a0..004ac6a 100644
--- a/plugins/elf/symbols.c
+++ b/plugins/elf/symbols.c
@@ -109,10 +109,10 @@ static bool load_imported_elf_symbols(GElfFormat *, wgroup_id_t, GtkStatusStack
 
 
 /* Enregistre un point d'entrée au sein d'un binaire ELF. */
-static bool register_elf_entry_point(GElfFormat *, virt_t, GBinRoutine *);
+static bool register_elf_entry_point(GElfFormat *, virt_t, GBinRoutine *, DisassPriorityLevel);
 
 /* Désigne tous les points d'entrée par une étiquette dédiée. */
-static bool load_elf_entry_points_from_array(GElfFormat *, const elf_dyn *, const elf_dyn *, const char *);
+static bool load_elf_entry_points_from_array(GElfFormat *, const elf_dyn *, const elf_dyn *, const char *, DisassPriorityLevel);
 
 /* Enumère tous les points d'entrée principaux d'un binaire ELF. */
 static bool load_all_elf_basic_entry_points(GElfFormat *, GtkStatusStack *);
@@ -295,7 +295,7 @@ static bool do_elf_symbol_loading(GElfLoading *loading, GElfFormat *format, bool
 
             /* Comptabilisation pour le désassemblage brut */
 
-            g_binary_format_register_code_point(base, original_virt, false);
+            g_binary_format_register_code_point(base, original_virt, DPL_SYMBOL);
 
             break;
 
@@ -982,6 +982,10 @@ static GBinSymbol *do_elf_relocation_convert(GElfLoading *loading, GElfFormat *f
 
     g_binary_symbol_set_status(result, SSS_IMPORTED);
 
+    /* Comptabilisation pour le désassemblage brut */
+
+    g_binary_format_register_code_point(G_BIN_FORMAT(format), start.virtual, DPL_FORMAT_POINT);
+
  exit:
 
     return result;
@@ -1165,6 +1169,7 @@ static bool load_imported_elf_symbols(GElfFormat *format, wgroup_id_t gid, GtkSt
 *  Paramètres  : format  = description de l'exécutable à compléter.           *
 *                vaddr   = adresse virtuelle du symbole à insérer.            *
 *                routine = représentation de la fonction repérée.             *
+*                level   = indication de priorité et d'origine de l'adresse.  *
 *                                                                             *
 *  Description : Enregistre un point d'entrée au sein d'un binaire ELF.       *
 *                                                                             *
@@ -1174,7 +1179,7 @@ static bool load_imported_elf_symbols(GElfFormat *format, wgroup_id_t gid, GtkSt
 *                                                                             *
 ******************************************************************************/
 
-static bool register_elf_entry_point(GElfFormat *format, virt_t vaddr, GBinRoutine *routine)
+static bool register_elf_entry_point(GElfFormat *format, virt_t vaddr, GBinRoutine *routine, DisassPriorityLevel level)
 {
     bool result;                            /* Bilan à renvoyer            */
     virt_t final_vaddr;                     /* Adresse virtuelle retenue   */
@@ -1226,7 +1231,7 @@ static bool register_elf_entry_point(GElfFormat *format, virt_t vaddr, GBinRouti
     g_object_unref(G_OBJECT(symbol));
 
     /* Comptabilisation pour le désassemblage brut */
-    g_binary_format_register_code_point(base, vaddr, true);
+    g_binary_format_register_code_point(base, vaddr, level);
 
  exit:
 
@@ -1241,6 +1246,7 @@ static bool register_elf_entry_point(GElfFormat *format, virt_t vaddr, GBinRouti
 *                array  = indications quant au tableau à charger.             *
 *                size   = indications quant à la taille de ce tableau.        *
 *                prefix = désignation de base des éléments du tableau.        *
+*                level  = indication de priorité et d'origine de l'adresse.   *
 *                                                                             *
 *  Description : Désigne tous les points d'entrée par une étiquette dédiée.   *
 *                                                                             *
@@ -1250,7 +1256,7 @@ static bool register_elf_entry_point(GElfFormat *format, virt_t vaddr, GBinRouti
 *                                                                             *
 ******************************************************************************/
 
-static bool load_elf_entry_points_from_array(GElfFormat *format, const elf_dyn *array, const elf_dyn *size, const char *prefix)
+static bool load_elf_entry_points_from_array(GElfFormat *format, const elf_dyn *array, const elf_dyn *size, const char *prefix, DisassPriorityLevel level)
 {
     bool result;                            /* Bilan à renvoyer            */
     GBinFormat *base;                       /* Autre version du format     */
@@ -1313,7 +1319,7 @@ static bool load_elf_entry_points_from_array(GElfFormat *format, const elf_dyn *
             snprintf(fullname, sizeof(fullname), "%s%u", prefix, i);
 
             routine = g_binary_format_decode_routine(base, fullname);
-            result = register_elf_entry_point(format, ep, routine);
+            result = register_elf_entry_point(format, ep, routine, level);
 
         }
 
@@ -1363,7 +1369,7 @@ static bool load_all_elf_basic_entry_points(GElfFormat *format, GtkStatusStack *
     if (ep != 0x0)
     {
         routine = g_binary_format_decode_routine(base, "entry_point");
-        result = register_elf_entry_point(format, ep, routine);
+        result = register_elf_entry_point(format, ep, routine, DPL_ENTRY_POINT);
         if (!result) goto exit;
     }
 
@@ -1381,7 +1387,7 @@ static bool load_all_elf_basic_entry_points(GElfFormat *format, GtkStatusStack *
         if (ep != 0x0)
         {
             routine = g_binary_format_decode_routine(base, "init_function");
-            result = register_elf_entry_point(format, ep, routine);
+            result = register_elf_entry_point(format, ep, routine, DPL_ENTRY_POINT);
             if (!result) goto exit;
         }
 
@@ -1394,7 +1400,7 @@ static bool load_all_elf_basic_entry_points(GElfFormat *format, GtkStatusStack *
         if (ep != 0x0)
         {
             routine = g_binary_format_decode_routine(base, "termination_function");
-            result = register_elf_entry_point(format, ep, routine);
+            result = register_elf_entry_point(format, ep, routine, DPL_FORMAT_POINT);
             if (!result) goto exit;
         }
 
@@ -1404,7 +1410,8 @@ static bool load_all_elf_basic_entry_points(GElfFormat *format, GtkStatusStack *
     {
         if (_find_elf_dynamic_item_by_type(format, &dynamic, DT_INIT_ARRAYSZ, &item_b))
         {
-            result = load_elf_entry_points_from_array(format, &item_a, &item_b, "init_array_function_");
+            result = load_elf_entry_points_from_array(format, &item_a, &item_b,
+                                                      "init_array_function_", DPL_ENTRY_POINT);
             if (!result) goto exit;
         }
 
@@ -1414,7 +1421,8 @@ static bool load_all_elf_basic_entry_points(GElfFormat *format, GtkStatusStack *
     {
         if (_find_elf_dynamic_item_by_type(format, &dynamic, DT_FINI_ARRAYSZ, &item_b))
         {
-            result = load_elf_entry_points_from_array(format, &item_a, &item_b, "fini_array_function_");
+            result = load_elf_entry_points_from_array(format, &item_a, &item_b,
+                                                      "fini_array_function_", DPL_FORMAT_POINT);
             if (!result) goto exit;
         }
 
@@ -1424,7 +1432,8 @@ static bool load_all_elf_basic_entry_points(GElfFormat *format, GtkStatusStack *
     {
         if (_find_elf_dynamic_item_by_type(format, &dynamic, DT_PREINIT_ARRAYSZ, &item_b))
         {
-            result = load_elf_entry_points_from_array(format, &item_a, &item_b, "preinit_array_function_");
+            result = load_elf_entry_points_from_array(format, &item_a, &item_b,
+                                                      "preinit_array_function_", DPL_ENTRY_POINT);
             if (!result) goto exit;
         }
 
@@ -1437,7 +1446,7 @@ static bool load_all_elf_basic_entry_points(GElfFormat *format, GtkStatusStack *
         if (ep != 0x0)
         {
             routine = g_binary_format_decode_routine(base, "plt_entry");
-            result = register_elf_entry_point(format, ep, routine);
+            result = register_elf_entry_point(format, ep, routine, DPL_FORMAT_POINT);
         }
 
     }
diff --git a/plugins/mobicore/symbols.c b/plugins/mobicore/symbols.c
index a0425ee..2523cbc 100644
--- a/plugins/mobicore/symbols.c
+++ b/plugins/mobicore/symbols.c
@@ -68,9 +68,7 @@ static void register_mclf_entry_point(GMCLFFormat *format, virt_t vaddr, phys_t
 
     /* Comptabilisation pour le désassemblage brut */
 
-    base->entry_points = (virt_t *)realloc(base->entry_points, ++base->ep_count * sizeof(virt_t));
-
-    base->entry_points[base->ep_count - 1] = vaddr;
+    g_binary_format_register_code_point(base, vaddr, DPL_ENTRY_POINT);
 
     /* Comptabilisation en tant que symbole */
 
diff --git a/plugins/pychrysalide/arch/constants.c b/plugins/pychrysalide/arch/constants.c
index b7dd8a1..f738ec3 100644
--- a/plugins/pychrysalide/arch/constants.c
+++ b/plugins/pychrysalide/arch/constants.c
@@ -150,3 +150,45 @@ bool define_arch_vmpa_constants(PyTypeObject *type)
     return result;
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type = type dont le dictionnaire est à compléter.            *
+*                                                                             *
+*  Description : Définit les constantes relatives aux contextes.              *
+*                                                                             *
+*  Retour      : true en cas de succès de l'opération, false sinon.           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool define_proc_context_constants(PyTypeObject *type)
+{
+    bool result;                            /* Bilan à retourner           */
+    PyObject *values;                       /* Groupe de valeurs à établir */
+
+    values = PyDict_New();
+
+    result = add_const_to_group(values, "ENTRY_POINT", DPL_ENTRY_POINT);
+    if (result) result = add_const_to_group(values, "FORMAT_POINT", DPL_FORMAT_POINT);
+    if (result) result = add_const_to_group(values, "SYMBOL", DPL_SYMBOL);
+    if (result) result = add_const_to_group(values, "OTHER", DPL_OTHER);
+    if (result) result = add_const_to_group(values, "COUNT", DPL_COUNT);
+
+    if (!result)
+    {
+        Py_DECREF(values);
+        goto exit;
+    }
+
+    result = attach_constants_group_to_type(type, true, "DisassPriorityLevel", values,
+                                            "Level of priority for a given point during the" \
+                                            " disassembling process.");
+
+ exit:
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/arch/constants.h b/plugins/pychrysalide/arch/constants.h
index ecd6ce8..f047c56 100644
--- a/plugins/pychrysalide/arch/constants.h
+++ b/plugins/pychrysalide/arch/constants.h
@@ -37,6 +37,9 @@ bool define_arch_instruction_constants(PyTypeObject *);
 /* Définit les constantes relatives aux emplacements. */
 bool define_arch_vmpa_constants(PyTypeObject *);
 
+/* Définit les constantes relatives aux contextes. */
+bool define_proc_context_constants(PyTypeObject *);
+
 
 
 #endif  /* _PLUGINS_PYCHRYSALIDE_ARCH_CONSTANTS_H */
diff --git a/plugins/pychrysalide/arch/context.c b/plugins/pychrysalide/arch/context.c
index 4428075..f7c6549 100644
--- a/plugins/pychrysalide/arch/context.c
+++ b/plugins/pychrysalide/arch/context.c
@@ -32,6 +32,7 @@
 #include <arch/context.h>
 
 
+#include "constants.h"
 #include "../access.h"
 #include "../helpers.h"
 
@@ -111,6 +112,9 @@ bool ensure_python_proc_context_is_registered(void)
         if (!register_class_for_pygobject(dict, G_TYPE_PROC_CONTEXT, type, &PyGObject_Type))
             return false;
 
+        if (!define_proc_context_constants(type))
+            return false;
+
     }
 
     return true;
diff --git a/plugins/pychrysalide/format/format.c b/plugins/pychrysalide/format/format.c
index 6cd706c..3709f6d 100644
--- a/plugins/pychrysalide/format/format.c
+++ b/plugins/pychrysalide/format/format.c
@@ -118,16 +118,16 @@ static bool define_python_binary_format_constants(PyTypeObject *);
 static PyObject *py_binary_format_register_code_point(PyObject *self, PyObject *args)
 {
     unsigned long long pt;                  /* Adresse virtuelle du point  */
-    int entry;                              /* Nature du point fourni      */
+    unsigned long level;                    /* Nature du point fourni      */
     int ret;                                /* Bilan de lecture des args.  */
     GBinFormat *format;                     /* Format de binaire manipulé  */
 
-    ret = PyArg_ParseTuple(args, "Kp", &pt, &entry);
+    ret = PyArg_ParseTuple(args, "Kk", &pt, &level);
     if (!ret) return NULL;
 
     format = G_BIN_FORMAT(pygobject_get(self));
 
-    g_binary_format_register_code_point(format, pt, entry);
+    g_binary_format_register_code_point(format, pt, level);
 
     Py_RETURN_NONE;
 
diff --git a/src/arch/context.h b/src/arch/context.h
index 4b37cdb..255909f 100644
--- a/src/arch/context.h
+++ b/src/arch/context.h
@@ -53,6 +53,7 @@ typedef struct _GProcContextClass GProcContextClass;
 typedef enum _DisassPriorityLevel
 {
     DPL_ENTRY_POINT,                        /* Validité indiscutable       */
+    DPL_FORMAT_POINT,                       /* Entrée liée au format #2    */
     DPL_SYMBOL,                             /* Symboles utilisés           */
     DPL_OTHER,                              /* Injections complémentaires  */
 
diff --git a/src/format/executable.c b/src/format/executable.c
index b081f64..553b157 100644
--- a/src/format/executable.c
+++ b/src/format/executable.c
@@ -286,8 +286,8 @@ bool g_exe_format_get_main_address(GExeFormat *format, vmpa2t *addr)
 
         g_rw_lock_reader_lock(&base->pt_lock);
 
-        if (base->ep_count > 0)
-            result = g_exe_format_translate_address_into_vmpa(format, base->entry_points[0], addr);
+        if (base->pt_count[DPL_ENTRY_POINT] > 0)
+            result = g_exe_format_translate_address_into_vmpa(format, base->start_points[DPL_ENTRY_POINT][0], addr);
 
         g_rw_lock_reader_unlock(&base->pt_lock);
 
diff --git a/src/format/flat.c b/src/format/flat.c
index 1ae813a..a9081d8 100644
--- a/src/format/flat.c
+++ b/src/format/flat.c
@@ -377,10 +377,14 @@ static bool g_flat_format_get_main_address(GFlatFormat *format, vmpa2t *addr)
 
     base = G_BIN_FORMAT(format);
 
-    result = (base->ep_count > 0);
+    g_rw_lock_reader_lock(&base->pt_lock);
+
+    result = (base->pt_count[DPL_ENTRY_POINT] > 0);
 
     if (result)
-        init_vmpa(addr, 0, base->entry_points[0]);
+        init_vmpa(addr, 0, base->start_points[DPL_ENTRY_POINT][0]);
+
+    g_rw_lock_reader_unlock(&base->pt_lock);
 
     return result;
 
diff --git a/src/format/format-int.h b/src/format/format-int.h
index d5ee2b4..c8f2b1a 100644
--- a/src/format/format-int.h
+++ b/src/format/format-int.h
@@ -54,7 +54,7 @@ typedef void (* format_complete_analysis_fc) (GBinFormat *, wgroup_id_t, GtkStat
 
 
 /* Rythme des allocations pour les entrées de code */
-#define EXTRA_POINT_BLOCK 100
+#define EXTRA_POINT_BLOCK 20
 
 
 /* Description d'une erreur */
@@ -75,13 +75,9 @@ struct _GBinFormat
 
     GBinContent *content;                   /* Contenu binaire à étudier   */
 
-    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*/
-
+    virt_t *start_points[DPL_COUNT];        /* Départ de désassemblage     */
+    size_t pt_allocated[DPL_COUNT];         /* Taille d'inscription allouée*/
+    size_t pt_count[DPL_COUNT];             /* Nombre de points enregistrés*/
     GRWLock pt_lock;                        /* Accès à la liste des points */
 
     GPreloadInfo *info;                     /* Préchargements du format    */
diff --git a/src/format/format.c b/src/format/format.c
index e782996..533d641 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -192,22 +192,21 @@ static void g_binary_format_dispose(GBinFormat *format)
 
 static void g_binary_format_finalize(GBinFormat *format)
 {
-    size_t i;                               /* Boucle de parcours          */
-
-    if (format->entry_points != NULL)
-        free(format->entry_points);
+    DisassPriorityLevel i;                  /* Boucle de parcours #1       */
+    size_t k;                               /* Boucle de parcours #2       */
 
-    if (format->extra_points != NULL)
-        free(format->extra_points);
+    for (i = 0; i < DPL_COUNT; i++)
+        if (format->start_points[i] != NULL)
+            free(format->start_points[i]);
 
     if (format->symbols != NULL)
         free(format->symbols);
 
     if (format->errors != NULL)
     {
-        for (i = 0; i < format->error_count; i++)
-            if (format->errors[i].desc != NULL)
-                free(format->errors[i].desc);
+        for (k = 0; k < format->error_count; k++)
+            if (format->errors[k].desc != NULL)
+                free(format->errors[k].desc);
 
         free(format->errors);
 
@@ -388,7 +387,7 @@ SourceEndian g_binary_format_get_endianness(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.                             *
+*                level  = indication de priorité et d'origine de l'adresse.   *
 *                                                                             *
 *  Description : Enregistre une adresse comme début d'une zone de code.       *
 *                                                                             *
@@ -398,30 +397,22 @@ SourceEndian g_binary_format_get_endianness(const GBinFormat *format)
 *                                                                             *
 ******************************************************************************/
 
-void g_binary_format_register_code_point(GBinFormat *format, virt_t pt, bool entry)
+void g_binary_format_register_code_point(GBinFormat *format, virt_t pt, DisassPriorityLevel level)
 {
+    assert(level < DPL_COUNT);
+
     g_rw_lock_writer_lock(&format->pt_lock);
 
-    if (entry)
+    if (format->pt_count[level] == format->pt_allocated[level])
     {
-        format->entry_points = realloc(format->entry_points, ++format->ep_count * sizeof(virt_t));
+        format->pt_allocated[level] += EXTRA_POINT_BLOCK;
 
-        format->entry_points[format->ep_count - 1] = pt;
+        format->start_points[level] = realloc(format->start_points[level],
+                                              format->pt_allocated[level] * sizeof(virt_t));
 
     }
-    else
-    {
-        if (format->xp_count == format->xp_allocated)
-        {
-            format->xp_allocated += EXTRA_POINT_BLOCK;
 
-            format->extra_points = realloc(format->extra_points, format->xp_allocated * sizeof(virt_t));
-
-        }
-
-        format->extra_points[format->xp_count++] = pt;
-
-    }
+    format->start_points[level][format->pt_count[level]++] = pt;
 
     g_rw_lock_writer_unlock(&format->pt_lock);
 
@@ -465,15 +456,14 @@ void g_binary_format_preload_disassembling_context(GBinFormat *format, GProcCont
 
 void g_binary_format_activate_disassembling_context(GBinFormat *format, GProcContext *ctx, GtkStatusStack *status)
 {
-    size_t i;                               /* Boucle de parcours          */
+    DisassPriorityLevel i;                  /* Boucle de parcours #1       */
+    size_t k;                               /* Boucle de parcours #2       */
 
     g_rw_lock_reader_lock(&format->pt_lock);
 
-    for (i = 0; i < format->ep_count; i++)
-        g_proc_context_push_drop_point(ctx, DPL_ENTRY_POINT, format->entry_points[i]);
-
-    for (i = 0; i < format->xp_count; i++)
-        g_proc_context_push_drop_point(ctx, DPL_SYMBOL, format->extra_points[i]);
+    for (i = 0; i < DPL_COUNT; i++)
+        for (k = 0; k < format->pt_count[i]; k++)
+            g_proc_context_push_drop_point(ctx, i, format->start_points[i][k]);
 
     g_rw_lock_reader_unlock(&format->pt_lock);
 
diff --git a/src/format/format.h b/src/format/format.h
index 450ebdc..626bb8a 100644
--- a/src/format/format.h
+++ b/src/format/format.h
@@ -76,7 +76,7 @@ bool g_binary_format_analyze(GBinFormat *, wgroup_id_t, GtkStatusStack *);
 SourceEndian g_binary_format_get_endianness(const GBinFormat *);
 
 /* Enregistre une adresse comme début d'une zone de code. */
-void g_binary_format_register_code_point(GBinFormat *, virt_t, bool);
+void g_binary_format_register_code_point(GBinFormat *, virt_t, DisassPriorityLevel);
 
 /* Intègre dans un contexte les informations tirées d'un format. */
 void g_binary_format_preload_disassembling_context(GBinFormat *, GProcContext *, GtkStatusStack *);
-- 
cgit v0.11.2-87-g4458