summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/ropgadgets/finder.c119
-rw-r--r--plugins/ropgadgets/finder.h13
-rw-r--r--plugins/ropgadgets/select.c39
3 files changed, 126 insertions, 45 deletions
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);