diff options
Diffstat (limited to 'src/arch')
| -rw-r--r-- | src/arch/Makefile.am | 2 | ||||
| -rw-r--r-- | src/arch/artificial.c | 46 | ||||
| -rw-r--r-- | src/arch/artificial.h | 14 | ||||
| -rw-r--r-- | src/arch/context-int.h | 49 | ||||
| -rw-r--r-- | src/arch/context.c | 77 | ||||
| -rw-r--r-- | src/arch/context.h | 52 | ||||
| -rw-r--r-- | src/arch/dalvik/Makefile.am | 2 | ||||
| -rw-r--r-- | src/arch/dalvik/context.c | 229 | ||||
| -rw-r--r-- | src/arch/dalvik/context.h | 73 | ||||
| -rw-r--r-- | src/arch/dalvik/processor.c | 40 | ||||
| -rw-r--r-- | src/arch/dalvik/specins.c | 115 | ||||
| -rw-r--r-- | src/arch/dalvik/specins.h | 51 | ||||
| -rw-r--r-- | src/arch/processor-int.h | 8 | ||||
| -rw-r--r-- | src/arch/processor.c | 42 | ||||
| -rw-r--r-- | src/arch/processor.h | 6 | 
15 files changed, 795 insertions, 11 deletions
diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am index 1a02c07..4f410cc 100644 --- a/src/arch/Makefile.am +++ b/src/arch/Makefile.am @@ -4,6 +4,8 @@ noinst_LTLIBRARIES = libarch.la  libarch_la_SOURCES =					\  	archbase.h archbase.c				\  	artificial.h artificial.c			\ +	context-int.h						\ +	context.h context.c					\  	immediate.h immediate.c				\  	instruction-int.h					\  	instruction.h instruction.c			\ diff --git a/src/arch/artificial.c b/src/arch/artificial.c index 7556d0a..4ffcbe3 100644 --- a/src/arch/artificial.c +++ b/src/arch/artificial.c @@ -37,6 +37,10 @@ struct _GDbInstruction  {      GArchInstruction parent;                /* A laisser en premier        */ +#ifdef DEBUG +    bool skipped;                           /* Donnée traitée              */ +#endif +  };  /* Définition générique d'une instruction d'architecture inconnue (classe) */ @@ -217,3 +221,45 @@ static bool g_db_instruction_is_return(const GDbInstruction *instr)      return false;  } + + +#ifdef DEBUG + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr = instruction à mettre à jour.                         * +*                                                                             * +*  Description : Marque une donnée comme ayant été considérée au sein du code.* +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_db_instruction_mark_as_skipped(GDbInstruction *instr) +{ +    instr->skipped = true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr = instruction à consulter.                             * +*                                                                             * +*  Description : Indique si une donnée fait partie du code exécutable.        * +*                                                                             * +*  Retour      : true si la donnée est intégrée dans le code, false sinon.    * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_db_instruction_is_skipped(const GDbInstruction *instr) +{ +    return instr->skipped; + +} + +#endif diff --git a/src/arch/artificial.h b/src/arch/artificial.h index 3e98595..f4a661d 100644 --- a/src/arch/artificial.h +++ b/src/arch/artificial.h @@ -37,9 +37,9 @@  #define G_TYPE_DB_INSTRUCTION                   g_db_instruction_get_type() -#define G_DB_INSTRUCTION(obj)                   (G_TYPE_CHECK_INSTANCE_CAST((obj), g_db_instruction_get_type(), GArchOperand)) +#define G_DB_INSTRUCTION(obj)                   (G_TYPE_CHECK_INSTANCE_CAST((obj), g_db_instruction_get_type(), GDbInstruction))  #define G_IS_DB_INSTRUCTION(obj)                (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_db_instruction_get_type())) -#define G_DB_INSTRUCTION_GET_IFACE(inst)        (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_db_instruction_get_type(), GArchOperandIface)) +#define G_DB_INSTRUCTION_GET_IFACE(inst)        (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_db_instruction_get_type(), GDbInstructionIface))  /* Définition générique d'une instruction d'architecture inconnue (instance) */ @@ -55,6 +55,16 @@ GType g_db_instruction_get_type(void);  /* Crée une instruction de type 'db' à partir de données. */  GArchInstruction *g_db_instruction_new_from_data(const bin_t *, off_t *, off_t, vmpa_t, const GArchProcessor *); +#ifdef DEBUG + +/*  Marque une donnée comme ayant été considérée au sein du code. */ +void g_db_instruction_mark_as_skipped(GDbInstruction *); + +/* Indique si une donnée fait partie du code exécutable. */ +bool g_db_instruction_is_skipped(const GDbInstruction *); + +#endif +  #endif  /* _ARCH_ARTIFICIAL_H */ diff --git a/src/arch/context-int.h b/src/arch/context-int.h new file mode 100644 index 0000000..c5bd386 --- /dev/null +++ b/src/arch/context-int.h @@ -0,0 +1,49 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * context-int.h - prototypes internes pour le contexte lié à l'exécution d'un processeur + * + * Copyright (C) 2011 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  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 _ARCH_CONTEXT_INT_H +#define _ARCH_CONTEXT_INT_H + + +#include "context.h" + + + +/* Définition d'un contexte pour processeur (instance) */ +struct _GProcContext +{ +    GObject parent;                         /* A laisser en premier        */ + +}; + + +/* Définition d'un contexte pour processeur (classe) */ +struct _GProcContextClass +{ +    GObjectClass parent;                    /* A laisser en premier        */ + +}; + + + +#endif  /* _ARCH_CONTEXT_INT_H */ diff --git a/src/arch/context.c b/src/arch/context.c new file mode 100644 index 0000000..3d8f08c --- /dev/null +++ b/src/arch/context.c @@ -0,0 +1,77 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * context.c - contexte lié à l'exécution d'un processeur + * + * Copyright (C) 2011 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  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 "context.h" + + +#include "context-int.h" + + + +/* Initialise la classe des contextes de processeur. */ +static void g_proc_context_class_init(GProcContextClass *); + +/* Initialise une instance de contexte de processeur. */ +static void g_proc_context_init(GProcContext *); + + + +/* Indique le type définit par la GLib pour le contexte de processeur. */ +G_DEFINE_TYPE(GProcContext, g_proc_context, G_TYPE_OBJECT); + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des contextes de processeur.            * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_proc_context_class_init(GProcContextClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : ctx = instance à initialiser.                                * +*                                                                             * +*  Description : Initialise une instance de contexte de processeur.           * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_proc_context_init(GProcContext *ctx) +{ + +} diff --git a/src/arch/context.h b/src/arch/context.h new file mode 100644 index 0000000..4111767 --- /dev/null +++ b/src/arch/context.h @@ -0,0 +1,52 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * context.h - prototypes pour le contexte lié à l'exécution d'un processeur + * + * Copyright (C) 2011 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  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 _ARCH_CONTEXT_H +#define _ARCH_CONTEXT_H + + +#include <glib-object.h> + + + +#define G_TYPE_PROC_CONTEXT              g_proc_context_get_type() +#define G_PROC_CONTEXT(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), g_proc_context_get_type(), GProcContext)) +#define G_IS_PROC_CONTEXT(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_proc_context_get_type())) +#define G_PROC_CONTEXT_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_PROC_CONTEXT, GGProcContextClass)) +#define G_IS_PROC_CONTEXT_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_PROC_CONTEXT)) +#define G_PROC_CONTEXT_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_PROC_CONTEXT, GGProcContextClass)) + + +/* Définition d'un contexte pour processeur (instance) */ +typedef struct _GProcContext GProcContext; + +/* Définition d'un contexte pour processeur (classe) */ +typedef struct _GProcContextClass GProcContextClass; + + +/* Indique le type définit par la GLib pour le contexte de processeur. */ +GType g_proc_context_get_type(void); + + + +#endif  /* _ARCH_CONTEXT_H */ diff --git a/src/arch/dalvik/Makefile.am b/src/arch/dalvik/Makefile.am index e8406b9..6640180 100644 --- a/src/arch/dalvik/Makefile.am +++ b/src/arch/dalvik/Makefile.am @@ -2,6 +2,7 @@  noinst_LTLIBRARIES = libarchdalvik.la  libarchdalvik_la_SOURCES =				\ +	context.h context.c					\  	instruction.h instruction.c			\  	dop_aget.c							\  	dop_aput.c							\ @@ -42,6 +43,7 @@ libarchdalvik_la_SOURCES =				\  	operand.h operand.c					\  	processor.h processor.c				\  	register.h register.c				\ +	specins.h specins.c					\  	translate.h  libarchdalvik_la_LIBADD =				\ diff --git a/src/arch/dalvik/context.c b/src/arch/dalvik/context.c new file mode 100644 index 0000000..67c1861 --- /dev/null +++ b/src/arch/dalvik/context.c @@ -0,0 +1,229 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * context.c - contexte lié à l'exécution d'un processeur + * + * Copyright (C) 2011 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  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 "context.h" + + +#include <malloc.h> +#include <string.h> + + +#include "../context-int.h" + + + +/* Mémorisation d'un saut dans le code */ +typedef struct _skipped_dalvik_area skipped_dalvik_area; + + +/* ------------------------ MANIPULATION GLOBALE DU CONTEXTE ------------------------ */ + + +/* Définition d'un contexte pour processeur Dalkvik (instance) */ +struct _GDalvikContext +{ +    GProcContext parent;                    /* A laisser en premier        */ + +    skipped_dalvik_area *skip;              /* Liste de Zones à écarter    */ +    size_t count;                           /* Taille de cette liste       */ + +}; + + +/* Définition d'un contexte pour processeur Dalkvik (classe) */ +struct _GDalvikContextClass +{ +    GProcContextClass parent;               /* A laisser en premier        */ + +}; + + +/* Initialise la classe des contextes de processeur Dalkvik. */ +static void g_dalvik_context_class_init(GDalvikContextClass *); + +/* Initialise une instance de contexte de processeur Dalkvik. */ +static void g_dalvik_context_init(GDalvikContext *); + + + +/* ------------------------- MEMORISATION DES SAUTS DE CODE ------------------------- */ + + +/* Mémorisation d'un saut dans le code */ +struct _skipped_dalvik_area +{ +    vmpa_t start;                           /* Début de la zone concernée  */ +    vmpa_t end;                             /* Fin de la zone concernée    */ + +}; + + + +/* ---------------------------------------------------------------------------------- */ +/*                          MANIPULATION GLOBALE DU CONTEXTE                          */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type définit par la GLib pour le contexte de processeur Dalkvik. */ +G_DEFINE_TYPE(GDalvikContext, g_dalvik_context, G_TYPE_PROC_CONTEXT); + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des contextes de processeur Dalkvik.    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_dalvik_context_class_init(GDalvikContextClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : ctx = instance à initialiser.                                * +*                                                                             * +*  Description : Initialise une instance de contexte de processeur Dalkvik.   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_dalvik_context_init(GDalvikContext *ctx) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : -                                                            * +*                                                                             * +*  Description : Crée un contexte pour l'exécution du processeur Dalvik.      * +*                                                                             * +*  Retour      : Contexte mis en place.                                       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GDalvikContext *g_dalvik_context_new(void) +{ +    GDalvikContext *result;                 /* Structure à retourner       */ + +    result = g_object_new(G_TYPE_DALVIK_CONTEXT, NULL); + +    return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                           MEMORISATION DES SAUTS DE CODE                           */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : ctx   = instance à mettre à jour.                            * +*                start = début de la zone à écarter du traitement.            * +*                end   = fin de la zone à écarter du traitement.              * +*                                                                             * +*  Description : Mémorise une nouvelle zone de code comme étant des données.  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_dalvik_context_skip_new_area(GDalvikContext *ctx, vmpa_t start, vmpa_t end) +{ +    ctx->skip = (skipped_dalvik_area *)realloc(ctx->skip, +                                               ++ctx->count * sizeof(skipped_dalvik_area)); + +    ctx->skip[ctx->count - 1].start = start; +    ctx->skip[ctx->count - 1].end = end; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : ctx  = instance à consulter.                                 * +*                addr = adresse à mainupuler.                                 * +*                                                                             * +*  Description : Indique si l'adresse est considérée comme zone de données.   * +*                                                                             * +*  Retour      : true si l'adresse est considérée comme zone de données.      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_dalvik_context_have_to_skip(GDalvikContext *ctx, vmpa_t addr) +{ +    bool result;                            /* verdict à retourner         */ +    size_t i;                               /* Boucle de parcours          */ + +    result = false; + +    for (i = 0; i < ctx->count && !result; i++) +        if (ctx->skip[i].start <= addr && addr < ctx->skip[i].end) +        { +            result = true; +            ctx->skip[i].start += sizeof(uint16_t); + +            /* BUG_ON(ctx->skip[i].start > ctx->skip[i].end) */ + +            if (ctx->skip[i].start >= ctx->skip[i].end) +            { +                if (i <= (ctx->count - 1)) +                    memmove(&ctx->skip[i], &ctx->skip[i + 1], ctx->count - i - 1); + +                if (--ctx->count == 0) +                    ctx->skip = NULL; +                else +                    ctx->skip = (skipped_dalvik_area *)realloc(ctx->skip, +                                                               ++ctx->count * sizeof(skipped_dalvik_area)); + +            } + +            break; + +        } + +    return result; + +} diff --git a/src/arch/dalvik/context.h b/src/arch/dalvik/context.h new file mode 100644 index 0000000..459cc22 --- /dev/null +++ b/src/arch/dalvik/context.h @@ -0,0 +1,73 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * context.h - prototypes pour le contexte lié à l'exécution d'un processeur + * + * Copyright (C) 2011 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  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 _ARCH_DALVIK_CONTEXT_H +#define _ARCH_DALVIK_CONTEXT_H + + +#include <glib-object.h> +#include <stdbool.h> + + +#include "../archbase.h" + + + +/* ------------------------ MANIPULATION GLOBALE DU CONTEXTE ------------------------ */ + + +#define G_TYPE_DALVIK_CONTEXT              g_dalvik_context_get_type() +#define G_DALVIK_CONTEXT(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dalvik_context_get_type(), GDalvikContext)) +#define G_IS_DALVIK_CONTEXT(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dalvik_context_get_type())) +#define G_DALVIK_CONTEXT_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DALVIK_CONTEXT, GGDalvikContextClass)) +#define G_IS_DALVIK_CONTEXT_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DALVIK_CONTEXT)) +#define G_DALVIK_CONTEXT_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DALVIK_CONTEXT, GGDalvikContextClass)) + + +/* Définition d'un contexte pour processeur Dalkvik (instance) */ +typedef struct _GDalvikContext GDalvikContext; + +/* Définition d'un contexte pour processeur Dalkvik (classe) */ +typedef struct _GDalvikContextClass GDalvikContextClass; + + +/* Indique le type définit par la GLib pour le contexte de processeur Dalkvik. */ +GType g_dalvik_context_get_type(void); + +/* Crée un contexte pour l'exécution du processeur Dalvik. */ +GDalvikContext *g_dalvik_context_new(void); + + + +/* ------------------------- MEMORISATION DES SAUTS DE CODE ------------------------- */ + + +/* Mémorise une nouvelle zone de code comme étant des données. */ +void g_dalvik_context_skip_new_area(GDalvikContext *, vmpa_t, vmpa_t); + +/* Indique si l'adresse est considérée comme zone de données. */ +bool g_dalvik_context_have_to_skip(GDalvikContext *, vmpa_t); + + + +#endif  /* _ARCH_DALVIK_CONTEXT_H */ diff --git a/src/arch/dalvik/processor.c b/src/arch/dalvik/processor.c index 4fd8a2f..2f56f87 100644 --- a/src/arch/dalvik/processor.c +++ b/src/arch/dalvik/processor.c @@ -24,8 +24,10 @@  #include "processor.h" +#include "context.h"  #include "instruction.h"  #include "opcodes.h" +#include "specins.h"  #include "../processor-int.h" @@ -52,8 +54,11 @@ static void g_dalvik_processor_class_init(GDalvikProcessorClass *);  /* Initialise une instance de processeur de VM Dalvik. */  static void g_dalvik_processor_init(GDalvikProcessor *); +/* Fournit un contexte pour l'exécution du processeur Dalvik. */ +static GDalvikContext *g_dalvik_processor_get_context(const GDalvikProcessor *); +  /* Décode une instruction dans un flux de données. */ -static GArchInstruction *g_dalvik_processor_decode_instruction(const GDalvikProcessor *, const bin_t *, off_t *, off_t, vmpa_t); +static GArchInstruction *g_dalvik_processor_decode_instruction(const GDalvikProcessor *, GDalvikContext *, const bin_t *, off_t *, off_t, vmpa_t);  /* Indique le type défini par la GLib pour le processeur DALVIK. */ @@ -101,6 +106,7 @@ static void g_dalvik_processor_init(GDalvikProcessor *proc)      parent->memsize = MDS_32_BITS;      parent->inssize = MDS_16_BITS; +    parent->get_ctx = (get_processor_context_fc)g_dalvik_processor_get_context;      parent->decode = (decode_instruction_fc)g_dalvik_processor_decode_instruction;  } @@ -131,7 +137,27 @@ GArchProcessor *g_dalvik_processor_new(void)  /******************************************************************************  *                                                                             * +*  Paramètres  : proc = architecture, spectatrice ici.                        * +*                                                                             * +*  Description : Fournit un contexte pour l'exécution du processeur Dalvik.   * +*                                                                             * +*  Retour      : Contexte mis en place.                                       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GDalvikContext *g_dalvik_processor_get_context(const GDalvikProcessor *proc) +{ +    return g_dalvik_context_new(); + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : proc = architecture visée par la procédure.                  * +*                ctx  = contexte lié à l'exécution du processeur.             *  *                data = flux de données à analyser.                           *  *                pos  = position courante dans ce flux. [OUT]                 *  *                len  = taille totale des données à analyser.                 * @@ -145,7 +171,7 @@ GArchProcessor *g_dalvik_processor_new(void)  *                                                                             *  ******************************************************************************/ -static GArchInstruction *g_dalvik_processor_decode_instruction(const GDalvikProcessor *proc, const bin_t *data, off_t *pos, off_t len, vmpa_t addr) +static GArchInstruction *g_dalvik_processor_decode_instruction(const GDalvikProcessor *proc, GDalvikContext *ctx, const bin_t *data, off_t *pos, off_t len, vmpa_t addr)  {      GArchInstruction *result;               /* Instruction à renvoyer      */      DalvikOpcodes id;                       /* Identifiant d'instruction   */ @@ -315,6 +341,16 @@ static GArchInstruction *g_dalvik_processor_decode_instruction(const GDalvikProc      }; +    /* Continuité d'une zone spéciale... */ +    if (g_dalvik_context_have_to_skip(ctx, addr)) +        return SKIPPED_INSTR; + +    /* Début d'une nouvelle zone spéciale... */ +    if (g_dalvik_guess_special_instruction(ctx, data, *pos, len, addr)) +        return SKIPPED_INSTR; + +    /* Ou instruction classique */ +      id = dalvik_guess_next_instruction(data, *pos, len);      if (id != DOP_COUNT) (*pos)++; diff --git a/src/arch/dalvik/specins.c b/src/arch/dalvik/specins.c new file mode 100644 index 0000000..b6a7c4e --- /dev/null +++ b/src/arch/dalvik/specins.c @@ -0,0 +1,115 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * specins.c - gestion des instructions spéciales de la VM Dalvik + * + * Copyright (C) 2011 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  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 "specins.h" + + +#include "../../common/endianness.h" + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : ctx  = contexte lié à l'exécution du processeur.             * +*                data = flux de données à analyser.                           * +*                pos  = position courante dans ce flux.                       * +*                len  = taille totale des données à analyser.                 * +*                addr = adresse virtuelle de l'instruction.                   * +*                                                                             * +*  Description : Détermine si du code doit être écarté du traitement.         * +*                                                                             * +*  Retour      : true si une nouvelle zone de données est à écarter.          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_dalvik_guess_special_instruction(GDalvikContext *ctx, const bin_t *data, off_t pos, off_t len, vmpa_t addr) +{ +    bool result;                            /* Bilan à retourner           */ +    uint16_t ident;                         /* Valeur lue dans le code     */ +    vmpa_t start;                           /* Début d'une zone de données */ +    vmpa_t end;                             /* Fin d'une zone de données   */ +    uint16_t switch_size;                   /* Taille du switch considéré  */ +    uint16_t array_width;                   /* Taille des éléments         */ +    uint32_t array_size;                    /* Taille du tableau           */ + +    /* Vérification astucieuse et rapide...*/ +    if (data[pos] != 0x00 /* DOP_NOP */) return false;  + +    if (!read_u16(&ident, data, &pos, len, SRE_LITTLE)) +        return false; + +    start = addr + sizeof(ident); +    end = start; + +    switch (ident) +    { +        case DID_PACKED_SWITCH: + +            if (!read_u16(&switch_size, data, &pos, len, SRE_LITTLE)) +                return false; + +            end += sizeof(switch_size) + (1 + switch_size) * sizeof(uint32_t); + +            g_dalvik_context_skip_new_area(ctx, start, end); +            result = true; + +            break; + +        case DID_SPARSE_SWITCH: + +            if (!read_u16(&switch_size, data, &pos, len, SRE_LITTLE)) +                return false; + +            end += sizeof(switch_size) + (2 * switch_size) * sizeof(uint32_t); + +            g_dalvik_context_skip_new_area(ctx, start, end); +            result = true; + +            break; + +        case DID_FILL_ARRAY_DATA: + +            if (!read_u16(&array_width, data, &pos, len, SRE_LITTLE)) +                return false; +            if (!read_u32(&array_size, data, &pos, len, SRE_LITTLE)) +                return false; + +            end += sizeof(array_width) + sizeof(array_size) +                + array_width * array_size; + +            g_dalvik_context_skip_new_area(ctx, start, end); +            result = true; + +            break; + +        default: +            result = false; +            break; + +    } + +    return result; + +} diff --git a/src/arch/dalvik/specins.h b/src/arch/dalvik/specins.h new file mode 100644 index 0000000..51cf6e9 --- /dev/null +++ b/src/arch/dalvik/specins.h @@ -0,0 +1,51 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * specins.h - prototypes pour la gestion des instructions spéciales de la VM Dalvik + * + * Copyright (C) 2011 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  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 _ARCH_DALVIK_SPECINS_H +#define _ARCH_DALVIK_SPECINS_H + + +#include <stdbool.h> + + +#include "../archbase.h" +#include "context.h" + + + +/* Speinss spéciales */ +typedef enum _DalvikIdents +{ +    DID_PACKED_SWITCH   = 0x0100,           /* Switch aux clefs compactes  */ +    DID_SPARSE_SWITCH   = 0x0200,           /* Switch aux clefs éclatées   */ +    DID_FILL_ARRAY_DATA = 0x0300            /* Contenu de tableau          */ + +} DalvikIdents; + + +/*  Détermine si du code doit être écarté du traitement. */ +bool g_dalvik_guess_special_instruction(GDalvikContext *, const bin_t *, off_t, off_t, vmpa_t); + + + +#endif  /* _ARCH_DALVIK_SPECINS_H */ diff --git a/src/arch/processor-int.h b/src/arch/processor-int.h index ccaaa57..9d067b1 100644 --- a/src/arch/processor-int.h +++ b/src/arch/processor-int.h @@ -46,10 +46,11 @@ - +/* Fournit un contexte propre au processeur d'une architecture. */ +typedef GProcContext * (* get_processor_context_fc) (const GArchProcessor *);  /* Décode une instruction dans un flux de données. */ -typedef GArchInstruction * (* decode_instruction_fc) (const GArchProcessor *, const bin_t *, off_t *, off_t, vmpa_t); +typedef GArchInstruction * (* decode_instruction_fc) (const GArchProcessor *, GProcContext *, const bin_t *, off_t *, off_t, vmpa_t);  /* Définition générique d'un processeur d'architecture (instance) */ @@ -61,6 +62,7 @@ struct _GArchProcessor      MemoryDataSize memsize;                 /* Taille de l'espace mémoire  */      MemoryDataSize inssize;                 /* Taille min. d'encodage      */ +    get_processor_context_fc get_ctx;       /* Obtention d'un contexte     */      decode_instruction_fc decode;           /* Traduction en instructions  */  }; @@ -81,6 +83,8 @@ struct _GArchProcessorClass +#define SKIPPED_INSTR ((void *)-1) + diff --git a/src/arch/processor.c b/src/arch/processor.c index 2b1f060..0e4fc3f 100644 --- a/src/arch/processor.c +++ b/src/arch/processor.c @@ -115,6 +115,33 @@ static void g_arch_processor_init(GArchProcessor *proc)  /******************************************************************************  *                                                                             * +*  Paramètres  : proc   = architecture visée par la procédure.                * +*                                                                             * +*  Description : Fournit un contexte propre au processeur d'une architecture. * +*                                                                             * +*  Retour      : Nouveau contexte mise à disposition.                         * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GProcContext *g_arch_processor_get_context(const GArchProcessor *proc) +{ +    GProcContext *result;                   /* Contexte à retourner        */ + +    if (proc->get_ctx != NULL) +        result = proc->get_ctx(proc); + +    else +        result = NULL; + +    return result; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : proc = processeur d'architecture à consulter.                *  *                                                                             *  *  Description : Fournit le boustime du processeur d'une architecture.        * @@ -173,6 +200,7 @@ MemoryDataSize g_arch_processor_get_instruction_size(const GArchProcessor *proc)  /******************************************************************************  *                                                                             *  *  Paramètres  : proc   = architecture visée par la procédure.                * +*                ctx    = contexte lié à l'exécution du processeur.           *  *                data   = flux de données à analyser.                         *  *                pos    = position courante dans ce flux. [OUT]               *  *                len    = taille totale des données à analyser.               * @@ -187,20 +215,26 @@ MemoryDataSize g_arch_processor_get_instruction_size(const GArchProcessor *proc)  *                                                                             *  ******************************************************************************/ -GArchInstruction *g_arch_processor_decode_instruction(const GArchProcessor *proc, const bin_t *data, off_t *pos, off_t len, off_t base, vmpa_t addr) +GArchInstruction *g_arch_processor_decode_instruction(const GArchProcessor *proc, GProcContext *ctx, const bin_t *data, off_t *pos, off_t len, off_t base, vmpa_t addr)  {      GArchInstruction *result;               /* Instruction à renvoyer      */      off_t old_pos;                          /* Sauvegarde de la position   */ +    bool skipped;                           /* Données prise en compte ?   */      old_pos = *pos; -    result = proc->decode(proc, data, pos, len, addr); +    result = proc->decode(proc, ctx, data, pos, len, addr); -    if (result == NULL) +    if (result == NULL || result == SKIPPED_INSTR)      { +        skipped = (result == SKIPPED_INSTR); +          *pos = old_pos; -        printf("ERRerr while decoding opcode 0x%02hhx at 0x%08llx\n", data[*pos], addr);          result = g_db_instruction_new_from_data(data, pos, len, base, proc); + +        if (skipped) +            g_db_instruction_mark_as_skipped(G_DB_INSTRUCTION(result)); +      }      g_arch_instruction_set_location(result, base + old_pos, *pos - old_pos, addr); diff --git a/src/arch/processor.h b/src/arch/processor.h index a7c171d..fbdbb38 100644 --- a/src/arch/processor.h +++ b/src/arch/processor.h @@ -28,6 +28,7 @@  #include <glib-object.h> +#include "context.h"  #include "instruction.h"  #include "../common/endianness.h" @@ -49,6 +50,9 @@ typedef struct _GArchProcessorClass GArchProcessorClass;  /* Indique le type défini pour un processeur d'architecture. */  GType g_arch_processor_get_type(void); +/* Fournit un contexte propre au processeur d'une architecture. */ +GProcContext *g_arch_processor_get_context(const GArchProcessor *); +  /* Fournit le boustime du processeur d'une architecture. */  SourceEndian g_arch_processor_get_endianness(const GArchProcessor *); @@ -59,7 +63,7 @@ MemoryDataSize g_arch_processor_get_memory_size(const GArchProcessor *);  MemoryDataSize g_arch_processor_get_instruction_size(const GArchProcessor *);  /* Décode une instruction dans un flux de données. */ -GArchInstruction *g_arch_processor_decode_instruction(const GArchProcessor *, const bin_t *, off_t *, off_t, off_t, vmpa_t); +GArchInstruction *g_arch_processor_decode_instruction(const GArchProcessor *, GProcContext *, const bin_t *, off_t *, off_t, off_t, vmpa_t);  | 
