summaryrefslogtreecommitdiff
path: root/src/arch/dalvik/processor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/dalvik/processor.c')
-rw-r--r--src/arch/dalvik/processor.c198
1 files changed, 106 insertions, 92 deletions
diff --git a/src/arch/dalvik/processor.c b/src/arch/dalvik/processor.c
index fdfb38d..9fe7253 100644
--- a/src/arch/dalvik/processor.c
+++ b/src/arch/dalvik/processor.c
@@ -24,12 +24,16 @@
#include "processor.h"
+#include <assert.h>
+
+
#include "context.h"
#include "instruction.h"
#include "opcodes/opcodes.h"
#include "pseudo/fill.h"
#include "pseudo/switch.h"
#include "../processor-int.h"
+#include "../../format/dex/dex.h"
@@ -67,11 +71,12 @@ static GDalvikContext *g_dalvik_processor_get_context(const GDalvikProcessor *);
/* Fournit un contexte pour la décompilation Dalvik. */
static GDalvikDContext *g_dalvik_processor_get_decomp_context(const GDalvikProcessor *);
+/* Décode une instruction dans un flux de données. */
+static GArchInstruction *g_dalvik_processor_disassemble(const GArchProcessor *, GDalvikContext *, const GBinContent *, vmpa2t *, GExeFormat *);
+
/* Décode une pseudo-instruction dans un flux de données. */
-static GArchInstruction *g_dalvik_guess_pseudo_instruction(const GDalvikProcessor *, const bin_t *, off_t *, off_t, vmpa_t);
+static GArchInstruction *g_dalvik_processor_disassemble_pseudo(const GArchProcessor *, GDalvikContext *, const GBinContent *, vmpa2t *, uint8_t);
-/* Décode une instruction dans un flux de données. */
-static GArchInstruction *g_dalvik_processor_decode_instruction(const GDalvikProcessor *, GDalvikContext *, const bin_t *, off_t *, off_t, vmpa_t, GDexFormat *);
/* Indique le type défini par la GLib pour le processeur DALVIK. */
@@ -103,7 +108,7 @@ static void g_dalvik_processor_class_init(GDalvikProcessorClass *klass)
proc = G_ARCH_PROCESSOR_CLASS(klass);
- proc->decode = (decode_instruction_fc)g_dalvik_processor_decode_instruction;
+ proc->disassemble = (disass_instr_fc)g_dalvik_processor_disassemble;
}
@@ -237,90 +242,37 @@ static GDalvikDContext *g_dalvik_processor_get_decomp_context(const GDalvikProce
/******************************************************************************
* *
-* Paramètres : proc = architecture visée par la procédure. *
-* data = flux de données à analyser. *
-* pos = position courante dans ce flux. [OUT] *
-* end = limite des données à analyser. *
-* addr = adresse virtuelle de l'instruction. *
+* Paramètres : proc = architecture visée par la procédure. *
+* ctx = contexte lié à l'exécution du processeur. *
+* content = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* format = format du fichier contenant le code. *
* *
-* Description : Décode une pseudo-instruction dans un flux de données. *
+* Description : Désassemble une instruction dans un flux de données. *
* *
-* Retour : Instruction mise en place ou NULL si aucune trouvée. *
+* Retour : Instruction mise en place ou NULL en cas d'échec. *
* *
* Remarques : - *
* *
******************************************************************************/
-static GArchInstruction *g_dalvik_guess_pseudo_instruction(const GDalvikProcessor *proc, const bin_t *data, off_t *pos, off_t end, vmpa_t addr)
-{
- GArchInstruction *result; /* Instruction à renvoyer */
- off_t tmp; /* Position modifiable */
- uint16_t ident; /* Valeur lue dans le code */
-
- /* Vérification astucieuse et rapide...*/
- if (data[*pos] != 0x00 /* DOP_NOP */) return NULL;
-
- tmp = *pos;
-
- if (!read_u16(&ident, data, &tmp, end, SRE_LITTLE))
- return NULL;
-
- switch (ident)
- {
- case DPO_PACKED_SWITCH:
- case DPO_SPARSE_SWITCH:
- result = g_dalvik_switch_instr_new(data, pos, end, addr, proc);
- break;
-
- case DPO_FILL_ARRAY_DATA:
- result = g_dalvik_fill_instr_new(data, pos, end, addr, proc);
- break;
-
- default:
- result = NULL;
- break;
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : proc = architecture visée par la procédure. *
-* ctx = contexte lié à l'exécution du processeur. *
-* data = flux de données à analyser. *
-* pos = position courante dans ce flux. [OUT] *
-* end = limite des données à analyser. *
-* addr = adresse virtuelle de l'instruction. *
-* format = format du fichier contenant le code. *
-* *
-* 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, GDalvikContext *ctx, const bin_t *data, off_t *pos, off_t end, vmpa_t addr, GDexFormat *format)
+static GArchInstruction *g_dalvik_processor_disassemble(const GArchProcessor *proc, GDalvikContext *ctx, const GBinContent *content, vmpa2t *pos, GExeFormat *format)
{
GArchInstruction *result; /* Instruction à renvoyer */
+ uint8_t raw8; /* Donnée de 8 bits à analyser */
DalvikOpcodes id; /* Identifiant d'instruction */
- static const dalvik_read_instr decodings[DOP_COUNT] = {
+ static const disass_instr_fc decodings[DOP_COUNT] = {
[DOP_NOP] = dalvik_read_instr_nop,
[DOP_MOVE] = dalvik_read_instr_move,
- [DOP_MOVE_FROM_16] = dalvik_read_instr_move_from_16,
+ [DOP_MOVE_FROM_16] = dalvik_read_instr_move_from16,
[DOP_MOVE_16] = dalvik_read_instr_move_16,
[DOP_MOVE_WIDE] = dalvik_read_instr_move_wide,
- [DOP_MOVE_WIDE_FROM_16] = dalvik_read_instr_move_wide_from_16,
+ [DOP_MOVE_WIDE_FROM_16] = dalvik_read_instr_move_wide_from16,
[DOP_MOVE_WIDE_16] = dalvik_read_instr_move_wide_16,
[DOP_MOVE_OBJECT] = dalvik_read_instr_move_object,
- [DOP_MOVE_OBJECT_FROM_16] = dalvik_read_instr_move_object_from_16,
+ [DOP_MOVE_OBJECT_FROM_16] = dalvik_read_instr_move_object_from16,
[DOP_MOVE_OBJECT_16] = dalvik_read_instr_move_object_16,
[DOP_MOVE_RESULT] = dalvik_read_instr_move_result,
[DOP_MOVE_RESULT_WIDE] = dalvik_read_instr_move_result_wide,
@@ -432,21 +384,21 @@ static GArchInstruction *g_dalvik_processor_decode_instruction(const GDalvikProc
[DOP_NOT_LONG] = dalvik_read_instr_not_long,
[DOP_NEG_FLOAT] = dalvik_read_instr_neg_float,
[DOP_NEG_DOUBLE] = dalvik_read_instr_neg_double,
- [DOP_TO_INT_LONG] = dalvik_read_instr_to_int_long,
- [DOP_TO_INT_FLOAT] = dalvik_read_instr_to_int_float,
- [DOP_TO_INT_DOUBLE] = dalvik_read_instr_to_int_double,
- [DOP_TO_LONG_INT] = dalvik_read_instr_to_long_int,
- [DOP_TO_LONG_FLOAT] = dalvik_read_instr_to_long_float,
- [DOP_TO_LONG_DOUBLE] = dalvik_read_instr_to_long_double,
- [DOP_TO_FLOAT_INT] = dalvik_read_instr_to_float_int,
- [DOP_TO_FLOAT_LONG] = dalvik_read_instr_to_float_long,
- [DOP_TO_FLOAT_DOUBLE] = dalvik_read_instr_to_float_double,
- [DOP_TO_DOUBLE_INT] = dalvik_read_instr_to_double_int,
- [DOP_TO_DOUBLE_LONG] = dalvik_read_instr_to_double_long,
- [DOP_TO_DOUBLE_FLOAT] = dalvik_read_instr_to_double_float,
- [DOP_TO_INT_BYTE] = dalvik_read_instr_to_int_byte,
- [DOP_TO_INT_CHAR] = dalvik_read_instr_to_int_char,
- [DOP_TO_INT_SHORT] = dalvik_read_instr_to_int_short,
+ [DOP_TO_INT_LONG] = dalvik_read_instr_int_to_long,
+ [DOP_TO_INT_FLOAT] = dalvik_read_instr_int_to_float,
+ [DOP_TO_INT_DOUBLE] = dalvik_read_instr_int_to_double,
+ [DOP_TO_LONG_INT] = dalvik_read_instr_long_to_int,
+ [DOP_TO_LONG_FLOAT] = dalvik_read_instr_long_to_float,
+ [DOP_TO_LONG_DOUBLE] = dalvik_read_instr_long_to_double,
+ [DOP_TO_FLOAT_INT] = dalvik_read_instr_float_to_int,
+ [DOP_TO_FLOAT_LONG] = dalvik_read_instr_float_to_long,
+ [DOP_TO_FLOAT_DOUBLE] = dalvik_read_instr_float_to_double,
+ [DOP_TO_DOUBLE_INT] = dalvik_read_instr_double_to_int,
+ [DOP_TO_DOUBLE_LONG] = dalvik_read_instr_double_to_long,
+ [DOP_TO_DOUBLE_FLOAT] = dalvik_read_instr_double_to_float,
+ [DOP_TO_INT_BYTE] = dalvik_read_instr_int_to_byte,
+ [DOP_TO_INT_CHAR] = dalvik_read_instr_int_to_char,
+ [DOP_TO_INT_SHORT] = dalvik_read_instr_int_to_short,
[DOP_ADD_INT] = dalvik_read_instr_add_int,
[DOP_SUB_INT] = dalvik_read_instr_sub_int,
[DOP_MUL_INT] = dalvik_read_instr_mul_int,
@@ -533,22 +485,84 @@ static GArchInstruction *g_dalvik_processor_decode_instruction(const GDalvikProc
};
+ if (!g_binary_content_read_u8(content, pos, &raw8))
+ return NULL;
+
/* Pseudo-instruction... */
- result = g_dalvik_guess_pseudo_instruction(proc, data, pos, end, addr);
+ result = g_dalvik_processor_disassemble_pseudo(proc, ctx, content, pos, raw8);
/* ... ou instruction classique */
if (result == NULL)
{
- id = dalvik_guess_next_instruction(data, *pos, end);
+ assert(raw8 < DOP_COUNT);
+
+ id = (DalvikOpcodes)raw8;
+
+ if (decodings[id] != NULL)
+ result = decodings[id](proc, G_PROC_CONTEXT(ctx), content, pos, format);
+
+ }
+
+ 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] *
+* end = limite des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* low8 = 8 bits de poids faible déjà lus. *
+* *
+* Description : Décode une pseudo-instruction dans un flux de données. *
+* *
+* Retour : Instruction mise en place ou NULL si aucune trouvée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GArchInstruction *g_dalvik_processor_disassemble_pseudo(const GArchProcessor *proc, GDalvikContext *ctx, const GBinContent *content, vmpa2t *pos, uint8_t low8)
+{
+ GArchInstruction *result; /* Instruction à renvoyer */
+ vmpa2t tmp; /* Position modifiable */
+ uint8_t high8; /* Nouvelle octet à venir lire */
+ uint16_t ident; /* Valeur lue dans le code */
+
+ /* Vérification astucieuse et rapide...*/
+ if (low8 != 0x00 /* DOP_NOP */)
+ return NULL;
+
+ copy_vmpa(&tmp, pos);
+
+ if (!g_binary_content_read_u8(content, pos, &high8))
+ return NULL;
+
+ ident = high8 << 8 | low8;
+
+ switch (ident)
+ {
+ case DPO_PACKED_SWITCH:
+ case DPO_SPARSE_SWITCH:
+ result = g_dalvik_switch_instr_new(ident, content, pos);
+ break;
+
+ case DPO_FILL_ARRAY_DATA:
+ result = g_dalvik_fill_instr_new(ident, content, pos);
+ break;
- if (id != DOP_COUNT)
- {
- (*pos)++;
- result = decodings[id](data, pos, end, addr, proc, format);
- }
+ default:
+ result = NULL;
+ break;
}
+ if (result != NULL)
+ copy_vmpa(pos, &tmp);
+
return result;
}