From 1c0e64604b6c49c413f1be02b40071820007c774 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 24 Jun 2018 22:08:13 +0200 Subject: Used more threads to disassemble binary areas. --- src/analysis/disass/area.c | 214 ++++++++++++++++++++++++++++++++++---------- src/analysis/disass/area.h | 6 +- src/analysis/disass/fetch.c | 12 +-- 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); -- cgit v0.11.2-87-g4458