summaryrefslogtreecommitdiff
path: root/plugins/ropgadgets
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-11-28 18:30:12 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-11-28 18:30:12 (GMT)
commit4da58817622d6c4c35e4cd4e6a99111065a87f54 (patch)
tree4af154a7c68a4f9034700a945df692ccf1313650 /plugins/ropgadgets
parent43c13d32ebaec164879dfadcdf2e341fbce26887 (diff)
Adapted ROP finding to architectures in a better way.
Diffstat (limited to 'plugins/ropgadgets')
-rw-r--r--plugins/ropgadgets/Makefile.am1
-rw-r--r--plugins/ropgadgets/finder.c70
-rw-r--r--plugins/ropgadgets/helper.c110
-rw-r--r--plugins/ropgadgets/helper.h43
-rw-r--r--plugins/ropgadgets/helper_arm.c87
-rw-r--r--plugins/ropgadgets/helper_arm.h8
6 files changed, 269 insertions, 50 deletions
diff --git a/plugins/ropgadgets/Makefile.am b/plugins/ropgadgets/Makefile.am
index 8df1c2e..3302421 100644
--- a/plugins/ropgadgets/Makefile.am
+++ b/plugins/ropgadgets/Makefile.am
@@ -6,6 +6,7 @@ libdir = $(pluginslibdir)
libropgadgets_la_SOURCES = \
finder.h finder.c \
+ helper.h helper.c \
helper_arm.h helper_arm.c \
plugin.h plugin.c \
select.h select.c
diff --git a/plugins/ropgadgets/finder.c b/plugins/ropgadgets/finder.c
index 7296757..3e7ed1a 100644
--- a/plugins/ropgadgets/finder.c
+++ b/plugins/ropgadgets/finder.c
@@ -28,22 +28,33 @@
#include <string.h>
-#include <i18n.h>
#include <core/processors.h>
#include <format/format.h>
+#include "helper.h"
#include "helper_arm.h"
+/* Actions selon l'architecture */
+typedef struct _domain_ops
+{
+ size_t (* list) (char ***);
+ GProcContext * (* get) (const GArchProcessor *, size_t);
+
+ const phys_t * (* setup) (size_t *);
+
+} domain_ops;
+
/* Données utiles à transmettre */
typedef struct _search_domain
{
GExeFormat *format; /* Format du fichier binaire */
GBinContent *content; /* Contenu associé récupéré */
GArchProcessor *proc; /* Processeur idéal en place */
- GProcContext *ctx; /* Contexte de désassemblage */
+
+ domain_ops ops; /* Actions particulières */
mrange_t *exe_ranges; /* Liste de zones exécutables */
size_t exe_count; /* Nombre de ces zones */
@@ -56,22 +67,23 @@ typedef struct _search_domain
/* Désassemble rapidement une instruction. */
-static GArchInstruction *disassemble_instruction_in_domain(const search_domain *, vmpa2t *);
+static GArchInstruction *disassemble_instruction_in_domain(const search_domain *, size_t, 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 void look_backward_for_gadgets(const search_domain *, const mrange_t *, const vmpa2t *, unsigned int, rop_chain *);
+static void look_backward_for_gadgets(const search_domain *, size_t, const mrange_t *, const vmpa2t *, unsigned int, rop_chain *);
/* Etablit une liste de tous les gadgets présents. */
-static rop_chain **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 *, size_t, unsigned int, update_search_progress_cb, GObject *, size_t *);
/******************************************************************************
* *
* Paramètres : domain = ensemble d'auxiliaires à disposition. *
+* index = indice du type de contexte désiré. *
* pos = tête de lecture pour le désassemblage. *
* *
* Description : Désassemble rapidement une instruction. *
@@ -82,12 +94,12 @@ static rop_chain **list_all_gadgets_in_domain(const search_domain *, unsigned in
* *
******************************************************************************/
-static GArchInstruction *disassemble_instruction_in_domain(const search_domain *domain, vmpa2t *pos)
+static GArchInstruction *disassemble_instruction_in_domain(const search_domain *domain, size_t index, vmpa2t *pos)
{
GArchInstruction *result; /* Instruction à retourner */
GProcContext *ctx; /* Contexte de désassemblage */
- ctx = domain->ctx; /* TODO : copie */
+ ctx = domain->ops.get(domain->proc, index);
result = g_arch_processor_disassemble(domain->proc, ctx, domain->content, pos, domain->format);
@@ -97,7 +109,7 @@ static GArchInstruction *disassemble_instruction_in_domain(const search_domain *
g_arch_instruction_call_hook(result, IPH_POST, domain->proc, ctx, domain->format);
}
- //g_object_unref(G_OBJECT(ctx)); /* TODO */
+ g_object_unref(G_OBJECT(ctx));
return result;
@@ -151,6 +163,7 @@ static rop_chain *push_new_instruction(rop_chain *chain, GArchInstruction *instr
/******************************************************************************
* *
* Paramètres : domain = ensemble d'auxiliaires à disposition. *
+* index = indice du type de contexte désiré. *
* exe_range = couverture globale dont il ne faut pas sortir. *
* ret = point de retour final déjà trouvé. *
* max_depth = profondeur maximale des recherches. *
@@ -164,7 +177,7 @@ static rop_chain *push_new_instruction(rop_chain *chain, GArchInstruction *instr
* *
******************************************************************************/
-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)
+static void look_backward_for_gadgets(const search_domain *domain, size_t index, const mrange_t *exe_range, const vmpa2t *ret, unsigned int max_depth, rop_chain *chain)
{
const phys_t *ins_sizes; /* Tailles potentielles */
size_t sizes_count; /* Quantité de tailles à tester*/
@@ -177,8 +190,7 @@ static void look_backward_for_gadgets(const search_domain *domain, const mrange_
phys_t diff; /* Volume de données traité */
mrange_t range; /* Couverture de l'instruction */
- ins_sizes = (phys_t []){ 2, 4 }; /* FIXME */
- sizes_count = 2;
+ ins_sizes = domain->ops.setup(&sizes_count);
copy_vmpa(&last, ret);
@@ -197,7 +209,7 @@ static void look_backward_for_gadgets(const search_domain *domain, const mrange_
copy_vmpa(&end, &start);
- instr = disassemble_instruction_in_domain(domain, &end);
+ instr = disassemble_instruction_in_domain(domain, index, &end);
if (instr == NULL) continue;
/* La jointure est-elle parfaite ? */
@@ -241,6 +253,7 @@ static void look_backward_for_gadgets(const search_domain *domain, const mrange_
/******************************************************************************
* *
* Paramètres : domain = ensemble d'auxiliaires à disposition. *
+* index = indice du type de contexte désiré. *
* max_depth = profondeur maximale des recherches. *
* update = fonction de suivi mise à disposition. *
* data = données à associer à une phase d'actualisation. *
@@ -254,7 +267,7 @@ static void look_backward_for_gadgets(const search_domain *domain, const mrange_
* *
******************************************************************************/
-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)
+static rop_chain **list_all_gadgets_in_domain(const search_domain *domain, size_t index, unsigned int max_depth, update_search_progress_cb update, GObject *data, size_t *count)
{
rop_chain **result; /* Liste de listes à renvoyer */
phys_t done; /* Accumulation des quantités */
@@ -295,7 +308,7 @@ static rop_chain **list_all_gadgets_in_domain(const search_domain *domain, unsig
copy_vmpa(&tmp, &ret);
- gadget = disassemble_instruction_in_domain(domain, &tmp);
+ gadget = disassemble_instruction_in_domain(domain, index, &tmp);
if (gadget == NULL) continue;
/* A-t-on bien affaire à une instruction de retour ? */
@@ -325,7 +338,7 @@ static rop_chain **list_all_gadgets_in_domain(const search_domain *domain, unsig
chain = push_new_instruction(NULL, gadget);
- look_backward_for_gadgets(domain, &domain->exe_ranges[i], &ret, max_depth, chain);
+ look_backward_for_gadgets(domain, index, &domain->exe_ranges[i], &ret, max_depth, chain);
result = (rop_chain **)realloc(result, ++(*count) * sizeof(rop_chain *));
result[*count - 1] = chain;
@@ -363,7 +376,6 @@ found_rop_list *list_all_gadgets(GExeFormat *format, unsigned int max_depth, upd
const char *target; /* Sous-traitance requise */
search_domain domain; /* Outils pour la recherche */
GBinPortion *portions; /* Couche première de portions */
- GProcContext **contexts; /* Contextes pour recherches */
char **names; /* Désignations humaines liées */
size_t i; /* Boucle de parcours */
@@ -410,19 +422,20 @@ found_rop_list *list_all_gadgets(GExeFormat *format, unsigned int max_depth, upd
/* Récupération des différents contextes */
if (strcmp(target, "armv7") == 0)
- contexts = get_rop_contexts_for_arm(domain.proc, &names, count);
-
+ {
+ domain.ops.list = list_rop_contexts_for_arm;
+ domain.ops.get = get_rop_contexts_for_arm;
+ domain.ops.setup = setup_instruction_sizes_for_arm;
+ }
else
{
- contexts = (GProcContext **)calloc(1, sizeof(GProcContext *));
- names = (char **)calloc(1, sizeof(char *));
- *count = 1;
-
- contexts[0] = g_arch_processor_get_context(domain.proc);
- names[0] = _("all");
-
+ domain.ops.list = list_rop_contexts_by_default;
+ domain.ops.get = get_rop_contexts_by_default;
+ domain.ops.setup = setup_instruction_sizes_by_default;
}
+ *count = domain.ops.list(&names);
+
/* Calcul de la surface totale à parcourir */
domain.sum = 0;
@@ -444,18 +457,13 @@ found_rop_list *list_all_gadgets(GExeFormat *format, unsigned int max_depth, upd
{
result[i].category = names[i];
- domain.ctx = contexts[i];
-
- result[i].gadgets = list_all_gadgets_in_domain(&domain, max_depth, update, data, &result[i].count);
-
- g_object_unref(G_OBJECT(domain.ctx));
+ result[i].gadgets = list_all_gadgets_in_domain(&domain, i, max_depth, update, data, &result[i].count);
domain.runs_done++;
}
free(names);
- free(contexts);
free(domain.exe_ranges);
diff --git a/plugins/ropgadgets/helper.c b/plugins/ropgadgets/helper.c
new file mode 100644
index 0000000..ff89e85
--- /dev/null
+++ b/plugins/ropgadgets/helper.c
@@ -0,0 +1,110 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * helper.c - recherche générique de gadgets
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "helper.h"
+
+
+#include <assert.h>
+#include <malloc.h>
+
+
+#include <i18n.h>
+
+
+
+/******************************************************************************
+* *
+* Paramètres : names = noms attribués aux différents contextes. [OUT] *
+* *
+* Description : Etablit une liste des contextes utiles à la recherche. *
+* *
+* Retour : Nombre de contextes gérés pour cette architecture. *
+* *
+* Remarques : Tous les tableaux créés sont à libérer après usage. *
+* *
+******************************************************************************/
+
+size_t list_rop_contexts_by_default(char ***names)
+{
+ size_t result; /* Quantité à renvoyer */
+
+ result = 1;
+
+ (*names) = malloc(result * sizeof(char *));
+
+ (*names)[0] = _("all");
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = processeur lié à l'architecture visée. *
+* index = indice du type de contexte désiré. *
+* *
+* Description : Etablit un contexte utile et adapté à une recherche. *
+* *
+* Retour : Contexte mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GProcContext *get_rop_contexts_by_default(const GArchProcessor *proc, size_t index)
+{
+ GProcContext *result; /* Contexte à retourner */
+
+ assert(index == 0);
+
+ result = g_arch_processor_get_context(proc);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : count = nombre d'éléments du tableau retourné. [OUT] *
+* *
+* Description : Définit les tailles possibles d'une instruction recherchée. *
+* *
+* Retour : Liste de tailles plausibles. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const phys_t *setup_instruction_sizes_by_default(size_t *count)
+{
+ const phys_t *result; /* Liste de taille à renvoyer */
+
+ result = (phys_t []){ 1 };
+
+ *count = 1;
+
+ return result;
+
+}
diff --git a/plugins/ropgadgets/helper.h b/plugins/ropgadgets/helper.h
new file mode 100644
index 0000000..84e5e13
--- /dev/null
+++ b/plugins/ropgadgets/helper.h
@@ -0,0 +1,43 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * helper.h - prototypes pour la recherche générique de gadgets
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _PLUGINS_ROPGADGETS_HELPER_H
+#define _PLUGINS_ROPGADGETS_HELPER_H
+
+
+#include <arch/processor.h>
+
+
+
+/* Etablit une liste des contextes utiles à la recherche. */
+size_t list_rop_contexts_by_default(char ***);
+
+/* Etablit un contexte utile et adapté à une recherche. */
+GProcContext *get_rop_contexts_by_default(const GArchProcessor *, size_t);
+
+/* Définit les tailles possibles d'une instruction recherchée. */
+const phys_t *setup_instruction_sizes_by_default(size_t *);
+
+
+
+#endif /* _PLUGINS_ROPGADGETS_HELPER_H */
diff --git a/plugins/ropgadgets/helper_arm.c b/plugins/ropgadgets/helper_arm.c
index 2361f06..ae6edf3 100644
--- a/plugins/ropgadgets/helper_arm.c
+++ b/plugins/ropgadgets/helper_arm.c
@@ -24,6 +24,7 @@
#include "helper_arm.h"
+#include <assert.h>
#include <malloc.h>
@@ -33,43 +34,93 @@
/******************************************************************************
* *
-* Paramètres : proc = processeur lié à l'architecture visée. *
-* names = noms attribués aux différents contextes. *
-* count = nombre de gadgets trouvés. [OUT] *
+* Paramètres : names = noms attribués aux différents contextes. [OUT] *
* *
* Description : Etablit une liste des contextes utiles à la recherche. *
* *
-* Retour : Liste de contextes mis en place. *
+* Retour : Nombre de contextes gérés pour cette architecture. *
* *
-* Remarques : Toues les tableaux créés sont à libérer après usage. *
+* Remarques : Tous les tableaux créés sont à libérer après usage. *
* *
******************************************************************************/
-GProcContext **get_rop_contexts_for_arm(const GArchProcessor *proc, char ***names, size_t *count)
+size_t list_rop_contexts_for_arm(char ***names)
{
- GProcContext **result; /* Contextes à retourner */
+ size_t result; /* Quantité à renvoyer */
- result = (GProcContext **)calloc(2, sizeof(GProcContext *));
+ result = 2;
- (*names) = (char **)calloc(2, sizeof(char *));
+ (*names) = malloc(result * sizeof(char *));
- *count = 2;
+ (*names)[0] = "Thumb";
+ (*names)[1] = "ARM";
- /* Thumb */
+ return result;
- result[0] = g_arch_processor_get_context(proc);
+}
- g_armv7_context_define_encoding(G_ARMV7_CONTEXT(result[0]), 0, AV7IS_THUMB);
- (*names)[0] = "Thumb";
+/******************************************************************************
+* *
+* Paramètres : proc = processeur lié à l'architecture visée. *
+* index = indice du type de contexte désiré. *
+* *
+* Description : Etablit un contexte utile et adapté à une recherche. *
+* *
+* Retour : Contexte mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- /* ARMM */
+GProcContext *get_rop_contexts_for_arm(const GArchProcessor *proc, size_t index)
+{
+ GProcContext *result; /* Contexte à retourner */
- result[1] = g_arch_processor_get_context(proc);
+ result = g_arch_processor_get_context(proc);
- g_armv7_context_define_encoding(G_ARMV7_CONTEXT(result[1]), 0, AV7IS_ARM);
+ switch (index)
+ {
+ /* Thumb */
+ case 0:
+ g_armv7_context_define_encoding(G_ARMV7_CONTEXT(result), 0, AV7IS_THUMB);
+ break;
- (*names)[1] = "ARM";
+ /* ARM */
+ case 1:
+ g_armv7_context_define_encoding(G_ARMV7_CONTEXT(result), 0, AV7IS_ARM);
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : count = nombre d'éléments du tableau retourné. [OUT] *
+* *
+* Description : Définit les tailles possibles d'une instruction recherchée. *
+* *
+* Retour : Liste de tailles plausibles. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const phys_t *setup_instruction_sizes_for_arm(size_t *count)
+{
+ const phys_t *result; /* Liste de taille à renvoyer */
+
+ result = (phys_t []){ 2, 4 };
+
+ *count = 2;
return result;
diff --git a/plugins/ropgadgets/helper_arm.h b/plugins/ropgadgets/helper_arm.h
index cb2021f..c9f3892 100644
--- a/plugins/ropgadgets/helper_arm.h
+++ b/plugins/ropgadgets/helper_arm.h
@@ -30,7 +30,13 @@
/* Etablit une liste des contextes utiles à la recherche. */
-GProcContext **get_rop_contexts_for_arm(const GArchProcessor *, char ***, size_t *);
+size_t list_rop_contexts_for_arm(char ***);
+
+/* Etablit un contexte utile et adapté à une recherche. */
+GProcContext *get_rop_contexts_for_arm(const GArchProcessor *, size_t);
+
+/* Définit les tailles possibles d'une instruction recherchée. */
+const phys_t *setup_instruction_sizes_for_arm(size_t *);