diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2018-04-21 22:00:00 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2018-04-21 22:00:00 (GMT) |
commit | 8eb95d316f7b6fbad0ff798abfe7f70f89e812d2 (patch) | |
tree | 4f310c7ffdb94d48fff236e63c7e6f0ed9f1dee1 /src/analysis/disass | |
parent | 315146a49b5570294ca20beca720c4e3f74a86bd (diff) |
Improved the way file formats are detected and loaded.
Diffstat (limited to 'src/analysis/disass')
-rw-r--r-- | src/analysis/disass/disassembler.c | 534 | ||||
-rw-r--r-- | src/analysis/disass/disassembler.h | 34 | ||||
-rw-r--r-- | src/analysis/disass/fetch.c | 2 |
3 files changed, 131 insertions, 439 deletions
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c index 6c63b0b..dded65b 100644 --- a/src/analysis/disass/disassembler.c +++ b/src/analysis/disass/disassembler.c @@ -33,13 +33,10 @@ #include "fetch.h" -#include "output.h" - #include "instructions.h" +#include "output.h" #include "routines.h" #include "../../core/global.h" -#include "../../format/format.h" -#include "../../glibext/delayed-int.h" #include "../../glibext/generators/prologue.h" #include "../../plugins/pglist.h" @@ -49,190 +46,18 @@ -/* ------------------------ DESASSEMBLAGE DE BINAIRE DIFFERE ------------------------ */ - - -/* Ensembles binaires à désassembler (instance) */ -struct _GDelayedDisassembly -{ - GDelayedWork parent; /* A laisser en premier */ - - GLoadedBinary *binary; /* Destinataire final */ - GExeFormat *format; /* Format du binaire représenté*/ - GCodingLanguage *lang; /* Traduction en ASM préférée */ - - GBufferCache *cache; /* Tampon pour le rendu */ - -}; - -/* Ensembles binaires à désassembler (classe) */ -struct _GDelayedDisassemblyClass -{ - GDelayedWorkClass parent; /* A laisser en premier */ - -}; - - -/* 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 *); - -/* Supprime toutes les références externes. */ -static void g_delayed_disassembly_dispose(GDelayedDisassembly *); - -/* Procède à la libération totale de la mémoire. */ -static void g_delayed_disassembly_finalize(GDelayedDisassembly *); - -/* Crée une tâche de désassemblage différé. */ -static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *, GBufferCache *); - /* Opère sur toutes les instructions. */ static void process_all_instructions(wgroup_id_t, GtkStatusStack *, const char *, ins_fallback_cb, GArchProcessor *, GProcContext *, GExeFormat *); /* Opère sur toutes les routines. */ static void process_all_routines(wgroup_id_t, GtkStatusStack *, const char *, rtn_fallback_cb, GArchProcessor *, GBinFormat *); -/* Assure le désassemblage en différé. */ -static void g_delayed_disassembly_process(GDelayedDisassembly *, GtkStatusStack *); - - - -/* -------------------------- GESTION GLOBALE DE PROCEDURE -------------------------- */ - - -/* Construit la description d'introduction du désassemblage. */ -static void build_disass_prologue(GBufferCache *, const GBinFormat *, const GCodingLanguage *, const char *, const char *); - - - -/* ---------------------------------------------------------------------------------- */ -/* 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 : klass = classe à initialiser. * -* * -* Description : Initialise la classe des tâches de désassemblage différé. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_delayed_disassembly_class_init(GDelayedDisassemblyClass *klass) -{ - GObjectClass *object; /* Autre version de la classe */ - GDelayedWorkClass *work; /* Version en classe parente */ - - object = G_OBJECT_CLASS(klass); - - object->dispose = (GObjectFinalizeFunc/* ! */)g_delayed_disassembly_dispose; - object->finalize = (GObjectFinalizeFunc)g_delayed_disassembly_finalize; - - work = G_DELAYED_WORK_CLASS(klass); - - work->run = (run_task_fc)g_delayed_disassembly_process; - -} - - -/****************************************************************************** -* * -* Paramètres : disass = instance à initialiser. * -* * -* Description : Initialise une tâche de désassemblage différé. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_delayed_disassembly_init(GDelayedDisassembly *disass) -{ - -} - - -/****************************************************************************** -* * -* Paramètres : disass = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_delayed_disassembly_dispose(GDelayedDisassembly *disass) -{ - g_object_unref(G_OBJECT(disass->format)); - g_object_unref(G_OBJECT(disass->lang)); - - G_OBJECT_CLASS(g_delayed_disassembly_parent_class)->dispose(G_OBJECT(disass)); - -} - - -/****************************************************************************** -* * -* Paramètres : disass = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ +/* Réalise un désassemblage effectif. */ +static void compute_disassembly(GLoadedBinary *, GProcContext *, wgroup_id_t, GtkStatusStack *); -static void g_delayed_disassembly_finalize(GDelayedDisassembly *disass) -{ - G_OBJECT_CLASS(g_delayed_disassembly_parent_class)->finalize(G_OBJECT(disass)); +/* Imprime le résultat d'un désassemblage. */ +static void output_disassembly(GLoadedBinary *, GProcContext *, GtkStatusStack *, GBufferCache **); -} - - -/****************************************************************************** -* * -* Paramètres : binary = binaire chargé en attente des résultats. * -* format = format du binaire représenté. * -* buffer = tampon de sortie pour les instructions. * -* * -* Description : Crée une tâche de désassemblage différé. * -* * -* Retour : Tâche créée. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GBufferCache *cache) -{ - GDelayedDisassembly *result; /* Tâche à retourner */ - - result = g_object_new(G_TYPE_DELAYED_DISASSEMBLY, NULL); - - result->binary = binary; - result->format = g_loaded_binary_get_format(binary); - result->lang = g_asm_language_new(); - - result->cache = cache; - - return result; - -} /****************************************************************************** @@ -374,10 +199,12 @@ static void process_all_routines(wgroup_id_t gid, GtkStatusStack *status, const /****************************************************************************** * * -* Paramètres : disass = analyse à mener. * -* status = barre de statut à tenir informée. * +* Paramètres : binary = représentation de binaire chargé. * +* context = contexte de désassemblage utilisé. * +* gid = groupe de travail dédié. * +* status = barre de statut à tenir informée. * * * -* Description : Assure le désassemblage en différé. * +* Description : Réalise un désassemblage effectif. * * * * Retour : - * * * @@ -385,249 +212,100 @@ static void process_all_routines(wgroup_id_t gid, GtkStatusStack *status, const * * ******************************************************************************/ -static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatusStack *status) +static void compute_disassembly(GLoadedBinary *binary, GProcContext *context, wgroup_id_t gid, GtkStatusStack *status) { - wgroup_id_t gid; /* Identifiant pour les tâches */ - - //GBinFormat *format; /* Format du fichier binaire */ GArchProcessor *proc; /* Architecture du binaire */ - GProcContext *ctx; /* Contexte de suivi dédié */ - - //size_t i; /* Boucle de parcours */ - + GExeFormat *format; /* Format du binaire représenté*/ GArchInstruction **instrs; /* Instructions résultantes */ size_t count; /* Quantité de ces instructions*/ + /** + * Récupération des objets utiles. + */ + proc = g_loaded_binary_get_processor(binary); - proc = g_loaded_binary_get_processor(disass->binary); - ctx = g_arch_processor_get_context(proc); - - - - gid = g_work_queue_define_work_group(get_work_queue()); - - - - - - - /* Première étape */ - - //id = gtk_extended_status_bar_push(statusbar, _("Disassembling..."), true); - - - - process_disassembly_event(PGA_DISASSEMBLY_STARTED, disass->binary); - - + format = g_loaded_binary_get_format(binary); - instrs = disassemble_binary_content(disass->binary, ctx, gid, status, &count); + /** + * Première étape : collecte des instructions. + */ + instrs = disassemble_binary_content(binary, context, gid, status, &count); g_arch_processor_set_instructions(proc, instrs, count); + process_disassembly_event(PGA_DISASSEMBLY_RAW, binary); - // plugins ////////////////////////// - process_disassembly_event(PGA_DISASSEMBLY_RAW, disass->binary); - - + /** + * Seconde étape : liaisons des instructions. + */ process_all_instructions(gid, status, _("Calling 'link' hook on all instructions..."), g_instructions_study_do_link_operation, - proc, ctx, disass->format); - - - // plugins ////////////////////////// - process_disassembly_event(PGA_DISASSEMBLY_HOOKED_LINK, disass->binary); - - - - //gtk_extended_status_bar_remove(statusbar, id); - + proc, context, format); - //run_plugins_on_binary(disass->binary, PGA_BINARY_DISASSEMBLED, true); + process_disassembly_event(PGA_DISASSEMBLY_HOOKED_LINK, binary); + /** + * Troisième étape : exécution d'éventuels post-traitements. + */ process_all_instructions(gid, status, _("Calling 'post' hook on all instructions..."), g_instructions_study_do_post_operation, - proc, ctx, disass->format); - - - - // plugins ////////////////////////// - process_disassembly_event(PGA_DISASSEMBLY_HOOKED_POST, disass->binary); - + proc, context, format); + process_disassembly_event(PGA_DISASSEMBLY_HOOKED_POST, binary); /** - * TODO : établir les couvertures de fonctions, - * pour être en mesure de disposer de résolution de type XXX+yyy lors - * de l'établissement des liens. + * Quatrième étape : établissement des couvertures de routines restantes. */ - - /* Seconde étape */ - - - - process_all_routines(gid, status, _("Finding remaining limits..."), - g_routines_study_compute_limits, proc, G_BIN_FORMAT(disass->format)); - - - - // plugins ////////////////////////// - process_disassembly_event(PGA_DISASSEMBLY_LIMITED, disass->binary); + g_routines_study_compute_limits, proc, G_BIN_FORMAT(format)); + process_disassembly_event(PGA_DISASSEMBLY_LIMITED, binary); - - /* Troisième étape */ + /** + * Cinquième étape : liaisons entre instructions. + */ process_all_instructions(gid, status, _("Establishing links betweek all instructions..."), g_instructions_study_establish_links, - proc, ctx, disass->format); - - - - // plugins ////////////////////////// - process_disassembly_event(PGA_DISASSEMBLY_LINKED, disass->binary); - - - - - - /* Quatrième étape */ - - // -- old -- id = gtk_extended_status_bar_push(statusbar, _("Detecting loops..."), true); - - // -- old -- detect_loops_in_code(proc, routines, routines_count, statusbar, 0/*id*/); - - // -- old -- gtk_extended_status_bar_remove(statusbar, 0/*id*/); - - /// + proc, context, format); - // plugins ////////////////////////// - // -- old -- process_disassembly_event(PGA_DISASSEMBLY_LOOPS, disass->binary); + process_disassembly_event(PGA_DISASSEMBLY_LINKED, binary); + /** + * Sixième étape : regroupement en blocs basiques. + */ - - - - - - - - - ////////////////////////////////////// - - - // Control-flow analysis... - -#if 1 process_all_routines(gid, status, _("Control-flow analysis for routines..."), - g_routines_study_handle_blocks, proc, G_BIN_FORMAT(disass->format)); -#endif - - - - - /* Cinquième étape */ - - // -- old -- id = gtk_extended_status_bar_push(statusbar, _("Grouping routines instructions..."), true); - - //qsort(routines, routines_count, sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_rcompare); + g_routines_study_handle_blocks, proc, G_BIN_FORMAT(format)); - // -- old -- group_routines_instructions(proc, routines, routines_count, statusbar, 0/*id*/); + process_disassembly_event(PGA_DISASSEMBLY_GROUPED, binary); - // -- old -- gtk_extended_status_bar_remove(statusbar, 0/*id*/); - - //run_plugins_on_binary(disass->binary, PGA_BINARY_GROUPED, true); - - - // -- old -- process_disassembly_event(PGA_DISASSEMBLY_GROUPED, disass->binary); - - - - - - /* Sixième étape */ - - // -- old -- id = gtk_extended_status_bar_push(statusbar, _("Ranking each instructions block..."), true); - - //qsort(routines, routines_count, sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_rcompare); - - // -- old -- rank_routines_blocks(routines, routines_count, statusbar, 0/*id*/); - - // -- old -- gtk_extended_status_bar_remove(statusbar, 0/*id*/); - - //run_plugins_on_binary(disass->binary, PGA_BINARY_GROUPED, true); - - - // -- old -- process_disassembly_event(PGA_DISASSEMBLY_RANKED, disass->binary); - - - - /* Septième étape */ - - //id = gtk_extended_status_bar_push(statusbar, _("Printing disassembled code..."), true); - - - - - print_disassembled_instructions(disass->cache, disass->lang, disass->binary, G_PRELOAD_INFO(ctx), status); - - - - - /* Rajout de tous les éléments mis en place automatiquement */ - - void add_to_collection(GDbItem *item, GLoadedBinary *binary) - { - g_object_ref(G_OBJECT(item)); - - g_loaded_binary_add_to_collection(binary, item); - - } - - g_proc_context_foreach_db_item(ctx, (GFunc)add_to_collection, disass->binary); - - /* Nettoyage final et sortie ! */ + /** + * Nettoyage final et sortie ! + */ - g_object_unref(G_OBJECT(ctx)); + g_object_unref(G_OBJECT(format)); g_object_unref(G_OBJECT(proc)); - process_disassembly_event(PGA_DISASSEMBLY_ENDED, disass->binary); - - - - //gtk_extended_status_bar_remove(statusbar, 0/*id*/); - - //run_plugins_on_binary(disass->binary, PGA_BINARY_PRINTED, true); - - - } - -/* ---------------------------------------------------------------------------------- */ -/* GESTION GLOBALE DE PROCEDURE */ -/* ---------------------------------------------------------------------------------- */ - - /****************************************************************************** * * -* Paramètres : cache = tampon de destination pour le texte. * -* format = format associé au contenu représenté. * -* lang = trauducteur pour l'impression finale. * -* filename = nom du fichier ciblé à décompiler. * -* checksum = empreinte identifiant le binaire chargé. * +* Paramètres : binary = représentation de binaire chargé. * +* context = contexte de désassemblage utilisé. * +* status = barre de statut à tenir informée. * +* cache = tampon de code mis en place. [OUT] * * * -* Description : Construit la description d'introduction du désassemblage. * +* Description : Imprime le résultat d'un désassemblage. * * * * Retour : - * * * @@ -635,31 +313,82 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatus * * ******************************************************************************/ -static void build_disass_prologue(GBufferCache *cache, const GBinFormat *format, const GCodingLanguage *lang, const char *filename, const char *checksum) +static void output_disassembly(GLoadedBinary *binary, GProcContext *context, GtkStatusStack *status, GBufferCache **cache) { + GBinFormat *format; /* Format associé au binaire */ + GBinContent *content; /* Contenu bianire manipulé */ + GCodingLanguage *lang; /* Langage de sortie préféré */ char **text; /* Contenu brute à imprimer */ + const char *desc; /* Désignation du binaire */ + const gchar *checksum; /* Identifiant de binaire */ GIntroGenerator *generator; /* Générateur constitué */ + /** + * Initialisation des biens communs. + */ + + format = G_BIN_FORMAT(g_loaded_binary_get_format(binary)); + content = g_binary_format_get_content(format); + lang = g_asm_language_new(); + + *cache = g_buffer_cache_new(content); + + /** + * Impression du prologue. + */ + text = calloc(4, sizeof(char *)); /* Introduction */ text[0] = strdup(_("Disassembly generated by Chrysalide")); - text[1] = strdup(_("Chrysalide is free software - © 2008-2016 Cyrille Bagard")); + text[1] = strdup(_("Chrysalide is free software - © 2008-2018 Cyrille Bagard")); /* Fichier */ - asprintf(&text[2], "%s%s", _("File: "), filename); + desc = g_binary_content_describe(content, true); + + asprintf(&text[2], "%s%s", _("Source: "), desc); /* Checksum SHA256 */ + checksum = g_binary_content_get_checksum(content); + asprintf(&text[3], "%s%s", _("Sha256: "), checksum); /* Intégration finale */ generator = g_intro_generator_new(format, lang, text, 4); - g_buffer_cache_append(cache, G_LINE_GENERATOR(generator), BLF_NONE); + g_buffer_cache_append(*cache, G_LINE_GENERATOR(generator), BLF_NONE); + + /** + * Impression des instructions désassemblées. + */ + + print_disassembled_instructions(*cache, lang, binary, G_PRELOAD_INFO(context), status); + + /** + * Rajout de tous les éléments mis en place automatiquement. + */ + + void add_to_collection(GDbItem *item, gpointer unused) + { + g_object_ref(G_OBJECT(item)); + + g_loaded_binary_add_to_collection(binary, item); + + } + + g_proc_context_foreach_db_item(context, (GFunc)add_to_collection, NULL); + + /** + * Nettoyage avant sortie. + */ + + g_object_unref(G_OBJECT(lang)); + g_object_unref(G_OBJECT(content)); + g_object_unref(G_OBJECT(format)); } @@ -667,11 +396,9 @@ static void build_disass_prologue(GBufferCache *cache, const GBinFormat *format, /****************************************************************************** * * * Paramètres : binary = représentation de binaire chargé. * -* parts = parties binaires à désassembler. * -* count = nombre de parties à traiter. * -* instrs = liste des instructions chargées. [OUT] * +* gid = groupe de travail dédié. * +* status = barre de statut à tenir informée. * * cache = tampon de code mis en place. [OUT] * -* ack = fonction à appeler une fois l'opération terminée. * * * * Description : Procède au désassemblage d'un contenu binaire donné. * * * @@ -681,38 +408,31 @@ static void build_disass_prologue(GBufferCache *cache, const GBinFormat *format, * * ******************************************************************************/ -void disassemble_binary(GLoadedBinary *binary, GBufferCache **cache, disassembly_ack_fc ack) +void disassemble_binary(GLoadedBinary *binary, wgroup_id_t gid, GtkStatusStack *status, GBufferCache **cache) { - GBinFormat *format; /* Format associé au binaire */ - GBinContent *content; /* Contenu bianire manipulé */ - GCodingLanguage *lang; /* Langage de sortie préféré */ - const char *desc; /* Désignation du binaire */ - const gchar *checksum; /* Identifiant de binaire */ - GDelayedDisassembly *disass; /* Désassemblage à mener */ - GWorkQueue *queue; /* Gestionnaire de différés */ + GArchProcessor *proc; /* Architecture du binaire */ + GProcContext *context; /* Contexte de suivi dédié */ - format = G_BIN_FORMAT(g_loaded_binary_get_format(binary)); - content = g_binary_format_get_content(format); + /* Préparatifs */ - *cache = g_buffer_cache_new(content); + process_disassembly_event(PGA_DISASSEMBLY_STARTED, binary); - lang = g_asm_language_new(); + proc = g_loaded_binary_get_processor(binary); - desc = g_binary_content_describe(content, true); - checksum = g_binary_content_get_checksum(content); + context = g_arch_processor_get_context(proc); - build_disass_prologue(*cache, format, lang, desc, checksum); + /* Lancement des opérations ! */ - g_object_unref(G_OBJECT(lang)); - g_object_unref(G_OBJECT(content)); - g_object_unref(G_OBJECT(format)); + compute_disassembly(binary, context, gid, status); - disass = g_delayed_disassembly_new(binary, *cache); + process_disassembly_event(PGA_DISASSEMBLY_ENDED, binary); - if (ack != NULL) - g_signal_connect(disass, "work-completed", G_CALLBACK(ack), binary); + output_disassembly(binary, context, status, cache); - queue = get_work_queue(); - g_work_queue_schedule_work(queue, G_DELAYED_WORK(disass), DEFAULT_WORK_GROUP); + /* Nettoyage final et sortie ! */ + + g_object_unref(G_OBJECT(context)); + + g_object_unref(G_OBJECT(proc)); } diff --git a/src/analysis/disass/disassembler.h b/src/analysis/disass/disassembler.h index a3fb74f..1adc9a1 100644 --- a/src/analysis/disass/disassembler.h +++ b/src/analysis/disass/disassembler.h @@ -26,40 +26,12 @@ #include "../binary.h" +#include "../../glibext/delayed.h" -/* ------------------------ DESASSEMBLAGE DE BINAIRE DIFFERE ------------------------ */ - - -#define G_TYPE_DELAYED_DISASSEMBLY g_delayed_disassembly_get_type() -#define G_DELAYED_DISASSEMBLY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_delayed_disassembly_get_type(), GDelayedDisassembly)) -#define G_IS_DELAYED_DISASSEMBLY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_delayed_disassembly_get_type())) -#define G_DELAYED_DISASSEMBLY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DELAYED_DISASSEMBLY, GDelayedDisassemblyClass)) -#define G_IS_DELAYED_DISASSEMBLY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DELAYED_DISASSEMBLY)) -#define G_DELAYED_DISASSEMBLY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DELAYED_DISASSEMBLY, GDelayedDisassemblyClass)) - - -/* Ensembles binaires à désassembler (instance) */ -typedef struct _GDelayedDisassembly GDelayedDisassembly; - -/* Ensembles binaires à désassembler (classe) */ -typedef struct _GDelayedDisassemblyClass GDelayedDisassemblyClass; - - -/* Indique le type défini pour les tâches de désassemblage différé. */ -GType g_delayed_disassembly_get_type(void); - - - -/* -------------------------- GESTION GLOBALE DE PROCEDURE -------------------------- */ - - -/* Acquitte la fin d'un désasemblage différé et complet. */ -typedef void (* disassembly_ack_fc) (GDelayedDisassembly *, GLoadedBinary *); - -/* Procède à la décompilation des routines d'un fichier donné. */ -void disassemble_binary(GLoadedBinary *, GBufferCache **, disassembly_ack_fc); +/* Procède au désassemblage d'un contenu binaire donné. */ +void disassemble_binary(GLoadedBinary *, wgroup_id_t, GtkStatusStack *, GBufferCache **); diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c index 55afe5a..934c755 100644 --- a/src/analysis/disass/fetch.c +++ b/src/analysis/disass/fetch.c @@ -395,7 +395,7 @@ static bool check_if_extra_wait_is_needed(GWorkQueue *queue, wgroup_id_t id, GPr GArchInstruction **disassemble_binary_content(GLoadedBinary *binary, GProcContext *ctx, wgroup_id_t gid, GtkStatusStack *status, size_t *count) { - GArchInstruction **result; /* Instruction désassemblées */ + GArchInstruction **result; /* Instruction désassemblées */ GDelayedFetching template; /* Patron des tâches à venir */ GBinFormat *format; /* Format du fichier binaire */ GBinContent *content; /* Contenu binaire à manipuler */ |