summaryrefslogtreecommitdiff
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
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
-rw-r--r--ChangeLog63
-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
-rw-r--r--src/arch/Makefile.am1
-rw-r--r--src/arch/arm/v7/Makefile.am2
-rw-r--r--src/arch/arm/v7/fetch.c (renamed from src/arch/arm/v7/link.c)22
-rw-r--r--src/arch/arm/v7/fetch.h113
-rw-r--r--src/arch/arm/v7/link.h113
-rw-r--r--src/arch/arm/v7/opdefs/Makefile.am2
-rw-r--r--src/arch/arm/v7/opdefs/b_A8818.d25
-rw-r--r--src/arch/arm/v7/opdefs/bl_A8825.d8
-rw-r--r--src/arch/arm/v7/opdefs/bx_A8827.d4
-rw-r--r--src/arch/arm/v7/opdefs/cbnz_A8829.d4
-rw-r--r--src/arch/arm/v7/opdefs/ldr_A8864.d6
-rw-r--r--src/arch/arm/v7/opdefs/pop_A88131.d3
-rw-r--r--src/arch/arm/v7/opdefs/pop_A88132.d2
-rw-r--r--src/arch/arm/v7/post.c12
-rw-r--r--src/arch/arm/v7/post.h8
-rw-r--r--src/arch/instruction.c8
-rw-r--r--src/arch/instruction.h16
-rw-r--r--src/arch/link.c190
-rw-r--r--src/arch/link.h45
-rw-r--r--src/arch/processor-int.h7
-rw-r--r--src/arch/processor.c147
-rw-r--r--src/arch/processor.h16
27 files changed, 878 insertions, 170 deletions
diff --git a/ChangeLog b/ChangeLog
index ffec386..0d4288c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,66 @@
+15-04-01 Cyrille Bagard <nocbos@gmail.com>
+
+ * src/analysis/disass/area.c:
+ Update code by changing IPH_LINK to IPH_FETCH.
+
+ * src/analysis/disass/disassembler.c:
+ Register all disassembled instructions and run the new IPH_LINK methods.
+
+ * src/analysis/disass/links.c:
+ Establish natural links in the execution flow.
+
+ * src/analysis/disass/macro.c:
+ Save some progress in the definition of basic blocks.
+
+ * src/arch/arm/v7/fetch.c:
+ * src/arch/arm/v7/fetch.h:
+ New entries: redefine the old IPH_LINK methods into IPH_FETCH new ones.
+
+ * src/arch/arm/v7/link.c:
+ * src/arch/arm/v7/link.h:
+ Moved entries: see the 'fetch.[ch]' files.
+
+ * src/arch/arm/v7/Makefile.am:
+ Replace the 'link.[ch]' files by the 'fetch.[ch]' ones
+ in libarcharmv7_la_SOURCES.
+
+ * src/arch/arm/v7/opdefs/b_A8818.d:
+ * src/arch/arm/v7/opdefs/bl_A8825.d:
+ * src/arch/arm/v7/opdefs/bx_A8827.d:
+ * src/arch/arm/v7/opdefs/cbnz_A8829.d:
+ * src/arch/arm/v7/opdefs/ldr_A8864.d:
+ Update definitions.
+
+ * src/arch/arm/v7/opdefs/Makefile.am:
+ Update included headers list.
+
+ * src/arch/arm/v7/opdefs/pop_A88131.d:
+ * src/arch/arm/v7/opdefs/pop_A88132.d:
+ Update definitions.
+
+ * src/arch/arm/v7/post.c:
+ * src/arch/arm/v7/post.h:
+ Update prototypes.
+
+ * src/arch/instruction.c:
+ Update code.
+
+ * src/arch/instruction.h:
+ Update code. Redefine prototypes for hooks. Register a link type dedicated
+ to cross refrences.
+
+ * src/arch/link.c:
+ * src/arch/link.h:
+ New entries: provide generic methods for some kinks of links.
+
+ * src/arch/Makefile.am:
+ Add the 'link.[ch]' files to libarch_la_SOURCES.
+
+ * src/arch/processor.c:
+ * src/arch/processor.h:
+ * src/arch/processor-int.h:
+ Begin to store all disassembled instructions in the processor structure.
+
15-03-29 Cyrille Bagard <nocbos@gmail.com>
* plugins/readelf/header.c:
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);
diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am
index 33747fb..aab7ec8 100644
--- a/src/arch/Makefile.am
+++ b/src/arch/Makefile.am
@@ -9,6 +9,7 @@ libarch_la_SOURCES = \
immediate.h immediate.c \
instruction-int.h \
instruction.h instruction.c \
+ link.h link.c \
operand-int.h \
operand.h operand.c \
processor-int.h \
diff --git a/src/arch/arm/v7/Makefile.am b/src/arch/arm/v7/Makefile.am
index 22e93d4..f9b35b6 100644
--- a/src/arch/arm/v7/Makefile.am
+++ b/src/arch/arm/v7/Makefile.am
@@ -4,9 +4,9 @@ noinst_LTLIBRARIES = libarcharmv7.la
libarcharmv7_la_SOURCES = \
arm.h arm.c \
context.h context.c \
+ fetch.h fetch.c \
helpers.h helpers.c \
instruction.h instruction.c \
- link.h link.c \
post.h post.c \
processor.h processor.c \
pseudo.h pseudo.c \
diff --git a/src/arch/arm/v7/link.c b/src/arch/arm/v7/fetch.c
index 308d4e5..18d61f0 100644
--- a/src/arch/arm/v7/link.c
+++ b/src/arch/arm/v7/fetch.c
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * post.c - traitements complémentaires à la phase de désassemblage
+ * fetch.c - traitements complémentaires à la phase de désassemblage
*
* Copyright (C) 2014 Cyrille Bagard
*
@@ -21,7 +21,7 @@
*/
-#include "link.h"
+#include "fetch.h"
#include <assert.h>
@@ -40,6 +40,7 @@
/******************************************************************************
* *
* Paramètres : instr = instruction ARMv7 à traiter. *
+* proc = représentation de l'architecture utilisée. *
* context = contexte associé à la phase de désassemblage. *
* format = acès aux données du binaire d'origine. *
* iset = type de jeu d'instructions courant à faire suivre. *
@@ -52,7 +53,7 @@
* *
******************************************************************************/
-void handle_links_with_instruction_b_with_orig(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
+void help_fetching_with_instruction_b_with_orig(GArchInstruction *instr, GArchProcessor *proc, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
{
const mrange_t *range; /* Emplacementt d'instruction */
virt_t pc; /* Position dans l'exécution */
@@ -106,6 +107,7 @@ void handle_links_with_instruction_b_with_orig(GArchInstruction *instr, GArmV7Co
/******************************************************************************
* *
* Paramètres : instr = instruction ARMv7 à traiter. *
+* proc = représentation de l'architecture utilisée. *
* context = contexte associé à la phase de désassemblage. *
* format = acès aux données du binaire d'origine. *
* iset = type de jeu d'instructions courant à faire suivre. *
@@ -118,7 +120,7 @@ void handle_links_with_instruction_b_with_orig(GArchInstruction *instr, GArmV7Co
* *
******************************************************************************/
-void handle_links_with_instruction_bl_with_orig(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
+void help_fetching_with_instruction_bl_with_orig(GArchInstruction *instr, GArchProcessor *proc, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
{
const mrange_t *range; /* Emplacementt d'instruction */
virt_t pc; /* Position dans l'exécution */
@@ -163,6 +165,7 @@ void handle_links_with_instruction_bl_with_orig(GArchInstruction *instr, GArmV7C
/******************************************************************************
* *
* Paramètres : instr = instruction ARMv7 à traiter. *
+* proc = représentation de l'architecture utilisée. *
* context = contexte associé à la phase de désassemblage. *
* format = acès aux données du binaire d'origine. *
* iset = type de jeu d'instructions courant à inverser. *
@@ -175,7 +178,7 @@ void handle_links_with_instruction_bl_with_orig(GArchInstruction *instr, GArmV7C
* *
******************************************************************************/
-void handle_links_with_instruction_blx_with_dest(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
+void help_fetching_with_instruction_blx_with_dest(GArchInstruction *instr, GArchProcessor *proc, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
{
const mrange_t *range; /* Emplacementt d'instruction */
virt_t pc; /* Position dans l'exécution */
@@ -221,6 +224,7 @@ void handle_links_with_instruction_blx_with_dest(GArchInstruction *instr, GArmV7
/******************************************************************************
* *
* Paramètres : instr = instruction ARMv7 à traiter. *
+* proc = représentation de l'architecture utilisée. *
* context = contexte associé à la phase de désassemblage. *
* format = acès aux données du binaire d'origine. *
* iset = type de jeu d'instructions courant à faire suivre. *
@@ -233,7 +237,7 @@ void handle_links_with_instruction_blx_with_dest(GArchInstruction *instr, GArmV7
* *
******************************************************************************/
-void handle_links_with_instruction_bx_with_orig(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
+void help_fetching_with_instruction_bx_with_orig(GArchInstruction *instr, GArchProcessor *proc, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
{
GArchOperand *op; /* Opérande numérique en place */
GArmRegister *reg; /* Registre matériel manipulé */
@@ -283,6 +287,7 @@ void handle_links_with_instruction_bx_with_orig(GArchInstruction *instr, GArmV7C
/******************************************************************************
* *
* Paramètres : instr = instruction ARMv7 à traiter. *
+* proc = représentation de l'architecture utilisée. *
* context = contexte associé à la phase de désassemblage. *
* format = acès aux données du binaire d'origine. *
* *
@@ -294,7 +299,7 @@ void handle_links_with_instruction_bx_with_orig(GArchInstruction *instr, GArmV7C
* *
******************************************************************************/
-void handle_links_with_instruction_cb_n_z(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format)
+void help_fetching_with_instruction_cb_n_z(GArchInstruction *instr, GArchProcessor *proc, GArmV7Context *context, GBinFormat *format)
{
const mrange_t *range; /* Emplacementt d'instruction */
virt_t pc; /* Position dans l'exécution */
@@ -334,6 +339,7 @@ void handle_links_with_instruction_cb_n_z(GArchInstruction *instr, GArmV7Context
/******************************************************************************
* *
* Paramètres : instr = instruction ARMv7 à traiter. *
+* proc = représentation de l'architecture utilisée. *
* context = contexte associé à la phase de désassemblage. *
* format = acès aux données du binaire d'origine. *
* iset = type de jeu d'instructions courant à inverser. *
@@ -346,7 +352,7 @@ void handle_links_with_instruction_cb_n_z(GArchInstruction *instr, GArmV7Context
* *
******************************************************************************/
-void handle_links_with_instruction_ldr_literal_with_orig(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
+void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *instr, GArchProcessor *proc, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
{
const mrange_t *range; /* Emplacementt d'instruction */
phys_t phys_pc; /* Position dans l'exécution */
diff --git a/src/arch/arm/v7/fetch.h b/src/arch/arm/v7/fetch.h
new file mode 100644
index 0000000..af42f2e
--- /dev/null
+++ b/src/arch/arm/v7/fetch.h
@@ -0,0 +1,113 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * fetch.h - prototypes pour l'édition des liens durant la phase de désassemblage
+ *
+ * Copyright (C) 2014 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * OpenIDA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * OpenIDA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ARCH_ARM_V7_FETCH_H
+#define _ARCH_ARM_V7_FETCH_H
+
+
+#include "context.h"
+#include "../../instruction.h"
+#include "../../../format/format.h"
+
+
+
+/* Complète un désassemblage accompli pour une instruction. */
+void help_fetching_with_instruction_b_with_orig(GArchInstruction *, GArchProcessor *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
+
+
+static inline void help_fetching_with_instruction_b_from_arm(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt)
+{
+ help_fetching_with_instruction_b_with_orig(ins, proc, ctx, fmt, AV7IS_ARM);
+}
+
+static inline void help_fetching_with_instruction_b_from_thumb(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt)
+{
+ help_fetching_with_instruction_b_with_orig(ins, proc, ctx, fmt, AV7IS_THUMB);
+}
+
+
+/* Complète un désassemblage accompli pour une instruction. */
+void help_fetching_with_instruction_bl_with_orig(GArchInstruction *, GArchProcessor *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
+
+
+static inline void help_fetching_with_instruction_bl_from_arm(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt)
+{
+ help_fetching_with_instruction_bl_with_orig(ins, proc, ctx, fmt, AV7IS_ARM);
+}
+
+static inline void help_fetching_with_instruction_bl_from_thumb(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt)
+{
+ help_fetching_with_instruction_bl_with_orig(ins, proc, ctx, fmt, AV7IS_THUMB);
+}
+
+
+/* Complète un désassemblage accompli pour une instruction. */
+void help_fetching_with_instruction_blx_with_dest(GArchInstruction *, GArchProcessor *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
+
+
+static inline void help_fetching_with_instruction_blx_from_arm(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt)
+{
+ help_fetching_with_instruction_blx_with_dest(ins, proc, ctx, fmt, AV7IS_THUMB);
+}
+
+static inline void help_fetching_with_instruction_blx_from_thumb(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt)
+{
+ help_fetching_with_instruction_blx_with_dest(ins, proc, ctx, fmt, AV7IS_ARM);
+}
+
+
+/* Complète un désassemblage accompli pour une instruction. */
+void help_fetching_with_instruction_bx_with_orig(GArchInstruction *, GArchProcessor *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
+
+
+static inline void help_fetching_with_instruction_bx_from_arm(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt)
+{
+ help_fetching_with_instruction_bx_with_orig(ins, proc, ctx, fmt, AV7IS_ARM);
+}
+
+static inline void help_fetching_with_instruction_bx_from_thumb(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt)
+{
+ help_fetching_with_instruction_bx_with_orig(ins, proc, ctx, fmt, AV7IS_THUMB);
+}
+
+
+/* Complète un désassemblage accompli pour une instruction. */
+void help_fetching_with_instruction_cb_n_z(GArchInstruction *, GArchProcessor *, GArmV7Context *, GBinFormat *);
+
+/* Complète un désassemblage accompli pour une instruction. */
+void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *, GArchProcessor *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
+
+
+static inline void help_fetching_with_instruction_ldr_literal_from_arm(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt)
+{
+ help_fetching_with_instruction_ldr_literal_with_orig(ins, proc, ctx, fmt, AV7IS_ARM);
+}
+
+static inline void help_fetching_with_instruction_ldr_literal_from_thumb(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt)
+{
+ help_fetching_with_instruction_ldr_literal_with_orig(ins, proc, ctx, fmt, AV7IS_THUMB);
+}
+
+
+
+#endif /* _ARCH_ARM_V7_FETCH_H */
diff --git a/src/arch/arm/v7/link.h b/src/arch/arm/v7/link.h
deleted file mode 100644
index 9e52fe6..0000000
--- a/src/arch/arm/v7/link.h
+++ /dev/null
@@ -1,113 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * link.h - prototypes pour l'édition des liens durant la phase de désassemblage
- *
- * Copyright (C) 2014 Cyrille Bagard
- *
- * This file is part of Chrysalide.
- *
- * OpenIDA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * OpenIDA is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _ARCH_ARM_V7_LINK_H
-#define _ARCH_ARM_V7_LINK_H
-
-
-#include "context.h"
-#include "../../instruction.h"
-#include "../../../format/format.h"
-
-
-
-/* Complète un désassemblage accompli pour une instruction. */
-void handle_links_with_instruction_b_with_orig(GArchInstruction *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
-
-
-static inline void handle_links_with_instruction_b_from_arm(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
-{
- handle_links_with_instruction_b_with_orig(ins, ctx, fmt, AV7IS_ARM);
-}
-
-static inline void handle_links_with_instruction_b_from_thumb(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
-{
- handle_links_with_instruction_b_with_orig(ins, ctx, fmt, AV7IS_THUMB);
-}
-
-
-/* Complète un désassemblage accompli pour une instruction. */
-void handle_links_with_instruction_bl_with_orig(GArchInstruction *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
-
-
-static inline void handle_links_with_instruction_bl_from_arm(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
-{
- handle_links_with_instruction_bl_with_orig(ins, ctx, fmt, AV7IS_ARM);
-}
-
-static inline void handle_links_with_instruction_bl_from_thumb(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
-{
- handle_links_with_instruction_bl_with_orig(ins, ctx, fmt, AV7IS_THUMB);
-}
-
-
-/* Complète un désassemblage accompli pour une instruction. */
-void handle_links_with_instruction_blx_with_dest(GArchInstruction *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
-
-
-static inline void handle_links_with_instruction_blx_from_arm(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
-{
- handle_links_with_instruction_blx_with_dest(ins, ctx, fmt, AV7IS_THUMB);
-}
-
-static inline void handle_links_with_instruction_blx_from_thumb(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
-{
- handle_links_with_instruction_blx_with_dest(ins, ctx, fmt, AV7IS_ARM);
-}
-
-
-/* Complète un désassemblage accompli pour une instruction. */
-void handle_links_with_instruction_bx_with_orig(GArchInstruction *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
-
-
-static inline void handle_links_with_instruction_bx_from_arm(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
-{
- handle_links_with_instruction_bx_with_orig(ins, ctx, fmt, AV7IS_ARM);
-}
-
-static inline void handle_links_with_instruction_bx_from_thumb(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
-{
- handle_links_with_instruction_bx_with_orig(ins, ctx, fmt, AV7IS_THUMB);
-}
-
-
-/* Complète un désassemblage accompli pour une instruction. */
-void handle_links_with_instruction_cb_n_z(GArchInstruction *, GArmV7Context *, GBinFormat *);
-
-/* Complète un désassemblage accompli pour une instruction. */
-void handle_links_with_instruction_ldr_literal_with_orig(GArchInstruction *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
-
-
-static inline void handle_links_with_instruction_ldr_literal_from_arm(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
-{
- handle_links_with_instruction_ldr_literal_with_orig(ins, ctx, fmt, AV7IS_ARM);
-}
-
-static inline void handle_links_with_instruction_ldr_literal_from_thumb(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
-{
- handle_links_with_instruction_ldr_literal_with_orig(ins, ctx, fmt, AV7IS_THUMB);
-}
-
-
-
-#endif /* _ARCH_ARM_V7_LINK_H */
diff --git a/src/arch/arm/v7/opdefs/Makefile.am b/src/arch/arm/v7/opdefs/Makefile.am
index 318e20b..b95b588 100644
--- a/src/arch/arm/v7/opdefs/Makefile.am
+++ b/src/arch/arm/v7/opdefs/Makefile.am
@@ -106,7 +106,7 @@ fmk.done: $(ARMV7_DEFS)
fix_includes_in_c_templates:
@for f in `find .gen/ -name '*tmpl.c'`; do \
if grep -q '##INCLUDES##' $$f; then \
- $(fix_verbose)sed -i 's/##INCLUDES##/\n#include "..\/helpers.h"\n#include "..\/instruction.h"\n#include "..\/link.h"\n#include "..\/post.h"\n#include "..\/..\/instruction.h"\n#include "..\/..\/..\/..\/common\/bconst.h"\n\n/' $$f; \
+ $(fix_verbose)sed -i 's/##INCLUDES##/\n#include "..\/helpers.h"\n#include "..\/instruction.h"\n#include "..\/fetch.h"\n#include "..\/post.h"\n#include "..\/..\/instruction.h"\n#include "..\/..\/..\/link.h"\n#include "..\/..\/..\/..\/common\/bconst.h"\n\n/' $$f; \
fi; \
done
diff --git a/src/arch/arm/v7/opdefs/b_A8818.d b/src/arch/arm/v7/opdefs/b_A8818.d
index 50bdda9..a275177 100644
--- a/src/arch/arm/v7/opdefs/b_A8818.d
+++ b/src/arch/arm/v7/opdefs/b_A8818.d
@@ -38,7 +38,8 @@
@hooks {
- link = handle_links_with_instruction_b_from_thumb
+ fetch = help_fetching_with_instruction_b_from_thumb
+ link = handle_branch_if_true_as_link
post = post_process_branch_instructions
}
@@ -47,7 +48,7 @@
//if cond == '1110' then UNDEFINED;
//if cond == '1111' then SEE SVC;
- chk_call DefineAsReturn(1)
+ //chk_call DefineAsReturn(1)
}
@@ -67,7 +68,8 @@
@hooks {
- link = handle_links_with_instruction_b_from_thumb
+ fetch = help_fetching_with_instruction_b_from_thumb
+ link = handle_branch_if_true_as_link
post = post_process_branch_instructions
}
@@ -75,7 +77,7 @@
@rules {
//if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
- chk_call DefineAsReturn(1)
+ //chk_call DefineAsReturn(1)
}
@@ -96,7 +98,8 @@
@hooks {
- link = handle_links_with_instruction_b_from_thumb
+ fetch = help_fetching_with_instruction_b_from_thumb
+ link = handle_branch_if_true_as_link
post = post_process_branch_instructions
}
@@ -105,7 +108,7 @@
//if cond<3:1> == '111' then SEE "Related encodings";
//if InITBlock() then UNPREDICTABLE;
- chk_call DefineAsReturn(1)
+ //chk_call DefineAsReturn(1)
}
@@ -127,7 +130,8 @@
@hooks {
- link = handle_links_with_instruction_b_from_thumb
+ fetch = help_fetching_with_instruction_b_from_thumb
+ link = handle_branch_if_true_as_link
post = post_process_branch_instructions
}
@@ -135,7 +139,7 @@
@rules {
//if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
- chk_call DefineAsReturn(1)
+ //chk_call DefineAsReturn(1)
}
@@ -156,14 +160,15 @@
@hooks {
- link = handle_links_with_instruction_b_from_arm
+ fetch = help_fetching_with_instruction_b_from_arm
+ link = handle_branch_if_true_as_link
post = post_process_branch_instructions
}
@rules {
- chk_call DefineAsReturn(1)
+ //chk_call DefineAsReturn(1)
}
diff --git a/src/arch/arm/v7/opdefs/bl_A8825.d b/src/arch/arm/v7/opdefs/bl_A8825.d
index 63922dd..62ac8f9 100644
--- a/src/arch/arm/v7/opdefs/bl_A8825.d
+++ b/src/arch/arm/v7/opdefs/bl_A8825.d
@@ -39,7 +39,7 @@
@hooks {
- link = handle_links_with_instruction_bl_from_thumb
+ fetch = help_fetching_with_instruction_bl_from_thumb
post = post_process_branch_and_link_instructions
}
@@ -68,7 +68,7 @@
@hooks {
- link = handle_links_with_instruction_blx_from_thumb
+ fetch = help_fetching_with_instruction_blx_from_thumb
post = post_process_branch_and_link_instructions
}
@@ -95,7 +95,7 @@
@hooks {
- link = handle_links_with_instruction_bl_from_arm
+ fetch = help_fetching_with_instruction_bl_from_arm
post = post_process_branch_and_link_instructions
}
@@ -122,7 +122,7 @@
@hooks {
- link = handle_links_with_instruction_blx_from_arm
+ fetch = help_fetching_with_instruction_blx_from_arm
post = post_process_branch_and_link_instructions
}
diff --git a/src/arch/arm/v7/opdefs/bx_A8827.d b/src/arch/arm/v7/opdefs/bx_A8827.d
index 4856885..f8027a4 100644
--- a/src/arch/arm/v7/opdefs/bx_A8827.d
+++ b/src/arch/arm/v7/opdefs/bx_A8827.d
@@ -38,7 +38,7 @@
@hooks {
- link = handle_links_with_instruction_bx_from_thumb
+ fetch = help_fetching_with_instruction_bx_from_thumb
}
@@ -65,7 +65,7 @@
@hooks {
- link = handle_links_with_instruction_bx_from_thumb
+ fetch = help_fetching_with_instruction_bx_from_thumb
}
diff --git a/src/arch/arm/v7/opdefs/cbnz_A8829.d b/src/arch/arm/v7/opdefs/cbnz_A8829.d
index 93a8d1f..d9815c1 100644
--- a/src/arch/arm/v7/opdefs/cbnz_A8829.d
+++ b/src/arch/arm/v7/opdefs/cbnz_A8829.d
@@ -38,7 +38,7 @@
@hooks {
- link = handle_links_with_instruction_cb_n_z
+ fetch = help_fetching_with_instruction_cb_n_z
post = post_process_comp_and_branch_instructions
}
@@ -60,7 +60,7 @@
@hooks {
- link = handle_links_with_instruction_cb_n_z
+ fetch = help_fetching_with_instruction_cb_n_z
post = post_process_comp_and_branch_instructions
}
diff --git a/src/arch/arm/v7/opdefs/ldr_A8864.d b/src/arch/arm/v7/opdefs/ldr_A8864.d
index c5b0dd0..4cf0048 100644
--- a/src/arch/arm/v7/opdefs/ldr_A8864.d
+++ b/src/arch/arm/v7/opdefs/ldr_A8864.d
@@ -39,7 +39,7 @@
@hooks {
- link = handle_links_with_instruction_ldr_literal_from_thumb
+ fetch = help_fetching_with_instruction_ldr_literal_from_thumb
post = post_process_ldr_instructions
}
@@ -62,7 +62,7 @@
@hooks {
- link = handle_links_with_instruction_ldr_literal_from_thumb
+ fetch = help_fetching_with_instruction_ldr_literal_from_thumb
post = post_process_ldr_instructions
}
@@ -93,7 +93,7 @@
@hooks {
- link = handle_links_with_instruction_ldr_literal_from_arm
+ fetch = help_fetching_with_instruction_ldr_literal_from_arm
post = post_process_ldr_instructions
}
diff --git a/src/arch/arm/v7/opdefs/pop_A88131.d b/src/arch/arm/v7/opdefs/pop_A88131.d
index 2663e1b..ef5ab25 100644
--- a/src/arch/arm/v7/opdefs/pop_A88131.d
+++ b/src/arch/arm/v7/opdefs/pop_A88131.d
@@ -39,6 +39,7 @@
//if BitCount(registers) < 1 then UNPREDICTABLE;
//if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
+ chk_call DefineAsReturn(1)
}
@@ -60,6 +61,7 @@
//if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
//if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
+ chk_call DefineAsReturn(1)
}
@@ -81,6 +83,7 @@
@rules {
//if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
+ chk_call DefineAsReturn(1)
}
diff --git a/src/arch/arm/v7/opdefs/pop_A88132.d b/src/arch/arm/v7/opdefs/pop_A88132.d
index 0c6c1b0..89c51c9 100644
--- a/src/arch/arm/v7/opdefs/pop_A88132.d
+++ b/src/arch/arm/v7/opdefs/pop_A88132.d
@@ -40,6 +40,7 @@
//if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
//if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
+ chk_call DefineAsReturn(1)
}
@@ -62,6 +63,7 @@
@rules {
//if t == 13 then UNPREDICTABLE;
+ chk_call DefineAsReturn(1)
}
diff --git a/src/arch/arm/v7/post.c b/src/arch/arm/v7/post.c
index e6a6c2e..23d0198 100644
--- a/src/arch/arm/v7/post.c
+++ b/src/arch/arm/v7/post.c
@@ -34,6 +34,7 @@
/******************************************************************************
* *
* Paramètres : instr = instruction ARMv7 à traiter. *
+* proc = représentation de l'architecture utilisée. *
* context = contexte associé à la phase de désassemblage. *
* format = accès aux données du binaire d'origine. *
* *
@@ -45,7 +46,7 @@
* *
******************************************************************************/
-void post_process_branch_instructions(GArchInstruction *instr, GProcContext *context, GBinFormat *format)
+void post_process_branch_instructions(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format)
{
GArchOperand *op; /* Opérande numérique en place */
uint32_t addr; /* Adresse visée par le saut */
@@ -97,6 +98,7 @@ void post_process_branch_instructions(GArchInstruction *instr, GProcContext *con
/******************************************************************************
* *
* Paramètres : instr = instruction ARMv7 à traiter. *
+* proc = représentation de l'architecture utilisée. *
* context = contexte associé à la phase de désassemblage. *
* format = accès aux données du binaire d'origine. *
* *
@@ -108,7 +110,7 @@ void post_process_branch_instructions(GArchInstruction *instr, GProcContext *con
* *
******************************************************************************/
-void post_process_branch_and_link_instructions(GArchInstruction *instr, GProcContext *context, GBinFormat *format)
+void post_process_branch_and_link_instructions(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format)
{
GArchOperand *op; /* Opérande numérique en place */
uint32_t addr; /* Adresse visée par le saut */
@@ -160,6 +162,7 @@ void post_process_branch_and_link_instructions(GArchInstruction *instr, GProcCon
/******************************************************************************
* *
* Paramètres : instr = instruction ARMv7 à traiter. *
+* proc = représentation de l'architecture utilisée. *
* context = contexte associé à la phase de désassemblage. *
* format = accès aux données du binaire d'origine. *
* *
@@ -171,7 +174,7 @@ void post_process_branch_and_link_instructions(GArchInstruction *instr, GProcCon
* *
******************************************************************************/
-void post_process_comp_and_branch_instructions(GArchInstruction *instr, GProcContext *context, GBinFormat *format)
+void post_process_comp_and_branch_instructions(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format)
{
GArchOperand *op; /* Opérande numérique en place */
uint32_t addr; /* Adresse visée par le saut */
@@ -223,6 +226,7 @@ void post_process_comp_and_branch_instructions(GArchInstruction *instr, GProcCon
/******************************************************************************
* *
* Paramètres : instr = instruction ARMv7 à traiter. *
+* proc = représentation de l'architecture utilisée. *
* context = contexte associé à la phase de désassemblage. *
* format = accès aux données du binaire d'origine. *
* *
@@ -234,7 +238,7 @@ void post_process_comp_and_branch_instructions(GArchInstruction *instr, GProcCon
* *
******************************************************************************/
-void post_process_ldr_instructions(GArchInstruction *instr, GProcContext *context, GBinFormat *format)
+void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format)
{
GArchOperand *op; /* Opérande numérique en place */
uint32_t addr; /* Adresse visée par le saut */
diff --git a/src/arch/arm/v7/post.h b/src/arch/arm/v7/post.h
index 79dcaa8..6165597 100644
--- a/src/arch/arm/v7/post.h
+++ b/src/arch/arm/v7/post.h
@@ -31,16 +31,16 @@
/* Complète un désassemblage accompli pour une instruction. */
-void post_process_branch_instructions(GArchInstruction *, GProcContext *, GBinFormat *);
+void post_process_branch_instructions(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *);
/* Complète un désassemblage accompli pour une instruction. */
-void post_process_branch_and_link_instructions(GArchInstruction *, GProcContext *, GBinFormat *);
+void post_process_branch_and_link_instructions(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *);
/* Complète un désassemblage accompli pour une instruction. */
-void post_process_comp_and_branch_instructions(GArchInstruction *, GProcContext *, GBinFormat *);
+void post_process_comp_and_branch_instructions(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *);
/* Complète un désassemblage accompli pour une instruction. */
-void post_process_ldr_instructions(GArchInstruction *, GProcContext *, GBinFormat *);
+void post_process_ldr_instructions(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *);
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index 0bcc739..08256d1 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -234,6 +234,7 @@ void g_arch_instruction_set_hook(GArchInstruction *instr, InstrProcessHook type,
* *
* Paramètres : instr = instruction quelconque à traiter. *
* type = type de procédure à utiliser. *
+* proc = représentation de l'architecture utilisée. *
* context = contexte associé à la phase de désassemblage. *
* format = accès aux données du binaire d'origine. *
* *
@@ -245,12 +246,15 @@ void g_arch_instruction_set_hook(GArchInstruction *instr, InstrProcessHook type,
* *
******************************************************************************/
-void g_arch_instruction_call_hook(GArchInstruction *instr, InstrProcessHook type, GProcContext *context, GBinFormat *format)
+void g_arch_instruction_call_hook(GArchInstruction *instr, InstrProcessHook type, GArchProcessor *proc, GProcContext *context, GBinFormat *format)
{
+ if (instr->range.addr.virtual == 0x83c2)
+ printf(" [%u] HAS BRANCH ? %p\n", (unsigned int)type, instr->hooks[type]);
+
assert(type < IPH_COUNT);
if (instr->hooks[type] != NULL)
- instr->hooks[type](instr, context, format);
+ instr->hooks[type](instr, proc, context, format);
}
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index 9251a34..0198bb5 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -76,22 +76,29 @@ void g_arch_instruction_set_flag(GArchInstruction *, ArchInstrFlag);
/* Fournit les informations complémentaires d'une instruction. */
ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *);
+
/**
* La définition de "GBinFormat", utile aux traitements complémentaires, ne peut
* se faire en incluant le fichier d'en-tête "../format/format.h", pour cause
* de références circulaires.
*
* On procède donc à une seconde déclaration, en attendant éventuellement mieux.
+ *
+ * Pareil pour "GArchProcessor", définie dans le fichier "processor.h", lequel
+ * inclut directement ce fichier.
*/
-
/* Format binaire générique (instance) */
typedef struct _GBinFormat GBinFormat;
+/* Ligne de représentation générique (instance) */
+typedef struct _GArchProcessor GArchProcessor;
+
/* Types de crochet de traitement */
typedef enum _InstrProcessHook
{
+ IPH_FETCH, /* Itinéraire de désassemblage */
IPH_LINK, /* Edition des liens */
IPH_POST, /* Résolution des symboles */
@@ -100,13 +107,13 @@ typedef enum _InstrProcessHook
} InstrProcessHook;
/* Complète un désassemblage accompli pour une instruction. */
-typedef void (* instr_hook_fc) (GArchInstruction *, GProcContext *, GBinFormat *);
+typedef void (* instr_hook_fc) (GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *);
/* Définit un traitement complémentare au désassemblage. */
void g_arch_instruction_set_hook(GArchInstruction *, InstrProcessHook, instr_hook_fc);
/* Complète un désassemblage accompli pour une instruction. */
-void g_arch_instruction_call_hook(GArchInstruction *, InstrProcessHook, GProcContext *, GBinFormat *);
+void g_arch_instruction_call_hook(GArchInstruction *, InstrProcessHook, GArchProcessor *, GProcContext *, GBinFormat *);
/* Définit la localisation d'une instruction. */
void g_arch_instruction_set_range(GArchInstruction *, const mrange_t *);
@@ -155,7 +162,8 @@ typedef enum _InstructionLinkType
ILT_JUMP_IF_FALSE, /* Saut conditionnel (si faux) */
ILT_LOOP, /* Retour en arrière (boucle) */
ILT_CALL, /* Appel d'une fonction */
- ILT_CATCH_EXCEPTION /* Gestion d'une exception */
+ ILT_CATCH_EXCEPTION, /* Gestion d'une exception */
+ ILT_REF /* Simple référence croisée */
} InstructionLinkType;
diff --git a/src/arch/link.c b/src/arch/link.c
new file mode 100644
index 0000000..bc80e39
--- /dev/null
+++ b/src/arch/link.c
@@ -0,0 +1,190 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * link.c - édition des liens après la phase de désassemblage
+ *
+ * Copyright (C) 2014 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * OpenIDA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * OpenIDA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "link.h"
+
+
+#include <assert.h>
+
+
+#include "target.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction ARMv7 à traiter. *
+* proc = représentation de l'architecture utilisée. *
+* context = contexte associé à la phase de désassemblage. *
+* format = acès aux données du binaire d'origine. *
+* *
+* Description : Etablit un lien de saut selon une instruction donnée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void handle_jump_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format)
+{
+ GArchOperand *op; /* Opérande numérique en place */
+ virt_t virt; /* Adresse virtuelle */
+ vmpa2t addr; /* Adresse de destination */
+ GArchInstruction *target; /* Ligne visée par la référence*/
+
+ assert(g_arch_instruction_count_operands(instr) > 0);
+
+ op = g_arch_instruction_get_operand(instr, 0);
+
+ if (!G_IS_IMM_OPERAND(op)) return;
+
+ if (g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &virt))
+ {
+ init_vmpa(&addr, VMPA_NO_PHYSICAL, virt);
+
+ target = g_arch_processor_find_instr_by_address(proc, &addr);
+
+ if (target != NULL)
+ g_arch_instruction_link_with(instr, target, ILT_JUMP);
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction ARMv7 à traiter. *
+* proc = représentation de l'architecture utilisée. *
+* context = contexte associé à la phase de désassemblage. *
+* format = acès aux données du binaire d'origine. *
+* *
+* Description : Etablit un lien d'appel selon une instruction donnée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+#include "instruction-int.h"
+void handle_branch_if_true_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format)
+{
+ GArchOperand *op; /* Opérande numérique en place */
+ virt_t virt; /* Adresse virtuelle */
+ vmpa2t addr; /* Adresse de destination */
+ GArchInstruction *target; /* Ligne visée par la référence*/
+ GArchInstruction *list; /* Ensemble des instructions */
+
+ assert(g_arch_instruction_count_operands(instr) > 0);
+
+ op = g_arch_instruction_get_operand(instr, 0);
+
+ virt = VMPA_NO_VIRTUAL;
+
+ if (G_IS_TARGET_OPERAND(op))
+ virt = g_target_operand_get_addr(G_TARGET_OPERAND(op));
+
+ else if (G_IS_IMM_OPERAND(op))
+ {
+ if (!g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &virt))
+ virt = VMPA_NO_VIRTUAL;
+ }
+
+ if (virt != VMPA_NO_VIRTUAL)
+ {
+ /* TODO : utiliser format pour contruire une adresse avec une position physique,
+ * ce qui accélèrerait les recherches.
+ */
+ init_vmpa(&addr, VMPA_NO_PHYSICAL, virt);
+
+ target = g_arch_processor_find_instr_by_address(proc, &addr);
+
+ printf(" @ 0x%08x BRANCH to 0x%08x -->> %p\n",
+ (unsigned int)instr->range.addr.virtual, (unsigned int)virt, target);
+
+ if (target != NULL)
+ {
+ g_arch_instruction_link_with(instr, target, ILT_JUMP_IF_TRUE);
+
+ list = g_arch_processor_get_disassembled_instructions(proc);
+
+ target = g_arch_instruction_get_next_iter(list, instr, ~0);
+
+ if (target != NULL)
+ g_arch_instruction_link_with(instr, target, ILT_JUMP_IF_FALSE);
+
+ }
+
+ }
+
+
+ else printf(" @ 0x%08x FAILED TO BRANCH\n",
+ (unsigned int)instr->range.addr.virtual);
+
+
+
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction ARMv7 à traiter. *
+* proc = représentation de l'architecture utilisée. *
+* context = contexte associé à la phase de désassemblage. *
+* format = acès aux données du binaire d'origine. *
+* *
+* Description : Etablit un lien d'appel selon une instruction donnée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void handle_call_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format)
+{
+ GArchOperand *op; /* Opérande numérique en place */
+ virt_t virt; /* Adresse virtuelle */
+ vmpa2t addr; /* Adresse de destination */
+ GArchInstruction *target; /* Ligne visée par la référence*/
+
+ assert(g_arch_instruction_count_operands(instr) > 0);
+
+ op = g_arch_instruction_get_operand(instr, 0);
+
+ if (!G_IS_IMM_OPERAND(op)) return;
+
+ if (g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &virt))
+ {
+ init_vmpa(&addr, VMPA_NO_PHYSICAL, virt);
+
+ target = g_arch_processor_find_instr_by_address(proc, &addr);
+
+ if (target != NULL)
+ g_arch_instruction_link_with(instr, target, ILT_CALL);
+
+ }
+
+}
diff --git a/src/arch/link.h b/src/arch/link.h
new file mode 100644
index 0000000..1923e0b
--- /dev/null
+++ b/src/arch/link.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * link.h - prototypes pour l'édition des liens après la phase de désassemblage
+ *
+ * Copyright (C) 2015 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * OpenIDA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * OpenIDA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ARCH_LINK_H
+#define _ARCH_LINK_H
+
+
+#include "instruction.h"
+#include "processor.h"
+#include "../format/format.h"
+
+
+
+/* Etablit un lien de saut selon une instruction donnée. */
+void handle_jump_as_link(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *);
+
+/* Etablit un lien d'appel selon une instruction donnée. */
+void handle_branch_if_true_as_link(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *);
+
+/* Etablit un lien d'appel selon une instruction donnée. */
+void handle_call_as_link(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *);
+
+
+
+#endif /* _ARCH_LINK_H */
diff --git a/src/arch/processor-int.h b/src/arch/processor-int.h
index 2b91b36..d387bde 100644
--- a/src/arch/processor-int.h
+++ b/src/arch/processor-int.h
@@ -43,6 +43,9 @@
+/* Taille des pré-allocations pour les instructions */
+#define INSTR_ALLOC_BLOCK 100
+
/* Fournit un contexte propre au processeur d'une architecture. */
@@ -70,6 +73,10 @@ struct _GArchProcessor
get_processor_context_fc get_ctx; /* Obtention d'un contexte #1 */
get_decomp_context_fc get_dec_ctx; /* Obtention d'un contexte #2 */
+ GArchInstruction **instructions; /* Instructions désassemblées */
+ size_t instr_allocated; /* Taille de la liste allouée */
+ size_t instr_count; /* Taille de la liste aplatie */
+
};
diff --git a/src/arch/processor.c b/src/arch/processor.c
index 0b33552..c2d190b 100644
--- a/src/arch/processor.c
+++ b/src/arch/processor.c
@@ -24,12 +24,16 @@
#include "processor.h"
+#include <malloc.h>
+#include <stdlib.h>
+
#include "instruction-int.h"
#include "processor-int.h"
+#include "raw.h"
@@ -294,3 +298,146 @@ GArchInstruction *g_arch_processor_disassemble(const GArchProcessor *proc, GProc
return result;
}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = architecture visée par la procédure. *
+* list = liste des instructions désassemblées. *
+* *
+* Description : Note les instructions désassemblées avec une architecture. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_arch_processor_set_disassembled_instructions(GArchProcessor *proc, GArchInstruction *list)
+{
+ GArchInstruction *iter; /* Boucle de parcours */
+
+ ainstr_list_for_each(iter, list)
+ {
+ /* Mise à disposition de d'avantage d'espace */
+ if (proc->instr_allocated == proc->instr_count)
+ {
+ proc->instr_allocated += INSTR_ALLOC_BLOCK;
+
+ proc->instructions = (GArchInstruction **)realloc(proc->instructions,
+ proc->instr_allocated * sizeof(GArchInstruction *));
+
+ }
+
+ proc->instructions[proc->instr_count++] = iter;
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = architecture visée par la procédure. *
+* *
+* Description : Fournit les instructions désassemblées pour une architecture.*
+* *
+* Retour : Liste des instructions désassemblées ou NULL si aucune. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *g_arch_processor_get_disassembled_instructions(const GArchProcessor *proc)
+{
+ return (proc->instr_count > 0 ? proc->instructions[0] : NULL);
+
+}
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = processeur recensant diverses instructions. *
+* addr = position en mémoire ou physique à chercher. *
+* *
+* Description : Recherche une instruction d'après son adresse. *
+* *
+* Retour : Instruction trouvée à l'adresse donnée, NULL si aucune. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *g_arch_processor_find_instr_by_address(const GArchProcessor *proc, const vmpa2t *addr)
+{
+ GArchInstruction *result; /* Trouvaille à retourner */
+ GArchInstruction *fake; /* Coquille vide à comparer */
+ void *ptr; /* Résultat des recherches */
+ size_t i; /* Boucle de parcours */
+ const mrange_t *range; /* Emplacement d'instruction */
+
+ if (has_phys_addr(addr))
+ {
+ fake = g_raw_instruction_new_from_value(addr, MDS_8_BITS_UNSIGNED, 0);
+
+ int search_for_instr_by_addr(const GArchInstruction **a, const GArchInstruction **b)
+ {
+ const mrange_t *range_a; /* Emplacement pour l'instr. A */
+ const mrange_t *range_b; /* Emplacement pour l'instr. B */
+
+ range_a = g_arch_instruction_get_range(*a);
+ range_b = g_arch_instruction_get_range(*b);
+
+ /*
+ printf(" -- cmp -- 0x%08x vs 0x%08x => %d\n",
+ (unsigned int)range_a->addr.virtual,
+ (unsigned int)range_b->addr.virtual,
+ cmp_vmpa(get_mrange_addr(range_a), get_mrange_addr(range_b)));
+ */
+
+ return cmp_vmpa(get_mrange_addr(range_a), get_mrange_addr(range_b));
+
+ }
+
+ ptr = bsearch(&fake, proc->instructions, proc->instr_count,
+ sizeof(GArchInstruction *), (__compar_fn_t)search_for_instr_by_addr);
+
+ g_object_unref(G_OBJECT(fake));
+
+ result = (ptr != NULL ? *((GArchInstruction **)ptr) : NULL);
+
+ }
+
+ else
+ {
+ result = NULL;
+
+ for (i = 0; i < proc->instr_count && result == NULL; i++)
+ {
+ range = g_arch_instruction_get_range(proc->instructions[i]);
+
+ if (cmp_vmpa(addr, get_mrange_addr(range)) == 0)
+ result = proc->instructions[i];
+
+ }
+
+ /*
+ for (i = 0; i < proc->instr_count; i++)
+ printf(" # %04zu 0x%08x\n", i, proc->instructions[i]->range.addr.virtual);
+ */
+
+ }
+
+ return result;
+
+}
diff --git a/src/arch/processor.h b/src/arch/processor.h
index 725307f..3eeefd5 100644
--- a/src/arch/processor.h
+++ b/src/arch/processor.h
@@ -78,4 +78,20 @@ GArchInstruction *g_arch_processor_disassemble(const GArchProcessor *, GProcCont
+/* ------------------ MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES ------------------ */
+
+
+/* Note les instructions désassemblées avec une architecture. */
+void g_arch_processor_set_disassembled_instructions(GArchProcessor *, GArchInstruction *);
+
+/* Fournit les instructions désassemblées pour une architecture. */
+GArchInstruction *g_arch_processor_get_disassembled_instructions(const GArchProcessor *);
+
+
+
+/* Recherche une instruction d'après son adresse. */
+GArchInstruction *g_arch_processor_find_instr_by_address(const GArchProcessor *, const vmpa2t *);
+
+
+
#endif /* _ARCH_PROCESSOR_H */