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