From a9bbd894bd25f7c2bb72fb7d4064b19377d90c6d Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Thu, 17 Jan 2013 22:21:03 +0000 Subject: Forked the decompilation context when needed. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@325 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 9 ++++++ src/analysis/decomp/il.c | 79 ++++++++++++++++++++++++++++++----------------- src/arch/dalvik/context.c | 41 ++++++++++++++++++++++++ src/decomp/context-int.h | 12 +++++-- src/decomp/context.c | 34 +++++++++++++++++--- src/decomp/context.h | 4 +-- 6 files changed, 143 insertions(+), 36 deletions(-) diff --git a/ChangeLog b/ChangeLog index 38b8828..620779f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +13-01-17 Cyrille Bagard + + * src/analysis/decomp/il.c: + * src/arch/dalvik/context.c: + * src/decomp/context.c: + * src/decomp/context.h: + * src/decomp/context-int.h: + Fork the decompilation context when needed. + 13-01-14 Cyrille Bagard * src/analysis/decomp/decompiler.c: diff --git a/src/analysis/decomp/il.c b/src/analysis/decomp/il.c index 60e86b6..642c921 100644 --- a/src/analysis/decomp/il.c +++ b/src/analysis/decomp/il.c @@ -40,7 +40,8 @@ static bool track_used_registers(GFlowBlock *, BlockFollowPosition, GRAccessList /* Etablit le relévé des allocations de registre. */ static void setup_awaited_regs_allocation(const GInstrBlock *, vmpa_t); - +/* Met en place un contexte adapté aux sous-blocs d'un bloc. */ +static GDecContext *create_new_context_for_sub_block(GDecContext *, GInstrBlock *); @@ -185,12 +186,9 @@ static bool track_used_registers(GFlowBlock *block, BlockFollowPosition pos, GRA static void setup_awaited_regs_allocation(const GInstrBlock *list, vmpa_t start) { - GDecContext *result; /* Contexte pour la décompil. */ GInstrBlock *first; /* Bloc de départ du flot */ GRAccessList *needed; /* Registres inter-blocs */ - result = NULL; - first = g_instr_block_find_by_addr(list, start, true); needed = g_raccess_list_new(); @@ -200,11 +198,31 @@ static void setup_awaited_regs_allocation(const GInstrBlock *list, vmpa_t start) g_object_unref(G_OBJECT(needed)); +} - return result; -} +/****************************************************************************** +* * +* Paramètres : ctx = contexte de décompilation courant. * +* block = block regroupant les branches de division. * +* * +* Description : Met en place un contexte adapté aux sous-blocs d'un bloc. * +* * +* Retour : Nouveau contexte près à emploi. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GDecContext *create_new_context_for_sub_block(GDecContext *ctx, GInstrBlock *block) +{ + + return g_dec_context_dup(ctx); + + + +} /* ---------------------------------------------------------------------------------- */ @@ -272,11 +290,13 @@ static GDecInstruction *decompiled_instructions_block(GFlowBlock *block, GDecCon vmpa_t max; /* Adresse de fin du bloc */ GArchInstruction *iter; /* Boucle de parcours */ GDecInstruction *decomp; /* Dernier résultat de décomp. */ + GInstrBlock *sub_parent; /* Groupe des sous-branches */ + GDecContext *sub_ctx; /* Sous-contexte pour branche */ 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_parent; /* Bloc basique correspondant */ + //GInstrBlock *next_parent; /* Bloc basique correspondant */ GInstrBlock *next_block; /* Sous-bloc basique direct */ instrs = g_flow_block_get_all_instructions_list(block); @@ -297,43 +317,47 @@ static GDecInstruction *decompiled_instructions_block(GFlowBlock *block, GDecCon /* Post-traitement selon les types de lien */ - res = g_dec_context_get_decomp_instrs(ctx); + //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); + sub_parent = g_instr_block_get_links_block(G_INSTR_BLOCK(block)); true_dinstr = NULL; + next = g_arch_instruction_get_given_destination(last, ILT_JUMP_IF_TRUE); if (next != NULL) { g_arch_instruction_get_location(next, NULL, NULL, &next_addr); - next_parent = g_instr_block_get_links_block(G_INSTR_BLOCK(block)); - next_block = g_instr_block_find_by_addr(next_parent, next_addr, false); + next_block = g_instr_block_find_by_addr(sub_parent, next_addr, false); if (next_block != NULL) - true_dinstr = decompiled_basic_block(next_block, ctx); + { + sub_ctx = create_new_context_for_sub_block(ctx, sub_parent); + true_dinstr = decompiled_basic_block(next_block, sub_ctx); + /* TODO : merge awaited */ + g_object_unref(G_OBJECT(sub_ctx)); + } } - next = g_arch_instruction_get_given_destination(last, ILT_JUMP_IF_FALSE); - - printf("@ 0x%08llx : false : %p\n", max, next); - false_dinstr = NULL; + next = g_arch_instruction_get_given_destination(last, ILT_JUMP_IF_FALSE); if (next != NULL) { g_arch_instruction_get_location(next, NULL, NULL, &next_addr); - next_parent = g_instr_block_get_links_block(G_INSTR_BLOCK(block)); - next_block = g_instr_block_find_by_addr(next_parent, next_addr, false); + next_block = g_instr_block_find_by_addr(sub_parent, next_addr, false); if (next_block != NULL) - false_dinstr = decompiled_basic_block(next_block, ctx); + { + sub_ctx = create_new_context_for_sub_block(ctx, sub_parent); + false_dinstr = decompiled_basic_block(next_block, sub_ctx); + /* TODO : merge awaited */ + g_object_unref(G_OBJECT(sub_ctx)); + } } @@ -350,9 +374,9 @@ static GDecInstruction *decompiled_instructions_block(GFlowBlock *block, GDecCon /* Renvoi des instructions mises en place */ - return res; + //return res; - //return g_dec_context_get_decomp_instrs(ctx); + return g_dec_context_get_decomp_instrs(ctx); } @@ -393,13 +417,15 @@ static GDecInstruction *decompiled_instructions_blocks(GVirtualBlock *block, GDe if (!G_IS_FLOW_BLOCK(sub_block)) continue; /* FIXME */ - g_dec_context_set_decomp_instrs(ctx, NULL); + //g_dec_context_set_decomp_instrs(ctx, NULL); dinstrs = decompiled_instructions_block(G_FLOW_BLOCK(sub_block), ctx); - result = merge_decompiled_instructions(result, dinstrs); + //result = merge_decompiled_instructions(result, dinstrs); } + result = merge_decompiled_instructions(result, dinstrs); + return result; } @@ -422,9 +448,6 @@ static GDecInstruction *decompiled_basic_block(GInstrBlock *block, GDecContext * { 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); diff --git a/src/arch/dalvik/context.c b/src/arch/dalvik/context.c index f1af7e9..e80ead3 100644 --- a/src/arch/dalvik/context.c +++ b/src/arch/dalvik/context.c @@ -120,6 +120,9 @@ static void g_dalvik_dcontext_dispose(GDalvikDContext *); /* Procède à la libération totale de la mémoire. */ static void g_dalvik_dcontext_finalize(GDalvikDContext *); +/* Duplique un contexte de compilation. */ +static GDalvikDContext *g_dalvik_dcontext_dup(GDalvikDContext *); + /* Convertit un registre machine en un pseudo-registre. */ static GDecInstruction *g_dalvik_dcontext_convert_register(GDalvikDContext *, GDalvikRegisterOperand *, bool); @@ -331,6 +334,7 @@ static void g_dalvik_dcontext_init(GDalvikDContext *ctx) parent = G_DEC_CONTEXT(ctx); + parent->dup = (dup_dec_context_fc)g_dalvik_dcontext_dup; parent->convert_reg = (convert_register_fc)g_dalvik_dcontext_convert_register; } @@ -402,6 +406,43 @@ GDalvikDContext *g_dalvik_dcontext_new(void) /****************************************************************************** * * +* Paramètres : orig = contexte de compilation à copier. * +* * +* Description : Duplique un contexte de compilation. * +* * +* Retour : Contexte de décompilation prêt à emploi. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GDalvikDContext *g_dalvik_dcontext_dup(GDalvikDContext *orig) +{ + GDalvikDContext *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_DALVIK_DCONTEXT, NULL); + + //g_object_unref(G_OBJECT(result->args)); + //g_object_unref(G_OBJECT(result->locals)); + + _g_dec_context_dup(G_DEC_CONTEXT(result), G_DEC_CONTEXT(orig)); + + if (orig->this != NULL) g_object_ref(G_OBJECT(orig->this)); + //g_object_ref(G_OBJECT(orig->args)); + //g_object_ref(G_OBJECT(orig->locals)); + + result->this = orig->this; + result->args = orig->args; + result->locals = orig->locals; + result->locals_count = orig->locals_count; + + 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. * diff --git a/src/decomp/context-int.h b/src/decomp/context-int.h index 8139077..7e5b1b0 100644 --- a/src/decomp/context-int.h +++ b/src/decomp/context-int.h @@ -33,6 +33,9 @@ +/* Duplique un contexte de compilation. */ +typedef GDecContext * (* dup_dec_context_fc) (GDecContext *); + /* Convertit un registre machine en un pseudo-registre. */ typedef GDecInstruction * (* convert_register_fc) (GDecContext *, gpointer, bool); @@ -42,13 +45,14 @@ struct _GDecContext { GObject parent; /* A laisser en premier */ + dup_dec_context_fc dup; /* Duplication de contexte */ + convert_register_fc convert_reg; /* Traduction des registres */ + GExeFormat *format; /* Format binaire concerné */ GBinRoutine *routine; /* Routine visée par l'opérat° */ GDecInstruction *list; /* Chaîne décompilée */ - convert_register_fc convert_reg; /* Traduction des registres */ - }; @@ -60,5 +64,9 @@ struct _GDecContextClass }; +/* Duplique partiellement un contexte de compilation. */ +void _g_dec_context_dup(GDecContext *, GDecContext *); + + #endif /* _DECOMP_CONTEXT_INT_H */ diff --git a/src/decomp/context.c b/src/decomp/context.c index 6905505..025c0d2 100644 --- a/src/decomp/context.c +++ b/src/decomp/context.c @@ -139,9 +139,35 @@ static void g_dec_context_finalize(GDecContext *ctx) /****************************************************************************** * * -* Paramètres : - * +* Paramètres : dest = contexte de compilation à définir. * +* src = contexte de compilation à copier. * * * -* Description : Met en place un nouveau contexte de décompilation. * +* Description : Duplique partiellement un contexte de compilation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void _g_dec_context_dup(GDecContext *dest, GDecContext *src) +{ + if (src->routine != NULL) + g_object_ref(G_OBJECT(src->routine)); + if (src->format != NULL) + g_object_ref(G_OBJECT(src->format)); + + dest->routine = src->routine; + dest->format = src->format; + +} + + +/****************************************************************************** +* * +* Paramètres : orig = contexte de compilation à copier. * +* * +* Description : Duplique un contexte de compilation. * * * * Retour : Contexte de décompilation prêt à emploi. * * * @@ -149,11 +175,11 @@ static void g_dec_context_finalize(GDecContext *ctx) * * ******************************************************************************/ -GDecContext *g_dec_context_new(void) +GDecContext *g_dec_context_dup(GDecContext *orig) { GDecContext *result; /* Instance à retourner */ - result = g_object_new(G_TYPE_DEC_CONTEXT, NULL); + result = orig->dup(orig); return result; diff --git a/src/decomp/context.h b/src/decomp/context.h index 2daff91..94b3270 100644 --- a/src/decomp/context.h +++ b/src/decomp/context.h @@ -65,8 +65,8 @@ typedef struct _GDecContextClass GDecContextClass; /* Indique le type défini pour un contexte de décompilation. */ GType g_dec_context_get_type(void); -/* Met en place un nouveau contexte de décompilation. */ -GDecContext *g_dec_context_new(void); +/* Duplique un contexte de compilation. */ +GDecContext *g_dec_context_dup(GDecContext *); /* Définit les informations essentielles à la décompilation. */ void g_dec_context_set_info(GDecContext *, GBinRoutine *, GExeFormat *); -- cgit v0.11.2-87-g4458