summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2013-01-14 22:08:00 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2013-01-14 22:08:00 (GMT)
commit2ab78407e9f73b6508afc281400a7c3fc018217f (patch)
tree437054ef874e9536e15b9254a6a8c4c2396604ff
parent35a6cd881528b5f77ce09476eccb39d02d9cc634 (diff)
Cleaned the context used for decompilations.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@324 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
-rw-r--r--ChangeLog25
-rw-r--r--src/analysis/decomp/decompiler.c16
-rw-r--r--src/analysis/decomp/il.c391
-rw-r--r--src/arch/dalvik/context.c67
-rw-r--r--src/arch/dalvik/decomp/const.c4
-rw-r--r--src/arch/dalvik/decomp/iget.c4
-rw-r--r--src/arch/dalvik/decomp/invoke.c12
-rw-r--r--src/arch/dalvik/decomp/iput.c4
-rw-r--r--src/arch/dalvik/decomp/new.c4
-rw-r--r--src/decomp/context-int.h10
-rw-r--r--src/decomp/context.c88
-rw-r--r--src/decomp/context.h21
-rw-r--r--src/format/format.c60
-rw-r--r--src/format/format.h7
14 files changed, 208 insertions, 505 deletions
diff --git a/ChangeLog b/ChangeLog
index 31709b8..38b8828 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+13-01-14 Cyrille Bagard <nocbos@gmail.com>
+
+ * src/analysis/decomp/decompiler.c:
+ * src/analysis/decomp/il.c:
+ Update code.
+
+ * src/arch/dalvik/context.c:
+ Clean the context used for decompilations.
+
+ * src/arch/dalvik/decomp/const.c:
+ * src/arch/dalvik/decomp/iget.c:
+ * src/arch/dalvik/decomp/invoke.c:
+ * src/arch/dalvik/decomp/iput.c:
+ * src/arch/dalvik/decomp/new.c:
+ Update code.
+
+ * src/decomp/context.c:
+ * src/decomp/context.h:
+ * src/decomp/context-int.h:
+ Clean the context used for decompilations.
+
+ * src/format/format.c:
+ * src/format/format.h:
+ Remove old code.
+
13-01-13 Cyrille Bagard <nocbos@gmail.com>
* src/analysis/block.c:
diff --git a/src/analysis/decomp/decompiler.c b/src/analysis/decomp/decompiler.c
index fff654f..71a9286 100644
--- a/src/analysis/decomp/decompiler.c
+++ b/src/analysis/decomp/decompiler.c
@@ -139,12 +139,12 @@ static void prepare_all_routines_for_decomp(const GLoadedBinary *binary, const c
size_t i;
- GDecContext *context; /* Contexte pour la décompil. */
+ //GDecContext *context; /* Contexte pour la décompil. */
GDecInstruction *dinstrs;
- GArchInstruction *instrs; /* Instructions natives */
+ //GArchInstruction *instrs; /* Instructions natives */
- vmpa_t max; /* Première adresse à écarter */
+ //vmpa_t max; /* Première adresse à écarter */
format = g_loaded_binary_get_format(binary);
proc = get_arch_processor_from_format(G_EXE_FORMAT(format));
@@ -156,17 +156,19 @@ static void prepare_all_routines_for_decomp(const GLoadedBinary *binary, const c
for (i = 0; i < count; i++)
{
+ /*
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", routines[i]);
g_dec_context_set_max_address(context, max);
-
+ */
+ /*
instrs = g_binary_routine_get_instructions(routines[i]);
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]));
@@ -185,10 +187,10 @@ static void prepare_all_routines_for_decomp(const GLoadedBinary *binary, const c
g_binary_routine_set_decomp_instructions(routines[i], dinstrs);
-
+ /*
if (context != NULL)
g_object_unref(context);
-
+ */
}
diff --git a/src/analysis/decomp/il.c b/src/analysis/decomp/il.c
index 6333216..60e86b6 100644
--- a/src/analysis/decomp/il.c
+++ b/src/analysis/decomp/il.c
@@ -37,6 +37,8 @@
/* Détermine les registres utilisés avant leur initialisation. */
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);
@@ -144,7 +146,7 @@ static bool track_used_registers(GFlowBlock *block, BlockFollowPosition pos, GRA
}
- /*
+
do
{
vmpa_t start, end;
@@ -157,7 +159,7 @@ static bool track_used_registers(GFlowBlock *block, BlockFollowPosition pos, GRA
}
while (0);
- */
+
break;
@@ -173,15 +175,15 @@ static bool track_used_registers(GFlowBlock *block, BlockFollowPosition pos, GRA
* Paramètres : list = ensemble des instructions d'assemblage à traiter. *
* start = adresse de départ de la routine visée. *
* *
-* Description : Procède à la décompilation d'une routinée déterminée. *
+* Description : Etablit le relévé des allocations de registre. *
* *
-* Retour : Instructions créées ou NULL si erreur. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static GDecContext *init_decomp_context(const GInstrBlock *list, vmpa_t start)
+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 */
@@ -303,7 +305,7 @@ static GDecInstruction *decompiled_instructions_block(GFlowBlock *block, GDecCon
{
next = g_arch_instruction_get_given_destination(last, ILT_JUMP_IF_TRUE);
- //printf("@ 0x%08llx : true : %p\n", max, next);
+ printf("@ 0x%08llx : true : %p\n", max, next);
true_dinstr = NULL;
@@ -320,7 +322,7 @@ static GDecInstruction *decompiled_instructions_block(GFlowBlock *block, GDecCon
next = g_arch_instruction_get_given_destination(last, ILT_JUMP_IF_FALSE);
- //printf("@ 0x%08llx : false : %p\n", max, next);
+ printf("@ 0x%08llx : false : %p\n", max, next);
false_dinstr = NULL;
@@ -335,13 +337,12 @@ static GDecInstruction *decompiled_instructions_block(GFlowBlock *block, GDecCon
}
- /*
printf(" -> ite : %p + %p\n", true_dinstr, false_dinstr);
printf(" -> ite : %s + %s\n",
true_dinstr ? g_type_name(G_TYPE_FROM_INSTANCE(true_dinstr)) : "none",
false_dinstr ? g_type_name(G_TYPE_FROM_INSTANCE(false_dinstr)) : "none");
- */
+
g_ite_instruction_set_branches(G_ITE_INSTRUCTION(decomp), true_dinstr, false_dinstr);
@@ -462,13 +463,11 @@ GDecInstruction *decompiled_routine_instructions(GBinRoutine *routine, GExeForma
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);
+ g_dec_context_set_info(context, routine, format);
blocks = g_binary_routine_get_basic_blocks(routine);
- init_decomp_context(blocks, g_binary_routine_get_address(routine));
+ setup_awaited_regs_allocation(blocks, g_binary_routine_get_address(routine));
result = decompiled_basic_block(blocks, context);
@@ -477,369 +476,3 @@ GDecInstruction *decompiled_routine_instructions(GBinRoutine *routine, GExeForma
return result;
}
-
-
-
-
-
-#if 0
-
-
-#include <malloc.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-#include "../../decomp/expr/block.h"
-#include "../../decomp/instr/ite.h"
-
-
-
-/* Indications sur une branche */
-typedef struct _branch_info
-{
- vmpa_t *jumps; /* Jalons de la branche */
- size_t count; /* Quantité de ces jalons */
-
-} branch_info;
-
-
-/* Indique si une adresse est retenue comme point de passage. */
-static bool is_addr_in_branch(const branch_info *, const vmpa_t *, bool);
-
-/* Identifie les différents points de passage d'une branche. */
-static void find_next_jumps(GArchInstruction *, vmpa_t, vmpa_t, branch_info *);
-
-/* Retrouve le point de ralliement entre deux branches. */
-static vmpa_t compute_first_common_addr(branch_info *, branch_info *);
-
-
-
-
-
-
-
-
-
-/******************************************************************************
-* *
-* Paramètres : info = informations à consulter. *
-* addr = adresse à rechercher. *
-* fast = autorise une recherche rapide. *
-* *
-* Description : Indique si une adresse est retenue comme point de passage. *
-* *
-* Retour : true si le jalon est déjà dans la liste, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool is_addr_in_branch(const branch_info *info, const vmpa_t *addr, bool fast)
-{
- bool result; /* Bilan à retourner */
- size_t i; /* Boucle de parcours */
- void *ptr; /* Résultat des recherches */
-
- result = false;
-
- if (!fast)
- for (i = 0; i < info->count && !result; i++)
- result = (info->jumps[i] == *addr);
-
- else
- {
- ptr = bsearch(addr, info->jumps, info->count, sizeof(vmpa_t), (__compar_fn_t)compare_vmpa);
- result = (ptr != NULL);
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : instrs = ensemble des instructions d'assemblage. *
-* start = adresse de début du bloc. *
-* end = adresse de fin du bloc (exclusive). *
-* count = nombre de sauts détectés. [OUT] *
-* *
-* Description : Identifie les différents points de passage d'une branche. *
-* *
-* Retour : Jalons dans le flot d'exécution. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void find_next_jumps(GArchInstruction *instrs, vmpa_t start, vmpa_t end, branch_info *info)
-{
- GArchInstruction *iter; /* Boucle de parcours #1 */
- GArchInstruction **dests; /* Instr. visée par une autre */
- InstructionLinkType *types; /* Type de lien entre lignes */
- size_t dcount; /* Nombre de liens de dest. */
- size_t i; /* Boucle de parcours #2 */
- vmpa_t addr; /* Adresse de la destination */
-
- /* On évite de boucler... */
- if (is_addr_in_branch(info, &start, false))
- return;
-
- info->jumps = (vmpa_t *)realloc(info->jumps, ++(info->count) * sizeof(vmpa_t));
- info->jumps[info->count - 1] = start;
-
- /* On suit le flot jusqu'à la prochaine bifurcation */
- for (iter = g_arch_instruction_find_by_address(instrs, start, true);
- iter != NULL;
- iter = g_arch_instruction_get_next_iter(instrs, iter, end))
- {
- if (!g_arch_instruction_has_destinations(iter))
- continue;
-
- dcount = g_arch_instruction_get_destinations(iter, &dests, &types);
-
- for (i = 0; i < dcount; i++)
- switch (types[i])
- {
- case ILT_EXEC_FLOW:
- case ILT_JUMP:
- case ILT_JUMP_IF_TRUE:
- case ILT_JUMP_IF_FALSE:
- g_arch_instruction_get_location(dests[i], NULL, NULL, &addr);
- find_next_jumps(instrs, addr, end, info);
- break;
-
- default:
- break;
-
- }
-
- break;
-
- }
-
- /* Si on termine... */
- if (iter != NULL && !is_addr_in_branch(info, &end, false))
- {
- info->jumps = (vmpa_t *)realloc(info->jumps, ++(info->count) * sizeof(vmpa_t));
- info->jumps[info->count - 1] = end;
- }
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : a = premier ensemble de jalons à parcourir. *
-* b = second ensemble de jalons à parcourir. *
-* *
-* Description : Retrouve le point de ralliement entre deux branches. *
-* *
-* Retour : Adresse commune à deux branches. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static vmpa_t compute_first_common_addr(branch_info *a, branch_info *b)
-{
- vmpa_t result; /* Adresse trouvée à retourner */
- size_t i; /* Boucle de parcours */
-
- /* Valeur conceptuellement impossible à renvoyer */
- result = VMPA_MAX;
-
- //qsort(a->jumps, a->count, sizeof(vmpa_t), (__compar_fn_t)compare_vmpa);
- //qsort(b->jumps, b->count, sizeof(vmpa_t), (__compar_fn_t)compare_vmpa);
-
- for (i = 0; i < a->count && result == VMPA_MAX; i++)
- if (is_addr_in_branch(b, &a->jumps[i], false))
- result = a->jumps[i];
-
- return result;
-
-}
-
-
-
-#include "../../arch/processor.h"
-
-
-/******************************************************************************
-* *
-* Paramètres : instrs = ensemble des instructions d'assemblage. *
-* start = adresse de début du bloc. *
-* end = adresse de fin du bloc (exclusive). *
-* stop = adresse d'arrêt en cas de saut ou VMPA_MAX. *
-* ctx = contexte de soutien à associer à l'opération. *
-* *
-* Description : Procède à la décompilation basique d'un bloc déterminé. *
-* *
-* Retour : Instructions créées et enregistrées, ou NULL si erreur. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GDecInstruction *build_decompiled_block(GArchInstruction *instrs, vmpa_t start, vmpa_t end, vmpa_t stop, GDecContext *ctx)
-{
- GDecInstruction *result; /* Instructions décompilées */
- GArchInstruction *iter; /* Boucle de parcours */
-
- GDecInstruction *pite; /* IfThenElse potientiel... */
-
- GArchInstruction **dests; /* Instr. visée par une autre */
- InstructionLinkType *types; /* Type de lien entre lignes */
- size_t dcount; /* Nombre de liens de dest. */
-
- size_t i; /* Boucle de parcours */
- vmpa_t addr; /* Adresse de la destination */
-
- branch_info true_branch; /* Branche 'condition vraie' */
- branch_info false_branch; /* Branche 'condition fausse' */
- GDecInstruction *true_dinstr; /* Décompilation 'cond vraie' */
- GDecInstruction *false_dinstr; /* Décompilation 'cond fausse' */
-
- vmpa_t next_addr; /* Prochaine instruction visée */
-
- GDecInstruction *first; /* Première décompilation */
- GDecInstruction *dinstr; /* Nouvelle décompilation */
-
-
- GExeFormat *format; /* Format du binaire fourni */
- GArchProcessor *proc; /* Architecture du binaire */
- GDecContext *context; /* Contexte pour la décompil. */
-
-
- result = NULL;
-
- //printf("[+] processing 0x%08llx -> 0x%08llx... stop @ 0x%08llx\n", start, end, stop);
-
- for (iter = g_arch_instruction_find_by_address(instrs, start, true);
- iter != NULL;
- )
- {
- /* On s'arrêter si l'instruction est déjà décompilée */
- if (g_object_get_data(G_OBJECT(iter), "decomp_done") != NULL) break;
- g_object_set_data(G_OBJECT(iter), "decomp_done", iter);
-
- pite = g_arch_instruction_decompile(iter, ctx);
-
- g_arch_instruction_get_location(iter, NULL, NULL, &addr);
- //printf(" --- decomp %p @ 0x%08llx\n", pite, addr);
-
- /* On n'approfondit que les chemins qui se séparent */
- if (!g_arch_instruction_has_destinations(iter))
- {
- iter = g_arch_instruction_get_next_iter(instrs, iter, end);
- continue;
- }
-
- /* Adaptations en fonction du type de bifurcation */
-
- dcount = g_arch_instruction_get_destinations(iter, &dests, &types);
-
- next_addr = 0;
- memset(&true_branch, 0, sizeof(branch_info));
- memset(&false_branch, 0, sizeof(branch_info));
-
- for (i = 0; i < dcount; i++)
- switch (types[i])
- {
- case ILT_EXEC_FLOW:
- case ILT_JUMP:
- g_arch_instruction_get_location(dests[i], NULL, NULL, &next_addr);
- break;
-
- case ILT_JUMP_IF_TRUE:
- g_arch_instruction_get_location(dests[i], NULL, NULL, &addr);
- find_next_jumps(instrs, addr, end, &true_branch);
- break;
-
- case ILT_JUMP_IF_FALSE:
- g_arch_instruction_get_location(dests[i], NULL, NULL, &addr);
- find_next_jumps(instrs, addr, end, &false_branch);
- break;
-
- default:
- next_addr = VMPA_MAX;
- break;
-
- }
-
- if (next_addr == VMPA_MAX)
- {
- iter = g_arch_instruction_get_next_iter(instrs, iter, end);
- continue;
- }
-
- else if (true_branch.count > 0 || false_branch.count > 0)
- {
- next_addr = compute_first_common_addr(&true_branch, &false_branch);
- next_addr = MIN(next_addr, end);
-
- format = g_object_get_data(G_OBJECT(ctx), "format");
- proc = get_arch_processor_from_format(G_EXE_FORMAT(format));
-
- context = g_arch_processor_get_decomp_context(proc);
-
- g_object_set_data(G_OBJECT(context), "format", g_object_get_data(G_OBJECT(ctx), "format"));
- g_object_set_data(G_OBJECT(context), "routine", g_object_get_data(G_OBJECT(ctx), "routine"));
- g_dec_context_set_max_address(context, next_addr);
-
- true_dinstr = build_decompiled_block(instrs, true_branch.jumps[0],
- end, next_addr, context);
-
-
- context = g_arch_processor_get_decomp_context(proc);
-
- g_object_set_data(G_OBJECT(context), "format", g_object_get_data(G_OBJECT(ctx), "format"));
- g_object_set_data(G_OBJECT(context), "routine", g_object_get_data(G_OBJECT(ctx), "routine"));
- g_dec_context_set_max_address(context, next_addr);
-
- false_dinstr = build_decompiled_block(instrs, false_branch.jumps[0],
- end, next_addr, context);
-
- /*
- printf("{branch : %p (0x%08llx) | %p (0x%08llx)\n",
- true_dinstr, true_branch.jumps[0],
- false_dinstr, false_branch.jumps[0]);
- */
- g_ite_instruction_set_branches(G_ITE_INSTRUCTION(pite), true_dinstr, false_dinstr);
-
- if (next_addr == end) break;
-
- }
-
- /* Détermination du prochain point de chute */
-
- if (next_addr == stop) break;
-
- iter = g_arch_instruction_find_by_address(instrs, next_addr, true);
-
- }
-
-
-
-
- first = g_dec_context_get_decomp_instrs(ctx);
-
- //printf(" ... context instr : %p\n", first);
-
- for (dinstr = first;
- dinstr != NULL;
- dinstr = g_dec_instruction_get_next_iter(first, dinstr))
- {
- if (result == NULL) result = g_expr_block_new(dinstr);
- else g_expr_block_add_item(G_EXPR_BLOCK(result), dinstr);
-
- }
-
- //printf(" ... return %p\n", result);
-
- return result;
-
-}
-
-#endif
diff --git a/src/arch/dalvik/context.c b/src/arch/dalvik/context.c
index e5041cb..f1af7e9 100644
--- a/src/arch/dalvik/context.c
+++ b/src/arch/dalvik/context.c
@@ -114,6 +114,12 @@ static void g_dalvik_dcontext_class_init(GDalvikDContextClass *);
/* Initialise une instance de contexte de décompilation Dalkvik. */
static void g_dalvik_dcontext_init(GDalvikDContext *);
+/* Supprime toutes les références externes. */
+static void g_dalvik_dcontext_dispose(GDalvikDContext *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_dalvik_dcontext_finalize(GDalvikDContext *);
+
/* Convertit un registre machine en un pseudo-registre. */
static GDecInstruction *g_dalvik_dcontext_convert_register(GDalvikDContext *, GDalvikRegisterOperand *, bool);
@@ -282,7 +288,7 @@ G_DEFINE_TYPE(GDalvikDContext, g_dalvik_dcontext, G_TYPE_DEC_CONTEXT);
/******************************************************************************
* *
-* Paramètres : klass = classe à initialiser. *
+* Paramètres : class = classe à initialiser. *
* *
* Description : Initialise la classe des contextes de décompilation Dalkvik. *
* *
@@ -292,8 +298,14 @@ G_DEFINE_TYPE(GDalvikDContext, g_dalvik_dcontext, G_TYPE_DEC_CONTEXT);
* *
******************************************************************************/
-static void g_dalvik_dcontext_class_init(GDalvikDContextClass *klass)
+static void g_dalvik_dcontext_class_init(GDalvikDContextClass *class)
{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(class);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_dalvik_dcontext_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_dalvik_dcontext_finalize;
}
@@ -326,6 +338,47 @@ static void g_dalvik_dcontext_init(GDalvikDContext *ctx)
/******************************************************************************
* *
+* Paramètres : ctx = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dalvik_dcontext_dispose(GDalvikDContext *ctx)
+{
+ if (ctx->this != NULL)
+ g_object_unref(G_OBJECT(ctx->this));
+
+ G_OBJECT_CLASS(g_dalvik_dcontext_parent_class)->dispose(G_OBJECT(ctx));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : ctx = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dalvik_dcontext_finalize(GDalvikDContext *ctx)
+{
+ G_OBJECT_CLASS(g_dalvik_dcontext_parent_class)->finalize(G_OBJECT(ctx));
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : - *
* *
* Description : Crée un contexte pour la décompilation Dalvik. *
@@ -373,8 +426,8 @@ static GDecInstruction *g_dalvik_dcontext_convert_register(GDalvikDContext *ctx,
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"));
+ format = G_DEX_FORMAT(G_DEC_CONTEXT(ctx)->format);
+ routine = G_DEC_CONTEXT(ctx)->routine;
method = g_dex_format_find_method_by_address(format, g_binary_routine_get_address(routine));
@@ -386,10 +439,7 @@ static GDecInstruction *g_dalvik_dcontext_convert_register(GDalvikDContext *ctx,
/* Objet "this" */
if (info & DVI_THIS)
{
- if (ctx->this != NULL)
- g_object_ref(G_OBJECT(ctx->this));
-
- else
+ if (ctx->this == NULL)
{
this = g_binary_variable_new(/* FIXME */g_basic_type_new(BTP_OTHER) /* FIXME */);
g_binary_variable_set_name(this, "this");
@@ -399,6 +449,7 @@ static GDecInstruction *g_dalvik_dcontext_convert_register(GDalvikDContext *ctx,
}
+ g_object_ref(G_OBJECT(ctx->this));
result = ctx->this;
}
diff --git a/src/arch/dalvik/decomp/const.c b/src/arch/dalvik/decomp/const.c
index 47a859e..98133ac 100644
--- a/src/arch/dalvik/decomp/const.c
+++ b/src/arch/dalvik/decomp/const.c
@@ -83,7 +83,6 @@ GDecInstruction *dalvik_decomp_instr_const_str(const GArchInstruction *instr, GD
GArchOperand *operand; /* Opérande de l'instruction */
GDecInstruction *reg; /* Pseudo-registre redéfini */
uint32_t index; /* Indice de la chaîne */
- GDexFormat *format; /* Accès aux constantes */
const char *value; /* Chaîne de caractères */
GDecInstruction *str; /* Chaîne décompilée */
@@ -93,8 +92,7 @@ GDecInstruction *dalvik_decomp_instr_const_str(const GArchInstruction *instr, GD
operand = g_arch_instruction_get_operand(instr, 1);
index = g_dalvik_pool_operand_get_index(G_DALVIK_POOL_OPERAND(operand));
- format = G_DEX_FORMAT(g_object_get_data(G_OBJECT(ctx), "format"));
- value = get_string_from_dex_pool(format, index);
+ value = get_string_from_dex_pool(G_DEX_FORMAT(g_dec_context_get_format(ctx)), index);
if (value == NULL) return NULL;
str = g_str_expression_new(value);
diff --git a/src/arch/dalvik/decomp/iget.c b/src/arch/dalvik/decomp/iget.c
index 931438c..5d1cf65 100644
--- a/src/arch/dalvik/decomp/iget.c
+++ b/src/arch/dalvik/decomp/iget.c
@@ -50,7 +50,6 @@ GDecInstruction *dalvik_decomp_instr_iget(const GArchInstruction *instr, GDecCon
GArchOperand *operand; /* Opérande de l'instruction */
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 */
@@ -61,8 +60,7 @@ GDecInstruction *dalvik_decomp_instr_iget(const GArchInstruction *instr, GDecCon
operand = g_arch_instruction_get_operand(instr, 2);
index = g_dalvik_pool_operand_get_index(G_DALVIK_POOL_OPERAND(operand));
- format = G_DEX_FORMAT(g_object_get_data(G_OBJECT(ctx), "format"));
- var = get_field_from_dex_pool(format, index);
+ var = get_field_from_dex_pool(G_DEX_FORMAT(g_dec_context_get_format(ctx)), index);
field = g_pseudo_register_new();
g_pseudo_register_set_variable(G_PSEUDO_REGISTER(field), var);
diff --git a/src/arch/dalvik/decomp/invoke.c b/src/arch/dalvik/decomp/invoke.c
index 6f863be..7337ccc 100644
--- a/src/arch/dalvik/decomp/invoke.c
+++ b/src/arch/dalvik/decomp/invoke.c
@@ -58,7 +58,6 @@ GDecInstruction *dalvik_decomp_instr_invoke_direct(const GArchInstruction *instr
size_t count; /* Quantité d'opérandes */
GArchOperand *operand; /* Opérande de l'instruction */
uint32_t index; /* Indice de l'élément visé */
- GDexFormat *format; /* Accès aux constantes */
GBinRoutine *routine; /* Routine visée par l'appel */
const char *name; /* Chaîne à afficher */
GDecInstruction *src; /* Source de l'assignation */
@@ -80,8 +79,7 @@ GDecInstruction *dalvik_decomp_instr_invoke_direct(const GArchInstruction *instr
index = g_dalvik_pool_operand_get_index(G_DALVIK_POOL_OPERAND(operand));
- format = G_DEX_FORMAT(g_object_get_data(G_OBJECT(ctx), "format"));
- routine = get_routine_from_dex_pool(format, index);
+ routine = get_routine_from_dex_pool(G_DEX_FORMAT(g_dec_context_get_format(ctx)), index);
if (routine == NULL) return NULL;
/* Détermination de la routine-cible exacte */
@@ -158,7 +156,6 @@ GDecInstruction *dalvik_decomp_instr_invoke_static(const GArchInstruction *instr
size_t count; /* Quantité d'opérandes */
GArchOperand *operand; /* Opérande de l'instruction */
uint32_t index; /* Indice de l'élément visé */
- GDexFormat *format; /* Accès aux constantes */
GBinRoutine *routine; /* Routine visée par l'appel */
GDecInstruction *call; /* Représentation de l'appel */
size_t i; /* Boucle de parcours #2 */
@@ -174,8 +171,7 @@ GDecInstruction *dalvik_decomp_instr_invoke_static(const GArchInstruction *instr
index = g_dalvik_pool_operand_get_index(G_DALVIK_POOL_OPERAND(operand));
- format = G_DEX_FORMAT(g_object_get_data(G_OBJECT(ctx), "format"));
- routine = get_routine_from_dex_pool(format, index);
+ routine = get_routine_from_dex_pool(G_DEX_FORMAT(g_dec_context_get_format(ctx)), index);
if (routine == NULL) return NULL;
call = g_routine_call_new(routine);
@@ -218,7 +214,6 @@ GDecInstruction *dalvik_decomp_instr_invoke_virtual(const GArchInstruction *inst
size_t count; /* Quantité d'opérandes */
GArchOperand *operand; /* Opérande de l'instruction */
uint32_t index; /* Indice de l'élément visé */
- GDexFormat *format; /* Accès aux constantes */
GBinRoutine *routine; /* Routine visée par l'appel */
GDecInstruction *call; /* Représentation de l'appel */
size_t i; /* Boucle de parcours #2 */
@@ -234,8 +229,7 @@ GDecInstruction *dalvik_decomp_instr_invoke_virtual(const GArchInstruction *inst
index = g_dalvik_pool_operand_get_index(G_DALVIK_POOL_OPERAND(operand));
- format = G_DEX_FORMAT(g_object_get_data(G_OBJECT(ctx), "format"));
- routine = get_routine_from_dex_pool(format, index);
+ routine = get_routine_from_dex_pool(G_DEX_FORMAT(g_dec_context_get_format(ctx)), index);
if (routine == NULL) return NULL;
call = g_routine_call_new(routine);
diff --git a/src/arch/dalvik/decomp/iput.c b/src/arch/dalvik/decomp/iput.c
index 002bdd4..fedb00e 100644
--- a/src/arch/dalvik/decomp/iput.c
+++ b/src/arch/dalvik/decomp/iput.c
@@ -51,7 +51,6 @@ GDecInstruction *dalvik_decomp_instr_iput(const GArchInstruction *instr, GDecCon
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 *access; /* Représentation de l'accès */
@@ -64,8 +63,7 @@ GDecInstruction *dalvik_decomp_instr_iput(const GArchInstruction *instr, GDecCon
operand = g_arch_instruction_get_operand(instr, 2);
index = g_dalvik_pool_operand_get_index(G_DALVIK_POOL_OPERAND(operand));
- format = G_DEX_FORMAT(g_object_get_data(G_OBJECT(ctx), "format"));
- var = get_field_from_dex_pool(format, index);
+ var = get_field_from_dex_pool(G_DEX_FORMAT(g_dec_context_get_format(ctx)), index);
field = g_pseudo_register_new();
g_pseudo_register_set_variable(G_PSEUDO_REGISTER(field), var);
diff --git a/src/arch/dalvik/decomp/new.c b/src/arch/dalvik/decomp/new.c
index ff80411..75dc259 100644
--- a/src/arch/dalvik/decomp/new.c
+++ b/src/arch/dalvik/decomp/new.c
@@ -48,7 +48,6 @@ GDecInstruction *dalvik_decomp_instr_new_instance(const GArchInstruction *instr,
GDecInstruction *result; /* Instruction à retourner */
GArchOperand *operand; /* Opérande de l'instruction */
uint32_t index; /* Indice dans la table */
- GDexFormat *format; /* Accès aux constantes */
GDataType *type; /* Type concerné par l'opérat° */
GBinRoutine *constructor; /* Constructeur reconstruit */
GDecInstruction *call; /* Appel au constructeur */
@@ -56,8 +55,7 @@ GDecInstruction *dalvik_decomp_instr_new_instance(const GArchInstruction *instr,
operand = g_arch_instruction_get_operand(instr, 1);
index = g_dalvik_pool_operand_get_index(G_DALVIK_POOL_OPERAND(operand));
- format = G_DEX_FORMAT(g_object_get_data(G_OBJECT(ctx), "format"));
- type = get_type_from_dex_pool(format, index);
+ type = get_type_from_dex_pool(G_DEX_FORMAT(g_dec_context_get_format(ctx)), index);
constructor = g_binary_routine_new_constructor(type);
call = g_routine_call_new(constructor);
diff --git a/src/decomp/context-int.h b/src/decomp/context-int.h
index 2be4218..8139077 100644
--- a/src/decomp/context-int.h
+++ b/src/decomp/context-int.h
@@ -28,6 +28,7 @@
#include "context.h"
+#include "../analysis/routine.h"
#include "../glibext/gnhash.h"
@@ -41,18 +42,13 @@ struct _GDecContext
{
GObject parent; /* A laisser en premier */
- vmpa_t max; /* Première adresse à écarter */
+ 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 */
- GHashTable *machine; /* Correspondance reg./pseudo */
- GHashTable *ssa; /* Remplacement des pseudos */
-
- GDecInstruction **pseudos; /* Liste des pseudos-registre */
- size_t count; /* Taille de cette liste */
-
};
diff --git a/src/decomp/context.c b/src/decomp/context.c
index 94a50c1..6905505 100644
--- a/src/decomp/context.c
+++ b/src/decomp/context.c
@@ -39,6 +39,12 @@ static void g_dec_context_class_init(GDecContextClass *);
/* Initialise une instance de contexte de décompilation. */
static void g_dec_context_init(GDecContext *);
+/* Supprime toutes les références externes. */
+static void g_dec_context_dispose(GDecContext *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_dec_context_finalize(GDecContext *);
+
/* Indique le type défini pour un contexte de décompilation. */
@@ -47,7 +53,7 @@ G_DEFINE_TYPE(GDecContext, g_dec_context, G_TYPE_OBJECT);
/******************************************************************************
* *
-* Paramètres : klass = classe à initialiser. *
+* Paramètres : class = classe à initialiser. *
* *
* Description : Initialise la classe des contextes de décompilation. *
* *
@@ -57,8 +63,14 @@ G_DEFINE_TYPE(GDecContext, g_dec_context, G_TYPE_OBJECT);
* *
******************************************************************************/
-static void g_dec_context_class_init(GDecContextClass *klass)
+static void g_dec_context_class_init(GDecContextClass *class)
{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(class);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_dec_context_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_dec_context_finalize;
}
@@ -77,8 +89,50 @@ static void g_dec_context_class_init(GDecContextClass *klass)
static void g_dec_context_init(GDecContext *ctx)
{
- ctx->machine = g_hash_table_new(g_constant_hash, (GEqualFunc)g_arch_operand_compare);
- ctx->ssa = g_hash_table_new(NULL, NULL);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : ctx = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dec_context_dispose(GDecContext *ctx)
+{
+ if (ctx->format != NULL)
+ g_object_unref(G_OBJECT(ctx->format));
+
+ if (ctx->routine != NULL)
+ g_object_unref(G_OBJECT(ctx->routine));
+
+ G_OBJECT_CLASS(g_dec_context_parent_class)->dispose(G_OBJECT(ctx));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : ctx = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dec_context_finalize(GDecContext *ctx)
+{
+ G_OBJECT_CLASS(g_dec_context_parent_class)->finalize(G_OBJECT(ctx));
}
@@ -108,19 +162,25 @@ GDecContext *g_dec_context_new(void)
/******************************************************************************
* *
-* Paramètres : ctx = instance à consulter. *
+* Paramètres : ctx = contexte de décompilation à compléter. *
+* routine = routine visée par l'opération. *
+* format = format du fichier binaire associé. *
* *
-* Description : Indique l'adresse où la décompilation n'est plus souhaitée. *
+* Description : Définit les informations essentielles à la décompilation. *
* *
-* Retour : Adresse mémoire ou physique. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-vmpa_t g_dec_context_get_max_address(const GDecContext *ctx)
+void g_dec_context_set_info(GDecContext *ctx, GBinRoutine *routine, GExeFormat *format)
{
- return ctx->max;
+ g_object_ref(G_OBJECT(routine));
+ g_object_ref(G_OBJECT(format));
+
+ ctx->routine = routine;
+ ctx->format = format;
}
@@ -128,19 +188,19 @@ vmpa_t g_dec_context_get_max_address(const GDecContext *ctx)
/******************************************************************************
* *
* Paramètres : ctx = instance à consulter. *
-* max = adresse mémoire ou physique. *
* *
-* Description : Définit l'adresse où la décompilation n'est plus souhaitée. *
+* Description : Fournit le format binaire associé au contexte. *
* *
-* Retour : - . *
+* Retour : Format du fichier binaire décompilé. *
* *
* Remarques : - *
* *
******************************************************************************/
-void g_dec_context_set_max_address(GDecContext *ctx, vmpa_t max)
+GExeFormat *g_dec_context_get_format(const GDecContext *ctx)
{
- ctx->max = max;
+ return ctx->format;
+
}
diff --git a/src/decomp/context.h b/src/decomp/context.h
index bf584f4..2daff91 100644
--- a/src/decomp/context.h
+++ b/src/decomp/context.h
@@ -30,6 +30,19 @@
#include "instruction.h"
#include "../arch/archbase.h"
+#include "../format/executable.h"
+
+
+/**
+ * Impossible d'inclure directement :
+ * - ../analysis/routine.h, qui inclut ../arch/instruction.h.
+ * - ../arch/instruction.h, qui inclut ce fichier.
+ *
+ * On redéclare donc manuellement les types manquants.
+ */
+
+/* "../analysis/routine.h" : Représentation générique de routine (instance) */
+typedef struct _GBinRoutine GBinRoutine;
@@ -55,11 +68,11 @@ GType g_dec_context_get_type(void);
/* Met en place un nouveau contexte de décompilation. */
GDecContext *g_dec_context_new(void);
-/* Indique l'adresse où la décompilation n'est plus souhaitée. */
-vmpa_t g_dec_context_get_max_address(const GDecContext *);
+/* Définit les informations essentielles à la décompilation. */
+void g_dec_context_set_info(GDecContext *, GBinRoutine *, GExeFormat *);
-/* Définit l'adresse où la décompilation n'est plus souhaitée. */
-void g_dec_context_set_max_address(GDecContext *, vmpa_t);
+/* Fournit le format binaire associé au contexte. */
+GExeFormat *g_dec_context_get_format(const GDecContext *);
/* Fournit le premier élément de la liste des instructions. */
GDecInstruction *g_dec_context_get_decomp_instrs(const GDecContext *tx);
diff --git a/src/format/format.c b/src/format/format.c
index 79ef5dd..b7ec199 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -2,7 +2,7 @@
/* OpenIDA - Outil d'analyse de fichiers binaires
* format.c - support des différents formats binaires
*
- * Copyright (C) 2009-2012 Cyrille Bagard
+ * Copyright (C) 2009-2013 Cyrille Bagard
*
* This file is part of OpenIDA.
*
@@ -270,64 +270,6 @@ 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. *
-* *
-* Retour : Instructions créées et enregistrées, ou NULL si erreur. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-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 */
- GArchInstruction *iter; /* Boucle de parcours */
- GDecInstruction *first; /* Première décompilation */
- GDecInstruction *dinstr; /* Nouvelle décompilation */
-
- result = NULL;
-
- instr = g_binary_routine_get_instructions(routine);
- max = g_binary_routine_get_address(routine)
- + g_binary_routine_get_size(routine);
-
- 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;
- iter != NULL;
- iter = g_arch_instruction_get_next_iter(instr, iter, max))
- {
- g_arch_instruction_decompile(iter, ctx);
- }
-
- first = g_dec_context_get_decomp_instrs(ctx);
-
- for (dinstr = first;
- dinstr != NULL;
- dinstr = g_dec_instruction_get_next_iter(first, dinstr))
- {
- if (result == NULL) result = g_expr_block_new(dinstr);
- else g_expr_block_add_item(G_EXPR_BLOCK(result), dinstr);
-
- }
-
- g_binary_routine_set_decomp_instructions(routine, result);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
* Paramètres : format = informations chargées à consulter. *
* count = taille de la liste retournée. [OUT] *
* defsrc = fichier de code principal. [OUT] *
diff --git a/src/format/format.h b/src/format/format.h
index fec03ea..f0489e9 100644
--- a/src/format/format.h
+++ b/src/format/format.h
@@ -2,7 +2,7 @@
/* OpenIDA - Outil d'analyse de fichiers binaires
* format.h - prototypes pour le support des différents formats binaires
*
- * Copyright (C) 2009-2011 Cyrille Bagard
+ * Copyright (C) 2009-2013 Cyrille Bagard
*
* This file is part of OpenIDA.
*
@@ -32,8 +32,6 @@
#include "symbol.h"
#include "../analysis/routine.h"
-#include "../decomp/context.h"
-#include "../decomp/instruction.h"
@@ -72,9 +70,6 @@ void g_binary_format_add_routine(GBinFormat *, GBinRoutine *);
/* Fournit le prototype de toutes les routines détectées. */
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 *, 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 *);