diff options
Diffstat (limited to 'src/analysis/disass/fetch.c')
-rw-r--r-- | src/analysis/disass/fetch.c | 429 |
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; |