diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2011-12-23 15:49:56 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2011-12-23 15:49:56 (GMT) |
commit | 55c034aa3d975320dbaa7e643e68289732386eec (patch) | |
tree | 2011c2a619197eb8e17b5cbb2a3fe4dd35986e6b /src/arch/dalvik/processor.c | |
parent | a6f7f152b62dd79ec492c0b3f51a2b5d19732d27 (diff) |
Decoded Dalvik pseudo-instructions properly.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@216 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/arch/dalvik/processor.c')
-rw-r--r-- | src/arch/dalvik/processor.c | 83 |
1 files changed, 69 insertions, 14 deletions
diff --git a/src/arch/dalvik/processor.c b/src/arch/dalvik/processor.c index 2f56f87..7925c55 100644 --- a/src/arch/dalvik/processor.c +++ b/src/arch/dalvik/processor.c @@ -27,7 +27,8 @@ #include "context.h" #include "instruction.h" #include "opcodes.h" -#include "specins.h" +#include "pseudo/fill.h" +#include "pseudo/switch.h" #include "../processor-int.h" @@ -57,6 +58,9 @@ static void g_dalvik_processor_init(GDalvikProcessor *); /* Fournit un contexte pour l'exécution du processeur Dalvik. */ static GDalvikContext *g_dalvik_processor_get_context(const GDalvikProcessor *); +/* 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); + /* 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); @@ -157,6 +161,58 @@ static GDalvikContext *g_dalvik_processor_get_context(const GDalvikProcessor *pr /****************************************************************************** * * * 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 pseudo-instruction dans un flux de données. * +* * +* Retour : Instruction mise en place ou NULL si aucune trouvée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GArchInstruction *g_dalvik_guess_pseudo_instruction(const GDalvikProcessor *proc, const bin_t *data, off_t *pos, off_t len, 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, len, SRE_LITTLE)) + return NULL; + + switch (ident) + { + case DPO_PACKED_SWITCH: + case DPO_SPARSE_SWITCH: + result = g_dalvik_switch_instr_new(data, pos, len, addr, proc); + break; + + case DPO_FILL_ARRAY_DATA: + result = g_dalvik_fill_instr_new(data, pos, len, 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] * @@ -341,22 +397,21 @@ static GArchInstruction *g_dalvik_processor_decode_instruction(const GDalvikProc }; - /* Continuité d'une zone spéciale... */ - if (g_dalvik_context_have_to_skip(ctx, addr)) - return SKIPPED_INSTR; - - /* Début d'une nouvelle zone spéciale... */ - if (g_dalvik_guess_special_instruction(ctx, data, *pos, len, addr)) - return SKIPPED_INSTR; - - /* Ou instruction classique */ + /* Pseudo-instruction... */ + result = g_dalvik_guess_pseudo_instruction(proc, data, pos, len, addr); - id = dalvik_guess_next_instruction(data, *pos, len); + /* ... ou instruction classique */ + if (result == NULL) + { + id = dalvik_guess_next_instruction(data, *pos, len); - if (id != DOP_COUNT) (*pos)++; + if (id != DOP_COUNT) + { + (*pos)++; + result = decodings[id](data, pos, len, addr, proc); + } - if (id == DOP_COUNT) result = NULL; - else result = decodings[id](data, pos, len, addr, proc); + } return result; |