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/context.c | |
parent | f3e84729588f7e2e518f82116e908455d957f9ca (diff) |
Handled switch and fill-array data pseudo-instructions without plugin.
Diffstat (limited to 'src/arch/dalvik/context.c')
-rw-r--r-- | src/arch/dalvik/context.c | 227 |
1 files changed, 174 insertions, 53 deletions
diff --git a/src/arch/dalvik/context.c b/src/arch/dalvik/context.c index 0eb8b48..b093345 100644 --- a/src/arch/dalvik/context.c +++ b/src/arch/dalvik/context.c @@ -25,31 +25,39 @@ #include <malloc.h> +#include <stdlib.h> #include <string.h> #include "operands/register.h" #include "../context-int.h" +#include "../raw.h" +#include "../../analysis/contents/restricted.h" +#include "../../common/sort.h" #include "../../decomp/context-int.h" #include "../../decomp/expr/pseudo.h" #include "../../format/dex/dex-int.h" -/* Mémorisation d'un saut dans le code */ -typedef struct _skipped_dalvik_area skipped_dalvik_area; +/* ------------------------ MANIPULATION GLOBALE DU CONTEXTE ------------------------ */ +/* Mémorisation de données brutes dans le code */ +typedef struct _raw_data_area +{ + mrange_t range; /* Couverture à laisser en 1er */ -/* ------------------------ MANIPULATION GLOBALE DU CONTEXTE ------------------------ */ + phys_t item_len; /* Taille de chaque élément */ +} raw_data_area; /* Définition d'un contexte pour processeur Dalkvik (instance) */ struct _GDalvikContext { GProcContext parent; /* A laisser en premier */ - skipped_dalvik_area *skip; /* Liste de Zones à écarter */ + raw_data_area *data; /* Liste de zones brutes */ size_t count; /* Taille de cette liste */ }; @@ -69,18 +77,11 @@ static void g_dalvik_context_class_init(GDalvikContextClass *); /* Initialise une instance de contexte de processeur Dalkvik. */ static void g_dalvik_context_init(GDalvikContext *); +/* Supprime toutes les références externes. */ +static void g_dalvik_context_dispose(GDalvikContext *); - -/* ------------------------- MEMORISATION DES SAUTS DE CODE ------------------------- */ - - -/* Mémorisation d'un saut dans le code */ -struct _skipped_dalvik_area -{ - vmpa_t start; /* Début de la zone concernée */ - vmpa_t end; /* Fin de la zone concernée */ - -}; +/* Procède à la libération totale de la mémoire. */ +static void g_dalvik_context_finalize(GDalvikContext *); @@ -154,6 +155,12 @@ G_DEFINE_TYPE(GDalvikContext, g_dalvik_context, G_TYPE_PROC_CONTEXT); static void g_dalvik_context_class_init(GDalvikContextClass *klass) { + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_dalvik_context_dispose; + object->finalize = (GObjectFinalizeFunc)g_dalvik_context_finalize; } @@ -178,6 +185,47 @@ static void g_dalvik_context_init(GDalvikContext *ctx) /****************************************************************************** * * +* Paramètres : ctx = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_context_dispose(GDalvikContext *ctx) +{ + G_OBJECT_CLASS(g_dalvik_context_parent_class)->dispose(G_OBJECT(ctx)); + +} + + +/****************************************************************************** +* * +* Paramètres : ctx = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_context_finalize(GDalvikContext *ctx) +{ + if (ctx->data != NULL) + free(ctx->data); + + G_OBJECT_CLASS(g_dalvik_context_parent_class)->finalize(G_OBJECT(ctx)); + +} + + +/****************************************************************************** +* * * Paramètres : - * * * * Description : Crée un contexte pour l'exécution du processeur Dalvik. * @@ -199,82 +247,155 @@ GDalvikContext *g_dalvik_context_new(void) } +/****************************************************************************** +* * +* Paramètres : ctx = contexte de désassemblage Dalvik à actualiser. * +* start = début de la zone à considérer. * +* length = taille de la zone couverte. * +* * +* Description : Mémorise une zone comme étant des données de branchements. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ -/* ---------------------------------------------------------------------------------- */ -/* MEMORISATION DES SAUTS DE CODE */ -/* ---------------------------------------------------------------------------------- */ +bool g_dalvik_context_register_switch_data(GDalvikContext *ctx, const vmpa2t *start, phys_t length) +{ + bool result; /* Bilan à retourner */ + raw_data_area new; /* Nouvel élément à insérer */ + size_t i; /* Boucle de parcours */ + + result = true; + + /* Vérification quant aux chevauchements */ + + init_mrange(&new.range, start, length); + + for (i = 0; i < ctx->count && result; i++) + result = !mrange_intersects_mrange(&ctx->data[i].range, &new.range); + + /* Insertion d'une nouvelle zone */ + + if (result) + { + new.item_len = 4; + + ctx->data = qinsert(ctx->data, &ctx->count, sizeof(raw_data_area), + (__compar_fn_t)cmp_mrange_with_vmpa_swapped, &new); + + } + + return result; + +} /****************************************************************************** * * -* Paramètres : ctx = instance à mettre à jour. * -* start = début de la zone à écarter du traitement. * -* end = fin de la zone à écarter du traitement. * +* Paramètres : ctx = contexte de désassemblage Dalvik à actualiser. * +* start = début de la zone à considérer. * +* width = taille de chacun des éléments. * +* length = taille de la zone couverte. * * * -* Description : Mémorise une nouvelle zone de code comme étant des données. * +* Description : Mémorise une zone comme étant des données d'un tableau. * * * -* Retour : - * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -void g_dalvik_context_skip_new_area(GDalvikContext *ctx, vmpa_t start, vmpa_t end) +bool g_dalvik_context_register_array_data(GDalvikContext *ctx, const vmpa2t *start, uint16_t width, phys_t length) { - ctx->skip = (skipped_dalvik_area *)realloc(ctx->skip, - ++ctx->count * sizeof(skipped_dalvik_area)); + bool result; /* Bilan à retourner */ + raw_data_area new; /* Nouvel élément à insérer */ + size_t i; /* Boucle de parcours */ + + result = true; + + /* Vérification quant aux chevauchements */ + + init_mrange(&new.range, start, length); + + for (i = 0; i < ctx->count && result; i++) + result = !mrange_intersects_mrange(&ctx->data[i].range, &new.range); + + /* Insertion d'une nouvelle zone */ + + if (result) + { + new.item_len = width; + + ctx->data = qinsert(ctx->data, &ctx->count, sizeof(raw_data_area), + (__compar_fn_t)cmp_mrange_with_vmpa_swapped, &new); + + } - ctx->skip[ctx->count - 1].start = start; - ctx->skip[ctx->count - 1].end = end; + return result; } /****************************************************************************** * * -* Paramètres : ctx = instance à consulter. * -* addr = adresse à mainupuler. * +* Paramètres : ctx = contexte de désassemblage Dalvik à consulter. * +* content = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * * * -* Description : Indique si l'adresse est considérée comme zone de données. * +* Description : Place une donnée en tant qu'instruction si besoin est. * * * -* Retour : true si l'adresse est considérée comme zone de données. * +* Retour : Instruction mise en place ou NULL en cas d'échec. * * * * Remarques : - * * * ******************************************************************************/ -bool g_dalvik_context_have_to_skip(GDalvikContext *ctx, vmpa_t addr) +GArchInstruction *g_dalvik_context_get_raw_data(GDalvikContext *ctx, const GBinContent *content, vmpa2t *pos) { - bool result; /* verdict à retourner */ - size_t i; /* Boucle de parcours */ + GArchInstruction *result; /* Instruction à retourner */ + raw_data_area *found; /* Zone de couverture trouvée */ + GBinContent *restricted; /* Zone de lecture effective */ - result = false; + result = NULL; - for (i = 0; i < ctx->count && !result; i++) - if (ctx->skip[i].start <= addr && addr < ctx->skip[i].end) - { - result = true; - ctx->skip[i].start += sizeof(uint16_t); + found = bsearch(pos, ctx->data, ctx->count, sizeof(raw_data_area), + (__compar_fn_t)cmp_mrange_with_vmpa_swapped); - /* BUG_ON(ctx->skip[i].start > ctx->skip[i].end) */ + if (found) + { + restricted = g_restricted_content_new_ro(content, &found->range); - if (ctx->skip[i].start >= ctx->skip[i].end) - { - if (i <= (ctx->count - 1)) - memmove(&ctx->skip[i], &ctx->skip[i + 1], ctx->count - i - 1); + switch (found->item_len) + { + case 1: + result = g_raw_instruction_new_array(restricted, MDS_8_BITS_UNSIGNED, 1, pos, SRE_LITTLE); + break; - if (--ctx->count == 0) - ctx->skip = NULL; - else - ctx->skip = (skipped_dalvik_area *)realloc(ctx->skip, - ++ctx->count * sizeof(skipped_dalvik_area)); + case 2: + result = g_raw_instruction_new_array(restricted, MDS_16_BITS_UNSIGNED, 1, pos, SRE_LITTLE); + break; - } + case 4: + result = g_raw_instruction_new_array(restricted, MDS_32_BITS_UNSIGNED, 1, pos, SRE_LITTLE); + break; + + case 8: + result = g_raw_instruction_new_array(restricted, MDS_64_BITS_UNSIGNED, 1, pos, SRE_LITTLE); + break; - break; + default: + result = g_raw_instruction_new_array(restricted, MDS_8_BITS_UNSIGNED, + found->item_len, pos, SRE_LITTLE); + break; } + g_object_unref(G_OBJECT(restricted)); + + } + return result; } |