summaryrefslogtreecommitdiff
path: root/src/arch/dalvik/operand.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2010-06-20 20:47:17 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2010-06-20 20:47:17 (GMT)
commitdad83b556250a85a9b2ccf68e5fb6f4df7dca1f4 (patch)
tree81f90d9966d712d006aa639d90874627ccd6970b /src/arch/dalvik/operand.c
parent0d7908e0c8282050ebbcc8a7c18fafd13152a36e (diff)
Supported more Dalvik opcodes.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@169 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/arch/dalvik/operand.c')
-rw-r--r--src/arch/dalvik/operand.c310
1 files changed, 301 insertions, 9 deletions
diff --git a/src/arch/dalvik/operand.c b/src/arch/dalvik/operand.c
index 184a6e6..07c0675 100644
--- a/src/arch/dalvik/operand.c
+++ b/src/arch/dalvik/operand.c
@@ -25,10 +25,10 @@
#include <malloc.h>
+#include <stdarg.h>
#include "register.h"
-#include "../immediate.h"
#include "../operand-int.h"
@@ -168,6 +168,41 @@ static void g_dalvik_pool_operand_to_buffer(const GDalvikPoolOperand *, GBufferL
+/* ---------------------- OPERANDES VISANT UNE ADRESSE DE CODE ---------------------- */
+
+
+/* Définition d'un opérande visant une adresse de code Dalvik (instance) */
+struct _GDalvikTargetOperand
+{
+ GDalvikOperand parent; /* Instance parente */
+
+ GImmOperand *immediate; /* Adresse visée reconstituée */
+
+};
+
+
+/* Définition d'un opérande visant une adresse de code Dalvik (classe) */
+struct _GDalvikTargetOperandClass
+{
+ GDalvikOperandClass parent; /* Classe parente */
+
+};
+
+
+/* Initialise la classe des opérandes de ciblage de code Dalvik. */
+static void g_dalvik_target_operand_class_init(GDalvikTargetOperandClass *);
+
+/* Initialise une instance d'opérande de ciblage de code Dalvik. */
+static void g_dalvik_target_operand_init(GDalvikTargetOperand *);
+
+/* Ajoute du texte simple à un fichier ouvert en écriture. */
+static void g_dalvik_target_operand_add_text(const GDalvikTargetOperand *, GRenderingOptions *, MainRendering, FILE *);
+
+/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
+static void g_dalvik_target_operand_to_buffer(const GDalvikTargetOperand *, GBufferLine *, GRenderingOptions *);
+
+
+
/* ------------------------- AIDE A LA CREATION D'OPERANDES ------------------------- */
@@ -182,16 +217,21 @@ typedef enum _DalvikOperandID
DOI_IMMEDIATE_4,
DOI_IMMEDIATE_8,
DOI_IMMEDIATE_16,
+ DOI_IMMEDIATE_32,
+ DOI_IMMEDIATE_64,
DOI_IMMEDIATE_H16,
- DOI_POOL_CONST
+ DOI_POOL_CONST,
+ DOI_TARGET_8,
+ DOI_TARGET_16,
+ DOI_TARGET_32
} DalvikOperandID;
/* Procède à la lecture d'opérandes pour une instruction. */
-static bool dalvik_read_basic_operands(GArchInstruction *, const bin_t *, off_t *, off_t, bool *, SourceEndian, DalvikOperandType);
+static bool dalvik_read_basic_operands(GArchInstruction *, const bin_t *, off_t *, off_t, bool *, SourceEndian, DalvikOperandType, va_list);
/* 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);
@@ -828,8 +868,173 @@ uint32_t g_dalvik_pool_operand_get_index(const GDalvikPoolOperand *operand)
+/* ---------------------------------------------------------------------------------- */
+/* OPERANDES VISANT UNE ADRESSE DE CODE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini par la GLib pour un opérande de ciblage de code Dalvik. */
+G_DEFINE_TYPE(GDalvikTargetOperand, g_dalvik_target_operand, G_TYPE_DALVIK_OPERAND);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des opérandes de ciblage de code Dalvik.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dalvik_target_operand_class_init(GDalvikTargetOperandClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = instance à initialiser. *
+* *
+* Description : Initialise une instance d'opérande de ciblage de code Dalvik.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dalvik_target_operand_init(GDalvikTargetOperand *operand)
+{
+ GContentExporter *parent; /* Instance parente */
+
+ parent = G_CONTENT_EXPORTER(operand);
+
+ parent->add_text = (add_text_fc)g_dalvik_target_operand_add_text;
+ parent->export_buffer = (export_buffer_fc)g_dalvik_target_operand_to_buffer;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* size = taille de l'opérande. *
+* endian = ordre des bits dans la source. *
+* base = adresse de référence pour le calcul. *
+* *
+* Description : Crée un opérande visant un instruction Dalvik. *
+* *
+* Retour : Opérande mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchOperand *g_dalvik_target_operand_new(const bin_t *data, off_t *pos, off_t len, MemoryDataSize size, SourceEndian endian, vmpa_t base)
+{
+ GDalvikTargetOperand *result; /* Structure à retourner */
+ off_t init_pos; /* Position avant lecture */
+ int8_t val8; /* Valeur sur 8 bits */
+ int16_t val16; /* Valeur sur 16 bits */
+ int32_t val32; /* Valeur sur 32 bits */
+ vmpa_t address; /* Adresse finale visée */
+
+ init_pos = *pos;
+
+ switch (size)
+ {
+ case MDS_8_BITS_SIGNED:
+ read_s8(&val8, data, pos, len, endian);
+ address = base + (*pos - init_pos) + val8;
+ break;
+ case MDS_16_BITS_SIGNED:
+ read_s16(&val16, data, pos, len, endian);
+ printf("ADDR :: 0x%08llx + (%d - %d) + 0x%08x\n", base, *pos, init_pos, val16);
+ address = base + (*pos - init_pos) + val16;
+ break;
+ case MDS_32_BITS_SIGNED:
+ read_s32(&val32, data, pos, len, endian);
+ address = base + (*pos - init_pos) + val32;
+ break;
+ default:
+ return NULL;
+ break;
+ }
+ result = g_object_new(G_TYPE_DALVIK_TARGET_OPERAND, NULL);
+ result->immediate = G_IMM_OPERAND(g_imm_operand_new_from_value(AOS_32_BITS/*FIXME*/, (uint32_t)address/* FIXME */));
+ return G_ARCH_OPERAND(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à transcrire. *
+* options = options de rendu. *
+* rendering = support effectif final des lignes de code. *
+* stream = flux ouvert en écriture. *
+* *
+* Description : Ajoute du texte simple à un fichier ouvert en écriture. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dalvik_target_operand_add_text(const GDalvikTargetOperand *operand, GRenderingOptions *options, MainRendering rendering, FILE *stream)
+{
+ g_content_exporter_add_text(G_CONTENT_EXPORTER(operand->immediate), options, rendering, stream);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à transcrire. *
+* buffer = espace où placer ledit contenu. *
+* options = options de rendu. *
+* *
+* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dalvik_target_operand_to_buffer(const GDalvikTargetOperand *operand, GBufferLine *buffer, GRenderingOptions *options)
+{
+ g_content_exporter_to_buffer(G_CONTENT_EXPORTER(operand->immediate), buffer, options);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à traiter. *
+* *
+* Description : Fournit l'adresse représentée par une opérande Dalvik. *
+* *
+* Retour : Valeur portée par l'opérande. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const GImmOperand *g_dalvik_target_operand_get_value(const GDalvikTargetOperand *operand)
+{
+ return operand->immediate;
+
+}
@@ -847,6 +1052,7 @@ uint32_t g_dalvik_pool_operand_get_index(const GDalvikPoolOperand *operand)
* 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. *
* *
* Description : Procède à la lecture d'opérandes pour une instruction. *
* *
@@ -856,7 +1062,7 @@ uint32_t g_dalvik_pool_operand_get_index(const GDalvikPoolOperand *operand)
* *
******************************************************************************/
-static bool dalvik_read_basic_operands(GArchInstruction *instr, const bin_t *data, off_t *pos, off_t len, bool *low, SourceEndian endian, DalvikOperandType model)
+static bool dalvik_read_basic_operands(GArchInstruction *instr, const bin_t *data, off_t *pos, off_t len, bool *low, SourceEndian endian, DalvikOperandType model, va_list ap)
{
bool result; /* Bilan à retourner */
DalvikOperandID *types; /* Liste des chargements */
@@ -868,8 +1074,15 @@ static bool dalvik_read_basic_operands(GArchInstruction *instr, const bin_t *dat
/* Choix des opérandes à charger */
- switch (model & ~DALVIK_OP_POOL_MASK)
+ switch (model & ~DALVIK_OP_EXTRA_MASK)
{
+ case DALVIK_OPT_10T:
+ types = (DalvikOperandID []) {
+ DOI_TARGET_8,
+ DOI_INVALID
+ };
+ break;
+
case DALVIK_OPT_11N:
types = (DalvikOperandID []) {
DOI_REGISTER_4,
@@ -893,6 +1106,13 @@ static bool dalvik_read_basic_operands(GArchInstruction *instr, const bin_t *dat
};
break;
+ case DALVIK_OPT_20T:
+ types = (DalvikOperandID []) {
+ DOI_TARGET_16,
+ DOI_INVALID
+ };
+ break;
+
case DALVIK_OPT_21C:
types = (DalvikOperandID []) {
DOI_REGISTER_8,
@@ -917,6 +1137,14 @@ static bool dalvik_read_basic_operands(GArchInstruction *instr, const bin_t *dat
};
break;
+ case DALVIK_OPT_21T:
+ types = (DalvikOperandID []) {
+ DOI_REGISTER_8,
+ DOI_TARGET_16,
+ DOI_INVALID
+ };
+ break;
+
case DALVIK_OPT_22B:
types = (DalvikOperandID []) {
DOI_REGISTER_8,
@@ -944,6 +1172,15 @@ static bool dalvik_read_basic_operands(GArchInstruction *instr, const bin_t *dat
};
break;
+ case DALVIK_OPT_22T:
+ types = (DalvikOperandID []) {
+ DOI_REGISTER_4,
+ DOI_REGISTER_4,
+ DOI_TARGET_16,
+ DOI_INVALID
+ };
+ break;
+
case DALVIK_OPT_23X:
types = (DalvikOperandID []) {
DOI_REGISTER_8,
@@ -953,6 +1190,29 @@ static bool dalvik_read_basic_operands(GArchInstruction *instr, const bin_t *dat
};
break;
+ case DALVIK_OPT_30T:
+ types = (DalvikOperandID []) {
+ DOI_TARGET_32,
+ DOI_INVALID
+ };
+ break;
+
+ case DALVIK_OPT_31I:
+ types = (DalvikOperandID []) {
+ DOI_REGISTER_8,
+ DOI_IMMEDIATE_32,
+ DOI_INVALID
+ };
+ break;
+
+ case DALVIK_OPT_51L:
+ types = (DalvikOperandID []) {
+ DOI_REGISTER_8,
+ DOI_IMMEDIATE_64,
+ DOI_INVALID
+ };
+ break;
+
default:
types = (DalvikOperandID []) {
DOI_INVALID
@@ -987,6 +1247,14 @@ static bool dalvik_read_basic_operands(GArchInstruction *instr, const bin_t *dat
op = g_imm_operand_new_from_data(MDS_16_BITS, data, pos, len, endian);
break;
+ case DOI_IMMEDIATE_32:
+ op = g_imm_operand_new_from_data(MDS_32_BITS, data, pos, len, endian);
+ break;
+
+ case DOI_IMMEDIATE_64:
+ op = g_imm_operand_new_from_data(MDS_64_BITS, data, pos, len, endian);
+ break;
+
case DOI_IMMEDIATE_H16:
result = read_u16(&value16, data, pos, len, endian);
if (result)
@@ -997,6 +1265,18 @@ 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_TARGET_8:
+ op = g_dalvik_target_operand_new(data, pos, len, MDS_8_BITS_SIGNED, endian, va_arg(ap, vmpa_t));
+ break;
+
+ case DOI_TARGET_16:
+ op = g_dalvik_target_operand_new(data, pos, len, MDS_16_BITS_SIGNED, endian, va_arg(ap, vmpa_t));
+ break;
+
+ case DOI_TARGET_32:
+ op = g_dalvik_target_operand_new(data, pos, len, MDS_32_BITS_SIGNED, endian, va_arg(ap, vmpa_t));
+ break;
+
default:
op = NULL;
break;
@@ -1058,6 +1338,7 @@ static bool dalvik_read_fixed_operands(GArchInstruction *instr, const bin_t *dat
if (0)
{
+ /* FIXME */
if (target2 == NULL) goto err_target2;
}
@@ -1136,7 +1417,7 @@ static bool dalvik_read_fixed_operands(GArchInstruction *instr, const bin_t *dat
* *
******************************************************************************/
-bool dalvik_read_operands(GArchInstruction *instr, const bin_t *data, off_t *pos, off_t len, SourceEndian endian, DalvikOperandType model)
+bool dalvik_read_operands(GArchInstruction *instr, const bin_t *data, off_t *pos, off_t len, SourceEndian endian, DalvikOperandType model, ...)
{
bool result; /* Bilan à retourner */
@@ -1145,6 +1426,8 @@ bool dalvik_read_operands(GArchInstruction *instr, const bin_t *data, off_t *pos
off_t old_pos;
+ va_list ap; /* Arguments complémentaires */
+
off_t length;
result = true;
@@ -1157,19 +1440,28 @@ bool dalvik_read_operands(GArchInstruction *instr, const bin_t *data, off_t *pos
- switch (model & ~DALVIK_OP_POOL_MASK)
+ switch (model & ~DALVIK_OP_EXTRA_MASK)
{
- case DALVIK_OPT_12X:
+ case DALVIK_OPT_10T:
case DALVIK_OPT_11N:
case DALVIK_OPT_11X:
+ case DALVIK_OPT_12X:
+ case DALVIK_OPT_20T:
case DALVIK_OPT_21C:
case DALVIK_OPT_21H:
case DALVIK_OPT_21S:
+ case DALVIK_OPT_21T:
case DALVIK_OPT_22B:
case DALVIK_OPT_22C:
case DALVIK_OPT_22S:
+ case DALVIK_OPT_22T:
case DALVIK_OPT_23X:
- result = dalvik_read_basic_operands(instr, data, pos, len, &low, endian, model);
+ case DALVIK_OPT_30T:
+ case DALVIK_OPT_31I:
+ case DALVIK_OPT_51L:
+ va_start(ap, model);
+ result = dalvik_read_basic_operands(instr, data, pos, len, &low, endian, model, ap);
+ va_end(ap);
break;
case DALVIK_OPT_35C: