summaryrefslogtreecommitdiff
path: root/plugins/ropgadgets/finder.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/ropgadgets/finder.c')
-rw-r--r--plugins/ropgadgets/finder.c119
1 files changed, 97 insertions, 22 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);
+
+}