summaryrefslogtreecommitdiff
path: root/src/analysis/delayed.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/delayed.c')
-rw-r--r--src/analysis/delayed.c299
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);