diff options
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/ropgadgets/Makefile.am | 1 | ||||
| -rw-r--r-- | plugins/ropgadgets/finder.c | 70 | ||||
| -rw-r--r-- | plugins/ropgadgets/helper.c | 110 | ||||
| -rw-r--r-- | plugins/ropgadgets/helper.h | 43 | ||||
| -rw-r--r-- | plugins/ropgadgets/helper_arm.c | 87 | ||||
| -rw-r--r-- | plugins/ropgadgets/helper_arm.h | 8 | 
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 *); | 
