From 6511f2fe4551c2ea231115d6c659c99e15b3a23b Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Wed, 19 May 2010 23:30:05 +0000 Subject: Added support for a few more Dalvik instructions. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@160 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 27 ++++ src/arch/dalvik/Makefile.am | 5 + src/arch/dalvik/instruction.c | 55 ++++++--- src/arch/dalvik/instruction.h | 25 +++- src/arch/dalvik/op_add.c | 65 ++++++++++ src/arch/dalvik/op_iget.c | 281 ++++++++++++++++++++++++++++++++++++++++++ src/arch/dalvik/op_iput.c | 281 ++++++++++++++++++++++++++++++++++++++++++ src/arch/dalvik/op_move.c | 65 ++++++++++ src/arch/dalvik/op_new.c | 65 ++++++++++ src/arch/dalvik/opcodes.h | 84 +++++++++++-- src/arch/dalvik/operand.c | 25 ++++ src/arch/dalvik/operand.h | 3 + src/arch/dalvik/processor.c | 54 +++++--- 13 files changed, 993 insertions(+), 42 deletions(-) create mode 100644 src/arch/dalvik/op_add.c create mode 100644 src/arch/dalvik/op_iget.c create mode 100644 src/arch/dalvik/op_iput.c create mode 100644 src/arch/dalvik/op_move.c create mode 100644 src/arch/dalvik/op_new.c diff --git a/ChangeLog b/ChangeLog index 51280b3..08bda34 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +10-05-20 Cyrille Bagard + + * src/arch/dalvik/instruction.c: + * src/arch/dalvik/instruction.h: + Add support for a few more Dalvik instructions. + + * src/arch/dalvik/Makefile.am: + Add the op_add.c, op_iget.c, op_iput.c, op_move.c and op_new.c files + to libarchdalvik_la_SOURCES. + + * src/arch/dalvik/op_add.c: + New entry: add support for one more Dalvik instruction. + + * src/arch/dalvik/opcodes.h: + * src/arch/dalvik/operand.c: + * src/arch/dalvik/operand.h: + Add support for a few more Dalvik instructions. + + * src/arch/dalvik/op_iget.c: + * src/arch/dalvik/op_iput.c: + * src/arch/dalvik/op_move.c: + * src/arch/dalvik/op_new.c: + New entries: add support for a few more Dalvik instructions. + + * src/arch/dalvik/processor.c: + Add support for a few more Dalvik instructions. + 10-05-19 Cyrille Bagard * Makefile.am: diff --git a/src/arch/dalvik/Makefile.am b/src/arch/dalvik/Makefile.am index 855d287..c8c0145 100644 --- a/src/arch/dalvik/Makefile.am +++ b/src/arch/dalvik/Makefile.am @@ -3,9 +3,14 @@ noinst_LTLIBRARIES = libarchdalvik.la libarchdalvik_la_SOURCES = \ instruction.h instruction.c \ + op_add.c \ op_const.c \ + op_iget.c \ op_invoke.c \ + op_iput.c \ + op_move.c \ op_mul.c \ + op_new.c \ op_nop.c \ op_ret.c \ op_sget.c \ diff --git a/src/arch/dalvik/instruction.c b/src/arch/dalvik/instruction.c index 8bd4894..f485cec 100644 --- a/src/arch/dalvik/instruction.c +++ b/src/arch/dalvik/instruction.c @@ -68,36 +68,59 @@ typedef struct _dalvik_instruction static dalvik_instruction _instructions[DOP_COUNT] = { - [DOP_NOP] = { 0x00, "nop" }, + [DOP_NOP] = { 0x00, "nop" }, - [DOP_CONST_4] = { 0x12, "const/4" }, - [DOP_CONST_16] = { 0x13, "const/16" }, + [DOP_MOVE_RESULT_OBJECT] = { 0x0c, "move-result-object" }, + [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_CONST_HIGH16] = { 0x15, "const/high16" }, + [DOP_CONST_STRING] = { 0x1a, "const-string" }, - [DOP_RETURN_VOID] = { 0x0e, "return-void" }, - [DOP_RETURN] = { 0x0f, "return" }, + [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_NEW_INSTANCE] = { 0x22, "new-instance" }, - [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_IGET] = { 0x52, "iget" }, + [DOP_IGET_WIDE] = { 0x53, "iget-wide" }, + [DOP_IGET_OBJECT] = { 0x54, "iget-object" }, + [DOP_IGET_BOOLEAN] = { 0x55, "iget-boolean" }, + [DOP_IGET_BYTE] = { 0x56, "iget-byte" }, + [DOP_IGET_CHAR] = { 0x57, "iget-char" }, + [DOP_IGET_SHORT] = { 0x58, "iget-short" }, + [DOP_IPUT] = { 0x59, "iput" }, + [DOP_IPUT_WIDE] = { 0x5a, "iput-wide" }, + [DOP_IPUT_OBJECT] = { 0x5b, "iput-object" }, + [DOP_IPUT_BOOLEAN] = { 0x5c, "iput-boolean" }, + [DOP_IPUT_BYTE] = { 0x5d, "iput-byte" }, + [DOP_IPUT_CHAR] = { 0x5e, "iput-char" }, + [DOP_IPUT_SHORT] = { 0x5f, "iput-short" }, + [DOP_SGET] = { 0x60, "sget" }, + [DOP_SGET_WIDE] = { 0x61, "sget-wide" }, + [DOP_SGET_OBJECT] = { 0x62, "sget-object" }, - [DOP_MUL_INT_2ADDR] = { 0xb2, "mul-int/2addr" } + [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" }, + + + + [DOP_ADD_INT_LIT8] = { 0xd8, "add-int/lit8" } }; diff --git a/src/arch/dalvik/instruction.h b/src/arch/dalvik/instruction.h index 2bd77a3..e5a3e69 100644 --- a/src/arch/dalvik/instruction.h +++ b/src/arch/dalvik/instruction.h @@ -29,13 +29,15 @@ - - /* Enumération de tous les opcodes */ typedef enum _DalvikOpcodes { DOP_NOP, /* nop (0x00) */ + + DOP_MOVE_RESULT_OBJECT, /* move-result-object (0x0c) */ + + DOP_CONST_4, /* const/4 (0x12) */ DOP_CONST_16, /* const/16 (0x13) */ @@ -48,6 +50,23 @@ typedef enum _DalvikOpcodes DOP_RETURN, /* return (0x0f) */ + DOP_NEW_INSTANCE, /* new-instance (0x22) */ + + + DOP_IGET, /* iget (0x52) */ + DOP_IGET_WIDE, /* iget-wide (0x53) */ + DOP_IGET_OBJECT, /* iget-object (0x54) */ + DOP_IGET_BOOLEAN, /* iget-boolean (0x55) */ + DOP_IGET_BYTE, /* iget-byte (0x56) */ + DOP_IGET_CHAR, /* iget-char (0x57) */ + DOP_IGET_SHORT, /* iget-short (0x58) */ + DOP_IPUT, /* iput (0x59) */ + DOP_IPUT_WIDE, /* iput-wide (0x5a) */ + DOP_IPUT_OBJECT, /* iput-object (0x5b) */ + DOP_IPUT_BOOLEAN, /* iput-boolean (0x5c) */ + DOP_IPUT_BYTE, /* iput-byte (0x5d) */ + DOP_IPUT_CHAR, /* iput-char (0x5e) */ + DOP_IPUT_SHORT, /* iput-short (0x5f) */ DOP_SGET, /* sget (0x60) */ DOP_SGET_WIDE, /* sget-wide (0x61) */ DOP_SGET_OBJECT, /* sget-object (0x62) */ @@ -61,6 +80,8 @@ typedef enum _DalvikOpcodes DOP_MUL_INT_2ADDR, /* mul-int/2addr (0xb2) */ + DOP_ADD_INT_LIT8, /* add-int/lit8 (0xd8) */ + DOP_COUNT } DalvikOpcodes; diff --git a/src/arch/dalvik/op_add.c b/src/arch/dalvik/op_add.c new file mode 100644 index 0000000..92ba818 --- /dev/null +++ b/src/arch/dalvik/op_add.c @@ -0,0 +1,65 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_add.c - décodage des opérations d'addition + * + * Copyright (C) 2010 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "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 'add-int/lit8'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_add_int_lit8(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_ADD_INT_LIT8); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_22B)) + { + g_object_unref(G_OBJECT(result)); + return NULL; + } + + return result; + +} diff --git a/src/arch/dalvik/op_iget.c b/src/arch/dalvik/op_iget.c new file mode 100644 index 0000000..e0e1e0f --- /dev/null +++ b/src/arch/dalvik/op_iget.c @@ -0,0 +1,281 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_iget.c - décodage des chargements de champs d'instance + * + * Copyright (C) 2010 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "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 'iget'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_iget(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_IGET); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_22C | 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 'iget-boolean'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_iget_boolean(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_IGET_BOOLEAN); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_22C | 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 'iget-byte'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_iget_byte(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_IGET_BYTE); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_22C | 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 'iget-char'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_iget_char(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_IGET_CHAR); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_22C | 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 'iget-object'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_iget_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_IGET_OBJECT); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_22C | 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 'iget-short'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_iget_short(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_IGET_SHORT); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_22C | 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 'iget-wide'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_iget_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_IGET_WIDE); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_22C | DALVIK_OP_POOL(DPT_FIELD))) + { + g_object_unref(G_OBJECT(result)); + return NULL; + } + + return result; + +} diff --git a/src/arch/dalvik/op_iput.c b/src/arch/dalvik/op_iput.c new file mode 100644 index 0000000..e221c3b --- /dev/null +++ b/src/arch/dalvik/op_iput.c @@ -0,0 +1,281 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_iput.c - décodage des enregistrements de champs d'instance + * + * Copyright (C) 2010 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "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 'iput'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_iput(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_IPUT); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_22C | 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 'iput-boolean'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_iput_boolean(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_IPUT_BOOLEAN); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_22C | 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 'iput-byte'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_iput_byte(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_IPUT_BYTE); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_22C | 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 'iput-char'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_iput_char(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_IPUT_CHAR); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_22C | 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 'iput-object'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_iput_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_IPUT_OBJECT); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_22C | 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 'iput-short'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_iput_short(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_IPUT_SHORT); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_22C | 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 'iput-wide'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_iput_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_IPUT_WIDE); + + endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc)); + + if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_22C | DALVIK_OP_POOL(DPT_FIELD))) + { + g_object_unref(G_OBJECT(result)); + return NULL; + } + + return result; + +} diff --git a/src/arch/dalvik/op_move.c b/src/arch/dalvik/op_move.c new file mode 100644 index 0000000..eb152a3 --- /dev/null +++ b/src/arch/dalvik/op_move.c @@ -0,0 +1,65 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_move.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 . + */ + + +#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 'move-result-object'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_move_result_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_MOVE_RESULT_OBJECT); + + 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; + +} diff --git a/src/arch/dalvik/op_new.c b/src/arch/dalvik/op_new.c new file mode 100644 index 0000000..709871c --- /dev/null +++ b/src/arch/dalvik/op_new.c @@ -0,0 +1,65 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_new.c - décodage des créations de nouvelles instances + * + * Copyright (C) 2010 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "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 'new-instance'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *dalvik_read_instr_new_instance(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_NEW_INSTANCE); + + 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_TYPE))) + { + g_object_unref(G_OBJECT(result)); + return NULL; + } + + return result; + +} diff --git a/src/arch/dalvik/opcodes.h b/src/arch/dalvik/opcodes.h index 3a90d6f..2389270 100644 --- a/src/arch/dalvik/opcodes.h +++ b/src/arch/dalvik/opcodes.h @@ -35,8 +35,8 @@ typedef GArchInstruction * (* dalvik_read_instr) (const bin_t *, off_t *, off_t, -/* 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 'add-int/lit8'. */ +GArchInstruction *dalvik_read_instr_add_int_lit8(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); @@ -63,17 +63,28 @@ GArchInstruction *dalvik_read_instr_const_string(const bin_t *, off_t *, off_t, +/* Décode une instruction de type 'iget'. */ +GArchInstruction *dalvik_read_instr_iget(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); +/* Décode une instruction de type 'iget-boolean'. */ +GArchInstruction *dalvik_read_instr_iget_boolean(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); +/* Décode une instruction de type 'iget-byte'. */ +GArchInstruction *dalvik_read_instr_iget_byte(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 'iget-char'. */ +GArchInstruction *dalvik_read_instr_iget_char(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + +/* Décode une instruction de type 'iget-object'. */ +GArchInstruction *dalvik_read_instr_iget_object(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + +/* Décode une instruction de type 'iget-short'. */ +GArchInstruction *dalvik_read_instr_iget_short(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + +/* Décode une instruction de type 'iget-wide'. */ +GArchInstruction *dalvik_read_instr_iget_wide(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 *); @@ -94,10 +105,46 @@ GArchInstruction *dalvik_read_instr_invoke_virtual(const bin_t *, off_t *, off_t + +/* Décode une instruction de type 'iput'. */ +GArchInstruction *dalvik_read_instr_iput(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + +/* Décode une instruction de type 'iput-boolean'. */ +GArchInstruction *dalvik_read_instr_iput_boolean(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + +/* Décode une instruction de type 'iput-byte'. */ +GArchInstruction *dalvik_read_instr_iput_byte(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + +/* Décode une instruction de type 'iput-char'. */ +GArchInstruction *dalvik_read_instr_iput_char(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + +/* Décode une instruction de type 'iput-object'. */ +GArchInstruction *dalvik_read_instr_iput_object(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + +/* Décode une instruction de type 'iput-short'. */ +GArchInstruction *dalvik_read_instr_iput_short(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + +/* Décode une instruction de type 'iput-wide'. */ +GArchInstruction *dalvik_read_instr_iput_wide(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); + + + + + +/* Décode une instruction de type 'move-result-object'. */ +GArchInstruction *dalvik_read_instr_move_result_object(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 'new-instance'. */ +GArchInstruction *dalvik_read_instr_new_instance(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 'return'. */ GArchInstruction *dalvik_read_instr_return(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *); @@ -107,4 +154,25 @@ GArchInstruction *dalvik_read_instr_return_void(const bin_t *, off_t *, off_t, v + + + + +/* 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 *); + + + + + + + + + #endif /* _ARCH_DALVIK_OPCODES_H */ diff --git a/src/arch/dalvik/operand.c b/src/arch/dalvik/operand.c index 7b58b1d..7e8bf43 100644 --- a/src/arch/dalvik/operand.c +++ b/src/arch/dalvik/operand.c @@ -180,6 +180,7 @@ typedef enum _DalvikOperandID DOI_REGISTER_8, DOI_IMMEDIATE_4, + DOI_IMMEDIATE_8, DOI_IMMEDIATE_16, DOI_IMMEDIATE_H16, @@ -916,6 +917,24 @@ static bool dalvik_read_basic_operands(GArchInstruction *instr, const bin_t *dat }; break; + case DALVIK_OPT_22B: + types = (DalvikOperandID []) { + DOI_REGISTER_8, + DOI_REGISTER_8, + DOI_IMMEDIATE_8, + DOI_INVALID + }; + break; + + case DALVIK_OPT_22C: + types = (DalvikOperandID []) { + DOI_REGISTER_4, + DOI_REGISTER_4, + DOI_POOL_CONST, + DOI_INVALID + }; + break; + default: types = (DalvikOperandID []) { DOI_INVALID @@ -942,6 +961,10 @@ static bool dalvik_read_basic_operands(GArchInstruction *instr, const bin_t *dat op = _g_imm_operand_new_from_data(MDS_4_BITS, data, pos, len, low, endian); break; + case DOI_IMMEDIATE_8: + op = g_imm_operand_new_from_data(MDS_8_BITS, data, pos, len, endian); + break; + case DOI_IMMEDIATE_16: op = g_imm_operand_new_from_data(MDS_16_BITS, data, pos, len, endian); break; @@ -1124,6 +1147,8 @@ bool dalvik_read_operands(GArchInstruction *instr, const bin_t *data, off_t *pos case DALVIK_OPT_21C: case DALVIK_OPT_21H: case DALVIK_OPT_21S: + case DALVIK_OPT_22B: + case DALVIK_OPT_22C: result = dalvik_read_basic_operands(instr, data, pos, len, &low, endian, model); break; diff --git a/src/arch/dalvik/operand.h b/src/arch/dalvik/operand.h index 4045c5f..fd26e96 100644 --- a/src/arch/dalvik/operand.h +++ b/src/arch/dalvik/operand.h @@ -196,6 +196,9 @@ typedef enum _DalvikOperandType DALVIK_OPT_21S = DALVIK_OP_LEN(2) | DALVIK_OP_REG(1) | 'S', + DALVIK_OPT_22B = DALVIK_OP_LEN(2) | DALVIK_OP_REG(2) | 'B', + DALVIK_OPT_22C = DALVIK_OP_LEN(2) | DALVIK_OP_REG(2) | 'C', + DALVIK_OPT_35C = DALVIK_OP_LEN(3) | DALVIK_OP_REG(5) | 'C' diff --git a/src/arch/dalvik/processor.c b/src/arch/dalvik/processor.c index 7bf469e..1e54146 100644 --- a/src/arch/dalvik/processor.c +++ b/src/arch/dalvik/processor.c @@ -151,37 +151,59 @@ static GArchInstruction *g_dalvik_processor_decode_instruction(const GDalvikProc static const dalvik_read_instr decodings[DOP_COUNT] = { - [DOP_NOP] = dalvik_read_instr_nop, + [DOP_NOP] = dalvik_read_instr_nop, - [DOP_CONST_4] = dalvik_read_instr_const_4, - [DOP_CONST_16] = dalvik_read_instr_const_16, + [DOP_MOVE_RESULT_OBJECT] = dalvik_read_instr_move_result_object, - [DOP_CONST_HIGH16] = dalvik_read_instr_const_high16, + [DOP_CONST_4] = dalvik_read_instr_const_4, + [DOP_CONST_16] = dalvik_read_instr_const_16, - [DOP_CONST_STRING] = dalvik_read_instr_const_string, + [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_RETURN_VOID] = dalvik_read_instr_return_void, + [DOP_RETURN] = dalvik_read_instr_return, + [DOP_NEW_INSTANCE] = dalvik_read_instr_new_instance, - [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_IGET] = dalvik_read_instr_iget, + [DOP_IGET_WIDE] = dalvik_read_instr_iget_wide, + [DOP_IGET_OBJECT] = dalvik_read_instr_iget_object, + [DOP_IGET_BOOLEAN] = dalvik_read_instr_iget_boolean, + [DOP_IGET_BYTE] = dalvik_read_instr_iget_byte, + [DOP_IGET_CHAR] = dalvik_read_instr_iget_char, + [DOP_IGET_SHORT] = dalvik_read_instr_iget_short, + [DOP_IPUT] = dalvik_read_instr_iput, + [DOP_IPUT_WIDE] = dalvik_read_instr_iput_wide, + [DOP_IPUT_OBJECT] = dalvik_read_instr_iput_object, + [DOP_IPUT_BOOLEAN] = dalvik_read_instr_iput_boolean, + [DOP_IPUT_BYTE] = dalvik_read_instr_iput_byte, + [DOP_IPUT_CHAR] = dalvik_read_instr_iput_char, + [DOP_IPUT_SHORT] = dalvik_read_instr_iput_short, + [DOP_SGET] = dalvik_read_instr_sget, + [DOP_SGET_WIDE] = dalvik_read_instr_sget_wide, + [DOP_SGET_OBJECT] = dalvik_read_instr_sget_object, - [DOP_MUL_INT_2ADDR] = dalvik_read_instr_mul_int_2addr + + [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, + + + [DOP_ADD_INT_LIT8] = dalvik_read_instr_add_int_lit8 }; -- cgit v0.11.2-87-g4458