diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2012-07-29 21:41:52 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2012-07-29 21:41:52 (GMT) |
commit | 8e1f2335773a9025cd46d45a33261725707af3ba (patch) | |
tree | 6001a1095985514bbde3c8ec49b4dd5d32182fc8 /src/arch/dalvik/context.c | |
parent | 8b35a66464636d0c46237af7490a6ca6866ecc4d (diff) |
Updated all decompiled instructions using right pseudo registers.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@253 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/arch/dalvik/context.c')
-rw-r--r-- | src/arch/dalvik/context.c | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/src/arch/dalvik/context.c b/src/arch/dalvik/context.c index 67c1861..c7b5ee6 100644 --- a/src/arch/dalvik/context.c +++ b/src/arch/dalvik/context.c @@ -28,7 +28,11 @@ #include <string.h> +#include "operands/register.h" #include "../context-int.h" +#include "../../decomp/context-int.h" +#include "../../decomp/expr/pseudo.h" +#include "../../format/dex/dex-int.h" @@ -36,6 +40,7 @@ typedef struct _skipped_dalvik_area skipped_dalvik_area; + /* ------------------------ MANIPULATION GLOBALE DU CONTEXTE ------------------------ */ @@ -79,6 +84,41 @@ struct _skipped_dalvik_area +/* ------------------------- CONTEXTE POUR LA DECOMPILATION ------------------------- */ + + +/* Définition d'un contexte pour décompilation Dalkvik (instance) */ +struct _GDalvikDContext +{ + GDecContext parent; /* A laisser en premier */ + + GDecInstruction *this; /* Représentation de la classe */ + GHashTable *args; /* Correspondance arg./pseudo */ + GHashTable *locals; /* Correspondance var./pseudo */ + size_t locals_count; /* Quantité de var. locales */ + +}; + + +/* Définition d'un contexte pour décompilation Dalkvik (classe) */ +struct _GDalvikDContextClass +{ + GDecContextClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des contextes de décompilation Dalkvik. */ +static void g_dalvik_dcontext_class_init(GDalvikDContextClass *); + +/* Initialise une instance de contexte de décompilation Dalkvik. */ +static void g_dalvik_dcontext_init(GDalvikDContext *); + +/* Convertit un registre machine en un pseudo-registre. */ +static GDecInstruction *g_dalvik_dcontext_convert_register(GDalvikDContext *, GDalvikRegisterOperand *, bool); + + + /* ---------------------------------------------------------------------------------- */ /* MANIPULATION GLOBALE DU CONTEXTE */ /* ---------------------------------------------------------------------------------- */ @@ -227,3 +267,187 @@ bool g_dalvik_context_have_to_skip(GDalvikContext *ctx, vmpa_t addr) return result; } + + + +/* ---------------------------------------------------------------------------------- */ +/* CONTEXTE POUR LA DECOMPILATION */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type définit par la GLib pour le contexte de décompilation Dalkvik. */ +G_DEFINE_TYPE(GDalvikDContext, g_dalvik_dcontext, G_TYPE_DEC_CONTEXT); + + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des contextes de décompilation Dalkvik. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_dcontext_class_init(GDalvikDContextClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : ctx = instance à initialiser. * +* * +* Description : Initialise une instance de contexte de décompilation Dalkvik.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_dcontext_init(GDalvikDContext *ctx) +{ + GDecContext *parent; /* Instance parente */ + + ctx->args = g_hash_table_new(g_constant_hash, g_direct_equal); + ctx->locals = g_hash_table_new(g_constant_hash, g_direct_equal); + + parent = G_DEC_CONTEXT(ctx); + + parent->convert_reg = (convert_register_fc)g_dalvik_dcontext_convert_register; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée un contexte pour la décompilation Dalvik. * +* * +* Retour : Contexte mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDalvikDContext *g_dalvik_dcontext_new(void) +{ + GDalvikDContext *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_DALVIK_DCONTEXT, NULL); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : ctx = instance à consulter, voire mettre à jour. * +* operand = opérande représentant un registre quelconque. * +* assign = précise le sort prochain du registre. * +* * +* Description : Convertit un registre machine en un pseudo-registre. * +* * +* Retour : Pseudo-registre, existant ou non, prêt à emploi. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GDecInstruction *g_dalvik_dcontext_convert_register(GDalvikDContext *ctx, GDalvikRegisterOperand *operand, bool assign) +{ + GDecInstruction *result; /* Instance à retourner */ + GDexFormat *format; /* Recherche de méthode */ + GBinRoutine *routine; /* Objet des recherches */ + GDexMethod *method; /* Méthode décompilée */ + GDalvikRegister *reg; /* Registre Dalvik représenté */ + uint16_t index; /* Identifiant du registre */ + DexVariableIndex info; /* Nature du registre */ + GBinVariable *this; /* Définition de "this" */ + gpointer *found; /* Pseudo-registre trouvé */ + + format = G_DEX_FORMAT(g_object_get_data(G_OBJECT(ctx), "format")); + routine = G_BIN_ROUTINE(g_object_get_data(G_OBJECT(ctx), "routine")); + + method = g_dex_format_find_method_by_address(format, g_binary_routine_get_address(routine)); + + reg = g_dalvik_register_operand_get(operand); + + index = g_dalvik_register_get_index(reg); + info = g_dex_method_get_variable(method, index); + + /* Objet "this" */ + if (info & DVI_THIS) + { + if (ctx->this != NULL) + g_object_ref(G_OBJECT(ctx->this)); + + else + { + this = g_binary_variable_new(/* FIXME */g_basic_type_new(BTP_OTHER) /* FIXME */); + g_binary_variable_set_name(this, "this"); + + ctx->this = g_pseudo_register_new(); + g_pseudo_register_set_variable(G_PSEUDO_REGISTER(ctx->this), this); + + } + + result = ctx->this; + + } + + /* Argument d'appel */ + else if (info & DVI_ARGUMENT) + { + found = g_hash_table_lookup(ctx->args, GUINT_TO_POINTER(DVI_INDEX(info))); + + if (found != NULL) + { + g_object_ref(G_OBJECT(found)); + result = G_DEC_INSTRUCTION(found); + } + else + { + result = g_pseudo_register_new(); + g_pseudo_register_set_basename(G_PSEUDO_REGISTER(result), "arg"); + g_pseudo_register_set_index(G_PSEUDO_REGISTER(result), DVI_INDEX(info)); + + g_hash_table_insert(ctx->args, GUINT_TO_POINTER(DVI_INDEX(info)), result); + + } + + } + + /* Variable locale */ + else + { + found = g_hash_table_lookup(ctx->locals, GUINT_TO_POINTER(DVI_INDEX(info))); + + if (!assign && found != NULL) + { + g_object_ref(G_OBJECT(found)); + result = G_DEC_INSTRUCTION(found); + } + else + { + result = g_pseudo_register_new(); + g_pseudo_register_set_basename(G_PSEUDO_REGISTER(result), "var"); + g_pseudo_register_set_index(G_PSEUDO_REGISTER(result), ctx->locals_count); + + g_hash_table_insert(ctx->locals, GUINT_TO_POINTER(DVI_INDEX(info)), result); + ctx->locals_count++; + + } + + } + + return result; + +} |