summaryrefslogtreecommitdiff
path: root/src/analysis/disass/fetch.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/disass/fetch.c')
-rw-r--r--src/analysis/disass/fetch.c429
1 files changed, 369 insertions, 60 deletions
diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c
index 67a6f3b..bfc0598 100644
--- a/src/analysis/disass/fetch.c
+++ b/src/analysis/disass/fetch.c
@@ -31,18 +31,331 @@
#include "area.h"
+#include "../../glibext/delayed-int.h"
+
+
+
+
+
+
+
+
+/* ------------------------- RECUPERATIONS EN TOILE DE FOND ------------------------- */
+/* ------------------------ DESASSEMBLAGE DE BINAIRE DIFFERE ------------------------ */
+
+
+#define G_TYPE_DELAYED_FETCHING g_delayed_fetching_get_type()
+#define G_DELAYED_FETCHING(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_delayed_fetching_get_type(), GDelayedFetching))
+#define G_IS_DELAYED_FETCHING(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_delayed_fetching_get_type()))
+#define G_DELAYED_FETCHING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DELAYED_FETCHING, GDelayedFetchingClass))
+#define G_IS_DELAYED_FETCHING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DELAYED_FETCHING))
+#define G_DELAYED_FETCHING_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DELAYED_FETCHING, GDelayedFetchingClass))
+
+
+/* Ensembles binaires à désassembler (instance) */
+typedef struct _GDelayedFetching
+{
+ GDelayedWork parent; /* A laisser en premier */
+
+ wgroup_id_t gid; /* Groupe de travail parallèle */
+
+ GExeFormat *format; /* Format du fichier binaire */
+
+ GProcContext *ctx; /* Contexte de désassemblage */
+ mem_area_v2 *areas; /* Zone de productions */
+ size_t count; /* Nombre de ces zones */
+ status_blob_info *info; /* Informations de progression */
+
+ virt_t virt; /* Adresse de départ dépilée */
+
+} GDelayedFetching;
+
+/* Ensembles binaires à désassembler (classe) */
+typedef struct _GDelayedFetchingClass
+{
+ GDelayedWorkClass parent; /* A laisser en premier */
+
+} GDelayedFetchingClass;
+
+
+/* Indique le type défini pour les tâches de récupération différée. */
+GType g_delayed_fetching_get_type(void);
+
+/* Initialise la classe des tâches de désassemblage différé. */
+static void g_delayed_fetching_class_init(GDelayedFetchingClass *);
+
+/* Initialise une tâche de désassemblage différé. */
+static void g_delayed_fetching_init(GDelayedFetching *);
+
+/* Supprime toutes les références externes. */
+static void g_delayed_fetching_dispose(GDelayedFetching *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_delayed_fetching_finalize(GDelayedFetching *);
+
+/* Crée une tâche de récupération d'instructions différée. */
+static GDelayedFetching *g_delayed_fetching_new(const GDelayedFetching *, virt_t);
+
+/* Assure la récupération d'instructions en différé. */
+static void g_delayed_fetching_process(GDelayedFetching *, GtkExtStatusBar *);
+
+
+
+
+
+
+
+
+
+
+/* ------------------------ DESASSEMBLAGE DE BINAIRE DIFFERE ------------------------ */
+/* ------------------------ DESASSEMBLAGE DE BINAIRE DIFFERE ------------------------ */
+
/* Suit un flot d'exécution pour désassembler du code. */
static void follow_execution_flow(const GLoadedBinary *, GProcContext *, mem_area **, size_t *, status_blob_info *);
-/* S'assure que l'ensemble des aires est entièrement décodé. */
-static void ensure_all_mem_areas_are_filled(mem_area **, size_t *, const GLoadedBinary *, GProcContext *, status_blob_info *);
+
+
+/* ---------------------------------------------------------------------------------- */
+/* RECUPERATIONS EN TOILE DE FOND */
+/* ---------------------------------------------------------------------------------- */
+
+
+
+
+
+
+
+
+/* Indique le type défini pour les tâches de récupération différée. */
+G_DEFINE_TYPE(GDelayedFetching, g_delayed_fetching, G_TYPE_DELAYED_WORK);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des tâches de récupération différée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_delayed_fetching_class_init(GDelayedFetchingClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GDelayedWorkClass *work; /* Version en classe parente */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_delayed_fetching_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_delayed_fetching_finalize;
+
+ work = G_DELAYED_WORK_CLASS(klass);
+
+ work->run = (run_task_fc)g_delayed_fetching_process;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : fetching = instance à initialiser. *
+* *
+* Description : Initialise une tâche de récupération différée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_delayed_fetching_init(GDelayedFetching *fetching)
+{
+
+
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : fetching = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_delayed_fetching_dispose(GDelayedFetching *fetching)
+{
+ g_object_unref(G_OBJECT(fetching->format));
+
+ g_object_unref(G_OBJECT(fetching->ctx));
+
+ G_OBJECT_CLASS(g_delayed_fetching_parent_class)->dispose(G_OBJECT(fetching));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : fetching = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_delayed_fetching_finalize(GDelayedFetching *fetching)
+{
+ G_OBJECT_CLASS(g_delayed_fetching_parent_class)->finalize(G_OBJECT(fetching));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : template = modèle dont les informations sont à copier. *
+* virt = point départ dépilé et personnalisant l'instance. *
+* *
+* Description : Crée une tâche de récupération d'instructions différée. *
+* *
+* Retour : Tâche créée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GDelayedFetching *g_delayed_fetching_new(const GDelayedFetching *template, virt_t virt)
+{
+ GDelayedFetching *result; /* Tâche à retourner */
+
+ result = g_object_new(G_TYPE_DELAYED_FETCHING, NULL);
+
+ result->gid = template->gid;
+
+ result->format = template->format;
+ g_object_ref(G_OBJECT(result->format));
+
+ result->ctx = template->ctx;
+ g_object_ref(G_OBJECT(result->ctx));
+
+ result->areas = template->areas;
+ result->count = template->count;
+ result->info = template->info;
+
+ result->virt = virt;
+
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : fetching = récupération à mener. *
+* statusbar = barre de statut à tenir informée. *
+* *
+* Description : Assure la récupération d'instructions en différé. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_delayed_fetching_process(GDelayedFetching *fetching, GtkExtStatusBar *statusbar)
+{
+ vmpa2t addr; /* Conversion en pleine adresse*/
+ mem_area_v2 *area; /* Zone trouvée à traiter */
+
+ if (!g_exe_format_translate_address_into_vmpa(fetching->format, fetching->virt, &addr))
+ init_vmpa(&addr, VMPA_NO_PHYSICAL, fetching->virt);
+
+ area = find_memory_area_by_addr_v2(fetching->areas, fetching->count, &addr);
+
+ if (area != NULL)
+ load_code_from_mem_area_v2(area, fetching->areas, fetching->count,
+ fetching->ctx, &addr, fetching->info);
+
+}
+
+
+
+
+
+
+
+
+
+
+/* Poursuit l'analyse à partir des points d'entrée découverts. */
+static void follow_execution_flow_v2(GProcContext *, const GDelayedFetching *);
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : ctx = contexte de désass. avec une nouvelle entrée. *
+* template = modèle dont les informations sont à copier. *
+* *
+* Description : Poursuit l'analyse à partir des points d'entrée découverts. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void follow_execution_flow_v2(GProcContext *ctx, const GDelayedFetching *template)
+{
+ GWorkQueue *queue; /* Gestionnaire de différés */
+ virt_t virt; /* Adresse de départ dépilée */
+ GDelayedFetching *fetching; /* Récupération à mener */
+
+ queue = get_work_queue();
+
+ while (g_proc_context_pop_drop_point(ctx, &virt))
+ {
+ fetching = g_delayed_fetching_new(template, virt);
+
+ /**
+ * Pas très élégant : l'identifiant du groupe de travail ne sert qu'ici ;
+ * il n'est donc aucune utilité dans la tâche elle-même.
+ *
+ * Cependant, les paramètres d'appel étant limités, il faudrait créer
+ * une structure intermediare pour communiquer l'identifiant, ce qui
+ * est tout aussi moche.
+ */
+
+ g_work_queue_schedule_work(queue, G_DELAYED_WORK(fetching), template->gid);
+
+ }
+
+}
+
+
/******************************************************************************
* *
* Paramètres : binary = représentation de binaire chargé. *
@@ -68,7 +381,7 @@ static void follow_execution_flow(const GLoadedBinary *binary, GProcContext *ctx
while (g_proc_context_has_drop_points(ctx))
{
- virt = g_proc_context_pop_drop_point(ctx);
+ g_proc_context_pop_drop_point(ctx, &virt);
format = g_loaded_binary_get_format(binary);
@@ -96,38 +409,13 @@ static void follow_execution_flow(const GLoadedBinary *binary, GProcContext *ctx
}
-
-/******************************************************************************
-* *
-* Paramètres : 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. *
-* info = indications quant à la progression à afficher. *
-* *
-* Description : S'assure que l'ensemble des aires est entièrement décodé. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void ensure_all_mem_areas_are_filled(mem_area **list, size_t *count, const GLoadedBinary *binary, GProcContext *ctx, status_blob_info *info)
-{
- size_t i; /* Boucle de parcours */
-
- for (i = 0; i < *count; i++)
- fill_mem_area(list, count, &i, binary, ctx, info);
-
-}
-
+static GDelayedFetching template; /* Patron des tâches à venir */
/******************************************************************************
* *
* Paramètres : binary = représentation de binaire chargé. *
+* gid = identifiant du groupe de travail à utiliser. *
* statusbar = barre de statut avec progression à mettre à jour.*
-* id = identifiant du message affiché à l'utilisateur. *
* *
* Description : Procède au désassemblage basique d'un contenu binaire. *
* *
@@ -137,75 +425,96 @@ static void ensure_all_mem_areas_are_filled(mem_area **list, size_t *count, cons
* *
******************************************************************************/
-GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExtStatusBar *statusbar)
+GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, wgroup_id_t gid, GtkExtStatusBar *statusbar)
{
GArchInstruction *result; /* Instruction désassemblées */
+ //GDelayedFetching template; /* Patron des tâches à venir */
GBinFormat *format; /* Format du fichier binaire */
GArchProcessor *proc; /* Architecture du binaire */
- GProcContext *ctx; /* Contexte de désassemblage */
GBinContent *content; /* Contenu binaire à manipuler */
phys_t length; /* Taille des données à lire */
- mem_area *areas; /* Zone de productions */
- size_t count; /* Nombre de ces zones */
- status_blob_info *info; /* Informations de progression */
+ GWorkQueue *queue; /* Gestionnaire de différés */
double done; /* Portion de travail accompli */
- format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
- proc = g_loaded_binary_get_processor(binary);
- ctx = g_arch_processor_get_context(proc);
- g_binary_format_setup_disassembling_context(format, ctx);
- /* Définition à la découpe des parties à traiter */
+
+
+
+
+
+ /* Constitution du modèle de référence */
+
+ template.gid = gid;
+
+ template.format = g_loaded_binary_get_format(binary);
+ format = G_BIN_FORMAT(template.format);
+
+ proc = g_loaded_binary_get_processor(binary);
+ template.ctx = g_arch_processor_get_context(proc);
+ g_object_unref(G_OBJECT(proc));
content = g_binary_format_get_content(format);
length = g_binary_content_compute_size(content);
+ g_object_unref(G_OBJECT(content));
- areas = compute_memory_areas(G_EXE_FORMAT(format), length, &count);
+ template.areas = compute_memory_areas_v2(binary, length, &template.count);
+
+ /* Amorce des traitements */
+
+ g_signal_connect(template.ctx, "drop-point-pushed", G_CALLBACK(follow_execution_flow_v2), &template);
+
+ queue = get_work_queue();
/**
* Première phase de désassemblage : suivi des chemins tracés.
*/
- info = init_progessive_status(statusbar,
- _("Disassembling following the execution flow..."),
- 0, length);
+ template.info = init_progessive_status(statusbar,
+ _("Disassembling following the execution flow..."),
+ 0, length);
+
+ g_binary_format_setup_disassembling_context(format, template.ctx);
+
+ g_work_queue_wait_for_completion(queue, gid);
- follow_execution_flow(binary, ctx, &areas, &count, info);
+ printf("===================== DONE !\n");
- done = get_current_progessive_status(info);
+ done = get_current_progessive_status(template.info);
- fini_progessive_status(info);
+ fini_progessive_status(template.info);
/**
* Seconde phase : on comble les trous laissés.
*/
- info = init_progessive_status(statusbar,
- _("Disassembling the remaining instructions..."),
- done, length);
+ template.info = init_progessive_status(statusbar,
+ _("Disassembling the remaining instructions..."),
+ done, length);
- ensure_all_mem_areas_are_filled(&areas, &count, binary, ctx, info);
+ ensure_all_mem_areas_are_filled(template.areas, template.count, template.ctx, template.info);
- fini_progessive_status(info);
+ fini_progessive_status(template.info);
/**
* Troisième et dernière phase : récolte des fruits.
*/
- info = init_progessive_status(statusbar,
- _("Collecting disassembled instructions..."),
- 0, length);
+ template.info = init_progessive_status(statusbar,
+ _("Collecting disassembled instructions..."),
+ 0, length);
- result = collect_instructions_from_mem_areas(areas, count);
+ result = collect_instructions_from_mem_areas_v2(template.areas, template.count);
- fini_progessive_status(info);
+ fini_progessive_status(template.info);
- /* free */
+ /* Libérations finales */
- g_object_unref(G_OBJECT(content));
+ //g_object_unref(G_OBJECT(template.format));
- g_object_unref(G_OBJECT(proc));
+ g_object_unref(G_OBJECT(template.ctx));
+
+ /* TODO / del(areas); */
return result;