From 836e4ca6053594ceba7b78b8407d8a1f03491cd2 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 1 Jan 2017 12:03:43 +0100
Subject: Removed usage of deprecated functions when looking for ROP gadgets.

---
 ChangeLog                   |   7 +++
 plugins/ropgadgets/finder.c | 119 ++++++++++++++++++++++++++++++++++++--------
 plugins/ropgadgets/finder.h |  13 ++++-
 plugins/ropgadgets/select.c |  39 +++++++--------
 4 files changed, 133 insertions(+), 45 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 40fa0c4..1c81be7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+17-01-01  Cyrille Bagard <nocbos@gmail.com>
+
+	* plugins/ropgadgets/finder.c:
+	* plugins/ropgadgets/finder.h:
+	* plugins/ropgadgets/select.c:
+	Remove usage of deprecated functions when looking for ROP gadgets.
+
 16-12-31  Cyrille Bagard <nocbos@gmail.com>
 
 	* *.[ch]:
diff --git a/plugins/ropgadgets/finder.c b/plugins/ropgadgets/finder.c
index 8fb620a..69d9959 100644
--- a/plugins/ropgadgets/finder.c
+++ b/plugins/ropgadgets/finder.c
@@ -24,16 +24,15 @@
 #include "finder.h"
 
 
+#include <malloc.h>
 #include <string.h>
 
 
+#include <i18n.h>
 #include <core/processors.h>
 #include <format/format.h>
 
 
-#include <i18n.h>
-
-
 #include "helper_arm.h"
 
 
@@ -59,11 +58,14 @@ typedef struct _search_domain
 /* Désassemble rapidement une instruction. */
 static GArchInstruction *disassemble_instruction_in_domain(const search_domain *, vmpa2t *);
 
+/* Etend la constitution d'une chaîne d'instructions. */
+static rop_chain *push_new_instruction(rop_chain *, GArchInstruction *);
+
 /* Désassemble en amont d'une position autant que possible. */
-static GArchInstruction *look_backward_for_gadgets(const search_domain *, const mrange_t *, const vmpa2t *, unsigned int);
+static void look_backward_for_gadgets(const search_domain *, const mrange_t *, const vmpa2t *, unsigned int, rop_chain *);
 
 /* Etablit une liste de tous les gadgets présents. */
-static GArchInstruction **list_all_gadgets_in_domain(const search_domain *, unsigned int, update_search_progress_cb, GObject *, size_t *);
+static rop_chain **list_all_gadgets_in_domain(const search_domain *, unsigned int, update_search_progress_cb, GObject *, size_t *);
 
 
 
@@ -104,10 +106,55 @@ static GArchInstruction *disassemble_instruction_in_domain(const search_domain *
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : instrs = liste d'instructions à compléter ou NULL.           *
+*                instr  = nouvelle instruction à ajouter.                     *
+*                                                                             *
+*  Description : Etend la constitution d'une chaîne d'instructions.           *
+*                                                                             *
+*  Retour      : Série d'instruction complétée.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static rop_chain *push_new_instruction(rop_chain *chain, GArchInstruction *instr)
+{
+    rop_chain *result;                      /* Chaîne à retourner          */
+
+    if (chain == NULL)
+    {
+        result = (rop_chain *)calloc(1, sizeof(rop_chain));
+
+        result->instrs = (GArchInstruction **)calloc(1, sizeof(GArchInstruction *));
+        result->count = 1;
+
+    }
+    else
+    {
+        result = chain;
+
+        result->count++;
+        result->instrs = (GArchInstruction **)realloc(result->instrs, result->count * sizeof(GArchInstruction *));
+
+    }
+
+    if (result->count > 1)
+        memmove(&result->instrs[1], &result->instrs[0], (result->count - 1) * sizeof(GArchInstruction *));
+
+    result->instrs[0] = instr;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : domain    = ensemble d'auxiliaires à disposition.            *
 *                exe_range = couverture globale dont il ne faut pas sortir.   *
 *                ret       = point de retour final déjà trouvé.               *
 *                max_depth = profondeur maximale des recherches.              *
+*                chain     = chaîne d'instructions à compléter. [OUT]         *
 *                                                                             *
 *  Description : Désassemble en amont d'une position autant que possible.     *
 *                                                                             *
@@ -117,9 +164,8 @@ static GArchInstruction *disassemble_instruction_in_domain(const search_domain *
 *                                                                             *
 ******************************************************************************/
 
-static GArchInstruction *look_backward_for_gadgets(const search_domain *domain, const mrange_t *exe_range, const vmpa2t *ret, unsigned int max_depth)
+static void look_backward_for_gadgets(const search_domain *domain, const mrange_t *exe_range, const vmpa2t *ret, unsigned int max_depth, rop_chain *chain)
 {
-    GArchInstruction *result;               /* Liste de gagdets trouvées   */
     const phys_t *ins_sizes;                /* Tailles potentielles        */
     size_t sizes_count;                     /* Quantité de tailles à tester*/
     vmpa2t last;                            /* Dernier point de départ     */
@@ -131,8 +177,6 @@ static GArchInstruction *look_backward_for_gadgets(const search_domain *domain,
     phys_t diff;                            /* Volume de données traité    */
     mrange_t range;                         /* Couverture de l'instruction */
 
-    result = NULL;
-
     ins_sizes = (phys_t []){ 2, 4 };    /* FIXME */
     sizes_count = 2;
 
@@ -187,13 +231,10 @@ static GArchInstruction *look_backward_for_gadgets(const search_domain *domain,
 
         g_arch_instruction_set_range(instr, &range);
 
-
-        g_arch_instruction_merge_lists(&result, &instr);
+        push_new_instruction(chain, instr);
 
     }
 
-    return result;
-
 }
 
 
@@ -213,9 +254,9 @@ static GArchInstruction *look_backward_for_gadgets(const search_domain *domain,
 *                                                                             *
 ******************************************************************************/
 
-static GArchInstruction **list_all_gadgets_in_domain(const search_domain *domain, unsigned int max_depth, update_search_progress_cb update, GObject *data, size_t *count)
+static rop_chain **list_all_gadgets_in_domain(const search_domain *domain, unsigned int max_depth, update_search_progress_cb update, GObject *data, size_t *count)
 {
-    GArchInstruction **result;              /* Liste de listes à renvoyer  */
+    rop_chain **result;                     /* Liste de listes à renvoyer  */
     phys_t done;                            /* Accumulation des quantités  */
     size_t i;                               /* Boucle de parcours #1       */
     phys_t max;                             /* Borne d'un parcours         */
@@ -227,7 +268,7 @@ static GArchInstruction **list_all_gadgets_in_domain(const search_domain *domain
     phys_t diff;                            /* Volume de données traité    */
     mrange_t ins_range;                     /* Emplacement d'une instruct° */
     vmpa2t end;                             /* Point d'arrivée obtenu      */
-    GArchInstruction *new;                  /* Nouvelle liste de gadgets   */
+    rop_chain *chain;                       /* Nouvelle chaîne trouvée     */
 
     result = NULL;
     *count = 0;
@@ -282,14 +323,12 @@ static GArchInstruction **list_all_gadgets_in_domain(const search_domain *domain
 
             g_arch_instruction_set_range(gadget, &ins_range);
 
-            //printf(" ROP @ 0x%08x / 0x%08x\n", gadget->range.addr.virtual, ret.virtual);
-
-            new = look_backward_for_gadgets(domain, &domain->exe_ranges[i], &ret, max_depth);
+            chain = push_new_instruction(NULL, gadget);
 
-            g_arch_instruction_merge_lists(&new, &gadget);
+            look_backward_for_gadgets(domain, &domain->exe_ranges[i], &ret, max_depth, chain);
 
-            result = (GArchInstruction **)realloc(result, ++(*count) * sizeof(GArchInstruction *));
-            result[*count - 1] = new;
+            result = (rop_chain **)realloc(result, ++(*count) * sizeof(rop_chain *));
+            result[*count - 1] = chain;
 
         }
 
@@ -427,3 +466,39 @@ found_rop_list *list_all_gadgets(GExeFormat *format, unsigned int max_depth, upd
     return result;
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list = ensemble de gadgets trouvés à supprimer.              *
+*                                                                             *
+*  Description : Libère la mémoire des gadgets trouvés pour du ROP.           *
+*                                                                             *
+*  Retour      :                                                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void free_rop_list(found_rop_list *list)
+{
+    size_t i;                               /* Boucle de parcours #1       */
+    rop_chain *chain;                       /* Accès direct à une chaîne   */
+    size_t j;                               /* Boucle de parcours #2       */
+
+    for (i = 0; i < list->count; i++)
+    {
+        chain = list->gadgets[i];
+
+        for (j = 0; j < chain->count; j++)
+            g_object_unref(G_OBJECT(chain->instrs[j]));
+
+        free(chain->instrs);
+        free(chain);
+
+    }
+
+    free(list->gadgets);
+    free(list);
+
+}
diff --git a/plugins/ropgadgets/finder.h b/plugins/ropgadgets/finder.h
index a12035e..f12f3ed 100644
--- a/plugins/ropgadgets/finder.h
+++ b/plugins/ropgadgets/finder.h
@@ -34,12 +34,20 @@
 typedef void (* update_search_progress_cb) (GObject *, gdouble);
 
 
+/* Chaîne d'instructions idéales */
+typedef struct _rop_chain
+{
+    GArchInstruction **instrs;              /* Instructions bien combinées */
+    size_t count;                           /* Taille de cette liste       */
+
+} rop_chain;
+
 /* Catégorisation des résultats */
 typedef struct _found_rop_list
 {
     const char *category;                   /* Désignation du groupe       */
 
-    GArchInstruction **gadgets;             /* Gadgets pour ROP trouvés    */
+    rop_chain **gadgets;                    /* Gadgets pour ROP trouvés    */
     size_t count;                           /* Taille de cette liste       */
 
 } found_rop_list;
@@ -48,6 +56,9 @@ typedef struct _found_rop_list
 /* Etablit une liste de tous les gadgets présents. */
 found_rop_list *list_all_gadgets(GExeFormat *, unsigned int, update_search_progress_cb, GObject *, size_t *);
 
+/* Libère la mémoire des gadgets trouvés pour du ROP. */
+void free_rop_list(found_rop_list *);
+
 
 
 #endif  /* _PLUGINS_ROPGADGETS_FINDER_H */
diff --git a/plugins/ropgadgets/select.c b/plugins/ropgadgets/select.c
index 5025ed8..2d8d77d 100644
--- a/plugins/ropgadgets/select.c
+++ b/plugins/ropgadgets/select.c
@@ -211,7 +211,7 @@ static void on_rop_gadgets_filter_changed(GtkSearchEntry *, GObject *);
 static gboolean filter_visible_rop_gadgets(GtkTreeModel *, GtkTreeIter *, GObject *);
 
 /* Ajoute de nouvelles chaînes de gadgets localisées. */
-static void add_new_gadgets_for_category(GExeFormat *, GtkComboBoxText *, GtkTreeStore *, const char *, GArchInstruction **, size_t);
+static void add_new_gadgets_for_category(GExeFormat *, GtkComboBoxText *, GtkTreeStore *, const char *, rop_chain **, size_t);
 
 
 
@@ -1199,7 +1199,7 @@ static gboolean register_found_rop_gadgets(search_step *step)
                                          step->list[i].category, step->list[i].gadgets, step->list[i].count);
 
         if (step->list != NULL)
-            free(step->list);
+            free_rop_list(step->list);
 
     }
 
@@ -1563,17 +1563,6 @@ static void register_rop_list_panel(GtkAssistant *assistant, GObject *ref)
 }
 
 
-
-
-
-
-
-
-
-
-
-
-
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : combo = composant de choix contenant le filtre brut.         *
@@ -1744,18 +1733,20 @@ static gboolean filter_visible_rop_gadgets(GtkTreeModel *model, GtkTreeIter *ite
 *                                                                             *
 ******************************************************************************/
 
-static void add_new_gadgets_for_category(GExeFormat *format, GtkComboBoxText *combo, GtkTreeStore *store, const char *category, GArchInstruction **gadgets, size_t count)
+static void add_new_gadgets_for_category(GExeFormat *format, GtkComboBoxText *combo, GtkTreeStore *store, const char *category, rop_chain **gadgets, size_t count)
 {
     const GBinContent *content;             /* Contenu binaire global      */
-    size_t i;                               /* Boucle de parcours          */
-    GArchInstruction *instr;                /* Elément de liste de gadgets */
-    GBufferLine *line;                      /* Ligne présente à l'adresse  */
+    size_t i;                               /* Boucle de parcours #1       */
     char *raw_virtual;                      /* Transcription pour export   */
     char *virtual;                          /* Transcription d'adresse     */
-    char *partial_raw;                      /* Contenu de la ligne visée   */
-    char *partial_markup;                   /* Contenu de la ligne visée   */
     char *content_raw;                      /* Contenu assemblé de chaîne  */
     char *content_markup;                   /* Contenu assemblé de chaîne  */
+    rop_chain *chain;                       /* Accès direct à une chaîne   */
+    size_t j;                               /* Boucle de parcours #2       */
+    GArchInstruction *instr;                /* Elément de liste de gadgets */
+    GBufferLine *line;                      /* Ligne présente à l'adresse  */
+    char *partial_raw;                      /* Contenu de la ligne visée   */
+    char *partial_markup;                   /* Contenu de la ligne visée   */
     GtkTreeIter iter;                       /* Point d'insertion           */
 
     content = g_binary_format_get_content(G_BIN_FORMAT(format));
@@ -1771,12 +1762,16 @@ static void add_new_gadgets_for_category(GExeFormat *format, GtkComboBoxText *co
         content_raw = NULL;
         content_markup = NULL;
 
-        for (instr = gadgets[i]; instr != NULL; instr = g_arch_instruction_get_next_iter(gadgets[i], instr, ~0))
+        chain = gadgets[i];
+
+        for (j = 0; j < chain->count; j++)
         {
-            line = g_buffer_line_new(NULL, BLC_ASSEMBLY);
+            instr = chain->instrs[j];
+
+            line = g_buffer_line_new((mrange_t []){ { { 0 }, 0 } }, BLC_ASSEMBLY);
             g_line_generator_print(G_LINE_GENERATOR(instr), line, -1, 0);
 
-            if (instr == gadgets[i])
+            if (j == 0)
             {
                 raw_virtual = g_buffer_line_get_text(line, BLC_VIRTUAL, BLC_VIRTUAL + 1, false);
                 virtual = g_buffer_line_get_text(line, BLC_VIRTUAL, BLC_VIRTUAL + 1, true);
-- 
cgit v0.11.2-87-g4458