summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-12-15 13:40:28 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-12-15 13:40:28 (GMT)
commit124c8410dbfcad59d66b850c50c96ec73a607ab7 (patch)
treeb7127c66abfccd11b9126741e2809a893ee44143
parentdb1a6171007a6641a4659392c9bcc05670396643 (diff)
Defined proper accesses to instructions loaded by a processor.
-rw-r--r--ChangeLog37
-rw-r--r--plugins/androhelpers/params.c2
-rw-r--r--plugins/androhelpers/switch.c2
-rw-r--r--plugins/androhelpers/try_n_catch.c4
-rw-r--r--plugins/libcsem/exit.c7
-rw-r--r--plugins/pychrysa/arch/instriter.c4
-rw-r--r--plugins/pychrysa/arch/processor.c109
-rw-r--r--src/analysis/db/items/comment.c2
-rw-r--r--src/analysis/db/items/switcher.c6
-rw-r--r--src/analysis/disass/disassembler.c6
-rw-r--r--src/analysis/disass/dragon.c51
-rw-r--r--src/analysis/disass/dragon.h2
-rw-r--r--src/analysis/disass/instructions.c32
-rw-r--r--src/analysis/disass/limit.c4
-rw-r--r--src/analysis/disass/limit.h2
-rw-r--r--src/analysis/disass/links.c5
-rw-r--r--src/analysis/disass/links.h2
-rw-r--r--src/analysis/disass/output.c10
-rw-r--r--src/analysis/disass/routines.c4
-rw-r--r--src/analysis/disass/routines.h2
-rw-r--r--src/arch/dalvik/link.c7
-rw-r--r--src/arch/instriter.c81
-rw-r--r--src/arch/instriter.h6
-rw-r--r--src/arch/link.c34
-rw-r--r--src/arch/processor.c329
-rw-r--r--src/arch/processor.h60
-rw-r--r--src/gtkext/gtkgraphview.c68
-rw-r--r--src/gui/menus/edition.c11
-rw-r--r--src/gui/panels/strings.c7
-rw-r--r--src/gui/status.c2
30 files changed, 550 insertions, 348 deletions
diff --git a/ChangeLog b/ChangeLog
index 00d2f12..7271d7e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,42 @@
16-12-15 Cyrille Bagard <nocbos@gmail.com>
+ * plugins/androhelpers/params.c:
+ * plugins/androhelpers/switch.c:
+ * plugins/androhelpers/try_n_catch.c:
+ * plugins/libcsem/exit.c:
+ * plugins/pychrysa/arch/instriter.c:
+ * plugins/pychrysa/arch/processor.c:
+ * src/analysis/db/items/comment.c:
+ * src/analysis/db/items/switcher.c:
+ * src/analysis/disass/disassembler.c:
+ * src/analysis/disass/dragon.c:
+ * src/analysis/disass/dragon.h:
+ * src/analysis/disass/instructions.c:
+ * src/analysis/disass/limit.c:
+ * src/analysis/disass/limit.h:
+ * src/analysis/disass/links.c:
+ * src/analysis/disass/links.h:
+ * src/analysis/disass/output.c:
+ * src/analysis/disass/routines.c:
+ * src/analysis/disass/routines.h:
+ * src/arch/dalvik/link.c:
+ * src/arch/instriter.c:
+ * src/arch/instriter.h:
+ * src/arch/link.c:
+ Update code.
+
+ * src/arch/processor.c:
+ * src/arch/processor.h:
+ Define proper accesses to instructions loaded by a processor.
+
+ * src/gtkext/gtkgraphview.c:
+ * src/gui/menus/edition.c:
+ * src/gui/panels/strings.c:
+ * src/gui/status.c:
+ Update code.
+
+16-12-15 Cyrille Bagard <nocbos@gmail.com>
+
* plugins/pychrysa/arch/Makefile.am:
Add the 'instriter.[ch]' files to libpychrysaarch_la_SOURCES.
diff --git a/plugins/androhelpers/params.c b/plugins/androhelpers/params.c
index c9b1109..20e0da9 100644
--- a/plugins/androhelpers/params.c
+++ b/plugins/androhelpers/params.c
@@ -194,7 +194,7 @@ bool replace_parameters(GLoadedBinary *binary)
format = G_DEX_FORMAT(g_loaded_binary_get_format(binary));
proc = g_loaded_binary_get_processor(binary);
- instrs = g_arch_processor_get_disassembled_instructions(proc);
+ instrs = NULL;//g_arch_processor_get_disassembled_instructions(proc);
cls_count = g_dex_format_count_classes(format);
for (i = 0; i < cls_count; i++)
diff --git a/plugins/androhelpers/switch.c b/plugins/androhelpers/switch.c
index 43b6ae1..0700cc8 100644
--- a/plugins/androhelpers/switch.c
+++ b/plugins/androhelpers/switch.c
@@ -398,7 +398,7 @@ bool extract_switch_info(GLoadedBinary *binary, bool link)
format = G_DEX_FORMAT(g_loaded_binary_get_format(binary));
proc = g_loaded_binary_get_processor(binary);
- instrs = g_arch_processor_get_disassembled_instructions(proc);
+ instrs = NULL;//g_arch_processor_get_disassembled_instructions(proc);
cls_count = g_dex_format_count_classes(format);
for (i = 0; i < cls_count; i++)
diff --git a/plugins/androhelpers/try_n_catch.c b/plugins/androhelpers/try_n_catch.c
index 28f7061..dbe0ef4 100644
--- a/plugins/androhelpers/try_n_catch.c
+++ b/plugins/androhelpers/try_n_catch.c
@@ -125,7 +125,7 @@ static void attach_caught_code(const GLoadedBinary *binary, const GBinRoutine *r
end = start + try->insn_count * sizeof(uint16_t);
proc = g_loaded_binary_get_processor(binary);
- instrs = g_arch_processor_get_disassembled_instructions(proc);
+ instrs = NULL;//g_arch_processor_get_disassembled_instructions(proc);
first = g_arch_instruction_find_by_address(instrs, start, true);
next = g_arch_instruction_find_by_address(instrs, end, true);
@@ -253,7 +253,7 @@ static caught_exception **build_all_destinations_list(const GLoadedBinary *binar
format = G_DEX_FORMAT(g_loaded_binary_get_format(binary));
proc = g_loaded_binary_get_processor(binary);
- instrs = g_arch_processor_get_disassembled_instructions(proc);
+ instrs = NULL;//g_arch_processor_get_disassembled_instructions(proc);
instrs = g_arch_instruction_find_by_address(instrs, start, true);
/* Création d'un espace mémoire pour les listes */
diff --git a/plugins/libcsem/exit.c b/plugins/libcsem/exit.c
index cbfec64..20511aa 100644
--- a/plugins/libcsem/exit.c
+++ b/plugins/libcsem/exit.c
@@ -70,6 +70,9 @@ static void mark_one_kind_of_exit_as_return(const GLoadedBinary *binary, const c
instr = g_arch_processor_find_instr_by_address(proc, get_mrange_addr(range));
+ if (instr == NULL)
+ goto mokoear_not_found;
+
g_arch_instruction_rlock_src(instr);
count = g_arch_instruction_get_sources(instr, &sources);
@@ -83,6 +86,10 @@ static void mark_one_kind_of_exit_as_return(const GLoadedBinary *binary, const c
g_arch_instruction_runlock_src(instr);
+ g_object_unref(G_OBJECT(instr));
+
+ mokoear_not_found:
+
g_object_unref(G_OBJECT(proc));
mokoear_done_with_sym:
diff --git a/plugins/pychrysa/arch/instriter.c b/plugins/pychrysa/arch/instriter.c
index 1e5346e..0d65f26 100644
--- a/plugins/pychrysa/arch/instriter.c
+++ b/plugins/pychrysa/arch/instriter.c
@@ -28,7 +28,6 @@
#include <pygobject.h>
-#include <arch/instriter.h>
#include <arch/processor.h>
@@ -101,7 +100,10 @@ static PyObject *py_instr_iterator_next(PyInstrIterator *self)
next = get_instruction_iterator_next(self->native);
if (next != NULL)
+ {
result = pygobject_new(G_OBJECT(next));
+ g_object_unref(G_OBJECT(next));
+ }
else
{
diff --git a/plugins/pychrysa/arch/processor.c b/plugins/pychrysa/arch/processor.c
index 3ef56e4..e34bf1f 100644
--- a/plugins/pychrysa/arch/processor.c
+++ b/plugins/pychrysa/arch/processor.c
@@ -68,12 +68,6 @@ static PyObject *py_arch_processor_get_instrs(PyObject *, void *);
/* Recherche une instruction d'après son adresse. */
static PyObject *py_arch_processor_find_instr_by_addr(PyObject *, PyObject *);
-/* Fournit l'instruction qui en précède une autre. */
-static PyObject *py_arch_processor_get_prev_instr(PyObject *, PyObject *);
-
-/* Fournit l'instruction qui en suit une autre. */
-static PyObject *py_arch_processor_get_next_instr(PyObject *, PyObject *);
-
/* ---------------------------------------------------------------------------------- */
@@ -182,102 +176,11 @@ static PyObject *py_arch_processor_find_instr_by_addr(PyObject *self, PyObject *
found = g_arch_processor_find_instr_by_address(proc, addr);
if (found != NULL)
- result = pygobject_new(G_OBJECT(found));
-
- else
{
- result = Py_None;
- Py_INCREF(result);
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : self = processeur d'architecture à manipuler. *
-* args = instruction représentant le point de départ. *
-* *
-* Description : Fournit l'instruction qui en précède une autre. *
-* *
-* Retour : Instruction précédente trouvée, ou NULL. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_arch_processor_get_prev_instr(PyObject *self, PyObject *args)
-{
- PyObject *result; /* Instance à retourner */
- PyObject *instr_obj; /* Objet pour une instruction */
- int ret; /* Bilan de lecture des args. */
- GArchProcessor *proc; /* Processeur manipulé */
- GArchInstruction *instr; /* Instruction de référence */
- GArchInstruction *found; /* Instruction liée trouvée */
-
- ret = PyArg_ParseTuple(args, "O", &instr_obj);
- if (!ret) return NULL;
-
- ret = PyObject_IsInstance(instr_obj, (PyObject *)get_python_arch_instruction_type());
- if (!ret) return NULL;
-
- proc = G_ARCH_PROCESSOR(pygobject_get(self));
- instr = G_ARCH_INSTRUCTION(pygobject_get(instr_obj));
-
- found = g_arch_processor_get_prev_instr(proc, instr);
-
- if (found != NULL)
result = pygobject_new(G_OBJECT(found));
-
- else
- {
- result = Py_None;
- Py_INCREF(result);
+ g_object_unref(G_OBJECT(found));
}
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : self = processeur d'architecture à manipuler. *
-* args = instruction représentant le point de départ. *
-* *
-* Description : Fournit l'instruction qui en suit une autre. *
-* *
-* Retour : Instruction suivante trouvée, ou NULL. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_arch_processor_get_next_instr(PyObject *self, PyObject *args)
-{
- PyObject *result; /* Instance à retourner */
- PyObject *instr_obj; /* Objet pour une instruction */
- int ret; /* Bilan de lecture des args. */
- GArchProcessor *proc; /* Processeur manipulé */
- GArchInstruction *instr; /* Instruction de référence */
- GArchInstruction *found; /* Instruction liée trouvée */
-
- ret = PyArg_ParseTuple(args, "O", &instr_obj);
- if (!ret) return NULL;
-
- ret = PyObject_IsInstance(instr_obj, (PyObject *)get_python_arch_instruction_type());
- if (!ret) return NULL;
-
- proc = G_ARCH_PROCESSOR(pygobject_get(self));
- instr = G_ARCH_INSTRUCTION(pygobject_get(instr_obj));
-
- found = g_arch_processor_get_next_instr(proc, instr);
-
- if (found != NULL)
- result = pygobject_new(G_OBJECT(found));
-
else
{
result = Py_None;
@@ -309,16 +212,6 @@ PyTypeObject *get_python_arch_processor_type(void)
METH_VARARGS,
"find_instr_by_addr($self, addr, /)\n--\n\nLook for an instruction located at a given address."
},
- {
- "get_prev_instr", py_arch_processor_get_prev_instr,
- METH_VARARGS,
- "get_prev_instr($self, instr, /)\n--\n\nProvide the instruction preceding a given instruction."
- },
- {
- "get_next_instr", py_arch_processor_get_next_instr,
- METH_VARARGS,
- "get_next_instr($self, instr, /)\n--\n\nProvide the instruction following a given instruction."
- },
{ NULL }
};
diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c
index 45331b8..55893d1 100644
--- a/src/analysis/db/items/comment.c
+++ b/src/analysis/db/items/comment.c
@@ -638,6 +638,8 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap
}
+ g_object_unref(G_OBJECT(instr));
+
g_object_unref(G_OBJECT(proc));
}
diff --git a/src/analysis/db/items/switcher.c b/src/analysis/db/items/switcher.c
index 15354e9..748c934 100644
--- a/src/analysis/db/items/switcher.c
+++ b/src/analysis/db/items/switcher.c
@@ -527,7 +527,7 @@ static bool g_db_switcher_run(GDbSwitcher *switcher, GLoadedBinary *binary, ImmO
}
result = G_IS_IMM_OPERAND(op);
- if (!result) goto exit_instr;
+ if (!result) goto exit_operand;
/* Traitement au niveau du rendu graphique */
@@ -559,6 +559,10 @@ static bool g_db_switcher_run(GDbSwitcher *switcher, GLoadedBinary *binary, ImmO
/* TODO g_object_unref(G_OBJECT(buffer));*/
+ exit_operand:
+
+ g_object_unref(G_OBJECT(proc));
+
exit_instr:
g_object_unref(G_OBJECT(proc));
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index 813701e..f210bd1 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -262,7 +262,11 @@ static void process_all_instructions(wgroup_id_t gid, GtkStatusStack *status, co
runs_count = g_get_num_processors();
- ins_count = g_arch_processor_count_disassembled_instructions(proc);
+ g_arch_processor_lock(proc);
+
+ ins_count = g_arch_processor_count_instructions(proc);
+
+ g_arch_processor_unlock(proc);
run_size = ins_count / runs_count;
diff --git a/src/analysis/disass/dragon.c b/src/analysis/disass/dragon.c
index 01e985d..cc1346c 100644
--- a/src/analysis/disass/dragon.c
+++ b/src/analysis/disass/dragon.c
@@ -49,7 +49,7 @@ struct _dragon_node
/* Dénombre le nombre de noeuds présents dans une routine. */
-static dragon_node *create_dragon_nodes(const GArchProcessor *, const instr_coverage *, const mrange_t *, const vmpa2t *, size_t *);
+static dragon_node *create_dragon_nodes(GArchProcessor *, const instr_coverage *, const mrange_t *, const vmpa2t *, size_t *);
/* Supprime de la mémoire tous les noeuds détectés. */
static void delete_dragon_nodes(dragon_node *, size_t);
@@ -93,13 +93,14 @@ struct _dragon_knight
* *
******************************************************************************/
-static dragon_node *create_dragon_nodes(const GArchProcessor *proc, const instr_coverage *coverage, const mrange_t *range, const vmpa2t *start, size_t *count)
+static dragon_node *create_dragon_nodes(GArchProcessor *proc, const instr_coverage *coverage, const mrange_t *range, const vmpa2t *start, size_t *count)
{
dragon_node *result; /* Liste à créer et renvoyer */
size_t allocated; /* Dimensionnement en mémoire */
bool need_alloc; /* Besoin d'une extension ? */
GArchInstruction *last; /* Mémorisation du passé */
- GArchInstruction *iter; /* Boucle de parcours */
+ instr_iter_t *iter; /* Boucle de parcours */
+ GArchInstruction *instr; /* Instruction analysée */
const mrange_t *irange; /* Emplacement d'instruction */
instr_link_t *sources; /* Liste des instructions liées*/
size_t scount; /* Nombre de liens de source */
@@ -115,16 +116,22 @@ static dragon_node *create_dragon_nodes(const GArchProcessor *proc, const instr_
allocated = 0;
need_alloc = true;
- for (last = NULL, iter = g_arch_processor_find_covered_instr_by_address(proc, coverage, start);
- iter != NULL;
- last = iter, iter = g_arch_instruction_get_next_iter(iter /* FIXME : list*/, iter, ~0))
+ iter = g_arch_processor_get_covered_iter_from_address(proc, coverage, start);
+ if (iter == NULL) goto cdn_no_coverage;
+
+ for (last = NULL, instr = get_instruction_iterator_current(iter);
+ instr != NULL;
+ last = instr, instr = get_instruction_iterator_next(iter))
{
/* L'instruction sort-elle des clous ? */
- irange = g_arch_instruction_get_range(iter);
+ irange = g_arch_instruction_get_range(instr);
if (!mrange_contains_mrange(range, irange))
+ {
+ g_object_unref(G_OBJECT(instr));
break;
+ }
/* Découpage en blocs */
@@ -142,7 +149,7 @@ static dragon_node *create_dragon_nodes(const GArchProcessor *proc, const instr_
new = &result[*count - 1];
- new->first = iter;
+ new->first = instr;
}
@@ -165,8 +172,8 @@ static dragon_node *create_dragon_nodes(const GArchProcessor *proc, const instr_
{
/* Analyse des sources */
- g_arch_instruction_rlock_src(iter);
- scount = g_arch_instruction_get_sources(iter, &sources);
+ g_arch_instruction_rlock_src(instr);
+ scount = g_arch_instruction_get_sources(instr, &sources);
cut = false;
@@ -192,7 +199,7 @@ static dragon_node *create_dragon_nodes(const GArchProcessor *proc, const instr_
new = &result[*count - 1];
- new->first = iter;
+ new->first = instr;
cut = true;
@@ -203,14 +210,14 @@ static dragon_node *create_dragon_nodes(const GArchProcessor *proc, const instr_
}
- g_arch_instruction_runlock_src(iter);
+ g_arch_instruction_runlock_src(instr);
}
/* Analyse des destinations */
- g_arch_instruction_rlock_dest(iter);
- dcount = g_arch_instruction_get_destinations(iter, &dests);
+ g_arch_instruction_rlock_dest(instr);
+ dcount = g_arch_instruction_get_destinations(instr, &dests);
cut = false;
@@ -219,7 +226,7 @@ static dragon_node *create_dragon_nodes(const GArchProcessor *proc, const instr_
{
case ILT_JUMP:
- result[*count - 1].last = iter;
+ result[*count - 1].last = instr;
cut = true;
@@ -232,21 +239,27 @@ static dragon_node *create_dragon_nodes(const GArchProcessor *proc, const instr_
}
- g_arch_instruction_runlock_dest(iter);
+ g_arch_instruction_runlock_dest(instr);
- if (!need_alloc && g_arch_instruction_get_flags(iter) & AIF_RETURN_POINT)
+ if (!need_alloc && g_arch_instruction_get_flags(instr) & AIF_RETURN_POINT)
{
- result[*count - 1].last = iter;
+ result[*count - 1].last = instr;
need_alloc = true;
}
+ g_object_unref(G_OBJECT(instr));
+
}
if (*count > 0)
result[*count - 1].last = last;
+ delete_instruction_iterator(iter);
+
+ cdn_no_coverage:
+
return result;
}
@@ -623,7 +636,7 @@ const bitfield_t *get_domination_bits(const dragon_node *node)
* *
******************************************************************************/
-dragon_knight *begin_dragon_knight(const GArchProcessor *proc, const instr_coverage *coverage, const mrange_t *range, const vmpa2t *start)
+dragon_knight *begin_dragon_knight(GArchProcessor *proc, const instr_coverage *coverage, const mrange_t *range, const vmpa2t *start)
{
dragon_knight *result; /* Données à retourner */
dragon_node *nodes; /* Noeuds mis en place */
diff --git a/src/analysis/disass/dragon.h b/src/analysis/disass/dragon.h
index 095281b..897e21b 100644
--- a/src/analysis/disass/dragon.h
+++ b/src/analysis/disass/dragon.h
@@ -72,7 +72,7 @@ typedef struct _dragon_knight dragon_knight;
/* Attaque la complexité d'un code en créant des noeuds. */
-dragon_knight *begin_dragon_knight(const GArchProcessor *, const instr_coverage *, const mrange_t *, const vmpa2t *);
+dragon_knight *begin_dragon_knight(GArchProcessor *, const instr_coverage *, const mrange_t *, const vmpa2t *);
/* Supprime de la mémoire les données d'une complexité de code. */
void end_dragon_knight(dragon_knight *);
diff --git a/src/analysis/disass/instructions.c b/src/analysis/disass/instructions.c
index 799d196..d83536d 100644
--- a/src/analysis/disass/instructions.c
+++ b/src/analysis/disass/instructions.c
@@ -251,10 +251,16 @@ void g_instructions_study_do_link_operation(GInstructionsStudy *study, size_t in
{
GArchInstruction *instr; /* Instruction en traitement */
- instr = g_arch_processor_get_disassembled_instruction(study->proc, index);
+ g_arch_processor_lock(study->proc);
+
+ instr = g_arch_processor_get_instruction(study->proc, index);
+
+ g_arch_processor_unlock(study->proc);
g_arch_instruction_call_hook(instr, IPH_LINK, study->proc, study->ctx, study->format);
+ g_object_unref(G_OBJECT(instr));
+
}
@@ -275,10 +281,16 @@ void g_instructions_study_do_post_operation(GInstructionsStudy *study, size_t in
{
GArchInstruction *instr; /* Instruction en traitement */
- instr = g_arch_processor_get_disassembled_instruction(study->proc, index);
+ g_arch_processor_lock(study->proc);
+
+ instr = g_arch_processor_get_instruction(study->proc, index);
+
+ g_arch_processor_unlock(study->proc);
g_arch_instruction_call_hook(instr, IPH_POST, study->proc, study->ctx, study->format);
+ g_object_unref(G_OBJECT(instr));
+
}
@@ -300,16 +312,28 @@ void g_instructions_study_establish_links(GInstructionsStudy *study, size_t inde
GArchInstruction *instr; /* Instruction en traitement */
GArchInstruction *prev; /* Instruction précédente */
- instr = g_arch_processor_get_disassembled_instruction(study->proc, index);
+ g_arch_processor_lock(study->proc);
+
+ instr = g_arch_processor_get_instruction(study->proc, index);
+
+ g_arch_processor_unlock(study->proc);
if (index > 0)
{
- prev = g_arch_processor_get_disassembled_instruction(study->proc, index - 1);
+ g_arch_processor_lock(study->proc);
+
+ prev = g_arch_processor_get_instruction(study->proc, index - 1);
+
+ g_arch_processor_unlock(study->proc);
establish_natural_link(instr, prev);
+ g_object_unref(G_OBJECT(prev));
+
}
establish_links_for_instruction(instr, G_BIN_FORMAT(study->format), study->proc);
+ g_object_unref(G_OBJECT(instr));
+
}
diff --git a/src/analysis/disass/limit.c b/src/analysis/disass/limit.c
index c7a9524..28a8264 100644
--- a/src/analysis/disass/limit.c
+++ b/src/analysis/disass/limit.c
@@ -76,7 +76,7 @@ static const mrange_t *find_x_range_for_addr(const mrange_t *ranges, size_t coun
* *
******************************************************************************/
-void compute_routine_limit(GBinRoutine *routine, GBinRoutine *prev, const GArchProcessor *proc, mrange_t *exe_ranges, size_t exe_count)
+void compute_routine_limit(GBinRoutine *routine, GBinRoutine *prev, GArchProcessor *proc, mrange_t *exe_ranges, size_t exe_count)
{
const mrange_t *range; /* Emplacement courant */
vmpa2t addr; /* Adresse à conserver */
@@ -100,6 +100,8 @@ void compute_routine_limit(GBinRoutine *routine, GBinRoutine *prev, const GArchP
g_arch_instruction_set_flag(start, AIF_ROUTINE_START);
+ g_object_unref(G_OBJECT(start));
+
/* Si on peut se raccrocher à la routine suivante... */
if (prev != NULL)
{
diff --git a/src/analysis/disass/limit.h b/src/analysis/disass/limit.h
index 431c642..7aba8a6 100644
--- a/src/analysis/disass/limit.h
+++ b/src/analysis/disass/limit.h
@@ -32,7 +32,7 @@
/* S'assure qu'une routine est bien bornée. */
-void compute_routine_limit(GBinRoutine *, GBinRoutine *, const GArchProcessor *, mrange_t *, size_t);
+void compute_routine_limit(GBinRoutine *, GBinRoutine *, GArchProcessor *, mrange_t *, size_t);
diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c
index 82da37d..18bbeb3 100644
--- a/src/analysis/disass/links.c
+++ b/src/analysis/disass/links.c
@@ -178,7 +178,7 @@ static void convert_immediate_into_target(GArchInstruction *instr, size_t index,
* *
******************************************************************************/
-void establish_links_for_instruction(GArchInstruction *instr, GBinFormat *format, const GArchProcessor *proc)
+void establish_links_for_instruction(GArchInstruction *instr, GBinFormat *format, GArchProcessor *proc)
{
bool skip; /* Saut des conversions */
size_t count; /* Nombre d'opérandes présents */
@@ -209,7 +209,10 @@ void establish_links_for_instruction(GArchInstruction *instr, GBinFormat *format
target = g_arch_processor_find_instr_by_address(proc, &addr);
if (target != NULL)
+ {
g_arch_instruction_link_with(instr, target, ILT_REF);
+ g_object_unref(G_OBJECT(target));
+ }
}
diff --git a/src/analysis/disass/links.h b/src/analysis/disass/links.h
index 8cdf663..bfa68db 100644
--- a/src/analysis/disass/links.h
+++ b/src/analysis/disass/links.h
@@ -35,7 +35,7 @@
void establish_natural_link(GArchInstruction *, GArchInstruction *);
/* Complète un désassemblage accompli pour une instruction. */
-void establish_links_for_instruction(GArchInstruction *, GBinFormat *, const GArchProcessor *);
+void establish_links_for_instruction(GArchInstruction *, GBinFormat *, GArchProcessor *);
diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c
index f5decb7..0d85870 100644
--- a/src/analysis/disass/output.c
+++ b/src/analysis/disass/output.c
@@ -112,7 +112,9 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
content = g_binary_format_get_content(G_BIN_FORMAT(format));
- count = g_arch_processor_count_disassembled_instructions(proc);
+ g_arch_processor_lock(proc);
+
+ count = g_arch_processor_count_instructions(proc);
id = gtk_status_stack_add_activity(status, _("Printing all disassebled parts..."), count);
@@ -120,7 +122,7 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
for (i = 0; i < count; i++)
{
- instr = g_arch_processor_get_disassembled_instruction(proc, i);
+ instr = g_arch_processor_get_instruction(proc, i);
iaddr = get_mrange_addr(g_arch_instruction_get_range(instr));
@@ -322,12 +324,16 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA
g_code_buffer_append_new_line(buffer, line);
+ g_object_unref(G_OBJECT(instr));
+
gtk_status_stack_update_activity_value(status, id, 1);
}
gtk_status_stack_remove_activity(status, id);
+ g_arch_processor_unlock(proc);
+
g_object_unref(G_OBJECT(content));
if (portions != NULL)
diff --git a/src/analysis/disass/routines.c b/src/analysis/disass/routines.c
index 04ef123..a9414fc 100644
--- a/src/analysis/disass/routines.c
+++ b/src/analysis/disass/routines.c
@@ -38,7 +38,7 @@ struct _GRoutinesStudy
{
GDelayedWork parent; /* A laisser en premier */
- const GArchProcessor *proc; /* Processeurs avec ses instr. */
+ GArchProcessor *proc; /* Processeurs avec ses instr. */
mrange_t *exe_ranges; /* Liste de zones exécutables */
size_t exe_count; /* Nombre de ces zones */
@@ -189,7 +189,7 @@ static void g_routines_study_finalize(GRoutinesStudy *study)
* *
******************************************************************************/
-GRoutinesStudy *g_routines_study_new(const GArchProcessor *proc, mrange_t *exe_ranges, size_t exe_count, GBinRoutine **routines, size_t count, size_t begin, size_t end, activity_id_t id, rtn_fallback_cb fallback)
+GRoutinesStudy *g_routines_study_new(GArchProcessor *proc, mrange_t *exe_ranges, size_t exe_count, GBinRoutine **routines, size_t count, size_t begin, size_t end, activity_id_t id, rtn_fallback_cb fallback)
{
GRoutinesStudy *result; /* Tâche à retourner */
diff --git a/src/analysis/disass/routines.h b/src/analysis/disass/routines.h
index 4b4e530..72df309 100644
--- a/src/analysis/disass/routines.h
+++ b/src/analysis/disass/routines.h
@@ -52,7 +52,7 @@ typedef void (* rtn_fallback_cb) (GRoutinesStudy *, size_t);
/* Crée une tâche d'étude de routines différée. */
-GRoutinesStudy *g_routines_study_new(const GArchProcessor *, mrange_t *, size_t, GBinRoutine **, size_t, size_t, size_t, activity_id_t, rtn_fallback_cb);
+GRoutinesStudy *g_routines_study_new(GArchProcessor *, mrange_t *, size_t, GBinRoutine **, size_t, size_t, size_t, activity_id_t, rtn_fallback_cb);
/* Détermine si besoin est les bornes des routines. */
void g_routines_study_compute_limits(GRoutinesStudy *, size_t);
diff --git a/src/arch/dalvik/link.c b/src/arch/dalvik/link.c
index 311f672..694ec65 100644
--- a/src/arch/dalvik/link.c
+++ b/src/arch/dalvik/link.c
@@ -151,6 +151,8 @@ void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor *
g_arch_instruction_link_with(instr, target, ILT_CASE_JUMP);
+ g_object_unref(G_OBJECT(target));
+
}
/* Autres cas */
@@ -223,6 +225,8 @@ void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor *
g_arch_instruction_link_with(instr, target, ILT_CASE_JUMP);
+ g_object_unref(G_OBJECT(target));
+
}
}
@@ -298,6 +302,9 @@ void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor *
}
+ if (switch_ins != NULL)
+ g_object_unref(G_OBJECT(switch_ins));
+
}
}
diff --git a/src/arch/instriter.c b/src/arch/instriter.c
index 0f33998..5a534d5 100644
--- a/src/arch/instriter.c
+++ b/src/arch/instriter.c
@@ -99,6 +99,83 @@ void delete_instruction_iterator(instr_iter_t *iter)
* *
* Paramètres : iter = itérateur à manipuler. *
* *
+* Description : Fournit l'instruction courante de l'itérateur. *
+* *
+* Retour : Instruction suivante trouvée, ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *get_instruction_iterator_current(instr_iter_t *iter)
+{
+ GArchInstruction *result; /* Résultat à retourner */
+
+ g_arch_processor_lock(iter->proc);
+
+ if (iter->stamp != g_arch_processor_get_stamp(iter->proc))
+ result = NULL;
+
+ else
+ {
+ if (iter->index < g_arch_processor_count_instructions(iter->proc))
+ result = g_arch_processor_get_instruction(iter->proc, iter->index);
+ else
+ result = NULL;
+
+ }
+
+ g_arch_processor_unlock(iter->proc);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : iter = itérateur à manipuler. *
+* *
+* Description : Fournit l'instruction qui en précède une autre. *
+* *
+* Retour : Instruction suivante trouvée, ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *get_instruction_iterator_prev(instr_iter_t *iter)
+{
+ GArchInstruction *result; /* Résultat à retourner */
+
+ g_arch_processor_lock(iter->proc);
+
+ if (iter->stamp != g_arch_processor_get_stamp(iter->proc))
+ result = NULL;
+
+ else
+ {
+ if (iter->index > 0)
+ result = g_arch_processor_get_instruction(iter->proc, iter->index);
+ else
+ result = NULL;
+
+ if (result != NULL)
+ iter->index--;
+
+ }
+
+ g_arch_processor_unlock(iter->proc);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : iter = itérateur à manipuler. *
+* *
* Description : Fournit l'instruction qui en suit une autre. *
* *
* Retour : Instruction suivante trouvée, ou NULL. *
@@ -118,8 +195,8 @@ GArchInstruction *get_instruction_iterator_next(instr_iter_t *iter)
else
{
- if (iter->index < g_arch_processor_count_disassembled_instructions(iter->proc))
- result = g_arch_processor_get_disassembled_instruction(iter->proc, iter->index);
+ if (iter->index < g_arch_processor_count_instructions(iter->proc))
+ result = g_arch_processor_get_instruction(iter->proc, iter->index);
else
result = NULL;
diff --git a/src/arch/instriter.h b/src/arch/instriter.h
index b9c7621..74e853d 100644
--- a/src/arch/instriter.h
+++ b/src/arch/instriter.h
@@ -42,6 +42,12 @@ instr_iter_t *create_instruction_iterator(GArchProcessor *, size_t);
/* Détruit un itérateur mis en place. */
void delete_instruction_iterator(instr_iter_t *);
+/* Fournit l'instruction courante de l'itérateur. */
+GArchInstruction *get_instruction_iterator_current(instr_iter_t *);
+
+/* Fournit l'instruction qui en précède une autre. */
+GArchInstruction *get_instruction_iterator_prev(instr_iter_t *);
+
/* Fournit l'instruction qui en suit une autre. */
GArchInstruction *get_instruction_iterator_next(instr_iter_t *);
diff --git a/src/arch/link.c b/src/arch/link.c
index 4519bc5..e5406da 100644
--- a/src/arch/link.c
+++ b/src/arch/link.c
@@ -66,7 +66,10 @@ void handle_jump_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcCon
target = g_arch_processor_find_instr_by_address(proc, &addr);
if (target != NULL)
+ {
g_arch_instruction_link_with(instr, target, ILT_JUMP);
+ g_object_unref(G_OBJECT(target));
+ }
}
@@ -94,8 +97,8 @@ void handle_branch_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcC
GArchOperand *op; /* Opérande numérique en place */
virt_t virt; /* Adresse virtuelle */
vmpa2t addr; /* Adresse de destination */
+ instr_iter_t *iter; /* Parcours d'instructions */
GArchInstruction *target; /* Ligne visée par la référence*/
- GArchInstruction *list; /* Ensemble des instructions */
assert(g_arch_instruction_count_operands(instr) > index);
@@ -114,24 +117,34 @@ void handle_branch_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcC
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);
+ iter = g_arch_processor_get_iter_from_address(proc, &addr);
- if (target != NULL)
+ if (iter != NULL)
{
- g_arch_instruction_link_with(instr, target, ILT_JUMP_IF_TRUE);
+ target = get_instruction_iterator_current(iter);
+
+ if (target != NULL)
+ {
+ g_arch_instruction_link_with(instr, target, ILT_JUMP_IF_TRUE);
- list = g_arch_processor_get_disassembled_instructions(proc);
+ g_object_unref(G_OBJECT(target));
- target = g_arch_instruction_get_next_iter(list, instr, ~0);
+ }
+
+ target = get_instruction_iterator_next(iter);
if (target != NULL)
+ {
g_arch_instruction_link_with(instr, target, ILT_JUMP_IF_FALSE);
+ g_object_unref(G_OBJECT(target));
+
+ }
+
+ delete_instruction_iterator(iter);
+
}
}
@@ -174,7 +187,10 @@ void handle_call_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcCon
target = g_arch_processor_find_instr_by_address(proc, &addr);
if (target != NULL)
+ {
g_arch_instruction_link_with(instr, target, ILT_CALL);
+ g_object_unref(G_OBJECT(target));
+ }
}
diff --git a/src/arch/processor.c b/src/arch/processor.c
index 26c7170..24e2db6 100644
--- a/src/arch/processor.c
+++ b/src/arch/processor.c
@@ -78,6 +78,8 @@ static void g_arch_processor_add_new_coverage(GArchProcessor *, GArchInstruction
/* Termine la définition d'un nouveau groupe d'instructions. */
static void g_arch_processor_finish_last_coverage(GArchProcessor *, GArchInstruction *, size_t);
+/* Recherche rapidement un indice d'instruction via une adresse. */
+static bool g_arch_processor_find_covered_index_by_address(const GArchProcessor *, const instr_coverage *, const vmpa2t *, bool, size_t *);
@@ -375,89 +377,28 @@ void g_arch_processor_lock_unlock(GArchProcessor *proc, bool state)
unsigned int g_arch_processor_get_stamp(const GArchProcessor *proc)
{
- //assert(g_atomic_int_get(&proc->locked) == 1);
-
return proc->stamp;
}
-
-/* ---------------------------------------------------------------------------------- */
-/* MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-* *
-* Paramètres : proc = architecture à comléter par la procédure. *
-* first = première instruction d'un nouveau groupe. *
-* start = indice de cette instruction dans l'ensemble global. *
-* *
-* Description : Démarre la définition d'un nouveau groupe d'instructions. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_arch_processor_add_new_coverage(GArchProcessor *proc, GArchInstruction *first, size_t start)
-{
- instr_coverage *coverage; /* Couverture à définir */
- const mrange_t *irange; /* Couverture de l'instruction */
-
- /* Mise à disposition de d'avantage d'espace */
- if (proc->cov_allocated == proc->cov_count)
- {
- proc->cov_allocated += INSTR_ALLOC_BLOCK;
-
- proc->coverages = (instr_coverage *)realloc(proc->coverages,
- proc->cov_allocated * sizeof(instr_coverage));
-
- }
-
- coverage = &proc->coverages[proc->cov_count++];
-
- irange = g_arch_instruction_get_range(first);
-
- init_mrange(&coverage->range, get_mrange_addr(irange), 0);
-
- coverage->start = start;
-
-}
-
-
/******************************************************************************
* *
-* Paramètres : proc = architecture à comléter par la procédure. *
-* last = dernière instruction d'un nouveau groupe. *
-* end = indice de cette instruction dans l'ensemble global. *
+* Paramètres : proc = architecture visée par la procédure. *
* *
-* Description : Termine la définition d'un nouveau groupe d'instructions. *
+* Description : Compte le nombre d'instructions représentées. *
* *
-* Retour : - *
+* Retour : Nombre d'instructions présentes. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void g_arch_processor_finish_last_coverage(GArchProcessor *proc, GArchInstruction *last, size_t end)
+size_t g_arch_processor_count_instructions(const GArchProcessor *proc)
{
- instr_coverage *coverage; /* Couverture à définir */
- const mrange_t *irange; /* Couverture de l'instruction */
- phys_t diff; /* Ecart entre les extrémités */
-
- coverage = &proc->coverages[proc->cov_count - 1];
-
- irange = g_arch_instruction_get_range(last);
-
- diff = compute_vmpa_diff(get_mrange_addr(&coverage->range), get_mrange_addr(irange));
- diff += get_mrange_length(irange);
+ assert(g_atomic_int_get(&proc->locked) == 1);
- set_mrange_length(&coverage->range, diff);
-
- coverage->count = end - coverage->start + 1;
+ return proc->instr_count;
}
@@ -523,70 +464,117 @@ void g_arch_processor_set_disassembled_instructions(GArchProcessor *proc, GArchI
/******************************************************************************
* *
* Paramètres : proc = architecture visée par la procédure. *
+* index = indice de l'instruction visée. *
* *
-* Description : Fournit les instructions désassemblées pour une architecture.*
+* Description : Fournit une instruction désassemblée pour une architecture. *
* *
-* Retour : Liste des instructions désassemblées ou NULL si aucune. *
+* Retour : Instructions désassemblée trouvée ou NULL si aucune. *
* *
* Remarques : - *
* *
******************************************************************************/
-GArchInstruction *g_arch_processor_get_disassembled_instructions(const GArchProcessor *proc)
+GArchInstruction *g_arch_processor_get_instruction(const GArchProcessor *proc, size_t index)
{
- return (proc->instr_count > 0 ? proc->instructions[0] : NULL);
+ GArchInstruction *result; /* Instruction à retourner */
+
+ assert(g_atomic_int_get(&proc->locked) == 1);
+
+ if (proc->instr_count == 0)
+ result = NULL;
+
+ else
+ {
+ assert(index < proc->instr_count);
+
+ result = proc->instructions[index];
+
+ if (result != NULL)
+ g_object_ref(G_OBJECT(result));
+
+ }
+
+ return result;
}
+
+/* ---------------------------------------------------------------------------------- */
+/* MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES */
+/* ---------------------------------------------------------------------------------- */
+
+
/******************************************************************************
* *
-* Paramètres : proc = architecture visée par la procédure. *
-* index = indice de l'instruction visée. *
+* Paramètres : proc = architecture à comléter par la procédure. *
+* first = première instruction d'un nouveau groupe. *
+* start = indice de cette instruction dans l'ensemble global. *
* *
-* Description : Fournit une instruction désassemblée pour une architecture. *
+* Description : Démarre la définition d'un nouveau groupe d'instructions. *
* *
-* Retour : Instructions désassemblée trouvée ou NULL si aucune. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-GArchInstruction *g_arch_processor_get_disassembled_instruction(const GArchProcessor *proc, size_t index)
+static void g_arch_processor_add_new_coverage(GArchProcessor *proc, GArchInstruction *first, size_t start)
{
- GArchInstruction *result; /* Instruction à retourner */
-
- if (proc->instr_count == 0)
- result = NULL;
+ instr_coverage *coverage; /* Couverture à définir */
+ const mrange_t *irange; /* Couverture de l'instruction */
- else
+ /* Mise à disposition de d'avantage d'espace */
+ if (proc->cov_allocated == proc->cov_count)
{
- assert(index < proc->instr_count);
+ proc->cov_allocated += INSTR_ALLOC_BLOCK;
- result = proc->instructions[index];
+ proc->coverages = (instr_coverage *)realloc(proc->coverages,
+ proc->cov_allocated * sizeof(instr_coverage));
}
- return result;
+ coverage = &proc->coverages[proc->cov_count++];
+
+ irange = g_arch_instruction_get_range(first);
+
+ init_mrange(&coverage->range, get_mrange_addr(irange), 0);
+
+ coverage->start = start;
}
/******************************************************************************
* *
-* Paramètres : proc = architecture visée par la procédure. *
+* Paramètres : proc = architecture à comléter par la procédure. *
+* last = dernière instruction d'un nouveau groupe. *
+* end = indice de cette instruction dans l'ensemble global. *
* *
-* Description : Compte le nombre d'instructions représentées. *
+* Description : Termine la définition d'un nouveau groupe d'instructions. *
* *
-* Retour : Nombre d'instructions présentes. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-size_t g_arch_processor_count_disassembled_instructions(const GArchProcessor *proc)
+static void g_arch_processor_finish_last_coverage(GArchProcessor *proc, GArchInstruction *last, size_t end)
{
- return proc->instr_count;
+ instr_coverage *coverage; /* Couverture à définir */
+ const mrange_t *irange; /* Couverture de l'instruction */
+ phys_t diff; /* Ecart entre les extrémités */
+
+ coverage = &proc->coverages[proc->cov_count - 1];
+
+ irange = g_arch_instruction_get_range(last);
+
+ diff = compute_vmpa_diff(get_mrange_addr(&coverage->range), get_mrange_addr(irange));
+ diff += get_mrange_length(irange);
+
+ set_mrange_length(&coverage->range, diff);
+
+ coverage->count = end - coverage->start + 1;
}
@@ -609,6 +597,8 @@ const instr_coverage *g_arch_processor_find_coverage_by_address(const GArchProce
instr_coverage *result; /* Trouvaille à retourner */
void *ptr; /* Résultat des recherches */
+ // TODO : assert locked !
+
int search_for_coverage_by_addr(const vmpa2t *a, const instr_coverage *c)
{
int status; /* Bilan d'une comparaison */
@@ -631,6 +621,72 @@ const instr_coverage *g_arch_processor_find_coverage_by_address(const GArchProce
/******************************************************************************
* *
+* Paramètres : proc = processeur recensant diverses instructions. *
+* coverage = zone de couverture fine à fouiller. *
+* addr = position en mémoire ou physique à chercher. *
+* nearby = la recherche s'effectue-t-elle de façon stricte ? *
+* index = indice de l'instruction trouvée. [OUT] *
+* *
+* Description : Recherche rapidement un indice d'instruction via une adresse.*
+* *
+* Retour : Validité de l'indice fourni. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_arch_processor_find_covered_index_by_address(const GArchProcessor *proc, const instr_coverage *coverage, const vmpa2t *addr, bool nearby, size_t *index)
+{
+ bool result; /* Bilan à faire remonter */
+ void *ptr; /* Résultat des recherches */
+ __compar_fn_t fn; /* Fonction auxiliaire adaptée */
+
+ assert(g_atomic_int_get(&proc->locked) == 1);
+
+ int search_for_instr_by_addr(const vmpa2t *a, const GArchInstruction **b)
+ {
+ const mrange_t *range_b; /* Emplacement pour l'instr. B */
+
+ range_b = g_arch_instruction_get_range(*b);
+
+ return cmp_vmpa(a, get_mrange_addr(range_b));
+
+ }
+
+ int search_for_instr_by_nearby_addr(const vmpa2t *a, const GArchInstruction **b)
+ {
+ const mrange_t *range_b; /* Emplacement pour l'instr. B */
+
+ range_b = g_arch_instruction_get_range(*b);
+
+ return cmp_mrange_with_vmpa(range_b, a);
+
+ }
+
+ if (nearby)
+ fn = (__compar_fn_t)search_for_instr_by_nearby_addr;
+ else
+ fn = (__compar_fn_t)search_for_instr_by_addr;
+
+ ptr = bsearch(addr, &proc->instructions[coverage->start], coverage->count,
+ sizeof(GArchInstruction *), fn);
+
+ if (ptr == NULL)
+ result = false;
+
+ else
+ {
+ result = true;
+ *index = ((GArchInstruction **)ptr) - proc->instructions;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : proc = processeur recensant diverses instructions. *
* addr = position en mémoire ou physique à chercher. *
* nearby = la recherche s'effectue-t-elle de façon stricte ? *
@@ -643,11 +699,13 @@ const instr_coverage *g_arch_processor_find_coverage_by_address(const GArchProce
* *
******************************************************************************/
-GArchInstruction *_g_arch_processor_find_instr_by_address(const GArchProcessor *proc, const vmpa2t *addr, bool nearby)
+GArchInstruction *_g_arch_processor_find_instr_by_address(GArchProcessor *proc, const vmpa2t *addr, bool nearby)
{
GArchInstruction *result; /* Trouvaille à retourner */
const instr_coverage *coverage; /* Couverture fine à fouiller */
+ g_arch_processor_lock(proc);
+
coverage = g_arch_processor_find_coverage_by_address(proc, addr);
if (coverage != NULL)
@@ -655,6 +713,8 @@ GArchInstruction *_g_arch_processor_find_instr_by_address(const GArchProcessor *
else
result = NULL;
+ g_arch_processor_unlock(proc);
+
return result;
}
@@ -678,92 +738,83 @@ GArchInstruction *_g_arch_processor_find_instr_by_address(const GArchProcessor *
GArchInstruction *_g_arch_processor_find_covered_instr_by_address(const GArchProcessor *proc, const instr_coverage *coverage, const vmpa2t *addr, bool nearby)
{
GArchInstruction *result; /* Trouvaille à retourner */
- void *ptr; /* Résultat des recherches */
- __compar_fn_t fn; /* Fonction auxiliaire adaptée */
+ size_t index; /* Indice d'instruction visée */
+ bool valid; /* Validité de l'indice */
- int search_for_instr_by_addr(const vmpa2t *a, const GArchInstruction **b)
- {
- const mrange_t *range_b; /* Emplacement pour l'instr. B */
-
- range_b = g_arch_instruction_get_range(*b);
-
- return cmp_vmpa(a, get_mrange_addr(range_b));
-
- }
-
- int search_for_instr_by_nearby_addr(const vmpa2t *a, const GArchInstruction **b)
- {
- const mrange_t *range_b; /* Emplacement pour l'instr. B */
-
- range_b = g_arch_instruction_get_range(*b);
-
- return cmp_mrange_with_vmpa(range_b, a);
+ valid = g_arch_processor_find_covered_index_by_address(proc, coverage, addr, nearby, &index);
- }
-
- if (nearby)
- fn = (__compar_fn_t)search_for_instr_by_nearby_addr;
+ if (valid)
+ result = g_arch_processor_get_instruction(proc, index);
else
- fn = (__compar_fn_t)search_for_instr_by_addr;
-
- ptr = bsearch(addr, &proc->instructions[coverage->start], coverage->count,
- sizeof(GArchInstruction *), fn);
-
- result = (ptr != NULL ? *((GArchInstruction **)ptr) : NULL);
+ result = NULL;
return result;
}
-
+
/******************************************************************************
* *
-* Paramètres : proc = processeur recensant diverses instructions. *
-* instr = instruction de référence pour un parcours. *
+* Paramètres : proc = processeur recensant diverses instructions. *
+* addr = position en mémoire ou physique à chercher. *
+* nearby = la recherche s'effectue-t-elle de façon stricte ? *
* *
-* Description : Fournit l'instruction qui en précède une autre. *
+* Description : Met en place un itérateur d'instruction selon une adresse. *
* *
-* Retour : Instruction précédente trouvée, ou NULL. *
+* Retour : Itérateur mis en place, ou NULL si l'opération est un échec. *
* *
* Remarques : - *
* *
******************************************************************************/
-GArchInstruction *g_arch_processor_get_prev_instr(const GArchProcessor *proc, const GArchInstruction *instr)
+instr_iter_t *_g_arch_processor_get_iter_from_address(GArchProcessor *proc, const vmpa2t *addr, bool nearby)
{
- GArchInstruction *result; /* Instruction à retourner */
- GArchInstruction *list; /* Ensemble des instructions */
+ instr_iter_t *result; /* Itérateur à retourner */
+ const instr_coverage *coverage; /* Couverture fine à fouiller */
+
+ g_arch_processor_lock(proc);
+
+ coverage = g_arch_processor_find_coverage_by_address(proc, addr);
- list = g_arch_processor_get_disassembled_instructions(proc);
+ if (coverage != NULL)
+ result = _g_arch_processor_get_covered_iter_from_address(proc, coverage, addr, nearby);
+ else
+ result = NULL;
- result = g_arch_instruction_get_prev_iter(list, instr);
+ g_arch_processor_unlock(proc);
return result;
}
-
+
/******************************************************************************
* *
-* Paramètres : proc = processeur recensant diverses instructions. *
-* instr = instruction de référence pour un parcours. *
+* Paramètres : proc = processeur recensant diverses instructions. *
+* coverage = zone de couverture fine à fouiller. *
+* addr = position en mémoire ou physique à chercher. *
+* nearby = la recherche s'effectue-t-elle de façon stricte ? *
* *
-* Description : Fournit l'instruction qui en suit une autre. *
+* Description : Met en place un itérateur d'instruction selon une adresse. *
* *
-* Retour : Instruction suivante trouvée, ou NULL. *
+* Retour : Itérateur mis en place, ou NULL si l'opération est un échec. *
* *
* Remarques : - *
* *
******************************************************************************/
-GArchInstruction *g_arch_processor_get_next_instr(const GArchProcessor *proc, const GArchInstruction *instr)
+instr_iter_t *_g_arch_processor_get_covered_iter_from_address(GArchProcessor *proc, const instr_coverage *coverage, const vmpa2t *addr, bool nearby)
{
- GArchInstruction *result; /* Instruction à retourner */
- GArchInstruction *list; /* Ensemble des instructions */
+ instr_iter_t *result; /* Itérateur à retourner */
+ size_t index; /* Indice d'instruction visée */
+ bool valid; /* Validité de l'indice */
- list = g_arch_processor_get_disassembled_instructions(proc);
+ valid = g_arch_processor_find_covered_index_by_address(proc, coverage, addr, nearby, &index);
- result = g_arch_instruction_get_next_iter(list, instr, ~0);
+ if (valid)
+ result = create_instruction_iterator(proc, index);
+ else
+ result = NULL;
return result;
diff --git a/src/arch/processor.h b/src/arch/processor.h
index 02b3533..05ea77a 100644
--- a/src/arch/processor.h
+++ b/src/arch/processor.h
@@ -29,6 +29,7 @@
#include "context.h"
+#include "instriter.h"
#include "instruction.h"
#include "../common/endianness.h"
#include "../format/executable.h"
@@ -86,47 +87,62 @@ void g_arch_processor_lock_unlock(GArchProcessor *, bool);
/* Fournit la marque de dernière modification des instructions. */
unsigned int g_arch_processor_get_stamp(const GArchProcessor *);
+/* Compte le nombre d'instructions représentées. */
+size_t g_arch_processor_count_instructions(const GArchProcessor *);
+/* Note les instructions désassemblées avec une architecture. */
+void g_arch_processor_set_disassembled_instructions(GArchProcessor *, GArchInstruction *);
-/* ------------------ MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES ------------------ */
-
+/* Fournit une instruction désassemblée pour une architecture. */
+GArchInstruction *g_arch_processor_get_instruction(const GArchProcessor *, size_t);
-/* Couverture d'un groupe d'instructions */
-typedef struct _instr_coverage instr_coverage;
-/* Note les instructions désassemblées avec une architecture. */
-void g_arch_processor_set_disassembled_instructions(GArchProcessor *, GArchInstruction *);
+/* ------------------ MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES ------------------ */
-/* Fournit les instructions désassemblées pour une architecture. */
-GArchInstruction *g_arch_processor_get_disassembled_instructions(const GArchProcessor *);
-/* Fournit une instruction désassemblée pour une architecture. */
-GArchInstruction *g_arch_processor_get_disassembled_instruction(const GArchProcessor *, size_t);
+/* Couverture d'un groupe d'instructions */
+typedef struct _instr_coverage instr_coverage;
-/* Compte le nombre d'instructions représentées. */
-size_t g_arch_processor_count_disassembled_instructions(const GArchProcessor *);
/* Recherche un groupe d'instruction d'après son adresse. */
const instr_coverage *g_arch_processor_find_coverage_by_address(const GArchProcessor *, const vmpa2t *);
/* Recherche une instruction d'après son adresse. */
-GArchInstruction *_g_arch_processor_find_instr_by_address(const GArchProcessor *, const vmpa2t *, bool);
+GArchInstruction *_g_arch_processor_find_instr_by_address(GArchProcessor *, const vmpa2t *, bool);
/* Recherche rapidement une instruction d'après son adresse. */
GArchInstruction *_g_arch_processor_find_covered_instr_by_address(const GArchProcessor *, const instr_coverage *, const vmpa2t *, bool);
-#define g_arch_processor_find_instr_by_address(proc, addr) \
+#define g_arch_processor_find_instr_by_address(proc, addr) \
_g_arch_processor_find_instr_by_address(proc, addr, false)
-#define g_arch_processor_find_covered_instr_by_address(proc, coverage, addr) \
- _g_arch_processor_find_covered_instr_by_address(proc, coverage, addr, false)
-
-/* Fournit l'instruction qui en précède une autre. */
-GArchInstruction *g_arch_processor_get_prev_instr(const GArchProcessor *, const GArchInstruction *);
-
-/* Fournit l'instruction qui en suit une autre. */
-GArchInstruction *g_arch_processor_get_next_instr(const GArchProcessor *, const GArchInstruction *);
+#define g_arch_processor_find_covered_instr_by_address(proc, coverage, addr) \
+ ({ \
+ GArchInstruction *__result; \
+ g_arch_processor_lock(proc); \
+ __result = _g_arch_processor_find_covered_instr_by_address(proc, coverage, addr, false); \
+ g_arch_processor_unlock(proc); \
+ __result; \
+ })
+
+/* Met en place un itérateur d'instruction selon une adresse. */
+instr_iter_t *_g_arch_processor_get_iter_from_address(GArchProcessor *, const vmpa2t *, bool);
+
+/* Met en place un itérateur d'instruction selon une adresse. */
+instr_iter_t *_g_arch_processor_get_covered_iter_from_address(GArchProcessor *, const instr_coverage *, const vmpa2t *, bool);
+
+#define g_arch_processor_get_iter_from_address(proc, addr) \
+ _g_arch_processor_get_iter_from_address(proc, addr, false)
+
+#define g_arch_processor_get_covered_iter_from_address(proc, coverage, addr) \
+ ({ \
+ instr_iter_t *__result; \
+ g_arch_processor_lock(proc); \
+ __result = _g_arch_processor_get_covered_iter_from_address(proc, coverage, addr, false); \
+ g_arch_processor_unlock(proc); \
+ __result; \
+ })
diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c
index d205e47..57bbec0 100644
--- a/src/gtkext/gtkgraphview.c
+++ b/src/gtkext/gtkgraphview.c
@@ -1208,11 +1208,12 @@ static void gtk_graph_view_reach_caret_limit(GtkBufferView *node, GdkScrollDirec
vmpa2t last; /* Fin d'un groupe de lignes */
const mrange_t *range; /* Couverture courante */
GArchProcessor *proc; /* Processeur pour instructions*/
- GArchInstruction *ref; /* Point de référence */
+ vmpa2t iaddr; /* Adresse du prochain saut */
+ instr_iter_t *iter; /* Boucle de parcours */
+ GArchInstruction *instr; /* Instruction à venir visiter */
#ifndef NDEBUG
bool is_return; /* Est-ce une instruc. finale ?*/
#endif
- vmpa2t iaddr; /* Position de l'instructin */
size_t i; /* Boucle de parcours */
bool updated; /* Besoin d'une mise à jour ? */
@@ -1225,7 +1226,7 @@ static void gtk_graph_view_reach_caret_limit(GtkBufferView *node, GdkScrollDirec
proc = g_loaded_binary_get_processor(GTK_DISPLAY_PANEL(view)->binary);
- ref = NULL;
+ init_vmpa(&iaddr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL);
#ifndef NDEBUG
is_return = false;
@@ -1235,42 +1236,66 @@ static void gtk_graph_view_reach_caret_limit(GtkBufferView *node, GdkScrollDirec
{
case GDK_SCROLL_LEFT:
case GDK_SCROLL_UP:
+
if (cmp_vmpa(get_mrange_addr(range), &first) != 0)
{
- ref = g_arch_processor_find_instr_by_address(proc, &first);
+ iter = g_arch_processor_get_iter_from_address(proc, &first);
+
+ if (iter != NULL)
+ {
+ instr = get_instruction_iterator_prev(iter);
+
+ if (instr != NULL)
+ {
+ /* TODO : boucler si !HAS_CODE */
+
+ if (mrange_contains_addr(range, &iaddr))
+ copy_vmpa(&iaddr, get_mrange_addr(g_arch_instruction_get_range(instr)));
- if (ref != NULL)
- ref = g_arch_processor_get_prev_instr(proc, ref);
+ g_object_unref(G_OBJECT(instr));
- /* TODO : boucler si !HAS_CODE */
+ }
- if (ref != NULL)
- copy_vmpa(&iaddr, get_mrange_addr(g_arch_instruction_get_range(ref)));
+ delete_instruction_iterator(iter);
+
+ }
}
+
break;
case GDK_SCROLL_RIGHT:
case GDK_SCROLL_DOWN:
- ref = g_arch_processor_find_instr_by_address(proc, &last);
+ iter = g_arch_processor_get_iter_from_address(proc, &last);
+ if (iter != NULL)
+ {
#ifndef NDEBUG
- if (ref != NULL)
- is_return = (g_arch_instruction_get_flags(ref) & AIF_RETURN_POINT);
+ instr = get_instruction_iterator_current(iter);
+ if (instr != NULL)
+ {
+ is_return = (g_arch_instruction_get_flags(instr) & AIF_RETURN_POINT);
+ g_object_unref(G_OBJECT(instr));
+ }
#endif
- if (ref != NULL)
- ref = g_arch_processor_get_next_instr(proc, ref);
+ instr = get_instruction_iterator_next(iter);
- /* TODO : boucler si !HAS_CODE */
+ if (instr != NULL)
+ {
+ /* TODO : boucler si !HAS_CODE */
- if (ref != NULL)
- {
- copy_vmpa(&iaddr, get_mrange_addr(g_arch_instruction_get_range(ref)));
+ copy_vmpa(&iaddr, get_mrange_addr(g_arch_instruction_get_range(instr)));
+
+ if (!mrange_contains_addr(range, &iaddr))
+ init_vmpa(&iaddr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL);
+
+ g_object_unref(G_OBJECT(instr));
+
+ }
- if (!mrange_contains_addr(range, &iaddr))
- ref = NULL;
+ delete_instruction_iterator(iter);
}
@@ -1286,7 +1311,8 @@ static void gtk_graph_view_reach_caret_limit(GtkBufferView *node, GdkScrollDirec
/* Recherche du bloc parent */
- if (ref == NULL)
+ /* FIXME : valid ! */
+ if (iaddr.physical == VMPA_NO_PHYSICAL && iaddr.virtual == VMPA_NO_VIRTUAL)
return;
for (i = 0; i < view->children_count; i++)
diff --git a/src/gui/menus/edition.c b/src/gui/menus/edition.c
index 95b4f50..da2c60f 100644
--- a/src/gui/menus/edition.c
+++ b/src/gui/menus/edition.c
@@ -384,6 +384,8 @@ static void mcb_edition_switch_numeric_operand(GtkMenuItem *menuitem, GMenuBar *
switcher = g_db_switcher_new(instr, G_IMM_OPERAND(creator), display);
+ g_object_unref(G_OBJECT(instr));
+
g_loaded_binary_add_to_collection(binary, G_DB_ITEM(switcher));
g_object_unref(G_OBJECT(proc));
@@ -492,7 +494,6 @@ static void mcb_edition_list_xrefs(GtkMenuItem *menuitem, GMenuBar *bar)
const mrange_t *range; /* Couverture en mémoire */
GLoadedBinary *binary; /* Représentation binaire */
GArchProcessor *proc; /* Processeur de l'architecture*/
- GArchInstruction *list; /* Ensemble des instructions */
GArchInstruction *instr; /* Point de croisements */
GObject *ref; /* Espace de référencements */
GtkWidget *dialog; /* Boîte de dialogue à montrer */
@@ -506,7 +507,6 @@ static void mcb_edition_list_xrefs(GtkMenuItem *menuitem, GMenuBar *bar)
binary = g_editor_item_get_current_binary(G_EDITOR_ITEM(bar));
proc = g_loaded_binary_get_processor(binary);
- list = g_arch_processor_get_disassembled_instructions(proc);
/**
* On ne peut pas se reposer sur l'espace couvert par une ligne, car il peut
@@ -518,9 +518,9 @@ static void mcb_edition_list_xrefs(GtkMenuItem *menuitem, GMenuBar *bar)
*
* instr = g_arch_instruction_find_by_range(list, range);
*
- * Il faut ainsi être plus souple.
+ * Il faut ainsi être plus souple, et se baser sur l'adresse uniquement.
*/
- instr = g_arch_instruction_find_by_address(list, get_mrange_addr(range), true);
+ instr = g_arch_processor_find_instr_by_address(proc, get_mrange_addr(range));
ref = g_editor_item_get_global_ref(G_EDITOR_ITEM(bar));
@@ -538,6 +538,9 @@ static void mcb_edition_list_xrefs(GtkMenuItem *menuitem, GMenuBar *bar)
gtk_widget_destroy(dialog);
+ if (instr != NULL)
+ g_object_unref(G_OBJECT(instr));
+
g_object_unref(G_OBJECT(proc));
g_object_unref(G_OBJECT(line));
diff --git a/src/gui/panels/strings.c b/src/gui/panels/strings.c
index 4f919b1..b8631b6 100644
--- a/src/gui/panels/strings.c
+++ b/src/gui/panels/strings.c
@@ -1030,7 +1030,6 @@ static void mcb_strings_panel_find_refs(GtkMenuItem *menuitem, GStringsPanel *pa
const mrange_t *range; /* Couverture en mémoire */
GLoadedBinary *binary; /* Représentation binaire */
GArchProcessor *proc; /* Processeur de l'architecture*/
- GArchInstruction *list; /* Ensemble des instructions */
GArchInstruction *instr; /* Point de croisements */
GObject *ref; /* Espace de référencements */
GtkWidget *dialog; /* Boîte de dialogue à montrer */
@@ -1044,13 +1043,12 @@ static void mcb_strings_panel_find_refs(GtkMenuItem *menuitem, GStringsPanel *pa
binary = g_editor_item_get_current_binary(G_EDITOR_ITEM(panel));
proc = g_loaded_binary_get_processor(binary);
- list = g_arch_processor_get_disassembled_instructions(proc);
/**
* Se rapporter aux commentaires de mcb_edition_list_xrefs() pour les questions
* concernant l'usage d'une adresse d'instruction au lieu de son emplacement.
*/
- instr = g_arch_instruction_find_by_address(list, get_mrange_addr(range), true);
+ instr = g_arch_processor_find_instr_by_address(proc, get_mrange_addr(range));
ref = g_editor_item_get_global_ref(G_EDITOR_ITEM(panel));
@@ -1069,6 +1067,9 @@ static void mcb_strings_panel_find_refs(GtkMenuItem *menuitem, GStringsPanel *pa
gtk_widget_destroy(dialog);
+ if (instr != NULL)
+ g_object_unref(G_OBJECT(instr));
+
g_object_unref(G_OBJECT(proc));
g_object_unref(G_OBJECT(symbol));
diff --git a/src/gui/status.c b/src/gui/status.c
index b6e8fe6..fc8eafd 100644
--- a/src/gui/status.c
+++ b/src/gui/status.c
@@ -269,6 +269,8 @@ static void focus_address_in_status_info(GStatusInfo *info, GLoadedBinary *binar
gtk_status_stack_update_current_instruction(GTK_STATUS_STACK(item->widget), binary, instr);
+ g_object_unref(G_OBJECT(instr));
+
g_object_unref(G_OBJECT(proc));
}