diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2016-10-10 20:03:23 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2016-10-10 20:03:23 (GMT) |
commit | 8dff3daac4d2dc98b90adaecea834fb65db4fb10 (patch) | |
tree | 39a747f8fcdcbf525bb64a7e4173ff2a5b360d28 /src/arch/dalvik/pseudo | |
parent | f3e84729588f7e2e518f82116e908455d957f9ca (diff) |
Handled switch and fill-array data pseudo-instructions without plugin.
Diffstat (limited to 'src/arch/dalvik/pseudo')
-rw-r--r-- | src/arch/dalvik/pseudo/fill.c | 94 | ||||
-rw-r--r-- | src/arch/dalvik/pseudo/fill.h | 13 | ||||
-rw-r--r-- | src/arch/dalvik/pseudo/switch.c | 130 | ||||
-rw-r--r-- | src/arch/dalvik/pseudo/switch.h | 16 |
4 files changed, 103 insertions, 150 deletions
diff --git a/src/arch/dalvik/pseudo/fill.c b/src/arch/dalvik/pseudo/fill.c index e1e1822..69452b5 100644 --- a/src/arch/dalvik/pseudo/fill.c +++ b/src/arch/dalvik/pseudo/fill.c @@ -37,7 +37,7 @@ struct _GDalvikFillInstr { GDalvikInstruction parent; /* A laisser en premier */ - uint16_t array_width; /* Taille des éléments */ + uint16_t item_width; /* Taille des éléments */ uint32_t array_size; /* Taille du tableau */ }; @@ -63,9 +63,6 @@ static void g_dalvik_fill_instr_dispose(GDalvikFillInstr *); /* Procède à la libération totale de la mémoire. */ static void g_dalvik_fill_instr_finalize(GDalvikFillInstr *); -/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ -static void g_dalvik_fill_instr_print(GDalvikFillInstr *, GCodeBuffer *, MemoryDataSize, const bin_t *, AsmSyntax); - /* Indique le type défini pour une pseudo-instruction Dalvik de remplissage. */ @@ -87,17 +84,12 @@ G_DEFINE_TYPE(GDalvikFillInstr, g_dalvik_fill_instr, G_TYPE_DALVIK_INSTRUCTION); static void g_dalvik_fill_instr_class_init(GDalvikFillInstrClass *klass) { GObjectClass *object; /* Autre version de la classe */ - GArchInstructionClass *instr; /* Encore une autre vision... */ object = G_OBJECT_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_dalvik_fill_instr_dispose; object->finalize = (GObjectFinalizeFunc)g_dalvik_fill_instr_finalize; - instr = G_ARCH_INSTRUCTION_CLASS(klass); - - //instr->print = (print_instruction_fc)g_dalvik_fill_instr_print; - } @@ -115,7 +107,7 @@ static void g_dalvik_fill_instr_class_init(GDalvikFillInstrClass *klass) static void g_dalvik_fill_instr_init(GDalvikFillInstr *instr) { - G_DALVIK_INSTRUCTION(instr)->keyword = "##fill-array##"; + G_DALVIK_INSTRUCTION(instr)->keyword = "array-data"; } @@ -161,6 +153,7 @@ static void g_dalvik_fill_instr_finalize(GDalvikFillInstr *instr) /****************************************************************************** * * * Paramètres : ident = identifiant de l'instruction déjà lu. * +* ctx = contexte lié à l'exécution du processeur. * * content = flux de données à analyser. * * pos = position courante dans ce flux. [OUT] * * * @@ -172,7 +165,7 @@ static void g_dalvik_fill_instr_finalize(GDalvikFillInstr *instr) * * ******************************************************************************/ -GArchInstruction *g_dalvik_fill_instr_new(uint16_t ident, const GBinContent *content, vmpa2t *pos) +GArchInstruction *g_dalvik_fill_instr_new(uint16_t ident, GDalvikContext *ctx, const GBinContent *content, vmpa2t *pos) { GDalvikFillInstr *result; /* Structure à retourner */ phys_t consumed; /* Données consommées */ @@ -183,19 +176,17 @@ GArchInstruction *g_dalvik_fill_instr_new(uint16_t ident, const GBinContent *con G_DALVIK_INSTRUCTION(result)->ptype = ident; - if (!g_binary_content_read_u16(content, pos, SRE_LITTLE, &result->array_width)) + if (!g_binary_content_read_u16(content, pos, SRE_LITTLE, &result->item_width)) goto gdfin_bad; if (!g_binary_content_read_u32(content, pos, SRE_LITTLE, &result->array_size)) goto gdfin_bad; - consumed = result->array_width * result->array_size; + consumed = result->item_width * result->array_size; - if (!g_binary_content_seek(content, pos, consumed)) + if (!g_dalvik_context_register_array_data(ctx, pos, result->item_width, consumed)) goto gdfin_bad; - g_arch_instruction_set_displayed_max_length(G_ARCH_INSTRUCTION(result), 8); - return G_ARCH_INSTRUCTION(result); gdfin_bad: @@ -205,74 +196,3 @@ GArchInstruction *g_dalvik_fill_instr_new(uint16_t ident, const GBinContent *con return NULL; } - - -/****************************************************************************** -* * -* Paramètres : instr = instruction d'assemblage à représenter. * -* buffer = espace où placer ledit contenu. * -* syntax = type de représentation demandée. * -* * -* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_dalvik_fill_instr_print(GDalvikFillInstr *instr, GCodeBuffer *buffer, MemoryDataSize msize, const bin_t *content, AsmSyntax syntax) -{ - GArchInstruction *base; /* Version basique de l'objet */ - GBufferLine *line; /* Ligne de destination */ - char address[VMPA_MAX_SIZE]; /* Adresse au format texte */ - size_t len; /* Taille de l'élément inséré */ - char *bin_code; /* Tampon du code binaire */ - off_t i; /* Boucle de parcours */ - const char *key; /* Mot clef principal */ - size_t klen; /* Taille de ce mot clef */ - - base = G_ARCH_INSTRUCTION(instr); - - line = NULL; - - -#if 0 - - line = g_code_buffer_append_new_line(buffer, base->address); - - /* Adresse virtuelle ou physique */ - - len = vmpa_to_string(base->address, msize, address); - - g_buffer_line_insert_text(line, BLC_PHYSICAL, address, len, RTT_RAW); - - /* TODO ... */ - - /* Code brut */ - - bin_code = (char *)calloc(3 * 3 + 3, sizeof(char)); - - for (i = 0; i < 3; i++) - { - if ((i + 1) < 3) - snprintf(&bin_code[i * (2 + 1)], 4, "%02hhx ", content[base->offset + i]); - else - snprintf(&bin_code[i * (2 + 1)], 6, "%02hhx...", content[base->offset + i]); - } - - g_buffer_line_insert_text(line, BLC_BINARY, - bin_code, 3 * 3 + 2, RTT_RAW_CODE); - - free(bin_code); - -#endif - - /* Instruction proprement dite */ - - key = "<fill-array>"; - klen = strlen(key); - - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION); - -} diff --git a/src/arch/dalvik/pseudo/fill.h b/src/arch/dalvik/pseudo/fill.h index aeb04b8..9c5a852 100644 --- a/src/arch/dalvik/pseudo/fill.h +++ b/src/arch/dalvik/pseudo/fill.h @@ -25,6 +25,7 @@ #define _ARCH_DALVIK_PSEUDO_FILL_H +#include "../context.h" #include "../instruction.h" #include "../processor.h" @@ -33,10 +34,12 @@ -#define G_TYPE_DALVIK_FILL_INSTR g_dalvik_fill_instr_get_type() -#define G_DALVIK_FILL_INSTR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dalvik_fill_instr_get_type(), GDalvikFillInstr)) -#define G_IS_DALVIK_FILL_INSTR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dalvik_fill_instr_get_type())) -#define G_DALVIK_FILL_INSTR_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_dalvik_fill_instr_get_type(), GDalvikFillInstrIface)) +#define G_TYPE_DALVIK_FILL_INSTR g_dalvik_fill_instr_get_type() +#define G_DALVIK_FILL_INSTR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DALVIK_FILL_INSTR, GDalvikFillInstr)) +#define G_IS_DALVIK_FILL_INSTR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_DALVIK_FILL_INSTR)) +#define G_DALVIK_FILL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DALVIK_FILL, GGDalvikFillClass)) +#define G_IS_DALVIK_FILL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DALVIK_FILL)) +#define G_DALVIK_FILL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DALVIK_FILL, GGDalvikFillClass)) /* Définition générique d'une instruction d'architecture (instance) */ @@ -50,7 +53,7 @@ typedef struct _GDalvikFillInstrClass GDalvikFillInstrClass; GType g_dalvik_fill_instr_get_type(void); /* Crée une pesudo-instruction Dalvik de remplissage. */ -GArchInstruction *g_dalvik_fill_instr_new(uint16_t, const GBinContent *, vmpa2t *); +GArchInstruction *g_dalvik_fill_instr_new(uint16_t, GDalvikContext *, const GBinContent *, vmpa2t *); diff --git a/src/arch/dalvik/pseudo/switch.c b/src/arch/dalvik/pseudo/switch.c index c1d0982..fd7e442 100644 --- a/src/arch/dalvik/pseudo/switch.c +++ b/src/arch/dalvik/pseudo/switch.c @@ -25,7 +25,7 @@ #include <assert.h> -#include <string.h> +#include <malloc.h> #include "../instruction-int.h" @@ -39,6 +39,9 @@ struct _GDalvikSwitchInstr uint16_t switch_size; /* Taille du switch considéré */ + uint32_t *keys; /* Table de clefs */ + uint32_t *targets; /* Table des sauts relatifs */ + }; /* Définition générique d'une instruction d'architecture Dalvik (classe) */ @@ -62,8 +65,8 @@ static void g_dalvik_switch_instr_dispose(GDalvikSwitchInstr *); /* Procède à la libération totale de la mémoire. */ static void g_dalvik_switch_instr_finalize(GDalvikSwitchInstr *); -/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ -static void g_dalvik_switch_instr_print(GDalvikSwitchInstr *, GCodeBuffer *, MemoryDataSize, const bin_t *, AsmSyntax); +/* Lit toutes les valeurs associés aux branchements. */ +static bool g_dalvik_switch_decode_data(GDalvikSwitchInstr *, const GBinContent *, const vmpa2t *); @@ -86,17 +89,12 @@ G_DEFINE_TYPE(GDalvikSwitchInstr, g_dalvik_switch_instr, G_TYPE_DALVIK_INSTRUCTI static void g_dalvik_switch_instr_class_init(GDalvikSwitchInstrClass *klass) { GObjectClass *object; /* Autre version de la classe */ - GArchInstructionClass *instr; /* Encore une autre vision... */ object = G_OBJECT_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_dalvik_switch_instr_dispose; object->finalize = (GObjectFinalizeFunc)g_dalvik_switch_instr_finalize; - instr = G_ARCH_INSTRUCTION_CLASS(klass); - - //instr->print = (print_instruction_fc)g_dalvik_switch_instr_print; - } @@ -114,7 +112,7 @@ static void g_dalvik_switch_instr_class_init(GDalvikSwitchInstrClass *klass) static void g_dalvik_switch_instr_init(GDalvikSwitchInstr *instr) { - G_DALVIK_INSTRUCTION(instr)->keyword = "##switch##"; + G_DALVIK_INSTRUCTION(instr)->keyword = "switch-data"; } @@ -152,6 +150,12 @@ static void g_dalvik_switch_instr_dispose(GDalvikSwitchInstr *instr) static void g_dalvik_switch_instr_finalize(GDalvikSwitchInstr *instr) { + if (instr->keys != NULL) + free(instr->keys); + + if (instr->targets != NULL) + free(instr->targets); + G_OBJECT_CLASS(g_dalvik_switch_instr_parent_class)->finalize(G_OBJECT(instr)); } @@ -160,6 +164,7 @@ static void g_dalvik_switch_instr_finalize(GDalvikSwitchInstr *instr) /****************************************************************************** * * * Paramètres : ident = identifiant de l'instruction déjà lu. * +* ctx = contexte lié à l'exécution du processeur. * * content = flux de données à analyser. * * pos = position courante dans ce flux. [OUT] * * * @@ -171,7 +176,7 @@ static void g_dalvik_switch_instr_finalize(GDalvikSwitchInstr *instr) * * ******************************************************************************/ -GArchInstruction *g_dalvik_switch_instr_new(uint16_t ident, const GBinContent *content, vmpa2t *pos) +GArchInstruction *g_dalvik_switch_instr_new(uint16_t ident, GDalvikContext *ctx, const GBinContent *content, vmpa2t *pos) { GDalvikSwitchInstr *result; /* Structure à retourner */ phys_t consumed; /* Données consommées */ @@ -185,16 +190,17 @@ GArchInstruction *g_dalvik_switch_instr_new(uint16_t ident, const GBinContent *c if (!g_binary_content_read_u16(content, pos, SRE_LITTLE, &result->switch_size)) goto gdsin_bad; + if (!g_dalvik_switch_decode_data(result, content, pos)) + goto gdsin_bad; + if (ident != DPO_PACKED_SWITCH) consumed = (1 + result->switch_size) * sizeof(uint32_t); else consumed = (2 * result->switch_size) * sizeof(uint32_t); - if (!g_binary_content_seek(content, pos, consumed)) + if (!g_dalvik_context_register_switch_data(ctx, pos, consumed)) goto gdsin_bad; - g_arch_instruction_set_displayed_max_length(G_ARCH_INSTRUCTION(result), 4); - return G_ARCH_INSTRUCTION(result); gdsin_bad: @@ -208,70 +214,88 @@ GArchInstruction *g_dalvik_switch_instr_new(uint16_t ident, const GBinContent *c /****************************************************************************** * * -* Paramètres : instr = instruction d'assemblage à représenter. * -* buffer = espace où placer ledit contenu. * -* syntax = type de représentation demandée. * +* Paramètres : instr = instruction d'assemblage à compléter. * +* content = flux de données à analyser. * +* pos = position de lecture courante dans ce flux. * * * -* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. * +* Description : Lit toutes les valeurs associés aux branchements. * * * -* Retour : - * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -static void g_dalvik_switch_instr_print(GDalvikSwitchInstr *instr, GCodeBuffer *buffer, MemoryDataSize msize, const bin_t *content, AsmSyntax syntax) +static bool g_dalvik_switch_decode_data(GDalvikSwitchInstr *instr, const GBinContent *content, const vmpa2t *pos) { - GArchInstruction *base; /* Version basique de l'objet */ - GBufferLine *line; /* Ligne de destination */ - char address[VMPA_MAX_SIZE]; /* Adresse au format texte */ - size_t len; /* Taille de l'élément inséré */ - char *bin_code; /* Tampon du code binaire */ - off_t i; /* Boucle de parcours */ - const char *key; /* Mot clef principal */ - size_t klen; /* Taille de ce mot clef */ + vmpa2t iter; /* Position modifiable */ + uint32_t first_key; /* Première clef */ + uint16_t i; /* Boucle de parcours */ - base = G_ARCH_INSTRUCTION(instr); + instr->keys = (uint32_t *)calloc(instr->switch_size, sizeof(uint32_t)); + instr->targets = (uint32_t *)calloc(instr->switch_size, sizeof(uint32_t)); - line = NULL; + copy_vmpa(&iter, pos); - //line = g_code_buffer_prepare_new_line(buffer, &range); - -#if 0 - line = g_code_buffer_append_new_line(buffer, base->address); + if (G_DALVIK_INSTRUCTION(instr)->ptype == DPO_PACKED_SWITCH) + { + if (!g_binary_content_read_u32(content, &iter, SRE_LITTLE, &first_key)) + goto gdsdd_bad; - /* Adresse virtuelle ou physique */ + for (i = 0; i < instr->switch_size; i++) + { + instr->keys[i] = first_key + i; - len = vmpa_to_string(base->address, msize, address); + if (!g_binary_content_read_u32(content, &iter, SRE_LITTLE, &instr->targets[i])) + goto gdsdd_bad; - g_buffer_line_insert_text(line, BLC_PHYSICAL, address, len, RTT_RAW); + } - /* TODO ... */ + } - /* Code brut */ + else + { + for (i = 0; i < instr->switch_size; i++) + if (!g_binary_content_read_u32(content, &iter, SRE_LITTLE, &instr->keys[i])) + goto gdsdd_bad; - bin_code = (char *)calloc(3 * 3 + 3, sizeof(char)); + for (i = 0; i < instr->switch_size; i++) + if (!g_binary_content_read_u32(content, &iter, SRE_LITTLE, &instr->targets[i])) + goto gdsdd_bad; - for (i = 0; i < 3; i++) - { - if ((i + 1) < 3) - snprintf(&bin_code[i * (2 + 1)], 4, "%02hhx ", content[base->offset + i]); - else - snprintf(&bin_code[i * (2 + 1)], 6, "%02hhx...", content[base->offset + i]); } - g_buffer_line_insert_text(line, BLC_BINARY, - bin_code, 3 * 3 + 2, RTT_RAW_CODE); + return true; + + gdsdd_bad: - free(bin_code); + return false; + +} -#endif - /* Instruction proprement dite */ +/****************************************************************************** +* * +* Paramètres : instr = instruction d'assemblage à compléter. * +* keys = tableau renseignant les conditions de saut. [OUT] * +* targets = tableau renseignant les sauts relatifs. [OUT] * +* * +* Description : Fournit les données associées à un branchement Dalvik. * +* * +* Retour : Taille des tableaux renseignés. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint16_t g_dalvik_switch_get_data(GDalvikSwitchInstr *instr, const uint32_t **keys, const uint32_t **targets) +{ + if (keys != NULL) + *keys = instr->keys; - key = "<fill-array>"; - klen = strlen(key); + if (targets != NULL) + *targets = instr->targets; - g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION); + return instr->switch_size; } diff --git a/src/arch/dalvik/pseudo/switch.h b/src/arch/dalvik/pseudo/switch.h index 02d61d0..ae52758 100644 --- a/src/arch/dalvik/pseudo/switch.h +++ b/src/arch/dalvik/pseudo/switch.h @@ -25,6 +25,7 @@ #define _ARCH_DALVIK_PSEUDO_SWITCH_H +#include "../context.h" #include "../instruction.h" #include "../processor.h" @@ -33,10 +34,12 @@ -#define G_TYPE_DALVIK_SWITCH_INSTR g_dalvik_switch_instr_get_type() -#define G_DALVIK_SWITCH_INSTR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dalvik_switch_instr_get_type(), GDalvikSwitchInstr)) -#define G_IS_DALVIK_SWITCH_INSTR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dalvik_switch_instr_get_type())) -#define G_DALVIK_SWITCH_INSTR_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_dalvik_switch_instr_get_type(), GDalvikSwitchInstrIface)) +#define G_TYPE_DALVIK_SWITCH_INSTR g_dalvik_switch_instr_get_type() +#define G_DALVIK_SWITCH_INSTR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DALVIK_SWITCH_INSTR, GDalvikSwitchInstr)) +#define G_IS_DALVIK_SWITCH_INSTR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_DALVIK_SWITCH_INSTR)) +#define G_DALVIK_SWITCH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DALVIK_SWITCH, GGDalvikSwitchClass)) +#define G_IS_DALVIK_SWITCH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DALVIK_SWITCH)) +#define G_DALVIK_SWITCH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DALVIK_SWITCH, GGDalvikSwitchClass)) /* Définition générique d'une instruction d'architecture (instance) */ @@ -50,7 +53,10 @@ typedef struct _GDalvikSwitchInstrClass GDalvikSwitchInstrClass; GType g_dalvik_switch_instr_get_type(void); /* Crée une pesudo-instruction Dalvik de branchement. */ -GArchInstruction *g_dalvik_switch_instr_new(uint16_t, const GBinContent *, vmpa2t *); +GArchInstruction *g_dalvik_switch_instr_new(uint16_t, GDalvikContext *, const GBinContent *, vmpa2t *); + +/* Fournit les données associées à un branchement Dalvik. */ +uint16_t g_dalvik_switch_get_data(GDalvikSwitchInstr *, const uint32_t **, const uint32_t **); |