summaryrefslogtreecommitdiff
path: root/src/arch/dalvik/operand.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2011-12-27 16:49:18 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2011-12-27 16:49:18 (GMT)
commitce12c2bb85d26b0f6de5ba42ff53e2ff6788f4e4 (patch)
tree216c4c4db2b92c05f29143b9c28fc9d8fb6151e2 /src/arch/dalvik/operand.c
parent8a12f3685fab7c975c307bbc7dc5e721616be6a3 (diff)
Added support for more Dalvik opcodes.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@220 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/arch/dalvik/operand.c')
-rw-r--r--src/arch/dalvik/operand.c93
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;