diff options
Diffstat (limited to 'src/arch/dalvik')
-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 |
6 files changed, 508 insertions, 2 deletions
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 */ |