From f4dbbab3190d13e61f125eea51a0ecec2ab9e897 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Tue, 18 Dec 2012 22:44:24 +0000
Subject: Created a proper panel for the Android permissions in the editor.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@305 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                               |  75 ++++++
 configure.ac                            |   1 +
 plugins/pychrysa/Makefile.am            |   4 +-
 plugins/pychrysa/glibext/module.c       |   2 +-
 plugins/pychrysa/gtkext/Makefile.am     |  17 ++
 plugins/pychrysa/gtkext/module.c        |  66 +++++
 plugins/pychrysa/gtkext/module.h        |  39 +++
 plugins/pychrysa/gtkext/viewpanel.c     | 214 ++++++++++++++++
 plugins/pychrysa/gtkext/viewpanel.h     |  44 ++++
 plugins/pychrysa/gui/Makefile.am        |   1 +
 plugins/pychrysa/gui/editem.c           | 441 ++++++++++++++++++++++++++++++++
 plugins/pychrysa/gui/editem.h           |  39 +++
 plugins/pychrysa/gui/module.c           |   2 +
 plugins/pychrysa/gui/panels/panel.c     |  33 +--
 plugins/pychrysa/gui/panels/panel.h     |   4 +-
 plugins/pychrysa/helpers.c              |  63 +++++
 plugins/pychrysa/helpers.h              |  37 +++
 plugins/pychrysa/plugin.c               | 129 +++++++---
 plugins/pychrysa/pychrysa.c             |   2 +
 plugins/pychrysa/quirks.c               |  29 +++
 plugins/pychrysa/quirks.h               |   3 +
 plugins/python/androperms/Makefile.am   |   1 +
 plugins/python/androperms/androperms.py |  91 ++-----
 plugins/python/androperms/db.py         |  94 +++++++
 plugins/python/androperms/panel.py      | 121 +++++----
 src/analysis/blocks/flow.c              |   4 +-
 src/analysis/disass/disassembler.c      |   4 +-
 src/analysis/disass/macro.c             |   4 +-
 src/plugins/pglist.c                    |  15 +-
 src/plugins/plugin-int.h                |   3 +-
 src/plugins/plugin.c                    |  10 +-
 src/plugins/plugin.h                    |   2 +-
 32 files changed, 1411 insertions(+), 183 deletions(-)
 create mode 100644 plugins/pychrysa/gtkext/Makefile.am
 create mode 100644 plugins/pychrysa/gtkext/module.c
 create mode 100644 plugins/pychrysa/gtkext/module.h
 create mode 100644 plugins/pychrysa/gtkext/viewpanel.c
 create mode 100644 plugins/pychrysa/gtkext/viewpanel.h
 create mode 100644 plugins/pychrysa/gui/editem.c
 create mode 100644 plugins/pychrysa/gui/editem.h
 create mode 100644 plugins/pychrysa/helpers.c
 create mode 100644 plugins/pychrysa/helpers.h
 create mode 100644 plugins/python/androperms/db.py

diff --git a/ChangeLog b/ChangeLog
index d797246..070bd51 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,78 @@
+12-12-18  Cyrille Bagard <nocbos@gmail.com>
+
+	* configure.ac:
+	Add the new Makfile from the 'plugins/pychrysa/gtkext directory to
+	AC_CONFIG_FILES.
+
+	* plugins/pychrysa/glibext/module.c:
+	Typo.
+
+	* plugins/pychrysa/gtkext/Makefile.am:
+	* plugins/pychrysa/gtkext/module.c:
+	* plugins/pychrysa/gtkext/module.h:
+	* plugins/pychrysa/gtkext/viewpanel.c:
+	* plugins/pychrysa/gtkext/viewpanel.h:
+	New entries: introduce a little support of view panels in Python.
+
+	* plugins/pychrysa/gui/editem.c:
+	* plugins/pychrysa/gui/editem.h:
+	New entries: create editor items in Python.
+
+	* plugins/pychrysa/gui/Makefile.am:
+	Add the 'editem.[ch]' files to libpychrysagui_la_SOURCES.
+
+	* plugins/pychrysa/gui/module.c:
+	Load the EditorItem type.
+
+	* plugins/pychrysa/gui/panels/panel.c:
+	* plugins/pychrysa/gui/panels/panel.h:
+	Clean and update the code.
+
+	* plugins/pychrysa/helpers.c:
+	* plugins/pychrysa/helpers.h:
+	New entries: provide a simple public way to run Python methods from C code.
+
+	* plugins/pychrysa/Makefile.am:
+	Add the 'helpers.[ch]' files to pychrysa_la_SOURCES,
+	'gtkext/libpychrysagtkext.la' to and pychrysa_la_LIBADD and
+	'gtkext' to SUBDIRS.
+
+	* plugins/pychrysa/plugin.c:
+	Clean the code and init Python plugins as the real ones.
+
+	* plugins/pychrysa/pychrysa.c:
+	Load the gtkext module.
+
+	* plugins/pychrysa/quirks.c:
+	* plugins/pychrysa/quirks.h:
+	Add a dirty function to retrieve the Python object of an already
+	converted GLib object, without using the creation method of PyGObject.
+
+	* plugins/python/androperms/androperms.py:
+	Create a proper panel for the Android permissions in the editor.
+
+	* plugins/python/androperms/db.py:
+	New entry: group database access here.
+
+	* plugins/python/androperms/Makefile.am:
+	Add the 'db.py' file to androperms_DATA.
+
+	* plugins/python/androperms/panel.py:
+	Create a proper panel for the Android permissions in the editor.
+
+	* src/analysis/blocks/flow.c:
+	* src/analysis/disass/disassembler.c:
+	* src/analysis/disass/macro.c:
+	Disable debug output.
+
+	* src/plugins/pglist.c:
+	* src/plugins/plugin.c:
+	* src/plugins/plugin.h:
+	Init the plugins in a single place: before adding them to the main list.
+
+	* src/plugins/plugin-int.h:
+	Typo. Store the plugin filename.
+
 12-12-16  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/analysis/binary.c:
diff --git a/configure.ac b/configure.ac
index 34aff02..c1df58c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -243,6 +243,7 @@ AC_CONFIG_FILES([Makefile
                  plugins/pychrysa/format/Makefile
                  plugins/pychrysa/format/dex/Makefile
                  plugins/pychrysa/glibext/Makefile
+                 plugins/pychrysa/gtkext/Makefile
                  plugins/pychrysa/gui/Makefile
                  plugins/pychrysa/gui/panels/Makefile
                  plugins/python/Makefile
diff --git a/plugins/pychrysa/Makefile.am b/plugins/pychrysa/Makefile.am
index e027c91..25074cb 100644
--- a/plugins/pychrysa/Makefile.am
+++ b/plugins/pychrysa/Makefile.am
@@ -2,6 +2,7 @@
 pkglib_LTLIBRARIES = pychrysa.la
 
 pychrysa_la_SOURCES =					\
+	helpers.h helpers.c					\
 	plugin.h plugin.c					\
 	py_log.h py_log.c					\
 	pychrysa.h pychrysa.c				\
@@ -13,6 +14,7 @@ pychrysa_la_LIBADD =					\
 	debug/libpychrysadebug.la			\
 	format/libpychrysaformat.la			\
 	glibext/libpychrysaglibext.la		\
+	gtkext/libpychrysagtkext.la			\
 	gui/libpychrysagui.la
 
 pychrysa_la_LDFLAGS = -module -avoid-version $(LIBGTK_LIBS) $(LIBXML_LIBS) $(LIBPYTHON_LIBS) \
@@ -27,4 +29,4 @@ AM_CPPFLAGS =
 
 AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
 
-SUBDIRS = analysis arch debug format glibext gui
+SUBDIRS = analysis arch debug format glibext gtkext gui
diff --git a/plugins/pychrysa/glibext/module.c b/plugins/pychrysa/glibext/module.c
index b2ba4ab..2212c32 100644
--- a/plugins/pychrysa/glibext/module.c
+++ b/plugins/pychrysa/glibext/module.c
@@ -34,7 +34,7 @@
 *                                                                             *
 *  Paramètres  : module = module dont la définition est à compléter.          *
 *                                                                             *
-*  Description : Ajoute le module 'glibext' au module Python.                *
+*  Description : Ajoute le module 'glibext' au module Python.                 *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
diff --git a/plugins/pychrysa/gtkext/Makefile.am b/plugins/pychrysa/gtkext/Makefile.am
new file mode 100644
index 0000000..79cece8
--- /dev/null
+++ b/plugins/pychrysa/gtkext/Makefile.am
@@ -0,0 +1,17 @@
+
+noinst_LTLIBRARIES = libpychrysagtkext.la
+
+libpychrysagtkext_la_SOURCES =			\
+	viewpanel.h viewpanel.c				\
+	module.h module.c
+
+
+libpychrysagtkext_la_LDFLAGS = 
+
+
+INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+	-I../../../src
+
+AM_CPPFLAGS = 
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
diff --git a/plugins/pychrysa/gtkext/module.c b/plugins/pychrysa/gtkext/module.c
new file mode 100644
index 0000000..fb17633
--- /dev/null
+++ b/plugins/pychrysa/gtkext/module.c
@@ -0,0 +1,66 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire gtkext en tant que module
+ *
+ * Copyright (C) 2012 Cyrille Bagard
+ *
+ *  This file is part of OpenIDA.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "module.h"
+
+
+#include "viewpanel.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Ajoute le module 'gtkext' au module Python.                  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool add_gtkext_module_to_python_module(PyObject *super)
+{
+    bool result;
+    PyObject *module;
+    int ret;                                /* Bilan d'un appel            */
+
+    static PyMethodDef py_gtkext_methods[] = {
+        { NULL }
+    };
+
+    module = Py_InitModule("pychrysalide.gtkext", py_gtkext_methods);
+    if (module == NULL) return false;
+
+    Py_INCREF(module);
+    ret = PyModule_AddObject(super, "pychrysalide.gtkext", module);
+
+    result = (ret != 0);
+
+    result &= register_python_view_panel(module);
+
+    return result;
+
+}
diff --git a/plugins/pychrysa/gtkext/module.h b/plugins/pychrysa/gtkext/module.h
new file mode 100644
index 0000000..94d1eeb
--- /dev/null
+++ b/plugins/pychrysa/gtkext/module.h
@@ -0,0 +1,39 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire gtkext en tant que module
+ *
+ * Copyright (C) 2012 Cyrille Bagard
+ *
+ *  This file is part of OpenIDA.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYOIDA_GTKEXT_MODULE_H
+#define _PLUGINS_PYOIDA_GTKEXT_MODULE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Ajoute le module 'gtkext' au module Python. */
+bool add_gtkext_module_to_python_module(PyObject *);
+
+
+
+#endif  /* _PLUGINS_PYOIDA_GTKEXT_MODULE_H */
diff --git a/plugins/pychrysa/gtkext/viewpanel.c b/plugins/pychrysa/gtkext/viewpanel.c
new file mode 100644
index 0000000..c1108c2
--- /dev/null
+++ b/plugins/pychrysa/gtkext/viewpanel.c
@@ -0,0 +1,214 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * viewpanel.c - prototypes pour l'équivalent Python du fichier "gtkext/gtkviewpanel.c"
+ *
+ * Copyright (C) 2012 Cyrille Bagard
+ *
+ *  This file is part of OpenIDA.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "viewpanel.h"
+
+
+#include <pygobject.h>
+
+
+#include "../quirks.h"
+
+
+
+/* Crée un nouvel objet Python de type 'ViewPanel'. */
+static PyObject *py_view_panel_new(PyTypeObject *, PyObject *, PyObject *);
+
+/* S'assure qu'une adresse donnée est visible à l'écran. */
+static PyObject *py_view_panel_scroll_to_address(PyObject *, PyObject *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type = type de l'objet à instancier.                         *
+*                args = arguments fournis à l'appel.                          *
+*                kwds = arguments de type key=val fournis.                    *
+*                                                                             *
+*  Description : Crée un nouvel objet Python de type 'ViewPanel'.             *
+*                                                                             *
+*  Retour      : Instance Python mise en place.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_view_panel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+#if 0
+    PyObject *result;                       /* Instance à retourner        */
+    const char *name;                       /* Désignation humaine         */
+    const char *lname;                      /* Nom version longue          */
+    PyGObject *widget;                      /* Composant visuel du panneau */
+    const char *path;                       /* Placement à l'affichage     */
+    int ret;                                /* Bilan de lecture des args.  */
+    GEditorItem *item;                      /* Version GLib du format      */
+
+    ret = PyArg_ParseTuple(args, "ssOs", &name, &lname, &widget, &path);
+    if (!ret) return Py_None;
+
+    item = g_view_panel_new(get_internal_ref(), name, lname,
+                            GTK_WIDGET(pygobject_get(widget)), path);
+
+    result = py_view_panel_from_c(G_VIEW_PANEL(item));
+    g_object_unref(item);
+
+    return (PyObject *)result;
+#endif
+
+    /* FIXME */
+    return Py_None;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item = instance existante GLib.                              *
+*                                                                             *
+*  Description : Crée un nouvel objet Python de type 'ViewPanel'.             *
+*                                                                             *
+*  Retour      : Instance Python mise en place.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyObject *py_view_panel_from_c(GtkViewPanel *item)
+{
+    PyObject *module;                       /* Module d'appartenance       */
+    PyTypeObject *type;                     /* Type Python correspondant   */
+
+    module = PyImport_ImportModule("pychrysalide.gtkext");
+    type = (PyTypeObject *)PyObject_GetAttrString(module, "ViewPanel");
+    Py_DECREF(module);
+
+    pychrysalide_set_instance_data(G_OBJECT(item), type);
+
+    return pygobject_new(G_OBJECT(item));
+
+}
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe représentant un tampon de code.                *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : S'assure qu'une adresse donnée est visible à l'écran.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_view_panel_scroll_to_address(PyObject *self, PyObject *args)
+{
+    GtkViewPanel *panel;                    /* Panneau à manipuler         */
+    vmpa_t addr;                            /* Adresse demandée en visuel  */
+    int ret;                                /* Bilan de lecture des args.  */
+
+    panel = GTK_VIEW_PANEL(pygobject_get(self));
+
+    ret = PyArg_ParseTuple(args, "K", &addr);
+    if (!ret) return Py_None;
+
+    gtk_view_panel_scroll_to_address(panel, addr);
+
+    Py_RETURN_NONE;
+
+}
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide.gtkext.ViewPanel'.     *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool register_python_view_panel(PyObject *module)
+{
+    PyObject *parent_mod;                   /* Module Python-EditorItem    */
+    int ret;                                /* Bilan d'un appel            */
+
+    static PyMethodDef py_view_panel_methods[] = {
+        {
+            "scroll_to_address", (PyCFunction)py_view_panel_scroll_to_address,
+            METH_VARARGS,
+            "Ensure a given address is displayed in the view panel."
+        },
+        { NULL }
+    };
+
+    static PyGetSetDef py_view_panel_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_view_panel_type = {
+
+        PyObject_HEAD_INIT(NULL)
+
+        .tp_name        = "pychrysalide.gtkext.ViewPanel",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = "PyChrysalide view panel",
+
+        .tp_methods     = py_view_panel_methods,
+        .tp_getset      = py_view_panel_getseters,
+        .tp_new         = (newfunc)py_view_panel_new,
+        .tp_init        = (initproc)pychrysalide_allow_args_for_gobjects
+
+    };
+
+    parent_mod = PyImport_ImportModule("gtk");
+    if (parent_mod == NULL) return false;
+
+    py_view_panel_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(parent_mod, "Fixed");
+    Py_DECREF(parent_mod);
+
+    if (PyType_Ready(&py_view_panel_type) < 0)
+        return false;
+
+    Py_INCREF(&py_view_panel_type);
+    ret = PyModule_AddObject(module, "ViewPanel", (PyObject *)&py_view_panel_type);
+
+    return (ret == 0);
+
+}
diff --git a/plugins/pychrysa/gtkext/viewpanel.h b/plugins/pychrysa/gtkext/viewpanel.h
new file mode 100644
index 0000000..98b1150
--- /dev/null
+++ b/plugins/pychrysa/gtkext/viewpanel.h
@@ -0,0 +1,44 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * viewpanel.h - prototypes pour l'équivalent Python du fichier "gtkext/gtkviewpanel.h"
+ *
+ * Copyright (C) 2012 Cyrille Bagard
+ *
+ *  This file is part of OpenIDA.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSA_GTKEXT_MODULE_VIEW_PANEL_H
+#define _PLUGINS_PYCHRYSA_GTKEXT_MODULE_VIEW_PANEL_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+#include <gtkext/gtkviewpanel.h>
+
+
+
+/* Crée un nouvel objet Python de type 'ViewPanel'. */
+PyObject *py_view_panel_from_c(GtkViewPanel *);
+
+/* Prend en charge l'objet 'pychrysalide.gtkext.ViewPanel'. */
+bool register_python_view_panel(PyObject *module);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSA_GTKEXT_MODULE_VIEW_PANEL_H */
diff --git a/plugins/pychrysa/gui/Makefile.am b/plugins/pychrysa/gui/Makefile.am
index 48fde30..97c2d46 100644
--- a/plugins/pychrysa/gui/Makefile.am
+++ b/plugins/pychrysa/gui/Makefile.am
@@ -2,6 +2,7 @@
 noinst_LTLIBRARIES = libpychrysagui.la
 
 libpychrysagui_la_SOURCES =				\
+	editem.h editem.c					\
 	module.h module.c
 
 libpychrysagui_la_LIBADD =				\
diff --git a/plugins/pychrysa/gui/editem.c b/plugins/pychrysa/gui/editem.c
new file mode 100644
index 0000000..3b7a8b8
--- /dev/null
+++ b/plugins/pychrysa/gui/editem.c
@@ -0,0 +1,441 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * editem.c - prototypes pour l'équivalent Python du fichier "gui/editem.c"
+ *
+ * Copyright (C) 2012 Cyrille Bagard
+ *
+ *  This file is part of OpenIDA.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "editem.h"
+
+
+#include <pygobject.h>
+
+
+#include <gui/editem-int.h>
+
+
+#include "../helpers.h"
+#include "../quirks.h"
+
+
+#include "../analysis/binary.h"
+#include "../gtkext/viewpanel.h"
+
+
+
+/* Réagit à un changement du binaire courant. */
+static void _update_editor_item_for_binary_python_wrapper(GEditorItem *, GLoadedBinary *);
+
+/* Réagit à un changement de vue. */
+static void _update_editor_item_for_view_python_wrapper(GEditorItem *, GtkViewPanel *);
+
+/* Réagit à un changement de contenu. */
+static void _update_editor_item_for_view_content_python_wrapper(GEditorItem *, GtkViewPanel *);
+
+/* Réagit à un changement du binaire courant. */
+static PyObject *py_editor_item_update_for_binary(PyObject *, PyObject *);
+
+/* Réagit à un changement d'affichage principal de contenu. */
+static PyObject *py_editor_item_update_for_view(PyObject *, PyObject *);
+
+/* Réagit à un changement d'affichage principal de contenu. */
+static PyObject *py_editor_item_update_for_content(PyObject *, PyObject *);
+
+/* Fournit l'affichage de binaire courant. */
+static PyObject *py_editor_item_get_current_view(PyObject *, PyObject *);
+
+/* Procède à l'enregistrement d'un élément reactif de l'éditeur. */
+static PyObject *py_editor_item_register(PyObject *, PyObject *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item   = élément à actualiser.                               *
+*                binary = nouvelle instance de binaire analysé.               *
+*                                                                             *
+*  Description : Réagit à un changement du binaire courant.                   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void _update_editor_item_for_binary_python_wrapper(GEditorItem *item, GLoadedBinary *binary)
+{
+    PyObject *target;                       /* Version Python de l'élément */
+    PyObject *args;                         /* Arguments pour l'appel      */
+    PyObject *value;                        /* Retour obtenu               */
+
+    /**
+     * Normalement, l'objet Python est enregistré dans la liste de Chrysalide
+     * des éléments d'éditeur, via py_editor_item_register(), donc son compteur
+     * de références doit le maintenir en vie.
+     *
+     * On peut donc le récupérer directement depuis l'instane GLib, sans passer
+     * par la procédure de pygobject, qui obligerait à connaître le type précis
+     * de l'instance GLib manipulée.
+     */
+    target = pychrysalide_get_pygobject(G_OBJECT(item));
+
+    args = PyTuple_New(1);
+    PyTuple_SetItem(args, 0, py_loaded_binary_from_c(binary));
+
+    value = run_python_method(target, "update_for_binary", args);
+
+    Py_XDECREF(value);
+    Py_DECREF(args);
+    Py_DECREF(target);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item = élément à actualiser.                                 *
+*                view = nouveau panneau d'affichage actif.                    *
+*                                                                             *
+*  Description : Réagit à un changement de vue.                               *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void _update_editor_item_for_view_python_wrapper(GEditorItem *item, GtkViewPanel *view)
+{
+    PyObject *target;                       /* Version Python de l'élément */
+    PyObject *args;                         /* Arguments pour l'appel      */
+    PyObject *value;                        /* Retour obtenu               */
+
+    /**
+     * Normalement, l'objet Python est enregistré dans la liste de Chrysalide
+     * des éléments d'éditeur, via py_editor_item_register(), donc son compteur
+     * de références doit le maintenir en vie.
+     *
+     * On peut donc le récupérer directement depuis l'instane GLib, sans passer
+     * par la procédure de pygobject, qui obligerait à connaître le type précis
+     * de l'instance GLib manipulée.
+     */
+    target = pychrysalide_get_pygobject(G_OBJECT(item));
+
+    args = PyTuple_New(1);
+    PyTuple_SetItem(args, 0, py_view_panel_from_c(view));
+
+    value = run_python_method(target, "update_for_view", args);
+
+    Py_XDECREF(value);
+    Py_DECREF(args);
+    Py_DECREF(target);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item = élément à actualiser.                                 *
+*                view = nouveau panneau d'affichage actif.                    *
+*                                                                             *
+*  Description : Réagit à un changement de contenu.                           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void _update_editor_item_for_view_content_python_wrapper(GEditorItem *item, GtkViewPanel *view)
+{
+    PyObject *target;                       /* Version Python de l'élément */
+    PyObject *args;                         /* Arguments pour l'appel      */
+    PyObject *value;                        /* Retour obtenu               */
+
+    /**
+     * Normalement, l'objet Python est enregistré dans la liste de Chrysalide
+     * des éléments d'éditeur, via py_editor_item_register(), donc son compteur
+     * de références doit le maintenir en vie.
+     *
+     * On peut donc le récupérer directement depuis l'instane GLib, sans passer
+     * par la procédure de pygobject, qui obligerait à connaître le type précis
+     * de l'instance GLib manipulée.
+     */
+    target = pychrysalide_get_pygobject(G_OBJECT(item));
+
+    args = PyTuple_New(1);
+    PyTuple_SetItem(args, 0, py_view_panel_from_c(view));
+
+    value = run_python_method(target, "update_for_content", args);
+
+    Py_XDECREF(value);
+    Py_DECREF(args);
+    Py_DECREF(target);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe représentant un binaire.                       *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Réagit à un changement du binaire courant.                   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_editor_item_update_for_binary(PyObject *self, PyObject *args)
+{
+    Py_RETURN_NONE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe représentant un binaire.                       *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Réagit à un changement d'affichage principal de contenu.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_editor_item_update_for_view(PyObject *self, PyObject *args)
+{
+    Py_RETURN_NONE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe représentant un binaire.                       *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Réagit à un changement d'affichage principal de contenu.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_editor_item_update_for_content(PyObject *self, PyObject *args)
+{
+    Py_RETURN_NONE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe représentant un binaire.                       *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Fournit le gestionnaire du binaire courant.                  *
+*                                                                             *
+*  Retour      : Instance en place ou Py_None si aucune.                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_editor_item_get_current_binary(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Résultat à retourner        */
+    GEditorItem *item;                      /* Elément à manipuler         */
+    GLoadedBinary *binary;                  /* Instance à convertir        */
+
+    item = G_EDITOR_ITEM(pygobject_get(self));
+    binary = g_editor_item_get_current_binary(item);
+
+    if (binary == NULL)
+    {
+        Py_INCREF(Py_None);
+        result = Py_None;
+    }
+    else
+        result = py_loaded_binary_from_c(binary);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe représentant un binaire.                       *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Fournit l'affichage de binaire courant.                      *
+*                                                                             *
+*  Retour      : Instance en place ou Py_None si aucune.                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_editor_item_get_current_view(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Résultat à retourner        */
+    GEditorItem *item;                      /* Elément à manipuler         */
+    GtkViewPanel *panel;                    /* Instance à convertir        */
+
+    item = G_EDITOR_ITEM(pygobject_get(self));
+    panel = g_editor_item_get_current_view(item);
+
+    if (panel == NULL)
+    {
+        Py_INCREF(Py_None);
+        result = Py_None;
+    }
+    else
+        result = py_view_panel_from_c(panel);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe représentant un binaire.                       *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Procède à l'enregistrement d'un élément reactif de l'éditeur.*
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_editor_item_register(PyObject *self, PyObject *args)
+{
+    GEditorItem *item;                      /* Version GLib de l'élément   */
+
+    item = G_EDITOR_ITEM(pygobject_get(self));
+
+    item->update_binary = _update_editor_item_for_binary_python_wrapper;
+    item->update_view = _update_editor_item_for_view_python_wrapper;
+    item->update_content = _update_editor_item_for_view_content_python_wrapper;
+
+    Py_INCREF(self);
+    register_editor_item(item);
+
+    Py_RETURN_NONE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide.gui.EditorItem'.       *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool register_python_editor_item(PyObject *module)
+{
+    PyObject *parent_mod;                   /* Module Python-GObject       */
+    int ret;                                /* Bilan d'un appel            */
+
+    static PyMethodDef py_editor_item_methods[] = {
+        {
+            "update_for_binary", (PyCFunction)py_editor_item_update_for_binary,
+            METH_VARARGS,
+            "Called by Chrysalide on each binary change, if the item is registered."
+        },
+        {
+            "update_for_view", (PyCFunction)py_editor_item_update_for_view,
+            METH_VARARGS,
+            "Called by Chrysalide on each view change, if the item is registered."
+        },
+        {
+            "update_for_content", (PyCFunction)py_editor_item_update_for_content,
+            METH_VARARGS,
+            "Called by Chrysalide on each view content change, if the item is registered."
+        },
+        {
+            "get_current_binary", (PyCFunction)py_editor_item_get_current_binary,
+            METH_NOARGS,
+            "Provide the current binary."
+        },
+        {
+            "get_current_view", (PyCFunction)py_editor_item_get_current_view,
+            METH_NOARGS,
+            "Provide the current binary view."
+        },
+        {
+            "register", (PyCFunction)py_editor_item_register,
+            METH_NOARGS,
+            "Register the item as editor item."
+        },
+        { NULL }
+    };
+
+    static PyGetSetDef py_editor_item_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_editor_item_type = {
+
+        PyObject_HEAD_INIT(NULL)
+
+        .tp_name        = "pychrysalide.gui.EditorItem",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = "PyChrysalide editor item",
+
+        .tp_methods     = py_editor_item_methods,
+        .tp_getset      = py_editor_item_getseters
+
+    };
+
+    parent_mod = PyImport_ImportModule("gobject");
+    if (parent_mod == NULL) return false;
+
+    py_editor_item_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(parent_mod, "GObject");
+    Py_DECREF(parent_mod);
+
+    if (PyType_Ready(&py_editor_item_type) < 0)
+        return false;
+
+    Py_INCREF(&py_editor_item_type);
+    ret = PyModule_AddObject(module, "EditorItem", (PyObject *)&py_editor_item_type);
+
+    return (ret == 0);
+
+}
diff --git a/plugins/pychrysa/gui/editem.h b/plugins/pychrysa/gui/editem.h
new file mode 100644
index 0000000..cea5118
--- /dev/null
+++ b/plugins/pychrysa/gui/editem.h
@@ -0,0 +1,39 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * editem.h - prototypes pour l'équivalent Python du fichier "gui/editem.h"
+ *
+ * Copyright (C) 2012 Cyrille Bagard
+ *
+ *  This file is part of OpenIDA.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSA_GUI_EDITEM_H
+#define _PLUGINS_PYCHRYSA_GUI_EDITEM_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Prend en charge l'objet 'pychrysalide.gui.EditorItem'. */
+bool register_python_editor_item(PyObject *module);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSA_GUI_EDITEM_H */
diff --git a/plugins/pychrysa/gui/module.c b/plugins/pychrysa/gui/module.c
index bee46df..cf09c44 100644
--- a/plugins/pychrysa/gui/module.c
+++ b/plugins/pychrysa/gui/module.c
@@ -25,6 +25,7 @@
 #include "module.h"
 
 
+#include "editem.h"
 #include "panels/module.h"
 
 
@@ -61,6 +62,7 @@ bool add_gui_module_to_python_module(PyObject *super)
 
     if (ret != 0) /* ... */;
 
+    result &= register_python_editor_item(module);
     result &= add_gui_panels_module_to_python_module(module);
 
     return true;
diff --git a/plugins/pychrysa/gui/panels/panel.c b/plugins/pychrysa/gui/panels/panel.c
index b1bcc61..4b982d0 100644
--- a/plugins/pychrysa/gui/panels/panel.c
+++ b/plugins/pychrysa/gui/panels/panel.c
@@ -40,7 +40,6 @@ static PyObject *py_panel_item_dock(PyObject *, PyObject *);
 
 
 
-
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : type = type de l'objet à instancier.                         *
@@ -71,7 +70,7 @@ static PyObject *py_panel_item_new(PyTypeObject *type, PyObject *args, PyObject
     item = g_panel_item_new(get_internal_ref(), name, lname,
                             GTK_WIDGET(pygobject_get(widget)), path);
 
-    result = py_panel_item_from_c(G_PANEL_ITEM(item));
+    result = _py_panel_item_from_c(G_PANEL_ITEM(item), type);
     g_object_unref(item);
 
     return (PyObject *)result;
@@ -79,9 +78,11 @@ static PyObject *py_panel_item_new(PyTypeObject *type, PyObject *args, PyObject
 }
 
 
+
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : item = instance existante GLib.                              *
+*                type = éventuel type final de l'instance Python imposé.      *
 *                                                                             *
 *  Description : Crée un nouvel objet Python de type 'PanelItem'.             *
 *                                                                             *
@@ -91,14 +92,16 @@ static PyObject *py_panel_item_new(PyTypeObject *type, PyObject *args, PyObject
 *                                                                             *
 ******************************************************************************/
 
-PyObject *py_panel_item_from_c(GPanelItem *item)
+PyObject *_py_panel_item_from_c(GPanelItem *item, PyTypeObject *type)
 {
     PyObject *module;                       /* Module d'appartenance       */
-    PyTypeObject *type;                     /* Type Python correspondant   */
 
-    module = PyImport_ImportModule("pychrysalide.gui.panels");
-    type = (PyTypeObject *)PyObject_GetAttrString(module, "PanelItem");
-    Py_DECREF(module);
+    if (type == NULL)
+    {
+        module = PyImport_ImportModule("pychrysalide.gui.panels");
+        type = (PyTypeObject *)PyObject_GetAttrString(module, "PanelItem");
+        Py_DECREF(module);
+    }
 
     pychrysalide_set_instance_data(G_OBJECT(item), type);
 
@@ -128,7 +131,7 @@ static PyObject *py_panel_item_dock(PyObject *self, PyObject *args)
 
     g_panel_item_dock(item);
 
-    return Py_None;
+    Py_RETURN_NONE;
 
 }
 
@@ -145,8 +148,6 @@ static PyObject *py_panel_item_dock(PyObject *self, PyObject *args)
 
 
 
-
-
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : module = module dont la définition est à compléter.          *
@@ -161,14 +162,14 @@ static PyObject *py_panel_item_dock(PyObject *self, PyObject *args)
 
 bool register_python_panel_item(PyObject *module)
 {
-    PyObject *pygobj_mod;                   /* Module Python-GObject       */
+    PyObject *parent_mod;                   /* Module Python-EditorItem    */
     int ret;                                /* Bilan d'un appel            */
 
     static PyMethodDef py_panel_item_methods[] = {
         {
             "dock", (PyCFunction)py_panel_item_dock,
             METH_NOARGS,
-            "DIsplay the panel item in the right place."
+            "Display the panel item in the right place."
         },
         { NULL }
     };
@@ -195,11 +196,11 @@ bool register_python_panel_item(PyObject *module)
 
     };
 
-    pygobj_mod = PyImport_ImportModule("gobject");
-    if (pygobj_mod == NULL) return false;
+    parent_mod = PyImport_ImportModule("pychrysalide.gui");
+    if (parent_mod == NULL) return false;
 
-    py_panel_item_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(pygobj_mod, "GObject");
-    Py_DECREF(pygobj_mod);
+    py_panel_item_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(parent_mod, "EditorItem");
+    Py_DECREF(parent_mod);
 
     if (PyType_Ready(&py_panel_item_type) < 0)
         return false;
diff --git a/plugins/pychrysa/gui/panels/panel.h b/plugins/pychrysa/gui/panels/panel.h
index 8d06094..a7b6e0c 100644
--- a/plugins/pychrysa/gui/panels/panel.h
+++ b/plugins/pychrysa/gui/panels/panel.h
@@ -34,7 +34,9 @@
 
 
 /* Crée un nouvel objet Python de type 'PanelItem'. */
-PyObject *py_panel_item_from_c(GPanelItem *);
+PyObject *_py_panel_item_from_c(GPanelItem *, PyTypeObject *);
+
+#define py_panel_item_from_c(item) _py_panel_item_from_c(item, NULL)
 
 /* Prend en charge l'objet 'pychrysalide.gui.panels.PanelItem'. */
 bool register_python_panel_item(PyObject *module);
diff --git a/plugins/pychrysa/helpers.c b/plugins/pychrysa/helpers.c
new file mode 100644
index 0000000..bc420c0
--- /dev/null
+++ b/plugins/pychrysa/helpers.c
@@ -0,0 +1,63 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * helpers.c - simplification des interactions de base avec Python
+ *
+ * Copyright (C) 2012 Cyrille Bagard
+ *
+ *  This file is part of OpenIDA.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "helpers.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : target = propriétaire de la routine visée.                   *
+*                method = désignation de la fonction à appeler.               *
+*                args   = arguments à associer à l'opération.                 *
+*                                                                             *
+*  Description : Appelle une routine Python.                                  *
+*                                                                             *
+*  Retour      : Retour obtenu ou NULL si erreur.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyObject *run_python_method(PyObject *module, const char *method, PyObject *args)
+{
+    PyObject *result;                       /* Bilan à retourner           */
+    PyObject *func;                         /* Fonction visée              */
+
+    result = NULL;
+
+    func = PyObject_GetAttrString(module, method);
+    if (func == NULL) return NULL;
+
+    if (PyCallable_Check(func))
+    {
+        result = PyObject_CallObject(func, args);
+        if (result == NULL) PyErr_Print();
+    }
+    else if (PyErr_Occurred()) PyErr_Print();
+
+    Py_DECREF(func);
+
+    return result;
+
+}
diff --git a/plugins/pychrysa/helpers.h b/plugins/pychrysa/helpers.h
new file mode 100644
index 0000000..474978b
--- /dev/null
+++ b/plugins/pychrysa/helpers.h
@@ -0,0 +1,37 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * helpers.h - prototypes pour la simplification des interactions de base avec Python
+ *
+ * Copyright (C) 2012 Cyrille Bagard
+ *
+ *  This file is part of OpenIDA.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _PLUGINS_HELPERS_H
+#define _PLUGINS_HELPERS_H
+
+
+#include <Python.h>
+
+
+
+/* Appelle une routine Python. */
+PyObject *run_python_method(PyObject *, const char *, PyObject *);
+
+
+
+#endif  /* _PLUGINS_HELPERS_H */
diff --git a/plugins/pychrysa/plugin.c b/plugins/pychrysa/plugin.c
index 9601432..1bda007 100644
--- a/plugins/pychrysa/plugin.c
+++ b/plugins/pychrysa/plugin.c
@@ -25,10 +25,14 @@
 #include "plugin.h"
 
 
+#include <pygobject.h>
+
+
 #include "../../src/analysis/binary.h"
 #include "../../src/plugins/plugin-int.h"
 
 
+#include "helpers.h"
 #include "analysis/binary.h"
 #include "debug/debugger.h"
 
@@ -65,6 +69,9 @@ static void g_python_plugin_class_init(GPythonPluginClass *);
 /* Initialise l'instance d'un greffon Python. */
 static void g_python_plugin_init(GPythonPlugin *);
 
+/* Procède à l'initialisation du greffon. */
+static bool g_python_plugin_do_init(GPythonPlugin *, GObject *);
+
 /* Indique l'utilité pratique du greffon. */
 static PluginAction g_python_plugin_get_action(const GPythonPlugin *);
 
@@ -106,6 +113,9 @@ static PyObject *pychrysa_plugin_run(PyObject *, PyObject *);
 /* Définit les constantes pour les greffons en Python. */
 static bool pychrysa_plugin_define_constants(PyObject *);
 
+/* Procède à l'initialisation du greffon. */
+static PyObject *pychrysa_plugin_init(PyObject *, PyObject *);
+
 /* Définit le comportement par défaut d'un greffon Python. */
 static PyObject *pychrysa_plugin_get_action(PyObject *, PyObject *);
 
@@ -255,29 +265,6 @@ static void g_python_plugin_init(GPythonPlugin *plugin)
 
 
 
-PyObject *run_python_method(PyObject *module, const char *method, PyObject *args)
-{
-    PyObject *result;                       /* Bilan à retourner           */
-    PyObject *func;                         /* Fonction visée              */
-
-    result = NULL;
-
-    func = PyObject_GetAttrString(module, method);
-    if (func == NULL) return NULL;
-
-    if (PyCallable_Check(func))
-    {
-        result = PyObject_CallObject(func, args);
-        if (result == NULL) PyErr_Print();
-    }
-    else if (PyErr_Occurred()) PyErr_Print();
-
-    Py_DECREF(func);
-
-    return result;
-
-}
-
 
 /******************************************************************************
 *                                                                             *
@@ -333,7 +320,9 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename)
 
     G_PLUGIN_MODULE(result)->name = strdup(modname);
     G_PLUGIN_MODULE(result)->name = stradd(G_PLUGIN_MODULE(result)->name, ".py");
+    G_PLUGIN_MODULE(result)->filename = strdup(G_PLUGIN_MODULE(result)->name);
 
+    G_PLUGIN_MODULE(result)->init = g_python_plugin_do_init;
     G_PLUGIN_MODULE(result)->get_action = g_python_plugin_get_action;
 
     G_PLUGIN_MODULE(result)->is_matching = g_python_plugin_is_matching;
@@ -360,6 +349,44 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : plugin = greffon à initialiser.                              *
+*                ref    = espace de référencement global.                     *
+*                                                                             *
+*  Description : Procède à l'initialisation du greffon.                       *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_python_plugin_do_init(GPythonPlugin *plugin, GObject *ref)
+{
+    bool result;                            /* Bilan à retourner           */
+    PyObject *args;                         /* Arguments pour l'appel      */
+    PyObject *value;                        /* Valeur obtenue              */
+    int cmp;                                /* Bilan de la comparaison     */
+
+    args = PyTuple_New(1);
+    PyTuple_SetItem(args, 0, pygobject_new(ref));
+
+    value = run_python_method(plugin->instance, "init", args);
+
+    if (PyObject_Cmp(value, Py_True, &cmp) == -1)
+        result = false;
+    else
+        result = (cmp == 0);
+
+    Py_XDECREF(value);
+    Py_DECREF(args);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : plugin = greffon de prise en charge à utiliser.              *
 *                                                                             *
 *  Description : Indique l'utilité pratique du greffon.                       *
@@ -669,6 +696,27 @@ static bool pychrysa_plugin_define_constants(PyObject *dict)
 *  Paramètres  : self = classe assurant le lien avec l'éditeur de messages.   *
 *                args = arguments fournis à l'appel.                          *
 *                                                                             *
+*  Description : Procède à l'initialisation du greffon.                       *
+*                                                                             *
+*  Retour      : Rien en équivalent Python.                                   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *pychrysa_plugin_init(PyObject *self, PyObject *args)
+{
+    Py_INCREF(Py_True);
+    return Py_True;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe assurant le lien avec l'éditeur de messages.   *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
 *  Description : Définit le comportement par défaut d'un greffon Python.      *
 *                                                                             *
 *  Retour      : Rien en équivalent Python.                                   *
@@ -820,20 +868,35 @@ bool add_plugin_to_python_module(PyObject *module)
 
 
 static PyMethodDef pychrysa_plugin_methods[] = {
-    { "get_action", (PyCFunction)pychrysa_plugin_get_action, METH_NOARGS,
-     "Register the plugin for given actions."
+    {
+        "init", (PyCFunction)pychrysa_plugin_init,
+        METH_VARARGS,
+        "Initialize the plugin."
+    },
+    {
+        "get_action", (PyCFunction)pychrysa_plugin_get_action,
+        METH_NOARGS,
+        "Register the plugin for given actions."
     },
-    { "is_matching", (PyCFunction)pychrysa_plugin_is_matching, METH_VARARGS,
-     "Define if the given file can be handled."
+    {
+        "is_matching", (PyCFunction)pychrysa_plugin_is_matching,
+        METH_VARARGS,
+        "Define if the given file can be handled."
     },
-    { "handle_debugger", (PyCFunction)pychrysa_plugin_handle_debugger, METH_VARARGS,
-     "Be notify about debugger attaching or detaching."
+    {
+        "handle_debugger", (PyCFunction)pychrysa_plugin_handle_debugger,
+        METH_VARARGS,
+        "Be notify about debugger attaching or detaching."
     },
-    { "run", (PyCFunction)pychrysa_plugin_run, METH_VARARGS,
-     "Run the plugin for a specific action."
+    {
+        "run", (PyCFunction)pychrysa_plugin_run,
+        METH_VARARGS,
+        "Run the plugin for a specific action."
     },
-    { "add_wgt", (PyCFunction)add_wgt, METH_VARARGS,
-     "Run the plugin for a specific action."
+    {
+        "add_wgt", (PyCFunction)add_wgt,
+        METH_VARARGS,
+        "Run the plugin for a specific action."
     },
     NULL
 };
diff --git a/plugins/pychrysa/pychrysa.c b/plugins/pychrysa/pychrysa.c
index 0aa6175..d7cdfe4 100644
--- a/plugins/pychrysa/pychrysa.c
+++ b/plugins/pychrysa/pychrysa.c
@@ -38,6 +38,7 @@
 #include "debug/module.h"
 #include "format/module.h"
 #include "glibext/module.h"
+#include "gtkext/module.h"
 #include "gui/module.h"
 
 /*
@@ -269,6 +270,7 @@ PyMODINIT_FUNC initpychrysa(void)
     add_debug_module_to_python_module(module);
     add_format_module_to_python_module(module);
     add_glibext_module_to_python_module(module);
+    add_gtkext_module_to_python_module(module);
     add_gui_module_to_python_module(module);
 
     add_log_to_python_module(module);
diff --git a/plugins/pychrysa/quirks.c b/plugins/pychrysa/quirks.c
index bd60925..68f0a2e 100644
--- a/plugins/pychrysa/quirks.c
+++ b/plugins/pychrysa/quirks.c
@@ -46,6 +46,8 @@ typedef struct _PyGObjectData_fake
 /* Clef d'accès réservée */
 static GQuark pygobject_instance_data_key_fake = 0;
 
+/* Clef pour l'enregistrement de l'objet Python dans l'objet GLib */
+static GQuark pygobject_wrapper_key_fake = 0;
 
 
 
@@ -113,6 +115,7 @@ static GObject *_ref = NULL;
 void pychrysalide_init_quirks(void)
 {
     pygobject_instance_data_key_fake = g_quark_from_static_string("PyGObject::instance-data");
+    pygobject_wrapper_key_fake = g_quark_from_static_string("PyGObject::wrapper");
 
 }
 
@@ -153,6 +156,32 @@ void pychrysalide_set_instance_data(GObject *obj, PyTypeObject *type)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : obj = instance existante GLib.                               *
+*                                                                             *
+*  Description : Fournit l'instance Python d'une instance GLib, si existante. *
+*                                                                             *
+*  Retour      : Instance Python mise en place ou NULL.                       *
+*                                                                             *
+*  Remarques   : Les retours non nuls voient leur compteur incrémenté.        *
+*                                                                             *
+******************************************************************************/
+
+PyObject *pychrysalide_get_pygobject(GObject *obj)
+{
+    PyObject *result;                       /* Objet en place à renvoyer   */
+
+    result = (PyObject *)g_object_get_qdata(obj, pygobject_wrapper_key_fake);
+
+    if (result != NULL)
+        Py_INCREF(result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : self = objet à initialiser (théoriquement).                  *
 *                args = arguments fournis à l'appel.                          *
 *                kwds = arguments de type key=val fournis.                    *
diff --git a/plugins/pychrysa/quirks.h b/plugins/pychrysa/quirks.h
index 84a778f..ca198f3 100644
--- a/plugins/pychrysa/quirks.h
+++ b/plugins/pychrysa/quirks.h
@@ -37,6 +37,9 @@ void pychrysalide_init_quirks(void);
 /* Crée l'association précise attendue par Python-GObject. */
 void pychrysalide_set_instance_data(GObject *, PyTypeObject *);
 
+/* Fournit l'instance Python d'une instance GLib, si existante. */
+PyObject *pychrysalide_get_pygobject(GObject *);
+
 /* Initialise un objet dérivé de GObject en Python. */
 int pychrysalide_allow_args_for_gobjects(PyObject *, PyObject *, PyObject *);
 
diff --git a/plugins/python/androperms/Makefile.am b/plugins/python/androperms/Makefile.am
index c9c8430..b1a1e4e 100644
--- a/plugins/python/androperms/Makefile.am
+++ b/plugins/python/androperms/Makefile.am
@@ -6,6 +6,7 @@ androperms_DATA = 							\
 	android.png								\
 	androperms.db							\
 	androperms.py							\
+	db.py									\
 	defs.py									\
 	manifest.py								\
 	panel.py								\
diff --git a/plugins/python/androperms/androperms.py b/plugins/python/androperms/androperms.py
index 569558a..18443fc 100644
--- a/plugins/python/androperms/androperms.py
+++ b/plugins/python/androperms/androperms.py
@@ -2,18 +2,25 @@
 # -*- coding: utf-8 -*-
 
 from manifest import AndroidManifest
+from db import PermsDataBase
 from panel import PermsPanel
 from pychrysalide import Plugin
-from pychrysalide.gui.panels import PanelItem
 from xml.dom import minidom
 
-import gtk
+import re
 import zipfile
 
 
 class AndroPerms(Plugin):
     """List all permissions given to an APK files."""
 
+    def init(self, ref):
+        """Initialize the plugin."""
+
+        self._panel = PermsPanel()
+
+        return True
+
 
     def get_action(self):
         """Register the plugin for given actions."""
@@ -33,36 +40,26 @@ class AndroPerms(Plugin):
         manifest = AndroidManifest(data)
         xml = minidom.parseString(manifest.getXML())
 
-        print
-        print "Permissions for ", binary.get_filename(), " :"
-        print "-------------"
-        print
+        # print
+        # print "Permissions for ", binary.get_filename(), " :"
+        # print "-------------"
+        # print
 
         plist = []
 
         for p in xml.getElementsByTagName("uses-permission"):
             plist.append(p.getAttribute("android:name"))
-            print p.getAttribute("android:name")
-
-        print
-
-
-
-        panel = PermsPanel()
+        #     print p.getAttribute("android:name")
 
-        self._build_panel_item()
-
-
-
-        panel.filter_permissions(plist)
+        # print
 
+        db = PermsDataBase()
+        db.filter_permissions(plist)
 
         instrs = binary.get_instructions()
         buffer = binary.disassembled_buffer
 
-
-
-
+        pfn = re.compile('<.* ([^ ]*)\(')
 
         for i in instrs:
 
@@ -71,52 +68,12 @@ class AndroPerms(Plugin):
                 line = buffer.find_line_by_addr(i.address)
                 text = line.get_text()
 
-                panel.check_call(i.address, text)
-
-
-
-
-
-        panel.fill_tree(self._store)
-        self._tree.expand_all()
-
-
-
-    def _build_panel_item(self):
-
-        self._scrolled_window = gtk.ScrolledWindow()
-        self._scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-        self._scrolled_window.show()
-
-        self._tree = gtk.TreeView()
-        self._tree.set_headers_visible(False)
-        self._tree.show()
-        self._scrolled_window.add_with_viewport(self._tree)
-
-        locations = gtk.TreeViewColumn()
-        self._tree.append_column(locations)
-
-        cell = gtk.CellRendererPixbuf()
-        locations.pack_start(cell, False)
-        locations.add_attribute(cell, 'pixbuf', 0)
-
-        cell = gtk.CellRendererText()
-        locations.pack_start(cell, False)
-        locations.add_attribute(cell, 'text', 1)
-
-        functions = gtk.TreeViewColumn()
-        self._tree.append_column(functions)
-
-        cell = gtk.CellRendererPixbuf()
-        functions.pack_start(cell, False)
-        functions.add_attribute(cell, 'pixbuf', 2)
+                #print "check %s" % text
 
-        cell = gtk.CellRendererText()
-        functions.pack_start(cell, True)
-        functions.add_attribute(cell, 'text', 3)
+                name = pfn.search(text)
 
-        self._store = gtk.TreeStore(gtk.gdk.Pixbuf, str, gtk.gdk.Pixbuf, str)
-        self._tree.set_model(self._store)
+                if name != None:
+                    #print " --> ", name.group(1)
+                    db.check_call(i.address, name.group(1))
 
-        pi = PanelItem('Permissions', 'Permissions', self._scrolled_window, 'SE')
-        pi.dock()
+        self._panel.memorize_permissions(binary, db.get_used_permissions())
diff --git a/plugins/python/androperms/db.py b/plugins/python/androperms/db.py
new file mode 100644
index 0000000..625d400
--- /dev/null
+++ b/plugins/python/androperms/db.py
@@ -0,0 +1,94 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+import os
+
+
+class PermsDataBase:
+    """Display all permissions found in the Manifest."""
+
+    def __init__(self):
+
+        self._perms = { }
+        self._used = { }
+                     
+        self._load_all_definitions()
+
+
+    def _load_all_definitions(self):
+        """Load the database in memory."""
+
+        with open(os.path.dirname(__file__) + '/androperms.db', 'r') as f:
+
+            for line in f.readlines():
+
+                perm = line.strip("\n").split("\t")
+
+                for p in perm[1].split(" "):
+
+                    if not p.startswith("android.permission."):
+                        continue
+
+                    if p not in self._perms:
+                        self._perms[p] = []
+
+                    call = perm[0].split("(")[0]
+
+                    if call not in self._perms[p]:
+                        self._perms[p].append(call)
+
+
+    def filter_permissions(self, used):
+        """Forget all permissions which are not used."""
+
+        keep = {}
+
+        for p in self._perms:
+            if p in used:
+                keep[p] = self._perms[p]
+
+        self._perms = keep
+
+        for p in keep:
+            self._used[p] = []
+
+
+    def check_call(self, addr, line):
+        """Check if a call requires some rights."""
+
+        found = False
+
+        for p in self._perms:
+
+            if line.find("Wall") > -1:
+                print "[+]", line, ' ==> ', p
+
+            for c in self._perms[p]:
+
+                #print "  - ", c
+
+                #if line.find(c) > -1:
+                if c.find(line) > -1:
+                    self._used[p].append([addr, c + "()"])
+                    #found = True
+
+        if not found:
+
+            func = line.split('.')[-1]
+
+            for p in self._perms:
+
+                for c in self._perms[p]:
+
+                    if line.find("Wall") > -1:
+                        print " <> ", c, " vs ", func
+
+                    if c.find(func) > -1:
+                        self._used[p].append([addr, line + "()"])
+                        break
+
+
+    def get_used_permissions(self):
+        """Provide the list of used permissions."""
+
+        return self._used
diff --git a/plugins/python/androperms/panel.py b/plugins/python/androperms/panel.py
index ea26f74..bebeed5 100644
--- a/plugins/python/androperms/panel.py
+++ b/plugins/python/androperms/panel.py
@@ -1,85 +1,120 @@
 #!/usr/bin/python
 # -*- coding: utf-8 -*-
 
-import os
+from pychrysalide.gui.panels import PanelItem
 
 import gtk
+import os
 
 
-class PermsPanel:
-    """Display all permissions found in the Manifest."""
+def _build_permissions_panel_content():
+    """Build content for permissions panels."""
 
-    def __init__(self):
+    scrolled_window = gtk.ScrolledWindow()
+    scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+    scrolled_window.show()
+
+    tree = gtk.TreeView()
+    tree.set_headers_visible(False)
+    tree.show()
+    scrolled_window.add_with_viewport(tree)
+
+    locations = gtk.TreeViewColumn()
+    tree.append_column(locations)
+
+    cell = gtk.CellRendererPixbuf()
+    locations.pack_start(cell, False)
+    locations.add_attribute(cell, 'pixbuf', 0)
+
+    cell = gtk.CellRendererText()
+    locations.pack_start(cell, False)
+    locations.add_attribute(cell, 'text', 1)
 
-        self._perms = { }
-        self._used = { }
-                     
-        self._load_all_definitions()
+    functions = gtk.TreeViewColumn()
+    tree.append_column(functions)
 
+    cell = gtk.CellRendererPixbuf()
+    functions.pack_start(cell, False)
+    functions.add_attribute(cell, 'pixbuf', 2)
 
-    def _load_all_definitions(self):
-        """Load the database in memory."""
+    cell = gtk.CellRendererText()
+    functions.pack_start(cell, True)
+    functions.add_attribute(cell, 'text', 3)
 
-        with open(os.path.dirname(__file__) + '/androperms.db', 'r') as f:
+    store = gtk.TreeStore(gtk.gdk.Pixbuf, str, gtk.gdk.Pixbuf, str)
+    tree.set_model(store)
 
-            for line in f.readlines():
+    return scrolled_window, tree, store
 
-                perm = line.strip("\n").split("\t")
 
-                for p in perm[1].split(" "):
+class PermsPanel(PanelItem):
+    """Display all permissions found in the Manifest."""
 
-                    if not p.startswith("android.permission."):
-                        continue
+    def __new__(cls):
+        """Create the GLib instance relative this class as soon as possible,
+        for the pygobject registering process."""
 
-                    if p not in self._perms:
-                        self._perms[p] = []
+        scrolled_window, tree, store = _build_permissions_panel_content()
 
-                    call = perm[0].split("(")[0]
+        self = super(PermsPanel, cls).__new__(cls, 'Permissions', 'Android Permissions', \
+                                                  scrolled_window, 'SE')
 
-                    if call not in self._perms[p]:
-                        self._perms[p].append(call)
+        self._scrolled_window = scrolled_window
+        self._tree = tree
+        self._store = store
 
+        self._perms = {}
 
-    def filter_permissions(self, used):
-        """Forget all permissions which are not used."""
+        return self
 
-        keep = {}
 
-        for p in self._perms:
-            if p in used:
-                keep[p] = self._perms[p]
+    def __init__(self):
+        """Initialize the Python instance of the panel."""
 
-        self._perms = keep
+        self._tree.connect('row-activated', self._on_row_selection)
 
-        for p in keep:
-            self._used[p] = []
+        self.dock()
+        self.register()
 
 
-    def check_call(self, addr, line):
-        """Check if a call requires some rights."""
+    def memorize_permissions(self, binary, perms):
+        """Attach found permissions to a new loaded binary."""
 
-        for p in self._perms:
+        self._perms[binary] = perms
 
-            for c in self._perms[p]:
 
-                if line.find(c) > -1:
-                    self._used[p].append([addr, c + "()"])
+    def update_for_binary(self, binary):
+        """Fill the treeview with all found permissions for the given binary."""
 
+        self._store.clear()
 
-    def fill_tree(self, store):
-        """Fill a treeview with all found permissions."""
+        used = self._perms[binary]
 
-        for p in self._used:
+        for p in used:
 
-            if len(self._used[p]) > 0 or True:
+            if len(used[p]) > 0 or True:
 
                 img = os.path.dirname(os.path.abspath(__file__)) + '/android.png'
                 buf = gtk.gdk.pixbuf_new_from_file(img)
 
-                it = store.append(None, [buf, p, None, None])
+                it = self._store.append(None, [buf, p, None, None])
 
                 img = os.path.dirname(os.path.abspath(__file__)) + '/routine.png'
                 buf = gtk.gdk.pixbuf_new_from_file(img)
 
-                for f in self._used[p]:
-                    store.append(it, [None, "0x%08x" % f[0], buf, f[1]])
+                for f in used[p]:
+                    self._store.append(it, [None, "0x%08x" % f[0], buf, f[1]])
+
+        self._tree.expand_all()
+
+
+    def _on_row_selection(self, treeview, path, column):
+        """Scroll the current view to the selected address."""
+
+        selection = treeview.get_selection()
+        model, it = selection.get_selected()
+
+        # On ne traite que les lignes de code
+        if model.get_value(it, 0) == None:
+
+            self.get_current_view().scroll_to_address(int(model.get_value(it, 1), 16))
diff --git a/src/analysis/blocks/flow.c b/src/analysis/blocks/flow.c
index 62856dd..2bdd0cf 100644
--- a/src/analysis/blocks/flow.c
+++ b/src/analysis/blocks/flow.c
@@ -203,10 +203,10 @@ GInstrBlock *g_flow_block_new(GArchInstruction *instrs, GArchInstruction *first,
 
 
     g_arch_instruction_get_location(first, NULL, NULL, &addr);
-    printf(" ! new block @ 0x%llx - ", addr);
+    //printf(" ! new block @ 0x%llx - ", addr);
 
     g_arch_instruction_get_location(last, NULL, NULL, &addr);
-    printf("0x%llx\n", addr);
+    //printf("0x%llx\n", addr);
 
 
 
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index e7c972d..6147f3b 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -257,7 +257,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta
     run_plugins_on_binary(disass->binary, PGA_BINARY_BOUNDED, true);
 
     /* Quatrième étape */
-
+#if 0
     id = gtk_extended_status_bar_push(statusbar, _("Grouping routines instructions..."), true);
 
     qsort(routines, routines_count, sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_rcompare);
@@ -267,7 +267,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, true);
-
+#endif
     /* Cinquième étape */
 
     id = gtk_extended_status_bar_push(statusbar, _("Printing disassembled code..."), true);
diff --git a/src/analysis/disass/macro.c b/src/analysis/disass/macro.c
index fc5d8dc..7fda6b9 100644
--- a/src/analysis/disass/macro.c
+++ b/src/analysis/disass/macro.c
@@ -238,7 +238,7 @@ static GInstrBlock *build_instruction_block(GArchInstruction *instrs, vmpa_t sta
     first = NULL;
     last = NULL;
 
-    printf("[+] blocking 0x%08llx -> 0x%08llx... stop @ 0x%08llx\n", start, end, stop);
+    //printf("[+] blocking 0x%08llx -> 0x%08llx... stop @ 0x%08llx\n", start, end, stop);
 
     for (iter = g_arch_instruction_find_by_address(instrs, start, true);
          iter != NULL;
@@ -385,7 +385,7 @@ void group_routines_instructions(GArchInstruction *list, GBinRoutine **routines,
         end = start + g_binary_routine_get_size(routines[i]);
 
 
-        printf("==== %s ====\n", g_binary_routine_to_string(routines[i]));
+        //printf("==== %s ====\n", g_binary_routine_to_string(routines[i]));
 
 
         block = build_instruction_block(list, start, end, VMPA_MAX);
diff --git a/src/plugins/pglist.c b/src/plugins/pglist.c
index bca3e6a..6b51690 100644
--- a/src/plugins/pglist.c
+++ b/src/plugins/pglist.c
@@ -151,13 +151,10 @@ void browse_directory_for_plugins(plugins_list *list, const char *dir)
 
         else
         {
-            plugin = g_plugin_module_new(filename, list->ref);
+            plugin = g_plugin_module_new(filename);
 
             if (plugin != NULL)
-            {
-                list->plugins = (GPluginModule **)realloc(list->plugins, ++list->plugins_count * sizeof(GPluginModule *));
-                list->plugins[list->plugins_count - 1] = plugin;
-            }
+                add_plugin_to_main_list(plugin);
 
         }
 
@@ -253,6 +250,14 @@ void add_plugin_to_main_list(GPluginModule *plugin)
 
     list = &_list;
 
+    if (plugin->init != NULL && !plugin->init(plugin, list->ref))
+    {
+        log_variadic_message(LMT_ERROR, _("Initialization of plugin '%s' failed !"),
+                             plugin->filename);
+        g_object_unref(G_OBJECT(plugin));
+        return;
+    }
+
     list->plugins = (GPluginModule **)realloc(list->plugins, ++list->plugins_count * sizeof(GPluginModule *));
     list->plugins[list->plugins_count - 1] = plugin;
 
diff --git a/src/plugins/plugin-int.h b/src/plugins/plugin-int.h
index 9a5c37c..055f6ff 100644
--- a/src/plugins/plugin-int.h
+++ b/src/plugins/plugin-int.h
@@ -37,7 +37,7 @@
 /* Précise le nom associé au greffon. */
 typedef char * (* get_plugin_name_fc) (void);
 
-/* Procède à l'initialisation du greffon */
+/* Procède à l'initialisation du greffon. */
 typedef bool (* init_plugin_fc) (GPluginModule *, GObject *);
 
 /* Fournit une indication sur le type d'opération(s) menée(s). */
@@ -61,6 +61,7 @@ struct _GPluginModule
     GModule *module;                        /* Abstration de manipulation  */
 
     char *name;                             /* Nom associé au greffon      */
+    char *filename;                         /* Fichier associé au greffon  */
     PluginType type;                        /* Type(s) du greffon          */
 
     init_plugin_fc init;                    /* Procédure d'initialisation  */
diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c
index c6a49c6..dabe493 100644
--- a/src/plugins/plugin.c
+++ b/src/plugins/plugin.c
@@ -90,7 +90,6 @@ static void g_plugin_module_init(GPluginModule *line)
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : filename = nom du fichier à charger.                         *
-*                ref      = espace de référencement global.                   *
 *                                                                             *
 *  Description : Crée un module pour un greffon donné.                        *
 *                                                                             *
@@ -100,7 +99,7 @@ static void g_plugin_module_init(GPluginModule *line)
 *                                                                             *
 ******************************************************************************/
 
-GPluginModule *g_plugin_module_new(const gchar *filename, GObject *ref)
+GPluginModule *g_plugin_module_new(const gchar *filename)
 {
     GPluginModule *result;                  /* Structure à retourner       */
     get_plugin_name_fc get_name;            /* Nom du greffon              */
@@ -123,6 +122,7 @@ GPluginModule *g_plugin_module_new(const gchar *filename, GObject *ref)
     }
 
     result->name = get_name();
+    result->filename = strdup(filename);
 
     if (!g_module_symbol(result->module, "init_plugin", (gpointer *)&result->init))
         result->init = NULL;
@@ -170,12 +170,6 @@ GPluginModule *g_plugin_module_new(const gchar *filename, GObject *ref)
 
 
 
-    if (result->init != NULL && !result->init(result, ref))
-    {
-        log_variadic_message(LMT_ERROR, _("Initialization of plugin '%s' failed !"), filename);
-        goto bad_plugin;
-    }
-
     dir = strdup(filename);
     dir = dirname(dir);
 
diff --git a/src/plugins/plugin.h b/src/plugins/plugin.h
index 6fbba4d..c0f6cd1 100644
--- a/src/plugins/plugin.h
+++ b/src/plugins/plugin.h
@@ -52,7 +52,7 @@ typedef struct _GPluginModuleClass GPluginModuleClass;
 GType g_plugin_module_get_type(void);
 
 /* Crée un module pour un greffon donné. */
-GPluginModule *g_plugin_module_new(const gchar *, GObject *);
+GPluginModule *g_plugin_module_new(const gchar *);
 
 /* Fournit le nom associé au greffon. */
 const char *g_plugin_module_get_name(const GPluginModule *);
-- 
cgit v0.11.2-87-g4458