summaryrefslogtreecommitdiff
path: root/src/analysis/decomp/il.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2013-01-09 20:36:26 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2013-01-09 20:36:26 (GMT)
commit7cc35e17f3af39ad9a23bff93c42d86f73dd1001 (patch)
tree13bf4ab0af8c277b5503720bb45f6a753206d241 /src/analysis/decomp/il.c
parentdcd03173f71b09f38238f50dfcf4c1db0c014c4c (diff)
Restored some parts of the decompilation process using the new basic blocks.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@320 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/analysis/decomp/il.c')
-rw-r--r--src/analysis/decomp/il.c326
1 files changed, 326 insertions, 0 deletions
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