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 | |
| 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
38 files changed, 752 insertions, 141 deletions
| @@ -1,3 +1,69 @@ +12-07-29  Cyrille Bagard <nocbos@gmail.com> + +	* src/analysis/decomp/decompiler.c: +	Decompile using a new loaded context. + +	* src/arch/dalvik/context.c: +	* src/arch/dalvik/context.h: +	Allow definitions of decompilation context by processor. + +	* src/arch/dalvik/decomp/aget.c: +	* src/arch/dalvik/decomp/aput.c: +	* src/arch/dalvik/decomp/arithm.c: +	* src/arch/dalvik/decomp/array.c: +	* src/arch/dalvik/decomp/const.c: +	* src/arch/dalvik/decomp/if.c: +	* src/arch/dalvik/decomp/iget.c: +	* src/arch/dalvik/decomp/invoke.c: +	* src/arch/dalvik/decomp/iput.c: +	* src/arch/dalvik/decomp/move.c: +	* src/arch/dalvik/decomp/new.c: +	* src/arch/dalvik/decomp/ret.c: +	Update all decompiled instructions using right pseudo registers. + +	* src/arch/dalvik/operands/register.c: +	* src/arch/dalvik/operands/register.h: +	Provide the index of a given register. + +	* src/arch/dalvik/processor.c: +	Allow definitions of decompilation context by processor. + +	* src/arch/dalvik/register.c: +	* src/arch/dalvik/register.h: +	Provide the internal version of Dalvik registers. + +	* src/arch/processor.c: +	* src/arch/processor.h: +	* src/arch/processor-int.h: +	* src/decomp/context.c: +	* src/decomp/context.h: +	Allow definitions of decompilation context by processor. + +	* src/decomp/context-int.h: +	New entry: allow definitions by processor. + +	* src/decomp/expr/pseudo.c: +	* src/decomp/expr/pseudo.h: +	Define a name for each register. + +	* src/decomp/Makefile.am: +	Add the context-int.h file to libdecomp_la_SOURCES. + +	* src/format/dex/class.c: +	* src/format/dex/class.h: +	* src/format/dex/dex.c: +	* src/format/dex/dex-int.h: +	Find methods by addresses. + +	* src/format/dex/method.c: +	* src/format/dex/method.h: +	Provide the offset of methods and information about used registers. + +	* src/format/format.c: +	* src/format/format.h: +	Use the provided decompilation context and attach the current routine. + +  12-07-23  Cyrille Bagard <nocbos@gmail.com>  	* src/analysis/routine.c: diff --git a/src/analysis/decomp/decompiler.c b/src/analysis/decomp/decompiler.c index b144846..24cd242 100644 --- a/src/analysis/decomp/decompiler.c +++ b/src/analysis/decomp/decompiler.c @@ -130,16 +130,19 @@ static void build_decomp_prologue(GCodeBuffer *buffer, const char *filename)  static void prepare_all_routines_for_decomp(const GOpenidaBinary *binary, const char *filename)  {      GExeFormat *format;                     /* Format du binaire fourni    */ +    GArchProcessor *proc;                   /* Architecture du binaire     */      GBinRoutine **routines;      size_t count;      size_t i; +    GDecContext *context;                   /* Contexte pour la décompil.  */      GDecInstruction *instr;      format = g_openida_binary_get_format(binary); -     +    proc = get_arch_processor_from_format(G_EXE_FORMAT(format)); +      routines = g_binary_format_get_routines(G_BIN_FORMAT(format), &count); @@ -147,16 +150,14 @@ static void prepare_all_routines_for_decomp(const GOpenidaBinary *binary, const      for (i = 0; i < count; i++)      { -        printf(" -- %s --\n", g_binary_routine_get_name(routines[i])); +        context = g_arch_processor_get_decomp_context(proc); -        //if (strcmp("fib2", g_binary_routine_get_name(routines[i])) == 0) -        { - -            printf("...\n"); +        printf(" -- %s --\n", g_binary_routine_get_name(routines[i])); -            instr = g_binary_format_decompile_routine(G_BIN_FORMAT(format), routines[i]); +        instr = g_binary_format_decompile_routine(G_BIN_FORMAT(format), routines[i], context); -        } +        if (context != NULL) +            g_object_unref(context);      } 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; + +} diff --git a/src/arch/dalvik/context.h b/src/arch/dalvik/context.h index 459cc22..c1c93a4 100644 --- a/src/arch/dalvik/context.h +++ b/src/arch/dalvik/context.h @@ -30,6 +30,7 @@  #include "../archbase.h" +#include "../../decomp/context.h" @@ -70,4 +71,30 @@ bool g_dalvik_context_have_to_skip(GDalvikContext *, vmpa_t); +/* ------------------------- CONTEXTE POUR LA DECOMPILATION ------------------------- */ + + +#define G_TYPE_DALVIK_DCONTEXT              g_dalvik_dcontext_get_type() +#define G_DALVIK_DCONTEXT(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dalvik_dcontext_get_type(), GDalvikDContext)) +#define G_IS_DALVIK_DCONTEXT(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dalvik_dcontext_get_type())) +#define G_DALVIK_DCONTEXT_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DALVIK_DCONTEXT, GGDalvikDContextClass)) +#define G_IS_DALVIK_DCONTEXT_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DALVIK_DCONTEXT)) +#define G_DALVIK_DCONTEXT_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DALVIK_DCONTEXT, GGDalvikDContextClass)) + + +/* Définition d'un contexte pour décompilation Dalkvik (instance) */ +typedef struct _GDalvikDContext GDalvikDContext; + +/* Définition d'un contexte pour décompilation Dalkvik (classe) */ +typedef struct _GDalvikDContextClass GDalvikDContextClass; + + +/* Indique le type définit par la GLib pour le contexte de décompilation Dalkvik. */ +GType g_dalvik_dcontext_get_type(void); + +/* Crée un contexte pour la décompilation Dalvik. */ +GDalvikDContext *g_dalvik_dcontext_new(void); + + +  #endif  /* _ARCH_DALVIK_CONTEXT_H */ diff --git a/src/arch/dalvik/decomp/aget.c b/src/arch/dalvik/decomp/aget.c index 41b7e34..0fa66eb 100644 --- a/src/arch/dalvik/decomp/aget.c +++ b/src/arch/dalvik/decomp/aget.c @@ -2,7 +2,7 @@  /* OpenIDA - Outil d'analyse de fichiers binaires   * aget.c - décompilation des instructions manipulant des tableaux (chargement)   * - * Copyright (C) 2010-2011 Cyrille Bagard + * Copyright (C) 2010-2012 Cyrille Bagard   *   *  This file is part of OpenIDA.   * @@ -46,19 +46,19 @@ GDecInstruction *dalvik_decomp_instr_aget(const GArchInstruction *instr, GDecCon  {      GDecInstruction *result;                /* Instruction à retourner     */      GArchOperand *operand;                  /* Opérande de l'instruction   */ -    GDecInstruction *content;               /* Contenu de cellule visé     */      GDecInstruction *array;                 /* Tableau accédé              */      GDecInstruction *index;                 /* Indice de cellule considérée*/ +    GDecInstruction *content;               /* Contenu de cellule visé     */      GDecInstruction *access;                /* Représentation de l'accès   */ -    operand = g_arch_instruction_get_operand(instr, 0); -    content = g_dec_context_convert_register(ctx, operand); -      operand = g_arch_instruction_get_operand(instr, 1); -    array = g_dec_context_convert_register(ctx, operand); +    array = g_dec_context_convert_register(ctx, operand, false);      operand = g_arch_instruction_get_operand(instr, 2); -    index = g_dec_context_convert_register(ctx, operand); +    index = g_dec_context_convert_register(ctx, operand, false); + +    operand = g_arch_instruction_get_operand(instr, 0); +    content = g_dec_context_convert_register(ctx, operand, true);      access = g_array_access_new(G_DEC_EXPRESSION(array), G_DEC_EXPRESSION(index));      result = g_assign_expression_new(G_DEC_EXPRESSION(content), G_DEC_EXPRESSION(access)); diff --git a/src/arch/dalvik/decomp/aput.c b/src/arch/dalvik/decomp/aput.c index 8d86789..41bd89f 100644 --- a/src/arch/dalvik/decomp/aput.c +++ b/src/arch/dalvik/decomp/aput.c @@ -2,7 +2,7 @@  /* OpenIDA - Outil d'analyse de fichiers binaires   * aput.c - décompilation des instructions manipulant des tableaux (enregistrement)   * - * Copyright (C) 2010-2011 Cyrille Bagard + * Copyright (C) 2010-2012 Cyrille Bagard   *   *  This file is part of OpenIDA.   * @@ -52,13 +52,13 @@ GDecInstruction *dalvik_decomp_instr_aput(const GArchInstruction *instr, GDecCon      GDecInstruction *access;                /* Représentation de l'accès   */      operand = g_arch_instruction_get_operand(instr, 0); -    content = g_dec_context_convert_register(ctx, operand); +    content = g_dec_context_convert_register(ctx, operand, false);      operand = g_arch_instruction_get_operand(instr, 1); -    array = g_dec_context_convert_register(ctx, operand); +    array = g_dec_context_convert_register(ctx, operand, false);      operand = g_arch_instruction_get_operand(instr, 2); -    index = g_dec_context_convert_register(ctx, operand); +    index = g_dec_context_convert_register(ctx, operand, false);      access = g_array_access_new(G_DEC_EXPRESSION(array), G_DEC_EXPRESSION(index));      result = g_assign_expression_new(G_DEC_EXPRESSION(access), G_DEC_EXPRESSION(content)); diff --git a/src/arch/dalvik/decomp/arithm.c b/src/arch/dalvik/decomp/arithm.c index 257c59a..a217adf 100644 --- a/src/arch/dalvik/decomp/arithm.c +++ b/src/arch/dalvik/decomp/arithm.c @@ -2,7 +2,7 @@  /* OpenIDA - Outil d'analyse de fichiers binaires   * arithm.c - décompilation des opérations arithmétiques   * - * Copyright (C) 2010-2011 Cyrille Bagard + * Copyright (C) 2010-2012 Cyrille Bagard   *   *  This file is part of OpenIDA.   * @@ -49,9 +49,9 @@ GDecInstruction *dalvik_decomp_instr_arithm(const GArchInstruction *instr, GDecC      GDecInstruction *result;                /* Instruction à retourner     */      ArithmOperationType type;               /* Type d'opération menée      */      GArchOperand *operand;                  /* Opérande de l'instruction   */ -    GDecInstruction *dest;                  /* Enregistrement du résultat  */      GDecInstruction *op1;                   /* Premier opérande utilisé    */      GDecInstruction *op2;                   /* Second opérande utilisé     */ +    GDecInstruction *dest;                  /* Enregistrement du résultat  */      GDecInstruction *arithm;                /* Opération arithmétique      */      switch (g_dalvik_instruction_get_opcode(G_DALVIK_INSTRUCTION(instr))) @@ -85,14 +85,14 @@ GDecInstruction *dalvik_decomp_instr_arithm(const GArchInstruction *instr, GDecC              break;      } -    operand = g_arch_instruction_get_operand(instr, 0); -    dest = g_dec_context_convert_register(ctx, operand); -      operand = g_arch_instruction_get_operand(instr, 1); -    op1 = g_dec_context_convert_register(ctx, operand); +    op1 = g_dec_context_convert_register(ctx, operand, false);      operand = g_arch_instruction_get_operand(instr, 2); -    op2 = g_dec_context_convert_register(ctx, operand); +    op2 = g_dec_context_convert_register(ctx, operand, false); + +    operand = g_arch_instruction_get_operand(instr, 0); +    dest = g_dec_context_convert_register(ctx, operand, true);      arithm = g_arithm_expression_new(G_DEC_EXPRESSION(op1), type, G_DEC_EXPRESSION(op2));      result = g_assign_expression_new(G_DEC_EXPRESSION(dest), G_DEC_EXPRESSION(arithm)); @@ -120,8 +120,8 @@ GDecInstruction *dalvik_decomp_instr_arithm_2addr(const GArchInstruction *instr,      GDecInstruction *result;                /* Instruction à retourner     */      ArithmOperationType type;               /* Type d'opération menée      */      GArchOperand *operand;                  /* Opérande de l'instruction   */ -    GDecInstruction *dest;                  /* Enregistrement du résultat  */      GDecInstruction *op1;                   /* Premier opérande utilisé    */ +    GDecInstruction *dest;                  /* Enregistrement du résultat  */      GDecInstruction *arithm;                /* Opération arithmétique      */      switch (g_dalvik_instruction_get_opcode(G_DALVIK_INSTRUCTION(instr))) @@ -153,11 +153,11 @@ GDecInstruction *dalvik_decomp_instr_arithm_2addr(const GArchInstruction *instr,              break;      } -    operand = g_arch_instruction_get_operand(instr, 0); -    dest = g_dec_context_convert_register(ctx, operand); -      operand = g_arch_instruction_get_operand(instr, 1); -    op1 = g_dec_context_convert_register(ctx, operand); +    op1 = g_dec_context_convert_register(ctx, operand, false); + +    operand = g_arch_instruction_get_operand(instr, 0); +    dest = g_dec_context_convert_register(ctx, operand, true);      arithm = g_arithm_expression_new(G_DEC_EXPRESSION(dest), type, G_DEC_EXPRESSION(op1));      result = g_assign_expression_new(G_DEC_EXPRESSION(dest), G_DEC_EXPRESSION(arithm)); @@ -185,9 +185,9 @@ GDecInstruction *dalvik_decomp_instr_arithm_lit(const GArchInstruction *instr, G      GDecInstruction *result;                /* Instruction à retourner     */      ArithmOperationType type;               /* Type d'opération menée      */      GArchOperand *operand;                  /* Opérande de l'instruction   */ -    GDecInstruction *dest;                  /* Enregistrement du résultat  */      GDecInstruction *op1;                   /* Premier opérande utilisé    */      GDecInstruction *op2;                   /* Second opérande utilisé     */ +    GDecInstruction *dest;                  /* Enregistrement du résultat  */      GDecInstruction *arithm;                /* Opération arithmétique      */      switch (g_dalvik_instruction_get_opcode(G_DALVIK_INSTRUCTION(instr))) @@ -225,15 +225,15 @@ GDecInstruction *dalvik_decomp_instr_arithm_lit(const GArchInstruction *instr, G              break;      } -    operand = g_arch_instruction_get_operand(instr, 0); -    dest = g_dec_context_convert_register(ctx, operand); -      operand = g_arch_instruction_get_operand(instr, 1); -    op1 = g_dec_context_convert_register(ctx, operand); +    op1 = g_dec_context_convert_register(ctx, operand, false);      operand = g_arch_instruction_get_operand(instr, 2);      op2 = g_imm_expression_new(G_IMM_OPERAND(operand)); +    operand = g_arch_instruction_get_operand(instr, 0); +    dest = g_dec_context_convert_register(ctx, operand, true); +      arithm = g_arithm_expression_new(G_DEC_EXPRESSION(op1), type, G_DEC_EXPRESSION(op2));      result = g_assign_expression_new(G_DEC_EXPRESSION(dest), G_DEC_EXPRESSION(arithm)); diff --git a/src/arch/dalvik/decomp/array.c b/src/arch/dalvik/decomp/array.c index a841986..3422461 100644 --- a/src/arch/dalvik/decomp/array.c +++ b/src/arch/dalvik/decomp/array.c @@ -2,7 +2,7 @@  /* OpenIDA - Outil d'analyse de fichiers binaires   * array.c - décompilation de l'opération récupérant la longueur d'un tableau   * - * Copyright (C) 2010-2011 Cyrille Bagard + * Copyright (C) 2010-2012 Cyrille Bagard   *   *  This file is part of OpenIDA.   * @@ -45,29 +45,19 @@  GDecInstruction *dalvik_decomp_instr_array_length(const GArchInstruction *instr, GDecContext *ctx)  {      GDecInstruction *result;                /* Instruction à retourner     */ - -      GArchOperand *operand;                  /* Opérande de l'instruction   */      GDecInstruction *reg;                   /* Pseudo-registre redéfini    */      GDecInstruction *len;                   /* Enregistrement de taille    */ - - -    result = NULL; - - -    //printf("PAssaage !\n"); - - +    GDecInstruction *dest;                  /* Destination de la création  */      operand = g_arch_instruction_get_operand(instr, 1); -    reg = g_dec_context_convert_register(ctx, operand); +    reg = g_dec_context_convert_register(ctx, operand, false);      len = g_dalvik_alength_new(G_DEC_EXPRESSION(reg));      operand = g_arch_instruction_get_operand(instr, 0); -    reg = g_dec_context_convert_register(ctx, operand); - +    dest = g_dec_context_convert_register(ctx, operand, true); -    result = g_assign_expression_new(G_DEC_EXPRESSION(reg), G_DEC_EXPRESSION(len)); +    result = g_assign_expression_new(G_DEC_EXPRESSION(dest), G_DEC_EXPRESSION(len));      return result; diff --git a/src/arch/dalvik/decomp/const.c b/src/arch/dalvik/decomp/const.c index dce6b35..2e63b36 100644 --- a/src/arch/dalvik/decomp/const.c +++ b/src/arch/dalvik/decomp/const.c @@ -2,7 +2,7 @@  /* OpenIDA - Outil d'analyse de fichiers binaires   * const.c - décompilation des chargements de constantes   * - * Copyright (C) 2010-2011 Cyrille Bagard + * Copyright (C) 2010-2012 Cyrille Bagard   *   *  This file is part of OpenIDA.   * @@ -52,7 +52,7 @@ GDecInstruction *dalvik_decomp_instr_const(const GArchInstruction *instr, GDecCo      GDecInstruction *imm;                   /* Valeur immédiate décompilée */      operand = g_arch_instruction_get_operand(instr, 0); -    reg = g_dec_context_convert_register(ctx, operand); +    reg = g_dec_context_convert_register(ctx, operand, true);      operand = g_arch_instruction_get_operand(instr, 1);      imm = g_imm_expression_new(G_IMM_OPERAND(operand)); @@ -88,7 +88,7 @@ GDecInstruction *dalvik_decomp_instr_const_str(const GArchInstruction *instr, GD      GDecInstruction *str;                   /* Chaîne décompilée           */      operand = g_arch_instruction_get_operand(instr, 0); -    reg = g_dec_context_convert_register(ctx, operand); +    reg = g_dec_context_convert_register(ctx, operand, true);      operand = g_arch_instruction_get_operand(instr, 1);      index = g_dalvik_pool_operand_get_index(G_DALVIK_POOL_OPERAND(operand)); diff --git a/src/arch/dalvik/decomp/if.c b/src/arch/dalvik/decomp/if.c index 1a8663c..43406c7 100644 --- a/src/arch/dalvik/decomp/if.c +++ b/src/arch/dalvik/decomp/if.c @@ -2,7 +2,7 @@  /* OpenIDA - Outil d'analyse de fichiers binaires   * array.c - décompilation des branchements conditionnels   * - * Copyright (C) 2010-2011 Cyrille Bagard + * Copyright (C) 2010-2012 Cyrille Bagard   *   *  This file is part of OpenIDA.   * @@ -79,10 +79,10 @@ GDecInstruction *dalvik_decomp_instr_if(const GArchInstruction *instr, GDecConte      }      operand = g_arch_instruction_get_operand(instr, 0); -    op1 = g_dec_context_convert_register(ctx, operand); +    op1 = g_dec_context_convert_register(ctx, operand, false);      operand = g_arch_instruction_get_operand(instr, 1); -    op2 = g_dec_context_convert_register(ctx, operand); +    op2 = g_dec_context_convert_register(ctx, operand, false);      operand = g_arch_instruction_get_operand(instr, 2);      jmp = 0x1234ull;/*g_dec_context_convert_register(ctx, operand);*/ diff --git a/src/arch/dalvik/decomp/iget.c b/src/arch/dalvik/decomp/iget.c index 8b8f9f0..931438c 100644 --- a/src/arch/dalvik/decomp/iget.c +++ b/src/arch/dalvik/decomp/iget.c @@ -48,19 +48,16 @@ GDecInstruction *dalvik_decomp_instr_iget(const GArchInstruction *instr, GDecCon  {      GDecInstruction *result;                /* Instruction à retourner     */      GArchOperand *operand;                  /* Opérande de l'instruction   */ -    GDecInstruction *dest;                  /* Registre de destination     */      GDecInstruction *src;                   /* Registre de l'object        */      uint32_t index;                         /* Indice dans la table        */      GDexFormat *format;                     /* Accès aux constantes        */      GDecInstruction *field;                 /* Champ concerné par l'opérat°*/      GBinVariable *var;                      /* Variable / champ accédé     */ +    GDecInstruction *dest;                  /* Registre de destination     */      GDecInstruction *access;                /* Représentation de l'accès   */ -    operand = g_arch_instruction_get_operand(instr, 0); -    dest = g_dec_context_convert_register(ctx, operand); -      operand = g_arch_instruction_get_operand(instr, 1); -    src = g_dec_context_convert_register(ctx, operand); +    src = g_dec_context_convert_register(ctx, operand, false);      operand = g_arch_instruction_get_operand(instr, 2);      index = g_dalvik_pool_operand_get_index(G_DALVIK_POOL_OPERAND(operand)); @@ -70,6 +67,9 @@ GDecInstruction *dalvik_decomp_instr_iget(const GArchInstruction *instr, GDecCon      field = g_pseudo_register_new();      g_pseudo_register_set_variable(G_PSEUDO_REGISTER(field), var); +    operand = g_arch_instruction_get_operand(instr, 0); +    dest = g_dec_context_convert_register(ctx, operand, true); +      access = g_access_expression_new(G_DEC_EXPRESSION(src), G_DEC_EXPRESSION(field));      result = g_assign_expression_new(G_DEC_EXPRESSION(dest), G_DEC_EXPRESSION(access)); diff --git a/src/arch/dalvik/decomp/invoke.c b/src/arch/dalvik/decomp/invoke.c index a8772cd..c3650b4 100644 --- a/src/arch/dalvik/decomp/invoke.c +++ b/src/arch/dalvik/decomp/invoke.c @@ -2,7 +2,7 @@  /* OpenIDA - Outil d'analyse de fichiers binaires   * invoke.c - décompilation des appels de méthode   * - * Copyright (C) 2010-2011 Cyrille Bagard + * Copyright (C) 2010-2012 Cyrille Bagard   *   *  This file is part of OpenIDA.   * @@ -128,7 +128,7 @@ GDecInstruction *dalvik_decomp_instr_invoke_direct(const GArchInstruction *instr      for (i = 1; i < count; i++)      {          arg = g_dalvik_args_operand_get(G_DALVIK_ARGS_OPERAND(operand), i); -        reg = g_dec_context_convert_register(ctx, arg); +        reg = g_dec_context_convert_register(ctx, arg, false);          g_routine_call_add_arg(G_ROUTINE_CALL(result), reg); @@ -188,7 +188,7 @@ GDecInstruction *dalvik_decomp_instr_invoke_virtual(const GArchInstruction *inst      for (i = 1; i < count; i++)      {          arg = g_dalvik_args_operand_get(G_DALVIK_ARGS_OPERAND(operand), i); -        reg = g_dec_context_convert_register(ctx, arg); +        reg = g_dec_context_convert_register(ctx, arg, false);          g_routine_call_add_arg(G_ROUTINE_CALL(call), reg); @@ -197,7 +197,7 @@ GDecInstruction *dalvik_decomp_instr_invoke_virtual(const GArchInstruction *inst      /* Appel depuis le propriétaire */      arg = g_dalvik_args_operand_get(G_DALVIK_ARGS_OPERAND(operand), 0); -    reg = g_dec_context_convert_register(ctx, arg); +    reg = g_dec_context_convert_register(ctx, arg, false);      result = g_access_expression_new(G_DEC_EXPRESSION(reg), G_DEC_EXPRESSION(call)); diff --git a/src/arch/dalvik/decomp/iput.c b/src/arch/dalvik/decomp/iput.c index 4db4770..002bdd4 100644 --- a/src/arch/dalvik/decomp/iput.c +++ b/src/arch/dalvik/decomp/iput.c @@ -57,10 +57,10 @@ GDecInstruction *dalvik_decomp_instr_iput(const GArchInstruction *instr, GDecCon      GDecInstruction *access;                /* Représentation de l'accès   */      operand = g_arch_instruction_get_operand(instr, 0); -    src = g_dec_context_convert_register(ctx, operand); +    src = g_dec_context_convert_register(ctx, operand, false);      operand = g_arch_instruction_get_operand(instr, 1); -    dest = g_dec_context_convert_register(ctx, operand); +    dest = g_dec_context_convert_register(ctx, operand, false);      operand = g_arch_instruction_get_operand(instr, 2);      index = g_dalvik_pool_operand_get_index(G_DALVIK_POOL_OPERAND(operand)); diff --git a/src/arch/dalvik/decomp/move.c b/src/arch/dalvik/decomp/move.c index 798b6b0..f700737 100644 --- a/src/arch/dalvik/decomp/move.c +++ b/src/arch/dalvik/decomp/move.c @@ -45,14 +45,14 @@ GDecInstruction *dalvik_decomp_instr_move_object(const GArchInstruction *instr,  {      GDecInstruction *result;                /* Instruction à retourner     */      GArchOperand *operand;                  /* Opérande de l'instruction   */ -    GDecInstruction *dest;                  /* Registre de destination     */      GDecInstruction *src;                   /* Registre de l'object        */ - -    operand = g_arch_instruction_get_operand(instr, 0); -    dest = g_dec_context_convert_register(ctx, operand); +    GDecInstruction *dest;                  /* Registre de destination     */      operand = g_arch_instruction_get_operand(instr, 1); -    src = g_dec_context_convert_register(ctx, operand); +    src = g_dec_context_convert_register(ctx, operand, false); + +    operand = g_arch_instruction_get_operand(instr, 0); +    dest = g_dec_context_convert_register(ctx, operand, true);      result = g_assign_expression_new(G_DEC_EXPRESSION(dest), G_DEC_EXPRESSION(src)); @@ -79,19 +79,19 @@ GDecInstruction *dalvik_decomp_instr_move_result(const GArchInstruction *instr,      GDecInstruction *result;                /* Instruction à retourner     */      GDecInstruction *list;                  /* Instructions décompilées    */      GArchOperand *operand;                  /* Opérande de l'instruction   */ -    GDecInstruction *dest;                  /* Registre de destination     */      GDecInstruction *last;                  /* Instruction précédante      */ +    GDecInstruction *dest;                  /* Registre de destination     */      list = g_dec_context_get_decomp_instrs(ctx);      if (list == NULL) return NULL; -    operand = g_arch_instruction_get_operand(instr, 0); -    dest = g_dec_context_convert_register(ctx, operand); -      last = g_dec_instruction_get_last(list);      g_dec_instruction_delete(&list, last);      g_dec_context_set_decomp_instrs(ctx, list); +    operand = g_arch_instruction_get_operand(instr, 0); +    dest = g_dec_context_convert_register(ctx, operand, true); +      result = g_assign_expression_new(G_DEC_EXPRESSION(dest), G_DEC_EXPRESSION(last));      return result; diff --git a/src/arch/dalvik/decomp/new.c b/src/arch/dalvik/decomp/new.c index 1c4c06e..65da469 100644 --- a/src/arch/dalvik/decomp/new.c +++ b/src/arch/dalvik/decomp/new.c @@ -47,15 +47,12 @@ GDecInstruction *dalvik_decomp_instr_new_instance(const GArchInstruction *instr,  {      GDecInstruction *result;                /* Instruction à retourner     */      GArchOperand *operand;                  /* Opérande de l'instruction   */ -    GDecInstruction *dest;                  /* Registre de destination     */      uint32_t index;                         /* Indice dans la table        */      GDexFormat *format;                     /* Accès aux constantes        */      GOpenidaType *type;                     /* Type concerné par l'opérat° */      GBinRoutine *constructor;               /* Constructeur reconstruit    */      GDecInstruction *call;                  /* Appel au constructeur       */ - -    operand = g_arch_instruction_get_operand(instr, 0); -    dest = g_dec_context_convert_register(ctx, operand); +    GDecInstruction *dest;                  /* Registre de destination     */      operand = g_arch_instruction_get_operand(instr, 1);      index = g_dalvik_pool_operand_get_index(G_DALVIK_POOL_OPERAND(operand)); @@ -65,6 +62,9 @@ GDecInstruction *dalvik_decomp_instr_new_instance(const GArchInstruction *instr,      constructor = g_binary_routine_new_constructor(type);      call = g_routine_call_new(constructor); +    operand = g_arch_instruction_get_operand(instr, 0); +    dest = g_dec_context_convert_register(ctx, operand, true); +      result = g_assign_expression_new(G_DEC_EXPRESSION(dest), G_DEC_EXPRESSION(call));      return result; diff --git a/src/arch/dalvik/decomp/ret.c b/src/arch/dalvik/decomp/ret.c index 3717529..b7c5414 100644 --- a/src/arch/dalvik/decomp/ret.c +++ b/src/arch/dalvik/decomp/ret.c @@ -2,7 +2,7 @@  /* OpenIDA - Outil d'analyse de fichiers binaires   * ret.c - décompilation des ordres de retour   * - * Copyright (C) 2010-2011 Cyrille Bagard + * Copyright (C) 2010-2012 Cyrille Bagard   *   *  This file is part of OpenIDA.   * @@ -48,7 +48,7 @@ GDecInstruction *dalvik_decomp_instr_return(const GArchInstruction *instr, GDecC      GDecInstruction *reg;                   /* Pseudo-registre redéfini    */      operand = g_arch_instruction_get_operand(instr, 0); -    reg = g_dec_context_convert_register(ctx, operand); +    reg = g_dec_context_convert_register(ctx, operand, false);      result = g_return_expression_new(G_DEC_EXPRESSION(reg)); diff --git a/src/arch/dalvik/operands/register.c b/src/arch/dalvik/operands/register.c index ced6608..cca4ee7 100644 --- a/src/arch/dalvik/operands/register.c +++ b/src/arch/dalvik/operands/register.c @@ -197,6 +197,25 @@ GArchOperand *g_dalvik_register_operand_new_from_existing(GDalvikRegister *reg)  /******************************************************************************  *                                                                             * +*  Paramètres  : operand = opérande représentant un registre.                 * +*                                                                             * +*  Description : Fournit le registre Dalvik associé à l'opérande.             * +*                                                                             * +*  Retour      : Représentation interne du registre.                          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GDalvikRegister *g_dalvik_register_operand_get(const GDalvikRegisterOperand *operand) +{ +    return operand->reg; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : a = premier opérande à consulter.                            *  *                b = second opérande à consulter.                             *  *                                                                             * diff --git a/src/arch/dalvik/operands/register.h b/src/arch/dalvik/operands/register.h index a4151f9..ee83b79 100644 --- a/src/arch/dalvik/operands/register.h +++ b/src/arch/dalvik/operands/register.h @@ -58,6 +58,9 @@ GArchOperand *g_dalvik_register_operand_new(const bin_t *, off_t *, off_t, bool  /* Crée un opérande visant un registre Dalvik. */  GArchOperand *g_dalvik_register_operand_new_from_existing(GDalvikRegister *); +/* Fournit le registre Dalvik associé à l'opérande. */ +GDalvikRegister *g_dalvik_register_operand_get(const GDalvikRegisterOperand *); +  #endif  /* _ARCH_DALVIK_OPERANDS_REGISTER_H */ diff --git a/src/arch/dalvik/processor.c b/src/arch/dalvik/processor.c index ca571c6..9936738 100644 --- a/src/arch/dalvik/processor.c +++ b/src/arch/dalvik/processor.c @@ -58,6 +58,9 @@ static void g_dalvik_processor_init(GDalvikProcessor *);  /* Fournit un contexte pour l'exécution du processeur Dalvik. */  static GDalvikContext *g_dalvik_processor_get_context(const GDalvikProcessor *); +/* Fournit un contexte pour la décompilation Dalvik. */ +static GDalvikDContext *g_dalvik_processor_get_decomp_context(const GDalvikProcessor *); +  /* Décode une pseudo-instruction dans un flux de données. */  static GArchInstruction *g_dalvik_guess_pseudo_instruction(const GDalvikProcessor *, const bin_t *, off_t *, off_t, vmpa_t); @@ -111,6 +114,7 @@ static void g_dalvik_processor_init(GDalvikProcessor *proc)      parent->inssize = MDS_16_BITS;      parent->get_ctx = (get_processor_context_fc)g_dalvik_processor_get_context; +    parent->get_dec_ctx = (get_decomp_context_fc)g_dalvik_processor_get_decomp_context;      parent->decode = (decode_instruction_fc)g_dalvik_processor_decode_instruction;  } @@ -160,6 +164,25 @@ static GDalvikContext *g_dalvik_processor_get_context(const GDalvikProcessor *pr  /******************************************************************************  *                                                                             * +*  Paramètres  : proc = architecture, spectatrice ici.                        * +*                                                                             * +*  Description : Fournit un contexte pour la décompilation Dalvik.            * +*                                                                             * +*  Retour      : Contexte mis en place.                                       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GDalvikDContext *g_dalvik_processor_get_decomp_context(const GDalvikProcessor *proc) +{ +    return g_dalvik_dcontext_new(); + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : proc = architecture visée par la procédure.                  *  *                data = flux de données à analyser.                           *  *                pos  = position courante dans ce flux. [OUT]                 * diff --git a/src/arch/dalvik/register.c b/src/arch/dalvik/register.c index cf926d2..6e709f9 100644 --- a/src/arch/dalvik/register.c +++ b/src/arch/dalvik/register.c @@ -127,6 +127,25 @@ GDalvikRegister *g_dalvik_register_new(uint16_t index)  /******************************************************************************  *                                                                             * +*  Paramètres  : reg = registre à consulter.                                  * +*                                                                             * +*  Description : Fournit l'indice d'un registre Dalvik.                       * +*                                                                             * +*  Retour      : Inditifiant représentant le registre.                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +uint16_t g_dalvik_register_get_index(const GDalvikRegister *reg) +{ +    return reg->index; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : a = premier opérande à consulter.                            *  *                b = second opérande à consulter.                             *  *                                                                             * diff --git a/src/arch/dalvik/register.h b/src/arch/dalvik/register.h index 9b405a5..3fc551a 100644 --- a/src/arch/dalvik/register.h +++ b/src/arch/dalvik/register.h @@ -55,6 +55,9 @@ GType g_dalvik_register_get_type(void);  /* Crée une réprésentation de registre Dalvik. */  GDalvikRegister *g_dalvik_register_new(uint16_t); +/* Fournit l'indice d'un registre Dalvik. */ +uint16_t g_dalvik_register_get_index(const GDalvikRegister *); +  /* Compare un registre avec un autre. */  bool g_dalvik_register_compare(const GDalvikRegister *, const GDalvikRegister *); diff --git a/src/arch/processor-int.h b/src/arch/processor-int.h index f83ff49..d1f83d4 100644 --- a/src/arch/processor-int.h +++ b/src/arch/processor-int.h @@ -49,6 +49,9 @@  /* Fournit un contexte propre au processeur d'une architecture. */  typedef GProcContext * (* get_processor_context_fc) (const GArchProcessor *); +/* Fournit un contexte lié au processeur pour une décompilation. */ +typedef GDecContext * (* get_decomp_context_fc) (const GArchProcessor *); +  /* Décode une instruction dans un flux de données. */  typedef GArchInstruction * (* decode_instruction_fc) (const GArchProcessor *, GProcContext *, const bin_t *, off_t *, off_t, vmpa_t, GBinFormat *); @@ -62,7 +65,8 @@ struct _GArchProcessor      MemoryDataSize memsize;                 /* Taille de l'espace mémoire  */      MemoryDataSize inssize;                 /* Taille min. d'encodage      */ -    get_processor_context_fc get_ctx;       /* Obtention d'un contexte     */ +    get_processor_context_fc get_ctx;       /* Obtention d'un contexte #1  */ +    get_decomp_context_fc get_dec_ctx;      /* Obtention d'un contexte #2  */      decode_instruction_fc decode;           /* Traduction en instructions  */  }; diff --git a/src/arch/processor.c b/src/arch/processor.c index 6063f93..01c3b82 100644 --- a/src/arch/processor.c +++ b/src/arch/processor.c @@ -115,11 +115,11 @@ static void g_arch_processor_init(GArchProcessor *proc)  /******************************************************************************  *                                                                             * -*  Paramètres  : proc   = architecture visée par la procédure.                * +*  Paramètres  : proc = architecture visée par la procédure.                  *  *                                                                             *  *  Description : Fournit un contexte propre au processeur d'une architecture. *  *                                                                             * -*  Retour      : Nouveau contexte mise à disposition.                         * +*  Retour      : Nouveau contexte mis à disposition.                          *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             * @@ -142,6 +142,33 @@ GProcContext *g_arch_processor_get_context(const GArchProcessor *proc)  /******************************************************************************  *                                                                             * +*  Paramètres  : proc = architecture visée par la procédure.                  * +*                                                                             * +*  Description : Fournit un contexte lié au processeur pour une décompilation.* +*                                                                             * +*  Retour      : Nouveau contexte mis à disposition.                          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GDecContext *g_arch_processor_get_decomp_context(const GArchProcessor *proc) +{ +    GDecContext *result;                    /* Contexte à retourner        */ + +    if (proc->get_dec_ctx != NULL) +        result = proc->get_dec_ctx(proc); + +    else +        result = NULL; + +    return result; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : proc = processeur d'architecture à consulter.                *  *                                                                             *  *  Description : Fournit le boustime du processeur d'une architecture.        * diff --git a/src/arch/processor.h b/src/arch/processor.h index ab06c52..5f9120d 100644 --- a/src/arch/processor.h +++ b/src/arch/processor.h @@ -31,6 +31,7 @@  #include "context.h"  #include "instruction.h"  #include "../common/endianness.h" +#include "../decomp/context.h"  #include "../format/format.h" @@ -54,6 +55,9 @@ GType g_arch_processor_get_type(void);  /* Fournit un contexte propre au processeur d'une architecture. */  GProcContext *g_arch_processor_get_context(const GArchProcessor *); +/* Fournit un contexte lié au processeur pour une décompilation. */ +GDecContext *g_arch_processor_get_decomp_context(const GArchProcessor *); +  /* Fournit le boustime du processeur d'une architecture. */  SourceEndian g_arch_processor_get_endianness(const GArchProcessor *); diff --git a/src/decomp/Makefile.am b/src/decomp/Makefile.am index ccae8ad..ab12e01 100755 --- a/src/decomp/Makefile.am +++ b/src/decomp/Makefile.am @@ -2,6 +2,7 @@  noinst_LTLIBRARIES  = libdecomp.la  libdecomp_la_SOURCES =					\ +	context.-int.h						\  	context.h context.c					\  	expression-int.h					\  	expression.h expression.c			\ diff --git a/src/decomp/context-int.h b/src/decomp/context-int.h new file mode 100644 index 0000000..2be4218 --- /dev/null +++ b/src/decomp/context-int.h @@ -0,0 +1,68 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * context.c - mise en place d'un contexte de décompilation + * + * Copyright (C) 2010 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _DECOMP_CONTEXT_INT_H +#define _DECOMP_CONTEXT_INT_H + + +#include "context.h" + + +#include "../glibext/gnhash.h" + + + +/* Convertit un registre machine en un pseudo-registre. */ +typedef GDecInstruction * (* convert_register_fc) (GDecContext *, gpointer, bool); + + +/* Définition d'une context décompilée (instance) */ +struct _GDecContext +{ +    GObject parent;                         /* A laisser en premier        */ + +    vmpa_t max;                             /* Première adresse à écarter  */ + +    GDecInstruction *list;                  /* Chaîne décompilée           */ + +    convert_register_fc convert_reg;        /* Traduction des registres    */ + +    GHashTable *machine;                    /* Correspondance reg./pseudo  */ +    GHashTable *ssa;                        /* Remplacement des pseudos    */ + +    GDecInstruction **pseudos;              /* Liste des pseudos-registre  */ +    size_t count;                           /* Taille de cette liste       */ + +}; + + +/* Définition d'une context décompilée (classe) */ +struct _GDecContextClass +{ +    GObjectClass parent;                    /* A laisser en premier        */ + +}; + + + +#endif  /* _DECOMP_CONTEXT_INT_H */ diff --git a/src/decomp/context.c b/src/decomp/context.c index 15215eb..9db0bca 100644 --- a/src/decomp/context.c +++ b/src/decomp/context.c @@ -27,39 +27,13 @@  #include <malloc.h> +#include "context-int.h"  #include "instruction-int.h" -#include "expr/pseudo.h"  #include "../arch/operand.h" -#include "../glibext/gnhash.h" +#include "../format/dex/method.h" -/* Définition d'une context décompilée (instance) */ -struct _GDecContext -{ -    GObject parent;                         /* A laisser en premier        */ - -    vmpa_t max;                             /* Première adresse à écarter  */ - -    GDecInstruction *list;                  /* Chaîne décompilée           */ - -    GHashTable *machine;                    /* Correspondance reg./pseudo  */ -    GHashTable *ssa;                        /* Remplacement des pseudos    */ - -    GDecInstruction **pseudos;              /* Liste des pseudos-registre  */ -    size_t count;                           /* Taille de cette liste       */ - -}; - - -/* Définition d'une context décompilée (classe) */ -struct _GDecContextClass -{ -    GObjectClass parent;                    /* A laisser en premier        */ - -}; - -  /* Initialise la classe des contextes de décompilation. */  static void g_dec_context_class_init(GDecContextClass *); @@ -216,6 +190,7 @@ void g_dec_context_set_decomp_instrs(GDecContext *ctx, GDecInstruction *instr)  *                                                                             *  *  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.         *  *                                                                             * @@ -225,27 +200,8 @@ void g_dec_context_set_decomp_instrs(GDecContext *ctx, GDecInstruction *instr)  *                                                                             *  ******************************************************************************/ -GDecInstruction *g_dec_context_convert_register(GDecContext *ctx, gpointer operand) +GDecInstruction *g_dec_context_convert_register(GDecContext *ctx, gpointer operand, bool assign)  { -    GDecInstruction *result;                /* Instance à retourner        */ -    gpointer *found;                        /* Pseudo-registre trouvé      */ - -    found = g_hash_table_lookup(ctx->machine, operand); - -    if (found != NULL) result = G_DEC_INSTRUCTION(found); -    else -    { -        result = g_pseudo_register_new(); -        g_pseudo_register_set_index(G_PSEUDO_REGISTER(result), ctx->count); - -        g_hash_table_insert(ctx->machine, operand, result); - -        ctx->pseudos = (GDecInstruction **)realloc(ctx->pseudos, -                                                   ++ctx->count * sizeof(GDecInstruction *)); -        ctx->pseudos[ctx->count - 1] = result; - -    } - -    return result; +    return ctx->convert_reg(ctx, operand, assign);  } diff --git a/src/decomp/context.h b/src/decomp/context.h index b7dd445..bf584f4 100644 --- a/src/decomp/context.h +++ b/src/decomp/context.h @@ -68,7 +68,7 @@ GDecInstruction *g_dec_context_get_decomp_instrs(const GDecContext *tx);  void g_dec_context_set_decomp_instrs(GDecContext *, GDecInstruction *);  /* Convertit un registre machine en un pseudo-registre. */ -GDecInstruction *g_dec_context_convert_register(GDecContext *, gpointer); +GDecInstruction *g_dec_context_convert_register(GDecContext *, gpointer, bool); diff --git a/src/decomp/expr/pseudo.c b/src/decomp/expr/pseudo.c index bb5861d..e73cb3d 100644 --- a/src/decomp/expr/pseudo.c +++ b/src/decomp/expr/pseudo.c @@ -38,6 +38,7 @@ struct _GPseudoRegister  {      GDecExpression parent;                  /* A laisser en premier        */ +    char *name;                             /* Désignation générale        */      size_t index;                           /* Position dans l'ensemble    */      GBinVariable *var;                      /* Variable plus précise       */ @@ -160,7 +161,7 @@ static void g_pseudo_register_print(const GPseudoRegister *reg, GCodeBuffer *buf      }      else      { -        snprintf(label, 32, "var%zu", reg->index); +        snprintf(label, 32, "%s%zu", reg->name, reg->index);          g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, label, strlen(label), RTT_RAW);      } @@ -169,6 +170,26 @@ static void g_pseudo_register_print(const GPseudoRegister *reg, GCodeBuffer *buf  /******************************************************************************  *                                                                             * +*  Paramètres  : reg  = expression représentant un pseudo-registre à traiter. * +*                name = désignation générale à associer au pseudo-registre.   * +*                                                                             * +*  Description : Définit un nom général pour un pseudo-registre donné.        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_pseudo_register_set_basename(GPseudoRegister *reg, const char *name) +{ +    reg->name = strdup(name); + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : reg   = expression représentant un pseudo-registre à traiter.*  *                index = indice à associer au pseudo-registre.                *  *                                                                             * diff --git a/src/decomp/expr/pseudo.h b/src/decomp/expr/pseudo.h index dce6337..a465b41 100644 --- a/src/decomp/expr/pseudo.h +++ b/src/decomp/expr/pseudo.h @@ -55,6 +55,9 @@ GType g_pseudo_register_get_type(void);  /* Assigne le contenu d'une expression dans une autre. */  GDecInstruction *g_pseudo_register_new(void); +/* Définit un nom général pour un pseudo-registre donné. */ +void g_pseudo_register_set_basename(GPseudoRegister *, const char *); +  /* Définit un indice unique pour un pseudo-registre donné. */  void g_pseudo_register_set_index(GPseudoRegister *, size_t); diff --git a/src/format/dex/class.c b/src/format/dex/class.c index d08c8e2..cdf6c2c 100644 --- a/src/format/dex/class.c +++ b/src/format/dex/class.c @@ -296,6 +296,39 @@ GBinPart **g_dex_class_get_parts(const GDexClass *class, GBinPart **parts, size_  /******************************************************************************  *                                                                             * +*  Paramètres  : class = informations chargées à consulter.                   * +*                addr  = adresse de la routine à retrouver.                   * +*                                                                             * +*  Description : Retrouve si possible la méthode associée à une adresse.      * +*                                                                             * +*  Retour      : Méthde retrouvée ou NULL en cas d'échec.                     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GDexMethod *g_dex_class_find_method_by_address(const GDexClass *class, vmpa_t addr) +{ +    GDexMethod *result;                     /* Trouvaille à retourner      */ +    size_t i;                               /* Boucle de parcours          */ + +    result = NULL; + +    for (i = 0; i < class->dmethods_count && result == NULL; i++) +        if (addr == (vmpa_t)g_dex_method_get_offset(class->direct_methods[i])) +            result = class->direct_methods[i]; + +    for (i = 0; i < class->vmethods_count && result == NULL; i++) +        if (addr == (vmpa_t)g_dex_method_get_offset(class->virtual_methods[i])) +            result = class->virtual_methods[i]; + +    return result; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : class  = informations chargées à consulter.                  *  *                format = représentation interne du format DEX à compléter.   *  *                                                                             * diff --git a/src/format/dex/class.h b/src/format/dex/class.h index f4d5cb0..998c1b7 100644 --- a/src/format/dex/class.h +++ b/src/format/dex/class.h @@ -29,6 +29,7 @@  #include "dex.h" +#include "method.h"  #include "../../decomp/output.h" @@ -56,6 +57,9 @@ GType g_dex_class_get_type(void);  /*  Fournit les références aux zones binaires à analyser. */  GBinPart **g_dex_class_get_parts(const GDexClass *, GBinPart **, size_t *); +/* Retrouve si possible la méthode associée à une adresse. */ +GDexMethod *g_dex_class_find_method_by_address(const GDexClass *, vmpa_t); +  /* Retrouve si possible le nom du fichier source d'une classe. */  const char *g_dex_class_get_source_file(const GDexClass *, const GDexFormat *); diff --git a/src/format/dex/dex-int.h b/src/format/dex/dex-int.h index feb63a8..5feb427 100755 --- a/src/format/dex/dex-int.h +++ b/src/format/dex/dex-int.h @@ -58,6 +58,10 @@ struct _GDexFormatClass  }; +/* Retrouve si possible la méthode associée à une adresse. */ +GDexMethod *g_dex_format_find_method_by_address(const GDexFormat *, vmpa_t); + +  /* ------------------------ ELEMENTS DE TABLE DES CONSTANTES ------------------------ */ diff --git a/src/format/dex/dex.c b/src/format/dex/dex.c index 0d17a4d..7075929 100755 --- a/src/format/dex/dex.c +++ b/src/format/dex/dex.c @@ -204,6 +204,34 @@ GBinFormat *g_dex_format_new(const bin_t *content, off_t length)  /******************************************************************************  *                                                                             * +*  Paramètres  : format = informations chargées à consulter.                  * +*                addr   = adresse de la routine à retrouver.                  * +*                                                                             * +*  Description : Retrouve si possible la méthode associée à une adresse.      * +*                                                                             * +*  Retour      : Méthde retrouvée ou NULL en cas d'échec.                     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GDexMethod *g_dex_format_find_method_by_address(const GDexFormat *format, vmpa_t addr) +{ +    GDexMethod *result;                     /* Trouvaille à retourner      */ +    size_t i;                               /* Boucle de parcours          */ + +    result = NULL; + +    for (i = 0; i < format->classes_count && result == NULL; i++) +        result = g_dex_class_find_method_by_address(format->classes[i], addr); + +    return result; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : format = informations chargées à mettre à jour.              *  *                                                                             *  *  Description : Détermine tous les fichiers source indiqués.                 * diff --git a/src/format/dex/method.c b/src/format/dex/method.c index 233ecb1..c22c11f 100644 --- a/src/format/dex/method.c +++ b/src/format/dex/method.c @@ -228,6 +228,69 @@ GBinPart *g_dex_method_as_part(const GDexMethod *method)  /******************************************************************************  *                                                                             * +*  Paramètres  : method = représentation interne du format DEX à consulter.   * +*                                                                             * +*  Description : Indique la position de la méthode au sein du binaire.        * +*                                                                             * +*  Retour      : Localisation dans le contenu binaire.                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +off_t g_dex_method_get_offset(const GDexMethod *method) +{ +    return method->offset; +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : method = représentation interne du format DEX à consulter.   * +*                index  = indice de base comme seul indice.                   * +*                                                                             * +*  Description : Fournit des indications sur la nature d'une variable donnée. * +*                                                                             * +*  Retour      : Indentifiant complet d'une variable utilisée.                * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +DexVariableIndex g_dex_method_get_variable(const GDexMethod *method, uint32_t index) +{ +    const encoded_method *info;             /* Propriétés de la méthode    */ +    const code_item *body;                  /* Corps de la méthode         */ +    uint32_t pivot;                         /* Bascule pour les arguments  */ + +    info = &method->info; +    body = &method->body; + +    /* S'agit-il d'un argument ? */ + +    pivot = body->registers_size - body->ins_size; + +    if (!(method->info.access_flags & ACC_STATIC)) +        pivot++; + +    if (index >= pivot) +        return (index - pivot) | DVI_ARGUMENT; + +    /* S'agit-il de "this" ? */ + +    if (!(method->info.access_flags & ACC_STATIC) +        && index == (body->registers_size - body->ins_size)) +        return DVI_THIS; + +    /* Alors il s'agit d'une variable locale... */ + +    return index | DVI_LOCAL; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : method = informations chargées à consulter.                  *  *                lang   = langage à utiliser pour la sortie humaine.          *  *                buffer = tampon mis à disposition pour la sortie.            * diff --git a/src/format/dex/method.h b/src/format/dex/method.h index 79dbd7e..c06df73 100644 --- a/src/format/dex/method.h +++ b/src/format/dex/method.h @@ -49,6 +49,19 @@ typedef struct _GDexMethod GDexMethod;  typedef struct _GDexMethodClass GDexMethodClass; +/* Détermination des variables */ +typedef enum _DexVariableIndex +{ +    /* Indices... */ + +    DVI_LOCAL       = (1 << 29), +    DVI_THIS        = (1 << 30), +    DVI_ARGUMENT    = (1 << 31) + +} DexVariableIndex; + +#define DVI_INDEX(v) (v & ~(7 << 29)) +  /* Détermine le type d'une methode issue du code source. */  GType g_dex_method_get_type(void); @@ -62,6 +75,12 @@ GBinRoutine *g_dex_method_get_routine(const GDexMethod *);  /* Fournit la zone binaire correspondant à la méthode. */  GBinPart *g_dex_method_as_part(const GDexMethod *); +/* Indique la position de la méthode au sein du binaire. */ +off_t g_dex_method_get_offset(const GDexMethod *); + +/* Fournit des indications sur la nature d'une variable donnée. */ +DexVariableIndex g_dex_method_get_variable(const GDexMethod *, uint32_t); +  /* Procède à la décompilation complète d'une routine donnée. */  void g_dex_method_decompile(const GDexMethod *, GLangOutput *, GCodeBuffer *); diff --git a/src/format/format.c b/src/format/format.c index 930d8db..4f6df03 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -272,6 +272,7 @@ GBinRoutine **g_binary_format_get_routines(const GBinFormat *format, size_t *cou  *                                                                             *  *  Paramètres  : format  = informations chargées à consulter.                 *  *                routine = routine à traiter.                                 * +*                ctx     = contexte de soutien à associer à l'opération.      *  *                                                                             *  *  Description : Procède à la décompilation basique d'une routine donnée.     *  *                                                                             * @@ -281,12 +282,11 @@ GBinRoutine **g_binary_format_get_routines(const GBinFormat *format, size_t *cou  *                                                                             *  ******************************************************************************/ -GDecInstruction *g_binary_format_decompile_routine(const GBinFormat *format, GBinRoutine *routine) +GDecInstruction *g_binary_format_decompile_routine(const GBinFormat *format, GBinRoutine *routine, GDecContext *ctx)  {      GDecInstruction *result;                /* Instructions décompilées    */      GArchInstruction *instr;                /* Instructions natives        */      vmpa_t max;                             /* Première adresse à écarter  */ -    GDecContext *ctx;                       /* Contexte de décompilation   */      GArchInstruction *iter;                 /* Boucle de parcours          */      GDecInstruction *first;                 /* Première décompilation      */      GDecInstruction *dinstr;                /* Nouvelle décompilation      */ @@ -297,8 +297,8 @@ GDecInstruction *g_binary_format_decompile_routine(const GBinFormat *format, GBi      max = g_binary_routine_get_address(routine)          + g_binary_routine_get_size(routine); -    ctx = g_dec_context_new();      g_object_set_data(G_OBJECT(ctx), "format", format); +    g_object_set_data(G_OBJECT(ctx), "routine", routine);      g_dec_context_set_max_address(ctx, max);      for (iter = instr; diff --git a/src/format/format.h b/src/format/format.h index ce49a26..ef85fbb 100644 --- a/src/format/format.h +++ b/src/format/format.h @@ -32,6 +32,7 @@  #include "symbol.h"  #include "../analysis/routine.h" +#include "../decomp/context.h"  #include "../decomp/instruction.h" @@ -72,7 +73,7 @@ void g_binary_format_add_routine(GBinFormat *, GBinRoutine *);  GBinRoutine **g_binary_format_get_routines(const GBinFormat *, size_t *);  /* Procède à la décompilation basique d'une routine donnée. */ -GDecInstruction *g_binary_format_decompile_routine(const GBinFormat *, GBinRoutine *); +GDecInstruction *g_binary_format_decompile_routine(const GBinFormat *, GBinRoutine *, GDecContext *);  /* Fournit la liste des fichiers source détectés. */  const char * const *g_binary_format_get_source_files(const GBinFormat *, size_t *, size_t *); | 
