summaryrefslogtreecommitdiff
path: root/src/analysis
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-06-24 20:08:13 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-06-24 20:08:13 (GMT)
commit1c0e64604b6c49c413f1be02b40071820007c774 (patch)
tree81b084264c9f8db9712979ab030ad36d85c2b58d /src/analysis
parent0becef388e9a68ab716583758ade15f8d8ca0cf9 (diff)
Used more threads to disassemble binary areas.
Diffstat (limited to 'src/analysis')
-rw-r--r--src/analysis/disass/area.c214
-rw-r--r--src/analysis/disass/area.h6
-rw-r--r--src/analysis/disass/fetch.c12
3 files changed, 173 insertions, 59 deletions
diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c
index 7050c9c..65024b2 100644
--- a/src/analysis/disass/area.c
+++ b/src/analysis/disass/area.c
@@ -99,13 +99,13 @@ static GArchInstruction *load_raw_instruction_from_mem_area(mem_area *, phys_t,
static void update_address_as_routine(GBinFormat *, const vmpa2t *);
/* Procède au désassemblage d'un contenu binaire non exécutable. */
-static void load_data_from_mem_area(mem_area *, GProcContext *, const vmpa2t *, GtkStatusStack *, activity_id_t);
+static void load_data_from_mem_area(mem_area *, const vmpa2t *, GtkStatusStack *, activity_id_t);
/* S'assure qu'une aire contient toutes ses instructions. */
static void fill_mem_area_with_code(mem_area *, mem_area *, size_t, GProcContext *, GtkStatusStack *, activity_id_t);
/* S'assure qu'une aire contient toutes ses instructions. */
-static void fill_mem_area_with_data(mem_area *, mem_area *, size_t, GProcContext *, GtkStatusStack *, activity_id_t);
+static void fill_mem_area_with_data(mem_area *, mem_area *, size_t, GtkStatusStack *, activity_id_t);
/* Rassemble les instructions conservées dans une zone donnée. */
static GArchInstruction **get_instructions_from_mem_area(const mem_area *, GArchInstruction **, size_t *);
@@ -173,6 +173,17 @@ typedef struct _GAreaCollector
struct
{
+ size_t count; /* Nombre de zones présentes */
+
+ GProcContext *ctx; /* Contexte de désassemblage */
+
+ size_t fill_start; /* Première zone à remplir */
+ size_t fill_stop; /* Première zone à écarter */
+
+ };
+
+ struct
+ {
size_t begin; /* Début du parcours à mener */
size_t end; /* Fin de ce même parcours */
@@ -223,6 +234,12 @@ static GAreaCollector *g_area_collector_new_insert(activity_id_t, mem_area *, si
/* Insère dans les zones contigües les instructions préchargées. */
static void g_area_collector_do_insert(GAreaCollector *, GtkStatusStack *);
+/* Crée une tâche de fin de désassemblage pour zones binaires. */
+static GAreaCollector *g_area_collector_new_filling(activity_id_t, mem_area *, size_t, GProcContext *, size_t, size_t);
+
+/* Remplit de code ou de données une série de zones. */
+static void g_area_collector_do_fill(GAreaCollector *, GtkStatusStack *);
+
/* Crée une tâche de récupération d'instructions différée. */
static GAreaCollector *g_area_collector_new_outro(activity_id_t, mem_area *, size_t, size_t);
@@ -803,7 +820,6 @@ void load_code_from_mem_area(mem_area *area, mem_area *list, size_t count, GProc
/******************************************************************************
* *
* Paramètres : area = aire représentant à contenu à parcourir. *
-* ctx = contexte offert en soutien à un désassemblage. *
* start = démarrage de l'exécution au sein de la zone. *
* status = barre de statut à actualiser. *
* id = identifiant du groupe de progression à l'affichage. *
@@ -816,7 +832,7 @@ void load_code_from_mem_area(mem_area *area, mem_area *list, size_t count, GProc
* *
******************************************************************************/
-static void load_data_from_mem_area(mem_area *area, GProcContext *ctx, const vmpa2t *start, GtkStatusStack *status, activity_id_t id)
+static void load_data_from_mem_area(mem_area *area, const vmpa2t *start, GtkStatusStack *status, activity_id_t id)
{
phys_t diff; /* Volume de données traité */
phys_t alen; /* Taille de l'aire utilisée */
@@ -935,8 +951,6 @@ static void fill_mem_area_with_code(mem_area *area, mem_area *list, size_t count
* Paramètres : area = aire représentant à contenu à parcourir. *
* list = liste de zones délimitant des contenus à traiter. *
* count = nombre de zones à disposition. *
-* binary = représentation de binaire chargé. *
-* ctx = contexte offert en soutien à un désassemblage. *
* status = barre de statut à actualiser. *
* id = identifiant du groupe de progression à l'affichage. *
* *
@@ -948,7 +962,7 @@ static void fill_mem_area_with_code(mem_area *area, mem_area *list, size_t count
* *
******************************************************************************/
-static void fill_mem_area_with_data(mem_area *area, mem_area *list, size_t count, GProcContext *ctx, GtkStatusStack *status, activity_id_t id)
+static void fill_mem_area_with_data(mem_area *area, mem_area *list, size_t count, GtkStatusStack *status, activity_id_t id)
{
const vmpa2t *addr; /* Début de la zone à traiter */
phys_t len; /* Taille de la zone à remplir */
@@ -977,7 +991,7 @@ static void fill_mem_area_with_data(mem_area *area, mem_area *list, size_t count
}
- load_data_from_mem_area(area, ctx, &start, status, id);
+ load_data_from_mem_area(area, &start, status, id);
}
@@ -1524,38 +1538,6 @@ static void insert_instr_into_mem_areas_forced(mem_area *areas, size_t count, GA
}
-/******************************************************************************
-* *
-* Paramètres : areas = liste de zones délimitant des contenus à traiter. *
-* count = nombre de zones à disposition. *
-* code = nature des instructions à utiliser pour le comble. *
-* ctx = contexte offert en soutien à un désassemblage. *
-* status = barre de statut à actualiser. *
-* id = identifiant du groupe de progression à l'affichage. *
-* *
-* Description : S'assure que l'ensemble des aires est entièrement décodé. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void ensure_all_mem_areas_are_filled(mem_area *areas, size_t count, bool code, GProcContext *ctx, GtkStatusStack *status, activity_id_t id)
-{
- size_t i; /* Boucle de parcours */
-
- if (code)
- for (i = 0; i < count; i++)
- fill_mem_area_with_code(&areas[i], areas, count, ctx, status, id);
-
- else
- for (i = 0; i < count; i++)
- fill_mem_area_with_data(&areas[i], areas, count, ctx, status, id);
-
-}
-
-
/* ---------------------------------------------------------------------------------- */
/* MANIPULATIONS PARALLELES DES ZONES */
@@ -1633,6 +1615,12 @@ static void g_area_collector_dispose(GAreaCollector *collector)
else if (collector->run == (run_task_fc)g_area_collector_do_insert)
g_object_unref(G_OBJECT(collector->info));
+ else if (collector->run == (run_task_fc)g_area_collector_do_fill)
+ {
+ if (collector->ctx != NULL)
+ g_object_unref(G_OBJECT(collector->ctx));
+ }
+
G_OBJECT_CLASS(g_area_collector_parent_class)->dispose(G_OBJECT(collector));
}
@@ -1744,8 +1732,8 @@ static GAreaCollector *g_area_collector_new_intro(activity_id_t id, GLoadedBinar
/******************************************************************************
* *
-* Paramètres : fetching = récupération à mener. *
-* status = barre de statut à tenir informée. *
+* Paramètres : collector = opération à mener. *
+* status = barre de statut à tenir informée. *
* *
* Description : Construit une liste bornée de zones contigües. *
* *
@@ -2058,8 +2046,8 @@ static GAreaCollector *g_area_collector_new_insert(activity_id_t id, mem_area *a
/******************************************************************************
* *
-* Paramètres : fetching = récupération à mener. *
-* status = barre de statut à tenir informée. *
+* Paramètres : collector = opération à mener. *
+* status = barre de statut à tenir informée. *
* *
* Description : Insère dans les zones contigües les instructions préchargées.*
* *
@@ -2181,6 +2169,140 @@ void populate_fresh_memory_areas(wgroup_id_t gid, GtkStatusStack *status, mem_ar
/******************************************************************************
* *
* Paramètres : id = identifiant pour signaler la progression courante. *
+* areas = liste complète des zones à traiter. *
+* count = taille de cette liste. *
+* ctx = éventuel contexte pour du code ou NULL si données. *
+* start = première zone à traiter. *
+* stop = première zone à écarter. *
+* *
+* Description : Crée une tâche de fin de désassemblage pour zones binaires. *
+* *
+* Retour : Tâche créée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GAreaCollector *g_area_collector_new_filling(activity_id_t id, mem_area *areas, size_t count, GProcContext *ctx, size_t start, size_t stop)
+{
+ GAreaCollector *result; /* Tâche à retourner */
+
+ result = g_object_new(G_TYPE_AREA_COLLECTOR, NULL);
+
+ result->id = id;
+ result->run = (run_task_fc)g_area_collector_do_fill;
+
+ result->areas = areas;
+
+ result->count = count;
+
+ result->ctx = ctx;
+
+ if (ctx != NULL)
+ g_object_ref(G_OBJECT(ctx));
+
+ result->fill_start = start;
+ result->fill_stop = stop;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : collector = opération à mener. *
+* status = barre de statut à tenir informée. *
+* *
+* Description : Remplit de code ou de données une série de zones. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_area_collector_do_fill(GAreaCollector *collector, GtkStatusStack *status)
+{
+ mem_area *areas; /* Zone de productions */
+ size_t count; /* Nombre de ces zones */
+ size_t i; /* Boucle de parcours */
+
+ areas = collector->areas;
+ count = collector->count;
+
+ if (collector->ctx != NULL)
+ for (i = collector->fill_start; i < collector->fill_stop; i++)
+ fill_mem_area_with_code(&areas[i], areas, count, collector->ctx, status, collector->id);
+
+ else
+ for (i = collector->fill_start; i < collector->fill_stop; i++)
+ fill_mem_area_with_data(&areas[i], areas, count, status, collector->id);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : gid = groupe de travail impliqué. *
+* status = barre de statut à tenir informée. *
+* id = identifiant d'activité à modifier. *
+* area = nombre de zones mises en place. *
+* count = quantité de ces zones. *
+* ctx = contexte de désassemblage pour du code, ou NULL. *
+* *
+* Description : Remplit les espaces vacants des zones à désassembler. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void ensure_all_mem_areas_are_filled(wgroup_id_t gid, GtkStatusStack *status, activity_id_t id, mem_area *areas, size_t count, GProcContext *ctx)
+{
+ guint runs_count; /* Qté d'exécutions parallèles */
+ phys_t run_size; /* Volume réparti par exécution*/
+ GWorkQueue *queue; /* Gestionnaire de différés */
+ guint i; /* Boucle de parcours */
+ size_t start; /* Premier indice à traiter */
+ size_t stop; /* Premier indice à ignorer */
+ GAreaCollector *collector; /* Collecteur à lancer */
+
+ runs_count = get_max_online_threads();
+
+ run_size = count / runs_count;
+
+ queue = get_work_queue();
+
+ if (ctx != NULL)
+ gtk_status_stack_update_activity(status, id, _("Disassembling the remaining instructions..."));
+ else
+ gtk_status_stack_update_activity(status, id, _("Filling holes with data..."));
+
+ for (i = 0; i < runs_count; i++)
+ {
+ start = i * run_size;
+
+ if ((i + 1) == runs_count)
+ stop = count;
+ else
+ stop = start + run_size;
+
+ collector = g_area_collector_new_filling(id, areas, count, ctx, start, stop);
+
+ g_work_queue_schedule_work(queue, G_DELAYED_WORK(collector), gid);
+
+ }
+
+ g_work_queue_wait_for_completion(queue, gid);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : id = identifiant pour signaler la progression courante. *
* list = liste des zones en place à parcourir. *
* begin = indice de la première zone à traiter. *
* end = indice de la première zone à ne pas traiter. *
@@ -2217,8 +2339,8 @@ static GAreaCollector *g_area_collector_new_outro(activity_id_t id, mem_area *li
/******************************************************************************
* *
-* Paramètres : fetching = récupération à mener. *
-* status = barre de statut à tenir informée. *
+* Paramètres : collector = opération à mener. *
+* status = barre de statut à tenir informée. *
* *
* Description : Assure la récupération d'instructions en différé. *
* *
diff --git a/src/analysis/disass/area.h b/src/analysis/disass/area.h
index dc84277..8c143a7 100644
--- a/src/analysis/disass/area.h
+++ b/src/analysis/disass/area.h
@@ -52,9 +52,6 @@ void load_code_from_mem_area(mem_area *, mem_area *, size_t, GProcContext *, con
/* Détermine une liste de zones contigües à traiter. */
mem_area *find_memory_area_by_addr(mem_area *, size_t, const vmpa2t *);
-/* S'assure que l'ensemble des aires est entièrement décodé. */
-void ensure_all_mem_areas_are_filled(mem_area *, size_t, bool, GProcContext *, GtkStatusStack *, activity_id_t);
-
/* ----------------------- MANIPULATIONS PARALLELES DES ZONES ----------------------- */
@@ -66,6 +63,9 @@ mem_area *collect_memory_areas(wgroup_id_t, GtkStatusStack *, GLoadedBinary *, p
/* Intègre toutes les instructions préchargées dans des zones. */
void populate_fresh_memory_areas(wgroup_id_t, GtkStatusStack *, mem_area *, size_t, GPreloadInfo *);
+/* Remplit les espaces vacants des zones à désassembler. */
+void ensure_all_mem_areas_are_filled(wgroup_id_t, GtkStatusStack *, activity_id_t, mem_area *, size_t, GProcContext *);
+
/* Rassemble les instructions conservées dans des zones données. */
GArchInstruction **collect_disassembled_instructions(wgroup_id_t, GtkStatusStack *, mem_area *, size_t, size_t *);
diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c
index fc1c2ab..f179860 100644
--- a/src/analysis/disass/fetch.c
+++ b/src/analysis/disass/fetch.c
@@ -461,21 +461,13 @@ GArchInstruction **disassemble_binary_content(GLoadedBinary *binary, GProcContex
* Troisième phase : on comble les trous laissés.
*/
- gtk_status_stack_update_activity(status, template.id, _("Disassembling the remaining instructions..."));
-
- ensure_all_mem_areas_are_filled(template.areas, template.count, true, template.ctx, status, template.id);
-
- g_work_queue_wait_for_completion(queue, gid);
+ ensure_all_mem_areas_are_filled(gid, status, template.id, template.areas, template.count, template.ctx);
g_work_queue_set_extra_wait_callback(queue, gid, NULL, NULL);
g_object_set_data(G_OBJECT(template.ctx), "remaining_counter", NULL);
- gtk_status_stack_update_activity(status, template.id, _("Filling holes with data..."));
-
- ensure_all_mem_areas_are_filled(template.areas, template.count, false, template.ctx, status, template.id);
-
- g_work_queue_wait_for_completion(queue, gid);
+ ensure_all_mem_areas_are_filled(gid, status, template.id, template.areas, template.count, NULL);
gtk_status_stack_remove_activity(status, template.id);