diff options
Diffstat (limited to 'src/arch/dalvik/operand.c')
-rw-r--r-- | src/arch/dalvik/operand.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/src/arch/dalvik/operand.c b/src/arch/dalvik/operand.c index 7c245d8..33fcf44 100644 --- a/src/arch/dalvik/operand.c +++ b/src/arch/dalvik/operand.c @@ -46,6 +46,7 @@ typedef enum _DalvikOperandID DOI_IMMEDIATE_H16, DOI_POOL_CONST, + DOI_POOL_CONST_WIDE, DOI_TARGET_8, DOI_TARGET_16, @@ -60,6 +61,9 @@ static bool dalvik_read_basic_operands(GArchInstruction *, const bin_t *, off_t /* 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); +/* Procède à la lecture d'opérandes pour une instruction. */ +static bool dalvik_read_variatic_operands(GArchInstruction *, const bin_t *, off_t *, off_t, bool *, SourceEndian, DalvikOperandType); + /****************************************************************************** @@ -224,6 +228,14 @@ static bool dalvik_read_basic_operands(GArchInstruction *instr, const bin_t *dat }; break; + case DALVIK_OPT_31C: + types = (DalvikOperandID []) { + DOI_REGISTER_8, + DOI_POOL_CONST_WIDE, + DOI_INVALID + }; + break; + case DALVIK_OPT_31I: types = (DalvikOperandID []) { DOI_REGISTER_8, @@ -304,6 +316,10 @@ static bool dalvik_read_basic_operands(GArchInstruction *instr, const bin_t *dat op = g_dalvik_pool_operand_new(DALVIK_OP_GET_POOL(model), data, pos, len, MDS_16_BITS, endian); break; + case DOI_POOL_CONST_WIDE: + op = g_dalvik_pool_operand_new(DALVIK_OP_GET_POOL(model), data, pos, len, MDS_32_BITS, endian); + break; + case DOI_TARGET_8: op = g_dalvik_target_operand_new(data, pos, len, MDS_8_BITS_SIGNED, endian, va_arg(ap, vmpa_t)); break; @@ -429,6 +445,76 @@ static bool dalvik_read_fixed_operands(GArchInstruction *instr, const bin_t *dat } +/****************************************************************************** +* * +* 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_variatic_operands(GArchInstruction *instr, const bin_t *data, off_t *pos, off_t len, bool *low, SourceEndian endian, DalvikOperandType model) +{ + uint8_t a; /* Nbre. de registres utilisés */ + uint16_t b; /* Indice dans la table const. */ + GArchOperand *target; /* Opérande visant la table */ + GArchOperand *args; /* Liste des opérandes */ + uint8_t i; /* Boucle de parcours */ + uint16_t c; /* Indice de registre */ + GArchOperand *op; /* Opérande unique décodé */ + + if (!read_u8(&a, data, pos, len, endian)) + return false; + + if (!read_u16(&b, data, pos, len, endian)) + return false; + + target = g_dalvik_pool_operand_new(DALVIK_OP_GET_POOL(model), data, pos, len, MDS_16_BITS, endian); + if (target == NULL) return false; + + /* Mise en place des arguments */ + + args = g_dalvik_args_operand_new(); + g_arch_instruction_attach_extra_operand(instr, args); + + for (i = 0; i < a; i++) + { + if (i == 0 && !read_u16(&c, data, pos, len, endian)) + goto drvo_registers; + + op = g_dalvik_register_operand_new_from_existing(g_dalvik_register_new(c + i)); + if (op == NULL) goto drvo_registers; + + g_dalvik_args_operand_add(G_DALVIK_ARGS_OPERAND(args), op); + + } + + /* Rajout de la cible */ + + g_arch_instruction_attach_extra_operand(instr, target); + + return true; + + drvo_registers: + + g_object_unref(G_OBJECT(args)); + + g_object_unref(G_OBJECT(target)); + + return false; + +} + @@ -498,6 +584,7 @@ bool dalvik_read_operands(GArchInstruction *instr, const bin_t *data, off_t *pos case DALVIK_OPT_22X: case DALVIK_OPT_23X: case DALVIK_OPT_30T: + case DALVIK_OPT_31C: case DALVIK_OPT_31I: case DALVIK_OPT_31T: case DALVIK_OPT_51L: @@ -510,6 +597,12 @@ bool dalvik_read_operands(GArchInstruction *instr, const bin_t *data, off_t *pos result = dalvik_read_fixed_operands(instr, data, pos, len, &low, endian, model); break; + case DALVIK_OPT_3RC: + case DALVIK_OPT_3RMS: + case DALVIK_OPT_3RFS: + result = dalvik_read_variatic_operands(instr, data, pos, len, &low, endian, model); + break; + default: break; |