summaryrefslogtreecommitdiff
path: root/src/analysis/disass
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-03-31 23:20:33 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-03-31 23:20:33 (GMT)
commit5cc7bd39ae41af40a0c939acf98f90bf1375effd (patch)
tree4f7140e2c5a8d939c672fb941e66903300229e82 /src/analysis/disass
parent52e036040b5e0ad8acde3d467ac8d9ca43ed414c (diff)
Saved some progress in the definition of basic blocks.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@497 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/analysis/disass')
-rw-r--r--src/analysis/disass/area.c2
-rw-r--r--src/analysis/disass/disassembler.c37
-rw-r--r--src/analysis/disass/links.c87
-rw-r--r--src/analysis/disass/macro.c105
4 files changed, 219 insertions, 12 deletions
diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c
index 90738be..3a23993 100644
--- a/src/analysis/disass/area.c
+++ b/src/analysis/disass/area.c
@@ -565,7 +565,7 @@ bool load_code_from_mem_area(mem_area **list, size_t *count, size_t *index, cons
/* Eventuel renvoi vers d'autres adresses */
- g_arch_instruction_call_hook(instr, IPH_LINK, ctx, format);
+ g_arch_instruction_call_hook(instr, IPH_FETCH, proc, ctx, format);
/* Progression dans les traitements */
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index 95d95d0..fcc41cb 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -186,6 +186,8 @@ static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GAr
static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtStatusBar *statusbar)
{
+ //GBinFormat *format; /* Format du fichier binaire */
+ GArchProcessor *proc; /* Architecture du binaire */
unsigned int valid; /* Instructions traduites */
@@ -199,9 +201,12 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta
bstatus_id_t id; /* Identifiant de statut */
- GArchProcessor *proc; /* Architecture du binaire */
+ //GArchProcessor *proc; /* Architecture du binaire */
+ //format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
+ proc = g_loaded_binary_get_processor(disass->binary);
+
routines = g_binary_format_get_routines(G_BIN_FORMAT(disass->format), &routines_count);
@@ -219,6 +224,8 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta
*disass->instrs = disassemble_binary_content(disass->binary, statusbar);
+ g_arch_processor_set_disassembled_instructions(proc, *disass->instrs);
+
/*
*disass->instrs = disassemble_binary_parts(disass->binary, disass->parts, disass->count,
@@ -229,6 +236,32 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta
+ do
+ {
+ GBinFormat *format; /* Format du fichier binaire */
+ GArchInstruction *iter; /* Boucle de parcours */
+
+
+
+ format = G_BIN_FORMAT(g_loaded_binary_get_format(disass->binary));
+
+ for (iter = *disass->instrs;
+ iter != NULL;
+ iter = g_arch_instruction_get_next_iter(*disass->instrs, iter, 0))
+ {
+
+ g_arch_instruction_call_hook(iter, IPH_LINK, proc, /*ctx*/NULL, format);
+
+
+
+ }
+
+
+
+ } while (0);
+
+
+
//gtk_extended_status_bar_remove(statusbar, id);
@@ -250,7 +283,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta
iter = g_arch_instruction_get_next_iter(*disass->instrs, iter, 0))
{
- g_arch_instruction_call_hook(iter, IPH_POST, /*ctx*/NULL, format);
+ g_arch_instruction_call_hook(iter, IPH_POST, proc, /*ctx*/NULL, format);
diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c
index 022ace3..06b6b03 100644
--- a/src/analysis/disass/links.c
+++ b/src/analysis/disass/links.c
@@ -33,10 +33,8 @@
/* Complète un désassemblage accompli pour une instruction. */
static void convert_immediate_into_target(GArchInstruction *, size_t, GBinFormat *);
-
-
-
-
+/* Rétablit un lien naturel coupé par un autre lien. */
+static void establish_natural_link(GArchInstruction *, GArchInstruction *);
@@ -118,10 +116,83 @@ static void establish_links_for_instruction(GArchInstruction *instr, GArchInstru
target = g_arch_instruction_find_by_address(list, &addr, true);
if (target != NULL)
- g_arch_instruction_link_with(instr, target, ILT_JUMP /* FIXME */);
+ g_arch_instruction_link_with(instr, target, ILT_REF);
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction désassemblée à traiter. *
+* prev = instruction précédente. *
+* *
+* Description : Rétablit un lien naturel coupé par un autre lien. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev)
+{
+ GArchInstruction **others; /* Instructions diverses liées */
+ InstructionLinkType *types; /* Types de lien existants */
+ size_t count; /* Nbre de sources affichées */
+ size_t i; /* Boucle de parcours */
+
+ /**
+ * Si rien ne vient séparer les deux instructions,
+ * on ne peut pas créer de lien plus naturel que l'existant.
+ */
+
+ if (!g_arch_instruction_has_sources(instr))
+ return;
+
+ /**
+ * Si on se trouve à une extrémité, on ne se lie pas
+ * avec le voisin.
+ */
+
+ if (g_arch_instruction_is_return(prev))
+ return;
+
+ if (g_arch_instruction_get_flags(instr) & AIF_ROUTINE_START)
+ return;
+
+ /**
+ * On s'assure que le lien naturel est valide.
+ */
+
+ count = g_arch_instruction_get_destinations(prev, &others, &types, NULL);
+
+ for (i = 0; i < count; i++)
+ {
+ if (types[i] == ILT_EXEC_FLOW) break;
+ if (types[i] == ILT_JUMP) break;
+ if (types[i] == ILT_CASE_JUMP) break;
+ if (types[i] == ILT_LOOP) break;
+ }
+
+ if (i < count) return;
+
+ /**
+ * On vérifie que le lien n'existe pas déjà avant d'en créer un...
+ */
+ count = g_arch_instruction_get_sources(instr, &others, &types);
+
+ for (i = 0; i < count; i++)
+ {
+ if (others[i] == prev && types[i] == ILT_JUMP_IF_TRUE) break;
+ if (others[i] == prev && types[i] == ILT_JUMP_IF_FALSE) break;
}
+ if (i == count)
+ g_arch_instruction_link_with(prev, instr, ILT_EXEC_FLOW);
+
}
@@ -142,13 +213,19 @@ static void establish_links_for_instruction(GArchInstruction *instr, GArchInstru
void establish_links_between_instructions(GArchInstruction *list, GBinFormat *format, GtkExtStatusBar *statusbar, bstatus_id_t id)
{
+ GArchInstruction *prev; /* Itération précédente */
GArchInstruction *iter; /* Boucle de parcours */
+ prev = NULL;
+
for (iter = list;
iter != NULL;
iter = g_arch_instruction_get_next_iter(list, iter, ~0/* FIXME */))
{
+ if (prev != NULL)
+ establish_natural_link(iter, prev);
+ prev = iter;
establish_links_for_instruction(iter, list, format);
diff --git a/src/analysis/disass/macro.c b/src/analysis/disass/macro.c
index 218371b..087f1ae 100644
--- a/src/analysis/disass/macro.c
+++ b/src/analysis/disass/macro.c
@@ -297,6 +297,9 @@ static bool code_coverage_stop_here(const code_coverage *coverage, const vmpa2t
{
void *ptr; /* Résultat des recherches */
+ if (!mrange_contains_addr(&coverage->range, addr))
+ return true;
+
ptr = bsearch(addr, coverage->ends, coverage->ends_count,
sizeof(vmpa2t), (__compar_fn_t)cmp_vmpa);
@@ -532,10 +535,21 @@ static void find_next_hops(GArchInstruction *instrs, const vmpa2t *start, const
InstructionLinkType *types; /* Type de lien entre lignes */
size_t dcount; /* Nombre de liens de dest. */
size_t i; /* Boucle de parcours #2 */
+ size_t not_handled; /* Nombre d'éléments écartés */
+
+ printf(" ---- FN [ %p ] ---------------------------\n", info);
+
+
+ printf("CONTAINS ? %d\n", mrange_contains_addr(&coverage->range, start));
/* Si la position est déjà présente, on évite de boucler... */
if (!add_hop_into_branch(info, start))
+ {
+ printf(" ++ !add 0x%08x\n", (unsigned int)start->virtual);
return;
+ }
+ else
+ printf(" ++ add 0x%08x\n", (unsigned int)start->virtual);
/* On suit le flot jusqu'à la prochaine bifurcation */
for (iter = g_arch_instruction_find_by_address(instrs, start, true);
@@ -544,20 +558,43 @@ static void find_next_hops(GArchInstruction *instrs, const vmpa2t *start, const
{
range = g_arch_instruction_get_range(iter);
+
+ if (code_coverage_stop_here(coverage, get_mrange_addr(range)))
+ printf(" ++ stop here 0x%08x\n", (unsigned int)range->addr.virtual);
+
if (code_coverage_stop_here(coverage, get_mrange_addr(range)))
break;
+
+ if (g_arch_instruction_has_sources(iter))
+ add_hop_into_branch(info, get_mrange_addr(range));
+
+
+
+ if (g_arch_instruction_is_return(iter))
+ printf(" ++ return 0x%08x\n", (unsigned int)range->addr.virtual);
+
if (g_arch_instruction_is_return(iter))
{
iter = NULL;
break;
}
+ /*
+ if (!g_arch_instruction_has_destinations(iter))
+ printf(" ++ no dest 0x%08x\n", (unsigned int)range->addr.virtual);
+ */
+
if (!g_arch_instruction_has_destinations(iter))
continue;
+
+ printf(" ++ dcount 0x%08x\n", (unsigned int)range->addr.virtual);
+
dcount = g_arch_instruction_get_destinations(iter, &dests, &types, NULL);
+ not_handled = 0;
+
for (i = 0; i < dcount; i++)
{
range = g_arch_instruction_get_range(dests[i]);
@@ -577,19 +614,23 @@ static void find_next_hops(GArchInstruction *instrs, const vmpa2t *start, const
break;
default:
+ not_handled++;
break;
}
}
- break;
+ if (not_handled < dcount)
+ break;
}
/* Si on termine... */
if (iter != NULL) add_hop_into_branch(info, get_mrange_addr(range));
+ printf(" ------- [ %p ] ---\n", info);
+
}
@@ -614,6 +655,20 @@ static bool compute_first_common_addr(const branch_info *a, const branch_info *b
result = false;
+
+ printf("....................\n");
+
+ printf(" A :: ");
+ for (i = 0; i < a->count; i++)
+ printf("0x%08x ", a->hops[i].virtual);
+ printf("\n");
+
+ printf(" B :: ");
+ for (i = 0; i < b->count; i++)
+ printf("0x%08x ", b->hops[i].virtual);
+ printf("\n");
+
+
for (i = 0; i < a->count && !result; i++)
if (is_addr_in_branch(b, &a->hops[i]))
{
@@ -621,6 +676,13 @@ static bool compute_first_common_addr(const branch_info *a, const branch_info *b
copy_vmpa(c, &a->hops[i]);
}
+ if (result)
+ printf(" N :: 0x%08x\n", (unsigned int)c->virtual);
+ else
+ printf(" N :: ----\n");
+
+ printf("....................\n");
+
return result;
}
@@ -862,6 +924,7 @@ static GInstrBlock *build_instruction_blocks_ite(GArchInstruction *instrs, code_
GInstrBlock *block; /* Nouveau bloc mis en place */
has_common = compute_first_common_addr(true_branch, false_branch, next);
+ if (!has_common) printf(" === nothing in common\n");
if (!has_common) return NULL;
result = g_virtual_block_new();
@@ -980,7 +1043,7 @@ static void add_instruction_blocks_except(GInstrBlock **result, GInstrBlock **ca
* Remarques : - *
* *
******************************************************************************/
-
+#include "../../arch/instruction-int.h"
static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_coverage *coverage)
{
GInstrBlock *result; /* Regroupement à retourner */
@@ -1059,11 +1122,25 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove
case ILT_EXEC_FLOW:
case ILT_JUMP:
+
+ //break;
+ {
+ GArchInstruction *_saved0;
+
+ _saved0 = first;
+
block = build_instruction_block_simple(instrs, coverage, &first, iter);
+ printf(" -- simple block JMP -- @ 0x%08x <-> 0x%08x\n",
+ (unsigned int)(_saved0 ? _saved0->range.addr.virtual : ~0),
+ (unsigned int)iter->range.addr.virtual);
+ fflush(NULL);
+ }
DELAYED_BLOCK_ADDING(result, result_cached, block);
range = g_arch_instruction_get_range(iter);
- copy_vmpa(&next_addr, get_mrange_addr(range));
+ compute_mrange_end_addr(range, &next_addr);
+
+ first = NULL;
break;
@@ -1072,10 +1149,12 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove
break;
case ILT_JUMP_IF_TRUE:
+ printf("FIND TRUE BRANCH @ 0x%08x\n", (unsigned int)iter->range.addr.virtual);
branch = &true_branch;
break;
case ILT_JUMP_IF_FALSE:
+ printf("FIND FALSE BRANCH @ 0x%08x\n", (unsigned int)iter->range.addr.virtual);
branch = &false_branch;
break;
@@ -1097,10 +1176,13 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove
/* Si on a une branche à compléter... */
if (branch != NULL)
{
- range = g_arch_instruction_get_range(iter);
+ range = g_arch_instruction_get_range(dests[i]);
addr = get_mrange_addr(range);
+ printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
+ printf("BUILD @ 0x%08x\n", (unsigned int)addr->virtual);
find_next_hops(instrs, addr, coverage, branch);
+ printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n");
}
@@ -1126,10 +1208,25 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove
else if (true_branch.count > 0 || false_branch.count > 0)
{
block = build_instruction_block_simple(instrs, coverage, &first, iter);
+
+ GArchInstruction *_saved1;
+
+ _saved1 = first;
+
+
+
+ printf(" -- branches -- %d vs %d\n", (int)true_branch.count, (int)false_branch.count);
+
+ printf(" -- simple block ITE -- @ 0x%08x <-> 0x%08x\n",
+ (unsigned int)(_saved1 ? _saved1->range.addr.virtual : ~0),
+ (unsigned int)iter->range.addr.virtual);
+ fflush(NULL);
DELAYED_BLOCK_ADDING(result, result_cached, block);
group = build_instruction_blocks_ite(instrs, coverage, &true_branch, &false_branch, &next_addr);
+ printf(" --> group = %p - next = 0x%08x\n", group, next_addr.virtual);
+
if (group != NULL)
{
DELAYED_BLOCK_ADDING(result, result_cached, group);