From 3bfff245c47c4dd1404c5ea7af0ff4858ac8d130 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Fri, 21 Dec 2012 23:34:14 +0000
Subject: Resolved relative addresses for routines and fixed bugs related to
 PyGObjects construction.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@308 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                                      |  97 +++++++++++++++++
 configure.ac                                   |   1 +
 plugins/pychrysa/analysis/Makefile.am          |   4 +
 plugins/pychrysa/analysis/binaries/Makefile.am |  16 +++
 plugins/pychrysa/analysis/binaries/file.c      | 142 +++++++++++++++++++++++++
 plugins/pychrysa/analysis/binaries/file.h      |  39 +++++++
 plugins/pychrysa/analysis/binaries/module.c    |  66 ++++++++++++
 plugins/pychrysa/analysis/binaries/module.h    |  39 +++++++
 plugins/pychrysa/analysis/binary.c             |  76 +------------
 plugins/pychrysa/analysis/binary.h             |   5 -
 plugins/pychrysa/analysis/module.c             |   2 +
 plugins/pychrysa/analysis/roptions.c           |   4 +-
 plugins/pychrysa/arch/instruction.c            |  62 +++++------
 plugins/pychrysa/arch/instruction.h            |   5 -
 plugins/pychrysa/arch/processor.c              |  26 -----
 plugins/pychrysa/debug/debugger.c              |   4 +-
 plugins/pychrysa/format/dex/class.c            |  34 ++----
 plugins/pychrysa/format/dex/class.h            |   5 -
 plugins/pychrysa/format/dex/dex.c              |  50 +++------
 plugins/pychrysa/format/dex/dex.h              |   5 -
 plugins/pychrysa/format/executable.c           |   2 +-
 plugins/pychrysa/format/format.c               |  65 +++++++----
 plugins/pychrysa/format/format.h               |   5 -
 plugins/pychrysa/format/module.c               |   2 +
 plugins/pychrysa/glibext/bufferline.c          |  34 ++----
 plugins/pychrysa/glibext/bufferline.h          |   5 -
 plugins/pychrysa/glibext/codebuffer.c          |  40 ++-----
 plugins/pychrysa/glibext/codebuffer.h          |   5 -
 plugins/pychrysa/gtkext/viewpanel.c            |  39 ++-----
 plugins/pychrysa/gtkext/viewpanel.h            |   5 -
 plugins/pychrysa/gui/editem.c                  |  10 +-
 plugins/pychrysa/gui/panels/panel.c            |   5 +-
 plugins/pychrysa/plugin.c                      |  69 ++----------
 plugins/pychrysa/pychrysa.c                    |   8 +-
 plugins/pychrysa/quirks.c                      |  60 ++++++++++-
 plugins/pychrysa/quirks.h                      |   3 +
 plugins/python/androperms/androperms.py        |  18 ++--
 plugins/python/androperms/db.py                |  24 ++---
 plugins/python/androperms/panel.py             |   8 +-
 src/analysis/routine.c                         |  37 ++++++-
 src/analysis/routine.h                         |   5 +-
 src/format/format.c                            |  44 ++++++++
 src/format/format.h                            |   3 +
 43 files changed, 727 insertions(+), 451 deletions(-)
 create mode 100644 plugins/pychrysa/analysis/binaries/Makefile.am
 create mode 100644 plugins/pychrysa/analysis/binaries/file.c
 create mode 100644 plugins/pychrysa/analysis/binaries/file.h
 create mode 100644 plugins/pychrysa/analysis/binaries/module.c
 create mode 100644 plugins/pychrysa/analysis/binaries/module.h

diff --git a/ChangeLog b/ChangeLog
index a0579f3..2878a1f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,100 @@
+12-12-22  Cyrille Bagard <nocbos@gmail.com>
+
+	* configure.ac:
+	Add the new Makfile from the 'plugins/pychrysa/analysis/binaries'
+	directory to AC_CONFIG_FILES.
+
+	* plugins/pychrysa/analysis/binaries/file.c:
+	* plugins/pychrysa/analysis/binaries/file.h:
+	* plugins/pychrysa/analysis/binaries/Makefile.am:
+	* plugins/pychrysa/analysis/binaries/module.c:
+	* plugins/pychrysa/analysis/binaries/module.h:
+	New entries: introduce the real object for file binaries.
+
+	* plugins/pychrysa/analysis/binary.c:
+	* plugins/pychrysa/analysis/binary.h:
+	Fix bugs related to PyGObjects construction. Update the code.
+
+	* plugins/pychrysa/analysis/Makefile.am:
+	Add the 'binaries/libpychrysaanalysisbinaries.la' file to
+	libpychrysaanalysis_la_LIBADD and 'binaries' to SUBDIRS.
+
+	* plugins/pychrysa/analysis/module.c:
+	Register the 'binaries' module.
+
+	* plugins/pychrysa/analysis/roptions.c:
+	Fix leaks when returning the Py_None singleton.
+
+	* plugins/pychrysa/arch/instruction.c:
+	* plugins/pychrysa/arch/instruction.h:
+	Fix memory leaks in the iterator and bugs related to PyGObjects
+	construction.
+
+	* plugins/pychrysa/arch/processor.c:
+	Clean the code.
+
+	* plugins/pychrysa/debug/debugger.c:
+	Fix leaks when returning the Py_None singleton.
+
+	* plugins/pychrysa/format/dex/class.c:
+	* plugins/pychrysa/format/dex/class.h:
+	* plugins/pychrysa/format/dex/dex.c:
+	* plugins/pychrysa/format/dex/dex.h:
+	Fix memory leaks and search for relative addresses. Fix bugs related to
+	PyGObjects construction.
+
+	* plugins/pychrysa/format/executable.c:
+	Disable the py_executable_format_from_c() function.
+
+	* plugins/pychrysa/format/format.c:
+	* plugins/pychrysa/format/format.h:
+	Fix memory leaks and search for relative addresses. Fix bugs related to
+	PyGObjects construction.
+
+	* plugins/pychrysa/format/module.c:
+	Register the 'BinaryFormat' Python object.
+
+	* plugins/pychrysa/glibext/bufferline.c:
+	* plugins/pychrysa/glibext/bufferline.h:
+	Fix bugs related to PyGObjects construction.
+
+	* plugins/pychrysa/glibext/codebuffer.c:
+	* plugins/pychrysa/glibext/codebuffer.h:
+	* plugins/pychrysa/gtkext/viewpanel.c:
+	* plugins/pychrysa/gtkext/viewpanel.h:
+	Fix bugs related to PyGObjects construction. Fix leaks when returning
+	the Py_None singleton.
+
+	* plugins/pychrysa/gui/editem.c:
+	Update the code.
+
+	* plugins/pychrysa/gui/panels/panel.c:
+	Fix memory leaks.
+
+	* plugins/pychrysa/plugin.c:
+	Fix memory leaks and clean the code.
+
+	* plugins/pychrysa/pychrysa.c:
+	Change the threshold of the Python garbage collector, as there still are
+	memory leaks to fix.
+
+	* plugins/pychrysa/quirks.c:
+	* plugins/pychrysa/quirks.h:
+	Increase the threshold of the Python garbage collector.
+
+	* plugins/python/androperms/androperms.py:
+	* plugins/python/androperms/db.py:
+	* plugins/python/androperms/panel.py:
+	Clean the code and display relative addresses.
+
+	* src/analysis/routine.c:
+	* src/analysis/routine.h:
+	Provide the long name of a given routine.
+
+	* src/format/format.c:
+	* src/format/format.h:
+	Resolve relative addresses for routines.
+
 12-12-21  Cyrille Bagard <nocbos@gmail.com>
 
 	* configure.ac:
diff --git a/configure.ac b/configure.ac
index 5658e46..e9f7a4e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -243,6 +243,7 @@ AC_CONFIG_FILES([Makefile
                  plugins/govm/Makefile
                  plugins/pychrysa/Makefile
                  plugins/pychrysa/analysis/Makefile
+                 plugins/pychrysa/analysis/binaries/Makefile
                  plugins/pychrysa/arch/Makefile
                  plugins/pychrysa/debug/Makefile
                  plugins/pychrysa/format/Makefile
diff --git a/plugins/pychrysa/analysis/Makefile.am b/plugins/pychrysa/analysis/Makefile.am
index f5322e8..66da864 100644
--- a/plugins/pychrysa/analysis/Makefile.am
+++ b/plugins/pychrysa/analysis/Makefile.am
@@ -6,6 +6,8 @@ libpychrysaanalysis_la_SOURCES =		\
 	module.h module.c					\
 	roptions.h roptions.c
 
+libpychrysaanalysis_la_LIBADD =			\
+	binaries/libpychrysaanalysisbinaries.la
 
 libpychrysaanalysis_la_LDFLAGS = 
 
@@ -16,3 +18,5 @@ INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_
 AM_CPPFLAGS = 
 
 AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
+
+SUBDIRS = binaries
diff --git a/plugins/pychrysa/analysis/binaries/Makefile.am b/plugins/pychrysa/analysis/binaries/Makefile.am
new file mode 100644
index 0000000..7643acf
--- /dev/null
+++ b/plugins/pychrysa/analysis/binaries/Makefile.am
@@ -0,0 +1,16 @@
+
+noinst_LTLIBRARIES = libpychrysaanalysisbinaries.la
+
+libpychrysaanalysisbinaries_la_SOURCES =\
+	file.h file.c						\
+	module.h module.c
+
+libpychrysaanalysisbinaries_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/analysis/binaries/file.c b/plugins/pychrysa/analysis/binaries/file.c
new file mode 100644
index 0000000..70192e9
--- /dev/null
+++ b/plugins/pychrysa/analysis/binaries/file.c
@@ -0,0 +1,142 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * file.c - prototypes pour l'équivalent Python du fichier "analysis/binaries/file.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 "file.h"
+
+
+
+#include <pygobject.h>
+
+
+#include <analysis/binaries/file.h>
+
+
+
+
+/* Crée un nouvel objet Python de type 'FileBinary'. */
+static PyObject *py_file_binary_new(PyTypeObject *, 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 'FileBinary'.            *
+*                                                                             *
+*  Retour      : Instance Python mise en place.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_file_binary_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    char *filename;                         /* Nom du fichier à charger    */
+    int ret;                                /* Bilan de lecture des args.  */
+    GLoadedBinary *binary;                  /* Version GLib du format      */
+
+    ret = PyArg_ParseTuple(args, "s", &filename);
+    if (!ret) Py_RETURN_NONE;
+
+    binary = g_file_binary_new_from_file(filename);
+
+    result = pygobject_new(G_OBJECT(binary));
+    //g_object_unref(binary);
+
+    return result;
+
+}
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide.analysis.LoadedBinary'.*
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool register_python_file_binary(PyObject *module)
+{
+    PyObject *parent_mod;                   /* Module Python-LoadedBinary  */
+    int ret;                                /* Bilan d'un appel            */
+
+    static PyMethodDef py_file_binary_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_file_binary_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_file_binary_type = {
+
+        PyObject_HEAD_INIT(NULL)
+
+        .tp_name        = "pychrysalide.analysis.binaries.FileBinary",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = "PyChrysalide file binary",
+
+        .tp_methods     = py_file_binary_methods,
+        .tp_getset      = py_file_binary_getseters,
+        .tp_new         = (newfunc)py_file_binary_new
+
+    };
+
+    parent_mod = PyImport_ImportModule("pychrysalide.analysis");
+    if (parent_mod == NULL) return false;
+
+    py_file_binary_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(parent_mod, "LoadedBinary");
+    Py_DECREF(parent_mod);
+
+    if (PyType_Ready(&py_file_binary_type) < 0)
+        return false;
+
+    Py_INCREF(&py_file_binary_type);
+    ret = PyModule_AddObject(module, "FileBinary", (PyObject *)&py_file_binary_type);
+
+    pygobject_register_class(module, "GFileBinary", G_TYPE_FILE_BINARY, &py_file_binary_type,
+                             Py_BuildValue("(O)", py_file_binary_type.tp_base));
+
+    return (ret == 0);
+
+}
diff --git a/plugins/pychrysa/analysis/binaries/file.h b/plugins/pychrysa/analysis/binaries/file.h
new file mode 100644
index 0000000..7cc3e26
--- /dev/null
+++ b/plugins/pychrysa/analysis/binaries/file.h
@@ -0,0 +1,39 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * file.h - prototypes pour l'équivalent Python du fichier "analysis/binaries/file.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_ANALYSIS_BINARIES_FILE_H
+#define _PLUGINS_PYCHRYSA_ANALYSIS_BINARIES_FILE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Prend en charge l'objet 'pychrysalide.analysis.binaries.FileBinary'. */
+bool register_python_file_binary(PyObject *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSA_ANALYSIS_BINARIES_FILE_H */
diff --git a/plugins/pychrysa/analysis/binaries/module.c b/plugins/pychrysa/analysis/binaries/module.c
new file mode 100644
index 0000000..084e0a4
--- /dev/null
+++ b/plugins/pychrysa/analysis/binaries/module.c
@@ -0,0 +1,66 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire binaries 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 "file.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Ajoute le module 'binaries' au module Python.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool add_binaries_module_to_python_module(PyObject *super)
+{
+    bool result;
+    PyObject *module;
+    int ret;                                /* Bilan d'un appel            */
+
+    static PyMethodDef py_format_methods[] = {
+        { NULL }
+    };
+
+    module = Py_InitModule("pychrysalide.analysis.binaries", py_format_methods);
+    if (module == NULL) return false;
+
+    Py_INCREF(module);
+    ret = PyModule_AddObject(super, "pychrysalide.analysis.binaries", module);
+
+    result = (ret != 0);
+
+    result &= register_python_file_binary(module);
+
+    return result;
+
+}
diff --git a/plugins/pychrysa/analysis/binaries/module.h b/plugins/pychrysa/analysis/binaries/module.h
new file mode 100644
index 0000000..228f33c
--- /dev/null
+++ b/plugins/pychrysa/analysis/binaries/module.h
@@ -0,0 +1,39 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire binaries 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_PYCHRYSA_ANALYSIS_BINARIES_MODULE_H
+#define _PLUGINS_PYCHRYSA_ANALYSIS_BINARIES_MODULE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Ajoute le module 'binaries' au module Python. */
+bool add_binaries_module_to_python_module(PyObject *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSA_ANALYSIS_BINARIES_MODULE_H */
diff --git a/plugins/pychrysa/analysis/binary.c b/plugins/pychrysa/analysis/binary.c
index e8158a2..abbbad5 100644
--- a/plugins/pychrysa/analysis/binary.c
+++ b/plugins/pychrysa/analysis/binary.c
@@ -28,7 +28,7 @@
 #include <pygobject.h>
 
 
-#include <analysis/binaries/file.h>  /* REMME ! */
+#include <analysis/binary.h>
 
 
 #include "../quirks.h"
@@ -38,9 +38,6 @@
 
 
 
-/* Crée un nouvel objet Python de type 'LoadedBinary'. */
-static PyObject *py_loaded_binary_new(PyTypeObject *, PyObject *, PyObject *);
-
 /* Fournit le fichier correspondant à l'élément binaire. */
 static PyObject *py_loaded_binary_get_filename(PyObject *self, PyObject *args);
 
@@ -60,68 +57,6 @@ static PyObject *py_loaded_binary_get_disassembled_buffer(PyObject *, void *);
 
 /******************************************************************************
 *                                                                             *
-*  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 'LoadedBinary'.          *
-*                                                                             *
-*  Retour      : Instance Python mise en place.                               *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static PyObject *py_loaded_binary_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
-    PyObject *result;                       /* Instance à retourner        */
-    char *filename;                         /* Nom du fichier à charger    */
-    int ret;                                /* Bilan de lecture des args.  */
-    GLoadedBinary *binary;                  /* Version GLib du format      */
-
-    ret = PyArg_ParseTuple(args, "s", &filename);
-    if (!ret) return Py_None;
-
-    binary = g_file_binary_new_from_file(filename);
-
-    result = py_loaded_binary_from_c(binary);
-    g_object_unref(binary);
-
-    return (PyObject *)result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : binary = instance existante GLib.                            *
-*                                                                             *
-*  Description : Crée un nouvel objet Python de type 'LoadedBinary'.          *
-*                                                                             *
-*  Retour      : Instance Python mise en place.                               *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-PyObject *py_loaded_binary_from_c(GLoadedBinary *binary)
-{
-    PyObject *module;                       /* Module d'appartenance       */
-    PyTypeObject *type;                     /* Type Python correspondant   */
-
-    module = PyImport_ImportModule("pychrysalide.analysis");
-    type = (PyTypeObject *)PyObject_GetAttrString(module, "LoadedBinary");
-    Py_DECREF(module);
-
-    pychrysalide_set_instance_data(G_OBJECT(binary), type);
-
-    return pygobject_new(G_OBJECT(binary));
-
-}
-
-
-/******************************************************************************
-*                                                                             *
 *  Paramètres  : self = classe représentant un binaire.                       *
 *                args = arguments fournis à l'appel.                          *
 *                                                                             *
@@ -172,7 +107,7 @@ static PyObject *py_loaded_binary_get_format(PyObject *self, PyObject *args)
     binary = G_LOADED_BINARY(pygobject_get(self));
     format = g_loaded_binary_get_format(binary);
 
-    result = py_executable_format_from_c(format);
+    result = pygobject_new(G_OBJECT(format));
 
     return result;
 
@@ -202,7 +137,7 @@ static PyObject *py_loaded_binary_get_instructions(PyObject *self, PyObject *arg
 
     instr = g_loaded_binary_get_instructions(binary);
 
-    result = py_arch_instruction_from_c(instr);
+    result = pygobject_new(G_OBJECT(instr));
 
     return result;
 
@@ -234,7 +169,7 @@ static PyObject *py_loaded_binary_get_disassembled_buffer(PyObject *self, void *
     binary = G_LOADED_BINARY(pygobject_get(self));
     buffer = g_loaded_binary_get_disassembled_buffer(binary);
 
-    result = py_code_buffer_from_c(buffer);
+    result = pygobject_new(G_OBJECT(buffer));
 
     return result;
 
@@ -304,8 +239,7 @@ bool register_python_loaded_binary(PyObject *module)
         .tp_doc         = "PyChrysalide loaded binary",
 
         .tp_methods     = py_loaded_binary_methods,
-        .tp_getset      = py_loaded_binary_getseters,
-        .tp_new         = (newfunc)py_loaded_binary_new
+        .tp_getset      = py_loaded_binary_getseters
 
     };
 
diff --git a/plugins/pychrysa/analysis/binary.h b/plugins/pychrysa/analysis/binary.h
index 33ead7e..e161a5b 100644
--- a/plugins/pychrysa/analysis/binary.h
+++ b/plugins/pychrysa/analysis/binary.h
@@ -29,13 +29,8 @@
 #include <Python.h>
 #include <stdbool.h>
 
-#include <analysis/binary.h>
 
 
-
-/* Crée un nouvel objet Python de type 'LoadedBinary'. */
-PyObject *py_loaded_binary_from_c(GLoadedBinary *);
-
 /* Prend en charge l'objet 'pychrysalide.analysis.LoadedBinary'. */
 bool register_python_loaded_binary(PyObject *);
 
diff --git a/plugins/pychrysa/analysis/module.c b/plugins/pychrysa/analysis/module.c
index 42b888e..688ea12 100644
--- a/plugins/pychrysa/analysis/module.c
+++ b/plugins/pychrysa/analysis/module.c
@@ -26,6 +26,7 @@
 
 
 #include "binary.h"
+#include "binaries/module.h"
 
 
 
@@ -60,6 +61,7 @@ bool add_analysis_module_to_python_module(PyObject *super)
     result = (ret != 0);
 
     result &= register_python_loaded_binary(module);
+    result &= add_binaries_module_to_python_module(module);
 
     return result;
 
diff --git a/plugins/pychrysa/analysis/roptions.c b/plugins/pychrysa/analysis/roptions.c
index 57a4f52..a2b72e1 100644
--- a/plugins/pychrysa/analysis/roptions.c
+++ b/plugins/pychrysa/analysis/roptions.c
@@ -85,7 +85,7 @@ static PyObject *py_rendering_options_new(PyTypeObject *type, PyObject *args, Py
     GExeFormat *_executable;                /* Version GLib du format      */
 
     ret = PyArg_ParseTuple(args, "O", &executable);
-    if (!ret) return Py_None;
+    if (!ret) Py_RETURN_NONE;
 
     result = (py_rendering_options *)type->tp_alloc(type, 0);
 
@@ -199,7 +199,7 @@ static PyObject *py_rendering_options_show_code(PyObject *self, PyObject *args)
 
     printf("show code :: %d\n", state);
 
-    return Py_None;
+    Py_RETURN_NONE;
 
 }
 
diff --git a/plugins/pychrysa/arch/instruction.c b/plugins/pychrysa/arch/instruction.c
index bed937b..09397fc 100644
--- a/plugins/pychrysa/arch/instruction.c
+++ b/plugins/pychrysa/arch/instruction.c
@@ -30,6 +30,9 @@
 #include <string.h>
 
 
+#include <arch/instruction.h>
+
+
 #include "../quirks.h"
 
 
@@ -105,13 +108,14 @@ static PyObject *py_arch_instruction_iterator_create(PyObject *origin)
     Py_DECREF(module);
 
     result = (PyArchInstructionIter *)type->tp_alloc(type, 0);
+    Py_DECREF(type);
 
     if (result != NULL)
     {
+        Py_INCREF(origin);
         result->head = G_ARCH_INSTRUCTION(pygobject_get(origin));
         g_object_ref(G_OBJECT(result->head));
 
-        Py_INCREF(origin);
         result->current = origin;
     }
 
@@ -134,8 +138,12 @@ static PyObject *py_arch_instruction_iterator_create(PyObject *origin)
 
 static void py_arch_instruction_iterator_dealloc(PyArchInstructionIter *self)
 {
+    PyObject *first;                        /* Récupération de la première */
+
+    first = pychrysalide_get_pygobject(G_OBJECT(self->head));
+
+    Py_DECREF(first);
     g_object_unref(G_OBJECT(self->head));
-    Py_DECREF(self->current);
 
 #if PY_VERSION_HEX < 0x03000000
     self->ob_type->tp_free((PyObject *)self);
@@ -167,6 +175,8 @@ static PyObject *py_arch_instruction_iterator_next(PyArchInstructionIter *self)
     {
         self->started = true;
         result = self->current;
+        Py_INCREF(result);
+
     }
     else
     {
@@ -175,17 +185,14 @@ static PyObject *py_arch_instruction_iterator_next(PyArchInstructionIter *self)
 
         if (next != NULL)
         {
-            result = py_arch_instruction_from_c(next);
-
-            Py_INCREF(result);
-            Py_DECREF(self->current);
+            result = pygobject_new(G_OBJECT(next));
             self->current = result;
-
         }
         else result = NULL;
 
     }
 
+    Py_XINCREF(result);
     return (PyObject *)result;
 
 }
@@ -258,35 +265,7 @@ bool register_python_arch_instruction_iterator(PyObject *module)
 
 static PyObject *py_arch_instruction_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
-    return Py_None;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : binary = instance existante GLib.                            *
-*                                                                             *
-*  Description : Crée un nouvel objet Python de type 'ArchInstruction'.       *
-*                                                                             *
-*  Retour      : Instance Python mise en place.                               *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-PyObject *py_arch_instruction_from_c(GArchInstruction *instr)
-{
-    PyObject *module;                       /* Module d'appartenance       */
-    PyTypeObject *type;                     /* Type Python correspondant   */
-
-    module = PyImport_ImportModule("pychrysalide.arch");
-    type = (PyTypeObject *)PyObject_GetAttrString(module, "ArchInstruction");
-    Py_DECREF(module);
-
-    pychrysalide_set_instance_data(G_OBJECT(instr), type);
-
-    return pygobject_new(G_OBJECT(instr));
+    Py_RETURN_NONE;
 
 }
 
@@ -337,12 +316,15 @@ static PyObject *py_arch_instruction_get_location(PyObject *self, char *name)
     if (strcmp(name, "offset") == 0)
         result = PyLong_FromLong(offset);
 
-    else if (strcmp(name, "") == 0)
+    else if (strcmp(name, "length") == 0)
         result = PyLong_FromLong(length);
 
-    else /*if (strcmp(name, "") == 0)*/
+    else if (strcmp(name, "address") == 0)
         result = PyLong_FromLongLong(address);
 
+    else
+        result = NULL;
+
     return result;
 
 }
@@ -449,6 +431,10 @@ bool register_python_arch_instruction(PyObject *module)
     Py_INCREF(&py_arch_instruction_type);
     ret = PyModule_AddObject(module, "ArchInstruction", (PyObject *)&py_arch_instruction_type);
 
+    pygobject_register_class(module, "GArchInstruction", G_TYPE_ARCH_INSTRUCTION,
+                             &py_arch_instruction_type,
+                             Py_BuildValue("(O)", py_arch_instruction_type.tp_base));
+
     return (ret == 0);
 
 }
diff --git a/plugins/pychrysa/arch/instruction.h b/plugins/pychrysa/arch/instruction.h
index 545d88e..d91b8d1 100644
--- a/plugins/pychrysa/arch/instruction.h
+++ b/plugins/pychrysa/arch/instruction.h
@@ -29,8 +29,6 @@
 #include <Python.h>
 #include <stdbool.h>
 
-#include <arch/instruction.h>
-
 
 
 /* --------------------- ITERATEUR POUR BOUCLE SUR INSTRUCTIONS --------------------- */
@@ -44,9 +42,6 @@ bool register_python_arch_instruction_iterator(PyObject *);
 /* --------------------- INSTRUCTIONS D'ARCHITECTURES EN PYTHON --------------------- */
 
 
-/* Crée un nouvel objet Python de type 'ArchInstruction'. */
-PyObject *py_arch_instruction_from_c(GArchInstruction *);
-
 /* Prend en charge l'objet 'pychrysalide.arch.ArchInstruction'. */
 bool register_python_arch_instruction(PyObject *);
 
diff --git a/plugins/pychrysa/arch/processor.c b/plugins/pychrysa/arch/processor.c
index 0a3fe95..cc1113a 100644
--- a/plugins/pychrysa/arch/processor.c
+++ b/plugins/pychrysa/arch/processor.c
@@ -224,32 +224,6 @@ static PyObject *py_processor_new(PyTypeObject *type, PyObject *args, PyObject *
 
 
 
-static PyObject *util_FromImport(const char *name, const char *from_item)
-{
-  PyObject *from_list;
-  PyObject *module;
-  PyObject *item;
-
-  /* Make the from list. */
-  from_list = PyList_New(1);
-  PyList_SetItem(from_list, 0, PyString_FromString(from_item));
-
-  /* Attempt the import, with const correctness removed. */
-  module = PyImport_ImportModuleEx((char *)name, NULL, NULL, from_list);
-  Py_DECREF(from_list);
-  if (!module)
-  {
-    return NULL;
-  }
-
-  /* Get the from_item from the module. */
-  item = PyObject_GetAttrString(module, (char *)from_item);
-  Py_DECREF(module);
-
-  return item;
-}
-
-
 
 
 
diff --git a/plugins/pychrysa/debug/debugger.c b/plugins/pychrysa/debug/debugger.c
index c27d30d..1e82272 100644
--- a/plugins/pychrysa/debug/debugger.c
+++ b/plugins/pychrysa/debug/debugger.c
@@ -67,7 +67,7 @@ static PyObject *py_binary_debugger_new(PyTypeObject *type, PyObject *args, PyOb
     GBinaryDebugger *debugger;              /* Version GLib du format      */
 
     ret = PyArg_ParseTuple(args, "l", &dtype);
-    if (!ret) return Py_None;
+    if (!ret) Py_RETURN_NONE;
 
     debugger = g_new_binary_debugger(dtype, NULL/* FIXME */);
 
@@ -188,7 +188,7 @@ static PyObject *py_binary_debugger_get_frames_stack(PyObject *self, PyObject *a
     debugger = G_BINARY_DEBUGGER(pygobject_get(self));
 
     if (!PyArg_ParseTuple(args, "k", &thread))
-        return Py_None;
+        Py_RETURN_NONE;
 
     frames = g_binary_debugger_get_frames_stack(debugger, thread, &count);
 
diff --git a/plugins/pychrysa/format/dex/class.c b/plugins/pychrysa/format/dex/class.c
index 97c1968..bc07fae 100644
--- a/plugins/pychrysa/format/dex/class.c
+++ b/plugins/pychrysa/format/dex/class.c
@@ -28,6 +28,9 @@
 #include <pygobject.h>
 
 
+#include <format/dex/class.h>
+
+
 #include "../../quirks.h"
 
 
@@ -53,37 +56,11 @@ static PyObject *py_dex_class_new(PyTypeObject *, PyObject *, PyObject *);
 
 static PyObject *py_dex_class_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
-    return Py_None;
+    Py_RETURN_NONE;
 
 }
 
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : item = instance existante GLib.                              *
-*                                                                             *
-*  Description : Crée un nouvel objet Python de type 'DexClass'.              *
-*                                                                             *
-*  Retour      : Instance Python mise en place.                               *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-PyObject *py_dex_class_from_c(GDexClass *class)
-{
-    PyObject *module;                       /* Module d'appartenance       */
-    PyTypeObject *type;                     /* Type Python correspondant   */
-
-    module = PyImport_ImportModule("pychrysalide.format.dex");
-    type = (PyTypeObject *)PyObject_GetAttrString(module, "DexClass");
-    Py_DECREF(module);
-
-    pychrysalide_set_instance_data(G_OBJECT(class), type);
-
-    return pygobject_new(G_OBJECT(class));
-
-}
 
 
 
@@ -152,6 +129,9 @@ bool register_python_dex_class(PyObject *module)
     Py_INCREF(&py_dex_class_type);
     ret = PyModule_AddObject(module, "DexClass", (PyObject *)&py_dex_class_type);
 
+    pygobject_register_class(module, "GDexClass", G_TYPE_DEX_CLASS, &py_dex_class_type,
+                             Py_BuildValue("(O)", py_dex_class_type.tp_base));
+
     return (ret == 0);
 
 }
diff --git a/plugins/pychrysa/format/dex/class.h b/plugins/pychrysa/format/dex/class.h
index addf7ca..c2a8222 100644
--- a/plugins/pychrysa/format/dex/class.h
+++ b/plugins/pychrysa/format/dex/class.h
@@ -29,13 +29,8 @@
 #include <Python.h>
 #include <stdbool.h>
 
-#include <format/dex/class.h>
 
 
-
-/* Crée un nouvel objet Python de type 'DexClass'. */
-PyObject *py_dex_class_from_c(GDexClass *);
-
 /* Prend en charge l'objet 'pychrysalide.format.dex.DexClass'. */
 bool register_python_dex_class(PyObject *module);
 
diff --git a/plugins/pychrysa/format/dex/dex.c b/plugins/pychrysa/format/dex/dex.c
index 2df8d1b..cae87f7 100644
--- a/plugins/pychrysa/format/dex/dex.c
+++ b/plugins/pychrysa/format/dex/dex.c
@@ -27,6 +27,7 @@
 
 #include <pygobject.h>
 
+
 #include <format/dex/dex-int.h>
 
 
@@ -69,13 +70,13 @@ static PyObject *py_dex_format_new(PyTypeObject *type, PyObject *args, PyObject
     GBinFormat *format;                     /* Version GLib du format      */
 
     ret = PyArg_ParseTuple(args, "s#", &content, &length);
-    if (!ret) return Py_None;
+    if (!ret) Py_RETURN_NONE;
 
     format = g_dex_format_new(content, length);
-    if (format == NULL) return Py_None;
+    if (format == NULL) Py_RETURN_NONE;
 
-    result = py_dex_format_from_c(G_DEX_FORMAT(format));
-    g_object_unref(format);
+    result = pygobject_new(G_OBJECT(format));
+    //g_object_unref(format);
 
     return (PyObject *)result;
 
@@ -84,34 +85,6 @@ static PyObject *py_dex_format_new(PyTypeObject *type, PyObject *args, PyObject
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : item = instance existante GLib.                              *
-*                                                                             *
-*  Description : Crée un nouvel objet Python de type 'DexFormat'.             *
-*                                                                             *
-*  Retour      : Instance Python mise en place.                               *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-PyObject *py_dex_format_from_c(GDexFormat *format)
-{
-    PyObject *module;                       /* Module d'appartenance       */
-    PyTypeObject *type;                     /* Type Python correspondant   */
-
-    module = PyImport_ImportModule("pychrysalide.format.dex");
-    type = (PyTypeObject *)PyObject_GetAttrString(module, "DexFormat");
-    Py_DECREF(module);
-
-    pychrysalide_set_instance_data(G_OBJECT(format), type);
-
-    return pygobject_new(G_OBJECT(format));
-
-}
-
-
-/******************************************************************************
-*                                                                             *
 *  Paramètres  : self = classe représentant un binaire.                       *
 *                args = arguments fournis à l'appel.                          *
 *                                                                             *
@@ -162,14 +135,14 @@ static PyObject *py_dex_format_get_class(PyObject *self, PyObject *args)
     GDexClass *class;                       /* Classe à communiquer        */
 
     ret = PyArg_ParseTuple(args, "i", &index);
-    if (!ret) return Py_None;
+    if (!ret) Py_RETURN_NONE;
 
     format = G_DEX_FORMAT(pygobject_get(self));
 
     class = g_dex_format_get_class(format, index);
-    if (class == NULL) return Py_None;
+    if (class == NULL) Py_RETURN_NONE;
 
-    result = py_dex_class_from_c(class);
+    result = pygobject_new(G_OBJECT(class));
 
     return result;
 
@@ -233,10 +206,10 @@ bool register_python_dex_format(PyObject *module)
 
     };
 
-    pygobj_mod = PyImport_ImportModule("gobject");
+    pygobj_mod = PyImport_ImportModule("pychrysalide.format");
     if (pygobj_mod == NULL) return false;
 
-    py_dex_format_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(pygobj_mod, "GObject");
+    py_dex_format_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(pygobj_mod, "BinFormat");
     Py_DECREF(pygobj_mod);
 
     if (PyType_Ready(&py_dex_format_type) < 0)
@@ -245,6 +218,9 @@ bool register_python_dex_format(PyObject *module)
     Py_INCREF(&py_dex_format_type);
     ret = PyModule_AddObject(module, "DexFormat", (PyObject *)&py_dex_format_type);
 
+    pygobject_register_class(module, "GDexFormat", G_TYPE_DEX_FORMAT, &py_dex_format_type,
+                             Py_BuildValue("(O)", py_dex_format_type.tp_base));
+
     return (ret == 0);
 
 }
diff --git a/plugins/pychrysa/format/dex/dex.h b/plugins/pychrysa/format/dex/dex.h
index 65eec0d..dc97269 100644
--- a/plugins/pychrysa/format/dex/dex.h
+++ b/plugins/pychrysa/format/dex/dex.h
@@ -29,13 +29,8 @@
 #include <Python.h>
 #include <stdbool.h>
 
-#include <format/dex/dex.h>
 
 
-
-/* Crée un nouvel objet Python de type 'DexFormat'. */
-PyObject *py_dex_format_from_c(GDexFormat *);
-
 /* Prend en charge l'objet 'pychrysalide.format.dex.DexFormat'. */
 bool register_python_dex_format(PyObject *module);
 
diff --git a/plugins/pychrysa/format/executable.c b/plugins/pychrysa/format/executable.c
index 7cdc855..43375ea 100644
--- a/plugins/pychrysa/format/executable.c
+++ b/plugins/pychrysa/format/executable.c
@@ -48,7 +48,7 @@
 
 PyObject *py_executable_format_from_c(GExeFormat *format)
 {
-    return py_binary_format_from_c(G_BIN_FORMAT(format));
+    return NULL;//py_binary_format_from_c(G_BIN_FORMAT(format));
 
 }
 
diff --git a/plugins/pychrysa/format/format.c b/plugins/pychrysa/format/format.c
index ea556ba..4032da0 100644
--- a/plugins/pychrysa/format/format.c
+++ b/plugins/pychrysa/format/format.c
@@ -28,6 +28,9 @@
 #include <pygobject.h>
 
 
+#include <format/format.h>
+
+
 #include "dex/dex.h"
 #include "../quirks.h"
 
@@ -36,6 +39,9 @@
 /* Crée un nouvel objet Python de type 'BinFormat'. */
 static PyObject *py_binary_format_new(PyTypeObject *, PyObject *, PyObject *);
 
+/* Recherche une position dans une routine selon une adresse. */
+static PyObject *py_binary_format_resolve_relative_routine(PyObject *, PyObject *);
+
 
 
 /******************************************************************************
@@ -54,43 +60,53 @@ static PyObject *py_binary_format_new(PyTypeObject *, PyObject *, PyObject *);
 
 static PyObject *py_binary_format_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
-    return Py_None;
+    Py_RETURN_NONE;
 
 }
 
 
+
+
+
+
+
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : format = instance existante GLib.                            *
+*  Paramètres  : self = classe représentant un binaire.                       *
+*                args = arguments fournis à l'appel.                          *
 *                                                                             *
-*  Description : Crée un nouvel objet Python de type 'BinFormat'.             *
+*  Description : Recherche une position dans une routine selon une adresse.   *
 *                                                                             *
-*  Retour      : Instance Python mise en place.                               *
+*  Retour      : Tuple (nom, décallage) ou Py_None.                           *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-PyObject *py_binary_format_from_c(GBinFormat *format)
+static PyObject *py_binary_format_resolve_relative_routine(PyObject *self, PyObject *args)
 {
-    PyObject *result;                       /* Conversion à retourner      */
-    GType type;                             /* Type réel du format         */
+    PyObject *result;                       /* Tuple à retourner           */
+    GBinFormat *format;                     /* Format à manipuler          */
+    vmpa_t addr;                            /* Adresse demandée en visuel  */
+    int ret;                                /* Bilan de lecture des args.  */
+    bool found;                             /* Bilan de la résolution      */
+    const char *label;                      /* Désignation de la trouvaille*/
 
-    type = G_OBJECT_TYPE(G_OBJECT(format));
-
-    if (type == G_TYPE_DEX_FORMAT)
-        result = py_dex_format_from_c(G_DEX_FORMAT(format));
-    else
-        result = Py_None;
-
-    return result;
-
-}
+    format = G_BIN_FORMAT(pygobject_get(self));
 
+    ret = PyArg_ParseTuple(args, "K", &addr);
+    if (!ret) Py_RETURN_NONE;
 
+    found = g_binary_format_resolve_relative_routine(format, &label, &addr);
+    if (!found) Py_RETURN_NONE;
 
+    result = PyTuple_New(2);
+    PyTuple_SetItem(result, 0, PyString_FromString(label));
+    PyTuple_SetItem(result, 1, PyLong_FromLongLong(addr));
 
+    return result;
 
+}
 
 
 
@@ -114,10 +130,15 @@ PyObject *py_binary_format_from_c(GBinFormat *format)
 
 bool register_python_binary_format(PyObject *module)
 {
-    PyObject *pygobj_mod;                   /* Module Python-GObject       */
+    PyObject *parent_mod;                   /* Module Python-GObject       */
     int ret;                                /* Bilan d'un appel            */
 
     static PyMethodDef py_binary_format_methods[] = {
+        {
+            "resolve_relative_routine", (PyCFunction)py_binary_format_resolve_relative_routine,
+            METH_VARARGS,
+            "Search a position inside a routine by a given address."
+        },
         { NULL }
     };
 
@@ -142,11 +163,11 @@ bool register_python_binary_format(PyObject *module)
 
     };
 
-    pygobj_mod = PyImport_ImportModule("gobject");
-    if (pygobj_mod == NULL) return false;
+    parent_mod = PyImport_ImportModule("gobject");
+    if (parent_mod == NULL) return false;
 
-    py_binary_format_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(pygobj_mod, "GObject");
-    Py_DECREF(pygobj_mod);
+    py_binary_format_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(parent_mod, "GObject");
+    Py_DECREF(parent_mod);
 
     if (PyType_Ready(&py_binary_format_type) < 0)
         return false;
diff --git a/plugins/pychrysa/format/format.h b/plugins/pychrysa/format/format.h
index 8f38408..ede833e 100644
--- a/plugins/pychrysa/format/format.h
+++ b/plugins/pychrysa/format/format.h
@@ -29,13 +29,8 @@
 #include <Python.h>
 #include <stdbool.h>
 
-#include <format/format.h>
 
 
-
-/* Crée un nouvel objet Python de type 'BinFormat'. */
-PyObject *py_binary_format_from_c(GBinFormat *);
-
 /* Prend en charge l'objet 'pychrysalide.format.BinFormat'. */
 bool register_python_binary_format(PyObject *module);
 
diff --git a/plugins/pychrysa/format/module.c b/plugins/pychrysa/format/module.c
index d3e863f..8bf2ed2 100644
--- a/plugins/pychrysa/format/module.c
+++ b/plugins/pychrysa/format/module.c
@@ -26,6 +26,7 @@
 
 
 #include "executable.h"
+#include "format.h"
 #include "dex/module.h"
 
 
@@ -62,6 +63,7 @@ bool add_format_module_to_python_module(PyObject *super)
 
     result = (ret != 0);
 
+    result &= register_python_binary_format(module);
     result &= add_format_executable_to_python_module(module);
 
     result &= add_format_dex_module_to_python_module(module);
diff --git a/plugins/pychrysa/glibext/bufferline.c b/plugins/pychrysa/glibext/bufferline.c
index 1e3b611..3804082 100644
--- a/plugins/pychrysa/glibext/bufferline.c
+++ b/plugins/pychrysa/glibext/bufferline.c
@@ -29,6 +29,9 @@
 #include <pygobject.h>
 
 
+#include <glibext/gbufferline.h>
+
+
 #include "../quirks.h"
 
 
@@ -40,34 +43,6 @@ static PyObject *py_buffer_line_get_text(PyObject *, PyObject *);
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : binary = instance existante GLib.                            *
-*                                                                             *
-*  Description : Crée un nouvel objet Python de type 'BufferLine'.            *
-*                                                                             *
-*  Retour      : Instance Python mise en place.                               *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-PyObject *py_buffer_line_from_c(GBufferLine *line)
-{
-    PyObject *module;                       /* Module d'appartenance       */
-    PyTypeObject *type;                     /* Type Python correspondant   */
-
-    module = PyImport_ImportModule("pychrysalide.glibext");
-    type = (PyTypeObject *)PyObject_GetAttrString(module, "BufferLine");
-    Py_DECREF(module);
-
-    pychrysalide_set_instance_data(G_OBJECT(line), type);
-
-    return pygobject_new(G_OBJECT(line));
-
-}
-
-
-/******************************************************************************
-*                                                                             *
 *  Paramètres  : self = classe représentant une ligne de tampon.              *
 *                args = arguments fournis à l'appel.                          *
 *                                                                             *
@@ -150,6 +125,9 @@ bool register_python_buffer_line(PyObject *module)
     Py_INCREF(&py_buffer_line_type);
     ret = PyModule_AddObject(module, "BufferLine", (PyObject *)&py_buffer_line_type);
 
+    pygobject_register_class(module, "GBufferLine", G_TYPE_BUFFER_LINE, &py_buffer_line_type,
+                             Py_BuildValue("(O)", py_buffer_line_type.tp_base));
+
     return (ret == 0);
 
 }
diff --git a/plugins/pychrysa/glibext/bufferline.h b/plugins/pychrysa/glibext/bufferline.h
index d15928f..abe6cd8 100644
--- a/plugins/pychrysa/glibext/bufferline.h
+++ b/plugins/pychrysa/glibext/bufferline.h
@@ -29,13 +29,8 @@
 #include <Python.h>
 #include <stdbool.h>
 
-#include <glibext/gbufferline.h>
 
 
-
-/* Crée un nouvel objet Python de type 'BufferLine'. */
-PyObject *py_buffer_line_from_c(GBufferLine *);
-
 /* Prend en charge l'objet 'pychrysalide.glibext.BufferLine'. */
 bool register_python_buffer_line(PyObject *);
 
diff --git a/plugins/pychrysa/glibext/codebuffer.c b/plugins/pychrysa/glibext/codebuffer.c
index a090e27..e4c94e3 100644
--- a/plugins/pychrysa/glibext/codebuffer.c
+++ b/plugins/pychrysa/glibext/codebuffer.c
@@ -28,6 +28,9 @@
 #include <pygobject.h>
 
 
+#include <glibext/gcodebuffer.h>
+
+
 #include "../quirks.h"
 
 
@@ -39,34 +42,6 @@ static PyObject *py_code_buffer_find_line_by_addr(PyObject *, PyObject *);
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : binary = instance existante GLib.                            *
-*                                                                             *
-*  Description : Crée un nouvel objet Python de type 'Codebuffer'.            *
-*                                                                             *
-*  Retour      : Instance Python mise en place.                               *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-PyObject *py_code_buffer_from_c(GCodeBuffer *buffer)
-{
-    PyObject *module;                       /* Module d'appartenance       */
-    PyTypeObject *type;                     /* Type Python correspondant   */
-
-    module = PyImport_ImportModule("pychrysalide.glibext");
-    type = (PyTypeObject *)PyObject_GetAttrString(module, "CodeBuffer");
-    Py_DECREF(module);
-
-    pychrysalide_set_instance_data(G_OBJECT(buffer), type);
-
-    return pygobject_new(G_OBJECT(buffer));
-
-}
-
-
-/******************************************************************************
-*                                                                             *
 *  Paramètres  : self = classe représentant un tampon de code.                *
 *                args = arguments fournis à l'appel.                          *
 *                                                                             *
@@ -89,12 +64,12 @@ static PyObject *py_code_buffer_find_line_by_addr(PyObject *self, PyObject *args
     buffer = G_CODE_BUFFER(pygobject_get(self));
 
     ret = PyArg_ParseTuple(args, "K", &addr);
-    if (!ret) return Py_None;
+    if (!ret) Py_RETURN_NONE;
 
     line = g_code_buffer_find_line_by_addr(buffer, addr);
-    if (line == NULL) return Py_None;
+    if (line == NULL) Py_RETURN_NONE;
 
-    result = py_buffer_line_from_c(line);
+    result = pygobject_new(G_OBJECT(line));
 
     return result;
 
@@ -154,6 +129,9 @@ bool register_python_code_buffer(PyObject *module)
     Py_INCREF(&py_code_buffer_type);
     ret = PyModule_AddObject(module, "CodeBuffer", (PyObject *)&py_code_buffer_type);
 
+    pygobject_register_class(module, "GCodeBuffer", G_TYPE_CODE_BUFFER, &py_code_buffer_type,
+                             Py_BuildValue("(O)", py_code_buffer_type.tp_base));
+
     return (ret == 0);
 
 }
diff --git a/plugins/pychrysa/glibext/codebuffer.h b/plugins/pychrysa/glibext/codebuffer.h
index ba53fda..d80597e 100644
--- a/plugins/pychrysa/glibext/codebuffer.h
+++ b/plugins/pychrysa/glibext/codebuffer.h
@@ -29,13 +29,8 @@
 #include <Python.h>
 #include <stdbool.h>
 
-#include <glibext/gcodebuffer.h>
 
 
-
-/* Crée un nouvel objet Python de type 'CodeBuffer'. */
-PyObject *py_code_buffer_from_c(GCodeBuffer *);
-
 /* Prend en charge l'objet 'pychrysalide.glibext.CodeBuffer'. */
 bool register_python_code_buffer(PyObject *);
 
diff --git a/plugins/pychrysa/gtkext/viewpanel.c b/plugins/pychrysa/gtkext/viewpanel.c
index c1108c2..9d5645a 100644
--- a/plugins/pychrysa/gtkext/viewpanel.c
+++ b/plugins/pychrysa/gtkext/viewpanel.c
@@ -28,6 +28,9 @@
 #include <pygobject.h>
 
 
+#include <gtkext/gtkviewpanel.h>
+
+
 #include "../quirks.h"
 
 
@@ -66,7 +69,7 @@ static PyObject *py_view_panel_new(PyTypeObject *type, PyObject *args, PyObject
     GEditorItem *item;                      /* Version GLib du format      */
 
     ret = PyArg_ParseTuple(args, "ssOs", &name, &lname, &widget, &path);
-    if (!ret) return Py_None;
+    if (!ret) Py_RETURN_NONE;
 
     item = g_view_panel_new(get_internal_ref(), name, lname,
                             GTK_WIDGET(pygobject_get(widget)), path);
@@ -78,35 +81,9 @@ static PyObject *py_view_panel_new(PyTypeObject *type, PyObject *args, PyObject
 #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));
+    Py_RETURN_NONE;
 
 }
 
@@ -114,6 +91,7 @@ PyObject *py_view_panel_from_c(GtkViewPanel *item)
 
 
 
+
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : self = classe représentant un tampon de code.                *
@@ -136,7 +114,7 @@ static PyObject *py_view_panel_scroll_to_address(PyObject *self, PyObject *args)
     panel = GTK_VIEW_PANEL(pygobject_get(self));
 
     ret = PyArg_ParseTuple(args, "K", &addr);
-    if (!ret) return Py_None;
+    if (!ret) Py_RETURN_NONE;
 
     gtk_view_panel_scroll_to_address(panel, addr);
 
@@ -209,6 +187,9 @@ bool register_python_view_panel(PyObject *module)
     Py_INCREF(&py_view_panel_type);
     ret = PyModule_AddObject(module, "ViewPanel", (PyObject *)&py_view_panel_type);
 
+    pygobject_register_class(module, "GtkViewPanel", GTK_TYPE_VIEW_PANEL, &py_view_panel_type,
+                             Py_BuildValue("(O)", py_view_panel_type.tp_base));
+
     return (ret == 0);
 
 }
diff --git a/plugins/pychrysa/gtkext/viewpanel.h b/plugins/pychrysa/gtkext/viewpanel.h
index 98b1150..7733e46 100644
--- a/plugins/pychrysa/gtkext/viewpanel.h
+++ b/plugins/pychrysa/gtkext/viewpanel.h
@@ -29,13 +29,8 @@
 #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);
 
diff --git a/plugins/pychrysa/gui/editem.c b/plugins/pychrysa/gui/editem.c
index 3b7a8b8..c7e4724 100644
--- a/plugins/pychrysa/gui/editem.c
+++ b/plugins/pychrysa/gui/editem.c
@@ -97,7 +97,7 @@ static void _update_editor_item_for_binary_python_wrapper(GEditorItem *item, GLo
     target = pychrysalide_get_pygobject(G_OBJECT(item));
 
     args = PyTuple_New(1);
-    PyTuple_SetItem(args, 0, py_loaded_binary_from_c(binary));
+    PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(binary)));
 
     value = run_python_method(target, "update_for_binary", args);
 
@@ -139,7 +139,7 @@ static void _update_editor_item_for_view_python_wrapper(GEditorItem *item, GtkVi
     target = pychrysalide_get_pygobject(G_OBJECT(item));
 
     args = PyTuple_New(1);
-    PyTuple_SetItem(args, 0, py_view_panel_from_c(view));
+    PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(view)));
 
     value = run_python_method(target, "update_for_view", args);
 
@@ -181,7 +181,7 @@ static void _update_editor_item_for_view_content_python_wrapper(GEditorItem *ite
     target = pychrysalide_get_pygobject(G_OBJECT(item));
 
     args = PyTuple_New(1);
-    PyTuple_SetItem(args, 0, py_view_panel_from_c(view));
+    PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(view)));
 
     value = run_python_method(target, "update_for_content", args);
 
@@ -280,7 +280,7 @@ static PyObject *py_editor_item_get_current_binary(PyObject *self, PyObject *arg
         result = Py_None;
     }
     else
-        result = py_loaded_binary_from_c(binary);
+        result = pygobject_new(G_OBJECT(binary));
 
     return result;
 
@@ -315,7 +315,7 @@ static PyObject *py_editor_item_get_current_view(PyObject *self, PyObject *args)
         result = Py_None;
     }
     else
-        result = py_view_panel_from_c(panel);
+        result = pygobject_new(G_OBJECT(panel));
 
     return result;
 
diff --git a/plugins/pychrysa/gui/panels/panel.c b/plugins/pychrysa/gui/panels/panel.c
index 4b982d0..fc261b5 100644
--- a/plugins/pychrysa/gui/panels/panel.c
+++ b/plugins/pychrysa/gui/panels/panel.c
@@ -65,7 +65,7 @@ static PyObject *py_panel_item_new(PyTypeObject *type, PyObject *args, PyObject
     GEditorItem *item;                      /* Version GLib du format      */
 
     ret = PyArg_ParseTuple(args, "ssOs", &name, &lname, &widget, &path);
-    if (!ret) return Py_None;
+    if (!ret) Py_RETURN_NONE;
 
     item = g_panel_item_new(get_internal_ref(), name, lname,
                             GTK_WIDGET(pygobject_get(widget)), path);
@@ -73,7 +73,7 @@ static PyObject *py_panel_item_new(PyTypeObject *type, PyObject *args, PyObject
     result = _py_panel_item_from_c(G_PANEL_ITEM(item), type);
     g_object_unref(item);
 
-    return (PyObject *)result;
+    return result;
 
 }
 
@@ -102,6 +102,7 @@ PyObject *_py_panel_item_from_c(GPanelItem *item, PyTypeObject *type)
         type = (PyTypeObject *)PyObject_GetAttrString(module, "PanelItem");
         Py_DECREF(module);
     }
+    else Py_INCREF(type);
 
     pychrysalide_set_instance_data(G_OBJECT(item), type);
 
diff --git a/plugins/pychrysa/plugin.c b/plugins/pychrysa/plugin.c
index 1bda007..c562044 100644
--- a/plugins/pychrysa/plugin.c
+++ b/plugins/pychrysa/plugin.c
@@ -132,7 +132,7 @@ static PyObject *pychrysa_plugin_handle_debugger(PyObject *, PyObject *);
 
 
 
-
+#if 0
 
 
 
@@ -155,19 +155,7 @@ main2(const char *filename, const char *method)
 
         if (pFunc && PyCallable_Check(pFunc)) {
             pArgs = PyTuple_New(0/*argc - 3*/);
-#if 0
-            for (i = 0; i < argc - 3; ++i) {
-                pValue = PyLong_FromLong(atoi(argv[i + 3]));
-                if (!pValue) {
-                    Py_DECREF(pArgs);
-                    Py_DECREF(pModule);
-                    fprintf(stderr, "Cannot convert argument\n");
-                    return 1;
-                }
-                /* pValue reference stolen here: */
-                PyTuple_SetItem(pArgs, i, pValue);
-            }
-#endif
+
             pValue = PyObject_CallObject(pFunc, pArgs);
             Py_DECREF(pArgs);
             if (pValue != NULL) {
@@ -199,7 +187,7 @@ main2(const char *filename, const char *method)
 }
 
 
-
+#endif
 
 
 
@@ -540,7 +528,7 @@ static bool g_python_plugin_execute_on_binary(GPythonPlugin *plugin, GLoadedBina
 
     args = PyTuple_New(2);
 
-    PyTuple_SetItem(args, 0, py_loaded_binary_from_c(binary));
+    PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(binary)));
     PyTuple_SetItem(args, 1, PyInt_FromLong(action));
 
     value = run_python_method(plugin->instance, "execute_on_binary", args);
@@ -752,7 +740,9 @@ static PyObject *pychrysa_plugin_is_matching(PyObject *self, PyObject *args)
     result = PyTuple_New(3);
 
     PyTuple_SetItem(result, 0, PyInt_FromLong(MFA_NONE));
+    Py_DECREF(Py_None);
     PyTuple_SetItem(result, 1, Py_None);
+    Py_DECREF(Py_None);
     PyTuple_SetItem(result, 2, Py_None);
 
     return result;
@@ -797,52 +787,12 @@ static PyObject *pychrysa_plugin_handle_debugger(PyObject *self, PyObject *args)
 
 static PyObject *pychrysa_plugin_run(PyObject *self, PyObject *args)
 {
-    return Py_None;
-
-}
-
-
-
-
-
-#include <pygtk-2.0/pygobject.h>
-
-static int convert_to_w(PyGObject *obj, void **out)
-{
-
-    //if (!pygobject_check(obj, 
-
-    *out = pygobject_get(obj);
-
-    return (1);
+    Py_RETURN_NONE;
 
 }
 
 
-static PyObject *add_wgt(PyObject *self, PyObject *args)
-{
-    GtkWidget *result;
-    GtkWidget *button;
-
 
-    result = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-    gtk_widget_set_size_request(result, 400, 300);
-    gtk_window_set_position(GTK_WINDOW(result), GTK_WIN_POS_CENTER);
-    gtk_container_set_border_width(GTK_CONTAINER(result), 4);
-    gtk_window_set_title(GTK_WINDOW(result), _("ChrysalideWWW"));
-
-    gtk_widget_show (result);
-
-
-    if (!PyArg_ParseTuple(args, "O&", convert_to_w, &button))
-        return Py_None;
-
-    gtk_container_add(GTK_CONTAINER(result), button);
-
-
-    return Py_None;
-
-}
 
 
 
@@ -893,11 +843,6 @@ static PyMethodDef pychrysa_plugin_methods[] = {
         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 0e8446d..94cd51e 100644
--- a/plugins/pychrysa/pychrysa.c
+++ b/plugins/pychrysa/pychrysa.c
@@ -129,6 +129,9 @@ bool init_plugin(GPluginModule *plugin, GObject *ref)
 
     Py_Initialize();
 
+    //pychrysalide_set_gc_threshold(10000, 10000, 10000);
+    pychrysalide_set_gc_threshold(INT_MAX, INT_MAX, INT_MAX);
+
     initpychrysa();
 
 
@@ -199,7 +202,8 @@ bool init_plugin(GPluginModule *plugin, GObject *ref)
 
 void exit_plugin(GPluginModule *plugin)
 {
-    Py_Finalize();
+    /* FIXME */
+    //Py_Finalize();
 
 }
 
@@ -290,7 +294,7 @@ PyMODINIT_FUNC initpychrysa(void)
     add_gtkext_module_to_python_module(module);
     add_gui_module_to_python_module(module);
 
-    add_log_to_python_module(module);
+    //add_log_to_python_module(module);
     add_plugin_to_python_module(module);
 
 }
diff --git a/plugins/pychrysa/quirks.c b/plugins/pychrysa/quirks.c
index 68f0a2e..2813fb2 100644
--- a/plugins/pychrysa/quirks.c
+++ b/plugins/pychrysa/quirks.c
@@ -30,6 +30,8 @@
 #include <pygobject.h>
 
 
+#include "helpers.h"
+
 
 
 
@@ -56,6 +58,7 @@ static void pygobject_data_free_fake(PyGObjectData_fake *data)
 {
     PyGILState_STATE state;                 /* Etat interne de Python      */
     GSList *iter;                           /* Boucle de parcours          */
+    GSList *old;                            /* Sauvegarde avant libération */
 
     //state = pyglib_gil_state_ensure();
 
@@ -69,9 +72,10 @@ static void pygobject_data_free_fake(PyGObjectData_fake *data)
          * On obtient le lien avant la libération via
          * pygobject_unwatch_closure()...
          */
+        old = iter;
         iter = iter->next;
 
-        g_closure_invalidate((GClosure *)iter->data);
+        g_closure_invalidate((GClosure *)old->data);
 
     }
 
@@ -122,6 +126,47 @@ void pychrysalide_init_quirks(void)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : threshold0 = seuil pour la collecte de niveau 0.             *
+*                threshold1 = seuil pour la collecte de niveau 1.             *
+*                threshold2 = seuil pour la collecte de niveau 2.             *
+*                                                                             *
+*  Description : Modifie les seuils de collecte pour le collecteur de Python. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void pychrysalide_set_gc_threshold(int threshold0, int threshold1, int threshold2)
+{
+    PyObject *module;                       /* Module Python "gc"          */
+    PyObject *args;                         /* Arguments pour l'appel      */
+    PyObject *value;                        /* Valeurs obtenues            */
+
+    module = PyImport_ImportModule("gc");
+
+    if (threshold0 == 0 && threshold1 == 0 && threshold2 == 0)
+    {
+        args = Py_BuildValue("()");
+        value = run_python_method(module, "disable", args);
+    }
+    else
+    {
+        args = Py_BuildValue("(iii)", threshold0, threshold1, threshold2);
+        value = run_python_method(module, "set_threshold", args);
+    }
+
+    Py_DECREF(value);
+    Py_DECREF(args);
+
+    Py_DECREF(module);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : obj  = instance GLib crée en C.                              *
 *                type = type de l'objet Python correspond.                    *
 *                                                                             *
@@ -139,17 +184,28 @@ void pychrysalide_set_instance_data(GObject *obj, PyTypeObject *type)
 
     data = g_object_get_qdata(obj, pygobject_instance_data_key_fake);
 
+    Py_INCREF(type);
+
     if (data == NULL)
     {
         data = pygobject_data_new_fake();
 
+        /**
+         * Dans la majorité des cas, le type est retrouvé depuis un appel à
+         * PyObject_GetAttrString(), qui fournit une nouvelle référence.
+         * Donc nul besoin d'incrémenter encore cette référence.
+         */
         data->type = type;
-        Py_INCREF(type);
 
         g_object_set_qdata_full(obj, pygobject_instance_data_key_fake,
                                 data, (GDestroyNotify)pygobject_data_free_fake);
 
     }
+    /**
+     * On décharge l'usage du type : le compteur est déjà bien à jour si
+     * le (futur) objet est en mémoire.
+     */
+    else Py_DECREF(type);
 
 }
 
diff --git a/plugins/pychrysa/quirks.h b/plugins/pychrysa/quirks.h
index ca198f3..991fe10 100644
--- a/plugins/pychrysa/quirks.h
+++ b/plugins/pychrysa/quirks.h
@@ -34,6 +34,9 @@
 /* Définit les éléments immuables pour toute association. */
 void pychrysalide_init_quirks(void);
 
+/* Modifie les seuils de collecte pour le collecteur de Python. */
+void pychrysalide_set_gc_threshold(int, int, int);
+
 /* Crée l'association précise attendue par Python-GObject. */
 void pychrysalide_set_instance_data(GObject *, PyTypeObject *);
 
diff --git a/plugins/python/androperms/androperms.py b/plugins/python/androperms/androperms.py
index 18443fc..ddccb8a 100644
--- a/plugins/python/androperms/androperms.py
+++ b/plugins/python/androperms/androperms.py
@@ -56,8 +56,9 @@ class AndroPerms(Plugin):
         db = PermsDataBase()
         db.filter_permissions(plist)
 
+        fmt = binary.get_format()
         instrs = binary.get_instructions()
-        buffer = binary.disassembled_buffer
+        buf = binary.disassembled_buffer
 
         pfn = re.compile('<.* ([^ ]*)\(')
 
@@ -65,15 +66,20 @@ class AndroPerms(Plugin):
 
             if i.keyword.startswith("invoke"):
 
-                line = buffer.find_line_by_addr(i.address)
+                line = buf.find_line_by_addr(i.address)
                 text = line.get_text()
 
-                #print "check %s" % text
-
                 name = pfn.search(text)
 
                 if name != None:
-                    #print " --> ", name.group(1)
-                    db.check_call(i.address, name.group(1))
+
+                    resolved = fmt.resolve_relative_routine(i.address)
+
+                    if resolved == None:
+                        reladdr = "0x%08x" % i.address
+                    else:
+                        reladdr = "<%s()+0x%x>" % (resolved[0], resolved[1])
+
+                    db.check_call(i.address, name.group(1), reladdr)
 
         self._panel.memorize_permissions(binary, db.get_used_permissions())
diff --git a/plugins/python/androperms/db.py b/plugins/python/androperms/db.py
index 625d400..7014915 100644
--- a/plugins/python/androperms/db.py
+++ b/plugins/python/androperms/db.py
@@ -53,7 +53,7 @@ class PermsDataBase:
             self._used[p] = []
 
 
-    def check_call(self, addr, line):
+    def check_call(self, addr, line, reladdr):
         """Check if a call requires some rights."""
 
         found = False
@@ -69,23 +69,23 @@ class PermsDataBase:
 
                 #if line.find(c) > -1:
                 if c.find(line) > -1:
-                    self._used[p].append([addr, c + "()"])
-                    #found = True
+                    self._used[p].append([reladdr, c + "()", addr])
+                    found = True
 
-        if not found:
+        # if not found:
 
-            func = line.split('.')[-1]
+        #     func = line.split('.')[-1]
 
-            for p in self._perms:
+        #     for p in self._perms:
 
-                for c in self._perms[p]:
+        #         for c in self._perms[p]:
 
-                    if line.find("Wall") > -1:
-                        print " <> ", c, " vs ", func
+        #             if c.find(func) > -1:
 
-                    if c.find(func) > -1:
-                        self._used[p].append([addr, line + "()"])
-                        break
+        #                 #print ">>> %s found in %s" % (func, c)
+
+        #                 self._used[p].append([reladdr, line + "()", addr])
+        #                 break
 
 
     def get_used_permissions(self):
diff --git a/plugins/python/androperms/panel.py b/plugins/python/androperms/panel.py
index bebeed5..b892339 100644
--- a/plugins/python/androperms/panel.py
+++ b/plugins/python/androperms/panel.py
@@ -41,7 +41,7 @@ def _build_permissions_panel_content():
     functions.pack_start(cell, True)
     functions.add_attribute(cell, 'text', 3)
 
-    store = gtk.TreeStore(gtk.gdk.Pixbuf, str, gtk.gdk.Pixbuf, str)
+    store = gtk.TreeStore(gtk.gdk.Pixbuf, str, gtk.gdk.Pixbuf, str, str)
     tree.set_model(store)
 
     return scrolled_window, tree, store
@@ -97,13 +97,13 @@ class PermsPanel(PanelItem):
                 img = os.path.dirname(os.path.abspath(__file__)) + '/android.png'
                 buf = gtk.gdk.pixbuf_new_from_file(img)
 
-                it = self._store.append(None, [buf, p, None, None])
+                it = self._store.append(None, [buf, p, None, None, None])
 
                 img = os.path.dirname(os.path.abspath(__file__)) + '/routine.png'
                 buf = gtk.gdk.pixbuf_new_from_file(img)
 
                 for f in used[p]:
-                    self._store.append(it, [None, "0x%08x" % f[0], buf, f[1]])
+                    self._store.append(it, [None, f[0], buf, f[1], f[2]])
 
         self._tree.expand_all()
 
@@ -117,4 +117,4 @@ class PermsPanel(PanelItem):
         # 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))
+            self.get_current_view().scroll_to_address(int(model.get_value(it, 4)))
diff --git a/src/analysis/routine.c b/src/analysis/routine.c
index 7a191c9..d52b74a 100644
--- a/src/analysis/routine.c
+++ b/src/analysis/routine.c
@@ -48,6 +48,7 @@ struct _GBinRoutine
     GDataType *namespace;                   /* Espace de noms / classe     */
     char *name;                             /* Désignation humaine         */
     GDataType *full_name;                   /* Désignation très complète   */
+    char *long_name;                        /* Désignation très complète ??*/
 
     GBinVariable **args;                    /* Arguments de la routines    */
     size_t args_count;                      /* Nombre d'arguments          */
@@ -421,7 +422,7 @@ void g_binary_routine_set_name(GBinRoutine *routine, char *name)
 *                                                                             *
 ******************************************************************************/
 
-const char *g_binary_routine_get_name(const GBinRoutine *routine)
+const char *g_binary_routine_get_name(GBinRoutine *routine)
 {
     if (routine->name == NULL && routine->full_name != NULL)
         g_binary_routine_set_name(routine, g_data_type_to_string(routine->full_name));
@@ -434,6 +435,40 @@ const char *g_binary_routine_get_name(const GBinRoutine *routine)
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : routine = routine à mettre à jour.                           *
+*                                                                             *
+*  Description : Fournit le nom long et humain d'une routine.                 *
+*                                                                             *
+*  Retour      : Désignation humainement lisible ou NULL si non définie.      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+const char *g_binary_routine_get_long_name(GBinRoutine *routine)
+{
+    if (routine->long_name == NULL)
+    {
+        if (routine->namespace != NULL)
+        {
+            routine->long_name = strdup("");
+            routine->long_name = g_data_type_to_string(routine->namespace);
+            routine->long_name = stradd(routine->long_name, "." /* FIXME */);
+        }
+        else
+            routine->long_name = strdup("");
+
+        routine->long_name = stradd(routine->long_name, g_binary_routine_get_name(routine));
+
+    }
+
+    return routine->long_name;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : routine = routine à mettre à jour.                           *
 *                type    = désignation complète du nom de la routine.         *
 *                                                                             *
 *  Description : Définit de façon indirecte le nom humain d'une routine.      *
diff --git a/src/analysis/routine.h b/src/analysis/routine.h
index de28f38..c6de039 100644
--- a/src/analysis/routine.h
+++ b/src/analysis/routine.h
@@ -111,7 +111,10 @@ GDataType *g_binary_routine_get_namespace(const GBinRoutine *);
 void g_binary_routine_set_name(GBinRoutine *, char *);
 
 /* Désignation humainement lisible ou NULL si non définie. */
-const char *g_binary_routine_get_name(const GBinRoutine *);
+const char *g_binary_routine_get_name(GBinRoutine *);
+
+/* Fournit le nom long et humain d'une routine. */
+const char *g_binary_routine_get_long_name(GBinRoutine *);
 
 /* Définit de façon indirecte le nom humain d'une routine. */
 void g_binary_routine_set_name_from_type(GBinRoutine *, GDataType *);
diff --git a/src/format/format.c b/src/format/format.c
index c7d95c4..79ef5dd 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -454,6 +454,50 @@ bool g_binary_format_resolve_symbol(const GBinFormat *format, const char **label
 }
 
 
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : format  = informations chargées à consulter.                 *
+*                label   = étiquette du symbole si trouvé. [OUT]              *
+*                address = adresse à cibler, puis décallage final. [OUT]      *
+*                                                                             *
+*  Description : Recherche une position dans une routine selon une adresse.   *
+*                                                                             *
+*  Retour      : true si l'opération a été un succès, false sinon.            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_format_resolve_relative_routine(const GBinFormat *format, const char **label, vmpa_t *address)
+{
+    bool result;                            /* Bilan à retourner           */
+    size_t i;                               /* Boucle de parcours          */
+    vmpa_t addr;                            /* Adresse de symbole          */
+    off_t size;                             /* Taille du symole            */
+
+    result = false;
+
+    for (i = 0; i < format->routines_count && !result; i++)
+    {
+        addr = g_binary_routine_get_address(format->routines[i]);
+        size = g_binary_routine_get_size(format->routines[i]);
+
+        if (addr <= *address && *address < (addr + size))
+        {
+            *label = g_binary_routine_get_long_name(format->routines[i]);
+            *address -= addr;
+
+            result = true;
+
+        }
+
+    }
+
+    return result;
+
+}
+
+
 
 /* ---------------------------------------------------------------------------------- */
 /*                         MANIPULATION D'ENSEMBLE DE FORMATS                         */
diff --git a/src/format/format.h b/src/format/format.h
index ef85fbb..fec03ea 100644
--- a/src/format/format.h
+++ b/src/format/format.h
@@ -84,6 +84,9 @@ void g_binary_format_decompile(const GBinFormat *, GCodeBuffer *, const char *fi
 /* Recherche le symbole correspondant à une adresse. */
 bool g_binary_format_resolve_symbol(const GBinFormat *, const char **, SymbolType *, vmpa_t *);
 
+/* Recherche une position dans une routine selon une adresse. */
+bool g_binary_format_resolve_relative_routine(const GBinFormat *, const char **, vmpa_t *);
+
 
 
 /* ----------------------- MANIPULATION D'ENSEMBLE DE FORMATS ----------------------- */
-- 
cgit v0.11.2-87-g4458