diff options
Diffstat (limited to 'src/arch')
27 files changed, 3312 insertions, 73 deletions
diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am index ce37874..a968d6f 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 = \ + dalvik/libarchdalvik.la \ jvm/libarchjvm.la \ mips/libarchmips.la \ x86/libarchx86.la @@ -27,4 +28,4 @@ AM_CPPFLAGS = AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) -SUBDIRS = jvm mips x86 +SUBDIRS = dalvik jvm mips x86 diff --git a/src/arch/archbase.h b/src/arch/archbase.h index 330e194..61de861 100644 --- a/src/arch/archbase.h +++ b/src/arch/archbase.h @@ -45,11 +45,13 @@ typedef enum _MemoryDataSize { MDS_UNDEFINED, /* Taille non définie */ + MDS_4_BITS_UNSIGNED, /* Opérande sur 4 bits n.-s. */ MDS_8_BITS_UNSIGNED, /* Opérande sur 8 bits n.-s. */ MDS_16_BITS_UNSIGNED, /* Opérande sur 16 bits n.-s. */ MDS_32_BITS_UNSIGNED, /* Opérande sur 32 bits n.-s. */ MDS_64_BITS_UNSIGNED, /* Opérande sur 64 bits n.-s. */ + MDS_4_BITS_SIGNED, /* Opérande sur 4 bits signés */ MDS_8_BITS_SIGNED, /* Opérande sur 8 bits signés */ MDS_16_BITS_SIGNED, /* Opérande sur 16 bits signés */ MDS_32_BITS_SIGNED, /* Opérande sur 32 bits signés */ @@ -58,6 +60,7 @@ typedef enum _MemoryDataSize } MemoryDataSize; +#define MDS_4_BITS MDS_4_BITS_UNSIGNED #define MDS_8_BITS MDS_8_BITS_UNSIGNED #define MDS_16_BITS MDS_16_BITS_UNSIGNED #define MDS_32_BITS MDS_32_BITS_UNSIGNED diff --git a/src/arch/artificial.c b/src/arch/artificial.c index 16e95bc..65d917e 100644 --- a/src/arch/artificial.c +++ b/src/arch/artificial.c @@ -59,6 +59,9 @@ static const char *g_db_instruction_get_text(const GDbInstruction *, const GExeF /* Informe sur une éventuelle référence à une autre instruction. */ static InstructionLinkType g_db_instruction_get_link(const GDbInstruction *, vmpa_t *); +/* Indique si l'instruction correspond à un retour de fonction. */ +static bool g_db_instruction_is_return(const GDbInstruction *); + /* ---------------------------------------------------------------------------------- */ @@ -108,6 +111,7 @@ static void g_db_instruction_init(GDbInstruction *instr) parent->get_text = (get_instruction_text_fc)g_db_instruction_get_text; parent->get_link = (get_instruction_link_fc)g_db_instruction_get_link; + parent->is_return = (is_instruction_return_fc)g_db_instruction_is_return; } @@ -191,3 +195,22 @@ static InstructionLinkType g_db_instruction_get_link(const GDbInstruction *instr return ILT_NONE; } + + +/****************************************************************************** +* * +* Paramètres : instr = instruction à consulter. * +* * +* Description : Indique si l'instruction correspond à un retour de fonction. * +* * +* Retour : true si l'instruction est un 'return' quelconque ou false. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_db_instruction_is_return(const GDbInstruction *instr) +{ + return false; + +} diff --git a/src/arch/dalvik/Makefile.am b/src/arch/dalvik/Makefile.am new file mode 100644 index 0000000..855d287 --- /dev/null +++ b/src/arch/dalvik/Makefile.am @@ -0,0 +1,27 @@ + +noinst_LTLIBRARIES = libarchdalvik.la + +libarchdalvik_la_SOURCES = \ + instruction.h instruction.c \ + op_const.c \ + op_invoke.c \ + op_mul.c \ + op_nop.c \ + op_ret.c \ + op_sget.c \ + opcodes.h \ + operand.h operand.c \ + processor.h processor.c \ + register.h register.c + +libarchdalvik_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/dalvik/instruction.c b/src/arch/dalvik/instruction.c new file mode 100644 index 0000000..8bd4894 --- /dev/null +++ b/src/arch/dalvik/instruction.c @@ -0,0 +1,286 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * instruction.c - gestion des instructions de la VM Dalvik + * + * 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 "instruction.h" + + +#include "../instruction-int.h" + + + +/* Définition générique d'une instruction d'architecture Dalvik (instance) */ +struct _GDalvikInstruction +{ + GArchInstruction parent; /* A laisser en premier */ + + DalvikOpcodes type; /* Position dans la liste */ + +}; + +/* Définition générique d'une instruction d'architecture Dalvik (classe) */ +struct _GDalvikInstructionClass +{ + GArchInstructionClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des instructions pour Dalvik. */ +static void g_dalvik_instruction_class_init(GDalvikInstructionClass *); + +/* Initialise une instance d'opérande d'architecture Dalvik. */ +static void g_dalvik_instruction_init(GDalvikInstruction *); + + + +/* --------------------- AIDE A LA MISE EN PLACE D'INSTRUCTIONS --------------------- */ + + +/* Répertoire de toutes les instructions Dalvik */ +typedef struct _dalvik_instruction +{ + bin_t opcode; /* Opcode de l'instruction */ + + const char *keyword; /* Mot clef de la commande */ + +} dalvik_instruction; + + +static dalvik_instruction _instructions[DOP_COUNT] = { + + [DOP_NOP] = { 0x00, "nop" }, + + [DOP_CONST_4] = { 0x12, "const/4" }, + [DOP_CONST_16] = { 0x13, "const/16" }, + + + [DOP_CONST_HIGH16] = { 0x15, "const/high16" }, + + [DOP_CONST_STRING] = { 0x1a, "const-string" }, + + + [DOP_RETURN_VOID] = { 0x0e, "return-void" }, + [DOP_RETURN] = { 0x0f, "return" }, + + + [DOP_SGET] = { 0x60, "sget" }, + [DOP_SGET_WIDE] = { 0x61, "sget-wide" }, + [DOP_SGET_OBJECT] = { 0x62, "sget-object" }, + + + + [DOP_INVOKE_VIRTUAL] = { 0x6e, "invoke-virtual" }, + [DOP_INVOKE_SUPER] = { 0x6f, "invoke-static" }, + [DOP_INVOKE_DIRECT] = { 0x70, "invoke-direct" }, + [DOP_INVOKE_STATIC] = { 0x71, "invoke-static" }, + [DOP_INVOKE_INTERFACE] = { 0x72, "invoke-interface" }, + + + + [DOP_MUL_INT_2ADDR] = { 0xb2, "mul-int/2addr" } + + +}; + + +/* Traduit une instruction en version humainement lisible. */ +static const char *dalvik_get_instruction_text(const GDalvikInstruction *, const GExeFormat *, AsmSyntax); + +/* Informe sur une éventuelle référence à une autre instruction. */ +static InstructionLinkType dalvik_get_instruction_link(const GDalvikInstruction *, vmpa_t *); + +/* Indique si l'instruction correspond à un retour de fonction. */ +static bool dalvik_instruction_is_return(const GDalvikInstruction *); + + + +/* Indique le type défini pour une instruction d'architecture Dalvik. */ +G_DEFINE_TYPE(GDalvikInstruction, g_dalvik_instruction, G_TYPE_ARCH_INSTRUCTION); + + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des instructions pour Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_instruction_class_init(GDalvikInstructionClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instance à initialiser. * +* * +* Description : Initialise une instance d'instruction d'architecture Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_instruction_init(GDalvikInstruction *instr) +{ + GArchInstruction *parent; /* Instance parente */ + + parent = G_ARCH_INSTRUCTION(instr); + + parent->get_text = (get_instruction_text_fc)dalvik_get_instruction_text; + parent->get_link = (get_instruction_link_fc)dalvik_get_instruction_link; + parent->is_return = (is_instruction_return_fc)dalvik_instruction_is_return; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type d'instruction à représenter. * +* * +* Description : Crée une instruction pour l'architecture Dalvik. * +* * +* Retour : Architecture mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *g_dalvik_instruction_new(DalvikOpcodes type) +{ + GArchInstruction *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_DALVIK_INSTRUCTION, NULL); + + G_DALVIK_INSTRUCTION(result)->type = type; + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* AIDE A LA MISE EN PLACE D'INSTRUCTIONS */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. * +* len = taille totale des données à analyser. * +* * +* Description : Recherche l'identifiant de la prochaine instruction. * +* * +* Retour : Identifiant de la prochaine instruction à tenter de charger. * +* * +* Remarques : - * +* * +******************************************************************************/ + +DalvikOpcodes dalvik_guess_next_instruction(const bin_t *data, off_t pos, off_t len) +{ + DalvikOpcodes result; /* Identifiant à retourner */ + bin_t opcode; /* Opcode à trouver */ + + opcode = data[pos]; + + for (result = 0; result < DOP_COUNT; result++) + { + if (_instructions[result].opcode == opcode) + break; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction à traiter. * +* format = format du binaire manipulé. * +* syntax = type de représentation demandée. * +* * +* Description : Traduit une instruction en version humainement lisible. * +* * +* Retour : Chaîne de caractères à libérer de la mémoire. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const char *dalvik_get_instruction_text(const GDalvikInstruction *instr, const GExeFormat *format, AsmSyntax syntax) +{ + return _instructions[instr->type].keyword; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction à consulter. * +* addr = eventuelle adresse associée à faire connaître. [OUT] * +* * +* Description : Informe sur une éventuelle référence à une autre instruction.* +* * +* Retour : Type de lien trouvé ou ILT_NONE si aucun. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static InstructionLinkType dalvik_get_instruction_link(const GDalvikInstruction *instr, vmpa_t *addr) +{ + return ILT_NONE/*instr->get_link(instr, addr)*/; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction à consulter. * +* * +* Description : Indique si l'instruction correspond à un retour de fonction. * +* * +* Retour : true si l'instruction est un 'return' quelconque ou false. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool dalvik_instruction_is_return(const GDalvikInstruction *instr) +{ + return (instr->type == DOP_RETURN_VOID); + +} diff --git a/src/arch/dalvik/instruction.h b/src/arch/dalvik/instruction.h new file mode 100644 index 0000000..2bd77a3 --- /dev/null +++ b/src/arch/dalvik/instruction.h @@ -0,0 +1,98 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * instruction.h - prototypes pour la gestion des instructions de la VM Dalvik + * + * 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_DALVIK_INSTRUCTION_H +#define _ARCH_DALVIK_INSTRUCTION_H + + +#include "../instruction.h" + + + + + +/* Enumération de tous les opcodes */ +typedef enum _DalvikOpcodes +{ + DOP_NOP, /* nop (0x00) */ + + DOP_CONST_4, /* const/4 (0x12) */ + DOP_CONST_16, /* const/16 (0x13) */ + + DOP_CONST_HIGH16, /* const/high16 (0x15) */ + + DOP_CONST_STRING, /* const-string (0x1a) */ + + + DOP_RETURN_VOID, /* return-void (0x0e) */ + DOP_RETURN, /* return (0x0f) */ + + + DOP_SGET, /* sget (0x60) */ + DOP_SGET_WIDE, /* sget-wide (0x61) */ + DOP_SGET_OBJECT, /* sget-object (0x62) */ + + + DOP_INVOKE_VIRTUAL, /* invoke-virtual (0x6e) */ + DOP_INVOKE_SUPER, /* invoke-super (0x6f) */ + DOP_INVOKE_DIRECT, /* invoke-direct (0x70) */ + DOP_INVOKE_STATIC, /* invoke-static (0x71) */ + DOP_INVOKE_INTERFACE, /* invoke-interface (0x72) */ + + DOP_MUL_INT_2ADDR, /* mul-int/2addr (0xb2) */ + + DOP_COUNT + +} DalvikOpcodes; + + +#define G_TYPE_DALVIK_INSTRUCTION g_dalvik_instruction_get_type() +#define G_DALVIK_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dalvik_instruction_get_type(), GDalvikInstruction)) +#define G_IS_DALVIK_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dalvik_instruction_get_type())) +#define G_DALVIK_INSTRUCTION_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_dalvik_instruction_get_type(), GDalvikInstructionIface)) + + +/* Définition générique d'une instruction d'architecture Dalvik (instance) */ +typedef struct _GDalvikInstruction GDalvikInstruction; + +/* Définition générique d'une instruction d'architecture Dalvik (classe) */ +typedef struct _GDalvikInstructionClass GDalvikInstructionClass; + + +/* Indique le type défini pour une instruction d'architecture Dalvik. */ +GType g_dalvik_instruction_get_type(void); + +/* Crée une instruction pour l'architecture Dalvik. */ +GArchInstruction *g_dalvik_instruction_new(DalvikOpcodes); + + + +/* --------------------- AIDE A LA MISE EN PLACE D'INSTRUCTIONS --------------------- */ + + +/* Recherche l'identifiant de la prochaine instruction. */ +DalvikOpcodes dalvik_guess_next_instruction(const bin_t *, off_t, off_t); + + + +#endif /* _ARCH_DALVIK_INSTRUCTION_H */ diff --git a/src/arch/dalvik/op_const.c b/src/arch/dalvik/op_const.c new file mode 100644 index 0000000..e8c720e --- /dev/null +++ b/src/arch/dalvik/op_const.c @@ -0,0 +1,173 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_const.c - décodage des chargements de constantes + * + * 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 "opcodes.h" + + +#include "instruction.h" +#include "operand.h" + + + +/****************************************************************************** +* * +* Paramètres : 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. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'const/16'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_const_16(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GDalvikProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + SourceEndian endian; /* Boutisme lié au binaire */ + + result = g_dalvik_instruction_new(DOP_CONST_16); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_21S)) + { + g_object_unref(G_OBJECT(result)); + return NULL; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : 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. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'const/4'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_const_4(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GDalvikProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + SourceEndian endian; /* Boutisme lié au binaire */ + + result = g_dalvik_instruction_new(DOP_CONST_4); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_11N)) + { + g_object_unref(G_OBJECT(result)); + return NULL; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : 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. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'const/high16'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_const_high16(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GDalvikProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + SourceEndian endian; /* Boutisme lié au binaire */ + + result = g_dalvik_instruction_new(DOP_CONST_HIGH16); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_21H)) + { + g_object_unref(G_OBJECT(result)); + return NULL; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : 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. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'const-string'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_const_string(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GDalvikProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + SourceEndian endian; /* Boutisme lié au binaire */ + + result = g_dalvik_instruction_new(DOP_CONST_STRING); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_21C | DALVIK_OP_POOL(DPT_STRING))) + { + g_object_unref(G_OBJECT(result)); + return NULL; + } + + return result; + +} diff --git a/src/arch/dalvik/op_invoke.c b/src/arch/dalvik/op_invoke.c new file mode 100644 index 0000000..913fb1a --- /dev/null +++ b/src/arch/dalvik/op_invoke.c @@ -0,0 +1,209 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_invoke.c - décodage des appels de méthode + * + * 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 "opcodes.h" + + +#include "instruction.h" +#include "operand.h" + + + +/****************************************************************************** +* * +* Paramètres : 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. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'invoke-direct'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_invoke_direct(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GDalvikProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + SourceEndian endian; /* Boutisme lié au binaire */ + + result = g_dalvik_instruction_new(DOP_INVOKE_DIRECT); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_35C | DALVIK_OP_POOL(DPT_METHOD))) + { + g_object_unref(G_OBJECT(result)); + return NULL; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : 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. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'invoke-interface'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_invoke_interface(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GDalvikProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + SourceEndian endian; /* Boutisme lié au binaire */ + + result = g_dalvik_instruction_new(DOP_INVOKE_INTERFACE); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_35C | DALVIK_OP_POOL(DPT_METHOD))) + { + g_object_unref(G_OBJECT(result)); + return NULL; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : 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. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'invoke-static'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_invoke_static(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GDalvikProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + SourceEndian endian; /* Boutisme lié au binaire */ + + result = g_dalvik_instruction_new(DOP_INVOKE_STATIC); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_35C | DALVIK_OP_POOL(DPT_METHOD))) + { + g_object_unref(G_OBJECT(result)); + return NULL; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : 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. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'invoke-super'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_invoke_super(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GDalvikProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + SourceEndian endian; /* Boutisme lié au binaire */ + + result = g_dalvik_instruction_new(DOP_INVOKE_SUPER); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_35C | DALVIK_OP_POOL(DPT_METHOD))) + { + g_object_unref(G_OBJECT(result)); + return NULL; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : 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. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'invoke-virtual'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_invoke_virtual(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GDalvikProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + SourceEndian endian; /* Boutisme lié au binaire */ + + result = g_dalvik_instruction_new(DOP_INVOKE_VIRTUAL); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_35C | DALVIK_OP_POOL(DPT_METHOD))) + { + g_object_unref(G_OBJECT(result)); + return NULL; + } + + return result; + +} diff --git a/src/arch/dalvik/op_mul.c b/src/arch/dalvik/op_mul.c new file mode 100644 index 0000000..1e2b584 --- /dev/null +++ b/src/arch/dalvik/op_mul.c @@ -0,0 +1,65 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_mul.c - décodage des opérations de multiplications + * + * 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 "opcodes.h" + + +#include "instruction.h" +#include "operand.h" + + + +/****************************************************************************** +* * +* Paramètres : 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. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'mul-int/2addr'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_mul_int_2addr(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GDalvikProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + SourceEndian endian; /* Boutisme lié au binaire */ + + result = g_dalvik_instruction_new(DOP_MUL_INT_2ADDR); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_12X)) + { + g_object_unref(G_OBJECT(result)); + return NULL; + } + + return result; + +} diff --git a/src/arch/dalvik/op_nop.c b/src/arch/dalvik/op_nop.c new file mode 100644 index 0000000..39f37d9 --- /dev/null +++ b/src/arch/dalvik/op_nop.c @@ -0,0 +1,65 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_ret.c - décodage de l'instruction nulle + * + * 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 "opcodes.h" + + +#include "instruction.h" +#include "operand.h" + + + +/****************************************************************************** +* * +* Paramètres : 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. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'nop'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_nop(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GDalvikProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + SourceEndian endian; /* Boutisme lié au binaire */ + + result = g_dalvik_instruction_new(DOP_NOP); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_10X)) + { + g_object_unref(G_OBJECT(result)); + return NULL; + } + + return result; + +} diff --git a/src/arch/dalvik/op_ret.c b/src/arch/dalvik/op_ret.c new file mode 100644 index 0000000..baba5e3 --- /dev/null +++ b/src/arch/dalvik/op_ret.c @@ -0,0 +1,101 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_ret.c - décodage des ordres de retour + * + * 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 "opcodes.h" + + +#include "instruction.h" +#include "operand.h" + + + +/****************************************************************************** +* * +* Paramètres : 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. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'return'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_return(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GDalvikProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + SourceEndian endian; /* Boutisme lié au binaire */ + + result = g_dalvik_instruction_new(DOP_RETURN); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_11X)) + { + g_object_unref(G_OBJECT(result)); + return NULL; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : 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. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'return-void'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_return_void(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GDalvikProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + SourceEndian endian; /* Boutisme lié au binaire */ + + result = g_dalvik_instruction_new(DOP_RETURN_VOID); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_10X)) + { + g_object_unref(G_OBJECT(result)); + return NULL; + } + + return result; + +} diff --git a/src/arch/dalvik/op_sget.c b/src/arch/dalvik/op_sget.c new file mode 100644 index 0000000..6b44700 --- /dev/null +++ b/src/arch/dalvik/op_sget.c @@ -0,0 +1,137 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_sget.c - décodage des chargements de champs statiques + * + * 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 "opcodes.h" + + +#include "instruction.h" +#include "operand.h" + + + +/****************************************************************************** +* * +* Paramètres : 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. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'sget'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_sget(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GDalvikProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + SourceEndian endian; /* Boutisme lié au binaire */ + + result = g_dalvik_instruction_new(DOP_SGET); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_21C | DALVIK_OP_POOL(DPT_FIELD))) + { + g_object_unref(G_OBJECT(result)); + return NULL; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : 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. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'sget-object'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_sget_object(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GDalvikProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + SourceEndian endian; /* Boutisme lié au binaire */ + + result = g_dalvik_instruction_new(DOP_SGET_OBJECT); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_21C | DALVIK_OP_POOL(DPT_FIELD))) + { + g_object_unref(G_OBJECT(result)); + return NULL; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : 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. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'sget-wide'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_sget_wide(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GDalvikProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + SourceEndian endian; /* Boutisme lié au binaire */ + + result = g_dalvik_instruction_new(DOP_SGET_WIDE); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_21C | DALVIK_OP_POOL(DPT_FIELD))) + { + g_object_unref(G_OBJECT(result)); + return NULL; + } + + return result; + +} diff --git a/src/arch/dalvik/opcodes.h b/src/arch/dalvik/opcodes.h new file mode 100644 index 0000000..3a90d6f --- /dev/null +++ b/src/arch/dalvik/opcodes.h @@ -0,0 +1,110 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * opcodes.h - prototypes pour la liste de tous les opcodes de l'architecture Dalvik + * + * 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_DALVIK_OPCODES_H +#define _ARCH_DALVIK_OPCODES_H + + +#include "instruction.h" +#include "processor.h" + + + +/* Prototype de décodage d'une instruction Dalvik. */ +typedef GArchInstruction * (* dalvik_read_instr) (const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + + + +/* Décode une instruction de type 'nop'. */ +GArchInstruction *dalvik_read_instr_nop(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + + + +/* Décode une instruction de type 'const/16'. */ +GArchInstruction *dalvik_read_instr_const_16(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + +/* Décode une instruction de type 'const/4'. */ +GArchInstruction *dalvik_read_instr_const_4(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + + + + +/* Décode une instruction de type 'const/high16'. */ +GArchInstruction *dalvik_read_instr_const_high16(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + + + + +/* Décode une instruction de type 'const-string'. */ +GArchInstruction *dalvik_read_instr_const_string(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + + + + + + + + + +/* Décode une instruction de type 'sget'. */ +GArchInstruction *dalvik_read_instr_sget(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + +/* Décode une instruction de type 'sget-object'. */ +GArchInstruction *dalvik_read_instr_sget_object(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + +/* Décode une instruction de type 'sget-wide'. */ +GArchInstruction *dalvik_read_instr_sget_wide(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + + + +/* Décode une instruction de type 'invoke-direct'. */ +GArchInstruction *dalvik_read_instr_invoke_direct(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + +/* Décode une instruction de type 'invoke-interface'. */ +GArchInstruction *dalvik_read_instr_invoke_interface(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + +/* Décode une instruction de type 'invoke-static'. */ +GArchInstruction *dalvik_read_instr_invoke_static(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + +/* Décode une instruction de type 'invoke-super'. */ +GArchInstruction *dalvik_read_instr_invoke_super(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + +/* Décode une instruction de type 'invoke-virtual'. */ +GArchInstruction *dalvik_read_instr_invoke_virtual(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + + + +/* Décode une instruction de type 'mul-int/2addr'. */ +GArchInstruction *dalvik_read_instr_mul_int_2addr(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + + + +/* Décode une instruction de type 'return'. */ +GArchInstruction *dalvik_read_instr_return(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + +/* Décode une instruction de type 'return-void'. */ +GArchInstruction *dalvik_read_instr_return_void(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + + + +#endif /* _ARCH_DALVIK_OPCODES_H */ diff --git a/src/arch/dalvik/operand.c b/src/arch/dalvik/operand.c new file mode 100644 index 0000000..cc36cb5 --- /dev/null +++ b/src/arch/dalvik/operand.c @@ -0,0 +1,1127 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * operand.c - gestion des operandes de l'architecture Dalvik + * + * 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 "operand.h" + + +#include <malloc.h> + + +#include "register.h" +#include "../immediate.h" +#include "../operand-int.h" + + + +/* ----------------------- COQUILLE VIDE POUR OPERANDE DALVIK ----------------------- */ + + +/* Définition d'un opérande de Dalvik (instance) */ +struct _GDalvikOperand +{ + GArchOperand parent; /* Instance parente */ + +}; + + +/* Définition d'un opérande de Dalvik (classe) */ +struct _GDalvikOperandClass +{ + GArchOperandClass parent; /* Classe parente */ + +}; + + +/* Initialise la classe des opérandes Dalvik de base. */ +static void g_dalvik_operand_class_init(GDalvikOperandClass *); + +/* Initialise une instance d'opérande de base pour Dalvik. */ +static void g_dalvik_operand_init(GDalvikOperand *); + + + +/* --------------------- OPERANDES VISANT UN REGISTRE DE DALVIK --------------------- */ + + +/* Définition d'un opérande visant un registre Dalvik (instance) */ +struct _GDalvikRegisterOperand +{ + GDalvikOperand parent; /* Instance parente */ + + GDalvikRegister *reg; /* Registre représenté */ + +}; + + +/* Définition d'un opérande visant un registre Dalvik (classe) */ +struct _GDalvikRegisterOperandClass +{ + GDalvikOperandClass parent; /* Classe parente */ + +}; + + +/* Initialise la classe des opérandes de registre Dalvik. */ +static void g_dalvik_register_operand_class_init(GDalvikRegisterOperandClass *); + +/* Initialise une instance d'opérande de registre Dalvik. */ +static void g_dalvik_register_operand_init(GDalvikRegisterOperand *); + +/* Ajoute du texte simple à un fichier ouvert en écriture. */ +static void g_dalvik_register_operand_add_text(const GDalvikRegisterOperand *, GRenderingOptions *, MainRendering, FILE *); + +/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ +static void g_dalvik_register_operand_to_buffer(const GDalvikRegisterOperand *, GBufferLine *, GRenderingOptions *); + + + +/* -------------------- LISTE D'OPERANDES RASSEMBLES EN ARGUMENT -------------------- */ + + + +/* Définition d'un opérande visant une liste d'opérandes Dalvik (instance) */ +struct _GDalvikArgsOperand +{ + GDalvikOperand parent; /* Instance parente */ + + GArchOperand **args; /* Liste d'arguments */ + size_t count; /* Taille de cette liste */ + +}; + + +/* Définition d'un opérande visant une liste d'opérandes Dalvik (classe) */ +struct _GDalvikArgsOperandClass +{ + GDalvikOperandClass parent; /* Classe parente */ + +}; + + +/* Initialise la classe des listes d'opérandes Dalvik. */ +static void g_dalvik_args_operand_class_init(GDalvikArgsOperandClass *); + +/* Initialise une instance de liste d'opérandes Dalvik. */ +static void g_dalvik_args_operand_init(GDalvikArgsOperand *); + +/* Ajoute du texte simple à un fichier ouvert en écriture. */ +static void g_dalvik_args_operand_add_text(const GDalvikArgsOperand *, GRenderingOptions *, MainRendering, FILE *); + +/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ +static void g_dalvik_args_operand_to_buffer(const GDalvikArgsOperand *, GBufferLine *, GRenderingOptions *); + + + +/* ----------------- OPERANDES POINTANT VERS LA TABLE DE CONSTANTES ----------------- */ + + +/* Définition d'un opérande visant un élément de table de constantes Dalvik (instance) */ +struct _GDalvikPoolOperand +{ + GDalvikOperand parent; /* Instance parente */ + + DalvikPoolType type; /* Type de table visée */ + uint32_t index; /* Indice de l'élément visé */ + +}; + + +/* Définition d'un opérande visant un élément de table de constantes Dalvik (classe) */ +struct _GDalvikPoolOperandClass +{ + GDalvikOperandClass parent; /* Classe parente */ + +}; + + +/* Initialise la classe des opérandes de constante Dalvik. */ +static void g_dalvik_pool_operand_class_init(GDalvikPoolOperandClass *); + +/* Initialise une instance d'opérande de constante Dalvik. */ +static void g_dalvik_pool_operand_init(GDalvikPoolOperand *); + +/* Ajoute du texte simple à un fichier ouvert en écriture. */ +static void g_dalvik_pool_operand_add_text(const GDalvikPoolOperand *, GRenderingOptions *, MainRendering, FILE *); + +/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ +static void g_dalvik_pool_operand_to_buffer(const GDalvikPoolOperand *, GBufferLine *, GRenderingOptions *); + + + +/* ------------------------- AIDE A LA CREATION D'OPERANDES ------------------------- */ + + +/* Liste de tous les types d'opérandes */ +typedef enum _DalvikOperandID +{ + DOI_INVALID, + + DOI_REGISTER_4, + DOI_REGISTER_8, + + DOI_IMMEDIATE_4, + DOI_IMMEDIATE_16, + DOI_IMMEDIATE_H16, + + DOI_POOL_CONST + + +} DalvikOperandID; + + +/* Procède à la lecture d'opérandes pour une instruction. */ +static bool dalvik_read_basic_operands(GArchInstruction *, const bin_t *, off_t *, off_t, bool *, SourceEndian, DalvikOperandType); + +/* Procède à la lecture d'opérandes pour une instruction. */ +static bool dalvik_read_fixed_operands(GArchInstruction *, const bin_t *, off_t *, off_t, bool *, SourceEndian, DalvikOperandType); + + + +/* ---------------------------------------------------------------------------------- */ +/* COQUILLE VIDE POUR OPERANDE DALVIK */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini par la GLib pour un opérande de Dalvik. */ +G_DEFINE_TYPE(GDalvikOperand, g_dalvik_operand, G_TYPE_ARCH_OPERAND); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des opérandes Dalvik de base. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_operand_class_init(GDalvikOperandClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance à initialiser. * +* * +* Description : Initialise une instance d'opérande de base pour Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_operand_init(GDalvikOperand *operand) +{ + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* OPERANDES VISANT UN REGISTRE DE DALVIK */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini par la GLib pour un opérande de registre Dalvik. */ +G_DEFINE_TYPE(GDalvikRegisterOperand, g_dalvik_register_operand, G_TYPE_DALVIK_OPERAND); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des opérandes de registre Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_register_operand_class_init(GDalvikRegisterOperandClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance à initialiser. * +* * +* Description : Initialise une instance d'opérande de registre Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_register_operand_init(GDalvikRegisterOperand *operand) +{ + GContentExporter *parent; /* Instance parente */ + + parent = G_CONTENT_EXPORTER(operand); + + parent->add_text = (add_text_fc)g_dalvik_register_operand_add_text; + parent->export_buffer = (export_buffer_fc)g_dalvik_register_operand_to_buffer; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* low = position éventuelle des 4 bits visés. [OUT] * +* size = taille de l'opérande, et donc du registre. * +* endian = ordre des bits dans la source. * +* * +* Description : Crée un opérande visant un registre Dalvik. * +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_dalvik_register_operand_new(const bin_t *data, off_t *pos, off_t len, bool *low, MemoryDataSize size, SourceEndian endian) +{ + GDalvikRegisterOperand *result; /* Structure à retourner */ + uint8_t index8; /* Indice sur 8 bits */ + uint16_t index16; /* Indice sur 16 bits */ + bool test; /* Bilan de lecture */ + + switch (size) + { + case MDS_4_BITS: + test = read_u4(&index8, data, pos, len, low, endian); + break; + case MDS_8_BITS: + test = read_u8(&index8, data, pos, len, endian); + break; + case MDS_16_BITS: + test = read_u16(&index16, data, pos, len, endian); + break; + default: + test = false; + break; + } + + if (!test) + return NULL; + + result = g_object_new(G_TYPE_DALVIK_REGISTER_OPERAND, NULL); + + switch (size) + { + case MDS_4_BITS: + case MDS_8_BITS: + result->reg = g_dalvik_register_new(index8); + break; + case MDS_16_BITS: + result->reg = g_dalvik_register_new(index16); + break; + default: + break; + } + + return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à transcrire. * +* options = options de rendu. * +* rendering = support effectif final des lignes de code. * +* stream = flux ouvert en écriture. * +* * +* Description : Ajoute du texte simple à un fichier ouvert en écriture. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_register_operand_add_text(const GDalvikRegisterOperand *operand, GRenderingOptions *options, MainRendering rendering, FILE *stream) +{ + g_content_exporter_add_text(G_CONTENT_EXPORTER(operand->reg), options, rendering, stream); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à transcrire. * +* buffer = espace où placer ledit contenu. * +* options = options de rendu. * +* * +* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_register_operand_to_buffer(const GDalvikRegisterOperand *operand, GBufferLine *buffer, GRenderingOptions *options) +{ + g_content_exporter_to_buffer(G_CONTENT_EXPORTER(operand->reg), buffer, options); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* LISTE D'OPERANDES RASSEMBLES EN ARGUMENT */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini par la GLib pour une liste d'arguments Dalvik. */ +G_DEFINE_TYPE(GDalvikArgsOperand, g_dalvik_args_operand, G_TYPE_DALVIK_OPERAND); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des listes d'opérandes Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_args_operand_class_init(GDalvikArgsOperandClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance à initialiser. * +* * +* Description : Initialise une instance de liste d'opérandes Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_args_operand_init(GDalvikArgsOperand *operand) +{ + GContentExporter *parent; /* Instance parente */ + + parent = G_CONTENT_EXPORTER(operand); + + parent->add_text = (add_text_fc)g_dalvik_args_operand_add_text; + parent->export_buffer = (export_buffer_fc)g_dalvik_args_operand_to_buffer; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée un réceptacle pour opérandes Dalvik servant d'arguments.* +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_dalvik_args_operand_new(void) +{ + GDalvikArgsOperand *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_DALVIK_ARGS_OPERAND, NULL); + + return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à compléter. * +* arg = nouvel argument pour un appel. * +* * +* Description : Ajoute un élément à la liste d'arguments Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_dalvik_args_operand_add(GDalvikArgsOperand *operand, GArchOperand *arg) +{ + operand->args = (GArchOperand **)realloc(operand->args, ++operand->count * sizeof(GArchOperand *)); + + operand->args[operand->count - 1] = arg; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à transcrire. * +* options = options de rendu. * +* rendering = support effectif final des lignes de code. * +* stream = flux ouvert en écriture. * +* * +* Description : Ajoute du texte simple à un fichier ouvert en écriture. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_args_operand_add_text(const GDalvikArgsOperand *operand, GRenderingOptions *options, MainRendering rendering, FILE *stream) +{ + GContentExporter *exporter; /* Autre vision de l'objet */ + size_t i; /* Boucle de parcours */ + + exporter = G_CONTENT_EXPORTER(operand); + + g_content_exporter_insert_text(exporter, stream, "{", 1, RTT_HOOK); + + if (operand->count > 0) + { + g_content_exporter_add_text(G_CONTENT_EXPORTER(operand->args[0]), + options, rendering, stream); + + for (i = 1; i < operand->count; i++) + { + g_content_exporter_insert_text(exporter, stream, ",", 1, RTT_NONE/* FIXME */); + + g_content_exporter_insert_text(exporter, stream, " ", 1, RTT_NONE); + + g_content_exporter_add_text(G_CONTENT_EXPORTER(operand->args[i]), + options, rendering, stream); + + } + + } + + g_content_exporter_insert_text(exporter, stream, "}", 1, RTT_HOOK); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à transcrire. * +* buffer = espace où placer ledit contenu. * +* options = options de rendu. * +* * +* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_args_operand_to_buffer(const GDalvikArgsOperand *operand, GBufferLine *buffer, GRenderingOptions *options) +{ + GContentExporter *exporter; /* Autre vision de l'objet */ + size_t i; /* Boucle de parcours */ + + exporter = G_CONTENT_EXPORTER(operand); + + g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY, + "{", 1, RTT_HOOK); + + if (operand->count > 0) + { + g_content_exporter_to_buffer(G_CONTENT_EXPORTER(operand->args[0]), buffer, options); + + for (i = 1; i < operand->count; i++) + { + g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY, + ",", 1, RTT_NONE/* FIXME */); + + g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY, + " ", 1, RTT_NONE); + + g_content_exporter_to_buffer(G_CONTENT_EXPORTER(operand->args[i]), buffer, options); + + } + + } + + g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY, + "}", 1, RTT_HOOK); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* OPERANDES POINTANT VERS LA TABLE DE CONSTANTES */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini par la GLib pour un un élément de table de constantes Dalvik. */ +G_DEFINE_TYPE(GDalvikPoolOperand, g_dalvik_pool_operand, G_TYPE_DALVIK_OPERAND); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des opérandes de constante Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_pool_operand_class_init(GDalvikPoolOperandClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance à initialiser. * +* * +* Description : Initialise une instance d'opérande de constante Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_pool_operand_init(GDalvikPoolOperand *operand) +{ + GContentExporter *parent; /* Instance parente */ + + parent = G_CONTENT_EXPORTER(operand); + + parent->add_text = (add_text_fc)g_dalvik_pool_operand_add_text; + parent->export_buffer = (export_buffer_fc)g_dalvik_pool_operand_to_buffer; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type de table visée avec la référence. * +* data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* size = taille de l'opérande, et donc du registre. * +* endian = ordre des bits dans la source. * +* * +* Description : Crée un opérande visant un élément constant Dalvik. * +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_dalvik_pool_operand_new(DalvikPoolType type, const bin_t *data, off_t *pos, off_t len, MemoryDataSize size, SourceEndian endian) +{ + GDalvikPoolOperand *result; /* Structure à retourner */ + uint8_t index8; /* Indice sur 8 bits */ + uint16_t index16; /* Indice sur 16 bits */ + bool test; /* Bilan de lecture */ + + switch (size) + { + case MDS_8_BITS: + test = read_u8(&index8, data, pos, len, endian); + break; + case MDS_16_BITS: + test = read_u16(&index16, data, pos, len, endian); + break; + default: + test = false; + break; + } + + if (!test) + return NULL; + + result = g_object_new(G_TYPE_DALVIK_POOL_OPERAND, NULL); + + result->type = type; + result->index = (size == MDS_8_BITS ? index8 : index16); + + return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à transcrire. * +* options = options de rendu. * +* rendering = support effectif final des lignes de code. * +* stream = flux ouvert en écriture. * +* * +* Description : Ajoute du texte simple à un fichier ouvert en écriture. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_pool_operand_add_text(const GDalvikPoolOperand *operand, GRenderingOptions *options, MainRendering rendering, FILE *stream) +{ + //g_content_exporter_add_text(G_CONTENT_EXPORTER(operand->reg), options, rendering, stream); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à transcrire. * +* buffer = espace où placer ledit contenu. * +* options = options de rendu. * +* * +* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_pool_operand_to_buffer(const GDalvikPoolOperand *operand, GBufferLine *buffer, GRenderingOptions *options) +{ + GContentExporter *exporter; /* Autre vision de l'opérande */ + + char value[20]; /* Chaîne à imprimer */ + size_t len; /* Taille de l'élément inséré */ + + + + + exporter = G_CONTENT_EXPORTER(operand); + + switch (operand->type) + { + case DPT_NONE: + g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY, + "????", 4, RTT_SECTION); + break; + case DPT_STRING: + g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY, + "string", 6, RTT_SECTION); + break; + case DPT_TYPE: + g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY, + "type", 4, RTT_SECTION); + break; + case DPT_PROTO: + g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY, + "proto", 5, RTT_SECTION); + break; + case DPT_FIELD: + g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY, + "field", 5, RTT_SECTION); + break; + case DPT_METHOD: + g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY, + "method", 6, RTT_SECTION); + break; + } + + g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY, + "@", 1, RTT_SIGNS); + + + //g_content_exporter_to_buffer(G_CONTENT_EXPORTER(operand->reg), buffer, options); + + len = snprintf(value, 20, "%d", operand->index); + /* + strcpy(value, "12345"); + + len = 5; + */ + g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ASSEMBLY, + value, len, RTT_IMMEDIATE); + +} + + + + + + + + + + + + +/* ---------------------------------------------------------------------------------- */ +/* AIDE A LA CREATION D'OPERANDES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : instr = instruction dont la définition est incomplète. [OUT]* +* data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* low = position éventuelle des 4 bits visés. [OUT] * +* endian = boutisme lié au binaire accompagnant. * +* model = type d'opérandes attendues. * +* * +* Description : Procède à la lecture d'opérandes pour une instruction. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool dalvik_read_basic_operands(GArchInstruction *instr, const bin_t *data, off_t *pos, off_t len, bool *low, SourceEndian endian, DalvikOperandType model) +{ + bool result; /* Bilan à retourner */ + DalvikOperandID *types; /* Liste des chargements */ + DalvikOperandID *iter; /* Boucle de parcours */ + GArchOperand *op; /* Opérande unique décodé */ + uint16_t value16; /* Valeur sur 16 bits */ + + result = true; + + /* Choix des opérandes à charger */ + + switch (model & ~DALVIK_OP_POOL_MASK) + { + case DALVIK_OPT_12X: + types = (DalvikOperandID []) { + DOI_REGISTER_4, + DOI_REGISTER_4, + DOI_INVALID + }; + break; + + case DALVIK_OPT_11N: + types = (DalvikOperandID []) { + DOI_REGISTER_4, + DOI_IMMEDIATE_4, + DOI_INVALID + }; + break; + + case DALVIK_OPT_11X: + types = (DalvikOperandID []) { + DOI_REGISTER_8, + DOI_INVALID + }; + break; + + case DALVIK_OPT_21C: + types = (DalvikOperandID []) { + DOI_REGISTER_8, + DOI_POOL_CONST, + DOI_INVALID + }; + break; + + case DALVIK_OPT_21H: + types = (DalvikOperandID []) { + DOI_REGISTER_8, + DOI_IMMEDIATE_H16, + DOI_INVALID + }; + break; + + case DALVIK_OPT_21S: + types = (DalvikOperandID []) { + DOI_REGISTER_8, + DOI_IMMEDIATE_16, + DOI_INVALID + }; + break; + + default: + types = (DalvikOperandID []) { + DOI_INVALID + }; + break; + + } + + /* Chargement des opérandes */ + + for (iter = types; *iter != G_TYPE_INVALID && result; iter++) + { + switch (*iter) + { + case DOI_REGISTER_4: + op = g_dalvik_register_operand_new(data, pos, len, low, MDS_4_BITS, endian); + break; + + case DOI_REGISTER_8: + op = g_dalvik_register_operand_new(data, pos, len, NULL, MDS_8_BITS, endian); + break; + + case DOI_IMMEDIATE_4: + op = _g_imm_operand_new_from_data(MDS_4_BITS, data, pos, len, low, endian); + break; + + case DOI_IMMEDIATE_16: + op = g_imm_operand_new_from_data(MDS_16_BITS, data, pos, len, endian); + break; + + case DOI_IMMEDIATE_H16: + result = read_u16(&value16, data, pos, len, endian); + if (result) + op = g_imm_operand_new_from_value(MDS_32_BITS_SIGNED, ((uint32_t)value16) << 16); + break; + + case DOI_POOL_CONST: + op = g_dalvik_pool_operand_new(DALVIK_OP_GET_POOL(model), data, pos, len, MDS_16_BITS, endian); + break; + + default: + op = NULL; + break; + + } + + if (op == NULL) result = false; + else g_arch_instruction_attach_extra_operand(instr, op); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction dont la définition est incomplète. [OUT]* +* data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* low = position éventuelle des 4 bits visés. [OUT] * +* endian = boutisme lié au binaire accompagnant. * +* model = type d'opérandes attendues. * +* * +* Description : Procède à la lecture d'opérandes pour une instruction. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool dalvik_read_fixed_operands(GArchInstruction *instr, const bin_t *data, off_t *pos, off_t len, bool *low, SourceEndian endian, DalvikOperandType model) +{ + GArchOperand *opa; /* Opérande vA décodé */ + uint8_t b; /* Nbre. de registres utilisés */ + GArchOperand *target1; /* Opérande visant la table #1 */ + GArchOperand *target2; /* Opérande visant la table #2 */ + GArchOperand *args; /* Liste des opérandes */ + uint8_t i; /* Boucle de parcours */ + GArchOperand *op; /* Opérande unique décodé */ + + + + opa = g_dalvik_register_operand_new(data, pos, len, low, MDS_4_BITS, endian); + + if (!read_u4(&b, data, pos, len, low, endian)) + goto err_va; + + + target1 = g_dalvik_pool_operand_new(DALVIK_OP_GET_POOL(model), data, pos, len, MDS_16_BITS, endian); + if (target1 == NULL) goto err_target1; + + + + target2 = NULL; + + if (0) + { + if (target2 == NULL) goto err_target2; + } + + + args = g_dalvik_args_operand_new(); + g_arch_instruction_attach_extra_operand(instr, args); + + + /* Mise en place des arguments */ + + for (i = 0; i < MIN(b, 4); i++) + { + op = g_dalvik_register_operand_new(data, pos, len, low, MDS_4_BITS, endian); + if (op == NULL) goto err_registers; + + g_dalvik_args_operand_add(G_DALVIK_ARGS_OPERAND(args), op); + + } + + /* Rajout des éléments finaux déjà chargés */ + + if (b < 5) g_object_unref(G_OBJECT(opa)); + else g_dalvik_args_operand_add(G_DALVIK_ARGS_OPERAND(args), opa); + + g_arch_instruction_attach_extra_operand(instr, target1); + + if (target2 != NULL) + g_arch_instruction_attach_extra_operand(instr, target2); + + return true; + + err_registers: + + if (target2 != NULL) + g_object_unref(G_OBJECT(target2)); + + err_target2: + + g_object_unref(G_OBJECT(target1)); + + err_target1: + + g_object_unref(G_OBJECT(opa)); + + err_va: + + return false; + +} + + + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : instr = instruction dont la définition est incomplète. [OUT]* +* data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* endian = boutisme lié au binaire accompagnant. * +* model = type d'opérandes attendues. * +* * +* Description : Procède à la lecture d'opérandes pour une instruction. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool dalvik_read_operands(GArchInstruction *instr, const bin_t *data, off_t *pos, off_t len, SourceEndian endian, DalvikOperandType model) +{ + bool result; /* Bilan à retourner */ + + + bool low; + + off_t old_pos; + + off_t length; + + result = true; + + + old_pos = *pos; + + + low = true; + + + + switch (model & ~DALVIK_OP_POOL_MASK) + { + case DALVIK_OPT_12X: + case DALVIK_OPT_11N: + case DALVIK_OPT_11X: + case DALVIK_OPT_21C: + case DALVIK_OPT_21H: + case DALVIK_OPT_21S: + result = dalvik_read_basic_operands(instr, data, pos, len, &low, endian, model); + break; + + case DALVIK_OPT_35C: + result = dalvik_read_fixed_operands(instr, data, pos, len, &low, endian, model); + break; + + default: + break; + + } + + + + *pos = old_pos; + + + + if (*pos < len) + { + (*pos)++; + + length = DALVIK_OP_GET_LEN(model); + + if (length > 1) + *pos += (length - 1) * sizeof(uint16_t); + + } + + + + + return result; + +} diff --git a/src/arch/dalvik/operand.h b/src/arch/dalvik/operand.h new file mode 100644 index 0000000..da14aa3 --- /dev/null +++ b/src/arch/dalvik/operand.h @@ -0,0 +1,207 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * operand.h - prototypes pour la gestion des operandes de l'architecture Dalvik + * + * 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_DALVIK_OPERAND_H +#define _ARCH_DALVIK_OPERAND_H + + +#include "../instruction.h" +#include "../../common/endianness.h" + + + +/* ----------------------- COQUILLE VIDE POUR OPERANDE DALVIK ----------------------- */ + + +#define G_TYPE_DALVIK_OPERAND g_dalvik_operand_get_type() +#define G_DALVIK_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dalvik_operand_get_type(), GDalvikOperand)) +#define G_IS_DALVIK_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dalvik_operand_get_type())) +#define G_DALVIK_OPERAND_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_dalvik_operand_get_type(), GDalvikOperandIface)) + + +/* Définition d'un opérande de Dalvik (instance) */ +typedef struct _GDalvikOperand GDalvikOperand; + +/* Définition d'un opérande de Dalvik (classe) */ +typedef struct _GDalvikOperandClass GDalvikOperandClass; + + +/* Indique le type défini par la GLib pour un opérande de Dalvik. */ +GType g_dalvik_operand_get_type(void); + + + +/* --------------------- OPERANDES VISANT UN REGISTRE DE DALVIK --------------------- */ + + +#define G_TYPE_DALVIK_REGISTER_OPERAND g_dalvik_register_operand_get_type() +#define G_DALVIK_REGISTER_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dalvik_register_operand_get_type(), GDalvikRegisterOperand)) +#define G_IS_DALVIK_REGISTER_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dalvik_register_operand_get_type())) +#define G_DALVIK_REGISTER_OPERAND_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_dalvik_register_operand_get_type(), GDalvikRegisterOperandIface)) + + +/* Définition d'un opérande visant un registre Dalvik (instance) */ +typedef struct _GDalvikRegisterOperand GDalvikRegisterOperand; + +/* Définition d'un opérande visant un registre Dalvik (classe) */ +typedef struct _GDalvikRegisterOperandClass GDalvikRegisterOperandClass; + + +/* Indique le type défini par la GLib pour un opérande de registre Dalvik. */ +GType g_dalvik_register_operand_get_type(void); + +/* Crée un opérande visant un registre Dalvik. */ +GArchOperand *g_dalvik_register_operand_new(const bin_t *, off_t *, off_t, bool *, MemoryDataSize, SourceEndian); + + + +/* -------------------- LISTE D'OPERANDES RASSEMBLES EN ARGUMENT -------------------- */ + + +#define G_TYPE_DALVIK_ARGS_OPERAND g_dalvik_args_operand_get_type() +#define G_DALVIK_ARGS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dalvik_args_operand_get_type(), GDalvikArgsOperand)) +#define G_IS_DALVIK_ARGS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dalvik_args_operand_get_type())) +#define G_DALVIK_ARGS_OPERAND_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_dalvik_args_operand_get_type(), GDalvikArgsOperandIface)) + + +/* Définition d'un opérande visant une liste d'opérandes Dalvik (instance) */ +typedef struct _GDalvikArgsOperand GDalvikArgsOperand; + +/* Définition d'un opérande visant une liste d'opérandes Dalvik (classe) */ +typedef struct _GDalvikArgsOperandClass GDalvikArgsOperandClass; + + +/* Indique le type défini par la GLib pour une liste d'arguments Dalvik. */ +GType g_dalvik_args_operand_get_type(void); + +/* Crée un réceptacle pour opérandes Dalvik servant d'arguments. */ +GArchOperand *g_dalvik_args_operand_new(void); + +/* Ajoute un élément à la liste d'arguments Dalvik. */ +void g_dalvik_args_operand_add(GDalvikArgsOperand *, GArchOperand *); + + + +/* ----------------- OPERANDES POINTANT VERS LA TABLE DE CONSTANTES ----------------- */ + + + +#define G_TYPE_DALVIK_POOL_OPERAND g_dalvik_pool_operand_get_type() +#define G_DALVIK_POOL_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dalvik_pool_operand_get_type(), GDalvikPoolOperand)) +#define G_IS_DALVIK_POOL_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dalvik_pool_operand_get_type())) +#define G_DALVIK_POOL_OPERAND_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_dalvik_pool_operand_get_type(), GDalvikPoolOperandIface)) + + +/* Définition d'un opérande visant un élément de table de constantes Dalvik (instance) */ +typedef struct _GDalvikPoolOperand GDalvikPoolOperand; + +/* Définition d'un opérande visant un élément de table de constantes Dalvik (classe) */ +typedef struct _GDalvikPoolOperandClass GDalvikPoolOperandClass; + + +/* Type de table de constantes */ +typedef enum _DalvikPoolType +{ + DPT_NONE = 0x0, + DPT_STRING = 0x1, + DPT_TYPE = 0x2, + DPT_PROTO = 0x3, + DPT_FIELD = 0x4, + DPT_METHOD = 0x5 + +} DalvikPoolType; + + +/* Indique le type défini par la GLib pour un un élément de table de constantes Dalvik. */ +GType g_dalvik_pool_operand_get_type(void); + +/* Crée un opérande visant un élément constant Dalvik. */ +GArchOperand *g_dalvik_pool_operand_new(DalvikPoolType, const bin_t *, off_t *, off_t, MemoryDataSize, SourceEndian); + + + + + + + +/* ------------------------- AIDE A LA CREATION D'OPERANDES ------------------------- */ + + +/** + * Cf. les documentations suivantes : + * - http://www.netmite.com/android/mydroid/dalvik/docs/instruction-formats.html + * - http://www.netmite.com/android/mydroid/dalvik/docs/dalvik-bytecode.html + * - http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html + */ + + +/* Construction d'identifiants typés */ + +#define DALVIK_OP_LEN_OFF 28 +#define DALVIK_OP_LEN_MASK 0xf0000000 + +#define DALVIK_OP_REG_OFF 24 +#define DALVIK_OP_REG_MASK 0x0f000000 + +#define DALVIK_OP_POOL_OFF 20 +#define DALVIK_OP_POOL_MASK 0x00f00000 + +#define DALVIK_OP_LEN(l) ((l) << DALVIK_OP_LEN_OFF) +#define DALVIK_OP_GET_LEN(v) (((v) & DALVIK_OP_LEN_MASK) >> DALVIK_OP_LEN_OFF) + +#define DALVIK_OP_REG(r) ((r) << DALVIK_OP_REG_OFF) +#define DALVIK_OP_COUNT_REG(v) (((v) & DALVIK_OP_REG_MASK) >> DALVIK_OP_REG_OFF) + +#define DALVIK_OP_POOL(p) ((p) << DALVIK_OP_POOL_OFF) +#define DALVIK_OP_GET_POOL(v) (((v) & DALVIK_OP_POOL_MASK) >> DALVIK_OP_POOL_OFF) + + +/* Types d'opérandes supportés */ +typedef enum _DalvikOperandType +{ + DALVIK_OPT_10X = DALVIK_OP_LEN(1) | DALVIK_OP_REG(0) | 'X', + + DALVIK_OPT_11N = DALVIK_OP_LEN(1) | DALVIK_OP_REG(1) | 'N', + DALVIK_OPT_11X = DALVIK_OP_LEN(1) | DALVIK_OP_REG(1) | 'X', + + DALVIK_OPT_12X = DALVIK_OP_LEN(1) | DALVIK_OP_REG(2) | 'X', + + DALVIK_OPT_21C = DALVIK_OP_LEN(2) | DALVIK_OP_REG(1) | 'C', + + DALVIK_OPT_21H = DALVIK_OP_LEN(2) | DALVIK_OP_REG(1) | 'H', + + DALVIK_OPT_21S = DALVIK_OP_LEN(2) | DALVIK_OP_REG(1) | 'S', + + + DALVIK_OPT_35C = DALVIK_OP_LEN(3) | DALVIK_OP_REG(5) | 'C' + + +} DalvikOperandType; + + +/* Procède à la lecture d'opérandes pour une instruction. */ +bool dalvik_read_operands(GArchInstruction *, const bin_t *, off_t *, off_t, SourceEndian, DalvikOperandType); + + + +#endif /* _ARCH_DALVIK_OPERAND_H */ diff --git a/src/arch/dalvik/processor.c b/src/arch/dalvik/processor.c new file mode 100644 index 0000000..7bf469e --- /dev/null +++ b/src/arch/dalvik/processor.c @@ -0,0 +1,198 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * processor.c - manipulation du processeur de la VM Dalvik + * + * 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 de la VM Dalvik (instance) */ +struct _GDalvikProcessor +{ + GArchProcessor parent; /* Instance parente */ + +}; + + +/* Définition du processeur de la VM Dalvik (classe) */ +struct _GDalvikProcessorClass +{ + GArchProcessorClass parent; /* Classe parente */ + +}; + + +/* Initialise la classe des processeurs de VM Dalvik. */ +static void g_dalvik_processor_class_init(GDalvikProcessorClass *); + +/* Initialise une instance de processeur de VM Dalvik. */ +static void g_dalvik_processor_init(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); + + +/* Indique le type défini par la GLib pour le processeur DALVIK. */ +G_DEFINE_TYPE(GDalvikProcessor, g_dalvik_processor, G_TYPE_ARCH_PROCESSOR); + + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des processeurs de VM Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_processor_class_init(GDalvikProcessorClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : proc = instance à initialiser. * +* * +* Description : Initialise une instance de processeur de VM Dalvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_processor_init(GDalvikProcessor *proc) +{ + GArchProcessor *parent; /* Instance parente */ + + parent = G_ARCH_PROCESSOR(proc); + + parent->endianness = SRE_LITTLE; + parent->memsize = MDS_32_BITS; + + parent->decode = (decode_instruction_fc)g_dalvik_processor_decode_instruction; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée le support de l'architecture Dalvik. * +* * +* Retour : Architecture mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchProcessor *g_dalvik_processor_new(void) +{ + GArchProcessor *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_DALVIK_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_dalvik_processor_decode_instruction(const GDalvikProcessor *proc, const bin_t *data, off_t *pos, off_t len, vmpa_t addr) +{ + GArchInstruction *result; /* Instruction à renvoyer */ + DalvikOpcodes id; /* Identifiant d'instruction */ + + static const dalvik_read_instr decodings[DOP_COUNT] = { + + [DOP_NOP] = dalvik_read_instr_nop, + + + [DOP_CONST_4] = dalvik_read_instr_const_4, + [DOP_CONST_16] = dalvik_read_instr_const_16, + + + [DOP_CONST_HIGH16] = dalvik_read_instr_const_high16, + + + [DOP_CONST_STRING] = dalvik_read_instr_const_string, + + + + [DOP_RETURN_VOID] = dalvik_read_instr_return_void, + [DOP_RETURN] = dalvik_read_instr_return, + + + [DOP_SGET] = dalvik_read_instr_sget, + [DOP_SGET_WIDE] = dalvik_read_instr_sget_wide, + [DOP_SGET_OBJECT] = dalvik_read_instr_sget_object, + + + [DOP_INVOKE_VIRTUAL] = dalvik_read_instr_invoke_virtual, + [DOP_INVOKE_SUPER] = dalvik_read_instr_invoke_super, + [DOP_INVOKE_DIRECT] = dalvik_read_instr_invoke_direct, + [DOP_INVOKE_STATIC] = dalvik_read_instr_invoke_static, + [DOP_INVOKE_INTERFACE] = dalvik_read_instr_invoke_interface, + + + [DOP_MUL_INT_2ADDR] = dalvik_read_instr_mul_int_2addr + + + }; + + id = dalvik_guess_next_instruction(data, *pos, len); + + if (id != DOP_COUNT) (*pos)++; + + if (id == DOP_COUNT) result = NULL; + else result = decodings[id](data, pos, len, addr, proc); + + return result; + +} diff --git a/src/arch/dalvik/processor.h b/src/arch/dalvik/processor.h new file mode 100644 index 0000000..d972d73 --- /dev/null +++ b/src/arch/dalvik/processor.h @@ -0,0 +1,53 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * processor.h - prototypes pour la manipulation du processeur de la VM Dalvik + * + * 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_DALVIK_PROCESSOR_H +#define _ARCH_DALVIK_PROCESSOR_H + + +#include "../processor.h" + + + +#define G_TYPE_DALVIK_PROCESSOR g_dalvik_processor_get_type() +#define G_DALVIK_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dalvik_processor_get_type(), GDalvikProcessor)) +#define G_IS_DALVIK_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dalvik_processor_get_type())) +#define G_DALVIK_PROCESSOR_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_dalvik_processor_get_type(), GDalvikProcessorIface)) + + +/* Définition du processeur de la VM Dalvik (instance) */ +typedef struct _GDalvikProcessor GDalvikProcessor; + +/* Définition du processeur de la VM Dalvik (classe) */ +typedef struct _GDalvikProcessorClass GDalvikProcessorClass; + + +/* Indique le type défini par la GLib pour le processeur Dalvik. */ +GType g_dalvik_processor_get_type(void); + +/* Crée le support de l'architecture Dalvik. */ +GArchProcessor *g_dalvik_processor_new(void); + + + +#endif /* _ARCH_DALVIK_PROCESSOR_H */ diff --git a/src/arch/dalvik/register.c b/src/arch/dalvik/register.c new file mode 100644 index 0000000..78b5166 --- /dev/null +++ b/src/arch/dalvik/register.c @@ -0,0 +1,264 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * registers.c - aides auxiliaires relatives aux registres Dalvik + * + * 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 "register.h" + + +#include <stdio.h> + + +#include "../operand-int.h" + + + +//* Représentation d'un registre Dalvik (instance) */ +struct _GDalvikRegister +{ + GArchOperand parent; /* Instance parente */ + + uint16_t index; /* Indice du registre */ + +}; + + +/* Représentation d'un registre Dalvik (classe) */ +struct _GDalvikRegisterClass +{ + GArchOperandClass parent; /* Classe parente */ + +}; + + +#define MAX_REGNAME_LEN 8 + + +/* Construit la chaîne de caractères correspondant à l'opérande. */ +static void g_dalvik_register_to_string(const GDalvikRegister *, AsmSyntax, char [MAX_REGNAME_LEN], size_t *); + +/* Ajoute du texte simple à un fichier ouvert en écriture. */ +static void g_dalvik_register_add_text(const GDalvikRegister *, GRenderingOptions *, MainRendering, FILE *); + +/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ +static void g_dalvik_register_to_buffer(const GDalvikRegister *, GBufferLine *, GRenderingOptions *); + + + +/* Indique le type défini pour une représentation d'un registre Dalvik. */ +G_DEFINE_TYPE(GDalvikRegister, g_dalvik_register, G_TYPE_CONTENT_EXPORTER); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des lignes de représentation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_register_class_init(GDalvikRegisterClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : reg = instance à initialiser. * +* * +* Description : Initialise une instance de ligne de représentation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_register_init(GDalvikRegister *reg) +{ + GContentExporter *parent; /* Instance parente */ + + parent = G_CONTENT_EXPORTER(reg); + + parent->add_text = (add_text_fc)g_dalvik_register_add_text; + parent->export_buffer = (export_buffer_fc)g_dalvik_register_to_buffer; + +} + + +/****************************************************************************** +* * +* Paramètres : index = indice du registre correspondant. * +* * +* Description : Crée une réprésentation de registre Dalvik. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDalvikRegister *g_dalvik_register_new(uint16_t index) +{ + GDalvikRegister *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_DALVIK_REGISTER, NULL); + + result->index = index; + + return result; + +} + + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à transcrire. * +* syntax = type de représentation demandée. * +* key = description humaine du registre. [OUT] * +* klen = nombre de caractères utilisés. [OUT] * +* * +* Description : Construit la chaîne de caractères correspondant à l'opérande.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_register_to_string(const GDalvikRegister *reg, AsmSyntax syntax, char key[MAX_REGNAME_LEN], size_t *klen) +{ + switch (syntax) + { + case ASX_INTEL: + *klen = snprintf(key, MAX_REGNAME_LEN, "v%hd", reg->index); + break; + + case ASX_ATT: + *klen = snprintf(key, MAX_REGNAME_LEN, "%%v%hd", reg->index); + break; + + default: + *klen = 0; + break; + + } + +} + + +/****************************************************************************** +* * +* Paramètres : reg = registre X86 à transcrire. * +* options = options de rendu. * +* rendering = support effectif final des lignes de code. * +* stream = flux ouvert en écriture. * +* * +* Description : Ajoute du texte simple à un fichier ouvert en écriture. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_register_add_text(const GDalvikRegister *reg, GRenderingOptions *options, MainRendering rendering, FILE *stream) +{ + char key[MAX_REGNAME_LEN]; /* Mot clef principal */ + size_t klen; /* Taille de ce mot clef */ + + g_dalvik_register_to_string(reg, g_rendering_options_get_syntax(options), key, &klen); + + g_content_exporter_insert_text(G_CONTENT_EXPORTER(reg), stream, + key, klen, RTT_REGISTER); + +} + + +/****************************************************************************** +* * +* Paramètres : reg = registre X86 à transcrire. * +* buffer = espace où placer ledit contenu. * +* options = options de rendu. * +* * +* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_register_to_buffer(const GDalvikRegister *reg, GBufferLine *buffer, GRenderingOptions *options) +{ + char key[MAX_REGNAME_LEN]; /* Mot clef principal */ + size_t klen; /* Taille de ce mot clef */ + + g_dalvik_register_to_string(reg, g_rendering_options_get_syntax(options), key, &klen); + + g_content_exporter_insert_into_buffer(G_CONTENT_EXPORTER(reg), buffer, BLC_ASSEMBLY, + key, klen, RTT_REGISTER); + +} + + +/****************************************************************************** +* * +* Paramètres : reg = registre à consulter. * +* * +* Description : Indique si le registre correspond à ebp ou similaire. * +* * +* Retour : true si la correspondance est avérée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_dalvik_register_is_base_pointer(const GDalvikRegister *reg) +{ + return false; + +} + + +/****************************************************************************** +* * +* Paramètres : reg = registre à consulter. * +* * +* Description : Indique si le registre correspond à esp ou similaire. * +* * +* Retour : true si la correspondance est avérée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_dalvik_register_is_stack_pointer(const GDalvikRegister *reg) +{ + return false; + +} diff --git a/src/arch/dalvik/register.h b/src/arch/dalvik/register.h new file mode 100644 index 0000000..5ac5617 --- /dev/null +++ b/src/arch/dalvik/register.h @@ -0,0 +1,65 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * registers.h - prototypes pour les aides auxiliaires relatives aux registres Dalvik + * + * 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_DALVIK_REGISTERS_H +#define _ARCH_DALVIK_REGISTERS_H + + +#include <glib-object.h> +#include <stdbool.h> + + +#include "../archbase.h" + + + +#define G_TYPE_DALVIK_REGISTER g_dalvik_register_get_type() +#define G_DALVIK_REGISTER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dalvik_register_get_type(), GDalvikRegister)) +#define G_IS_DALVIK_REGISTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dalvik_register_get_type())) +#define G_DALVIK_REGISTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DALVIK_REGISTER, GDalvikRegisterClass)) +#define G_IS_DALVIK_REGISTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DALVIK_REGISTER)) +#define G_DALVIK_REGISTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DALVIK_REGISTER, GDalvikRegisterClass)) + + +/* Représentation d'un registre Dalvik (instance) */ +typedef struct _GDalvikRegister GDalvikRegister; + +/* Représentation d'un registre Dalvik (classe) */ +typedef struct _GDalvikRegisterClass GDalvikRegisterClass; + + +/* Indique le type défini pour une représentation d'un registre Dalvik. */ +GType g_dalvik_register_get_type(void); + +/* Crée une réprésentation de registre Dalvik. */ +GDalvikRegister *g_dalvik_register_new(uint16_t); + +/* Indique si le registre correspond à ebp ou similaire. */ +bool g_dalvik_register_is_base_pointer(const GDalvikRegister *); + +/* Indique si le registre correspond à esp ou similaire. */ +bool g_dalvik_register_is_stack_pointer(const GDalvikRegister *); + + + +#endif /* _ARCH_DALVIK_REGISTERS_H */ diff --git a/src/arch/immediate.c b/src/arch/immediate.c index 07f848f..1a32748 100644 --- a/src/arch/immediate.c +++ b/src/arch/immediate.c @@ -41,7 +41,7 @@ struct _GImmOperand { GArchOperand parent; /* Instance parente */ - AsmOperandSize size; /* Taille de l'opérande */ + MemoryDataSize size; /* Taille de l'opérande */ /** * Note : dans le cas d'une valeur signée, @@ -148,6 +148,7 @@ static void g_imm_operand_init(GImmOperand *operand) * data = flux de données à analyser. * * pos = position courante dans ce flux. [OUT] * * len = taille totale des données à analyser. * +* low = position éventuelle des 4 bits visés. [OUT] * * endian = ordre des bits dans la source. * * * * Description : Crée un opérande réprésentant une valeur numérique. * @@ -158,7 +159,7 @@ static void g_imm_operand_init(GImmOperand *operand) * * ******************************************************************************/ -GArchOperand *g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *data, off_t *pos, off_t len, SourceEndian endian) +GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *data, off_t *pos, off_t len, bool *low, SourceEndian endian) { GImmOperand *result; /* Opérande à retourner */ @@ -168,42 +169,52 @@ GArchOperand *g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *data switch (size) { - case AOS_8_BITS_UNSIGNED: + case MDS_4_BITS_UNSIGNED: + if (!read_u4(&result->unsigned_imm.val8, data, pos, len, low, endian)) + goto gionfd_error; + break; + + case MDS_8_BITS_UNSIGNED: if (!read_u8(&result->unsigned_imm.val8, data, pos, len, endian)) goto gionfd_error; break; - case AOS_16_BITS_UNSIGNED: + case MDS_16_BITS_UNSIGNED: if (!read_u16(&result->unsigned_imm.val16, data, pos, len, endian)) goto gionfd_error; break; - case AOS_32_BITS_UNSIGNED: + case MDS_32_BITS_UNSIGNED: if (!read_u32(&result->unsigned_imm.val32, data, pos, len, endian)) goto gionfd_error; break; - case AOS_64_BITS_UNSIGNED: + case MDS_64_BITS_UNSIGNED: if (!read_u64(&result->unsigned_imm.val64, data, pos, len, endian)) goto gionfd_error; break; - case AOS_8_BITS_SIGNED: + case MDS_4_BITS_SIGNED: + if (!read_s4(&result->signed_imm.val8, data, pos, len, low, endian)) + goto gionfd_error; + break; + + case MDS_8_BITS_SIGNED: if (!read_s8(&result->signed_imm.val8, data, pos, len, endian)) goto gionfd_error; break; - case AOS_16_BITS_SIGNED: + case MDS_16_BITS_SIGNED: if (!read_s16(&result->signed_imm.val16, data, pos, len, endian)) goto gionfd_error; break; - case AOS_32_BITS_SIGNED: + case MDS_32_BITS_SIGNED: if (!read_s32(&result->signed_imm.val32, data, pos, len, endian)) goto gionfd_error; break; - case AOS_64_BITS_SIGNED: + case MDS_64_BITS_SIGNED: if (!read_s64(&result->signed_imm.val64, data, pos, len, endian)) goto gionfd_error; break; @@ -218,7 +229,7 @@ GArchOperand *g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *data gionfd_error: - /* TODO : free */ + g_object_unref(G_OBJECT(result)); return NULL; @@ -238,7 +249,7 @@ GArchOperand *g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *data * * ******************************************************************************/ -GArchOperand *g_imm_operand_new_from_value(AsmOperandSize size, ...) +GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, ...) { GImmOperand *result; /* Opérande à retourner */ va_list ap; /* Liste des compléments */ @@ -251,7 +262,7 @@ GArchOperand *g_imm_operand_new_from_value(AsmOperandSize size, ...) int32_t sval32; /* Valeur sur 32 bits */ int64_t sval64; /* Valeur sur 64 bits */ - if (size == AOS_UNDEFINED) return NULL; + if (size == MDS_UNDEFINED) return NULL; result = g_object_new(G_TYPE_IMM_OPERAND, NULL); @@ -262,37 +273,37 @@ GArchOperand *g_imm_operand_new_from_value(AsmOperandSize size, ...) switch (size) { /* Pour GCC... */ - case AOS_UNDEFINED: + case MDS_UNDEFINED: break; - case AOS_8_BITS_UNSIGNED: + case MDS_8_BITS_UNSIGNED: uval8 = (uint8_t)va_arg(ap, unsigned int); result->unsigned_imm.val8 = uval8; break; - case AOS_16_BITS_UNSIGNED: + case MDS_16_BITS_UNSIGNED: uval16 = (uint16_t)va_arg(ap, unsigned int); result->unsigned_imm.val16 = uval16; break; - case AOS_32_BITS_UNSIGNED: + case MDS_32_BITS_UNSIGNED: uval32 = (uint32_t)va_arg(ap, unsigned int); result->unsigned_imm.val32 = uval32; break; - case AOS_64_BITS_UNSIGNED: + case MDS_64_BITS_UNSIGNED: uval64 = (uint64_t)va_arg(ap, unsigned int); result->unsigned_imm.val64 = uval64; break; - case AOS_8_BITS_SIGNED: + case MDS_8_BITS_SIGNED: sval8 = (int8_t)va_arg(ap, int); result->signed_imm.val8 = sval8; break; - case AOS_16_BITS_SIGNED: + case MDS_16_BITS_SIGNED: sval16 = (int16_t)va_arg(ap, int); result->signed_imm.val16 = sval16; break; - case AOS_32_BITS_SIGNED: + case MDS_32_BITS_SIGNED: sval32 = (int32_t)va_arg(ap, int); result->signed_imm.val32 = sval32; break; - case AOS_64_BITS_SIGNED: + case MDS_64_BITS_SIGNED: sval64 = (int64_t)va_arg(ap, int); result->signed_imm.val64 = sval64; break; @@ -323,16 +334,19 @@ bool g_imm_operand_is_negative(const GImmOperand *operand) switch (operand->size) { - case AOS_8_BITS_SIGNED: + case MDS_4_BITS_SIGNED: + result = (operand->signed_imm.val8 & 0x08); + break; + case MDS_8_BITS_SIGNED: result = (operand->signed_imm.val8 & 0x80); break; - case AOS_16_BITS_SIGNED: + case MDS_16_BITS_SIGNED: result = (operand->signed_imm.val16 & 0x8000); break; - case AOS_32_BITS_SIGNED: + case MDS_32_BITS_SIGNED: result = (operand->signed_imm.val32 & 0x80000000); break; - case AOS_64_BITS_SIGNED: + case MDS_64_BITS_SIGNED: result = (operand->signed_imm.val64 & 0x8000000000000000ll); break; default: @@ -371,37 +385,38 @@ 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 AOS_8_BITS_UNSIGNED: + case MDS_4_BITS_UNSIGNED: + case MDS_8_BITS_UNSIGNED: result = snprintf(value, VMPA_MAX_SIZE, "0x%hhx", operand->unsigned_imm.val8); break; - case AOS_16_BITS_UNSIGNED: + case MDS_16_BITS_UNSIGNED: result = snprintf(value, VMPA_MAX_SIZE, "0x%hx", operand->unsigned_imm.val16); break; - case AOS_32_BITS_UNSIGNED: + case MDS_32_BITS_UNSIGNED: result = snprintf(value, VMPA_MAX_SIZE, "0x%x", operand->unsigned_imm.val32); break; - case AOS_64_BITS_UNSIGNED: + case MDS_64_BITS_UNSIGNED: result = snprintf(value, VMPA_MAX_SIZE, "0x%llx", operand->unsigned_imm.val64); break; - case AOS_8_BITS_SIGNED: + case MDS_8_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 AOS_16_BITS_SIGNED: + 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); else result = snprintf(value, VMPA_MAX_SIZE, "0x%hx", operand->signed_imm.val16); break; - case AOS_32_BITS_SIGNED: + 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); else result = snprintf(value, VMPA_MAX_SIZE, "0x%x", operand->signed_imm.val32); break; - case AOS_64_BITS_SIGNED: + 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); else @@ -416,28 +431,29 @@ 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 AOS_8_BITS_UNSIGNED: + case MDS_4_BITS_UNSIGNED: + case MDS_8_BITS_UNSIGNED: result = snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", operand->unsigned_imm.val8); break; - case AOS_16_BITS_UNSIGNED: + case MDS_16_BITS_UNSIGNED: result = snprintf(value, VMPA_MAX_SIZE, "$0x%hx", operand->unsigned_imm.val16); break; - case AOS_32_BITS_UNSIGNED: + case MDS_32_BITS_UNSIGNED: result = snprintf(value, VMPA_MAX_SIZE, "$0x%x", operand->unsigned_imm.val32); break; - case AOS_64_BITS_UNSIGNED: + case MDS_64_BITS_UNSIGNED: result = snprintf(value, VMPA_MAX_SIZE, "$0x%llx", operand->unsigned_imm.val64); break; - case AOS_8_BITS_SIGNED: + case MDS_8_BITS_SIGNED: result = snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", ~operand->signed_imm.val8 + 1); break; - case AOS_16_BITS_SIGNED: + case MDS_16_BITS_SIGNED: result = snprintf(value, VMPA_MAX_SIZE, "$0x%hx", ~operand->signed_imm.val16 + 1); break; - case AOS_32_BITS_SIGNED: + case MDS_32_BITS_SIGNED: result = snprintf(value, VMPA_MAX_SIZE, "$0x%x", ~operand->signed_imm.val32 + 1); break; - case AOS_64_BITS_SIGNED: + case MDS_64_BITS_SIGNED: result = snprintf(value, VMPA_MAX_SIZE, "$0x%llx", ~operand->signed_imm.val64 + 1); break; } @@ -528,16 +544,17 @@ bool g_imm_operand_to_vmpa_t(const GImmOperand *operand, vmpa_t *addr) switch (operand->size) { - case AOS_8_BITS_UNSIGNED: + case MDS_4_BITS_UNSIGNED: + case MDS_8_BITS_UNSIGNED: *addr = operand->unsigned_imm.val8; break; - case AOS_16_BITS_UNSIGNED: + case MDS_16_BITS_UNSIGNED: *addr = operand->unsigned_imm.val16; break; - case AOS_32_BITS_UNSIGNED: + case MDS_32_BITS_UNSIGNED: *addr = operand->unsigned_imm.val32; break; - case AOS_64_BITS_UNSIGNED: + case MDS_64_BITS_UNSIGNED: *addr = operand->unsigned_imm.val64; break; default: @@ -572,35 +589,36 @@ bool g_imm_operand_to_size_t(const GImmOperand *operand, size_t *value, bool *ne switch (operand->size) { - case AOS_8_BITS_UNSIGNED: + case MDS_4_BITS_UNSIGNED: + case MDS_8_BITS_UNSIGNED: result = (sizeof(size_t) >= 1); if (result) *value = operand->unsigned_imm.val8; break; - case AOS_16_BITS_UNSIGNED: + case MDS_16_BITS_UNSIGNED: result = (sizeof(size_t) >= 2); if (result) *value = operand->unsigned_imm.val16; break; - case AOS_32_BITS_UNSIGNED: + case MDS_32_BITS_UNSIGNED: result = (sizeof(size_t) >= 4); if (result) *value = operand->unsigned_imm.val32; break; - case AOS_64_BITS_UNSIGNED: + case MDS_64_BITS_UNSIGNED: result = (sizeof(size_t) >= 8); if (result) *value = operand->unsigned_imm.val64; break; - case AOS_8_BITS_SIGNED: + case MDS_8_BITS_SIGNED: result = (sizeof(size_t) >= 1); if (result) *value = (*negative ? -1 : 1 ) * operand->signed_imm.val8; break; - case AOS_16_BITS_SIGNED: + case MDS_16_BITS_SIGNED: result = (sizeof(size_t) >= 2); if (result) *value = (*negative ? -1 : 1 ) * operand->signed_imm.val16; break; - case AOS_32_BITS_SIGNED: + case MDS_32_BITS_SIGNED: result = (sizeof(size_t) >= 4); if (result) *value = (*negative ? -1 : 1 ) * operand->signed_imm.val32; break; - case AOS_64_BITS_SIGNED: + case MDS_64_BITS_SIGNED: result = (sizeof(size_t) >= 8); if (result) *value = (*negative ? -1 : 1 ) * operand->signed_imm.val64; break; @@ -636,35 +654,36 @@ bool g_imm_operand_to_off_t(const GImmOperand *operand, off_t *value, bool *nega switch (operand->size) { - case AOS_8_BITS_UNSIGNED: + case MDS_4_BITS_UNSIGNED: + case MDS_8_BITS_UNSIGNED: result = (sizeof(off_t) >= 1); if (result) *value = operand->unsigned_imm.val8; break; - case AOS_16_BITS_UNSIGNED: + case MDS_16_BITS_UNSIGNED: result = (sizeof(off_t) >= 2); if (result) *value = operand->unsigned_imm.val16; break; - case AOS_32_BITS_UNSIGNED: + case MDS_32_BITS_UNSIGNED: result = (sizeof(off_t) >= 4); if (result) *value = operand->unsigned_imm.val32; break; - case AOS_64_BITS_UNSIGNED: + case MDS_64_BITS_UNSIGNED: result = (sizeof(off_t) >= 8); if (result) *value = operand->unsigned_imm.val64; break; - case AOS_8_BITS_SIGNED: + case MDS_8_BITS_SIGNED: result = (sizeof(off_t) >= 1); if (result) *value = (*negative ? -1 : 1 ) * operand->signed_imm.val8; break; - case AOS_16_BITS_SIGNED: + case MDS_16_BITS_SIGNED: result = (sizeof(off_t) >= 2); if (result) *value = (*negative ? -1 : 1 ) * operand->signed_imm.val16; break; - case AOS_32_BITS_SIGNED: + case MDS_32_BITS_SIGNED: result = (sizeof(off_t) >= 4); if (result) *value = (*negative ? -1 : 1 ) * operand->signed_imm.val32; break; - case AOS_64_BITS_SIGNED: + case MDS_64_BITS_SIGNED: result = (sizeof(off_t) >= 8); if (result) *value = (*negative ? -1 : 1 ) * operand->signed_imm.val64; break; diff --git a/src/arch/immediate.h b/src/arch/immediate.h index 63ce970..1e66d54 100644 --- a/src/arch/immediate.h +++ b/src/arch/immediate.h @@ -52,10 +52,12 @@ typedef struct _GImmOperandClass GImmOperandClass; GType g_imm_operand_get_type(void); /* Crée un opérande réprésentant une valeur numérique. */ -GArchOperand *g_imm_operand_new_from_data(MemoryDataSize, const bin_t *, off_t *, off_t, SourceEndian); +GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize, const bin_t *, off_t *, off_t, bool *, SourceEndian); + +#define g_imm_operand_new_from_data(size, data, pos, len, endian) _g_imm_operand_new_from_data(size, data, pos, len, NULL, endian) /* Crée un opérande réprésentant une valeur numérique. */ -GArchOperand *g_imm_operand_new_from_value(AsmOperandSize, ...); +GArchOperand *g_imm_operand_new_from_value(MemoryDataSize, ...); /* Indique le signe d'une valeur immédiate. */ bool g_imm_operand_is_negative(const GImmOperand *); diff --git a/src/arch/jvm/processor.c b/src/arch/jvm/processor.c index 034b864..e9dffe2 100644 --- a/src/arch/jvm/processor.c +++ b/src/arch/jvm/processor.c @@ -46,10 +46,10 @@ struct _GJvmProcessorClass }; -/* Initialise la classe des lignes de descriptions initiales. */ +/* Initialise la classe des processeurs de JVM. */ static void g_jvm_processor_class_init(GJvmProcessorClass *); -/* Initialise la classe des lignes de descriptions initiales. */ +/* Initialise une instance de processeur de JVM. */ static void g_jvm_processor_init(GJvmProcessor *); /* Décode une instruction dans un flux de données. */ @@ -65,7 +65,7 @@ G_DEFINE_TYPE(GJvmProcessor, g_jvm_processor, G_TYPE_ARCH_PROCESSOR); * * * Paramètres : klass = classe à initialiser. * * * -* Description : Initialise la classe des lignes de descriptions initiales. * +* Description : Initialise la classe des processeurs de JVM. * * * * Retour : - * * * @@ -83,7 +83,7 @@ static void g_jvm_processor_class_init(GJvmProcessorClass *klass) * * * Paramètres : proc = instance à initialiser. * * * -* Description : Initialise la classe des lignes de descriptions initiales. * +* Description : Initialise une instance de processeur de JVM. * * * * Retour : - * * * diff --git a/src/arch/processor.c b/src/arch/processor.c index 103296a..9bea205 100644 --- a/src/arch/processor.c +++ b/src/arch/processor.c @@ -42,6 +42,7 @@ #include "artificial.h" +#include "dalvik/processor.h" #include "jvm/processor.h" #include "mips/processor.h" #include "x86/processor.h" @@ -209,6 +210,7 @@ GArchInstruction *g_arch_processor_decode_instruction(const GArchProcessor *proc bool init_all_processors(void) { + _processors_list[APT_DALVIK] = g_dalvik_processor_new(); _processors_list[APT_JVM] = g_jvm_processor_new(); _processors_list[APT_MIPS] = g_mips_processor_new(); _processors_list[APT_386] = g_x86_processor_new(); @@ -255,6 +257,10 @@ GArchProcessor *get_arch_processor_from_format(const GExeFormat *format) switch (g_exe_format_get_target_machine(format)) { + case FTM_DALVIK: + result = get_arch_processor_for_type(APT_DALVIK); + break; + case FTM_JVM: result = get_arch_processor_for_type(APT_JVM); break; diff --git a/src/arch/processor.h b/src/arch/processor.h index ea954cc..063a3ba 100644 --- a/src/arch/processor.h +++ b/src/arch/processor.h @@ -66,6 +66,7 @@ GArchInstruction *g_arch_processor_decode_instruction(const GArchProcessor *, co /* Type de processeurs disponibles */ typedef enum _ArchProcessorType { + APT_DALVIK, /* Dalvik Virtual Machine */ APT_JVM, /* Java Virtual Machine */ APT_MIPS, /* Mips 32 ou 64 bits */ APT_386, /* Intel 80386 */ diff --git a/src/arch/x86/opcodes.h b/src/arch/x86/opcodes.h index 5a6d69f..92b6124 100644 --- a/src/arch/x86/opcodes.h +++ b/src/arch/x86/opcodes.h @@ -25,8 +25,8 @@ #define _ARCH_X86_OPCODES_H -#include "processor.h" #include "instruction.h" +#include "processor.h" diff --git a/src/arch/x86/operand.c b/src/arch/x86/operand.c index 849e54d..b3f0997 100644 --- a/src/arch/x86/operand.c +++ b/src/arch/x86/operand.c @@ -29,7 +29,6 @@ #include <stdio.h> -#include "../operand.h" #include "../operand-int.h" #include "../../common/extstr.h" @@ -92,7 +91,7 @@ static void g_x86_register_operand_init(GX86RegisterOperand *); /* Ajoute du texte simple à un fichier ouvert en écriture. */ static void g_x86_register_operand_add_text(const GX86RegisterOperand *, GRenderingOptions *, MainRendering, FILE *); -/*Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ +/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ static void g_x86_register_operand_to_buffer(const GX86RegisterOperand *, GBufferLine *, GRenderingOptions *); diff --git a/src/arch/x86/processor.h b/src/arch/x86/processor.h index 1014d11..a04d880 100644 --- a/src/arch/x86/processor.h +++ b/src/arch/x86/processor.h @@ -26,7 +26,7 @@ #include "../processor.h" -#include "instruction.h" +#include "instruction.h" /* FIXME : remme */ |