From b070fb755b9e32bfa80e8854606f431d285ca23e Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Mon, 6 Aug 2018 23:34:51 +0200
Subject: Extended the API to allow obfuscators detections.

---
 plugins/pychrysalide/analysis/loaded.c | 55 ++++++++++++++++++++++++++++++++++
 src/analysis/loaded.c                  | 28 +++++++++++++++++
 src/analysis/loaded.h                  |  3 ++
 src/analysis/routine.c                 |  2 +-
 src/analysis/routine.h                 |  2 +-
 src/plugins/pglist.h                   |  5 ++++
 src/plugins/plugin-def.h               |  8 +++++
 src/plugins/plugin-int.h               |  5 ++++
 src/plugins/plugin.c                   | 30 +++++++++++++++++++
 src/plugins/plugin.h                   |  3 ++
 10 files changed, 139 insertions(+), 2 deletions(-)

diff --git a/plugins/pychrysalide/analysis/loaded.c b/plugins/pychrysalide/analysis/loaded.c
index 0c94a88..9b280a2 100644
--- a/plugins/pychrysalide/analysis/loaded.c
+++ b/plugins/pychrysalide/analysis/loaded.c
@@ -26,6 +26,7 @@
 
 
 #include <assert.h>
+#include <malloc.h>
 #include <pygobject.h>
 
 
@@ -42,6 +43,9 @@ static PyObject *py_loaded_content_analyze(PyObject *, PyObject *);
 /* Lance l'analyse de l'élément chargé et attend sa conclusion. */
 static PyObject *py_loaded_content_analyze_and_wait(PyObject *, PyObject *);
 
+/* Etablit une liste d'obscurcissements présents. */
+static PyObject *py_loaded_content_detect_obfuscators(PyObject *, PyObject *);
+
 /* Détermine le nombre de vues disponibles pour un contenu. */
 static PyObject *py_loaded_content_count_views(PyObject *, PyObject *);
 
@@ -106,6 +110,52 @@ static PyObject *py_loaded_content_analyze_and_wait(PyObject *self, PyObject *ar
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : self = contenu binaire à manipuler.                          *
+*                args = non utilisé ici.                                      *
+*                                                                             *
+*  Description : Etablit une liste d'obscurcissements présents.               *
+*                                                                             *
+*  Retour      : Désignations humaines correspondantes.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_loaded_content_detect_obfuscators(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Bilan à retourner           */
+    int version;                            /* Avec la version si possible */
+    int ret;                                /* Bilan de lecture des args.  */
+    GLoadedContent *content;                /* Version GLib de l'élément   */
+    size_t count;                           /* Nombre de détections        */
+    char **detections;                      /* Liste d'obscurcissements    */
+    size_t i;                               /* Boucle de parcours          */
+
+    ret = PyArg_ParseTuple(args, "p", &version);
+    if (!ret) Py_RETURN_NONE;
+
+    content = G_LOADED_CONTENT(pygobject_get(self));
+
+    detections = g_loaded_content_detect_obfuscators(content, version, &count);
+
+    result = PyTuple_New(count);
+
+    for (i = 0; i < count; i++)
+    {
+        PyTuple_SetItem(result, i, PyUnicode_FromString(detections[i]));
+        free(detections[i]);
+    }
+
+    if (detections != NULL)
+        free(detections);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : self = contenu chargé à manipuler.                           *
 *                args = non utilisé ici.                                      *
 *                                                                             *
@@ -162,6 +212,11 @@ PyTypeObject *get_python_loaded_content_type(void)
             "wait for its completion."
         },
         {
+            "detect_obfuscators", py_loaded_content_detect_obfuscators,
+            METH_VARARGS,
+            "detect_obfuscators($self, version, /)\n--\n\nList all detected obfuscators."
+        },
+        {
             "count_views", py_loaded_content_count_views,
             METH_NOARGS,
             "count_views($self, /)\n--\n\nCompute the quantity of available views."
diff --git a/src/analysis/loaded.c b/src/analysis/loaded.c
index a035e5e..9b7a2ff 100644
--- a/src/analysis/loaded.c
+++ b/src/analysis/loaded.c
@@ -370,6 +370,34 @@ const char *g_loaded_content_describe(const GLoadedContent *content, bool full)
 }
 
 
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = élément chargé à consulter.                        *
+*                version = précise si les versions doivent être recherchées.  *
+*                count   = nombre de types d'obscurcissement trouvés. [OUT]   *
+*                                                                             *
+*  Description : Etablit une liste d'obscurcissements présents.               *
+*                                                                             *
+*  Retour      : Désignations humaines correspondantes à libérer après usage  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+char **g_loaded_content_detect_obfuscators(const GLoadedContent *content, bool version, size_t *count)
+{
+    char **result;                          /* Liste à retourner           */
+
+    result = NULL;
+    *count = 0;
+
+    detect_external_tools(PGA_DETECTION_OBFUSCATORS, content, version, &result, count);
+
+    return result;
+
+}
+
+
 
 /* ---------------------------------------------------------------------------------- */
 /*                             GESTION DYNAMIQUE DES VUES                             */
diff --git a/src/analysis/loaded.h b/src/analysis/loaded.h
index 71e1ff6..60d1fce 100644
--- a/src/analysis/loaded.h
+++ b/src/analysis/loaded.h
@@ -79,6 +79,9 @@ bool g_loaded_content_analyze_and_wait(GLoadedContent *);
 /* Fournit le désignation associée à l'élément chargé. */
 const char *g_loaded_content_describe(const GLoadedContent *, bool);
 
+/* Etablit une liste d'obscurcissements présents. */
+char **g_loaded_content_detect_obfuscators(const GLoadedContent *, bool, size_t *);
+
 
 
 /* --------------------------- GESTION DYNAMIQUE DES VUES --------------------------- */
diff --git a/src/analysis/routine.c b/src/analysis/routine.c
index 3b47930..edb9cb3 100644
--- a/src/analysis/routine.c
+++ b/src/analysis/routine.c
@@ -491,7 +491,7 @@ size_t g_binary_routine_get_args_count(const GBinRoutine *routine)
 *                                                                             *
 ******************************************************************************/
 
-GBinVariable *g_binary_routine_get_arg(GBinRoutine *routine, size_t index)
+GBinVariable *g_binary_routine_get_arg(const GBinRoutine *routine, size_t index)
 {
     GBinVariable *result;                   /* Argument à retourner        */
 
diff --git a/src/analysis/routine.h b/src/analysis/routine.h
index e1512a8..1a2cd92 100644
--- a/src/analysis/routine.h
+++ b/src/analysis/routine.h
@@ -105,7 +105,7 @@ void g_binary_routine_add_arg(GBinRoutine *, GBinVariable *);
 size_t g_binary_routine_get_args_count(const GBinRoutine *);
 
 /* Fournit un argument d'une routine. */
-GBinVariable *g_binary_routine_get_arg(GBinRoutine *, size_t);
+GBinVariable *g_binary_routine_get_arg(const GBinRoutine *, size_t);
 
 /* Retire un argument d'une routine. */
 void g_binary_routine_remove_arg(GBinRoutine *, size_t);
diff --git a/src/plugins/pglist.h b/src/plugins/pglist.h
index b2635eb..7cc4416 100644
--- a/src/plugins/pglist.h
+++ b/src/plugins/pglist.h
@@ -109,6 +109,11 @@ GPluginModule **get_all_plugins_for_action(PluginAction, size_t *);
 #define process_disassembly_event(a, b, s, c) \
     process_all_plugins_for(a, g_plugin_module_process_disassembly_event, b, s, c)
 
+/* DPS_DETECTION */
+
+#define detect_external_tools(a, cnt, v, n, c) \
+    process_all_plugins_for(a, g_plugin_module_detect_external_tools, cnt, v, n, c)
+
 
 
 #endif  /* _PLUGINS_PGLIST_H */
diff --git a/src/plugins/plugin-def.h b/src/plugins/plugin-def.h
index 6bc2086..b8b0e0d 100644
--- a/src/plugins/plugin-def.h
+++ b/src/plugins/plugin-def.h
@@ -83,6 +83,7 @@ typedef uint32_t plugin_action_t;
 #define DPS_CONTENT             DEFINE_PLUGIN_SUB_CATEGORY(0)
 #define DPS_FORMAT              DEFINE_PLUGIN_SUB_CATEGORY(1)
 #define DPS_DISASSEMBLY         DEFINE_PLUGIN_SUB_CATEGORY(2)
+#define DPS_DETECTION           DEFINE_PLUGIN_SUB_CATEGORY(3)
 
 // GUI -> project
 // binary loaded
@@ -172,6 +173,13 @@ typedef enum _PluginAction
     /* Désassemblage fini */
     PGA_DISASSEMBLY_ENDED       = DPC_BINARY_PROCESSING | DPS_DISASSEMBLY | DEFINE_PLUGIN_ACTION(9),
 
+    /**
+     * DPC_BINARY_PROCESSING | DPS_DETECTION
+     */
+
+    /* Intervention en toute fin d'analyse de contenu chargé */
+    PGA_DETECTION_OBFUSCATORS = DPC_BINARY_PROCESSING | DPS_DETECTION | DEFINE_PLUGIN_ACTION(0),
+
 
 
 
diff --git a/src/plugins/plugin-int.h b/src/plugins/plugin-int.h
index 04b87bb..d04d9ab 100644
--- a/src/plugins/plugin-int.h
+++ b/src/plugins/plugin-int.h
@@ -59,6 +59,9 @@ typedef bool (* pg_handle_format_fc) (const GPluginModule *, PluginAction, GBinF
 /* Procède à un préchargement de format de fichier. */
 typedef bool (* pg_preload_format_fc) (const GPluginModule *, PluginAction, GBinFormat *, GPreloadInfo *, GtkStatusStack *);
 
+/* Effectue la détection d'effets d'outils externes. */
+typedef void (* pg_detect_tools_fc) (const GPluginModule *, PluginAction, const GLoadedContent *, bool, char ***, size_t *);
+
 
 
 
@@ -124,6 +127,8 @@ struct _GPluginModule
     pg_handle_format_fc handle_format;      /* Manipulation du format      */
     pg_preload_format_fc preload_format;    /* Préchargement d'un format   */
 
+    pg_detect_tools_fc detect;              /* Lancement de détections     */
+
 };
 
 
diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c
index de9c953..7780f43 100644
--- a/src/plugins/plugin.c
+++ b/src/plugins/plugin.c
@@ -373,6 +373,12 @@ GPluginModule *g_plugin_module_new(const gchar *filename)
                             goto bad_plugin;
                         break;
 
+                    case DPS_DETECTION:
+                        if (!load_plugin_symbol(result->module,
+                                                "chrysalide_plugin_detect_external_tools", &result->detect))
+                            goto bad_plugin;
+                        break;
+
                     default:
                         log_variadic_message(LMT_WARNING,
                                              _("Unknown sub-category '0x%02x' in plugin '%s'..."), sub, filename);
@@ -847,3 +853,27 @@ void g_plugin_module_process_disassembly_event(const GPluginModule *plugin, Plug
     plugin->process_disass(plugin, action, binary, status, context);
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : plugin  = greffon à manipuler.                               *
+*                action  = type d'action attendue.                            *
+*                content = élément chargé à consulter.                        *
+*                version = précise si les versions doivent être recherchées.  *
+*                names   = désignations humaines correspondantes, à libérer.  *
+*                count   = nombre de types d'obscurcissement trouvés. [OUT]   *
+*                                                                             *
+*  Description : Effectue la détection d'effets d'outils externes.            *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_plugin_module_detect_external_tools(const GPluginModule *plugin, PluginAction action, const GLoadedContent *content, bool version, char ***names, size_t *count)
+{
+    plugin->detect(plugin, action, content, version, names, count);
+
+}
diff --git a/src/plugins/plugin.h b/src/plugins/plugin.h
index d0aeb28..a73cc6f 100644
--- a/src/plugins/plugin.h
+++ b/src/plugins/plugin.h
@@ -106,6 +106,9 @@ bool g_plugin_module_preload_binary_format(const GPluginModule *, PluginAction,
 /* Exécute une action pendant un désassemblage de binaire. */
 void g_plugin_module_process_disassembly_event(const GPluginModule *, PluginAction, GLoadedBinary *, GtkStatusStack *, GProcContext *);
 
+/* Effectue la détection d'effets d'outils externes. */
+void g_plugin_module_detect_external_tools(const GPluginModule *, PluginAction, const GLoadedContent *, bool, char ***, size_t *);
+
 
 
 #endif  /* _PLUGINS_PLUGIN_H */
-- 
cgit v0.11.2-87-g4458