diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2015-05-11 00:58:05 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2015-05-11 00:58:05 (GMT) | 
| commit | 46bcc7f122245f22772fd3e38d16e6afa7bd5881 (patch) | |
| tree | d3c2ba1a9999e373428954f24d0e60c1ea63b756 | |
| parent | 1bda6c517d30d873ff0d92a96380946ef944c9ae (diff) | |
Provided a way to look for ROP gadgets in binary code.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@533 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
28 files changed, 2821 insertions, 19 deletions
| @@ -1,3 +1,56 @@ +15-05-11  Cyrille Bagard <nocbos@gmail.com> + +	* configure.ac; +	Add the new Makefile from the 'plugins/ropgadgets' directory. + +	* plugins/Makefile.am: +	Add ropgadgets to SUBDIRS. + +	* plugins/mobicore/mobicore.c: +	* plugins/mobicore/mobicore.h: +	Update code for init/exit prototypes. + +	* plugins/ropgadgets/finder.c: +	* plugins/ropgadgets/finder.h: +	* plugins/ropgadgets/helper_arm.c: +	* plugins/ropgadgets/helper_arm.h: +	* plugins/ropgadgets/Makefile.am: +	* plugins/ropgadgets/plugin.c: +	* plugins/ropgadgets/plugin.h: +	* plugins/ropgadgets/select.c: +	* plugins/ropgadgets/select.h: +	New entries: provide a way to look for ROP gadgets in binary code. + +	* src/analysis/disass/area.c: +	Typo. + +	* src/arch/arm/v7/opdefs/pop_A88131.d: +	* src/arch/arm/v7/opdefs/pop_A88132.d: +	Define ARM instructions as return points if and only if it is the case. + +	* src/arch/processor.h: +	Define the next way to disassemble binary code. + +	* src/arch/vmpa.c: +	* src/arch/vmpa.h: +	Provide one extra operation with vmpa_t structures. + +	* src/gui/menus/Makefile.am: +	Add the 'plugins.[ch]' files to libguimenus_la_SOURCES. + +	* src/gui/menus/menubar.c: +	Update code. + +	* src/gui/menus/plugins.c: +	* src/gui/menus/plugins.h: +	New entries: add a menu for plugins. + +	* src/plugins/pglist.c: +	* src/plugins/plugin.c: +	* src/plugins/plugin.h: +	* src/plugins/plugin-int.h: +	Provide a global reference to all plugins init/exit functions. +  15-05-06  Cyrille Bagard <nocbos@gmail.com>  	* src/arch/arm/v7/post.c: @@ -214,7 +267,7 @@  15-04-25  Cyrille Bagard <nocbos@gmail.com>  	* configure.ac: -	Add the new Makefile from the 'plugins/libcsem directory. +	Add the new Makefile from the 'plugins/libcsem' directory.  	* plugins/libcsem/exit.c:  	* plugins/libcsem/exit.h: diff --git a/configure.ac b/configure.ac index ef05fde..bd15448 100644 --- a/configure.ac +++ b/configure.ac @@ -287,6 +287,7 @@ AC_CONFIG_FILES([Makefile                   plugins/python/exectracer/Makefile                   plugins/python/samples/Makefile                   plugins/readelf/Makefile +                 plugins/ropgadgets/Makefile                   plugins/stackvars/Makefile                   src/Makefile                   src/analysis/Makefile diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 2fdd3ad..726534f 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -1,2 +1,2 @@ -SUBDIRS = androhelpers devdbg libcsem mobicore pychrysa python readelf stackvars +SUBDIRS = androhelpers devdbg libcsem mobicore pychrysa python readelf ropgadgets stackvars diff --git a/plugins/mobicore/mobicore.c b/plugins/mobicore/mobicore.c index 9f7b8a4..15bc0a1 100644 --- a/plugins/mobicore/mobicore.c +++ b/plugins/mobicore/mobicore.c @@ -40,6 +40,7 @@ DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("Mobicore", "Support MobiCore file format for Tr  /******************************************************************************  *                                                                             *  *  Paramètres  : plugin = greffon à manipuler.                                * +*                ref    = espace de référencement global.                     *  *                                                                             *  *  Description : Prend acte du chargement du greffon.                         *  *                                                                             * @@ -49,7 +50,7 @@ DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("Mobicore", "Support MobiCore file format for Tr  *                                                                             *  ******************************************************************************/ -G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin) +G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin, GObject *ref)  {      bool result;                            /* Bilan à retourner           */ @@ -65,6 +66,7 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin)  /******************************************************************************  *                                                                             *  *  Paramètres  : plugin = greffon à manipuler.                                * +*                ref    = espace de référencement global.                     *  *                                                                             *  *  Description : Prend acte du déchargement du greffon.                       *  *                                                                             * @@ -74,7 +76,7 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin)  *                                                                             *  ******************************************************************************/ -G_MODULE_EXPORT void chrysalide_plugin_exit(GPluginModule *plugin) +G_MODULE_EXPORT void chrysalide_plugin_exit(GPluginModule *plugin, GObject *ref)  {      printf("Unloaded !\n"); diff --git a/plugins/mobicore/mobicore.h b/plugins/mobicore/mobicore.h index d8687a1..ea0cd15 100644 --- a/plugins/mobicore/mobicore.h +++ b/plugins/mobicore/mobicore.h @@ -31,10 +31,10 @@  /* Prend acte du chargement du greffon. */ -G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *); +G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *, GObject *);  /* Prend acte du déchargement du greffon. */ -G_MODULE_EXPORT void chrysalide_plugin_exit(GPluginModule *); +G_MODULE_EXPORT void chrysalide_plugin_exit(GPluginModule *, GObject *); diff --git a/plugins/ropgadgets/Makefile.am b/plugins/ropgadgets/Makefile.am new file mode 100644 index 0000000..5d11366 --- /dev/null +++ b/plugins/ropgadgets/Makefile.am @@ -0,0 +1,15 @@ + +lib_LTLIBRARIES = libropgadgets.la + +libropgadgets_la_SOURCES =				\ +	finder.h finder.c					\ +	helper_arm.h helper_arm.c			\ +	plugin.h plugin.c					\ +	select.h select.c + +libropgadgets_la_CFLAGS = $(AM_CFLAGS) + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) -I../../src + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/plugins/ropgadgets/finder.c b/plugins/ropgadgets/finder.c new file mode 100644 index 0000000..ff0c6ad --- /dev/null +++ b/plugins/ropgadgets/finder.c @@ -0,0 +1,399 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * finder.c - recherche de gadgets pour ROP + * + * Copyright (C) 2015 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA 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. + * + *  OpenIDA 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 Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "finder.h" + + +#include <string.h> + + +#include <core/processors.h> + + +#include <i18n.h> + + +#include "helper_arm.h" + + + +/* Données utiles à transmettre */ +typedef struct _search_domain +{ +    GBinFormat *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   */ + +    mrange_t *exe_ranges;                   /* Liste de zones exécutables  */ +    size_t exe_count;                       /* Nombre de ces zones         */ + +    phys_t sum;                             /* Surface totale à parcourir  */ +    size_t runs_count;                      /* Nombre de passages à faire  */ +    size_t runs_done;                       /* Nombre de passages effectués*/ + +} search_domain; + + +/* Désassemble rapidement une instruction. */ +static GArchInstruction *disassemble_instruction_in_domain(const search_domain *, vmpa2t *); + +/* 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); + +/* 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 *); + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : domain = ensemble d'auxiliaires à disposition.               * +*                pos    = tête de lecture pour le désassemblage.              * +*                                                                             * +*  Description : Désassemble rapidement une instruction.                      * +*                                                                             * +*  Retour      : Instruction créée ou NULL en cas d'échec.                    * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GArchInstruction *disassemble_instruction_in_domain(const search_domain *domain, vmpa2t *pos) +{ +    GArchInstruction *result;               /* Instruction à retourner     */ +    GProcContext *ctx;                      /* Contexte de désassemblage   */ + +    ctx = domain->ctx;  /* TODO : copie */ + +    result = g_arch_processor_disassemble_nextgen(domain->proc, ctx, domain->content, pos); + +    if (result != NULL) +    { +        g_arch_instruction_call_hook(result, IPH_LINK, domain->proc, ctx, domain->format); +        g_arch_instruction_call_hook(result, IPH_POST, domain->proc, ctx, domain->format); +    } + +    //g_object_unref(G_OBJECT(ctx)); /* TODO */ + +    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.              * +*                                                                             * +*  Description : Désassemble en amont d'une position autant que possible.     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GArchInstruction *look_backward_for_gadgets(const search_domain *domain, const mrange_t *exe_range, const vmpa2t *ret, unsigned int max_depth) +{ +    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     */ +    unsigned int i;                         /* Boucle de parcours #1       */ +    GArchInstruction *instr;                /* Elément de gadget trouvé    */ +    size_t k;                               /* Boucle de parcours #2       */ +    vmpa2t start;                           /* Point de départ courant     */ +    vmpa2t end;                             /* Point d'arrivée obtenu      */ +    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; + +    copy_vmpa(&last, ret); + +    /* On parcours jusqu'à la profondeur maximale */ +    for (i = 0; i < max_depth; i++) +    { +        instr = NULL; + +        for (k = 0; k < sizes_count && instr == NULL; k++) +        { +            copy_vmpa(&start, &last); +            deminish_vmpa(&start, ins_sizes[k]); + +            /* Est-on toujours dans les clous ? */ +            if (!mrange_contains_addr(exe_range, &start)) break; + +            copy_vmpa(&end, &start); + +            instr = disassemble_instruction_in_domain(domain, &end); +            if (instr == NULL) continue; + +            /* La jointure est-elle parfaite ? */ + +            if (cmp_vmpa(&end, &last) != 0) +            { +                g_object_unref(G_OBJECT(instr)); +                instr = NULL; +                continue; +            } + +            /* S'il s'agit d'un point de retour, on laisse la main à une autre liste */ + +            if (g_arch_instruction_is_return(instr)) +            { +                g_object_unref(G_OBJECT(instr)); +                instr = NULL; +                continue; +            } + +        } + +        /* Aucune instruction n'a été trouvée à cette profondeur, on s'arrête donc */ +        if (instr == NULL) break; + +        copy_vmpa(&last, &start); + +        diff = compute_vmpa_diff(&end, &start); + +        init_mrange(&range, &start, diff); + +        g_arch_instruction_set_range(instr, &range); + + +        g_arch_instruction_merge_lists(&result, &instr); + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : domain    = ensemble d'auxiliaires à disposition.            * +*                max_depth = profondeur maximale des recherches.              * +*                update    = fonction de suivi mise à disposition.            * +*                data      = données à associer à une phase d'actualisation.  * +*                count     = nombre de gadgets trouvés. [OUT]                 * +*                                                                             * +*  Description : Etablit une liste de tous les gadgets présents.              * +*                                                                             * +*  Retour      : Liste de listes d'instructions, à libérer après usage.       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +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) +{ +    GArchInstruction **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         */ +    phys_t k;                               /* Boucle de parcours #2       */ +    gdouble fraction;                       /* Progression générale        */ +    vmpa2t ret;                             /* Emplacement du retour       */ +    vmpa2t tmp;                             /* Copie de travail modifiable */ +    GArchInstruction *gadget;               /* Nouveau gadget détecté      */ +    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   */ + +    result = NULL; +    *count = 0; + +    done = 0; + +    for (i = 0; i < domain->exe_count; i++) +    { +        max = get_mrange_length(&domain->exe_ranges[i]); + +        for (k = 0; k < max; k++) +        { +            /* Affichage de la progression */ + +            fraction = 1.0 * (domain->runs_done * domain->sum + done + k); +            fraction /= (domain->runs_count * domain->sum); + +            update(data, fraction); + +            /* Réception de la première / dernière instruction */ + +            copy_vmpa(&ret, get_mrange_addr(&domain->exe_ranges[i])); +            advance_vmpa(&ret, k); + +            copy_vmpa(&tmp, &ret); + +            gadget = disassemble_instruction_in_domain(domain, &tmp); +            if (gadget == NULL) continue; + +            /* A-t-on bien affaire à une instruction de retour ? */ + +            if (!g_arch_instruction_is_return(gadget)) +            { +                g_object_unref(G_OBJECT(gadget)); +                continue; +            } + +            /* Ne déborde-t-on pas dans une zone voisine ? */ + +            diff = compute_vmpa_diff(&ret, &tmp); +            init_mrange(&ins_range, &ret, diff); + +            compute_mrange_end_addr(&ins_range, &end); + +            if (!mrange_contains_mrange(&domain->exe_ranges[i], &ins_range)) +            { +                g_object_unref(G_OBJECT(gadget)); +                continue; +            } + +            /* Ajout d'un nouvel ensemble de gadgets */ + +            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); + +            g_arch_instruction_merge_lists(&new, &gadget); + +            result = (GArchInstruction **)realloc(result, ++(*count) * sizeof(GArchInstruction *)); +            result[*count - 1] = new; + +        } + +        done += max; + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : binary    = binaire dont le contenu est à traiter.           * +*                max_depth = profondeur maximale des recherches.              * +*                update    = fonction de suivi mise à disposition.            * +*                data      = données à associer à une phase d'actualisation.  * +*                count     = nombre de gadgets trouvés. [OUT]                 * +*                                                                             * +*  Description : Etablit une liste de tous les gadgets présents.              * +*                                                                             * +*  Retour      : Liste de listes d'instructions, à libérer après usage.       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +found_rop_list *list_all_gadgets(GBinFormat *format, unsigned int max_depth, update_search_progress_cb update, GObject *data, size_t *count) +{ +    found_rop_list *result;                 /* Liste de listes à renvoyer  */ +    const char *target;                     /* Sous-traitance requise      */ +    search_domain domain;                   /* Outils pour la recherche    */ +    GProcContext **contexts;                /* Contextes pour recherches   */ +    char **names;                           /* Désignations humaines liées */ +    size_t i;                               /* Boucle de parcours          */ + +    /* Constitution du socle commun */ + +    g_object_ref(G_OBJECT(format)); +    domain.format = format; + +    domain.content = g_binary_format_get_conten_(format); + +    target = g_exe_format_get_target_machine(G_EXE_FORMAT(format)); +    domain.proc = get_arch_processor_for_type(target); + +    domain.exe_ranges = g_exe_format_get_x_ranges(G_EXE_FORMAT(format), &domain.exe_count); + +    /* Récupération des différents contextes */ + +    if (strcmp(target, "armv7") == 0) +        contexts = get_rop_contexts_for_arm(domain.proc, &names, count); + +    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"); + +    } + +    /* Calcul de la surface totale à parcourir */ + +    domain.sum = 0; + +    for (i = 0; i < domain.exe_count; i++) +        domain.sum += get_mrange_length(&domain.exe_ranges[i]); + +    /* Détermination des différents parcours */ + +    domain.runs_count = *count; + +    domain.runs_done = 0; + +    /* Parcours des différentes surfaces */ + +    result = (found_rop_list *)calloc(*count, sizeof(found_rop_list)); + +    for (i = 0; i < *count; i++) +    { +        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)); + +        domain.runs_done++; + +    } + +    free(names); +    free(contexts); + +    free(domain.exe_ranges); + +    g_object_unref(G_OBJECT(domain.proc)); +    g_object_unref(G_OBJECT(domain.content)); +    g_object_unref(G_OBJECT(domain.format)); + +    return result; + +} diff --git a/plugins/ropgadgets/finder.h b/plugins/ropgadgets/finder.h new file mode 100644 index 0000000..fe6dfe7 --- /dev/null +++ b/plugins/ropgadgets/finder.h @@ -0,0 +1,53 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * finder.h - prototypes pour la recherche de gadgets pour ROP + * + * Copyright (C) 2015 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA 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. + * + *  OpenIDA 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 Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _PLUGINS_ROPGADGETS_FINDER_H +#define _PLUGINS_ROPGADGETS_FINDER_H + + +#include <arch/instruction.h> +#include <format/format.h> + + + +/* Actualise la barre de progression affichée. */ +typedef void (* update_search_progress_cb) (GObject *, gdouble); + + +/* Catégorisation des résultats */ +typedef struct _found_rop_list +{ +    const char *category;                   /* Désignation du groupe       */ + +    GArchInstruction **gadgets;             /* Gadgets pour ROP trouvés    */ +    size_t count;                           /* Taille de cette liste       */ + +} found_rop_list; + + +/* Etablit une liste de tous les gadgets présents. */ +found_rop_list *list_all_gadgets(GBinFormat *, unsigned int, update_search_progress_cb, GObject *, size_t *); + + + +#endif  /* _PLUGINS_ROPGADGETS_FINDER_H */ diff --git a/plugins/ropgadgets/helper_arm.c b/plugins/ropgadgets/helper_arm.c new file mode 100644 index 0000000..7288399 --- /dev/null +++ b/plugins/ropgadgets/helper_arm.c @@ -0,0 +1,76 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * helper_arm.c - prise en compte des spécifités ARM pour la recherche de gadgets + * + * Copyright (C) 2015 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA 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. + * + *  OpenIDA 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 Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "helper_arm.h" + + +#include <malloc.h> + + +#include <arch/arm/v7/context.h> + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : proc  = processeur lié à l'architecture visée.               * +*                names = noms attribués aux différents contextes.             * +*                count = nombre de gadgets trouvés. [OUT]                     * +*                                                                             * +*  Description : Etablit une liste des contextes utiles à la recherche.       * +*                                                                             * +*  Retour      : Liste de contextes mis en place.                             * +*                                                                             * +*  Remarques   : Toues les tableaux créés sont à libérer après usage.         * +*                                                                             * +******************************************************************************/ + +GProcContext **get_rop_contexts_for_arm(const GArchProcessor *proc, char ***names, size_t *count) +{ +    GProcContext **result;                  /* Contextes à retourner       */ + +    result = (GProcContext **)calloc(2, sizeof(GProcContext *)); + +    (*names) = (char **)calloc(2, sizeof(char *)); + +    *count = 2; + +    /* Thumb */ + +    result[0] = g_arch_processor_get_context(proc); + +    g_armv7_context_define_encoding(G_ARMV7_CONTEXT(result[0]), 0, AV7IS_THUMB); + +    (*names)[0] = "Thumb"; + +    /* ARMM */ + +    result[1] = g_arch_processor_get_context(proc); + +    g_armv7_context_define_encoding(G_ARMV7_CONTEXT(result[1]), 0, AV7IS_ARM); + +    (*names)[1] = "ARM"; + +    return result; + +} diff --git a/plugins/ropgadgets/helper_arm.h b/plugins/ropgadgets/helper_arm.h new file mode 100644 index 0000000..afae191 --- /dev/null +++ b/plugins/ropgadgets/helper_arm.h @@ -0,0 +1,37 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * helper_arm.h - prototypes pour la prise en compte des spécifités ARM pour la recherche de gadgets + * + * Copyright (C) 2015 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA 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. + * + *  OpenIDA 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 Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _PLUGINS_ROPGADGETS_HELPER_ARM_H +#define _PLUGINS_ROPGADGETS_HELPER_ARM_H + + +#include <arch/processor.h> + + + +/* Etablit une liste des contextes utiles à la recherche. */ +GProcContext **get_rop_contexts_for_arm(const GArchProcessor *, char ***, size_t *); + + + +#endif  /* _PLUGINS_ROPGADGETS_HELPER_ARM_H */ diff --git a/plugins/ropgadgets/plugin.c b/plugins/ropgadgets/plugin.c new file mode 100644 index 0000000..a243a74 --- /dev/null +++ b/plugins/ropgadgets/plugin.c @@ -0,0 +1,95 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * plugin.c - description et intégration du présent greffon + * + * Copyright (C) 2015 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA 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. + * + *  OpenIDA 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 Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "plugin.h" + + +#include <i18n.h> + + +#include <gtkext/easygtk.h> +#include <plugins/plugin-def.h> + + +#include "select.h" + + + +DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("ROP gadgets", "Find available gadgets for a ROP chain", "0.1.0", +                                PGA_PLUGIN_INIT); + + + +/* Réagit avec le menu "Greffons -> Lister les gadgets ROP". */ +static void mcb_plugins_list_rop_gadgets(GtkMenuItem *, GObject *); + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : plugin = greffon à manipuler.                                * +*                ref    = espace de référencement global.                     * +*                                                                             * +*  Description : Prend acte du chargement du greffon.                         * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin, GObject *ref) +{ +    GtkContainer *menubar;                  /* Support pour éléments       */ +    GtkWidget *submenuitem;                 /* Sous-élément de menu        */ + +    menubar = GTK_CONTAINER(g_object_get_data(ref, "menubar_plugins")); +    if (menubar == NULL) return false; + +    submenuitem = qck_create_menu_item(ref, "mnu_plugins_ropgadgets", _("List ROP gadgets"), +                                       G_CALLBACK(mcb_plugins_list_rop_gadgets), ref); +    gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + +    return true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : menuitem = élément de menu sélectionné.                      * +*                ref      = adresse de l'espace de référencement global.      * +*                                                                             * +*  Description : Réagit avec le menu "Greffons -> Lister les gadgets ROP".    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void mcb_plugins_list_rop_gadgets(GtkMenuItem *menuitem, GObject *ref) +{ +    run_rop_finder_assistant(ref, NULL); + +} diff --git a/plugins/ropgadgets/plugin.h b/plugins/ropgadgets/plugin.h new file mode 100644 index 0000000..67612de --- /dev/null +++ b/plugins/ropgadgets/plugin.h @@ -0,0 +1,37 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * plugin.h - prototypes pour la description et intégration du présent greffon + * + * Copyright (C) 2015 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA 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. + * + *  OpenIDA 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 Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _PLUGINS_ROPGADGETS_PLUGIN_H +#define _PLUGINS_ROPGADGETS_PLUGIN_H + + +#include <plugins/plugin.h> + + + +/* Prend acte du chargement du greffon. */ +G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *, GObject *ref); + + + +#endif  /* _PLUGINS_ROPGADGETS_PLUGIN_H */ diff --git a/plugins/ropgadgets/select.c b/plugins/ropgadgets/select.c new file mode 100644 index 0000000..2889eb5 --- /dev/null +++ b/plugins/ropgadgets/select.c @@ -0,0 +1,1845 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * goto.c - boîte de dialogue pour les sauts à une adresse donnée + * + * Copyright (C) 2012-2014 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA 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. + * + *  OpenIDA 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 Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "select.h" + + +#include <fcntl.h> +#include <malloc.h> +#include <regex.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + + +#include <i18n.h> + + +#include <project.h> +#include <common/cpp.h> +#include <common/extstr.h> +#include <core/formats.h> +#include <core/processors.h> +#include <gtkext/easygtk.h> + + +#include "finder.h" + + + +/* ------------------------ PARTIE PRINCIPALE DE L'ASSISTANT ------------------------ */ + + +/* Colonnes de la liste des binaires */ +typedef enum _CurrentProjectBinaries +{ +    CPB_BINARY,                             /* Instance GLib du bianire    */ +    CPB_FILENAME,                           /* Chemin d'accès au fichier   */ + +    CPB_COUNT                               /* Nombre de colonnes          */ + +} CurrentProjectBinaries; + + +/* Ferme l'assistant sans dérouler la procédure. */ +static void rop_finder_assistant_cancel(GtkAssistant *, gpointer); + +/* Ferme l'assistant et déroule la procédure. */ +static void rop_finder_assistant_apply(GtkAssistant *, GObject *); + +/* Accompagne le chargement de certaines pages de l'assistant. */ +static void rop_finder_assistant_prepare(GtkAssistant *, GtkWidget *, GObject *); + + + +/* ------------------------ DEFINITION DES ENTREES / SORTIES ------------------------ */ + + +/* Ajoute le panneau de choix quant aux fichiers d'E/S. */ +static void register_input_output_panel(GtkAssistant *, GObject *); + +/* Construit la sélection d'un binaire déjà chargé. */ +static GtkWidget *load_and_populate_current_project_binaries(GObject *); + +/* Met à jour l'accès à la sélection du type d'entrée. */ +static void on_input_type_toggle(GtkToggleButton *, GObject *); + +/* Réagit à un changement de sélection du binaire d'entrée. */ +static void on_loaded_binary_selection_change(GtkComboBox *, GObject *); + +/* Réagit à un changement de fichier binaire d'entrée. */ +static void on_input_filename_change(GtkEditable *, GObject *); + +/* Sélectionne ou non un nouveau fichier d'entrée. */ +static void on_input_filename_browsing_clicked(GtkButton *, GObject *); + +/* Met à jour l'accès à la définition d'un fichier de sortie. */ +static void on_output_need_toggle(GtkToggleButton *, GObject *); + +/* Sélectionne ou non un nouveau fichier de sortie. */ +static void on_output_filename_browsing_clicked(GtkButton *, GObject *); + + + +/* ------------------------- SUIVI DE LA PHASE DE RECHERCHE ------------------------- */ + + +/* Ajoute le panneau de suivi des opérations de recherche. */ +static void register_search_display_panel(GtkAssistant *, GObject *); + +/* Initialise une ligne de rapport quant aux opérations menées. */ +static void init_rop_search_step(GtkGrid *, gint, GObject *, const char *, const char *, GtkWidget *); + +/* Réinitialise tous les rapports de recherches imprimés. */ +static void reset_rop_search_steps(GObject *); + + +/* Description d'une évolution du processus */ +typedef struct _search_step +{ +    GObject *ref;                           /* Espace de référencements    */ + +    union +    { +        struct +        { +            const char *key;                /* Clef d'accès partielle      */ +            bool dynamic;                   /* Mémoire à libérer ?         */ +            union +            { +                const char *msg;            /* Message de conclusion       */ +                char *dmsg;                 /* Message de conclusion       */ +            }; +            bool success;                   /* Indication claire           */ +        }; + +        gdouble fraction;                   /* Avancée du désasssemblage   */ + +        struct +        { +            GBinFormat *format;             /* Format binaire chargé       */ +            found_rop_list *list;           /* Liste de gadgets ROP trouvés*/ +            size_t count;                   /* Nombre de gadgets trouvés   */ +        }; + +    }; + +} search_step; + + +/* Affiche un message de statut quant aux recherches en cours. */ +static gboolean print_status_of_rop_search_step(search_step *); + +/* Affiche un message de statut quant aux recherches en cours. */ +static void push_status_printing_of_rop_search_step(GObject *, const char *, const char *, bool); + +/* Affiche un message de statut quant aux recherches en cours. */ +static void push_dyn_status_printing_of_rop_search_step(GObject *, const char *, char *, bool); + +/* Actualise la barre de progression affichée. */ +static gboolean update_progress_bar_fraction(search_step *); + +/* Lance l'actualisation de la barre de progression affichée. */ +static void push_new_progress_fraction(GObject *, gdouble); + +/* Enregistre une référence vers les gadgets trouvés. */ +static gboolean register_found_rop_gadgets(search_step *); + +/* Lance une conservation des gadgets trouvés. */ +static void push_found_rop_gadgets(GObject *, GBinFormat *, found_rop_list *, size_t); + +/* Charge un format binaire interne déjà chargé. */ +static GBinFormat *load_internal_format_for_rop_gadgets(GObject *); + +/* Charge un format binaire externe. */ +static GBinFormat *load_external_format_for_rop_gadgets(GObject *); + +/* Procède à la recherche de gadgets de façon séparée. */ +static gpointer look_for_rop_gadgets(GObject *); + + + +/* ----------------------- MISE EN FORME DES GADGETS PRESENTS ----------------------- */ + + +/* Colonnes de la liste des symboles */ +typedef enum _FoundROPGadget +{ +    FRG_CATEGORY,                           /* Catégorie d'appartenance    */ +    FRG_RAW_VIRTUAL,                        /* Correspondance virtuelle    */ +    FRG_RAW,                                /* Brut pour recherche         */ + +    FRG_VIRTUAL,                            /* Correspondance virtuelle    */ +    FRG_CONTENT,                            /* Contenu des lignes visées   */ + +    FRG_COUNT                               /* Nombre de colonnes          */ + +} FoundROPGadget; + + +/* Ajoute le panneau de sélection des gadgets ROP identifiés. */ +static void register_rop_list_panel(GtkAssistant *, GObject *); + +/* Lance l'actualisation du filtrage des gadgets ROP. */ +static void on_rop_gadgets_category_changed(GtkComboBox *, GObject *); + +/* Lance l'actualisation du filtrage des gadgets ROP. */ +static void on_rop_gadgets_filter_changed(GtkSearchEntry *, GObject *); + +/* Détermine la visibilité de tel ou tel gadget ROP. */ +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(GBinFormat *, GtkComboBoxText *, GtkTreeStore *, const char *, GArchInstruction **, size_t); + + + +/* ---------------------------------------------------------------------------------- */ +/*                          PARTIE PRINCIPALE DE L'ASSISTANT                          */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : global = espace de référencements global.                    * +*                parent = fenêtre principale de l'éditeur.                    * +*                                                                             * +*  Description : Crée et affiche un assistant de sélection de gadgets ROP.    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void run_rop_finder_assistant(GObject *global, GtkWindow *parent) +{ +    GtkWidget *assistant;                   /* Fenêtre à afficher          */ +    GObject *ref;                           /* Espace de référencement     */ + +    assistant = gtk_assistant_new(); +    gtk_widget_set_size_request(assistant, 900, 550); +    gtk_window_set_position(GTK_WINDOW(assistant), GTK_WIN_POS_CENTER); +    gtk_window_set_title(GTK_WINDOW(assistant), _("Export assistant")); + +    gtk_window_set_modal(GTK_WINDOW(assistant), TRUE); +    gtk_window_set_transient_for(GTK_WINDOW(assistant), parent); + +    ref = G_OBJECT(assistant); +    g_object_set_data(ref, "global", global); + +    register_input_output_panel(GTK_ASSISTANT(assistant), ref); +    register_search_display_panel(GTK_ASSISTANT(assistant), ref); +    register_rop_list_panel(GTK_ASSISTANT(assistant), ref); + +    g_signal_connect(G_OBJECT(assistant), "cancel", G_CALLBACK(rop_finder_assistant_cancel), NULL); +    g_signal_connect(G_OBJECT(assistant), "close", G_CALLBACK(rop_finder_assistant_cancel), NULL); +    g_signal_connect(G_OBJECT(assistant), "apply", G_CALLBACK(rop_finder_assistant_apply), ref); +    g_signal_connect(G_OBJECT(assistant), "prepare", G_CALLBACK(rop_finder_assistant_prepare), ref); + +    gtk_widget_show_all(assistant); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : assistant = fenêtre d'assistance à traiter.                  * +*                data      = adresse non utilisée ici.                        * +*                                                                             * +*  Description : Ferme l'assistant sans dérouler la procédure.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void rop_finder_assistant_cancel(GtkAssistant *assistant, gpointer data) +{ +    gtk_widget_destroy(GTK_WIDGET(assistant)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : assistant = fenêtre d'assistance à traiter.                  * +*                ref       = adresse de l'espace de référencement global.     * +*                                                                             * +*  Description : Ferme l'assistant et déroule la procédure.                   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void rop_finder_assistant_apply(GtkAssistant *assistant, GObject *ref) +{ +    GtkEntry *entry;                        /* Zone de saisie              */ +    const gchar *filename;                  /* Chemin d'accès du fichier   */ +    int fd;                                 /* Flux ouvert en écriture     */ +    GtkTreeView *treeview;                  /* Arborescence à actualiser   */ +    GtkTreeModel *model;                    /* Modèle de gestion           */ +    GtkTreeIter iter;                       /* Boucle de parcours          */ +    gboolean loop;                          /* Poursuite de la boucle ?    */ +    gchar *virtual;                         /* Adresse correspondante      */ +    gchar *raw;                             /* ROP en format texte simple  */ + +    /* Fichier de sortie */ + +    entry = GTK_ENTRY(g_object_get_data(ref, "output_filename")); +    filename = gtk_entry_get_text(entry); + +    fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR); +    if (fd == -1) +    { +        perror("open"); +        return; +    } + +    /* Boucle de parcours */ + +    treeview = GTK_TREE_VIEW(g_object_get_data(ref, "treeview")); +    model = gtk_tree_view_get_model(treeview); + +    for (loop = gtk_tree_model_get_iter_first(model, &iter); +         loop; +         loop = gtk_tree_model_iter_next(model, &iter)) +    { +        gtk_tree_model_get(model, &iter, FRG_RAW_VIRTUAL, &virtual, FRG_RAW, &raw, -1); + +        dprintf(fd, "%s\t%s\n", virtual, raw); + +        g_free(virtual); +        g_free(raw); + +    } + +    /* Conclusion */ + +    close(fd); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : assistant = fenêtre d'assistance à traiter.                  * +*                page      = élément de l'assistant à préparer.               * +*                ref       = adresse de l'espace de référencement global.     * +*                                                                             * +*  Description : Accompagne le chargement de certaines pages de l'assistant.  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void rop_finder_assistant_prepare(GtkAssistant *assistant, GtkWidget *page, GObject *ref) +{ +    GtkWidget *test;                        /* Reconnaissance à l'aveugle  */ +    GThread *thread;                        /* Tâche de fond à programmer  */ + +    test = gtk_assistant_get_nth_page(assistant, 1); + +    if (test == page) +    { +        reset_rop_search_steps(ref); + +        thread = g_thread_new("gadgets_finder", (GThreadFunc)look_for_rop_gadgets, ref); +        g_thread_unref(thread); + +    } + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                          DEFINITION DES ENTREES / SORTIES                          */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : assistant = fenêtre d'assistance à compléter.                * +*                ref       = espace de référencements inter-panneaux.         * +*                                                                             * +*  Description : Ajoute le panneau de choix quant aux fichiers d'E/S.         * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void register_input_output_panel(GtkAssistant *assistant, GObject *ref) +{ +    GtkWidget *vbox;                        /* Support principal           */ +    GtkWidget *frame;                       /* Support avec encadrement    */ +    GtkWidget *alignment;                   /* Disposition sur le support  */ +    GtkWidget *sub_vbox;                    /* Division verticale          */ +    GtkWidget *radio;                       /* Choix du type d'entrée      */ +    GtkWidget *combobox;                    /* Sélection du binaire interne*/ +    GtkWidget *sub_hbox;                    /* Division horizontale        */ +    GtkWidget *entry;                       /* Zone de saisie de texte     */ +    GtkWidget *button;                      /* Sélection de fichier        */ +    GtkWidget *checkbutton;                 /* Coche pour une option       */ + +    vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 16); +    gtk_widget_show(vbox); + +    /* Fichier de sortie */ + +    frame = qck_create_frame(_("<b>Input binary</b>"), &alignment, 0, 0, 12, 8); +    gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, TRUE, 0); + +    sub_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); +    gtk_widget_show(sub_vbox); +    gtk_container_add(GTK_CONTAINER(alignment), sub_vbox); + +    radio = qck_create_radio_button(ref, "loaded_as_input", _("Use a binary from the current project:"), +                                    NULL, G_CALLBACK(on_input_type_toggle), ref); +    gtk_box_pack_start(GTK_BOX(sub_vbox), radio, FALSE, FALSE, 0); + +    combobox = load_and_populate_current_project_binaries(ref); +    gtk_box_pack_start(GTK_BOX(sub_vbox), combobox, TRUE, TRUE, 0); + +    radio = qck_create_radio_button(ref, "extern_as_input", _("Open a new binary file:"), +                                    GTK_RADIO_BUTTON(radio), G_CALLBACK(on_input_type_toggle), ref); +    gtk_box_pack_start(GTK_BOX(sub_vbox), radio, FALSE, FALSE, 0); + +    sub_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); +    gtk_widget_show(sub_hbox); +    gtk_box_pack_start(GTK_BOX(sub_vbox), sub_hbox, FALSE, FALSE, 0); + +    entry = qck_create_entry(ref, "input_filename", NULL); +    g_signal_connect(entry, "changed", G_CALLBACK(on_input_filename_change), ref); +    gtk_box_pack_start(GTK_BOX(sub_hbox), entry, TRUE, TRUE, 0); + +    button = qck_create_button(ref, "input_browser", _("Browse..."), +                               G_CALLBACK(on_input_filename_browsing_clicked), assistant); +    gtk_box_pack_start(GTK_BOX(sub_hbox), button, FALSE, FALSE, 0); + +    /* Actualisation des accès */ + +    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio), TRUE); +    on_input_type_toggle(GTK_TOGGLE_BUTTON(radio), ref); + +    /* Fichier de sortie */ + +    frame = qck_create_frame(_("<b>Ouput results</b>"), &alignment, 0, 0, 12, 8); +    gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, TRUE, 0); + +    sub_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); +    gtk_widget_show(sub_vbox); +    gtk_container_add(GTK_CONTAINER(alignment), sub_vbox); + +    checkbutton = qck_create_check_button(ref, "use_output", +                                          _("Save selected ROP gadgets in a file:"), +                                          G_CALLBACK(on_output_need_toggle), ref); +    gtk_widget_show(checkbutton); + +    gtk_box_pack_start(GTK_BOX(sub_vbox), checkbutton, FALSE, FALSE, 0); + +    sub_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); +    gtk_widget_show(sub_hbox); +    gtk_box_pack_start(GTK_BOX(sub_vbox), sub_hbox, FALSE, TRUE, 0); + +    entry = qck_create_entry(ref, "output_filename", NULL); +    gtk_box_pack_start(GTK_BOX(sub_hbox), entry, TRUE, TRUE, 0); + +    button = qck_create_button(ref, "output_browser", _("Browse..."), +                               G_CALLBACK(on_output_filename_browsing_clicked), assistant); +    gtk_box_pack_start(GTK_BOX(sub_hbox), button, FALSE, FALSE, 0); + +    /* Actualisation des accès */ + +    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), FALSE); +    on_output_need_toggle(GTK_TOGGLE_BUTTON(checkbutton), ref); + +    /* Intégration */ + +    gtk_assistant_append_page(assistant, vbox); +    gtk_assistant_set_page_title(assistant, vbox, _("Input / output")); +    gtk_assistant_set_page_type(assistant, vbox, GTK_ASSISTANT_PAGE_INTRO); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : ref = espace de référencements inter-panneaux.               * +*                                                                             * +*  Description : Construit la sélection d'un binaire déjà chargé.             * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GtkWidget *load_and_populate_current_project_binaries(GObject *ref) +{ +    GtkWidget *result;                      /* Composant à retourner       */ +    GObject *global;                        /* Espace de référencements    */ +    GLoadedBinary *current;                 /* Binaire actif courant       */ +    gint selected;                          /* Indice à sélectionner       */ +    GtkListStore *store;                    /* Modèle de gestion en liste  */ +    GLoadedBinary **binaries;               /* Liste de binaires           */ +    size_t count;                           /* Taille de cette liste       */ +    size_t i;                               /* Boucle de parcours          */ +    GtkTreeIter iter;                       /* Point d'insertion           */ +    GtkCellRenderer *renderer;              /* Moteur de rendu de colonne  */ + +    /* Récupération du binaire courant */ + +    global = G_OBJECT(g_object_get_data(ref, "global")); + +    current = G_LOADED_BINARY(g_object_get_data(global, "current_binary")); + +    /* Constitution d'une liste de binaires courants */ + +    selected = -1; + +    store = gtk_list_store_new(CPB_COUNT, G_TYPE_OBJECT, G_TYPE_STRING); + +    binaries = g_study_project_get_binaries(get_current_project(), &count); + +    if (binaries != NULL) +    { +        for (i = 0; i < count; i++) +        { +            gtk_list_store_append(store, &iter); +            gtk_list_store_set(store, &iter, +                               CPB_BINARY, binaries[i], +                               CPB_FILENAME, g_loaded_binary_get_name(binaries[i], true), +                               -1); + +            if (binaries[i] == current) +                selected = i; + +            g_object_unref(G_OBJECT(binaries[i])); + +        } + +        free(binaries); + +    } + +    /* Mise en place d'un affichage graphique */ + +    result = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store)); +    g_object_set_data(ref, "input_binary", result); + +    g_signal_connect(result, "changed", G_CALLBACK(on_loaded_binary_selection_change), ref); + +    gtk_widget_show(result); + +    gtk_combo_box_set_active(GTK_COMBO_BOX(result), selected); + +    renderer = gtk_cell_renderer_text_new(); +    gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(result), renderer, TRUE); +    gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(result), renderer, +                                   "text", CPB_FILENAME, +                                   NULL); + +    g_object_unref(G_OBJECT(store)); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : button = oche dont le status vient de changer.               * +*                ref    = espace de référencements inter-panneaux.            * +*                                                                             * +*  Description : Met à jour l'accès à la sélection du type d'entrée.          * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void on_input_type_toggle(GtkToggleButton *button, GObject *ref) +{ +    GtkToggleButton *internal;              /* Bouton de sélection interne */ +    gboolean state;                         /* Etat du bouton courant      */ +    GtkWidget *widget;                      /* Element dont l'accès change */ + +    internal = GTK_TOGGLE_BUTTON(g_object_get_data(ref, "loaded_as_input")); +    state = gtk_toggle_button_get_active(internal); + +    /* Elément de sélection interne */ + +    widget = GTK_WIDGET(g_object_get_data(ref, "input_binary")); + +    if (widget != NULL) +    { +        gtk_widget_set_sensitive(widget, state); + +        if (state) +            on_loaded_binary_selection_change(GTK_COMBO_BOX(widget), ref); + +    } + +    /* Elément de sélection externe */ + +    widget = GTK_WIDGET(g_object_get_data(ref, "input_filename")); + +    if (widget != NULL) +    { +        gtk_widget_set_sensitive(widget, !state); + +        if (!state) +            on_input_filename_change(GTK_EDITABLE(widget), ref); + +    } + +    widget = GTK_WIDGET(g_object_get_data(ref, "input_browser")); +    if (widget != NULL) +        gtk_widget_set_sensitive(widget, !state); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : combo = composant graphique de sélection concerné.           * +*                ref   = espace de référencement principal.                   * +*                                                                             * +*  Description : Réagit à un changement de sélection du binaire d'entrée.     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void on_loaded_binary_selection_change(GtkComboBox *combo, GObject *ref) +{ +    gint selected;                          /* Indice sélectionné          */ +    GtkWidget *page;                        /* Page de la partie terminée  */ + +    selected = gtk_combo_box_get_active(combo); + +    page = gtk_assistant_get_nth_page(GTK_ASSISTANT(ref), 0); + +    if (page != NULL) +        gtk_assistant_set_page_complete(GTK_ASSISTANT(ref), page, selected != -1); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : editable = composant graphique d'édition concerné.           * +*                ref      = espace de référencement principal.                * +*                                                                             * +*  Description : Réagit à un changement de fichier binaire d'entrée.          * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void on_input_filename_change(GtkEditable *editable, GObject *ref) +{ +    guint16 length;                         /* Taille du texte fourni      */ +    GtkWidget *page;                        /* Page de la partie terminée  */ + +    length = gtk_entry_get_text_length(GTK_ENTRY(editable)); + +    page = gtk_assistant_get_nth_page(GTK_ASSISTANT(ref), 0); + +    if (page != NULL) +        gtk_assistant_set_page_complete(GTK_ASSISTANT(ref), page, length > 0); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : button = bouton d'édition de la sélection.                   * +*                ref    = espace de référencement principal.                  * +*                                                                             * +*  Description : Sélectionne ou non un nouveau fichier d'entrée.              * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void on_input_filename_browsing_clicked(GtkButton *button, GObject *ref) +{ +    GtkWidget *dialog;                      /* Boîte à afficher            */ +    gchar *filename;                        /* Nom du fichier à intégrer   */ +    GtkEntry *entry;                        /* Zone de saisie à maj.       */ + +    dialog = gtk_file_chooser_dialog_new(_("Choose an input filename"), GTK_WINDOW(ref), +                                         GTK_FILE_CHOOSER_ACTION_OPEN, +                                         _("_Cancel"), GTK_RESPONSE_CANCEL, +                                         _("_Open"), GTK_RESPONSE_ACCEPT, +                                         NULL); + +    entry = GTK_ENTRY(g_object_get_data(ref, "input_filename")); +    gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), gtk_entry_get_text(entry)); + +    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) +    { +        filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + +        gtk_entry_set_text(GTK_ENTRY(entry), filename); + +        g_free(filename); + +    } + +    gtk_widget_destroy(dialog); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : button = coche dont le status vient de changer.              * +*                ref    = espace de référencements inter-panneaux.            * +*                                                                             * +*  Description : Met à jour l'accès à la définition d'un fichier de sortie.   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void on_output_need_toggle(GtkToggleButton *button, GObject *ref) +{ +    gboolean state;                         /* Etat du bouton courant      */ +    GtkWidget *widget;                      /* Element dont l'accès change */ + +    state = gtk_toggle_button_get_active(button); + +    widget = GTK_WIDGET(g_object_get_data(ref, "output_filename")); +    if (widget != NULL) +        gtk_widget_set_sensitive(widget, state); + +    widget = GTK_WIDGET(g_object_get_data(ref, "output_browser")); +    if (widget != NULL) +        gtk_widget_set_sensitive(widget, state); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : button = bouton d'édition de la sélection.                   * +*                ref    = espace de référencement principal.                  * +*                                                                             * +*  Description : Sélectionne ou non un nouveau fichier de sortie.             * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void on_output_filename_browsing_clicked(GtkButton *button, GObject *ref) +{ +    GtkWidget *dialog;                      /* Boîte à afficher            */ +    gchar *filename;                        /* Nom du fichier à intégrer   */ +    GtkEntry *entry;                        /* Zone de saisie à maj.       */ + +    dialog = gtk_file_chooser_dialog_new(_("Choose an output filename"), GTK_WINDOW(ref), +                                         GTK_FILE_CHOOSER_ACTION_SAVE, +                                         _("_Cancel"), GTK_RESPONSE_CANCEL, +                                         _("_Save"), GTK_RESPONSE_ACCEPT, +                                         NULL); + +    entry = GTK_ENTRY(g_object_get_data(ref, "output_filename")); +    gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), gtk_entry_get_text(entry)); + +    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) +    { +        filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + +        gtk_entry_set_text(GTK_ENTRY(entry), filename); + +        g_free(filename); + +    } + +    gtk_widget_destroy(dialog); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                           SUIVI DE LA PHASE DE RECHERCHE                           */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : assistant = fenêtre d'assistance à compléter.                * +*                ref       = espace de référencements inter-panneaux.         * +*                                                                             * +*  Description : Ajoute le panneau de suivi des opérations de recherche.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void register_search_display_panel(GtkAssistant *assistant, GObject *ref) +{ +    GtkGrid *grid;                          /* Table de résumé             */ +    GtkWidget *pbar;                        /* barre de progression        */ + +    grid = GTK_GRID(gtk_grid_new()); +    gtk_grid_set_column_spacing(grid, 8); +    gtk_grid_set_row_spacing(grid, 8); + +    g_object_set(G_OBJECT(grid), +                 "halign", GTK_ALIGN_CENTER, +                 "valign", GTK_ALIGN_CENTER, +                 "margin-bottom", 100, NULL); + +    /* Représentation des étapes */ + +    init_rop_search_step(grid, 0, ref, "loading", _("Loading the input binary..."), NULL); + +    init_rop_search_step(grid, 1, ref, "format", _("Detecting the proper format..."), NULL); + +    pbar = gtk_progress_bar_new(); +    g_object_set(G_OBJECT(pbar), "valign", GTK_ALIGN_CENTER, NULL); +    gtk_widget_show(pbar); + +    init_rop_search_step(grid, 2, ref, "gadgets", _("Looking for all ROP gadgets..."), pbar); + +    init_rop_search_step(grid, 3, ref, "final", _("Results:"), NULL); + +    /* Intégration */ + +    gtk_assistant_append_page(assistant, GTK_WIDGET(grid)); +    gtk_assistant_set_page_title(assistant, GTK_WIDGET(grid), _("Search process")); +    gtk_assistant_set_page_type(assistant, GTK_WIDGET(grid), GTK_ASSISTANT_PAGE_PROGRESS); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : ref  = espace de référencements inter-panneaux.              * +*                key  = clef partielle d'accès aux composants concernés.      * +*                info = message d'information annonçant la conclusion.        * +*                pbar = éventuel composant de statut ou NULL.                 * +*                                                                             * +*  Description : Initialise une ligne de rapport quant aux opérations menées. * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void init_rop_search_step(GtkGrid *grid, gint top, GObject *ref, const char *key, const char *info, GtkWidget *pbar) +{ +    char *access;                           /* Chemin d'accès final        */ +    GtkWidget *render;                      /* Image de statut à afficher  */ +    GtkWidget *label;                       /* Etiquette d'indication      */ + +    /* Icone de représentation */ + +    access = strdup("process_"); +    access = stradd(access, key); +    access = stradd(access, "_icon"); + +    render = gtk_image_new_from_icon_name("dialog-question", GTK_ICON_SIZE_DND); +    g_object_set_data(ref, access, render); +    gtk_widget_show(render); +    gtk_grid_attach(grid, render, 0, top, 1, 1); + +    free(access); + +    /* Désignation humaine d'indicatif */ + +    access = strdup("process_"); +    access = stradd(access, key); +    access = stradd(access, "_caption"); + +    label = qck_create_label(ref, access, info); +    gtk_grid_attach(grid, label, 1, top, 1, 1); + +    free(access); + +    /* Statut final */ + +    access = strdup("process_"); +    access = stradd(access, key); +    access = stradd(access, "_status"); + +    if (pbar == NULL) +    { +        label = qck_create_label(ref, access, "done"); +        gtk_grid_attach(grid, label, 2, top, 1, 1); +    } +    else +    { +        g_object_set_data(ref, access, pbar); +        gtk_grid_attach(grid, pbar, 2, top, 1, 1); +    } + +    free(access); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : ref = espace de référencements inter-panneaux.               * +*                                                                             * +*  Description : Réinitialise tous les rapports de recherches imprimés.       * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void reset_rop_search_steps(GObject *ref) +{ +    size_t i;                               /* Boucle de parcours          */ +    char *access;                           /* Chemin d'accès final        */ +    GObject *render;                        /* Image de statut à afficher  */ +    GtkLabel *label;                        /* Etiquette d'indication      */ +    GtkProgressBar *pbar;                   /* Barre à mettre à jour       */ + +    static const char *icon_keys[] = { "loading", "format", "gadgets", "final" }; +    static const char *status_keys[] = { "loading", "format", "final" }; + +    /* Réinitialisation des images */ + +    for (i = 0; i < ARRAY_SIZE(icon_keys); i++) +    { +        access = strdup("process_"); +        access = stradd(access, icon_keys[i]); +        access = stradd(access, "_icon"); + +        render = G_OBJECT(g_object_get_data(ref, access)); +        g_object_set(render, "icon-name", "dialog-question", NULL); + +        free(access); + +    } + +    /* Statut final */ + +    for (i = 0; i < ARRAY_SIZE(status_keys); i++) +    { +        access = strdup("process_"); +        access = stradd(access, status_keys[i]); +        access = stradd(access, "_status"); + +        label = GTK_LABEL(g_object_get_data(ref, access)); +        gtk_label_set_text(label, ""); + +        free(access); + +    } + +    /* Progression des recherches */ + +    pbar = GTK_PROGRESS_BAR(g_object_get_data(ref, "process_gadgets_status")); + +    gtk_progress_bar_set_fraction(pbar, 0.0); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : step = informations quant à l'étape avancée.                 * +*                                                                             * +*  Description : Affiche un message de statut quant aux recherches en cours.  * +*                                                                             * +*  Retour      : FALSE pour ne pas reprogrammer l'exécution de la tâche.      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static gboolean print_status_of_rop_search_step(search_step *step) +{ +    char *access;                           /* Chemin d'accès final        */ +    GObject *render;                        /* Image de statut à afficher  */ +    GtkLabel *status;                       /* Bilan à faire paraître      */ + +    /* Icone de représentation */ + +    access = strdup("process_"); +    access = stradd(access, step->key); +    access = stradd(access, "_icon"); + +    render = G_OBJECT(g_object_get_data(step->ref, access)); +    g_object_set(render, "icon-name", step->success ? "face-smile" : "face-sad", NULL); + +    free(access); + +    /* Mot de la fin */ + +    if (step->msg != NULL) +    { +        access = strdup("process_"); +        access = stradd(access, step->key); +        access = stradd(access, "_status"); + +        status = GTK_LABEL(g_object_get_data(step->ref, access)); +        gtk_label_set_text(status, step->msg); + +        free(access); + +    } + +    /* Nettoyage final */ + +    if (step->dynamic) +        free(step->dmsg); + +    free(step); + +    return FALSE; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : ref     = espace de référencements inter-panneaux.           * +*                key     = clef partielle d'accès aux composants concernés.   * +*                msg     = message d'information accompagnant la conclusion.  * +*                success = indication quant à la réussite de l'opération.     * +*                                                                             * +*  Description : Affiche un message de statut quant aux recherches en cours.  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void push_dyn_status_printing_of_rop_search_step(GObject *ref, const char *key, char *dmsg, bool success) +{ +    search_step *step;                      /* Informations d'étape        */ + +    step = (search_step *)calloc(1, sizeof(search_step)); + +    step->ref = ref; + +    step->key = key; +    step->dynamic = true; +    step->dmsg = dmsg; +    step->success = success; + +    g_idle_add((GSourceFunc)print_status_of_rop_search_step, step); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : ref     = espace de référencements inter-panneaux.           * +*                key     = clef partielle d'accès aux composants concernés.   * +*                msg     = message d'information accompagnant la conclusion.  * +*                success = indication quant à la réussite de l'opération.     * +*                                                                             * +*  Description : Affiche un message de statut quant aux recherches en cours.  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void push_status_printing_of_rop_search_step(GObject *ref, const char *key, const char *msg, bool success) +{ +    search_step *step;                      /* Informations d'étape        */ + +    step = (search_step *)calloc(1, sizeof(search_step)); + +    step->ref = ref; + +    step->key = key; +    step->dynamic = false; +    step->msg = msg; +    step->success = success; + +    g_idle_add((GSourceFunc)print_status_of_rop_search_step, step); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : step = informations quant à l'étape avancée.                 * +*                                                                             * +*  Description : Actualise la barre de progression affichée.                  * +*                                                                             * +*  Retour      : FALSE pour ne pas reprogrammer l'exécution de la tâche.      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static gboolean update_progress_bar_fraction(search_step *step) +{ +    GtkProgressBar *pbar;                   /* Barre à mettre à jour       */ + +    pbar = GTK_PROGRESS_BAR(g_object_get_data(step->ref, "process_gadgets_status")); + +    gtk_progress_bar_set_fraction(pbar, step->fraction); + +    /* Nettoyage final */ + +    free(step); + +    return FALSE; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : ref      = espace de référencements inter-panneaux.          * +*                fraction = avancée globale du désassemblage en cours.        * +*                                                                             * +*  Description : Lance l'actualisation de la barre de progression affichée.   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void push_new_progress_fraction(GObject *ref, gdouble fraction) +{ +    search_step *step;                      /* Informations d'étape        */ + +    step = (search_step *)calloc(1, sizeof(search_step)); + +    step->ref = ref; + +    step->fraction = fraction; + +    g_idle_add((GSourceFunc)update_progress_bar_fraction, step); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : step = informations quant à l'étape avancée.                 * +*                                                                             * +*  Description : Enregistre une référence vers les gadgets trouvés.           * +*                                                                             * +*  Retour      : FALSE pour ne pas reprogrammer l'exécution de la tâche.      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static gboolean register_found_rop_gadgets(search_step *step) +{ +    GtkComboBoxText *combo;                 /* Sélection d'une catégorie   */ +    GtkTreeView *treeview;                  /* Arborescence à actualiser   */ +    GtkTreeModelFilter *filter;             /* Modèle de gestion associé   */ +    size_t i;                               /* Boucle de parcours          */ +    GtkWidget *page;                        /* Page de la partie terminée  */ + +    /* Affichage des résulats */ + +    if (step->format != NULL) +    { +        combo = GTK_COMBO_BOX_TEXT(g_object_get_data(step->ref, "filter_cat")); + +        treeview = GTK_TREE_VIEW(g_object_get_data(step->ref, "treeview")); +        filter = GTK_TREE_MODEL_FILTER(gtk_tree_view_get_model(treeview)); + +        for (i = 0; i < step->count; i++) +            add_new_gadgets_for_category(step->format, +                                         combo, GTK_TREE_STORE(gtk_tree_model_filter_get_model(filter)), +                                         step->list[i].category, step->list[i].gadgets, step->list[i].count); + +        if (step->list != NULL) +            free(step->list); + +    } + +    /* Déverrouillage des accès à la suite */ + +    page = gtk_assistant_get_nth_page(GTK_ASSISTANT(step->ref), 1); + +    gtk_assistant_set_page_complete(GTK_ASSISTANT(step->ref), page, TRUE); + +    /* Nettoyage final */ + +    free(step); + +    return FALSE; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : ref    = espace de référencements inter-panneaux.            * +*                format = format binaire chargé.                              * +*                list   = liste de liste de gadgets pour ROP.                 * +*                count  = taille de cette liste.                              * +*                                                                             * +*  Description : Lance une conservation des gadgets trouvés.                  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void push_found_rop_gadgets(GObject *ref, GBinFormat *format, found_rop_list *list, size_t count) +{ +    search_step *step;                      /* Informations d'étape        */ + +    step = (search_step *)calloc(1, sizeof(search_step)); + +    step->ref = ref; + +    step->format = format; +    step->list = list; +    step->count = count; + +    g_idle_add((GSourceFunc)register_found_rop_gadgets, step); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : ref = espace de référencements inter-panneaux.               * +*                                                                             * +*  Description : Charge un format binaire interne déjà chargé.                * +*                                                                             * +*  Retour      : Nouveau format au contenu à fouiller ou NULL en cas d'échec. * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GBinFormat *load_internal_format_for_rop_gadgets(GObject *ref) +{ +    GBinFormat *result;                     /* Format chargé à retourner   */ +    GtkComboBox *combo;                     /* Composant de sélection      */ +    GtkTreeIter iter;                       /* Tête de lecture à placer    */ +    GtkTreeModel *model;                    /* Modèle de gestion           */ +    GLoadedBinary *binary;                  /* Binaire chargé à utiliser   */ + +    combo = GTK_COMBO_BOX(g_object_get_data(ref, "input_binary")); + +    if (!gtk_combo_box_get_active_iter(combo, &iter)) +    { +        push_status_printing_of_rop_search_step(ref, "loading", _("unable to get the current binary"), false); +        return NULL; +    } + +    model = gtk_combo_box_get_model(combo); +    gtk_tree_model_get(model, &iter, CPB_BINARY, &binary, -1); + +    push_status_printing_of_rop_search_step(ref, "loading", _("done"), true); + +    result = G_BIN_FORMAT(g_loaded_binary_get_format(binary)); + +    push_status_printing_of_rop_search_step(ref, "format", _("already loaded"), true); + +    g_object_ref(G_OBJECT(result)); +    g_object_unref(G_OBJECT(binary)); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : ref = espace de référencements inter-panneaux.               * +*                                                                             * +*  Description : Charge un format binaire externe.                            * +*                                                                             * +*  Retour      : Nouveau format au contenu à fouiller ou NULL en cas d'échec. * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GBinFormat *load_external_format_for_rop_gadgets(GObject *ref) +{ +    GBinFormat *result;                     /* Format chargé à retourner   */ +    GtkEntry *entry;                        /* Zone de saisie de texte     */ +    const gchar *filename;                  /* Nom du fichier à charger    */ +    GBinContent *content;                   /* Contenu binaire chargé      */ +    const char *target;                     /* Sous-traitance requise      */ +    const char *desc;                       /* Description humaine associée*/ + +    /* Récupération du nom de fichier */ + +    entry = GTK_ENTRY(g_object_get_data(ref, "input_filename")); + +    filename = gtk_entry_get_text(entry); + +    /* Récupération du contenu binaire */ + +    content = g_binary_content_new_from_file(filename); +    if (content == NULL) +    { +        push_status_printing_of_rop_search_step(ref, "loading", _("unable to get the binary content"), false); +        goto leffrg_error; +    } + +    push_status_printing_of_rop_search_step(ref, "loading", _("done"), true); + +    /* Récupération du format de fichier associé */ + +    target = find_matching_format(content); +    desc = get_binary_format_name(target); + +    if (desc == NULL) +    { +        g_object_unref(G_OBJECT(content)); +        push_status_printing_of_rop_search_step(ref, "format", _("unknown binary format"), false); +        goto leffrg_error; +    } + +    result = load_new_named_format(target, content); + +    if (result == NULL) +    { +        push_status_printing_of_rop_search_step(ref, "format", _("error while loading the binary"), false); +        goto leffrg_error; +    } + +    push_status_printing_of_rop_search_step(ref, "format", desc, true); + +    return result; + + leffrg_error: + +    return NULL; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : ref = espace de référencements inter-panneaux.               * +*                                                                             * +*  Description : Procède à la recherche de gadgets de façon séparée.          * +*                                                                             * +*  Retour      : ?                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static gpointer look_for_rop_gadgets(GObject *ref) +{ +    GtkToggleButton *internal;              /* Bouton de sélection interne */ +    gboolean state;                         /* Etat du bouton courant      */ +    GBinFormat *format;                     /* Format du binaire à traiter */ +    found_rop_list *list;                   /* Liste de gadgets ROP trouvés*/ +    size_t count;                           /* Nombre de ces listes        */ +    size_t found;                           /* Nombre de gadgets trouvés   */ +    size_t i;                               /* Boucle de parcours          */ +    char *msg;                              /* Message final à faire passer*/ + +    internal = GTK_TOGGLE_BUTTON(g_object_get_data(ref, "loaded_as_input")); +    state = gtk_toggle_button_get_active(internal); + +    if (state) +        format = load_internal_format_for_rop_gadgets(ref); +    else +        format = load_external_format_for_rop_gadgets(ref); + +    if (format == NULL) goto lfrg_unlock; + +    list = list_all_gadgets(format, 7, push_new_progress_fraction, ref, &count); + +    push_status_printing_of_rop_search_step(ref, "gadgets", NULL, true); + +    found = 0; + +    for (i = 0; i < count; i++) +        found += list[i].count; + +    switch (found) +    { +        case 0: +            msg = strdup(_("No ROP gadget has been found.")); +            break; + +        case 1: +            msg = strdup(_("1 ROP gadget has been found.")); +            break; + +        default: +            asprintf(&msg, _("%zu gadgets have been found."), found); +            break; + +    } + +    push_dyn_status_printing_of_rop_search_step(ref, "final", msg, count > 0); + + lfrg_unlock: + +    push_found_rop_gadgets(ref, format, list, count); + +    return NULL; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                         MISE EN FORME DES GADGETS PRESENTS                         */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : assistant = fenêtre d'assistance à compléter.                * +*                ref       = espace de référencements inter-panneaux.         * +*                                                                             * +*  Description : Ajoute le panneau de sélection des gadgets ROP identifiés.   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void register_rop_list_panel(GtkAssistant *assistant, GObject *ref) +{ +    GtkWidget *vbox;                        /* Support principal           */ +    GtkWidget *hbox;                        /* Petite barre supérieure     */ +    GtkWidget *label;                       /* Etiquette d'indication      */ +    GtkWidget *comboboxentry;               /* Liste de sélection simple   */ +    GtkWidget *vseparator;                  /* Barre de séparation         */ +    GtkWidget *filter;                      /* Zone de recherche           */ +    GtkWidget *scrollwnd;                   /* Support défilant            */ +    GtkTreeStore *store;                    /* Modèle de gestion           */ +    GtkTreeModel *model;                    /* Modèle de gestion supérieur */ +    GtkWidget *treeview;                    /* Affichage de la liste       */ +    GtkCellRenderer *renderer;              /* Moteur de rendu de colonne  */ +    GtkTreeViewColumn *column;              /* Colonne de la liste         */ + +    vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); +    gtk_widget_show(vbox); +    gtk_container_set_border_width(GTK_CONTAINER(vbox), 8); + +    hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); +    gtk_widget_show(hbox); +    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0); + +    /* Choix de la catégorie */ + +    label = gtk_label_new(_("ROP selection:")); +    gtk_widget_show(label); +    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + +    comboboxentry = qck_create_combobox(ref, "filter_cat", G_CALLBACK(on_rop_gadgets_category_changed), ref); +    gtk_box_pack_start(GTK_BOX(hbox), comboboxentry, FALSE, TRUE, 0); + +    /* Séparation fine */ + +    vseparator = gtk_separator_new(GTK_ORIENTATION_VERTICAL); +    gtk_widget_show(vseparator); +    gtk_box_pack_start(GTK_BOX(hbox), vseparator, FALSE, FALSE, 0); + +    /* Espace de recherche */ + +    label = gtk_label_new(_("Filter:")); +    gtk_widget_show(label); +    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + +    filter = gtk_search_entry_new(); +    g_object_set_data(ref, "filter_rop", filter); +    gtk_widget_set_tooltip_text(filter, _("Filter gadgets using POSIX extended regular expressions")); + +    g_signal_connect(filter, "search-changed", G_CALLBACK(on_rop_gadgets_filter_changed), ref); +    gtk_widget_show(filter); +    gtk_widget_set_hexpand(filter, TRUE); + +    gtk_box_pack_start(GTK_BOX(hbox), filter, TRUE, TRUE, 0); + +    /* Liste arborescente ou linéaire */ + +    scrollwnd = gtk_scrolled_window_new(NULL, NULL); +    gtk_widget_show(scrollwnd); +    gtk_box_pack_start(GTK_BOX(vbox), scrollwnd, TRUE, TRUE, 0); + +    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwnd), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); +    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollwnd), GTK_SHADOW_IN); + +    store = gtk_tree_store_new(FRG_COUNT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, +                               G_TYPE_STRING, G_TYPE_STRING); + +    model = gtk_tree_model_filter_new(GTK_TREE_MODEL(store), NULL); + +    gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(model), +                                           (GtkTreeModelFilterVisibleFunc)filter_visible_rop_gadgets, +                                           ref, NULL); + +    treeview = gtk_tree_view_new_with_model(model); +    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), TRUE); +    gtk_tree_view_set_enable_tree_lines(GTK_TREE_VIEW(treeview), TRUE); + +    g_object_set_data(ref, "treeview", treeview); + +    gtk_widget_show(treeview); +    gtk_container_add(GTK_CONTAINER(scrollwnd), treeview); + +    /* Cellules d'affichage */ + +    renderer = gtk_cell_renderer_text_new(); +    column = gtk_tree_view_column_new_with_attributes(_("Address"), renderer, +                                                      "markup", FRG_VIRTUAL, +                                                      NULL); +    gtk_tree_view_column_set_sort_column_id(column, FRG_VIRTUAL); +    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + +    renderer = gtk_cell_renderer_text_new(); +    column = gtk_tree_view_column_new_with_attributes(_("Gadgets"), renderer, +                                                      "markup", FRG_CONTENT, +                                                      NULL); +    gtk_tree_view_column_set_sort_column_id(column, FRG_CONTENT); +    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + +    /* Intégration */ + +    gtk_assistant_append_page(assistant, vbox); +    gtk_assistant_set_page_title(assistant, vbox, _("ROP Gadgets")); +    gtk_assistant_set_page_type(assistant, vbox, GTK_ASSISTANT_PAGE_CONFIRM); + +    gtk_assistant_set_page_complete(assistant, vbox, TRUE); + +} + + + + + + + + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : combo = composant de choix contenant le filtre brut.         * +*                ref   = espace de référencements inter-panneaux.             * +*                                                                             * +*  Description : Lance l'actualisation du filtrage des gadgets ROP.           * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void on_rop_gadgets_category_changed(GtkComboBox *combo, GObject *ref) +{ +    GtkTreeView *treeview;                  /* Arborescence à actualiser   */ +    GtkTreeModelFilter *filter;             /* Modèle de gestion associé   */ + +    treeview = GTK_TREE_VIEW(g_object_get_data(ref, "treeview")); + +    filter = GTK_TREE_MODEL_FILTER(gtk_tree_view_get_model(treeview)); + +    gtk_tree_model_filter_refilter(filter); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : entry = entrée de texte contenant le filtre brut.            * +*                ref   = espace de référencements inter-panneaux.             * +*                                                                             * +*  Description : Lance l'actualisation du filtrage des gadgets ROP.           * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void on_rop_gadgets_filter_changed(GtkSearchEntry *entry, GObject *ref) +{ +    regex_t preg;                           /* Expression régulière de test*/ +    const gchar *text;                      /* Texte de l'utilisateur      */ +    int ret;                                /* Bilan de mise en place      */ +    GdkRGBA error;                          /* Couleur d'erreur            */ +    GtkTreeView *treeview;                  /* Arborescence à actualiser   */ +    GtkTreeModelFilter *filter;             /* Modèle de gestion associé   */ + +    text = gtk_entry_get_text(GTK_ENTRY(entry)); + +    if (text[0] != '\0') +    { +        ret = regcomp(&preg, text, REG_EXTENDED); + +        if (ret != 0) +        { +            error.red = 1.0; +            error.green = 0.0; +            error.blue = 0.0; +            error.alpha = 1.0; +            gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, &error); + +            return; + +        } + +        regfree(&preg); + +    } + +    gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, NULL); + +    treeview = GTK_TREE_VIEW(g_object_get_data(ref, "treeview")); + +    filter = GTK_TREE_MODEL_FILTER(gtk_tree_view_get_model(treeview)); + +    gtk_tree_model_filter_refilter(filter); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : model = gestionnaire des lignes et colonnes affichées.       * +*                iter  = ligne concernée par l'analyse à mener.               * +*                ref   = espace de référencements inter-panneaux.             * +*                                                                             * +*  Description : Détermine la visibilité de tel ou tel gadget ROP.            * +*                                                                             * +*  Retour      : Indication d'affichage pour une ligne donnée.                * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static gboolean filter_visible_rop_gadgets(GtkTreeModel *model, GtkTreeIter *iter, GObject *ref) +{ +    gboolean result;                        /* Visibilité à retourner      */ +    gchar *category;                        /* Catégorie d'appartenance    */ +    gchar *raw;                             /* Brut pour recherche         */ +    GtkComboBoxText *combo;                 /* Sélection à choix multiples */ +    gchar *selected;                        /* Texte de l'utilisateur #1   */ +    GtkEntry *entry;                        /* Zone de texte à utiliser    */ +    const gchar *text;                      /* Texte de l'utilisateur #2   */ +    regex_t preg;                           /* Expression régulière de test*/ +    int ret;                                /* Bilan de mise en place      */ +    regmatch_t match;                       /* Récupération des trouvailles*/ + +    result = TRUE; + +    gtk_tree_model_get(model, iter, FRG_CATEGORY, &category, FRG_RAW, &raw, -1); + +    if (category == NULL || raw == NULL) return FALSE; + +    /* Filtre sur les catégories */ + +    combo = g_object_get_data(ref, "filter_cat"); + + 	selected = gtk_combo_box_text_get_active_text(combo); + +    result &= (g_strcmp0(category, selected) == 0); + +    g_free(selected); + +    /* Filtre sur les gadgets ROP */ + +    entry = g_object_get_data(ref, "filter_rop"); + +    text = gtk_entry_get_text(GTK_ENTRY(entry)); + +    ret = regcomp(&preg, text, REG_EXTENDED); +    result &= (ret == 0); + +    if (ret == 0) +    { +        ret = regexec(&preg, raw, 1, &match, 0); +        result &= (ret != REG_NOMATCH); + +        regfree(&preg); + +    } + +    /* Nettoyages finaux */ + +    g_free(category); +    g_free(raw); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format   = format binaire chargé sur lequel se reposer.      * +*                combo    = composant de sélection des catégories à compléter.* +*                store    = modèle de gestionnaire pour la liste affichée.    * +*                category = représentation du binaire chargé en mémoire.      * +*                gadgets  = liste de listes d'instructions de ROP.            * +*                count    = taille de cette liste.                            * +*                                                                             * +*  Description : Ajoute de nouvelles chaînes de gadgets localisées.           * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void add_new_gadgets_for_category(GBinFormat *format, GtkComboBoxText *combo, GtkTreeStore *store, const char *category, GArchInstruction **gadgets, size_t count) +{ +    const char *target;                     /* Sous-traitance requise      */ +    GArchProcessor *proc;                   /* Architecture du binaire     */ +    MemoryDataSize msize;                   /* Taille du bus d'adresses    */ +    const bin_t *content;                   /* Contenu binaire global      */ +    GCodeBuffer *buffer;                    /* Tampon de rassemblement     */ +    size_t i;                               /* Boucle de parcours          */ +    GArchInstruction *instr;                /* Elément de liste de gadgets */ +    GBufferLine *line;                      /* Ligne présente à l'adresse  */ +    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  */ +    GtkTreeIter iter;                       /* Point d'insertion           */ + +    /* Définition de l'écosystème nécessaire */ + +    target = g_exe_format_get_target_machine(G_EXE_FORMAT(format)); +    proc = get_arch_processor_for_type(target); + +    msize = g_arch_processor_get_memory_size(proc); + +    g_object_unref(G_OBJECT(proc)); + +    content = g_binary_format_get_content(G_BIN_FORMAT(format), NULL); + +    /* Conversion en contenu textuel */ + +    buffer = g_code_buffer_new(BLC_ASSEMBLY); + +    for (i = 0; i < count; i++) +    { +        /* Parcours des différentes lignes */ + +        content_raw = NULL; +        content_markup = NULL; + +        for (instr = gadgets[i]; instr != NULL; instr = g_arch_instruction_get_next_iter(gadgets[i], instr, ~0)) +        { +            line = g_arch_instruction_print(instr, buffer, msize, content, ASX_INTEL); +            if (line == NULL) continue; + +            if (instr == gadgets[i]) +            { +                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); +            } + +            partial_raw = g_buffer_line_get_text(line, BLC_ASSEMBLY_HEAD, BLC_COUNT, false); +            partial_markup = g_buffer_line_get_text(line, BLC_ASSEMBLY_HEAD, BLC_COUNT, true); + +            if (content_raw != NULL) +                content_raw = stradd(content_raw, " ; "); + +            content_raw = stradd(content_raw, partial_raw); + +            if (content_markup != NULL) +                content_markup = stradd(content_markup, " ; "); + +            content_markup = stradd(content_markup, partial_markup); + +            free(partial_raw); +            free(partial_markup); + +        } + +        /* Insertion finale */ + +        gtk_tree_store_append(store, &iter, NULL); + +        gtk_tree_store_set(store, &iter, +                           FRG_CATEGORY, category, +                           FRG_RAW_VIRTUAL, raw_virtual, +                           FRG_RAW, content_raw, +                           FRG_VIRTUAL, virtual, +                           FRG_CONTENT, content_markup, +                           -1); + +        /* Nettoyage de la mémoire */ + +        free(raw_virtual); +        free(virtual); +        free(content_raw); +        free(content_markup); + +    } + +    g_object_unref(G_OBJECT(buffer)); + +    /* Rajout de la catégorie et filtre au besoin */ + +    gtk_combo_box_text_append_text(combo, category); + +    if (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)) == -1) +        gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0); + +} diff --git a/plugins/ropgadgets/select.h b/plugins/ropgadgets/select.h new file mode 100644 index 0000000..9e18ddd --- /dev/null +++ b/plugins/ropgadgets/select.h @@ -0,0 +1,40 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * goto.h - prototypes pour la boîte de dialogue pour les sauts à une adresse donnée + * + * Copyright (C) 2012 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA 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. + * + *  OpenIDA 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 Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _DIALOGS_GOTOX_H +#define _DIALOGS_GOTOX_H + + +#include <gtk/gtk.h> + + +#include <analysis/binary.h> + + + +/* Crée et affiche un assistant de sélection de gadgets ROP. */ +void run_rop_finder_assistant(GObject *, GtkWindow *); + + + +#endif  /* _DIALOGS_GOTOX_H */ diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c index 6ed6804..2e7b46d 100644 --- a/src/analysis/disass/area.c +++ b/src/analysis/disass/area.c @@ -490,7 +490,7 @@ bool load_code_from_mem_area(mem_area **list, size_t *count, size_t *index, cons -    mrange_t range;                             /* Couverture de l'instruction */ +    mrange_t range;                         /* Couverture de l'instruction */      vmpa2t sym_addr;                        /* Adresse de nouveau symbole  */ diff --git a/src/arch/arm/v7/opdefs/pop_A88131.d b/src/arch/arm/v7/opdefs/pop_A88131.d index ef5ab25..5229af9 100644 --- a/src/arch/arm/v7/opdefs/pop_A88131.d +++ b/src/arch/arm/v7/opdefs/pop_A88131.d @@ -39,7 +39,6 @@          //if BitCount(registers) < 1 then UNPREDICTABLE;          //if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; -        chk_call DefineAsReturn(1)      } @@ -61,7 +60,6 @@          //if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;          //if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; -        chk_call DefineAsReturn(1)      } @@ -83,7 +81,7 @@      @rules {          //if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; -        chk_call DefineAsReturn(1) +        if (Rt == '1111') ; chk_call DefineAsReturn(1)      } diff --git a/src/arch/arm/v7/opdefs/pop_A88132.d b/src/arch/arm/v7/opdefs/pop_A88132.d index 89c51c9..1762b45 100644 --- a/src/arch/arm/v7/opdefs/pop_A88132.d +++ b/src/arch/arm/v7/opdefs/pop_A88132.d @@ -40,7 +40,7 @@          //if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;          //if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; -        chk_call DefineAsReturn(1) +        if (register_list & 0x8000) ; chk_call DefineAsReturn(1)      } @@ -63,7 +63,7 @@      @rules {          //if t == 13 then UNPREDICTABLE; -        chk_call DefineAsReturn(1) +        if (Rt == '1111') ; chk_call DefineAsReturn(1)      } diff --git a/src/arch/processor.h b/src/arch/processor.h index d650266..a856942 100644 --- a/src/arch/processor.h +++ b/src/arch/processor.h @@ -74,7 +74,17 @@ MemoryDataSize g_arch_processor_get_instruction_size(const GArchProcessor *);  GArchInstruction *g_arch_processor_decode_instruction(const GArchProcessor *, GProcContext *, const bin_t *, off_t *, off_t, vmpa_t, GBinFormat *) __attribute__ ((deprecated));  /* Désassemble une instruction dans un flux de données. */ -GArchInstruction *g_arch_processor_disassemble(const GArchProcessor *, GProcContext *, const bin_t *, vmpa2t *, phys_t); +GArchInstruction *g_arch_processor_disassemble(const GArchProcessor *, GProcContext *, const bin_t *, vmpa2t *, phys_t) __attribute__ ((deprecated)); + + + +#define g_arch_processor_disassemble_nextgen(_proc, _ctx, _cnt, _pos)               \ +    ({                                                                              \ +        const bin_t *_bin_data;                                                     \ +        off_t _bin_length;                                                          \ +        _bin_data = g_binary_content_get(_cnt, &_bin_length);                       \ +        g_arch_processor_disassemble(_proc, _ctx, _bin_data, _pos, _bin_length);    \ +    }) diff --git a/src/arch/vmpa.c b/src/arch/vmpa.c index ad4c078..b10b007 100644 --- a/src/arch/vmpa.c +++ b/src/arch/vmpa.c @@ -247,6 +247,32 @@ void advance_vmpa(vmpa2t *addr, phys_t qty)  /******************************************************************************  *                                                                             * +*  Paramètres  : addr = élément à modifier.                                   * +*                qty  = quantité d'unités de décallage.                       * +*                                                                             * +*  Description : Décalle une position d'une certaine quantité.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void deminish_vmpa(vmpa2t *addr, phys_t qty) +{ +    /* On choisit de ne pas vérifier les débordements */ + +    if (addr->physical != VMPA_NO_PHYSICAL) +        addr->physical -= qty; + +    if (addr->virtual != VMPA_NO_VIRTUAL) +        addr->virtual -= qty; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : a = première élément à venir consulter.                      *  *                b = second élément à traiter en parallèle.                   *  *                                                                             * diff --git a/src/arch/vmpa.h b/src/arch/vmpa.h index 3e0d35c..4611ebf 100644 --- a/src/arch/vmpa.h +++ b/src/arch/vmpa.h @@ -111,6 +111,9 @@ int cmp_vmpa(const vmpa2t *, const vmpa2t *);  /* Décalle une position d'une certaine quantité. */  void advance_vmpa(vmpa2t *, phys_t); +/* Décalle une position d'une certaine quantité. */ +void deminish_vmpa(vmpa2t *, phys_t); +  /* Calcule au mieux la distance entre deux coordonnées. */  phys_t compute_vmpa_diff(const vmpa2t *, const vmpa2t *); diff --git a/src/gui/menus/Makefile.am b/src/gui/menus/Makefile.am index fcebcf2..d932141 100644 --- a/src/gui/menus/Makefile.am +++ b/src/gui/menus/Makefile.am @@ -8,6 +8,7 @@ libguimenus_la_SOURCES =				\  	file.h file.c						\  	help.h help.c						\  	menubar.h menubar.c					\ +	plugins.h plugins.c					\  	project.h project.c					\  	view.h view.c diff --git a/src/gui/menus/menubar.c b/src/gui/menus/menubar.c index cc69e0d..1fc1b6f 100644 --- a/src/gui/menus/menubar.c +++ b/src/gui/menus/menubar.c @@ -30,6 +30,7 @@  #include "edition.h"  #include "file.h"  #include "help.h" +#include "plugins.h"  #include "project.h"  #include "view.h"  #include "../editem-int.h" @@ -47,6 +48,7 @@ struct _GMenuBar      GtkWidget *project;                     /* Menu "Projet"               */      GtkWidget *binary;                      /* Menu "Binaire"              */      GtkWidget *debug;                       /* Menu "Débogage"             */ +    GtkWidget *plugins;                     /* Menu "Greffons"             */      GtkWidget *help;                        /* Menu "Aide"                 */  }; @@ -239,6 +241,11 @@ GEditorItem *g_menu_bar_new(GObject *ref, GtkAccelGroup *accgroup)      result->debug = build_menu_debug(ref, accgroup);      gtk_container_add(GTK_CONTAINER(item->widget), result->debug); +    /* Greffons */ + +    result->plugins = build_menu_plugins(ref, accgroup); +    gtk_container_add(GTK_CONTAINER(item->widget), result->plugins); +      /* Aide */      result->help = build_menu_help(ref, accgroup); diff --git a/src/gui/menus/plugins.c b/src/gui/menus/plugins.c new file mode 100644 index 0000000..6967665 --- /dev/null +++ b/src/gui/menus/plugins.c @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * plugins.c - gestion du menu 'Greffons' + * + * Copyright (C) 2015 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA 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. + * + *  OpenIDA 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 this program; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + */ + + +#include "plugins.h" + + +#include <string.h> + + +#include <i18n.h> + + +#include "../../gtkext/easygtk.h" + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : ref      = espace de référencement global.                   * +*                accgroup = groupe d'accélérateurs pour les menus.            * +*                                                                             * +*  Description : Construit le menu "Aide".                                    * +*                                                                             * +*  Retour      : Panneau de menus mis en place.                               * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GtkWidget *build_menu_plugins(GObject *ref, GtkAccelGroup *accgroup) +{ +    GtkWidget *result;                      /* Support à retourner         */ +    GtkWidget *menubar;                     /* Support pour éléments       */ + +    result = gtk_menu_item_new_with_mnemonic(_("_Plugins")); +    gtk_widget_show(result); + +    menubar = gtk_menu_new(); +    g_object_set_data(ref, "menubar_plugins", G_OBJECT(menubar)); +    gtk_menu_item_set_submenu(GTK_MENU_ITEM(result), menubar); + +    return result; + +} diff --git a/src/gui/menus/plugins.h b/src/gui/menus/plugins.h new file mode 100644 index 0000000..9d83f4d --- /dev/null +++ b/src/gui/menus/plugins.h @@ -0,0 +1,38 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * plugins.h - prototypes pour la gestion du menu 'Greffons' + * + * Copyright (C) 2015 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA 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. + * + *  OpenIDA 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 this program; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + */ + + +#ifndef _GUI_MENUS_PLUGINS_H +#define _GUI_MENUS_PLUGINS_H + + +#include <gtk/gtk.h> + + + +/* Construit le menu "Aide". */ +GtkWidget *build_menu_plugins(GObject *, GtkAccelGroup *); + + + +#endif  /* _GUI_MENUS_PLUGINS_H */ diff --git a/src/plugins/pglist.c b/src/plugins/pglist.c index 70fc66a..f85eee7 100644 --- a/src/plugins/pglist.c +++ b/src/plugins/pglist.c @@ -197,7 +197,7 @@ void browse_directory_for_plugins(plugins_list *list, const char *dir)          else          { -            plugin = g_plugin_module_new(filename); +            plugin = g_plugin_module_new(filename, _list.ref);              if (plugin != NULL)                  add_plugin_to_main_list(plugin); diff --git a/src/plugins/plugin-int.h b/src/plugins/plugin-int.h index 41cc535..1f4e17e 100644 --- a/src/plugins/plugin-int.h +++ b/src/plugins/plugin-int.h @@ -37,7 +37,7 @@  /* Prend acte du [dé]chargement du greffon. */ -typedef bool (* pg_management_fc) (GPluginModule *); +typedef bool (* pg_management_fc) (GPluginModule *, GObject *);  /* Indique si le format peut être pris en charge ici. */  typedef bool (* pg_format_is_matching) (const GPluginModule *, GBinContent **); diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c index 89a8040..65f3cc6 100644 --- a/src/plugins/plugin.c +++ b/src/plugins/plugin.c @@ -113,7 +113,7 @@ static void g_plugin_module_init(GPluginModule *plugin)  static void g_plugin_module_dispose(GPluginModule *plugin)  {      if (plugin->exit != NULL) -        plugin->exit(plugin); +        plugin->exit(plugin, NULL /* FIXME */);      if (plugin->module != NULL)          g_module_close(plugin->module); @@ -147,6 +147,7 @@ static void g_plugin_module_finalize(GPluginModule *plugin)  /******************************************************************************  *                                                                             *  *  Paramètres  : filename = nom du fichier à charger.                         * +*                ref      = espace de référencement global.                   *  *                                                                             *  *  Description : Crée un module pour un greffon donné.                        *  *                                                                             * @@ -156,7 +157,7 @@ static void g_plugin_module_finalize(GPluginModule *plugin)  *                                                                             *  ******************************************************************************/ -GPluginModule *g_plugin_module_new(const gchar *filename) +GPluginModule *g_plugin_module_new(const gchar *filename, GObject *ref)  {      GPluginModule *result;                  /* Structure à retourner       */      plugin_abi_version_t current;           /* Version de l'ABI actuelle   */ @@ -304,7 +305,7 @@ GPluginModule *g_plugin_module_new(const gchar *filename)      if (result->init != NULL)      { -        if (!result->init(result)) +        if (!result->init(result, ref))          {              log_variadic_message(LMT_ERROR,                                   _("Plugin '%s' failed to load itself..."), filename); diff --git a/src/plugins/plugin.h b/src/plugins/plugin.h index d571659..b974ca8 100644 --- a/src/plugins/plugin.h +++ b/src/plugins/plugin.h @@ -53,7 +53,7 @@ typedef struct _GPluginModuleClass GPluginModuleClass;  GType g_plugin_module_get_type(void);  /* Crée un module pour un greffon donné. */ -GPluginModule *g_plugin_module_new(const gchar *); +GPluginModule *g_plugin_module_new(const gchar *, GObject *);  /* Fournit la description du greffon dans son intégralité. */  const plugin_interface *g_plugin_module_get_interface(const GPluginModule *); | 
