From f38beea1951f9c323af3d05a3c4d2cf35f407245 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 27 Jun 2010 23:27:38 +0000 Subject: Defined the minimal instruction size for a given architecture. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@171 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 34 +++++++ configure.ac | 1 + src/analysis/binary.c | 3 + src/arch/Makefile.am | 3 +- src/arch/arm/Makefile.am | 17 ++++ src/arch/arm/processor.c | 158 +++++++++++++++++++++++++++++ src/arch/arm/processor.h | 53 ++++++++++ src/arch/artificial.c | 5 +- src/arch/dalvik/processor.c | 1 + src/arch/immediate.c | 238 ++++++++++++++++++++++++++++++++++++++++---- src/arch/immediate.h | 6 ++ src/arch/processor-int.h | 1 + src/arch/processor.c | 25 +++++ src/arch/processor.h | 4 + src/format/elf/elf.c | 8 +- src/format/elf/elf_def.h | 1 + src/format/executable.h | 1 + 17 files changed, 533 insertions(+), 26 deletions(-) create mode 100644 src/arch/arm/Makefile.am create mode 100644 src/arch/arm/processor.c create mode 100644 src/arch/arm/processor.h diff --git a/ChangeLog b/ChangeLog index bff9366..395a95b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,37 @@ +10-06-28 Cyrille Bagard + + * 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 * 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 . + */ + + +#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 . + */ + + +#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 */ -- cgit v0.11.2-87-g4458