summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2013-01-17 22:21:03 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2013-01-17 22:21:03 (GMT)
commita9bbd894bd25f7c2bb72fb7d4064b19377d90c6d (patch)
treed430c135864caa960c71ed86c5713507de66f708 /src
parent2ab78407e9f73b6508afc281400a7c3fc018217f (diff)
Forked the decompilation context when needed.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@325 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src')
-rw-r--r--src/analysis/decomp/il.c79
-rw-r--r--src/arch/dalvik/context.c41
-rw-r--r--src/decomp/context-int.h12
-rw-r--r--src/decomp/context.c34
-rw-r--r--src/decomp/context.h4
5 files changed, 134 insertions, 36 deletions
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 *);