From 5e76e91ea41f9a7cf1a1a4a77e12277d45417e43 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Fri, 23 Dec 2016 19:44:01 +0100 Subject: Collected the loaded instructions using all available processors. --- ChangeLog | 20 ++ src/analysis/binary.c | 3 +- src/analysis/disass/area.c | 361 ++++++++++++++++++++++++++++++++++--- src/analysis/disass/area.h | 12 +- src/analysis/disass/disassembler.c | 18 +- src/analysis/disass/disassembler.h | 2 +- src/analysis/disass/fetch.c | 19 +- src/analysis/disass/fetch.h | 2 +- src/arch/processor-int.h | 3 +- src/arch/processor.c | 45 +++-- src/arch/processor.h | 2 +- 11 files changed, 404 insertions(+), 83 deletions(-) diff --git a/ChangeLog b/ChangeLog index 62a4158..abc2950 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +16-12-23 Cyrille Bagard + + * src/analysis/binary.c: + Do not save loaded instructions into the loaded binary. + + * src/analysis/disass/area.c: + * src/analysis/disass/area.h: + Collect the loaded instructions using all available processors. + + * src/analysis/disass/disassembler.c: + * src/analysis/disass/disassembler.h: + * src/analysis/disass/fetch.c: + * src/analysis/disass/fetch.h: + Update code. + + * src/arch/processor-int.h: + * src/arch/processor.c: + * src/arch/processor.h: + Update code as the instructions are already provided using an array. + 16-12-18 Cyrille Bagard * src/arch/dalvik/operands/args.c: diff --git a/src/analysis/binary.c b/src/analysis/binary.c index 61f775c..3af62cf 100644 --- a/src/analysis/binary.c +++ b/src/analysis/binary.c @@ -78,7 +78,6 @@ struct _GLoadedBinary GDbgFormat *debug; /* Informations de débogage */ //// REMME GArchProcessor *proc; /* Architecture du binaire */ - GArchInstruction *instrs; /* Instructions d'assemblage */ GCodeBuffer *disass_buffer; /* Instructions lisibles */ GCodeBuffer **dec_buffers; /* Sources sous forme de texte */ size_t decbuf_count; /* Taille des tableaux */ @@ -1378,7 +1377,7 @@ void g_loaded_binary_analyse(GLoadedBinary *binary) g_loaded_binary_connect_internal(binary); - disassemble_binary(binary, &binary->instrs, &binary->disass_buffer, ack_completed_disassembly); + disassemble_binary(binary, &binary->disass_buffer, ack_completed_disassembly); diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c index 48ac6ec..71e2784 100644 --- a/src/analysis/disass/area.c +++ b/src/analysis/disass/area.c @@ -25,6 +25,8 @@ #include +#include +#include #include @@ -34,10 +36,14 @@ #include "../../arch/raw.h" #include "../../common/bits.h" #include "../../format/format.h" +#include "../../glibext/delayed-int.h" #include "../../gui/panels/log.h" +/* ------------------------- TRAITEMENT DES ZONES DE DONNES ------------------------- */ + + /* Zone mémoire bien bornée */ typedef struct _mem_area { @@ -52,6 +58,7 @@ typedef struct _mem_area bitfield_t *processed; /* Octets traités dans la zone */ GArchInstruction **instructions; /* Instructions en place */ + size_t count; /* Quantité d'instructions */ bool is_exec; /* Zone exécutable ? */ @@ -83,8 +90,76 @@ static void load_data_from_mem_area(mem_area *, GProcContext *, const vmpa2t *, static void fill_mem_area(mem_area *, mem_area *, size_t, GProcContext *, GtkStatusStack *, activity_id_t); /* Rassemble les instructions conservées dans une zone donnée. */ -static GArchInstruction *get_instructions_from_mem_area(const mem_area *); +static GArchInstruction **get_instructions_from_mem_area(const mem_area *, GArchInstruction **, size_t *); + + + +/* ----------------------- MANIPULATIONS PARALLELES DES ZONES ----------------------- */ + + +#define G_TYPE_AREA_COLLECTOR g_area_collector_get_type() +#define G_AREA_COLLECTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_AREA_COLLECTOR, GAreaCollector)) +#define G_IS_AREA_COLLECTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_AREA_COLLECTOR)) +#define G_AREA_COLLECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_AREA_COLLECTOR, GAreaCollectorClass)) +#define G_IS_AREA_COLLECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_AREA_COLLECTOR)) +#define G_AREA_COLLECTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_AREA_COLLECTOR, GAreaCollectorClass)) + + +/* Ensembles binaires à désassembler (instance) */ +typedef struct _GAreaCollector +{ + GDelayedWork parent; /* A laisser en premier */ + + activity_id_t id; /* Groupe de progression */ + run_task_fc run; /* Activité dans la pratique */ + + mem_area *areas; /* Zone de productions */ + + size_t begin; /* Début du parcours à mener */ + size_t end; /* Fin de ce même parcours */ + + GArchInstruction **collected; /* Instructions collectées */ + size_t count; /* Quantité de ces instructions*/ + +} GAreaCollector; + +/* Ensembles binaires à désassembler (classe) */ +typedef struct _GAreaCollectorClass +{ + GDelayedWorkClass parent; /* A laisser en premier */ + +} GAreaCollectorClass; + + +/* Indique le type défini pour les tâches de traitement des zones. */ +GType g_area_collector_get_type(void); + +/* Initialise la classe des manipulations parallèles de zones. */ +static void g_area_collector_class_init(GAreaCollectorClass *); + +/* Initialise des manipulations parallèles de zones. */ +static void g_area_collector_init(GAreaCollector *); + +/* Supprime toutes les références externes. */ +static void g_area_collector_dispose(GAreaCollector *); +/* Procède à la libération totale de la mémoire. */ +static void g_area_collector_finalize(GAreaCollector *); + +/* Assure un traitement particulier concernant les zones. */ +static void g_area_collector_process(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); + +/* Assure la récupération d'instructions en différé. */ +static void g_area_collector_do_collect(GAreaCollector *, GtkStatusStack *); + + + +/* ---------------------------------------------------------------------------------- */ +/* RAITEMENT DES ZONES DE DONNES */ +/* ---------------------------------------------------------------------------------- */ /****************************************************************************** @@ -123,6 +198,7 @@ static void init_mem_area_from_addr(mem_area *area, const vmpa2t *addr, phys_t l area->processed = create_bit_field(len, false); area->instructions = (GArchInstruction **)calloc(len, sizeof(GArchInstruction *)); + area->count = 0; } @@ -226,7 +302,13 @@ static bool mark_range_in_mem_area_as_processed(mem_area *area, GArchInstruction result |= force; if (result) + { + assert(area->instructions[offset] == NULL); + area->instructions[offset] = instr; + g_atomic_pointer_add(&area->count, 1); + + } return result; @@ -642,7 +724,9 @@ static void fill_mem_area(mem_area *area, mem_area *list, size_t count, GProcCon /****************************************************************************** * * -* Paramètres : area = aire représentant à contenu à parcourir. * +* Paramètres : area = aire représentant à contenu à parcourir. * +* list = liste d'instructions à compléter. * +* count = taille de cette liste. [OUT] * * * * Description : Rassemble les instructions conservées dans une zone donnée. * * * @@ -652,17 +736,24 @@ static void fill_mem_area(mem_area *area, mem_area *list, size_t count, GProcCon * * ******************************************************************************/ -static GArchInstruction *get_instructions_from_mem_area(const mem_area *area) +static GArchInstruction **get_instructions_from_mem_area(const mem_area *area, GArchInstruction **list, size_t *count) { - GArchInstruction *result; /* Liste d'instr. à renvoyer */ + GArchInstruction **result; /* Liste d'instr. à renvoyer */ phys_t len; /* Nombre d'instructions au max*/ +#ifndef NDEBUG + size_t check; /* Verification de débordement */ +#endif phys_t i; /* Boucle de parcours */ GArchInstruction *instr; /* Instruction décodée */ - result = NULL; + result = (GArchInstruction **)realloc(list, (*count + area->count) * sizeof(GArchInstruction *)); len = get_mrange_length(&area->range); +#ifndef NDEBUG + check = 0; +#endif + for (i = 0; i < len; i++) { instr = area->instructions[i]; @@ -670,7 +761,13 @@ static GArchInstruction *get_instructions_from_mem_area(const mem_area *area) if (instr != NULL) { g_object_ref(G_OBJECT(instr)); - g_arch_instruction_add_to_list(&result, instr); + result[(*count)++] = instr; + +#ifndef NDEBUG + check++; + assert(check <= area->count); +#endif + } } @@ -1044,32 +1141,152 @@ void ensure_all_mem_areas_are_filled(mem_area *list, size_t count, GProcContext } + +/* ---------------------------------------------------------------------------------- */ +/* MANIPULATIONS PARALLELES DES ZONES */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour les tâches de traitement des zones. */ +G_DEFINE_TYPE(GAreaCollector, g_area_collector, G_TYPE_DELAYED_WORK); + + /****************************************************************************** * * -* Paramètres : list = série d'aires représentant du contenu à parcourir. * -* count = nombre de ces zones présentes. * +* Paramètres : klass = classe à initialiser. * * * -* Description : Rassemble les instructions conservées dans des zones données.* +* Description : Initialise la classe des manipulations parallèles de zones. * * * -* Retour : Liste d'instructions prêtes à emploi. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -GArchInstruction *collect_instructions_from_mem_areas(const mem_area *list, size_t count) +static void g_area_collector_class_init(GAreaCollectorClass *klass) { - GArchInstruction *result; /* Liste d'instr. à renvoyer */ - size_t i; /* Boucle de parcours */ - GArchInstruction *instr; /* Instruction(s) à insérer */ + GObjectClass *object; /* Autre version de la classe */ + GDelayedWorkClass *work; /* Version en classe parente */ - result = NULL; + object = G_OBJECT_CLASS(klass); - for (i = 0; i < count; i++) - { - instr = get_instructions_from_mem_area(&list[i]); - g_arch_instruction_merge_lists(&result, &instr); - } + object->dispose = (GObjectFinalizeFunc/* ! */)g_area_collector_dispose; + object->finalize = (GObjectFinalizeFunc)g_area_collector_finalize; + + work = G_DELAYED_WORK_CLASS(klass); + + work->run = (run_task_fc)g_area_collector_process; + +} + + +/****************************************************************************** +* * +* Paramètres : collector = instance à initialiser. * +* * +* Description : Initialise des manipulations parallèles de zones. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_area_collector_init(GAreaCollector *collector) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : collector = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_area_collector_dispose(GAreaCollector *collector) +{ + G_OBJECT_CLASS(g_area_collector_parent_class)->dispose(G_OBJECT(collector)); + +} + + +/****************************************************************************** +* * +* Paramètres : collector = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_area_collector_finalize(GAreaCollector *collector) +{ + G_OBJECT_CLASS(g_area_collector_parent_class)->finalize(G_OBJECT(collector)); + +} + + +/****************************************************************************** +* * +* Paramètres : collector = opérations à mener. * +* status = barre de statut à tenir informée. * +* * +* Description : Assure un traitement particulier concernant les zones. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_area_collector_process(GAreaCollector *collector, GtkStatusStack *status) +{ + collector->run(G_DELAYED_WORK(collector), status); + +} + + +/****************************************************************************** +* * +* 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. * +* * +* Description : Crée une tâche de récupération d'instructions différée. * +* * +* Retour : Tâche créée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GAreaCollector *g_area_collector_new_outro(activity_id_t id, mem_area *list, size_t begin, size_t end) +{ + 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_collect; + + result->areas = list; + + result->begin = begin; + result->end = end; + + result->collected = NULL; + result->count = 0; return result; @@ -1078,10 +1295,10 @@ GArchInstruction *collect_instructions_from_mem_areas(const mem_area *list, size /****************************************************************************** * * -* Paramètres : list = série d'aires représentant du contenu à libérer. * -* count = nombre de ces zones présentes. * +* Paramètres : fetching = récupération à mener. * +* status = barre de statut à tenir informée. * * * -* Description : Libère la mémoire occupée par des zones de données. * +* Description : Assure la récupération d'instructions en différé. * * * * Retour : - * * * @@ -1089,13 +1306,105 @@ GArchInstruction *collect_instructions_from_mem_areas(const mem_area *list, size * * ******************************************************************************/ -void release_mem_areas(mem_area *list, size_t count) +static void g_area_collector_do_collect(GAreaCollector *collector, GtkStatusStack *status) { size_t i; /* Boucle de parcours */ - for (i = 0; i < count; i++) - fini_mem_area(&list[i]); + for (i = collector->begin; i < collector->end; i++) + { + collector->collected = get_instructions_from_mem_area(&collector->areas[i], + collector->collected, &collector->count); + + fini_mem_area(&collector->areas[i]); + + gtk_status_stack_update_activity_value(status, collector->id, 1); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : gid = groupe de travail impliqué. * +* status = barre de statut à tenir informée. * +* list = liste des zones de données à relire puis libérer. * +* acount = taille de cette liste de zones. * +* icount = nombre d'instructions récupérées. [OUT] * +* * +* Description : Rassemble les instructions conservées dans des zones données.* +* * +* Retour : Liste d'instructions rassemblées. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction **collect_disassembled_instructions(wgroup_id_t gid, GtkStatusStack *status, mem_area *list, size_t acount, size_t *icount) +{ + GArchInstruction **result; /* Liste finale à retourner */ + guint runs_count; /* Qté d'exécutions parallèles */ + GAreaCollector **collectors; /* Collecteurs à suivre */ + size_t run_size; /* Volume réparti par exécution*/ + GWorkQueue *queue; /* Gestionnaire de différés */ + activity_id_t id; /* Identifiant de progression */ + guint i; /* Boucle de parcours */ + size_t begin; /* Début de bloc de traitement */ + size_t end; /* Fin d'un bloc de traitement */ + + runs_count = g_get_num_processors(); + + collectors = (GAreaCollector **)calloc(runs_count, sizeof(GAreaCollector *)); + + run_size = acount / runs_count; + + queue = get_work_queue(); + + id = gtk_status_stack_add_activity(status, _("Collecting all disassembled instructions"), acount); + + for (i = 0; i < runs_count; i++) + { + begin = i * run_size; + + if ((i + 1) == runs_count) + end = acount; + else + end = begin + run_size; + + collectors[i] = g_area_collector_new_outro(id, list, begin, end); + + g_object_ref(G_OBJECT(collectors[i])); + g_work_queue_schedule_work(queue, G_DELAYED_WORK(collectors[i]), gid); + + } + + g_work_queue_wait_for_completion(queue, gid); + + /* Récupération des instructions */ + + result = NULL; + *icount = 0; + + for (i = 0; i < runs_count; i++) + { + result = (GArchInstruction **)realloc(result, + (*icount + collectors[i]->count) * sizeof(GArchInstruction *)); + + memcpy(&result[*icount], collectors[i]->collected, collectors[i]->count * sizeof(GArchInstruction *)); + *icount += collectors[i]->count; + + g_object_unref(G_OBJECT(collectors[i])); + + } + + /* Fin */ + + free(collectors); free(list); + gtk_status_stack_remove_activity(status, id); + + return result; + } diff --git a/src/analysis/disass/area.h b/src/analysis/disass/area.h index 39313fd..725b9a8 100644 --- a/src/analysis/disass/area.h +++ b/src/analysis/disass/area.h @@ -32,6 +32,9 @@ +/* ------------------------- TRAITEMENT DES ZONES DE DONNES ------------------------- */ + + /* Zone mémoire bien bornée */ typedef struct _mem_area mem_area; @@ -51,11 +54,12 @@ void insert_extra_symbol_into_mem_areas(mem_area *, size_t, const GBinSymbol *); /* S'assure que l'ensemble des aires est entièrement décodé. */ void ensure_all_mem_areas_are_filled(mem_area *, size_t, GProcContext *, GtkStatusStack *, activity_id_t); -/* Rassemble les instructions conservées dans des zones données. */ -GArchInstruction *collect_instructions_from_mem_areas(const mem_area *, size_t); -/* Libère la mémoire occupée par des zones de données. */ -void release_mem_areas(mem_area *, size_t); +/* ----------------------- MANIPULATIONS PARALLELES DES ZONES ----------------------- */ + + +/* 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/disassembler.c b/src/analysis/disass/disassembler.c index f210bd1..172ee1c 100644 --- a/src/analysis/disass/disassembler.c +++ b/src/analysis/disass/disassembler.c @@ -55,7 +55,6 @@ struct _GDelayedDisassembly GLoadedBinary *binary; /* Destinataire final */ GExeFormat *format; /* Format du binaire représenté*/ - GArchInstruction **instrs; /* Instructions résultantes */ GCodeBuffer *buffer; /* Tampon pour le rendu */ }; @@ -81,7 +80,7 @@ static void g_delayed_disassembly_dispose(GDelayedDisassembly *); static void g_delayed_disassembly_finalize(GDelayedDisassembly *); /* Crée une tâche de désassemblage différé. */ -static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *, GArchInstruction **, GCodeBuffer *); +static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *, GCodeBuffer *); /* Opère sur toutes les instructions. */ static void process_all_instructions(wgroup_id_t, GtkStatusStack *, const char *, ins_fallback_cb, GArchProcessor *, GProcContext *, GExeFormat *); @@ -202,7 +201,6 @@ static void g_delayed_disassembly_finalize(GDelayedDisassembly *disass) * * * Paramètres : binary = binaire chargé en attente des résultats. * * format = format du binaire représenté. * -* instrs = emplacement pour la liste d'instructions. * * buffer = tampon de sortie pour les instructions. * * * * Description : Crée une tâche de désassemblage différé. * @@ -213,7 +211,7 @@ static void g_delayed_disassembly_finalize(GDelayedDisassembly *disass) * * ******************************************************************************/ -static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GArchInstruction **instrs, GCodeBuffer *buffer) +static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GCodeBuffer *buffer) { GDelayedDisassembly *result; /* Tâche à retourner */ @@ -222,7 +220,6 @@ static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GAr result->binary = binary; result->format = g_loaded_binary_get_format(binary); - result->instrs = instrs; result->buffer = buffer; return result; @@ -389,7 +386,8 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatus //size_t i; /* Boucle de parcours */ - + GArchInstruction **instrs; /* Instructions résultantes */ + size_t count; /* Quantité de ces instructions*/ @@ -417,10 +415,10 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatus - *disass->instrs = disassemble_binary_content(disass->binary, ctx, gid, status); + instrs = disassemble_binary_content(disass->binary, ctx, gid, status, &count); - g_arch_processor_set_disassembled_instructions(proc, *disass->instrs); + g_arch_processor_set_instructions(proc, instrs, count); // plugins ////////////////////////// @@ -739,7 +737,7 @@ static void build_disass_prologue(GCodeBuffer *buffer, const char *filename, con * * ******************************************************************************/ -void disassemble_binary(GLoadedBinary *binary, GArchInstruction **instrs, GCodeBuffer **buffer, disassembly_ack_fc ack) +void disassemble_binary(GLoadedBinary *binary, GCodeBuffer **buffer, disassembly_ack_fc ack) { GBinFormat *format; /* Format associé au binaire */ GBinContent *content; /* Contenu bianire manipulé */ @@ -759,7 +757,7 @@ void disassemble_binary(GLoadedBinary *binary, GArchInstruction **instrs, GCodeB build_disass_prologue(*buffer, g_binary_content_describe(content, true), checksum); - disass = g_delayed_disassembly_new(binary, instrs, *buffer); + disass = g_delayed_disassembly_new(binary, *buffer); g_signal_connect(disass, "work-completed", G_CALLBACK(ack), binary); queue = get_work_queue(); diff --git a/src/analysis/disass/disassembler.h b/src/analysis/disass/disassembler.h index dd9e362..9151d23 100644 --- a/src/analysis/disass/disassembler.h +++ b/src/analysis/disass/disassembler.h @@ -59,7 +59,7 @@ GType g_delayed_disassembly_get_type(void); typedef void (* disassembly_ack_fc) (GDelayedDisassembly *, GLoadedBinary *); /* Procède à la décompilation des routines d'un fichier donné. */ -void disassemble_binary(GLoadedBinary *, GArchInstruction **, GCodeBuffer **, disassembly_ack_fc); +void disassemble_binary(GLoadedBinary *, GCodeBuffer **, disassembly_ack_fc); diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c index 1a55eeb..784e103 100644 --- a/src/analysis/disass/fetch.c +++ b/src/analysis/disass/fetch.c @@ -163,8 +163,6 @@ static void g_delayed_fetching_class_init(GDelayedFetchingClass *klass) static void g_delayed_fetching_init(GDelayedFetching *fetching) { - - } @@ -384,6 +382,7 @@ static bool check_if_extra_wait_is_needed(GWorkQueue *queue, wgroup_id_t id, GPr * ctx = contexte fourni pour suivre le désassemblage. * * gid = identifiant du groupe de travail à utiliser. * * status = barre de statut avec progression à mettre à jour. * +* count = nombre d'instructions récupérées. * * * * Description : Procède au désassemblage basique d'un contenu binaire. * * * @@ -393,9 +392,9 @@ static bool check_if_extra_wait_is_needed(GWorkQueue *queue, wgroup_id_t id, GPr * * ******************************************************************************/ -GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GProcContext *ctx, wgroup_id_t gid, GtkStatusStack *status) +GArchInstruction **disassemble_binary_content(const GLoadedBinary *binary, GProcContext *ctx, wgroup_id_t gid, GtkStatusStack *status, size_t *count) { - GArchInstruction *result; /* Instruction désassemblées */ + GArchInstruction **result; /* Instruction désassemblées */ GDelayedFetching template; /* Patron des tâches à venir */ GBinFormat *format; /* Format du fichier binaire */ GBinContent *content; /* Contenu binaire à manipuler */ @@ -462,22 +461,18 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GProcC g_object_set_data(G_OBJECT(template.ctx), "remaining_counter", NULL); + gtk_status_stack_remove_activity(status, template.id); + /** * Troisième et dernière phase : récolte des fruits. */ - gtk_status_stack_update_activity(status, template.id, _("Collecting disassembled instructions...")); + result = collect_disassembled_instructions(gid, status, template.areas, template.count, count); - result = collect_instructions_from_mem_areas(template.areas, template.count); - - gtk_status_stack_remove_activity(status, template.id); - - /* Libérations finales */ + /* Libération finale */ g_object_unref(G_OBJECT(template.format)); - release_mem_areas(template.areas, template.count); - return result; } diff --git a/src/analysis/disass/fetch.h b/src/analysis/disass/fetch.h index 11b2890..bf2b52f 100644 --- a/src/analysis/disass/fetch.h +++ b/src/analysis/disass/fetch.h @@ -32,7 +32,7 @@ /* Procède au désassemblage basique d'un contenu binaire. */ -GArchInstruction *disassemble_binary_content(const GLoadedBinary *, GProcContext *, wgroup_id_t, GtkStatusStack *); +GArchInstruction **disassemble_binary_content(const GLoadedBinary *, GProcContext *, wgroup_id_t, GtkStatusStack *, size_t *); diff --git a/src/arch/processor-int.h b/src/arch/processor-int.h index b170cad..4eaa690 100644 --- a/src/arch/processor-int.h +++ b/src/arch/processor-int.h @@ -44,7 +44,7 @@ /* Taille des pré-allocations pour les instructions */ -#define INSTR_ALLOC_BLOCK 100 +#define COV_ALLOC_BLOCK 100 @@ -85,7 +85,6 @@ struct _GArchProcessor //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 */ unsigned int stamp; /* Marque de suivi des modifs */ GMutex mutex; /* Verrou pour l'accès */ diff --git a/src/arch/processor.c b/src/arch/processor.c index 24e2db6..5cc1951 100644 --- a/src/arch/processor.c +++ b/src/arch/processor.c @@ -405,8 +405,9 @@ size_t g_arch_processor_count_instructions(const GArchProcessor *proc) /****************************************************************************** * * -* Paramètres : proc = architecture visée par la procédure. * -* list = liste des instructions désassemblées. * +* Paramètres : proc = architecture visée par la procédure. * +* list = liste des instructions désassemblées. * +* count = taille de cette liste. * * * * Description : Note les instructions désassemblées avec une architecture. * * * @@ -416,48 +417,44 @@ size_t g_arch_processor_count_instructions(const GArchProcessor *proc) * * ******************************************************************************/ -void g_arch_processor_set_disassembled_instructions(GArchProcessor *proc, GArchInstruction *list) +void g_arch_processor_set_instructions(GArchProcessor *proc, GArchInstruction **list, size_t count) { GArchInstruction *last; /* Dernière instruction traitée*/ - GArchInstruction *iter; /* Boucle de parcours */ + size_t i; /* Boucle de parcours */ + GArchInstruction *instr; /* Instruction à analyser */ + + g_arch_processor_lock(proc); - /* TODO : vider une éventuelle liste existante */ - /* TODO : incrémenter les références (cf. code Python) */ + proc->instructions = list; + proc->instr_count = count; + proc->stamp++; last = NULL; - ainstr_list_for_each(iter, list) + for (i = 0; i < count; i++) { - /* 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 *)); - - } + instr = list[i]; /* Constitution des groupes */ - if (last == NULL || g_arch_instruction_get_flags(iter) & AIF_ROUTINE_START) + + if (last == NULL || g_arch_instruction_get_flags(instr) & AIF_ROUTINE_START) { if (last != NULL) - g_arch_processor_finish_last_coverage(proc, last, proc->instr_count - 1); + g_arch_processor_finish_last_coverage(proc, last, i - 1); - g_arch_processor_add_new_coverage(proc, iter, proc->instr_count); + g_arch_processor_add_new_coverage(proc, instr, i); } - /* Enregistrement */ - proc->instructions[proc->instr_count++] = iter; - - last = iter; + last = instr; } if (last != NULL) g_arch_processor_finish_last_coverage(proc, last, proc->instr_count - 1); + g_arch_processor_unlock(proc); + } @@ -527,7 +524,7 @@ static void g_arch_processor_add_new_coverage(GArchProcessor *proc, GArchInstruc /* Mise à disposition de d'avantage d'espace */ if (proc->cov_allocated == proc->cov_count) { - proc->cov_allocated += INSTR_ALLOC_BLOCK; + proc->cov_allocated += COV_ALLOC_BLOCK; proc->coverages = (instr_coverage *)realloc(proc->coverages, proc->cov_allocated * sizeof(instr_coverage)); diff --git a/src/arch/processor.h b/src/arch/processor.h index 05ea77a..76691ec 100644 --- a/src/arch/processor.h +++ b/src/arch/processor.h @@ -91,7 +91,7 @@ unsigned int g_arch_processor_get_stamp(const GArchProcessor *); 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 *); +void g_arch_processor_set_instructions(GArchProcessor *, GArchInstruction **, size_t); /* Fournit une instruction désassemblée pour une architecture. */ GArchInstruction *g_arch_processor_get_instruction(const GArchProcessor *, size_t); -- cgit v0.11.2-87-g4458