summaryrefslogtreecommitdiff
path: root/src/arch/dalvik
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/dalvik')
-rw-r--r--src/arch/dalvik/Makefile.am2
-rw-r--r--src/arch/dalvik/context.c229
-rw-r--r--src/arch/dalvik/context.h73
-rw-r--r--src/arch/dalvik/processor.c40
-rw-r--r--src/arch/dalvik/specins.c115
-rw-r--r--src/arch/dalvik/specins.h51
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 */