diff options
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/dalvik/instruction.c | 27 | ||||
-rw-r--r-- | src/arch/dalvik/operand.c | 99 | ||||
-rw-r--r-- | src/arch/dalvik/operand.h | 4 | ||||
-rw-r--r-- | src/arch/dalvik/operands/target.c | 17 | ||||
-rw-r--r-- | src/arch/dalvik/operands/target.h | 2 | ||||
-rw-r--r-- | src/arch/processor.c | 3 |
6 files changed, 132 insertions, 20 deletions
diff --git a/src/arch/dalvik/instruction.c b/src/arch/dalvik/instruction.c index 31f02c8..4c1dee0 100644 --- a/src/arch/dalvik/instruction.c +++ b/src/arch/dalvik/instruction.c @@ -48,6 +48,9 @@ static void g_dalvik_instruction_dispose(GDalvikInstruction *); /* Procède à la libération totale de la mémoire. */ static void g_dalvik_instruction_finalize(GDalvikInstruction *); +/* Indique l'encodage d'une instruction de façon détaillée. */ +static const char *g_dalvik_instruction_get_encoding(const GDalvikInstruction *); + /* Liste les registres lus et écrits par l'instruction. */ static void g_dalvik_instruction_get_rw_registers(const GDalvikInstruction *, GArchRegister ***, size_t *, GArchRegister ***, size_t *); @@ -373,6 +376,7 @@ static void g_dalvik_instruction_class_init(GDalvikInstructionClass *klass) instr = G_ARCH_INSTRUCTION_CLASS(klass); + instr->get_encoding = (get_instruction_encoding_fc)g_dalvik_instruction_get_encoding; instr->build_key = (build_instruction_keyword_fc)dalvik_build_instruction_keyword; } @@ -469,6 +473,29 @@ GArchInstruction *g_dalvik_instruction_new(const char *keyword) /****************************************************************************** * * +* Paramètres : instr = instruction quelconque à consulter. * +* * +* Description : Indique l'encodage d'une instruction de façon détaillée. * +* * +* Retour : Description humaine de l'encodage utilisé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const char *g_dalvik_instruction_get_encoding(const GDalvikInstruction *instr) +{ + const char *result; /* Description à retourner */ + + result = "Dalvik"; + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : instr = instruction Dalvik à consulter. * * * * Description : Indique l'opcode associé à une instruction Dalvik. * diff --git a/src/arch/dalvik/operand.c b/src/arch/dalvik/operand.c index f8f7b39..83d95e5 100644 --- a/src/arch/dalvik/operand.c +++ b/src/arch/dalvik/operand.c @@ -24,6 +24,7 @@ #include "operand.h" +#include <assert.h> #include <malloc.h> #include <stdarg.h> @@ -56,7 +57,7 @@ typedef enum _DalvikOperandID /* Procède à la lecture d'opérandes pour une instruction. */ -static bool dalvik_read_basic_operands(GArchInstruction *, GDexFormat *, const GBinContent *, vmpa2t *, bool *, SourceEndian, DalvikOperandType, va_list); +static bool dalvik_read_basic_operands(GArchInstruction *, GDexFormat *, const GBinContent *, vmpa2t *, bool *, SourceEndian, DalvikOperandType, ...); /* Procède à la lecture d'opérandes pour une instruction. */ static bool dalvik_read_fixed_operands(GArchInstruction *, GDexFormat *, const GBinContent *, vmpa2t *, bool *, SourceEndian, DalvikOperandType); @@ -75,7 +76,7 @@ static bool dalvik_read_variatic_operands(GArchInstruction *, GDexFormat *, cons * low = position éventuelle des 4 bits visés. [OUT] * * endian = boutisme lié au binaire accompagnant. * * model = type d'opérandes attendues. * -* ap = éventuels arguments complémentaires. * +* ... = éventuels arguments complémentaires. * * * * Description : Procède à la lecture d'opérandes pour une instruction. * * * @@ -85,7 +86,7 @@ static bool dalvik_read_variatic_operands(GArchInstruction *, GDexFormat *, cons * * ******************************************************************************/ -static bool dalvik_read_basic_operands(GArchInstruction *instr, GDexFormat *format, const GBinContent *content, vmpa2t *pos, bool *low, SourceEndian endian, DalvikOperandType model, va_list ap) +static bool dalvik_read_basic_operands(GArchInstruction *instr, GDexFormat *format, const GBinContent *content, vmpa2t *pos, bool *low, SourceEndian endian, DalvikOperandType model, ...) { bool result; /* Bilan à retourner */ DalvikOperandID *types; /* Liste des chargements */ @@ -93,6 +94,8 @@ static bool dalvik_read_basic_operands(GArchInstruction *instr, GDexFormat *form GArchOperand *op; /* Opérande unique décodé */ uint16_t value16; /* Valeur sur 16 bits */ DalvikPoolType pool_type; /* Type de table à manipuler */ + va_list ap; /* Arguments complémentaires */ + const vmpa2t *base; /* Base pour les sauts de code */ result = true; @@ -334,15 +337,24 @@ static bool dalvik_read_basic_operands(GArchInstruction *instr, GDexFormat *form break; case DOI_TARGET_8: - op = g_dalvik_target_operand_new(content, pos, MDS_8_BITS_SIGNED, endian, va_arg(ap, vmpa_t)); + va_start(ap, model); + base = va_arg(ap, const vmpa2t *); + op = g_dalvik_target_operand_new(content, pos, MDS_8_BITS_SIGNED, endian, base); + va_end(ap); break; case DOI_TARGET_16: - op = g_dalvik_target_operand_new(content, pos, MDS_16_BITS_SIGNED, endian, va_arg(ap, vmpa_t)); + va_start(ap, model); + base = va_arg(ap, const vmpa2t *); + op = g_dalvik_target_operand_new(content, pos, MDS_16_BITS_SIGNED, endian, base); + va_end(ap); break; case DOI_TARGET_32: - op = g_dalvik_target_operand_new(content, pos, MDS_32_BITS_SIGNED, endian, va_arg(ap, vmpa_t)); + va_start(ap, model); + base = va_arg(ap, const vmpa2t *); + op = g_dalvik_target_operand_new(content, pos, MDS_32_BITS_SIGNED, endian, base); + va_end(ap); break; default: @@ -413,6 +425,12 @@ static bool dalvik_read_fixed_operands(GArchInstruction *instr, GDexFormat *form } + /* Consommation pleine et entière */ + + for (; i < 4; i++) + if (!g_binary_content_read_u4(content, pos, low, (uint8_t []) { 0 })) + goto err_padding; + /* Rajout des éléments finaux déjà chargés */ if (a == 5) @@ -428,6 +446,8 @@ static bool dalvik_read_fixed_operands(GArchInstruction *instr, GDexFormat *form return true; + err_padding: + err_registers: g_object_unref(G_OBJECT(target)); @@ -522,7 +542,6 @@ static bool dalvik_read_variatic_operands(GArchInstruction *instr, GDexFormat *f * pos = position courante dans ce flux. [OUT] * * endian = boutisme lié au binaire accompagnant. * * model = type d'opérandes attendues. * -* ... = éventuelles données complémentaires. * * * * Description : Procède à la lecture d'opérandes pour une instruction. * * * @@ -532,12 +551,21 @@ static bool dalvik_read_variatic_operands(GArchInstruction *instr, GDexFormat *f * * ******************************************************************************/ -bool dalvik_read_operands(GArchInstruction *instr, GExeFormat *format, const GBinContent *content, vmpa2t *pos, SourceEndian endian, DalvikOperandType model, ...) +bool dalvik_read_operands(GArchInstruction *instr, GExeFormat *format, const GBinContent *content, vmpa2t *pos, SourceEndian endian, DalvikOperandType model) { bool result; /* Bilan à retourner */ GDexFormat *dformat; /* Autre version du format */ bool low; /* Partie d'octets à lire */ +#ifndef NDEBUG + vmpa2t old; /* Position avant traitements */ +#endif + vmpa2t base; /* Base pour les sauts de code */ + vmpa2t *extra; /* Information complémentaire */ va_list ap; /* Arguments complémentaires */ +#ifndef NDEBUG + phys_t expected; /* Consommation attendue */ + phys_t consumed; /* Consommation réelle */ +#endif result = true; @@ -545,6 +573,42 @@ bool dalvik_read_operands(GArchInstruction *instr, GExeFormat *format, const GBi low = true; +#ifndef NDEBUG + + copy_vmpa(&old, pos); + +#endif + + /* Récupération de la base ? */ + + if (DALVIK_OP_GET_MNEMONIC(model) == 'T') + { + extra = &base; + + copy_vmpa(extra, pos); + deminish_vmpa(extra, 1); + + } + else extra = NULL; + + /* Bourrage : ØØ|op ? */ + + switch (model & ~DALVIK_OP_EXTRA_MASK) + { + case DALVIK_OPT_10X: + case DALVIK_OPT_20T: + case DALVIK_OPT_30T: + case DALVIK_OPT_32X: + advance_vmpa(pos, 1); + break; + + default: + break; + + } + + /* Décodage... */ + switch (model & ~DALVIK_OP_EXTRA_MASK) { case DALVIK_OPT_10T: @@ -568,9 +632,7 @@ bool dalvik_read_operands(GArchInstruction *instr, GExeFormat *format, const GBi case DALVIK_OPT_31T: case DALVIK_OPT_32X: case DALVIK_OPT_51L: - va_start(ap, model); - result = dalvik_read_basic_operands(instr, dformat, content, pos, &low, endian, model, ap); - va_end(ap); + result = dalvik_read_basic_operands(instr, dformat, content, pos, &low, endian, model, extra); break; case DALVIK_OPT_35C: @@ -588,6 +650,21 @@ bool dalvik_read_operands(GArchInstruction *instr, GExeFormat *format, const GBi } +#ifndef NDEBUG + + /* Vérification d'implémentation */ + + if (result) + { + expected = DALVIK_OP_GET_LEN(model) * 2; + consumed = 1 + compute_vmpa_diff(&old, pos); + + assert(consumed == expected); + + } + +#endif + return result; } diff --git a/src/arch/dalvik/operand.h b/src/arch/dalvik/operand.h index 27901be..af15bde 100644 --- a/src/arch/dalvik/operand.h +++ b/src/arch/dalvik/operand.h @@ -65,6 +65,8 @@ #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) +#define DALVIK_OP_GET_MNEMONIC(v) ((v) & 0xff) + /* Types d'opérandes supportés */ typedef enum _DalvikOperandType @@ -112,7 +114,7 @@ typedef enum _DalvikOperandType /* Procède à la lecture d'opérandes pour une instruction. */ -bool dalvik_read_operands(GArchInstruction *, GExeFormat *, const GBinContent *, vmpa2t *, SourceEndian, DalvikOperandType, ...); +bool dalvik_read_operands(GArchInstruction *, GExeFormat *, const GBinContent *, vmpa2t *, SourceEndian, DalvikOperandType); /* Procède à la lecture d'opérandes pour une instruction. */ void dalvik_mark_first_operand_as_written(GArchInstruction *); diff --git a/src/arch/dalvik/operands/target.c b/src/arch/dalvik/operands/target.c index 42d09cf..5e8b91a 100644 --- a/src/arch/dalvik/operands/target.c +++ b/src/arch/dalvik/operands/target.c @@ -169,31 +169,34 @@ static void g_dalvik_target_operand_finalize(GDalvikTargetOperand *operand) * * ******************************************************************************/ -GArchOperand *g_dalvik_target_operand_new(const GBinContent *content, vmpa2t *pos, MemoryDataSize size, SourceEndian endian, vmpa_t base) +GArchOperand *g_dalvik_target_operand_new(const GBinContent *content, vmpa2t *pos, MemoryDataSize size, SourceEndian endian, const vmpa2t *base) { GDalvikTargetOperand *result; /* Structure à retourner */ + phys_t offset; /* Emplacement de base */ int8_t val8; /* Valeur sur 8 bits */ int16_t val16; /* Valeur sur 16 bits */ int32_t val32; /* Valeur sur 32 bits */ bool test; /* Bilan de lecture */ - vmpa_t address; /* Adresse finale visée */ + phys_t address; /* Adresse finale visée */ + + offset = get_phy_addr(base); switch (size) { case MDS_8_BITS_SIGNED: test = g_binary_content_read_s8(content, pos, &val8); - address = base + val8 * sizeof(uint16_t); + address = offset + val8 * sizeof(uint16_t); break; case MDS_16_BITS_SIGNED: test = g_binary_content_read_s16(content, pos, endian, &val16); - address = base + val16 * sizeof(uint16_t); + address = offset + val16 * sizeof(uint16_t); break; case MDS_32_BITS_SIGNED: test = g_binary_content_read_s32(content, pos, endian, &val32); - address = base + val32 * sizeof(uint16_t); + address = offset + val32 * sizeof(uint16_t); break; default: - return NULL; + test = false; break; } @@ -201,7 +204,7 @@ GArchOperand *g_dalvik_target_operand_new(const GBinContent *content, vmpa2t *po return NULL; result = g_object_new(G_TYPE_DALVIK_TARGET_OPERAND, NULL); - result->immediate = G_IMM_OPERAND(g_imm_operand_new_from_value(MDS_32_BITS/*FIXME*/, (uint32_t)address/* FIXME */)); + result->immediate = G_IMM_OPERAND(g_imm_operand_new_from_value(MDS_32_BITS, address)); return G_ARCH_OPERAND(result); diff --git a/src/arch/dalvik/operands/target.h b/src/arch/dalvik/operands/target.h index cb0e9f1..6328546 100644 --- a/src/arch/dalvik/operands/target.h +++ b/src/arch/dalvik/operands/target.h @@ -51,7 +51,7 @@ typedef struct _GDalvikTargetOperandClass GDalvikTargetOperandClass; GType g_dalvik_target_operand_get_type(void); /* Crée un opérande visant un instruction Dalvik. */ -GArchOperand *g_dalvik_target_operand_new(const GBinContent *, vmpa2t *, MemoryDataSize, SourceEndian, vmpa_t); +GArchOperand *g_dalvik_target_operand_new(const GBinContent *, vmpa2t *, MemoryDataSize, SourceEndian, const vmpa2t *); /* Fournit l'adresse représentée par une opérande Dalvik. */ const GImmOperand *g_dalvik_target_operand_get_value(const GDalvikTargetOperand *); diff --git a/src/arch/processor.c b/src/arch/processor.c index bbe506a..21db869 100644 --- a/src/arch/processor.c +++ b/src/arch/processor.c @@ -24,6 +24,7 @@ #include "processor.h" +#include <assert.h> #include <malloc.h> #include <stdlib.h> @@ -304,6 +305,8 @@ GArchInstruction *g_arch_processor_disassemble(const GArchProcessor *proc, GProc GArchInstruction *result; /* Instruction à renvoyer */ vmpa2t back; /* Position sauvegardée */ + assert(has_phys_addr(pos) && has_virt_addr(pos)); + copy_vmpa(&back, pos); result = G_ARCH_PROCESSOR_GET_CLASS(proc)->disassemble(proc, ctx, content, pos, format); |