diff options
Diffstat (limited to 'src/analysis/delayed.c')
-rw-r--r-- | src/analysis/delayed.c | 299 |
1 files changed, 113 insertions, 186 deletions
diff --git a/src/analysis/delayed.c b/src/analysis/delayed.c index 6ec03e8..0d02d39 100644 --- a/src/analysis/delayed.c +++ b/src/analysis/delayed.c @@ -24,13 +24,11 @@ #include "delayed.h" -#include <malloc.h> - - #include "line_code.h" #include "line_comment.h" #include "../common/dllist.h" #include "../format/format.h" +#include "../glibext/delayed-int.h" #include "../gtkext/gtkextstatusbar.h" #include "../gtkext/iodamarshal.h" @@ -43,75 +41,75 @@ -/* Ensembles binaires à désassembler */ -typedef struct _disassembly_task +/* ------------------------ DESASSEMBLAGE DE BINAIRE DIFFERE ------------------------ */ + + +/* Ensembles binaires à désassembler (instance) */ +struct _GDelayedDisassembly { - GOpenidaBinary *owner; /* Destinataire final */ + GDelayedWork parent; /* A laisser en premier */ - DL_LIST_ITEM(link); /* Lien vers les maillons */ + GOpenidaBinary *binary; /* Destinataire final */ GBinPart **parts; /* Parties binaires à traiter */ size_t count; /* Nombre de ces parties */ -} disassembly_task; - +}; -#define disassembly_task_list_add_tail(new, head) dl_list_add_tail(new, head, disassembly_task, link) -#define disassembly_task_list_del(item, head) dl_list_del(item, head, disassembly_task, link) +/* Ensembles binaires à désassembler (classe) */ +struct _GDelayedDisassemblyClass +{ + GDelayedWorkClass parent; /* A laisser en premier */ +}; -/* Crée un tâche de désassemblage différé. */ -static disassembly_task *create_disassembly_task(GOpenidaBinary *, GBinPart **, size_t); -/* Efface une tâche de désassemblage de la mémoire. */ -static void delete_disassembly_task(disassembly_task *); +/* Initialise la classe des tâches de désassemblage différé. */ +static void g_delayed_disassembly_class_init(GDelayedDisassemblyClass *); +/* Initialise une tâche de désassemblage différé. */ +static void g_delayed_disassembly_init(GDelayedDisassembly *); +/* ------------------------- GESTION DES ANALYSES DIFFEREES ------------------------- */ /* Gestionnaire des analyses différées (instance) */ -struct _GDelayedManager +struct _GDisassManager { - GObject parent; /* A laisser en premier */ + GWorkQueue parent; /* A laisser en premier */ GtkExtStatusBar *statusbar; /* Barre de statut principale */ - disassembly_task *disassemblies; /* Binaires à désassembler */ - GMutex *disass_mutex; /* Verrou pour l'accès */ - GCond *disass_cond; /* Réveil pour un traitement */ - - GThread *disassemble; /* Procédures de désassemblage */ - }; /* Gestionnaire des analyses différées (classe) */ -struct _GDelayedManagerClass +struct _GDisassManagerClass { - GObjectClass parent; /* A laisser en premier */ + GWorkQueueClass parent; /* A laisser en premier */ /* Signaux */ - void (* disassembly_completed) (GDelayedManager *, GOpenidaBinary *, GRenderingLine *); + void (* disassembly_completed) (GDisassManager *, GOpenidaBinary *, GRenderingLine *); }; /* Initialise la classe des gestionnaires d'analyses différées. */ -static void g_delayed_manager_class_init(GDelayedManagerClass *); +static void g_disassembly_manager_class_init(GDisassManagerClass *); /* Initialise un gestionnaire d'analyses différées. */ -static void g_delayed_manager_init(GDelayedManager *); +static void g_disassembly_manager_init(GDisassManager *); /* Crée un gestionnaire d'analyses différées. */ -static GDelayedManager *g_delayed_manager_new(GObject *); +static GDisassManager *g_disassembly_manager_new(GObject *); /* Assure le désassemblage en différé. */ -static void *process_disassemblies(GDelayedManager *); +static void process_disassemblies(GDisassManager *, GDelayedDisassembly *); /* Procède au désassemblage basique d'un contenu binaire. */ -static GRenderingLine *disassemble_binary_parts(disassembly_task *, GBinRoutine **, size_t, GtkExtStatusBar *, guint); +static GRenderingLine *disassemble_binary_parts(GDelayedDisassembly *, GBinRoutine **, size_t, GtkExtStatusBar *, guint); /* Etablit les liens entres les différentes lignes de code. */ static void establish_links_between_lines(GRenderingLine *, GBinRoutine **, size_t, GtkExtStatusBar *, guint); @@ -124,48 +122,38 @@ static vmpa_t find_best_ending_address_for_routine(GRenderingLine *, size_t, con +/* ---------------------------------------------------------------------------------- */ +/* DESASSEMBLAGE DE BINAIRE DIFFERE */ +/* ---------------------------------------------------------------------------------- */ - +/* Indique le type défini pour les tâches de désassemblage différé. */ +G_DEFINE_TYPE(GDelayedDisassembly, g_delayed_disassembly, G_TYPE_DELAYED_WORK); /****************************************************************************** * * -* Paramètres : owner = binaire chargé en attente des résultats. * -* parts = parties binaires à désassembler. * -* count = nombre de parties à traiter. * +* Paramètres : klass = classe à initialiser. * * * -* Description : Crée un tâche de désassemblage différé. * +* Description : Initialise la classe des tâches de désassemblage différé. * * * -* Retour : Tâche créée. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -static disassembly_task *create_disassembly_task(GOpenidaBinary *owner, GBinPart **parts, size_t count) +static void g_delayed_disassembly_class_init(GDelayedDisassemblyClass *klass) { - disassembly_task *result; /* Tâche à retourner */ - - result = (disassembly_task *)calloc(1, sizeof(disassembly_task)); - - result->owner = owner; - - DL_LIST_ITEM_INIT(&result->link); - - result->parts = parts; - result->count = count; - - return result; } /****************************************************************************** * * -* Paramètres : task = tâche à libérer de la mémoire. * +* Paramètres : disass = instance à initialiser. * * * -* Description : Efface une tâche de désassemblage de la mémoire. * +* Description : Initialise une tâche de désassemblage différé. * * * * Retour : - * * * @@ -173,34 +161,50 @@ static disassembly_task *create_disassembly_task(GOpenidaBinary *owner, GBinPart * * ******************************************************************************/ -static void delete_disassembly_task(disassembly_task *task) +static void g_delayed_disassembly_init(GDelayedDisassembly *disass) { - /* TODO - result->parts = parts; - result->count = count; - */ - - free(task); } +/****************************************************************************** +* * +* Paramètres : binary = binaire chargé en attente des résultats. * +* parts = parties binaires à désassembler. * +* count = nombre de parties à traiter. * +* * +* Description : Crée une tâche de désassemblage différé. * +* * +* Retour : Tâche créée. * +* * +* Remarques : - * +* * +******************************************************************************/ +GDelayedDisassembly *g_delayed_disassembly_new(GOpenidaBinary *binary, GBinPart **parts, size_t count) +{ + GDelayedDisassembly *result; /* Tâche à retourner */ + result = g_object_new(G_TYPE_DELAYED_DISASSEMBLY, NULL); + result->binary = binary; + result->parts = parts; + result->count = count; + return result; +} - - - +/* ---------------------------------------------------------------------------------- */ +/* GESTION DES ANALYSES DIFFEREES */ +/* ---------------------------------------------------------------------------------- */ /* Indique le type défini pour le gestionnaire des analyses différées. */ -G_DEFINE_TYPE(GDelayedManager, g_delayed_manager, G_TYPE_OBJECT); +G_DEFINE_TYPE(GDisassManager, g_disassembly_manager, G_TYPE_WORK_QUEUE); /****************************************************************************** @@ -215,12 +219,12 @@ G_DEFINE_TYPE(GDelayedManager, g_delayed_manager, G_TYPE_OBJECT); * * ******************************************************************************/ -static void g_delayed_manager_class_init(GDelayedManagerClass *klass) +static void g_disassembly_manager_class_init(GDisassManagerClass *klass) { g_signal_new("disassembly-completed", - G_TYPE_DELAYED_MANAGER, + G_TYPE_DISASS_MANAGER, G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GDelayedManagerClass, disassembly_completed), + G_STRUCT_OFFSET(GDisassManagerClass, disassembly_completed), NULL, NULL, g_cclosure_user_marshal_VOID__OBJECT_OBJECT, G_TYPE_NONE, 2, G_TYPE_OPENIDA_BINARY, G_TYPE_RENDERING_LINE); @@ -240,8 +244,13 @@ static void g_delayed_manager_class_init(GDelayedManagerClass *klass) * * ******************************************************************************/ -static void g_delayed_manager_init(GDelayedManager *manager) +static void g_disassembly_manager_init(GDisassManager *manager) { + GWorkQueue *parent; /* Instance parente */ + + parent = G_WORK_QUEUE(manager); + + parent->process = (process_work_fc)process_disassemblies; } @@ -258,116 +267,76 @@ static void g_delayed_manager_init(GDelayedManager *manager) * * ******************************************************************************/ -static GDelayedManager *g_delayed_manager_new(GObject *ref) +static GDisassManager *g_disassembly_manager_new(GObject *ref) { - GDelayedManager *result; /* Adresse à retourner */ - GError *error; /* Bilan de création de thread */ + GDisassManager *result; /* Adresse à retourner */ - result = g_object_new(G_TYPE_DELAYED_MANAGER, NULL); + result = g_object_new(G_TYPE_DISASS_MANAGER, NULL); result->statusbar = g_object_get_data(ref, "statusbar"); - result->disass_mutex = g_mutex_new(); - if (result->disass_mutex == NULL) - goto dmn_error; - - result->disass_cond = g_cond_new(); - if (result->disass_cond == NULL) - goto dmn_error; - - result->disassemble = g_thread_create((GThreadFunc)process_disassemblies, result, FALSE, &error); - if (!result->disassemble) - goto dmn_error; - return result; - dmn_error: - - /* TODO */ - - return NULL; - } /****************************************************************************** * * * Paramètres : manager = gestionnaire des actions à mener. * +* disass = analyse à mener. * * * * Description : Assure le désassemblage en différé. * * * -* Retour : Bilan de l'opération. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -static void *process_disassemblies(GDelayedManager *manager) +static void process_disassemblies(GDisassManager *manager, GDelayedDisassembly *disass) { - disassembly_task *task; /* Désassemblage à effectuer */ GBinRoutine **routines; /* Liste des routines trouvées */ size_t routines_count; /* Nombre de ces routines */ guint id; /* Identifiant de statut */ GRenderingLine *lines; /* Nouvelles lignes de rendu */ - while (1) - { - g_mutex_lock(manager->disass_mutex); - - if (dl_list_empty(manager->disassemblies)) - g_cond_wait(manager->disass_cond, manager->disass_mutex); - - task = manager->disassemblies; - disassembly_task_list_del(task, &manager->disassemblies); - - g_mutex_unlock(manager->disass_mutex); + routines = g_binary_format_get_routines(G_BIN_FORMAT(g_openida_binary_get_format(disass->binary)), &routines_count); + qsort(routines, routines_count, sizeof(GBinRoutine *), g_binary_routine_rcompare); - routines = g_binary_format_get_routines(G_BIN_FORMAT(g_openida_binary_get_format(task->owner)), &routines_count); - qsort(routines, routines_count, sizeof(GBinRoutine *), g_binary_routine_rcompare); + /* Première étape */ - /* Première étape */ + id = gtk_extended_status_bar_push(manager->statusbar, _("Disassembling..."), true); - id = gtk_extended_status_bar_push(manager->statusbar, _("Disassembling..."), true); + lines = disassemble_binary_parts(disass, routines, routines_count, manager->statusbar, id); - lines = disassemble_binary_parts(task, routines, routines_count, - manager->statusbar, id); + gtk_extended_status_bar_remove(manager->statusbar, id); - gtk_extended_status_bar_remove(manager->statusbar, id); + /* Seconde étape */ - /* Seconde étape */ + id = gtk_extended_status_bar_push(manager->statusbar, _("Establishing links..."), true); - id = gtk_extended_status_bar_push(manager->statusbar, _("Establishing links..."), true); + establish_links_between_lines(lines, routines, routines_count, manager->statusbar, id); - establish_links_between_lines(lines, routines, routines_count, - manager->statusbar, id); + gtk_extended_status_bar_remove(manager->statusbar, id); - gtk_extended_status_bar_remove(manager->statusbar, id); + /* Troisième étape */ - /* Troisième étape */ + id = gtk_extended_status_bar_push(manager->statusbar, _("Finding remaining limits..."), true); - id = gtk_extended_status_bar_push(manager->statusbar, _("Finding remaining limits..."), true); + limit_all_routines(lines, routines, routines_count, manager->statusbar, id); - limit_all_routines(lines, routines, routines_count, - manager->statusbar, id); + gtk_extended_status_bar_remove(manager->statusbar, id); - gtk_extended_status_bar_remove(manager->statusbar, id); + /* Fin */ - /* Fin */ - - g_signal_emit_by_name(manager, "disassembly-completed", task->owner, lines); - - delete_disassembly_task(task); - - } - - return NULL; + g_signal_emit_by_name(manager, "disassembly-completed", disass->binary, lines); } /****************************************************************************** * * -* Paramètres : task = tâche à l'origine du traitement. * +* Paramètres : disass = tâche à l'origine du traitement. * * routines = prototypes existants à insérer. * * count = quantité de ces prototypes. * * statusbar = barre de statut avec progression à mettre à jour.* @@ -381,7 +350,7 @@ static void *process_disassemblies(GDelayedManager *manager) * * ******************************************************************************/ -static GRenderingLine *disassemble_binary_parts(disassembly_task *task, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, guint id) +static GRenderingLine *disassemble_binary_parts(GDelayedDisassembly *disass, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, guint id) { GRenderingLine *result; /* Ligne de rendu à retourner */ GArchProcessor *proc; /* Architecture du binaire */ @@ -403,25 +372,25 @@ static GRenderingLine *disassemble_binary_parts(disassembly_task *task, GBinRout result = NULL; - proc = get_arch_processor_from_format(g_openida_binary_get_format(task->owner)); - options = g_openida_binary_get_options(task->owner); - bin_data = g_openida_binary_get_data(task->owner, NULL); + proc = get_arch_processor_from_format(g_openida_binary_get_format(disass->binary)); + options = g_openida_binary_get_options(disass->binary); + bin_data = g_openida_binary_get_data(disass->binary, NULL); /* Préparation du suivi de la progression */ sum = 0; - for (i = 0; i < task->count; i++) + for (i = 0; i < disass->count; i++) { - g_binary_part_get_values(task->parts[i], NULL, &len, NULL); + g_binary_part_get_values(disass->parts[i], NULL, &len, NULL); sum += len; } done = 0; - for (i = 0; i < task->count; i++) + for (i = 0; i < disass->count; i++) { - g_binary_part_get_values(task->parts[i], &pos, &len, &base); + g_binary_part_get_values(disass->parts[i], &pos, &len, &base); /* Décodage des instructions */ @@ -695,48 +664,6 @@ static vmpa_t find_best_ending_address_for_routine(GRenderingLine *line, size_t } - - - - - - -/****************************************************************************** -* * -* Paramètres : manager = gestionnaire des actions à mener. * -* binary = élément binaire concerné par la procédure. * -* parts = blocs binaires à désassembler. * -* count = quantité de ces blocs binaires. * -* * -* Description : Place un nouveau désassemblage en attente. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_delayed_manager_schedule_disassembly(GDelayedManager *manager, GOpenidaBinary *binary, GBinPart **parts, size_t count) -{ - disassembly_task *task; /* Nouveau désassemblage */ - - task = create_disassembly_task(binary, parts, count); - - g_mutex_lock(manager->disass_mutex); - - disassembly_task_list_add_tail(task, &manager->disassemblies); - - g_cond_signal(manager->disass_cond); - - g_mutex_unlock(manager->disass_mutex); - -} - - - - - - /****************************************************************************** * * * Paramètres : manager = nouveau gestionnaire à mémoriser ou NULL. * @@ -749,9 +676,9 @@ void g_delayed_manager_schedule_disassembly(GDelayedManager *manager, GOpenidaBi * * ******************************************************************************/ -GDelayedManager *_get_delayed_manager(GDelayedManager *manager) +GDisassManager *_get_disassembly_manager(GDisassManager *manager) { - static GDelayedManager *result = NULL; /* Singleton à retourner */ + static GDisassManager *result = NULL; /* Singleton à retourner */ if (manager != NULL) result = manager; @@ -773,14 +700,14 @@ GDelayedManager *_get_delayed_manager(GDelayedManager *manager) * * ******************************************************************************/ -bool init_delayed_manager(GObject *ref) +bool init_disassembly_manager(GObject *ref) { - GDelayedManager *manager; /* Singleton à mettre en place */ + GDisassManager *manager; /* Singleton à mettre en place */ - manager = g_delayed_manager_new(ref); + manager = g_disassembly_manager_new(ref); if (manager != NULL) - _get_delayed_manager(manager); + _get_disassembly_manager(manager); return (manager != NULL); |