diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2010-06-20 20:47:17 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2010-06-20 20:47:17 (GMT) |
commit | dad83b556250a85a9b2ccf68e5fb6f4df7dca1f4 (patch) | |
tree | 81f90d9966d712d006aa639d90874627ccd6970b /src/arch/dalvik/operand.c | |
parent | 0d7908e0c8282050ebbcc8a7c18fafd13152a36e (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.c | 310 |
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: |