summaryrefslogtreecommitdiff
path: root/src/analysis
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-11-26 23:30:01 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-11-26 23:30:01 (GMT)
commit6b1a70c16f83a926f7b1f1fb2af5d6a2e017737b (patch)
tree8ffb0b3d8f3063c612f8cebe4f00a65f8b029a52 /src/analysis
parenta93a5dca1a7292b7e61ae09b74f3252e04b73488 (diff)
Used several threads without lock to disassemble binary code.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@610 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/analysis')
-rw-r--r--src/analysis/disass/area.c1085
-rw-r--r--src/analysis/disass/area.h43
-rw-r--r--src/analysis/disass/disassembler.c11
-rw-r--r--src/analysis/disass/fetch.c429
-rw-r--r--src/analysis/disass/fetch.h3
5 files changed, 1506 insertions, 65 deletions
diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c
index 1d841be..355b716 100644
--- a/src/analysis/disass/area.c
+++ b/src/analysis/disass/area.c
@@ -27,6 +27,1087 @@
#include <assert.h>
+#include <i18n.h>
+
+
+#include "../../analysis/contents/restricted.h"
+#include "../../common/bits.h"
+#include "../../gui/panels/log.h"
+
+
+
+
+/* Zone mémoire bien bornée */
+typedef struct _mem_area_v2
+{
+ GBinFormat *format; /* Format du fichier binaire */
+ GBinContent *content; /* Données binaires à lire */
+ GArchProcessor *proc; /* Architecture du binaire */
+ SourceEndian endianness; /* Boutisme de cette machine */
+
+ mrange_t range; /* Couverture de la zone */
+
+ phys_t packing_size; /* Granularité des découpages */
+
+ bitfield_t *processed; /* Octets traités dans la zone */
+ GArchInstruction **instructions; /* Instructions en place */
+
+
+
+
+ bool is_exec; /* Zone exécutable ? */
+
+} mem_area_v2;
+
+
+
+/* Initialise une aire de données à partir d'une adresse donnée. */
+static void init_mem_area_from_addr_v2(mem_area_v2 *, const vmpa2t *, phys_t, const GLoadedBinary *);
+
+/* Libère d'une aire de données les ressources allouées. */
+static void fini_mem_area_v2(mem_area_v2 *);
+
+/* Indique si une zone donnée est intégralement vierge ou non. */
+static bool is_range_blank_in_mem_area_v2(mem_area_v2 *, phys_t, phys_t);
+
+/* Marque une série d'octets comme ayant été traités. */
+static bool mark_range_in_mem_area_as_processed_v2(mem_area_v2 *, GArchInstruction *, bool);
+
+
+
+
+/* Procède au désassemblage d'un contenu binaire non exécutable. */
+static void load_data_from_mem_area_v2(mem_area_v2 *, GProcContext *, const vmpa2t *, status_blob_info *);
+
+/* S'assure qu'une aire contient toutes ses instructions. */
+static void fill_mem_area_v2(mem_area_v2 *, mem_area_v2 *, size_t, GProcContext *, status_blob_info *);
+
+/* Rassemble les instructions conservées dans une zone donnée. */
+static GArchInstruction *get_instructions_from_mem_area_v2(const mem_area_v2 *);
+
+
+
+
+
+
+/* S'assure de la présence d'un début de routine à un point. */
+static void update_address_as_routine(GBinFormat *, const vmpa2t *);
+
+
+/**
+ * Content :: à passer en restricted.
+
+ * Les sections croisées : pas de sens de les traiter ici, car au final une instruction sera à cheval
+ * sur deux sections différentes -> incohérence au niveau de l'éditeur.
+ * => régler le périmètres de segments règle donc tous les soucis.
+
+ */
+
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : area = aire représentant à contenu à initialiser. *
+* addr = adresse de départ de l'espace à mettre en place. *
+* len = longueur de l'espace à créer. *
+* binary = binaire analysé content quantités d'informations. *
+* *
+* Description : Initialise une aire de données à partir d'une adresse donnée.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void init_mem_area_from_addr_v2(mem_area_v2 *area, const vmpa2t *addr, phys_t len, const GLoadedBinary *binary)
+{
+ GBinContent *content; /* Données binaires à lire */
+
+ assert(len > 0);
+
+ area->format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
+
+ content = g_binary_format_get_content(area->format);
+
+ area->proc = g_loaded_binary_get_processor(binary);
+ area->endianness = g_arch_processor_get_endianness(area->proc);
+
+ init_mrange(&area->range, addr, len);
+
+ area->content = g_restricted_content_new(content, &area->range);
+
+ area->packing_size = 2; /* FIXME */
+
+ area->processed = create_bit_field(len, false);
+ area->instructions = (GArchInstruction **)calloc(len, sizeof(GArchInstruction *));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : area = aire représentant à contenu à nettoyer en mémoire. *
+* *
+* Description : Libère d'une aire de données les ressources allouées. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void fini_mem_area_v2(mem_area_v2 *area)
+{
+ phys_t len; /* Etendue du parcours total */
+ phys_t i; /* Boucle de parcours */
+
+ //g_object_unref(area->format); /* FIXME */
+ g_object_unref(area->content);
+ //g_object_unref(area->proc); /* FIXME */
+
+ delete_bit_field(area->processed);
+
+ len = get_mrange_length(&area->range);
+
+ for (i = 0; i < len; i++)
+ if (area->instructions[i] != NULL)
+ g_object_unref(G_OBJECT(area->instructions[i]));
+
+ free(area->instructions);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : area = aire représentant à contenu à parcourir. *
+* start = début de la zone à manipuler. *
+* len = taille de cette même aire de données. *
+* *
+* Description : Indique si une zone donnée est intégralement vierge ou non. *
+* *
+* Retour : true si l'aire visée n'a jamais été traitée, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool is_range_blank_in_mem_area_v2(mem_area_v2 *area, phys_t start, phys_t len)
+{
+ bool result; /* Résultat à renvoyer */
+
+ if ((start + len) >= get_mrange_length(&area->range))
+ result = false;
+
+ else
+ result = !test_in_bit_field(area->processed, start, len);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : area = aire représentant à contenu à parcourir. *
+* instr = instruction à mémoriser pour la suite. *
+* force = impose l'enregistrement de l'instruction. *
+* *
+* Description : Marque une série d'octets comme ayant été traités. *
+* *
+* Retour : true si l'enregistrement a bien été réalisé, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool mark_range_in_mem_area_as_processed_v2(mem_area_v2 *area, GArchInstruction *instr, bool force)
+{
+ bool result; /* Bilan d'action à renvoyer */
+ const vmpa2t *start; /* Adresse de départ de la zone*/
+ const mrange_t *range; /* Emplacement d'instruction */
+ const vmpa2t *addr; /* Début de la zone à traiter */
+ phys_t len; /* Taille de l'aire visée */
+ phys_t offset; /* Décallage de départ */
+
+ start = get_mrange_addr(&area->range);
+
+ range = g_arch_instruction_get_range(instr);
+ addr = get_mrange_addr(range);
+ len = get_mrange_length(range);
+
+ offset = compute_vmpa_diff(start, addr);
+
+ result = set_atomic_in_bit_field(area->processed, offset, len);
+
+ /* Si l'instruction était bien la première à s'inscrire... */
+
+ result |= force;
+
+ if (result)
+ area->instructions[offset] = instr;
+
+ return result;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : area = aire représentant à contenu à parcourir. *
+* list = liste de zones délimitant des contenus à traiter. *
+* count = nombre de zones à disposition. *
+* index = indice de l'aire à considérer pendant l'opération. *
+* binary = représentation de binaire chargé. *
+* ctx = contexte offert en soutien à un désassemblage. *
+* start = démarrage de l'exécution au sein de la zone. *
+* info = indications quant à la progression à afficher. *
+* *
+* Description : Procède au désassemblage d'un contenu binaire exécutable. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void load_code_from_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t count, GProcContext *ctx, const vmpa2t *start, status_blob_info *info)
+{
+
+
+
+ GBinFormat *format; /* Format du fichier binaire */
+ GArchProcessor *proc; /* Architecture du binaire */
+ GBinContent *content; /* Données binaires à lire */
+
+ phys_t diff; /* Volume de données traité */
+ phys_t alen; /* Taille de l'aire utilisée */
+
+ phys_t i; /* Boucle de parcours */
+
+
+ vmpa2t pos; /* Boucle de parcours */
+ vmpa2t prev; /* Boucle de parcours */
+
+ GArchInstruction *instr; /* Instruction décodée */
+
+
+
+ mrange_t range; /* Couverture de l'instruction */
+
+
+ bool done; /* Enregistrement effectué ? */
+
+
+ vmpa2t sym_addr; /* Adresse de nouveau symbole */
+ bool has_new_sym; /* Statut d'un dépilement */
+
+ GBinSymbol *symbol; /* Symbole créé en parallèle */
+
+
+
+
+
+ /* Récupération des informations de base */
+
+ format = area->format;
+ proc = area->proc;
+ content = area->content;
+
+ diff = compute_vmpa_diff(get_mrange_addr(&area->range), start);
+ alen = get_mrange_length(&area->range);
+
+ copy_vmpa(&pos, start);
+
+ /* Traitement de la zone */
+
+ printf("=== processing @ 0x%08x\n", (unsigned int)start->virtual);
+
+ for (i = diff; i < alen; i += diff)
+ {
+ /**
+ * On réalise un premier test informel (car non atomique) peu coûteux
+ * avant de se lancer dans un désassemblage d'instruction potentiellement
+ * inutile.
+ */
+
+ printf(" (%u) blank ? %d\n", (unsigned int)i, is_range_blank_in_mem_area_v2(area, i, 1));
+ printf(" +1 blank ? %d\n", is_range_blank_in_mem_area_v2(area, i + 1, 1));
+
+ if (!is_range_blank_in_mem_area_v2(area, i, 1))
+ break;
+
+ /* Décodage d'une nouvelle instruction */
+
+ copy_vmpa(&prev, &pos);
+
+ instr = g_arch_processor_disassemble(proc, ctx, content, &pos);
+ if (instr == NULL) break;
+
+ /* Enregistrement des positions et adresses */
+
+ diff = compute_vmpa_diff(&prev, &pos);
+
+ init_mrange(&range, &prev, diff);
+
+ g_arch_instruction_set_range(instr, &range);
+
+ /* Progression dans les traitements */
+
+ done = mark_range_in_mem_area_as_processed_v2(area, instr, false);
+
+ if (!done)
+ {
+ g_object_unref(G_OBJECT(instr));
+ break;
+ }
+
+ inc_progessive_status(info, diff);
+
+ assert(!is_range_blank_in_mem_area_v2(area, i, diff));
+
+ /* Enregistrement d'un éventuel début de routine */
+
+ if (g_arch_instruction_get_flags(instr) & AIF_ROUTINE_START)
+ update_address_as_routine(format, &prev);
+
+ /* Eventuel renvoi vers d'autres adresses */
+
+ g_arch_instruction_call_hook(instr, IPH_FETCH, proc, ctx, format);
+
+ /* Insertion des symboles découverts en parallèle */
+
+ for (has_new_sym = g_proc_context_pop_new_symbol_at(ctx, &sym_addr);
+ has_new_sym;
+ has_new_sym = g_proc_context_pop_new_symbol_at(ctx, &sym_addr))
+ {
+ has_new_sym = g_binary_format_find_symbol_at(format, &sym_addr, &symbol);
+ assert(has_new_sym);
+
+ insert_extra_symbol_into_mem_areas_v2(list, count, symbol);
+
+ }
+
+ /* Rupture du flot d'exécution ? */
+ if (g_arch_instruction_get_flags(instr) & AIF_RETURN_POINT)
+ break;
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : area = aire représentant à contenu à parcourir. *
+* ctx = contexte offert en soutien à un désassemblage. *
+* start = démarrage de l'exécution au sein de la zone. *
+* info = indications quant à la progression à afficher. *
+* *
+* Description : Procède au désassemblage d'un contenu binaire non exécutable.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void load_data_from_mem_area_v2(mem_area_v2 *area, GProcContext *ctx, const vmpa2t *start, status_blob_info *info)
+{
+ GBinContent *content; /* Données binaires à lire */
+ SourceEndian endianness; /* Boutisme de cette machine */
+ phys_t diff; /* Volume de données traité */
+ phys_t alen; /* Taille de l'aire utilisée */
+ vmpa2t pos; /* Boucle de parcours */
+ phys_t i; /* Boucle de parcours */
+ vmpa2t prev; /* Boucle de parcours */
+ GArchInstruction *instr; /* Instruction décodée */
+ mrange_t range; /* Couverture de l'instruction */
+ bool done; /* Enregistrement effectué ? */
+
+ /* Récupération des informations de base */
+
+ content = area->content;
+ endianness = area->endianness;
+
+ diff = compute_vmpa_diff(get_mrange_addr(&area->range), start);
+ alen = get_mrange_length(&area->range);
+
+ copy_vmpa(&pos, start);
+
+ /* Traitement de la zone */
+
+ for (i = diff; i < alen; i += diff)
+ {
+ /* On cherche à obtenir l'assurance que le traitement n'a jamais été fait */
+
+ if (!is_range_blank_in_mem_area_v2(area, i, 1))
+ break;
+
+ instr = NULL;
+
+ copy_vmpa(&prev, &pos);
+
+ /* Décodage d'une nouvelle instruction, sur mesure puis minimale */
+
+ if (get_virt_addr(&pos) % area->packing_size == 0
+ && is_range_blank_in_mem_area_v2(area, i, area->packing_size))
+ {
+ diff = area->packing_size;
+
+ instr = g_raw_instruction_new_array(content, MDS_FROM_BYTES(diff), 1, &pos, endianness);
+
+ if (instr == NULL)
+ copy_vmpa(&pos, &prev);
+
+ }
+
+ if (instr == NULL)
+ {
+ diff = 1;
+
+ instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, &pos, endianness);
+
+ }
+
+ /* On rencontre ici un morceau déjà traité. */
+
+ if (instr == NULL) break;
+
+ /* Enregistrement des positions et adresses */
+
+ assert(diff == compute_vmpa_diff(&prev, &pos));
+
+ init_mrange(&range, &prev, diff);
+
+ g_arch_instruction_set_range(instr, &range);
+
+ /* Progression dans les traitements */
+
+ done = mark_range_in_mem_area_as_processed_v2(area, instr, false);
+
+ if (!done)
+ {
+ g_object_unref(G_OBJECT(instr));
+ break;
+ }
+
+ inc_progessive_status(info, diff);
+
+ assert(!is_range_blank_in_mem_area_v2(area, i, diff));
+
+ /* On laisse une chance au code pour se reprendre... */
+
+ if (area->is_exec) break;
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : area = aire représentant à contenu à parcourir. *
+* 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 qu'une aire contient toutes ses instructions. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void fill_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t count, GProcContext *ctx, status_blob_info *info)
+{
+ const vmpa2t *addr; /* Début de la zone à traiter */
+ phys_t len; /* Taille de la zone à remplir */
+ phys_t i; /* Boucle de parcours */
+ vmpa2t start; /* Adresse de départ de combles*/
+
+ addr = get_mrange_addr(&area->range);
+ len = get_mrange_length(&area->range);
+
+ for (i = 0; i < len; i++)
+ {
+ if (is_range_blank_in_mem_area_v2(area, i, 1))
+ {
+ copy_vmpa(&start, addr);
+ advance_vmpa(&start, i);
+
+ if (area->is_exec && get_virt_addr(&start) % area->packing_size == 0)
+ load_code_from_mem_area_v2(area, list, count, ctx, &start, info);
+
+ if (is_range_blank_in_mem_area_v2(area, i, 1))
+ load_data_from_mem_area_v2(area, ctx, &start, info);
+
+ }
+
+ assert(!is_range_blank_in_mem_area_v2(area, i, 1));
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : area = aire représentant à contenu à parcourir. *
+* *
+* Description : Rassemble les instructions conservées dans une zone donnée. *
+* *
+* Retour : Liste d'instructions prêtes à emploi. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GArchInstruction *get_instructions_from_mem_area_v2(const mem_area_v2 *area)
+{
+ GArchInstruction *result; /* Liste d'instr. à renvoyer */
+ phys_t len; /* Nombre d'instructions au max*/
+ phys_t i; /* Boucle de parcours */
+ GArchInstruction *instr; /* Instruction décodée */
+
+ result = NULL;
+
+ len = get_mrange_length(&area->range);
+
+ for (i = 0; i < len; i++)
+ {
+ instr = area->instructions[i];
+
+ if (instr != NULL)
+ {
+ g_object_ref(G_OBJECT(instr));
+ g_arch_instruction_add_to_list(&result, instr);
+ }
+
+ }
+
+ return result;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : list = listes de zones utable à consulter. *
+* count = nombre de zones mises en place. *
+* addr = adresse à retrouver dans les aires présentes. *
+* *
+* Description : Détermine une liste de zones contigües à traiter. *
+* *
+* Retour : Indice de la zone trouvée, ou nombre d'aires en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+mem_area_v2 *find_memory_area_by_addr_v2(mem_area_v2 *list, size_t count, const vmpa2t *addr)
+{
+ mem_area_v2 *result; /* Elément trouvé à renvoyer */
+
+ int find_mem_area(const vmpa2t *addr, const mem_area_v2 *area)
+ {
+ int status; /* Bilan à retourner */
+
+ if (mrange_contains_addr(&area->range, addr))
+ status = 0;
+
+ else
+ status = cmp_vmpa(addr, get_mrange_addr(&area->range));
+
+ return status;
+
+ }
+
+ result = bsearch(addr, list, count, sizeof(mem_area_v2), (__compar_fn_t)find_mem_area);
+
+ return result;
+
+}
+
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : binary = binaire analysé contenant quantités d'infos. *
+* bin_length = quantité d'octets à traiter au total. *
+* count = nombre de zones mises en place. [OUT] *
+* *
+* Description : Détermine une liste de zones contigües à traiter. *
+* *
+* Retour : Liste de zones mémoire à libérer après usage. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+mem_area_v2 *compute_memory_areas_v2(const GLoadedBinary *binary, phys_t bin_length, size_t *count)
+{
+ mem_area_v2 *result; /* Liste à renvoyer */
+ GExeFormat *format; /* Format de fichier associé */
+ mrange_t *exe_ranges; /* Liste de zones exécutables */
+ size_t exe_count; /* Nombre de ces zones */
+ GBinSymbol **symbols; /* Symboles à représenter */
+ size_t sym_count; /* Qté de symboles présents */
+ vmpa2t last; /* Dernière bordure rencontrée */
+ bool status; /* Bilan d'une conversion */
+ size_t i; /* Boucle de parcours #1 */
+ const vmpa2t *border; /* Nouvelle bordure rencontrée */
+ mem_area_v2 *area; /* Zone avec valeurs à éditer */
+ vmpa2t tmp; /* Stockage temporaire */
+ GBinPortion **portions; /* Morceaux d'encadrement */
+ size_t portions_count; /* Taille de cette liste */
+ const vmpa2t *portion_start; /* Point de départ de portion */
+ size_t j; /* Boucle de parcours #2 */
+ SymbolType type; /* Nature d'un symbole */
+ const mrange_t *range; /* Couverture d'un symbole */
+ phys_t length; /* Taille de ce même symbole */
+ phys_t new_length; /* Nouvelle taille déterminée */
+
+ result = NULL;
+ *count = 0;
+
+ /**
+ * Le parcours n'est valide que si les zones exécutables sont triées !
+ */
+
+ format = g_loaded_binary_get_format(binary);
+
+ exe_ranges = g_exe_format_get_x_ranges(format, &exe_count);
+
+ symbols = g_binary_format_get_symbols(G_BIN_FORMAT(format), &sym_count);
+
+ /* Première étape : on comble les trous ! */
+
+ status = g_exe_format_translate_offset_into_vmpa(format, 0, &last);
+ assert(status);
+
+ for (i = 0; i < exe_count; i++)
+ {
+ border = get_mrange_addr(&exe_ranges[i]);
+
+ /* Zone tampon à constituer */
+
+ if (cmp_vmpa(&last, border) < 0)
+ {
+ result = (mem_area_v2 *)realloc(result, ++(*count) * sizeof(mem_area_v2));
+
+ area = &result[*count - 1];
+
+ init_mem_area_from_addr_v2(area, &last, compute_vmpa_diff(&last, border), binary);
+ area->is_exec = false;
+
+ }
+
+ /* Insertion d'une zone exécutable déjà définie */
+
+ result = (mem_area_v2 *)realloc(result, ++(*count) * sizeof(mem_area_v2));
+
+ area = &result[*count - 1];
+
+ init_mem_area_from_addr_v2(area, get_mrange_addr(&exe_ranges[i]),
+ get_mrange_length(&exe_ranges[i]), binary);
+ area->is_exec = true;
+
+ /* Avancée du curseur */
+
+ compute_mrange_end_addr(&exe_ranges[i], &last);
+
+ }
+
+ /* Extension finale complémentaire ? */
+
+ area = &result[*count - 1];
+
+ copy_vmpa(&tmp, get_mrange_addr(&area->range));
+ advance_vmpa(&tmp, get_mrange_length(&area->range));
+
+ if (get_phy_addr(&tmp) < bin_length)
+ {
+ result = (mem_area_v2 *)realloc(result, ++(*count) * sizeof(mem_area_v2));
+
+ area = &result[*count - 1];
+
+ init_mem_area_from_addr_v2(area, &tmp, bin_length - get_phy_addr(&tmp), binary);
+ area->is_exec = false;
+
+ }
+
+
+
+
+
+
+
+
+ for (i = 0; i < *count; i++)
+ {
+ printf(" (init) AREA %zu :: 0x%x / 0x%x + 0x%x\n",
+ i,
+ (unsigned int)get_phy_addr(get_mrange_addr(&result[i].range)),
+ (unsigned int)get_virt_addr(get_mrange_addr(&result[i].range)),
+ (unsigned int)get_mrange_length(&result[i].range));
+
+ }
+
+ printf("--------------------\n");
+
+
+
+
+
+
+
+
+ /* Seconde étape : on s'assure du découpage autour des portions pour respecter l'alignement */
+
+ portions = g_exe_format_get_portions_at_level(format, -1, &portions_count);
+
+ for (i = 1; i < portions_count; i++)
+ {
+ portion_start = get_mrange_addr(g_binary_portion_get_range(portions[i]));
+
+ printf(" [portion % 3zu] addr = 0x%x / 0x%x\n",
+ i,
+ (unsigned int)get_phy_addr(portion_start),
+ (unsigned int)get_virt_addr(portion_start));
+
+ for (j = 0; j < *count; j++)
+ {
+ area = &result[j];
+
+ if (!mrange_contains_addr(&area->range, portion_start))
+ continue;
+
+ /* Si le déccoupage actuel ne correspond pas au besoin des portions... */
+ if (cmp_vmpa(get_mrange_addr(&area->range), portion_start) != 0)
+ {
+ fini_mem_area_v2(&result[j]);
+
+ result = (mem_area_v2 *)realloc(result, ++(*count) * sizeof(mem_area_v2));
+
+ memmove(&result[j + 2], &result[j + 1], (*count - j - 2) * sizeof(mem_area_v2));
+
+ status = result[j].is_exec;
+
+ /* Première moitié */
+
+ area = &result[j];
+
+ copy_vmpa(&tmp, get_mrange_addr(&area->range));
+ length = get_mrange_length(&area->range);
+
+ new_length = compute_vmpa_diff(&tmp, portion_start);
+
+ init_mem_area_from_addr_v2(area, &tmp, new_length, binary);
+ area->is_exec = status;
+
+ /* Seconde moitié */
+
+ length -= get_mrange_length(&area->range);
+
+ area = &result[j + 1];
+
+ init_mem_area_from_addr_v2(area, portion_start, length, binary);
+ area->is_exec = status;
+
+ }
+
+ j = *count;
+
+ }
+
+ }
+
+
+
+
+
+
+
+
+ for (i = 0; i < *count; i++)
+ {
+ printf(" (fini) AREA %zu :: 0x%x / 0x%x + 0x%x\n",
+ i,
+ (unsigned int)get_phy_addr(get_mrange_addr(&result[i].range)),
+ (unsigned int)get_virt_addr(get_mrange_addr(&result[i].range)),
+ (unsigned int)get_mrange_length(&result[i].range));
+
+ }
+
+ printf("--------------------\n");
+
+
+
+
+
+
+
+
+ /* Troisième étape : on insère les symboles existants */
+
+ for (i = 0; i < sym_count; i++)
+ {
+ type = g_binary_symbol_get_target_type(symbols[i]);
+
+ /**
+ * On ne garde que les symboles renvoyant directement une ou
+ * plusieurs instructions, c'est à dire les symboles valides
+ * pour un appel à g_binary_symbol_get_instruction().
+ *
+ * Les instructions des autres symboles sont obtenues et mises
+ * en place durant la procédure de désassemblage.
+ */
+
+ if (type == STP_ROUTINE || type == STP_ENTRY_POINT || type == STP_CODE_LABEL)
+ continue;
+
+ range = g_binary_symbol_get_range(symbols[i]);
+
+ length = get_mrange_length(range);
+
+ if (length == 0)
+ continue;
+
+ insert_extra_symbol_into_mem_areas_v2(result, *count, symbols[i]);
+
+ }
+
+ /* Nettoyage final */
+
+ if (portions != NULL)
+ free(portions);
+
+ if (exe_ranges != NULL)
+ free(exe_ranges);
+
+ /// FIXME g_object_unref(G_OBJECT(format));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : areas = liste de zones délimitant des contenus à traiter. *
+* count = nombre de zones à disposition. *
+* symbol = élément nouveau à venir insérer dans les zones. *
+* *
+* Description : Insère un symbole dans un découpage en aires. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void insert_extra_symbol_into_mem_areas_v2(mem_area_v2 *areas, size_t count, const GBinSymbol *symbol)
+{
+ SymbolType type; /* Type de symbole */
+ GArchInstruction *list; /* Ensemble à insérer */
+ GArchInstruction *iter; /* Boucle de parcours */
+ const mrange_t *range; /* Emplacement d'instruction */
+ const vmpa2t *addr; /* Départ de cet emplacement */
+ mem_area_v2 *area; /* Zone d'accueil désignée */
+ VMPA_BUFFER(loc); /* Description d'un emplacement*/
+ phys_t start; /* Point de départ */
+
+ type = g_binary_symbol_get_target_type(symbol);
+
+ if (!HAS_DATA_INSTR(type))
+ return;
+
+ list = g_binary_symbol_get_instruction(symbol);
+
+ for (iter = list; iter != NULL; iter = g_arch_instruction_get_next_iter(list, iter, ~0))
+ {
+ range = g_arch_instruction_get_range(iter);
+ addr = get_mrange_addr(range);
+
+ /* Une aire d'accueil existe-t-elle ? */
+
+ area = find_memory_area_by_addr_v2(areas, count, addr);
+
+ if (area == NULL)
+ {
+ vmpa2_virt_to_string(addr, MDS_UNDEFINED, loc, NULL);
+
+ log_variadic_message(LMT_WARNING, _("No place found for symbol located at %s."), loc);
+ continue;
+
+ }
+
+ /* L'instruction est-elle accueillie dans son intégralité ? */
+
+ start = compute_vmpa_diff(get_mrange_addr(&area->range), addr);
+
+ if (start + get_mrange_length(range) > get_mrange_length(&area->range))
+ {
+ vmpa2_virt_to_string(addr, MDS_UNDEFINED, loc, NULL);
+
+ log_variadic_message(LMT_WARNING, _("The symbol located at %s is too big for one place only."), loc);
+ continue;
+
+ }
+
+ /* Inscription d'une instruction de symbole (sans retour arrière possible :/ ) */
+
+ mark_range_in_mem_area_as_processed_v2(area, iter, true);
+
+ g_object_ref(G_OBJECT(iter));
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* 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 : - *
+* *
+******************************************************************************/
+
+void ensure_all_mem_areas_are_filled(mem_area_v2 *list, size_t count, GProcContext *ctx, status_blob_info *info)
+{
+ size_t i; /* Boucle de parcours */
+
+ for (i = 0; i < count; i++)
+ fill_mem_area_v2(&list[i], list, count, ctx, info);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : areas = série d'aires représentant à contenu à parcourir. *
+* count = nombre de ces zones présentes. *
+* *
+* Description : Rassemble les instructions conservées dans des zones données.*
+* *
+* Retour : Liste d'instructions prêtes à emploi. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *collect_instructions_from_mem_areas_v2(const mem_area_v2 *list, size_t count)
+{
+ GArchInstruction *result; /* Liste d'instr. à renvoyer */
+ size_t i; /* Boucle de parcours */
+ GArchInstruction *instr; /* Instruction(s) à insérer */
+
+ result = NULL;
+
+ for (i = 0; i < count; i++)
+ {
+ instr = get_instructions_from_mem_area_v2(&list[i]);
+ g_arch_instruction_merge_lists(&result, &instr);
+ }
+
+ return result;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//////////////////////////////////::://////////////////////////////////////////////////////////////////////
+//////////////////////////////////::://////////////////////////////////////////////////////////////////////
+//////////////////////////////////::://////////////////////////////////////////////////////////////////////
+//////////////////////////////////::://////////////////////////////////////////////////////////////////////
+//////////////////////////////////::://////////////////////////////////////////////////////////////////////
+//////////////////////////////////::://////////////////////////////////////////////////////////////////////
+//////////////////////////////////::://////////////////////////////////////////////////////////////////////
+//////////////////////////////////::://////////////////////////////////////////////////////////////////////
+//////////////////////////////////::://////////////////////////////////////////////////////////////////////
+//////////////////////////////////::://////////////////////////////////////////////////////////////////////
+//////////////////////////////////::://////////////////////////////////////////////////////////////////////
+//////////////////////////////////::://////////////////////////////////////////////////////////////////////
+//////////////////////////////////::://////////////////////////////////////////////////////////////////////
+//////////////////////////////////::://////////////////////////////////////////////////////////////////////
+//////////////////////////////////::://////////////////////////////////////////////////////////////////////
+//////////////////////////////////::://////////////////////////////////////////////////////////////////////
+//////////////////////////////////::://////////////////////////////////////////////////////////////////////
+//////////////////////////////////::://////////////////////////////////////////////////////////////////////
+//////////////////////////////////::://////////////////////////////////////////////////////////////////////
+
+
+
/* Zone mémoire bien bornée */
typedef struct _mem_area
@@ -72,7 +1153,7 @@ static bool mark_range_in_mem_area_as_processed(mem_area *, phys_t, phys_t, GArc
/* S'assure de la présence d'un début de routine à un point. */
-static void update_address_as_routine(GBinFormat *, const vmpa2t *);
+//static void update_address_as_routine(GBinFormat *, const vmpa2t *);
@@ -1468,8 +2549,6 @@ static bool insert_extra_symbol_into_mem_areas(mem_area **list, size_t *count, G
memmove(&(*list)[index + 1], &(*list)[index], (*count - index - 1) * sizeof(mem_area));
- /* Aire raccourcie */
-
copy_vmpa(&area_pos, get_mrange_addr(&area_range));
new_length = get_mrange_length(&area_range) - get_mrange_length(sym_range);
diff --git a/src/analysis/disass/area.h b/src/analysis/disass/area.h
index 35a3533..aa26da0 100644
--- a/src/analysis/disass/area.h
+++ b/src/analysis/disass/area.h
@@ -25,10 +25,52 @@
#define _ANALYSIS_DISASS_AREA_H
+#include "../binary.h"
+#include "../../arch/instruction.h"
+#include "../../gtkext/gtkextstatusbar.h"
+
+
+
+
+/* Zone mémoire bien bornée */
+typedef struct _mem_area_v2 mem_area_v2;
+
+
+
+
+
+/* Procède au désassemblage d'un contenu binaire exécutable. */
+void load_code_from_mem_area_v2(mem_area_v2 *, mem_area_v2 *, size_t, GProcContext *, const vmpa2t *, status_blob_info *);
+
+
+
+
+/* Détermine une liste de zones contigües à traiter. */
+mem_area_v2 *find_memory_area_by_addr_v2(mem_area_v2 *, size_t, const vmpa2t *);
+
+
+
+/* Détermine une liste de zones contigües à traiter. */
+mem_area_v2 *compute_memory_areas_v2(const GLoadedBinary *, phys_t, size_t *);
+
+/* Insère un symbole dans un découpage en aires. */
+void insert_extra_symbol_into_mem_areas_v2(mem_area_v2 *, 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_v2 *, size_t, GProcContext *, status_blob_info *);
+
+/* Rassemble les instructions conservées dans des zones données. */
+GArchInstruction *collect_instructions_from_mem_areas_v2(const mem_area_v2 *, size_t);
+
+
+
+
+
#include <stdbool.h>
+
#include "../binary.h"
#include "../../format/executable.h"
#include "../../gtkext/gtkextstatusbar.h"
@@ -48,6 +90,7 @@ typedef struct _mem_area mem_area;
+
/* Procède au désassemblage d'un contenu binaire exécutable. */
bool load_code_from_mem_area(mem_area **, size_t *, size_t *, const GLoadedBinary *, GProcContext *, const vmpa2t *, status_blob_info *);
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index ce49aca..ce2e6ff 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -190,6 +190,8 @@ static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GAr
static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtStatusBar *statusbar)
{
+ wgroup_id_t gid; /* Identifiant pour les tâches */
+
//GBinFormat *format; /* Format du fichier binaire */
GArchProcessor *proc; /* Architecture du binaire */
@@ -208,6 +210,13 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta
//GArchProcessor *proc; /* Architecture du binaire */
+
+ gid = g_work_queue_define_work_group(get_work_queue());
+
+
+
+
+
//format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
proc = g_loaded_binary_get_processor(disass->binary);
@@ -225,7 +234,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta
- *disass->instrs = disassemble_binary_content(disass->binary, statusbar);
+ *disass->instrs = disassemble_binary_content(disass->binary, gid, statusbar);
g_arch_processor_set_disassembled_instructions(proc, *disass->instrs);
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;
diff --git a/src/analysis/disass/fetch.h b/src/analysis/disass/fetch.h
index 0270f78..37dac80 100644
--- a/src/analysis/disass/fetch.h
+++ b/src/analysis/disass/fetch.h
@@ -26,12 +26,13 @@
#include "../binary.h"
+#include "../../glibext/delayed.h"
#include "../../gtkext/gtkextstatusbar.h"
/* Procède au désassemblage basique d'un contenu binaire. */
-GArchInstruction *disassemble_binary_content(const GLoadedBinary *, GtkExtStatusBar *);
+GArchInstruction *disassemble_binary_content(const GLoadedBinary *, wgroup_id_t, GtkExtStatusBar *);