summaryrefslogtreecommitdiff
path: root/src/arch/dalvik
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-02-10 10:02:16 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-02-10 10:02:16 (GMT)
commit465488d5b231c2552116a305c48b5fcccea55a09 (patch)
treef4d072ad9cf56466f4e55d0608f7a3fe9204efaf /src/arch/dalvik
parent946f5f093c7265dc5a5e00694325605b249eea43 (diff)
Improved the support of the DEX format.
Diffstat (limited to 'src/arch/dalvik')
-rw-r--r--src/arch/dalvik/instruction.c27
-rw-r--r--src/arch/dalvik/operand.c99
-rw-r--r--src/arch/dalvik/operand.h4
-rw-r--r--src/arch/dalvik/operands/target.c17
-rw-r--r--src/arch/dalvik/operands/target.h2
5 files changed, 129 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 *);