diff options
Diffstat (limited to 'plugins/ropgadgets/finder.c')
-rw-r--r-- | plugins/ropgadgets/finder.c | 119 |
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); + +} |