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 */  | 
