summaryrefslogtreecommitdiff
path: root/src/analysis/decomp/il.c
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 /src/analysis/decomp/il.c
parent35a6cd881528b5f77ce09476eccb39d02d9cc634 (diff)
Cleaned the context used for decompilations.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@324 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/analysis/decomp/il.c')
-rw-r--r--src/analysis/decomp/il.c391
1 files changed, 12 insertions, 379 deletions
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