summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog34
-rw-r--r--configure.ac1
-rw-r--r--src/analysis/binary.c3
-rw-r--r--src/arch/Makefile.am3
-rw-r--r--src/arch/arm/Makefile.am17
-rw-r--r--src/arch/arm/processor.c158
-rw-r--r--src/arch/arm/processor.h53
-rw-r--r--src/arch/artificial.c5
-rw-r--r--src/arch/dalvik/processor.c1
-rw-r--r--src/arch/immediate.c238
-rw-r--r--src/arch/immediate.h6
-rw-r--r--src/arch/processor-int.h1
-rw-r--r--src/arch/processor.c25
-rw-r--r--src/arch/processor.h4
-rw-r--r--src/format/elf/elf.c8
-rw-r--r--src/format/elf/elf_def.h1
-rw-r--r--src/format/executable.h1
17 files changed, 533 insertions, 26 deletions
diff --git a/ChangeLog b/ChangeLog
index bff9366..395a95b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,37 @@
+10-06-28 Cyrille Bagard <nocbos@gmail.com>
+
+ * configure.ac:
+ Add the new Makefile from the 'src/arch/arm' directory to AC_CONFIG_FILES.
+
+ * src/analysis/binary.c:
+ Display a message for the ARM architecture.
+
+ * src/arch/arm/Makefile.am:
+ * src/arch/arm/processor.c:
+ * src/arch/arm/processor.h:
+ New entries: begin to support the ARM architecture.
+
+ * src/arch/artificial.c:
+ * src/arch/dalvik/processor.c:
+ Update code.
+
+ * src/arch/immediate.c:
+ * src/arch/immediate.h:
+ Pad values with 0 when printing if needed.
+
+ * src/arch/Makefile.am:
+ Add arm/libarcharm.la to libarch_la_LIBADD and arm to SUBDIRS.
+
+ * src/arch/processor.c:
+ * src/arch/processor.h:
+ * src/arch/processor-int.h:
+ Define the minimal instruction size for a given architecture.
+
+ * src/format/elf/elf.c:
+ * src/format/elf/elf_def.h:
+ * src/format/executable.h:
+ Recognize the ARM architecture when needed.
+
10-06-27 Cyrille Bagard <nocbos@gmail.com>
* src/arch/dalvik/instruction.c:
diff --git a/configure.ac b/configure.ac
index 66c9e43..70c6c4e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -243,6 +243,7 @@ AC_CONFIG_FILES([Makefile
src/Makefile
src/analysis/Makefile
src/arch/Makefile
+ src/arch/arm/Makefile
src/arch/dalvik/Makefile
src/arch/jvm/Makefile
src/arch/mips/Makefile
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index d860efc..d8199c0 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -746,6 +746,9 @@ GOpenidaBinary *g_openida_binary_new_from_file(const char *filename)
/* FIXME : à déplacer dans arch/... */
switch (g_exe_format_get_target_machine(result->format))
{
+ case FTM_ARM:
+ log_simple_message(LMT_INFO, _("Detected architecture: ARM"));
+ break;
case FTM_DALVIK:
log_simple_message(LMT_INFO, _("Detected architecture: Dalvik Virtual Machine"));
break;
diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am
index a968d6f..8f1c1ff 100644
--- a/src/arch/Makefile.am
+++ b/src/arch/Makefile.am
@@ -13,6 +13,7 @@ libarch_la_SOURCES = \
processor.h processor.c
libarch_la_LIBADD = \
+ arm/libarcharm.la \
dalvik/libarchdalvik.la \
jvm/libarchjvm.la \
mips/libarchmips.la \
@@ -28,4 +29,4 @@ AM_CPPFLAGS =
AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
-SUBDIRS = dalvik jvm mips x86
+SUBDIRS = arm dalvik jvm mips x86
diff --git a/src/arch/arm/Makefile.am b/src/arch/arm/Makefile.am
new file mode 100644
index 0000000..f97d24a
--- /dev/null
+++ b/src/arch/arm/Makefile.am
@@ -0,0 +1,17 @@
+
+noinst_LTLIBRARIES = libarcharm.la
+
+libarcharm_la_SOURCES = \
+ processor.h processor.c
+
+libarcharm_la_CFLAGS = $(AM_CFLAGS)
+
+
+INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)
+
+AM_CPPFLAGS =
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
+
+
+SUBDIRS =
diff --git a/src/arch/arm/processor.c b/src/arch/arm/processor.c
new file mode 100644
index 0000000..79a44fe
--- /dev/null
+++ b/src/arch/arm/processor.c
@@ -0,0 +1,158 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * processor.c - manipulation du processeur ARM
+ *
+ * Copyright (C) 2010 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 "processor.h"
+
+
+//#include "instruction.h"
+//#include "opcodes.h"
+#include "../processor-int.h"
+
+
+
+/* Définition du processeur ARM (instance) */
+struct _GArmProcessor
+{
+ GArchProcessor parent; /* Instance parente */
+
+};
+
+
+/* Définition du processeur ARM (classe) */
+struct _GArmProcessorClass
+{
+ GArchProcessorClass parent; /* Classe parente */
+
+};
+
+
+/* Initialise la classe des processeurs ARM. */
+static void g_arm_processor_class_init(GArmProcessorClass *);
+
+/* Initialise une instance de processeur ARM. */
+static void g_arm_processor_init(GArmProcessor *);
+
+/* Décode une instruction dans un flux de données. */
+static GArchInstruction *g_arm_processor_decode_instruction(const GArmProcessor *, const bin_t *, off_t *, off_t, vmpa_t);
+
+
+/* Indique le type défini par la GLib pour le processeur ARM. */
+G_DEFINE_TYPE(GArmProcessor, g_arm_processor, G_TYPE_ARCH_PROCESSOR);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des processeurs ARM. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_arm_processor_class_init(GArmProcessorClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = instance à initialiser. *
+* *
+* Description : Initialise une instance de processeur ARM. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_arm_processor_init(GArmProcessor *proc)
+{
+ GArchProcessor *parent; /* Instance parente */
+
+ parent = G_ARCH_PROCESSOR(proc);
+
+ parent->endianness = SRE_LITTLE;
+ parent->memsize = MDS_32_BITS;
+ parent->inssize = MDS_32_BITS;
+
+ parent->decode = (decode_instruction_fc)g_arm_processor_decode_instruction;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Crée le support de l'architecture ARM. *
+* *
+* Retour : Architecture mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchProcessor *g_arm_processor_new(void)
+{
+ GArchProcessor *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_ARM_PROCESSOR, NULL);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = architecture visée par la procédure. *
+* data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* *
+* Description : Décode une instruction dans un flux de données. *
+* *
+* Retour : Instruction mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GArchInstruction *g_arm_processor_decode_instruction(const GArmProcessor *proc, const bin_t *data, off_t *pos, off_t len, vmpa_t addr)
+{
+ GArchInstruction *result; /* Instruction à renvoyer */
+
+
+ result = NULL;
+
+
+ return result;
+
+}
diff --git a/src/arch/arm/processor.h b/src/arch/arm/processor.h
new file mode 100644
index 0000000..1386d26
--- /dev/null
+++ b/src/arch/arm/processor.h
@@ -0,0 +1,53 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * processor.h - prototypes pour la manipulation du processeur ARM
+ *
+ * Copyright (C) 2010 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_ARM_PROCESSOR_H
+#define _ARCH_ARM_PROCESSOR_H
+
+
+#include "../processor.h"
+
+
+
+#define G_TYPE_ARM_PROCESSOR g_arm_processor_get_type()
+#define G_ARM_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_arm_processor_get_type(), GArmProcessor))
+#define G_IS_ARM_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_arm_processor_get_type()))
+#define G_ARM_PROCESSOR_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_arm_processor_get_type(), GArmProcessorIface))
+
+
+/* Définition du processeur ARM (instance) */
+typedef struct _GArmProcessor GArmProcessor;
+
+/* Définition du processeur ARM (classe) */
+typedef struct _GArmProcessorClass GArmProcessorClass;
+
+
+/* Indique le type défini par la GLib pour le processeur ARM. */
+GType g_arm_processor_get_type(void);
+
+/* Crée le support de l'architecture ARM. */
+GArchProcessor *g_arm_processor_new(void);
+
+
+
+#endif /* _ARCH_ARM_PROCESSOR_H */
diff --git a/src/arch/artificial.c b/src/arch/artificial.c
index 65d917e..e588a4e 100644
--- a/src/arch/artificial.c
+++ b/src/arch/artificial.c
@@ -139,10 +139,13 @@ GArchInstruction *g_db_instruction_new_from_data(const bin_t *data, off_t *pos,
result = g_object_new(G_TYPE_DB_INSTRUCTION, NULL);
- operand = g_imm_operand_new_from_data(MDS_8_BITS, data, pos, len,
+ operand = g_imm_operand_new_from_data(g_arch_processor_get_instruction_size(proc),
+ data, pos, len,
g_arch_processor_get_endianness(proc));
if (operand == NULL) goto gdinfd_error;
+ g_imm_operand_pad(G_IMM_OPERAND(operand), true);
+
g_arch_instruction_attach_extra_operand(result, operand);
return result;
diff --git a/src/arch/dalvik/processor.c b/src/arch/dalvik/processor.c
index c6861c9..379fc98 100644
--- a/src/arch/dalvik/processor.c
+++ b/src/arch/dalvik/processor.c
@@ -99,6 +99,7 @@ static void g_dalvik_processor_init(GDalvikProcessor *proc)
parent->endianness = SRE_LITTLE;
parent->memsize = MDS_32_BITS;
+ parent->inssize = MDS_16_BITS;
parent->decode = (decode_instruction_fc)g_dalvik_processor_decode_instruction;
diff --git a/src/arch/immediate.c b/src/arch/immediate.c
index 1a32748..3018b6b 100644
--- a/src/arch/immediate.c
+++ b/src/arch/immediate.c
@@ -67,6 +67,8 @@ struct _GImmOperand
} signed_imm;
+ bool zpad; /* Ajoute des 0 à l'impression */
+
};
@@ -139,6 +141,8 @@ static void g_imm_operand_init(GImmOperand *operand)
parent->add_text = (add_text_fc)g_imm_operand_add_text;
parent->export_buffer = (export_buffer_fc)g_imm_operand_to_buffer;
+ operand->zpad = false;
+
}
@@ -275,6 +279,7 @@ GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, ...)
/* Pour GCC... */
case MDS_UNDEFINED:
break;
+ case MDS_4_BITS_UNSIGNED:
case MDS_8_BITS_UNSIGNED:
uval8 = (uint8_t)va_arg(ap, unsigned int);
result->unsigned_imm.val8 = uval8;
@@ -291,6 +296,7 @@ GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, ...)
uval64 = (uint64_t)va_arg(ap, unsigned int);
result->unsigned_imm.val64 = uval64;
break;
+ case MDS_4_BITS_SIGNED:
case MDS_8_BITS_SIGNED:
sval8 = (int8_t)va_arg(ap, int);
result->signed_imm.val8 = sval8;
@@ -318,6 +324,44 @@ GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, ...)
/******************************************************************************
* *
+* Paramètres : state = true si des zéro sont à ajouter, false sinon. *
+* *
+* Description : Précise si des zéro doivent compléter l'affichage ou non. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_imm_operand_pad(GImmOperand *operand, bool state)
+{
+ operand->zpad = state;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = structure dont le contenu est à définir. *
+* *
+* Description : Indique le signe d'une valeur immédiate. *
+* *
+* Retour : true si des zéro sont ajoutés à l'affichage, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_imm_operand_does_padding(const GImmOperand *operand)
+{
+ return operand->zpad;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : operand = structure dont le contenu est à définir. *
* *
* Description : Indique le signe d'une valeur immédiate. *
@@ -385,42 +429,111 @@ static size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax synt
case MDS_UNDEFINED:
result = snprintf(value, VMPA_MAX_SIZE, "0x???");
break;
+
case MDS_4_BITS_UNSIGNED:
- case MDS_8_BITS_UNSIGNED:
result = snprintf(value, VMPA_MAX_SIZE, "0x%hhx", operand->unsigned_imm.val8);
+
+ case MDS_8_BITS_UNSIGNED:
+ if (operand->zpad)
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%02hhx", operand->unsigned_imm.val8);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%hhx", operand->unsigned_imm.val8);
break;
+
case MDS_16_BITS_UNSIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, "0x%hx", operand->unsigned_imm.val16);
+ if (operand->zpad)
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%04hx", operand->unsigned_imm.val16);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%hx", operand->unsigned_imm.val16);
break;
+
case MDS_32_BITS_UNSIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, "0x%x", operand->unsigned_imm.val32);
+ if (operand->zpad)
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%08x", operand->unsigned_imm.val32);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%x", operand->unsigned_imm.val32);
break;
+
case MDS_64_BITS_UNSIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, "0x%llx", operand->unsigned_imm.val64);
+ if (operand->zpad)
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%016llx", operand->unsigned_imm.val64);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%llx", operand->unsigned_imm.val64);
break;
- case MDS_8_BITS_SIGNED:
+
+ case MDS_4_BITS_SIGNED:
if (g_imm_operand_is_negative(operand))
result = snprintf(value, VMPA_MAX_SIZE, "0x%hhx", ~operand->signed_imm.val8 + 1);
else
result = snprintf(value, VMPA_MAX_SIZE, "0x%hhx", operand->signed_imm.val8);
break;
+
+ case MDS_8_BITS_SIGNED:
+ if (operand->zpad)
+ {
+ if (g_imm_operand_is_negative(operand))
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%02hhx", ~operand->signed_imm.val8 + 1);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%02hhx", operand->signed_imm.val8);
+ }
+ else
+ {
+ if (g_imm_operand_is_negative(operand))
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%hhx", ~operand->signed_imm.val8 + 1);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%hhx", operand->signed_imm.val8);
+ }
+ break;
+
case MDS_16_BITS_SIGNED:
- if (g_imm_operand_is_negative(operand))
- result = snprintf(value, VMPA_MAX_SIZE, "0x%hx", ~operand->signed_imm.val16 + 1);
+ if (operand->zpad)
+ {
+ if (g_imm_operand_is_negative(operand))
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%04hx", ~operand->signed_imm.val16 + 1);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%04hx", operand->signed_imm.val16);
+ }
else
- result = snprintf(value, VMPA_MAX_SIZE, "0x%hx", operand->signed_imm.val16);
+ {
+ if (g_imm_operand_is_negative(operand))
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%hx", ~operand->signed_imm.val16 + 1);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%hx", operand->signed_imm.val16);
+ }
break;
+
case MDS_32_BITS_SIGNED:
- if (g_imm_operand_is_negative(operand))
- result = snprintf(value, VMPA_MAX_SIZE, "0x%x", ~operand->signed_imm.val32 + 1);
+ if (operand->zpad)
+ {
+ if (g_imm_operand_is_negative(operand))
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%08x", ~operand->signed_imm.val32 + 1);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%08x", operand->signed_imm.val32);
+ }
else
- result = snprintf(value, VMPA_MAX_SIZE, "0x%x", operand->signed_imm.val32);
+ {
+ if (g_imm_operand_is_negative(operand))
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%x", ~operand->signed_imm.val32 + 1);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%x", operand->signed_imm.val32);
+ }
break;
+
case MDS_64_BITS_SIGNED:
- if (g_imm_operand_is_negative(operand))
- result = snprintf(value, VMPA_MAX_SIZE, "0x%llx", ~operand->signed_imm.val64 + 1);
+ if (operand->zpad)
+ {
+ if (g_imm_operand_is_negative(operand))
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%016llx", ~operand->signed_imm.val64 + 1);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%016llx", operand->signed_imm.val64);
+ }
else
- result = snprintf(value, VMPA_MAX_SIZE, "0x%llx", operand->signed_imm.val64);
+ {
+ if (g_imm_operand_is_negative(operand))
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%llx", ~operand->signed_imm.val64 + 1);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "0x%llx", operand->signed_imm.val64);
+ }
break;
}
break;
@@ -431,30 +544,111 @@ static size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax synt
case MDS_UNDEFINED:
result = snprintf(value, VMPA_MAX_SIZE, "$0x???");
break;
+
case MDS_4_BITS_UNSIGNED:
- case MDS_8_BITS_UNSIGNED:
result = snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", operand->unsigned_imm.val8);
+
+ case MDS_8_BITS_UNSIGNED:
+ if (operand->zpad)
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%02hhx", operand->unsigned_imm.val8);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", operand->unsigned_imm.val8);
break;
+
case MDS_16_BITS_UNSIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%hx", operand->unsigned_imm.val16);
+ if (operand->zpad)
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%04hx", operand->unsigned_imm.val16);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%hx", operand->unsigned_imm.val16);
break;
+
case MDS_32_BITS_UNSIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%x", operand->unsigned_imm.val32);
+ if (operand->zpad)
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%08x", operand->unsigned_imm.val32);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%x", operand->unsigned_imm.val32);
break;
+
case MDS_64_BITS_UNSIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%llx", operand->unsigned_imm.val64);
+ if (operand->zpad)
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%016llx", operand->unsigned_imm.val64);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%llx", operand->unsigned_imm.val64);
+ break;
+
+ case MDS_4_BITS_SIGNED:
+ if (g_imm_operand_is_negative(operand))
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", ~operand->signed_imm.val8 + 1);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", operand->signed_imm.val8);
break;
+
case MDS_8_BITS_SIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", ~operand->signed_imm.val8 + 1);
+ if (operand->zpad)
+ {
+ if (g_imm_operand_is_negative(operand))
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%02hhx", ~operand->signed_imm.val8 + 1);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%02hhx", operand->signed_imm.val8);
+ }
+ else
+ {
+ if (g_imm_operand_is_negative(operand))
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", ~operand->signed_imm.val8 + 1);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", operand->signed_imm.val8);
+ }
break;
+
case MDS_16_BITS_SIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%hx", ~operand->signed_imm.val16 + 1);
+ if (operand->zpad)
+ {
+ if (g_imm_operand_is_negative(operand))
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%04hx", ~operand->signed_imm.val16 + 1);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%04hx", operand->signed_imm.val16);
+ }
+ else
+ {
+ if (g_imm_operand_is_negative(operand))
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%hx", ~operand->signed_imm.val16 + 1);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%hx", operand->signed_imm.val16);
+ }
break;
+
case MDS_32_BITS_SIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%x", ~operand->signed_imm.val32 + 1);
+ if (operand->zpad)
+ {
+ if (g_imm_operand_is_negative(operand))
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%08x", ~operand->signed_imm.val32 + 1);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%08x", operand->signed_imm.val32);
+ }
+ else
+ {
+ if (g_imm_operand_is_negative(operand))
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%x", ~operand->signed_imm.val32 + 1);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%x", operand->signed_imm.val32);
+ }
break;
+
case MDS_64_BITS_SIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, "$0x%llx", ~operand->signed_imm.val64 + 1);
+ if (operand->zpad)
+ {
+ if (g_imm_operand_is_negative(operand))
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%016llx", ~operand->signed_imm.val64 + 1);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%016llx", operand->signed_imm.val64);
+ }
+ else
+ {
+ if (g_imm_operand_is_negative(operand))
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%llx", ~operand->signed_imm.val64 + 1);
+ else
+ result = snprintf(value, VMPA_MAX_SIZE, "$0x%llx", operand->signed_imm.val64);
+ }
break;
}
break;
diff --git a/src/arch/immediate.h b/src/arch/immediate.h
index 1e66d54..1d0c770 100644
--- a/src/arch/immediate.h
+++ b/src/arch/immediate.h
@@ -59,6 +59,12 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize, const bin_t *, off_t
/* Crée un opérande réprésentant une valeur numérique. */
GArchOperand *g_imm_operand_new_from_value(MemoryDataSize, ...);
+/* Précise si des zéro doivent compléter l'affichage ou non. */
+void g_imm_operand_pad(GImmOperand *, bool);
+
+/* Indique le signe d'une valeur immédiate. */
+bool g_imm_operand_does_padding(const GImmOperand *);
+
/* Indique le signe d'une valeur immédiate. */
bool g_imm_operand_is_negative(const GImmOperand *);
diff --git a/src/arch/processor-int.h b/src/arch/processor-int.h
index fc9097e..ccaaa57 100644
--- a/src/arch/processor-int.h
+++ b/src/arch/processor-int.h
@@ -59,6 +59,7 @@ struct _GArchProcessor
SourceEndian endianness; /* Boutisme de l'architecture */
MemoryDataSize memsize; /* Taille de l'espace mémoire */
+ MemoryDataSize inssize; /* Taille min. d'encodage */
decode_instruction_fc decode; /* Traduction en instructions */
diff --git a/src/arch/processor.c b/src/arch/processor.c
index 9bea205..2b1f060 100644
--- a/src/arch/processor.c
+++ b/src/arch/processor.c
@@ -42,6 +42,7 @@
#include "artificial.h"
+#include "arm/processor.h"
#include "dalvik/processor.h"
#include "jvm/processor.h"
#include "mips/processor.h"
@@ -152,6 +153,25 @@ MemoryDataSize g_arch_processor_get_memory_size(const GArchProcessor *proc)
/******************************************************************************
* *
+* Paramètres : proc = processeur d'architecture à consulter. *
+* *
+* Description : Fournit la taille min. des instructions d'une architecture. *
+* *
+* Retour : Taille d'encodage des instructions *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+MemoryDataSize g_arch_processor_get_instruction_size(const GArchProcessor *proc)
+{
+ return proc->inssize;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : proc = architecture visée par la procédure. *
* data = flux de données à analyser. *
* pos = position courante dans ce flux. [OUT] *
@@ -210,6 +230,7 @@ GArchInstruction *g_arch_processor_decode_instruction(const GArchProcessor *proc
bool init_all_processors(void)
{
+ _processors_list[APT_ARM] = g_arm_processor_new();
_processors_list[APT_DALVIK] = g_dalvik_processor_new();
_processors_list[APT_JVM] = g_jvm_processor_new();
_processors_list[APT_MIPS] = g_mips_processor_new();
@@ -257,6 +278,10 @@ GArchProcessor *get_arch_processor_from_format(const GExeFormat *format)
switch (g_exe_format_get_target_machine(format))
{
+ case FTM_ARM:
+ result = get_arch_processor_for_type(APT_ARM);
+ break;
+
case FTM_DALVIK:
result = get_arch_processor_for_type(APT_DALVIK);
break;
diff --git a/src/arch/processor.h b/src/arch/processor.h
index 063a3ba..a7c171d 100644
--- a/src/arch/processor.h
+++ b/src/arch/processor.h
@@ -55,6 +55,9 @@ SourceEndian g_arch_processor_get_endianness(const GArchProcessor *);
/* Fournit la taille de l'espace mémoire d'une architecture. */
MemoryDataSize g_arch_processor_get_memory_size(const GArchProcessor *);
+/* Fournit la taille min. des instructions d'une architecture. */
+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);
@@ -66,6 +69,7 @@ GArchInstruction *g_arch_processor_decode_instruction(const GArchProcessor *, co
/* Type de processeurs disponibles */
typedef enum _ArchProcessorType
{
+ APT_ARM, /* ARM vX */
APT_DALVIK, /* Dalvik Virtual Machine */
APT_JVM, /* Java Virtual Machine */
APT_MIPS, /* Mips 32 ou 64 bits */
diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c
index ccd00ae..3ed3dda 100644
--- a/src/format/elf/elf.c
+++ b/src/format/elf/elf.c
@@ -245,12 +245,16 @@ static FormatTargetMachine g_elf_format_get_target_machine(const GElfFormat *for
switch (ELF_HDR(format, format->header, e_machine))
{
+ case EM_386:
+ result = FTM_386;
+ break;
+
case EM_MIPS:
result = FTM_MIPS;
break;
- case EM_386:
- result = FTM_386;
+ case EM_ARM:
+ result = FTM_ARM;
break;
case EM_NONE:
diff --git a/src/format/elf/elf_def.h b/src/format/elf/elf_def.h
index f125106..916e81d 100644
--- a/src/format/elf/elf_def.h
+++ b/src/format/elf/elf_def.h
@@ -130,6 +130,7 @@ typedef union _elf_header
#define EM_386 3 /* Intel 80386 */
#define EM_MIPS 8 /* MIPS R3000 big-endian */
#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */
+#define EM_ARM 40 /* ARM */
diff --git a/src/format/executable.h b/src/format/executable.h
index c90ccfe..a122977 100644
--- a/src/format/executable.h
+++ b/src/format/executable.h
@@ -37,6 +37,7 @@ typedef enum _FormatTargetMachine
{
FTM_NONE, /* Aucune archi. (reconnue) */
+ FTM_ARM, /* ARM vX */
FTM_DALVIK, /* Dalvik Virtual Machine */
FTM_JVM, /* Java Virtual Machine */
FTM_MIPS, /* Mips 32 ou 64 bits */