diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/analysis/block-int.h | 4 | ||||
| -rw-r--r-- | src/analysis/block.c | 20 | ||||
| -rw-r--r-- | src/analysis/block.h | 3 | ||||
| -rw-r--r-- | src/analysis/blocks/flow.c | 62 | ||||
| -rw-r--r-- | src/analysis/blocks/flow.h | 3 | ||||
| -rw-r--r-- | src/analysis/blocks/virtual.c | 56 | ||||
| -rw-r--r-- | src/analysis/blocks/virtual.h | 3 | ||||
| -rw-r--r-- | src/analysis/decomp/decompiler.c | 11 | ||||
| -rw-r--r-- | src/analysis/decomp/il.c | 326 | ||||
| -rw-r--r-- | src/analysis/decomp/il.h | 14 | ||||
| -rw-r--r-- | src/analysis/variable.c | 7 | ||||
| -rw-r--r-- | src/arch/dalvik/instruction.c | 12 | ||||
| -rw-r--r-- | src/arch/instruction.c | 29 | ||||
| -rw-r--r-- | src/arch/instruction.h | 3 | ||||
| -rw-r--r-- | src/decomp/context.c | 1 | 
15 files changed, 538 insertions, 16 deletions
| diff --git a/src/analysis/block-int.h b/src/analysis/block-int.h index ba84fcb..355c1ee 100644 --- a/src/analysis/block-int.h +++ b/src/analysis/block-int.h @@ -29,6 +29,9 @@ +/* Recherche le bloc contenant une adresse donnée. */ +typedef GInstrBlock * (* find_by_addr_fc) (const GInstrBlock *, vmpa_t); +  /* Parcours tous les blocs d'instructions dans un ordre donné. */  typedef bool (* visit_all_blocks_fc) (GInstrBlock *, instr_block_visitor_cb, void *); @@ -45,6 +48,7 @@ struct _GInstrBlock  {      GObject parent;                         /* A laisser en premier        */ +    find_by_addr_fc find_by_addr;           /* Recherche par adresse       */      visit_all_blocks_fc visit_blocks;       /* Visite des différents blocs */      list_all_blocks_fc list_blocks;         /* Liste de tous les blocs     */      list_regs_accesses_fc list_regs;        /* Liste des accès registres   */ diff --git a/src/analysis/block.c b/src/analysis/block.c index 3b3eaf3..62b56ab 100644 --- a/src/analysis/block.c +++ b/src/analysis/block.c @@ -157,6 +157,26 @@ static void g_instr_block_finalize(GInstrBlock *block)  /******************************************************************************  *                                                                             * +*  Paramètres  : block = bloc de départ des recherches.                       * +*                addr  = ensemble de blocs à parcourir.                       * +*                                                                             * +*  Description : Recherche le bloc contenant une adresse donnée.              * +*                                                                             * +*  Retour      : bloc basique trouvé ou NULL en cas d'échec.                  * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GInstrBlock *g_instr_block_find_by_addr(const GInstrBlock *block, vmpa_t addr) +{ +    return block->find_by_addr(block, addr); + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : block    = bloc d'instructions démarrant la visite.          *  *                callback = ensemble de blocs à parcourir.                    *  *                data     = donnée utilisateur à associer au parcours.        * diff --git a/src/analysis/block.h b/src/analysis/block.h index a85e4aa..1574dc1 100644 --- a/src/analysis/block.h +++ b/src/analysis/block.h @@ -95,6 +95,9 @@ typedef bool (* instr_block_visitor_cb) (GInstrBlock *, BlockVisitOrder, void *)  /* Indique le type défini pour un bloc d'instructions. */  GType g_instr_block_get_type(void); +/* Recherche le bloc contenant une adresse donnée. */ +GInstrBlock *g_instr_block_find_by_addr(const GInstrBlock *, vmpa_t); +  /* Parcours tous les blocs d'instructions dans un ordre donné. */  bool g_instr_block_visit(GInstrBlock *, instr_block_visitor_cb, void *); diff --git a/src/analysis/blocks/flow.c b/src/analysis/blocks/flow.c index 85d98ee..6fb5849 100644 --- a/src/analysis/blocks/flow.c +++ b/src/analysis/blocks/flow.c @@ -65,6 +65,9 @@ static void g_flow_block_dispose(GFlowBlock *);  /* Procède à la libération totale de la mémoire. */  static void g_flow_block_finalize(GFlowBlock *); +/* Recherche le bloc contenant une adresse donnée. */ +static GInstrBlock *g_flow_block_find_by_addr(const GFlowBlock *, vmpa_t); +  /* Parcours le bloc d'instructions dans un ordre donné. */  static bool g_flow_block_visit(GFlowBlock *, instr_block_visitor_cb, void *); @@ -128,6 +131,7 @@ static void g_flow_block_init(GFlowBlock *block)      parent = G_INSTR_BLOCK(block); +    parent->find_by_addr = (find_by_addr_fc)g_flow_block_find_by_addr;      parent->visit_blocks = (visit_all_blocks_fc)g_flow_block_visit;      parent->list_blocks = (list_all_blocks_fc)g_flow_block_list_all_blocks;      parent->list_regs = (list_regs_accesses_fc)g_flow_block_list_regs_accesses; @@ -236,6 +240,38 @@ GInstrBlock *g_flow_block_new(GArchInstruction *instrs, GArchInstruction *first,  /******************************************************************************  *                                                                             * +*  Paramètres  : block = bloc de départ des recherches.                       * +*                addr  = ensemble de blocs à parcourir.                       * +*                                                                             * +*  Description : Recherche le bloc contenant une adresse donnée.              * +*                                                                             * +*  Retour      : bloc basique trouvé ou NULL en cas d'échec.                  * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GInstrBlock *g_flow_block_find_by_addr(const GFlowBlock *block, vmpa_t addr) +{ +    GInstrBlock *result;                    /* Resultat à retourner        */ +    vmpa_t start;                           /* Adresse de début du bloc    */ +    vmpa_t end;                             /* Adresse de fin du bloc      */ + +    g_flow_block_get_boundary_addresses(block, &start, &end); + +    if (start <= addr && addr <= end) +        result = G_INSTR_BLOCK(block); + +    else +        result = NULL; + +    return result; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : block    = bloc d'instructions concerné par la visite.       *  *                callback = ensemble de blocs à parcourir.                    *  *                data     = donnée utilisateur à associer au parcours.        * @@ -419,6 +455,25 @@ static const reg_access *g_flow_block_list_regs_accesses(const GFlowBlock *block  /******************************************************************************  *                                                                             *  *  Paramètres  : block = bloc d'instructions à consulter.                     * +*                                                                             * +*  Description : Fournit la liste d'appartenance des instructions du bloc.    * +*                                                                             * +*  Retour      : Liste de l'ensemble des instructions.                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GArchInstruction *g_flow_block_get_all_instructions_list(const GFlowBlock *block) +{ +    return block->instrs; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : block = bloc d'instructions à consulter.                     *  *                first = instruction de départ du bloc. [OUT]                 *  *                last  = dernière instruction du bloc. [OUT]                  *  *                                                                             * @@ -432,8 +487,11 @@ static const reg_access *g_flow_block_list_regs_accesses(const GFlowBlock *block  void g_flow_block_get_boundary(const GFlowBlock *block, GArchInstruction **first, GArchInstruction **last)  { -    *first = block->first; -    *last = block->last; +    if (first != NULL) +        *first = block->first; + +    if (last != NULL) +        *last = block->last;  } diff --git a/src/analysis/blocks/flow.h b/src/analysis/blocks/flow.h index 8bd7257..28fb5a9 100644 --- a/src/analysis/blocks/flow.h +++ b/src/analysis/blocks/flow.h @@ -55,6 +55,9 @@ GType g_flow_block_get_type(void);  /* Crée un bloc d'exécution d'instructions. */  GInstrBlock *g_flow_block_new(GArchInstruction *, GArchInstruction *, GArchInstruction *); +/* Fournit la liste d'appartenance des instructions du bloc. */ +GArchInstruction *g_flow_block_get_all_instructions_list(const GFlowBlock *); +  /* Fournit les instructions limites d'un bloc d'exécution. */  void g_flow_block_get_boundary(const GFlowBlock *, GArchInstruction **, GArchInstruction **); diff --git a/src/analysis/blocks/virtual.c b/src/analysis/blocks/virtual.c index 90bccca..71a6d06 100644 --- a/src/analysis/blocks/virtual.c +++ b/src/analysis/blocks/virtual.c @@ -69,6 +69,9 @@ static void g_virtual_block_dispose(GVirtualBlock *);  /* Procède à la libération totale de la mémoire. */  static void g_virtual_block_finalize(GVirtualBlock *); +/* Recherche le bloc contenant une adresse donnée. */ +static GInstrBlock *g_virtual_block_find_by_addr(const GVirtualBlock *, vmpa_t); +  /* Parcours le bloc d'instructions dans un ordre donné. */  static bool g_virtual_block_visit(GVirtualBlock *, instr_block_visitor_cb, void *); @@ -126,6 +129,7 @@ static void g_virtual_block_init(GVirtualBlock *block)      parent = G_INSTR_BLOCK(block); +    parent->find_by_addr = (find_by_addr_fc)g_virtual_block_find_by_addr;      parent->visit_blocks = (visit_all_blocks_fc)g_virtual_block_visit;      parent->list_blocks = (list_all_blocks_fc)g_virtual_block_list_all_blocks;      parent->list_regs = (list_regs_accesses_fc)g_virtual_block_list_regs_accesses; @@ -207,6 +211,34 @@ GInstrBlock *g_virtual_block_new(void)  /******************************************************************************  *                                                                             * +*  Paramètres  : block = bloc de départ des recherches.                       * +*                addr  = ensemble de blocs à parcourir.                       * +*                                                                             * +*  Description : Recherche le bloc contenant une adresse donnée.              * +*                                                                             * +*  Retour      : bloc basique trouvé ou NULL en cas d'échec.                  * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GInstrBlock *g_virtual_block_find_by_addr(const GVirtualBlock *block, vmpa_t addr) +{ +    GInstrBlock *result;                    /* Resultat à retourner        */ +    size_t i;                               /* Boucle de parcours          */ + +    result = NULL; + +    for (i = 0; i < block->children_count && result == NULL; i++) +        result = g_instr_block_find_by_addr(block->children[i], addr); + +    return result; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : block    = bloc d'instructions concerné par la visite.       *  *                callback = ensemble de blocs à parcourir.                    *  *                data     = donnée utilisateur à associer au parcours.        * @@ -324,3 +356,27 @@ size_t g_virtual_block_count_children(GVirtualBlock *block)      return block->children_count;  } + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : block = bloc d'instructions à consulter.                     * +*                index = indice du sous-bloc recherché.                       * +*                                                                             * +*  Description : Renvoie un des blocs contenus dans le groupe courant.        * +*                                                                             * +*  Retour      : Un des blocs du groupe.                                      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GInstrBlock *g_virtual_block_get_child(GVirtualBlock *block, size_t index) +{ +    if (index >= block->children_count) +        return NULL; + +    else +        return block->children[index]; + +} diff --git a/src/analysis/blocks/virtual.h b/src/analysis/blocks/virtual.h index 5e8ddcd..b254a27 100644 --- a/src/analysis/blocks/virtual.h +++ b/src/analysis/blocks/virtual.h @@ -61,6 +61,9 @@ void g_virtual_block_add_child(GVirtualBlock *, GInstrBlock *);  /* Compte le nombre de blocs contenus dans le groupe courant. */  size_t g_virtual_block_count_children(GVirtualBlock *); +/* Renvoie un des blocs contenus dans le groupe courant. */ +GInstrBlock *g_virtual_block_get_child(GVirtualBlock *, size_t); +  #endif  /* _ANALYSIS_BLOCKS_VIRTUAL_H */ diff --git a/src/analysis/decomp/decompiler.c b/src/analysis/decomp/decompiler.c index c824697..47c379d 100644 --- a/src/analysis/decomp/decompiler.c +++ b/src/analysis/decomp/decompiler.c @@ -167,11 +167,16 @@ static void prepare_all_routines_for_decomp(const GLoadedBinary *binary, const c          max = g_binary_routine_get_address(routines[i])              + g_binary_routine_get_size(routines[i]); -        //printf("##### DECOMPILE '%s' #####\n", g_binary_routine_to_string(routines[i])); +        printf("##### DECOMPILE '%s' #####\n", g_binary_routine_to_string(routines[i])); + +        dinstrs = decompiled_routine_instructions(routines[i], format, proc); + +        /*          dinstrs = build_decompiled_block(instrs,                                           g_binary_routine_get_address(routines[i]),                                           max, VMPA_MAX, context); +        */          //instr = g_binary_format_decompile_routine(G_BIN_FORMAT(format), routines[i], context); @@ -216,8 +221,6 @@ GCodeBuffer *decompile_all_from_file(const GLoadedBinary *binary, const char *fi      build_decomp_prologue(result, filename); - -    /*      prepare_all_routines_for_decomp(binary, filename); @@ -225,7 +228,7 @@ GCodeBuffer *decompile_all_from_file(const GLoadedBinary *binary, const char *fi      format = g_loaded_binary_get_format(binary);      g_binary_format_decompile(G_BIN_FORMAT(format), result, filename); -    */ +      return result; diff --git a/src/analysis/decomp/il.c b/src/analysis/decomp/il.c index 693b8cb..c2bc0be 100644 --- a/src/analysis/decomp/il.c +++ b/src/analysis/decomp/il.c @@ -24,6 +24,330 @@  #include "il.h" +#include "../blocks/flow.h" +#include "../blocks/virtual.h" +#include "../../decomp/expr/block.h" +#include "../../decomp/instr/ite.h" + + + +/* --------------------- GESTION DES CONTEXTES DE DECOMPILATION --------------------- */ + + + + + + + +/* -------------------------- ENCADREMENT DES INSTRUCTIONS -------------------------- */ + + +/* Retrouve et rassemble les instructions décompilées. */ +static GDecInstruction *merge_decompiled_instructions(GDecInstruction *, GDecInstruction *); + +/* Procède à la décompilation d'un bloc déterminé. */ +static GDecInstruction *decompiled_instructions_block(GFlowBlock *, GVirtualBlock *, GDecContext *); + +/* Procède à la décompilation d'un ensemble de blocs déterminé. */ +static GDecInstruction *decompiled_instructions_blocks(GVirtualBlock *, GDecContext *); + +/* Procède à la décompilation d'un bloc basique quelconque. */ +static GDecInstruction *decompiled_basic_block(GInstrBlock *, GDecContext *); + + + +/* ---------------------------------------------------------------------------------- */ +/*                       GESTION DES CONTEXTES DE DECOMPILATION                       */ +/* ---------------------------------------------------------------------------------- */ + + + + + + + + +/* ---------------------------------------------------------------------------------- */ +/*                            ENCADREMENT DES INSTRUCTIONS                            */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : group = groupe d'instructions à compléter ou constituer.     * +*                list  = liste d'instructions à intégrer.                     * +*                                                                             * +*  Description : Retrouve et rassemble les instructions décompilées.          * +*                                                                             * +*  Retour      : Groupe fourni ou nouveau groupe créé pour l'occasion.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GDecInstruction *merge_decompiled_instructions(GDecInstruction *group, GDecInstruction *list) +{ +    GExprBlock *block;                      /* Autre vision du groupe      */ +    GDecInstruction *iter;                  /* Boucle de parcours          */ + +    if (group == NULL) block = NULL; +    else block = G_EXPR_BLOCK(group); + +    for (iter = list; +         iter != NULL; +         iter = g_dec_instruction_get_next_iter(list, iter)) +    { +        if (block == NULL) +            block = G_EXPR_BLOCK(g_expr_block_new(iter)); +        else +            g_expr_block_add_item(block, iter); + +    } + +    return G_DEC_INSTRUCTION(block); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : block  = ensemble des instructions d'assemblage à traiter.   * +*                parent = groupe de blocs d'appartenance.                     * +*                ctx    = contexte de soutien à associer à l'opération.       * +*                                                                             * +*  Description : Procède à la décompilation d'un bloc déterminé.              * +*                                                                             * +*  Retour      : Instructions créées et enregistrées, ou NULL si erreur.      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GDecInstruction *decompiled_instructions_block(GFlowBlock *block, GVirtualBlock *parent, GDecContext *ctx) +{ +    GDecInstruction *res; + +    GArchInstruction *instrs;               /* Liste d'instructions natives*/ +    GArchInstruction *first;                /* Première instruction du lot */ +    GArchInstruction *last;                 /* Dernière instruction du lot */ +    vmpa_t max;                             /* Adresse de fin du bloc      */ +    GArchInstruction *iter;                 /* Boucle de parcours          */ +    GDecInstruction *decomp;                /* Dernier résultat de décomp. */ +    GDecInstruction *true_dinstr;           /* Décompilation 'cond vraie'  */ +    GDecInstruction *false_dinstr;          /* Décompilation 'cond fausse' */ +    GArchInstruction *next;                 /* Instruction de branchement  */ +    vmpa_t next_addr;                       /* Adresse de cette instruct°  */ +    GInstrBlock *next_block;                /* Bloc basique correspondant  */ + +    instrs = g_flow_block_get_all_instructions_list(block); +    g_flow_block_get_boundary(block, &first, &last); + +    g_flow_block_get_boundary_addresses(block, NULL, &max); +    max++; + +    /* Décompilation du corps du bloc */ + +    for (iter = first; +         iter != NULL; +         iter = g_arch_instruction_get_next_iter(instrs, iter, max)) +    { +        decomp = g_arch_instruction_decompile(iter, ctx); +    } + +    /* Post-traitement selon les types de lien */ + + +    res = g_dec_context_get_decomp_instrs(ctx); + + +    /* if ... then ... else ... */ +    if (G_IS_ITE_INSTRUCTION(decomp)) +    { +        next = g_arch_instruction_get_given_destination(last, ILT_JUMP_IF_TRUE); + +        printf("@ 0x%08llx : true : %p\n", max, next); + +        true_dinstr = NULL; + +        if (next != NULL) +        { +            g_arch_instruction_get_location(next, NULL, NULL, &next_addr); +            next_block = g_instr_block_find_by_addr(G_INSTR_BLOCK(parent), next_addr); + +            if (next_block != NULL) +            { +                next_block = g_instr_block_find_by_addr(next_block, next_addr); +                true_dinstr = decompiled_basic_block(next_block, ctx); +            } + +        } + +        next = g_arch_instruction_get_given_destination(last, ILT_JUMP_IF_FALSE); + +        printf("@ 0x%08llx : false : %p\n", max, next); + +        false_dinstr = NULL; + +        if (next != NULL) +        { +            g_arch_instruction_get_location(next, NULL, NULL, &next_addr); +            next_block = g_instr_block_find_by_addr(G_INSTR_BLOCK(parent), next_addr); + +            if (next_block != NULL) +            { +                next_block = g_instr_block_find_by_addr(next_block, next_addr); +                false_dinstr = decompiled_basic_block(next_block, ctx); +            } + +        } + +        printf(" -> ite : %p + %p\n", true_dinstr, false_dinstr); + +        printf(" -> ite : %s + %s\n", +               g_type_name(G_TYPE_FROM_INSTANCE(true_dinstr)), +               g_type_name(G_TYPE_FROM_INSTANCE(false_dinstr))); + + +        g_ite_instruction_set_branches(G_ITE_INSTRUCTION(decomp), true_dinstr, false_dinstr); + +    } + +    /* Renvoi des instructions mises en place */ + +    return res; + +    //return g_dec_context_get_decomp_instrs(ctx); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : block = ensemble des instructions d'assemblage à traiter.    * +*                ctx   = contexte de soutien à associer à l'opération.        * +*                                                                             * +*  Description : Procède à la décompilation d'un ensemble de blocs déterminé. * +*                                                                             * +*  Retour      : Instructions créées et enregistrées, ou NULL si erreur.      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GDecInstruction *decompiled_instructions_blocks(GVirtualBlock *block, GDecContext *ctx) +{ +    GDecInstruction *result;                /* Instructions à renvoyer     */ +    size_t count;                           /* Nombre de sous-blocs        */ +    size_t i;                               /* Boucle de parcours          */ +    GInstrBlock *sub_block;                 /* Sous-bloc à traiter         */ +    GDecInstruction *dinstrs;               /* Instructions décompilées    */ + +    result = NULL; + +    count = g_virtual_block_count_children(block); + +    for (i = 0; i < count; i++) +    { +        sub_block = g_virtual_block_get_child(block, i); + +        /** +         * Les groupes de blocs sont forcément rattachés à une instruction, +         * donc ils sont décompilés depuis ces instructions, pas ici. +         */ +        if (!G_IS_FLOW_BLOCK(sub_block)) continue; + +        /* FIXME */ +        g_dec_context_set_decomp_instrs(ctx, NULL); + +        dinstrs = decompiled_instructions_block(G_FLOW_BLOCK(sub_block), block, ctx); +        result = merge_decompiled_instructions(result, dinstrs); + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : block = ensemble des instructions d'assemblage à traiter.    * +*                ctx   = contexte de soutien à associer à l'opération.        * +*                                                                             * +*  Description : Procède à la décompilation d'un bloc basique quelconque.     * +*                                                                             * +*  Retour      : Instructions créées et enregistrées, ou NULL si erreur.      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GDecInstruction *decompiled_basic_block(GInstrBlock *block, GDecContext *ctx) +{ +    GDecInstruction *result;                /* Instructions à retourner    */ + +    /* FIXME */ +    g_dec_context_set_decomp_instrs(ctx, NULL); + +    if (G_IS_VIRTUAL_BLOCK(block)) +        result = decompiled_instructions_blocks(G_VIRTUAL_BLOCK(block), ctx); + +    else +    { +        result = decompiled_instructions_block(G_FLOW_BLOCK(block), NULL, ctx); + +        if (!G_IS_EXPR_BLOCK(result)) +            result = merge_decompiled_instructions(NULL, result); + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : routine = routine dont le corps est à traiter.               * +*                format  = format du binaire contenant les instructions.      * +*                proc    = architecture du code machine.                      * +*                                                                             * +*  Description : Procède à la décompilation d'une routinée déterminée.        * +*                                                                             * +*  Retour      : Instructions créées ou NULL si erreur.                       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GDecInstruction *decompiled_routine_instructions(GBinRoutine *routine, GExeFormat *format, GArchProcessor *proc) +{ +    GDecInstruction *result;                /* Instructions à retourner    */ +    GDecContext *context;                   /* Contexte pour la décompil.  */ +    GInstrBlock *blocks;                    /* Blocs basiques de routine   */ + +    context = g_arch_processor_get_decomp_context(proc); + +    g_object_set_data(G_OBJECT(context), "format", format); +    g_object_set_data(G_OBJECT(context), "routine", routine); + +    blocks = g_binary_routine_get_basic_blocks(routine); + +    result = decompiled_basic_block(blocks, context); + +    g_object_unref(context); + +    return result; + +} + + + + + +#if 0 + +  #include <malloc.h>  #include <stdlib.h>  #include <string.h> @@ -380,3 +704,5 @@ GDecInstruction *build_decompiled_block(GArchInstruction *instrs, vmpa_t start,      return result;  } + +#endif diff --git a/src/analysis/decomp/il.h b/src/analysis/decomp/il.h index 4f38b4f..670505c 100644 --- a/src/analysis/decomp/il.h +++ b/src/analysis/decomp/il.h @@ -25,6 +25,18 @@  #define _ANALYSIS_DECOMP_IL_H +#include "../routine.h" +#include "../../arch/processor.h" + + + +/* Procède à la décompilation d'une routinée déterminée. */ +GDecInstruction *decompiled_routine_instructions(GBinRoutine *, GExeFormat *, GArchProcessor *); + + + + +#if 0  #include "../../arch/instruction.h"  #include "../../decomp/instruction.h" @@ -32,7 +44,7 @@  /* Procède à la décompilation basique d'un bloc déterminé. */  GDecInstruction *build_decompiled_block(GArchInstruction *, vmpa_t, vmpa_t, vmpa_t, GDecContext *); - +#endif  #endif  /* _ANALYSIS_DECOMP_IL_H */ diff --git a/src/analysis/variable.c b/src/analysis/variable.c index 6a7c145..edc176a 100644 --- a/src/analysis/variable.c +++ b/src/analysis/variable.c @@ -253,11 +253,14 @@ char *g_binary_variable_to_string(const GBinVariable *var, bool simple)  {      char *result;                           /* Valeur à retourner          */ -    result = _g_data_type_to_string(var->type, simple); +    /* FIXME : décompilation sans type ! */ +    //result = _g_data_type_to_string(var->type, simple); + +    result = strdup("");      if (var->name != NULL)      { -        if (!g_data_type_is_pointer(var->type, true)) +        if (!g_data_type_is_pointer(var->type, true) /* FIXME */ && strlen(result) > 0 /* FIXME */)              result = stradd(result, " ");          result = stradd(result, var->name); diff --git a/src/arch/dalvik/instruction.c b/src/arch/dalvik/instruction.c index 1c109ba..20982b7 100644 --- a/src/arch/dalvik/instruction.c +++ b/src/arch/dalvik/instruction.c @@ -117,12 +117,12 @@ static dalvik_instruction _instructions[DOP_COUNT] = {      [DOP_IF_GE]                 = { 0x35, "if-ge",              dalvik_decomp_instr_if },      [DOP_IF_GT]                 = { 0x36, "if-gt",              dalvik_decomp_instr_if },      [DOP_IF_LE]                 = { 0x37, "if-le",              dalvik_decomp_instr_if }, -    [DOP_IF_EQZ]                = { 0x38, "if-eqz",             dalvik_decomp_instr_if_zero }, -    [DOP_IF_NEZ]                = { 0x39, "if-nez",             dalvik_decomp_instr_if_zero }, -    [DOP_IF_LTZ]                = { 0x3a, "if-ltz",             dalvik_decomp_instr_if_zero }, -    [DOP_IF_GEZ]                = { 0x3b, "if-gez",             dalvik_decomp_instr_if_zero }, -    [DOP_IF_GTZ]                = { 0x3c, "if-gtz",             dalvik_decomp_instr_if_zero }, -    [DOP_IF_LEZ]                = { 0x3d, "if-lez",             dalvik_decomp_instr_if_zero }, +    [DOP_IF_EQZ]                = { 0x38, "if-eqz"/*,             dalvik_decomp_instr_if_zero*/ }, +    [DOP_IF_NEZ]                = { 0x39, "if-nez"/*,             dalvik_decomp_instr_if_zero*/ }, +    [DOP_IF_LTZ]                = { 0x3a, "if-ltz"/*,             dalvik_decomp_instr_if_zero*/ }, +    [DOP_IF_GEZ]                = { 0x3b, "if-gez"/*,             dalvik_decomp_instr_if_zero*/ }, +    [DOP_IF_GTZ]                = { 0x3c, "if-gtz"/*,             dalvik_decomp_instr_if_zero*/ }, +    [DOP_IF_LEZ]                = { 0x3d, "if-lez"/*,             dalvik_decomp_instr_if_zero*/ },      [DOP_UNUSED_3E]             = { 0x3e, NULL /* unused */ },      [DOP_UNUSED_3F]             = { 0x3f, NULL /* unused */ },      [DOP_UNUSED_40]             = { 0x40, NULL /* unused */ }, diff --git a/src/arch/instruction.c b/src/arch/instruction.c index b460b37..06d3e71 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -448,6 +448,35 @@ size_t g_arch_instruction_get_destinations(const GArchInstruction *instr, GArchI  } +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr = instruction dont les informations sont à consulter.  * +*                type  = type de lien recherché.                              * +*                                                                             * +*  Description : Fournit la destination d'une instruction et d'un type donné. * +*                                                                             * +*  Retour      : Instruction de destination trouvée ou NULL.                  * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GArchInstruction *g_arch_instruction_get_given_destination(const GArchInstruction *instr, InstructionLinkType type) +{ +    GArchInstruction *result;               /* Résultat à remonter         */ +    size_t i;                               /* Boucle de parcours          */ + +    result = NULL; + +    for (i = 0; i < instr->to_count && result == NULL; i++) +        if (instr->links_type[i] == type) +            result = instr->to[i]; + +    return result; + +} + +  /* ---------------------------------------------------------------------------------- */  /*                       CONVERSIONS DU FORMAT DES INSTRUCTIONS                       */ diff --git a/src/arch/instruction.h b/src/arch/instruction.h index 2eddc3c..051ce51 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -117,6 +117,9 @@ bool g_arch_instruction_has_destinations(const GArchInstruction *);  /* Fournit les destinations d'une instruction donnée. */  size_t g_arch_instruction_get_destinations(const GArchInstruction *, GArchInstruction ***, InstructionLinkType **); +/* Fournit la destination d'une instruction et d'un type donné. */ +GArchInstruction *g_arch_instruction_get_given_destination(const GArchInstruction *, InstructionLinkType); +  /* --------------------- CONVERSIONS DU FORMAT DES INSTRUCTIONS --------------------- */ diff --git a/src/decomp/context.c b/src/decomp/context.c index 9db0bca..94a50c1 100644 --- a/src/decomp/context.c +++ b/src/decomp/context.c @@ -30,7 +30,6 @@  #include "context-int.h"  #include "instruction-int.h"  #include "../arch/operand.h" -#include "../format/dex/method.h" | 
