summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2012-12-16 21:55:04 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2012-12-16 21:55:04 (GMT)
commit64e09a6c3e39785975b5322973ed83734cedb82e (patch)
treea87d29cca9d86ccd26676460282ddf59c4e9cb17 /src
parent2581d80875304c466e8930dbe67986ceb95752b2 (diff)
Reintroduced the delayed disassembling of binaries.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@304 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src')
-rw-r--r--src/analysis/binary.c17
-rw-r--r--src/analysis/disass/disassembler.c40
-rw-r--r--src/analysis/disass/disassembler.h31
-rw-r--r--src/analysis/disass/output.c25
-rw-r--r--src/analysis/disass/output.h3
-rw-r--r--src/arch/instruction-int.h1
-rw-r--r--src/arch/instruction.c19
-rw-r--r--src/arch/instruction.h3
-rw-r--r--src/glibext/delayed.c4
-rw-r--r--src/gtkext/gtkextstatusbar.c19
-rw-r--r--src/main.c4
-rw-r--r--src/plugins/pglist.c12
-rw-r--r--src/plugins/pglist.h2
-rw-r--r--src/project.c6
14 files changed, 127 insertions, 59 deletions
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index 54beba7..ecf9c79 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -65,7 +65,7 @@ static bool g_loaded_binary_load_parts_from_xml(GLoadedBinary *, xmlXPathContext
static bool g_loaded_binary_save_parts(const GLoadedBinary *, xmlDocPtr, xmlXPathContextPtr, const char *);
/* Acquitte la fin d'un désasemblage différé et complet. */
-void ack_completed_disassembly(void/*GDelayedDisassembly*/ *, GLoadedBinary *);
+static void ack_completed_disassembly(GDelayedDisassembly *, GLoadedBinary *);
@@ -572,10 +572,11 @@ void g_loaded_binary_analyse(GLoadedBinary *binary)
}
disassemble_binary(binary, parts, parts_count,
- &binary->instrs, &binary->disass_buffer);
+ &binary->instrs, &binary->disass_buffer,
+ ack_completed_disassembly);
/* TODO : remme ! */
- ack_completed_disassembly(NULL, binary);
+ //ack_completed_disassembly(NULL, binary);
}
@@ -783,7 +784,7 @@ bool *g_loaded_binary_display_decomp_lines(GLoadedBinary *binary)
* *
******************************************************************************/
-void ack_completed_disassembly(void/*GDelayedDisassembly*/ *disass, GLoadedBinary *binary)
+void ack_completed_disassembly(GDelayedDisassembly *disass, GLoadedBinary *binary)
{
//GRenderingLine *line; /* "Première" ligne de rendu */
@@ -792,6 +793,10 @@ void ack_completed_disassembly(void/*GDelayedDisassembly*/ *disass, GLoadedBinar
const char * const *files; /* Liste de fichiers source */
+
+ g_object_unref(G_OBJECT(disass));
+
+
/* Décompilation... */
@@ -802,10 +807,10 @@ void ack_completed_disassembly(void/*GDelayedDisassembly*/ *disass, GLoadedBinar
if (binary->decbuf_count > 0)
{
binary->dec_buffers = (GCodeBuffer **)calloc(binary->decbuf_count, sizeof(GCodeBuffer *));
-
+ /*
for (i = 0; i < binary->decbuf_count; i++)
binary->dec_buffers[i] = decompile_all_from_file(binary, files[i]);
-
+ */
}
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index ee56043..e7c972d 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -48,16 +48,8 @@
/* ------------------------ 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
+struct _GDelayedDisassembly
{
GDelayedWork parent; /* A laisser en premier */
@@ -70,19 +62,16 @@ typedef struct _GDelayedDisassembly
GArchInstruction **instrs; /* Instructions résultantes */
GCodeBuffer *buffer; /* Tampon pour le rendu */
-} GDelayedDisassembly;
+};
/* Ensembles binaires à désassembler (classe) */
-typedef struct _GDelayedDisassemblyClass
+struct _GDelayedDisassemblyClass
{
GDelayedWorkClass parent; /* A laisser en premier */
-} GDelayedDisassemblyClass;
+};
-/* Indique le type défini pour les tâches de désassemblage différé. */
-static GType g_delayed_disassembly_get_type(void);
-
/* Initialise la classe des tâches de désassemblage différé. */
static void g_delayed_disassembly_class_init(GDelayedDisassemblyClass *);
@@ -99,6 +88,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *, GtkExtStatusBar
/* -------------------------- GESTION GLOBALE DE PROCEDURE -------------------------- */
+
/* Construit la description d'introduction du désassemblage. */
static void build_disass_prologue(GCodeBuffer *, const char *, const uint8_t *, off_t);
@@ -242,7 +232,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta
#endif
- run_plugins_on_binary(disass->binary, PGA_BINARY_DISASSEMBLED);
+ run_plugins_on_binary(disass->binary, PGA_BINARY_DISASSEMBLED, true);
/* Seconde étape */
@@ -252,7 +242,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta
gtk_extended_status_bar_remove(statusbar, id);
- run_plugins_on_binary(disass->binary, PGA_BINARY_LINKED);
+ run_plugins_on_binary(disass->binary, PGA_BINARY_LINKED, true);
/* Troisième étape */
@@ -264,7 +254,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta
gtk_extended_status_bar_remove(statusbar, id);
- run_plugins_on_binary(disass->binary, PGA_BINARY_BOUNDED);
+ run_plugins_on_binary(disass->binary, PGA_BINARY_BOUNDED, true);
/* Quatrième étape */
@@ -276,7 +266,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta
gtk_extended_status_bar_remove(statusbar, id);
- run_plugins_on_binary(disass->binary, PGA_BINARY_GROUPED);
+ run_plugins_on_binary(disass->binary, PGA_BINARY_GROUPED, true);
/* Cinquième étape */
@@ -285,11 +275,11 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta
qsort(routines, routines_count, sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_compare);
print_disassembled_instructions(disass->buffer, disass->format, *disass->instrs,
- routines, routines_count);
+ routines, routines_count, statusbar, id);
gtk_extended_status_bar_remove(statusbar, id);
- run_plugins_on_binary(disass->binary, PGA_BINARY_PRINTED);
+ run_plugins_on_binary(disass->binary, PGA_BINARY_PRINTED, true);
}
@@ -395,6 +385,7 @@ static void build_disass_prologue(GCodeBuffer *buffer, const char *filename, con
* count = nombre de parties à traiter. *
* instrs = liste des instructions chargées. [OUT] *
* buffer = 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é. *
* *
@@ -404,7 +395,7 @@ static void build_disass_prologue(GCodeBuffer *buffer, const char *filename, con
* *
******************************************************************************/
-void disassemble_binary(GLoadedBinary *binary, GBinPart **parts, size_t parts_count, GArchInstruction **instrs, GCodeBuffer **buffer)
+void disassemble_binary(GLoadedBinary *binary, GBinPart **parts, size_t parts_count, GArchInstruction **instrs, GCodeBuffer **buffer, disassembly_ack_fc ack)
{
const uint8_t *data; /* Données binaires brutes */
off_t length; /* Quantité de ces données */
@@ -417,12 +408,9 @@ void disassemble_binary(GLoadedBinary *binary, GBinPart **parts, size_t parts_co
build_disass_prologue(*buffer, g_loaded_binary_get_filename(binary, true), data, length);
disass = g_delayed_disassembly_new(binary, parts, parts_count, instrs, *buffer);
+ g_signal_connect(disass, "work-completed", G_CALLBACK(ack), binary);
queue = get_work_queue();
g_work_queue_schedule_work(queue, G_DELAYED_WORK(disass));
- g_delayed_work_wait_for_completion(G_DELAYED_WORK(disass));
-
- g_object_unref(G_OBJECT(disass));
-
}
diff --git a/src/analysis/disass/disassembler.h b/src/analysis/disass/disassembler.h
index 8cca194..b7c286c 100644
--- a/src/analysis/disass/disassembler.h
+++ b/src/analysis/disass/disassembler.h
@@ -30,8 +30,37 @@
+/* ------------------------ 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 *, GBinPart **parts, size_t parts_count, GArchInstruction **, GCodeBuffer **);
+void disassemble_binary(GLoadedBinary *, GBinPart **parts, size_t parts_count, GArchInstruction **, GCodeBuffer **, disassembly_ack_fc);
diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c
index 812b811..135168e 100644
--- a/src/analysis/disass/output.c
+++ b/src/analysis/disass/output.c
@@ -32,10 +32,13 @@
/******************************************************************************
* *
-* Paramètres : buffer = tampon de récueil des résultats d'impression. *
-* instrs = ensemble d'instructions à traiter. *
-* routines = liste de routines intervenant dans le flot. *
-* count = quantité de ces routines. *
+* Paramètres : buffer = tampon de récueil des résultats d'impression. *
+* format = format du binaire traité. *
+* instrs = ensemble d'instructions à traiter. *
+* routines = liste de routines intervenant dans le flot. *
+* count = quantité de ces routines. *
+* statusbar = barre de statut avec progression à mettre à jour.*
+* id = identifiant du message affiché à l'utilisateur. *
* *
* Description : Transcrit du code désassemblé en texte humainement lisible. *
* *
@@ -45,12 +48,14 @@
* *
******************************************************************************/
-void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *format, const GArchInstruction *instrs, GBinRoutine * const *routines, size_t count)
+void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *format, const GArchInstruction *instrs, GBinRoutine * const *routines, size_t count, GtkExtStatusBar *statusbar, guint id)
{
GLangOutput *output; /* Modèle de sortie adéquat */
GArchProcessor *proc; /* Architecture du binaire */
MemoryDataSize msize; /* Taille du bus d'adresses */
const bin_t *content; /* Contenu binaire global */
+ vmpa_t start; /* Adresse de départ */
+ vmpa_t end; /* Adresse de fin */
const GArchInstruction *iter; /* Boucle de parcours #1 */
size_t i; /* Boucle de parcours #2 */
vmpa_t iaddr; /* Adresse d'instruction */
@@ -63,16 +68,20 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form
content = g_binary_format_get_content(G_BIN_FORMAT(format), NULL);
+ g_arch_instruction_get_location(instrs, NULL, NULL, &start);
+ iter = g_arch_instruction_find_last(instrs);
+ g_arch_instruction_get_location(iter, NULL, NULL, &end);
+
for (iter = instrs, i = 0;
iter != NULL;
iter = g_arch_instruction_get_next_iter(instrs, iter, VMPA_MAX))
{
+ g_arch_instruction_get_location(iter, NULL, NULL, &iaddr);
+
/* Ajout des prototypes de fonction */
for (; i < count; i++)
{
- g_arch_instruction_get_location(iter, NULL, NULL, &iaddr);
raddr = g_binary_routine_get_address(routines[i]);
-
if (raddr > iaddr) break;
g_binary_routine_output_info(routines[i], output, buffer);
@@ -81,6 +90,8 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form
g_arch_instruction_print(iter, buffer, msize, content, ASX_INTEL);
+ gtk_extended_status_bar_update_activity(statusbar, id, (iaddr - start) * 1.0 / (end - start));
+
}
g_object_unref(G_OBJECT(output));
diff --git a/src/analysis/disass/output.h b/src/analysis/disass/output.h
index 7e0a3cc..81c028d 100644
--- a/src/analysis/disass/output.h
+++ b/src/analysis/disass/output.h
@@ -28,11 +28,12 @@
#include "../routine.h"
#include "../../arch/instruction.h"
#include "../../glibext/gcodebuffer.h"
+#include "../../gtkext/gtkextstatusbar.h"
/* Transcrit du code désassemblé en texte humainement lisible. */
-void print_disassembled_instructions(GCodeBuffer *, const GExeFormat *, const GArchInstruction *, GBinRoutine * const *, size_t);
+void print_disassembled_instructions(GCodeBuffer *, const GExeFormat *, const GArchInstruction *, GBinRoutine * const *, size_t, GtkExtStatusBar *, guint);
diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h
index af72a87..25d65e5 100644
--- a/src/arch/instruction-int.h
+++ b/src/arch/instruction-int.h
@@ -87,6 +87,7 @@ struct _GArchInstructionClass
};
+#define ainstr_list_last(head) dl_list_last(head, GArchInstruction, flow)
#define ainstr_list_prev_iter(iter, head) dl_list_prev_iter(iter, head, GArchInstruction, flow)
#define ainstr_list_next_iter(iter, head) dl_list_next_iter(iter, head, GArchInstruction, flow)
#define ainstr_list_add_tail(new, head) dl_list_add_tail(new, head, GArchInstruction, flow)
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index a45e8fa..b460b37 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -623,6 +623,25 @@ GDecInstruction *g_arch_instruction_decompile(const GArchInstruction *instr, GDe
/******************************************************************************
* *
+* Paramètres : list = liste d'instructions à consulter. *
+* *
+* Description : Renvoie vers la dernière instruction d'une série. *
+* *
+* Retour : Dernière instruction trouvée (ou NULL ?!). *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *g_arch_instruction_find_last(const GArchInstruction *list)
+{
+ return ainstr_list_last(list);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : list = liste d'instructions à compléter, ou NULL. *
* instr = nouvelle instruction à intégrer à l'ensemble. *
* *
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index 8963284..2eddc3c 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -136,6 +136,9 @@ GDecInstruction *g_arch_instruction_decompile(const GArchInstruction *, GDecCont
/* -------------------- TRAITEMENT DES INSTRUCTIONS PAR ENSEMBLE -------------------- */
+/* Renvoie vers la dernière instruction d'une série. */
+GArchInstruction *g_arch_instruction_find_last(const GArchInstruction *);
+
/* Ajoute une instruction à un ensemble existant. */
void g_arch_instruction_add_to_list(GArchInstruction **, GArchInstruction *);
diff --git a/src/glibext/delayed.c b/src/glibext/delayed.c
index a183449..e4dc37e 100644
--- a/src/glibext/delayed.c
+++ b/src/glibext/delayed.c
@@ -266,8 +266,6 @@ static void g_delayed_work_process(GDelayedWork *work, GtkExtStatusBar *statusba
{
work->run(work, statusbar);
- g_signal_emit_by_name(work, "work-completed");
-
g_mutex_lock(work->mutex);
work->completed = true;
@@ -275,6 +273,8 @@ static void g_delayed_work_process(GDelayedWork *work, GtkExtStatusBar *statusba
g_cond_signal(work->cond);
g_mutex_unlock(work->mutex);
+ g_signal_emit_by_name(work, "work-completed");
+
}
diff --git a/src/gtkext/gtkextstatusbar.c b/src/gtkext/gtkextstatusbar.c
index c89cfe4..dfb08d7 100644
--- a/src/gtkext/gtkextstatusbar.c
+++ b/src/gtkext/gtkextstatusbar.c
@@ -124,7 +124,7 @@ guint gtk_extended_status_bar_push(GtkExtStatusBar *bar, const gchar *message, g
{
guint result; /* Identifiant à retourner */
- //gdk_threads_enter();
+ gdk_threads_enter();
result = gtk_statusbar_push(GTK_STATUSBAR(bar), bar->context, message);
@@ -145,9 +145,8 @@ guint gtk_extended_status_bar_push(GtkExtStatusBar *bar, const gchar *message, g
}
else gtk_widget_hide(GTK_WIDGET(bar->progress));
- //gdk_flush ();
-
- //gdk_threads_leave();
+ gdk_flush();
+ gdk_threads_leave();
return result;
@@ -181,12 +180,13 @@ void gtk_extended_status_bar_update_activity(GtkExtStatusBar *bar, guint id, gdo
g_snprintf(percent, 5, "%.0f%%", value * 100);
- //gdk_threads_enter();
+ gdk_threads_enter();
gtk_progress_bar_set_fraction(bar->progress, value);
gtk_progress_bar_set_text(bar->progress, percent);
- //gdk_threads_leave();
+ gdk_flush();
+ gdk_threads_leave();
}
@@ -210,7 +210,7 @@ void gtk_extended_status_bar_remove(GtkExtStatusBar *bar, guint id)
{
size_t i; /* Boucle de parcours */
- //gdk_threads_enter();
+ gdk_threads_enter();
gtk_statusbar_remove(GTK_STATUSBAR(bar), bar->context, id);
@@ -234,8 +234,7 @@ void gtk_extended_status_bar_remove(GtkExtStatusBar *bar, guint id)
else
gtk_widget_hide(GTK_WIDGET(bar->progress));
- //gdk_flush ();
-
- //gdk_threads_leave();
+ gdk_flush();
+ gdk_threads_leave();
}
diff --git a/src/main.c b/src/main.c
index 09d9998..8612b1d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -117,6 +117,7 @@ int main(int argc, char **argv)
/* init threads */
g_thread_init(NULL);
gdk_threads_init();
+ gdk_threads_enter();
/* Initialisation de GTK */
setlocale (LC_ALL, "");
@@ -160,9 +161,8 @@ int main(int argc, char **argv)
/* Exécution du programme */
- //gdk_threads_enter();
gtk_main();
- //gdk_threads_leave();
+ gdk_threads_leave();
exit_global_pango_context();
diff --git a/src/plugins/pglist.c b/src/plugins/pglist.c
index 14e6b48..bca3e6a 100644
--- a/src/plugins/pglist.c
+++ b/src/plugins/pglist.c
@@ -263,6 +263,7 @@ void add_plugin_to_main_list(GPluginModule *plugin)
* *
* Paramètres : binary = binaire chargé en mémoire à traiter. *
* action = fonctionnalité recherchée. *
+* lock = indique si l'exécution n'est pas celle principale. *
* *
* Description : Opère une action donnée sur un binaire défini. *
* *
@@ -272,12 +273,21 @@ void add_plugin_to_main_list(GPluginModule *plugin)
* *
******************************************************************************/
-void run_plugins_on_binary(GLoadedBinary *binary, PluginAction action)
+void run_plugins_on_binary(GLoadedBinary *binary, PluginAction action, bool lock)
{
size_t i; /* Boucle de parcours */
+ if (lock)
+ gdk_threads_enter();
+
for (i = 0; i < _list.plugins_count; i++)
if (g_plugin_module_get_action(_list.plugins[i]) & action)
g_plugin_module_execute_action_on_binary(_list.plugins[i], binary, action);
+ if (lock)
+ {
+ gdk_flush();
+ gdk_threads_leave();
+ }
+
}
diff --git a/src/plugins/pglist.h b/src/plugins/pglist.h
index 2804108..e77bc8b 100644
--- a/src/plugins/pglist.h
+++ b/src/plugins/pglist.h
@@ -45,7 +45,7 @@ GPluginModule *get_one_plugin_for_action(PluginAction);
GPluginModule **get_all_plugins_for_action(PluginAction, size_t *) __attribute__ ((deprecated));
/*Opère une action donnée sur un binaire défini. */
-void run_plugins_on_binary(GLoadedBinary *, PluginAction);
+void run_plugins_on_binary(GLoadedBinary *, PluginAction, bool);
diff --git a/src/project.c b/src/project.c
index ca49954..8a8f803 100644
--- a/src/project.c
+++ b/src/project.c
@@ -325,12 +325,14 @@ void g_study_project_add_loaded_binary(GLoadedBinary *binary, GStudyProject *pro
{
size_t index; /* Indice du nouveau binaire */
+ gdk_threads_enter();
+
index = g_study_project_attach_binary(project, binary);
g_panel_item_dock(G_PANEL_ITEM(project->binaries[index]->item));
- //gdk_flush ();
- //gdk_threads_leave();
+ gdk_flush();
+ gdk_threads_leave();
}