summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/analysis/disass/fetch.c16
-rw-r--r--src/arch/Makefile.am2
-rw-r--r--src/arch/artificial.c46
-rw-r--r--src/arch/artificial.h14
-rw-r--r--src/arch/context-int.h49
-rw-r--r--src/arch/context.c77
-rw-r--r--src/arch/context.h52
-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
-rw-r--r--src/arch/processor-int.h8
-rw-r--r--src/arch/processor.c42
-rw-r--r--src/arch/processor.h6
-rw-r--r--src/format/elf/helper_x86.c2
17 files changed, 809 insertions, 15 deletions
diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c
index 5f93eba..2ac9f5c 100644
--- a/src/analysis/disass/fetch.c
+++ b/src/analysis/disass/fetch.c
@@ -62,6 +62,7 @@ GArchInstruction *disassemble_binary_parts(const GOpenidaBinary *binary, GBinPar
off_t len; /* Taille de cette même zone */
vmpa_t base; /* Adresse de la zone binaire */
off_t start; /* Conservation du pt de départ*/
+ GProcContext *context; /* Contexte pour le décodage */
vmpa_t addr; /* Adresse d'une instruction */
GArchInstruction *instr; /* Instruction décodée */
@@ -89,6 +90,8 @@ GArchInstruction *disassemble_binary_parts(const GOpenidaBinary *binary, GBinPar
if (len > bin_length) continue;
+ context = g_arch_processor_get_context(proc);
+
/* Décodage des instructions */
#ifdef DEBUG
@@ -103,13 +106,15 @@ GArchInstruction *disassemble_binary_parts(const GOpenidaBinary *binary, GBinPar
{
addr = base + pos;
- instr = g_arch_processor_decode_instruction(proc, &bin_data[start],
+ instr = g_arch_processor_decode_instruction(proc, context, &bin_data[start],
&pos, len, start, addr);
g_arch_instruction_add_to_list(&result, instr);
#ifdef DEBUG
- if (G_IS_DB_INSTRUCTION(instr)) db++;
- else valid++;
+ if (G_IS_DB_INSTRUCTION(instr) && !g_db_instruction_is_skipped(G_DB_INSTRUCTION(instr)))
+ db++;
+ else
+ valid++;
#endif
if (pos < len)
@@ -117,7 +122,12 @@ GArchInstruction *disassemble_binary_parts(const GOpenidaBinary *binary, GBinPar
}
+ if (context != NULL)
+ g_object_unref(context);
+
+#ifdef DEBUG
g_binary_part_set_checkup(parts[i], valid, db);
+#endif
done += len;
gtk_extended_status_bar_update_activity(statusbar, id, done * 1.0 / sum);
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);
diff --git a/src/format/elf/helper_x86.c b/src/format/elf/helper_x86.c
index 3b9084c..dd6d278 100644
--- a/src/format/elf/helper_x86.c
+++ b/src/format/elf/helper_x86.c
@@ -219,7 +219,7 @@ GArchInstruction **decode_elf_relocations(GElfFormat *format, const elf_shdr *pl
{
address = plt_address + pos;
- instr = g_arch_processor_decode_instruction(proc, &G_BIN_FORMAT(format)->content[plt_start],
+ instr = g_arch_processor_decode_instruction(proc, NULL /*FIXME*/, &G_BIN_FORMAT(format)->content[plt_start],
&pos, plt_size, 0/* FIXME*/, address);
result = (GArchInstruction **)realloc(result, ++(*count) * sizeof(GArchInstruction *));