From de82c8165e61e3c19be184dbc00f66bfc7479c76 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Tue, 14 Jul 2020 13:01:17 +0200
Subject: Updated the code handling binary contents.

---
 plugins/pychrysalide/analysis/binary.c  |  37 --
 plugins/pychrysalide/analysis/content.c | 687 +++++++++++++++++++++++++++++++-
 plugins/ropgadgets/select.c             |  12 +-
 src/analysis/binary.c                   |  29 --
 src/analysis/binary.h                   |   3 -
 src/analysis/content-int.h              |   2 +-
 src/analysis/content.c                  |  44 +-
 src/analysis/content.h                  |   2 +-
 src/analysis/contents/encapsulated.c    |  12 +-
 src/analysis/contents/file.c            |  17 +-
 src/analysis/contents/memory.c          |   8 +-
 src/analysis/disass/disassembler.c      |   4 +-
 src/gui/dialogs/export_disass.c         |   6 +-
 src/gui/panels/bintree.c                |   7 +-
 14 files changed, 745 insertions(+), 125 deletions(-)

diff --git a/plugins/pychrysalide/analysis/binary.c b/plugins/pychrysalide/analysis/binary.c
index acc3ae5..2f8af5f 100644
--- a/plugins/pychrysalide/analysis/binary.c
+++ b/plugins/pychrysalide/analysis/binary.c
@@ -58,9 +58,6 @@ static PyObject *py_loaded_binary_add_to_collection(PyObject *, PyObject *);
 /* Active les éléments en amont d'un horodatage donné. */
 static PyObject *py_loaded_binary_set_last_active(PyObject *, PyObject *);
 
-/* Fournit le nom associé à l'élément binaire. */
-static PyObject *py_loaded_binary_get_name(PyObject *, void *);
-
 /* Fournit l'ensemble des collections utilisées par un binaire. */
 static PyObject *py_loaded_binary_get_collections(PyObject *, void *);
 
@@ -322,36 +319,6 @@ static PyObject *py_loaded_binary_set_last_active(PyObject *self, PyObject *args
 *  Paramètres  : self    = objet Python concerné par l'appel.                 *
 *                closure = non utilisé ici.                                   *
 *                                                                             *
-*  Description : Fournit le nom associé à l'élément binaire.                  *
-*                                                                             *
-*  Retour      : Nom de fichier avec chemin absolu.                           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static PyObject *py_loaded_binary_get_name(PyObject *self, void *closure)
-{
-    PyObject *result;                       /* Trouvailles à retourner     */
-    GLoadedBinary *binary;                  /* Version native              */
-    const char *name;                       /* Désignation du binaire      */
-
-    binary = G_LOADED_BINARY(pygobject_get(self));
-
-    name = g_loaded_binary_get_name(binary, true);
-
-    result = PyUnicode_FromString(name);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : self    = objet Python concerné par l'appel.                 *
-*                closure = non utilisé ici.                                   *
-*                                                                             *
 *  Description : Fournit l'ensemble des collections utilisées par un binaire. *
 *                                                                             *
 *  Retour      : Liste de collections en place.                               *
@@ -536,10 +503,6 @@ PyTypeObject *get_python_loaded_binary_type(void)
     };
 
     static PyGetSetDef py_loaded_binary_getseters[] = {
-        {
-            "name", py_loaded_binary_get_name, NULL,
-            "Name of the loaded binary.", NULL
-        },
         LOADED_BINARY_COLLECTIONS_ATTRIB,
         {
             "format", py_loaded_binary_get_format, NULL,
diff --git a/plugins/pychrysalide/analysis/content.c b/plugins/pychrysalide/analysis/content.c
index 8a404ed..5b5608c 100644
--- a/plugins/pychrysalide/analysis/content.c
+++ b/plugins/pychrysalide/analysis/content.c
@@ -26,13 +26,15 @@
 
 
 #include <assert.h>
+#include <malloc.h>
 #include <pygobject.h>
+#include <string.h>
 
 
 #include <i18n.h>
 
 
-#include <analysis/content.h>
+#include <analysis/content-int.h>
 #include <common/endianness.h>
 
 
@@ -44,15 +46,34 @@
 
 
 
-#define BINARY_CONTENT_DOC                                              \
-    "The BinContent is an interface which handles access to a given"    \
-    " binary content."                                                  \
-    "\n"                                                                \
-    "All of its implementations are located in the"                     \
-    " pychrysalide.analysis.contents module. The main implemantation"   \
-    " is the pychrysalide.analysis.contents.FileContent class."
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
 
 
+/* Procède à l'initialisation de l'interface de génération. */
+static void py_binary_content_interface_init(GBinContentIface *, gpointer *);
+
+/* Fournit le nom associé au contenu binaire. */
+static char *py_binary_content_describe_wrapper(const GBinContent *, bool);
+
+/* Fournit une portion des données représentées. */
+static bool py_binary_content_read_raw_wrapper(const GBinContent *, vmpa2t *, phys_t, bin_t *);;
+
+/* Lit un nombre non signé sur un octet. */
+static bool py_binary_content_read_u8_wrapper(const GBinContent *, vmpa2t *, uint8_t *);
+
+/* Lit un nombre non signé sur deux octets. */
+static bool py_binary_content_read_u16_wrapper(const GBinContent *, vmpa2t *, SourceEndian, uint16_t *);
+
+/* Lit un nombre non signé sur quatre octets. */
+static bool py_binary_content_read_u32_wrapper(const GBinContent *, vmpa2t *, SourceEndian, uint32_t *);
+
+/* Lit un nombre non signé sur huit octets. */
+static bool py_binary_content_read_u64_wrapper(const GBinContent *, vmpa2t *, SourceEndian, uint64_t *);
+
+
+
+/* ------------------------- CONNEXION AVEC L'API DE PYTHON ------------------------- */
+
 
 /* Fournit le nom associé au contenu binaire. */
 static PyObject *py_binary_content_describe(PyObject *, PyObject *);
@@ -95,6 +116,608 @@ static PyObject *py_binary_content_get_data(PyObject *, void *);
 
 
 
+/* ---------------------------------------------------------------------------------- */
+/*                          GLUE POUR CREATION DEPUIS PYTHON                          */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iface  = interface GLib à initialiser.                       *
+*                unused = adresse non utilisée ici.                           *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de génération.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void py_binary_content_interface_init(GBinContentIface *iface, gpointer *unused)
+{
+#define BINARY_CONTENT_DOC                                                  \
+    "The BinContent is an interface which handles access to a given binary" \
+    " content.\n"                                                           \
+    "\n"                                                                    \
+    "All of its implementations are located in the"                         \
+    " pychrysalide.analysis.contents module. The main implemantation is"    \
+    " the pychrysalide.analysis.contents.FileContent class.\n"              \
+    "\n"                                                                    \
+    "A typical class declaration for a new implementation looks like:\n"    \
+    "\n"                                                                    \
+    "    class NewImplem(GObject.Object, BinContent):\n"                    \
+    "        ...\n"                                                         \
+    "\n"                                                                    \
+    "The following methods have to be defined for new implementations:\n"   \
+    "* pychrysalide.analysis.BinContent._describe();\n"       \
+    "* pychrysalide.analysis.BinContent._read_raw();\n"       \
+    "* pychrysalide.analysis.BinContent._read_u4();\n"       \
+    "* pychrysalide.analysis.BinContent._read_u8();\n"       \
+    "* pychrysalide.analysis.BinContent._read_u16();\n"       \
+    "* pychrysalide.analysis.BinContent._read_u32();\n"       \
+    "* pychrysalide.analysis.BinContent._read_u64();\n"
+
+    iface->describe = py_binary_content_describe_wrapper;
+
+    iface->read_raw = py_binary_content_read_raw_wrapper;
+    iface->read_u8 = py_binary_content_read_u8_wrapper;
+    iface->read_u16 = py_binary_content_read_u16_wrapper;
+    iface->read_u32 = py_binary_content_read_u32_wrapper;
+    iface->read_u64 = py_binary_content_read_u64_wrapper;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = élément chargé à consulter.                        *
+*                full    = précise s'il s'agit d'une version longue ou non.   *
+*                                                                             *
+*  Description : Fournit le nom associé au contenu binaire.                   *
+*                                                                             *
+*  Retour      : Nom de fichier avec chemin absolu au besoin.                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *py_binary_content_describe_wrapper(const GBinContent *content, bool full)
+{
+    char *result;                           /* Description à retourner     */
+    PyGILState_STATE gstate;                /* Sauvegarde d'environnement  */
+    PyObject *full_obj;                     /* Précision sur la longueur   */
+    PyObject *args;                         /* Arguments pour l'appel      */
+    PyObject *pyobj;                        /* Objet Python concerné       */
+    PyObject *pyret;                        /* Bilan de consultation       */
+    int ret;                                /* Validité d'une conversion   */
+
+#define BINARY_CONTENT_DESCRIBE_WRAPPER PYTHON_WRAPPER_DEF      \
+(                                                               \
+    _describe, "$self, full",                                   \
+    METH_VARARGS,                                               \
+    "Abstract method used to build a (full ?) description of"   \
+    " the binary content.describe the loaded content.\n"        \
+    "\n"                                                        \
+    "The description is returned as a string."                  \
+)
+
+    result = NULL;
+
+    gstate = PyGILState_Ensure();
+
+    pyobj = pygobject_new(G_OBJECT(content));
+
+    if (has_python_method(pyobj, "_describe"))
+    {
+        full_obj = full ? Py_True : Py_False;
+        Py_INCREF(full_obj);
+
+        args = PyTuple_New(1);
+        PyTuple_SetItem(args, 0, full_obj);
+
+        pyret = run_python_method(pyobj, "_describe", args);
+
+        if (pyret != NULL)
+        {
+            ret = PyUnicode_Check(pyret);
+
+            if (ret)
+                result = strdup(PyUnicode_AsUTF8(pyret));
+
+            Py_DECREF(pyret);
+
+        }
+
+        Py_DECREF(args);
+
+    }
+
+    Py_DECREF(pyobj);
+
+    PyGILState_Release(gstate);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = contenu binaire à venir lire.                      *
+*                addr    = position de la tête de lecture.                    *
+*                length  = quantité d'octets à lire.                          *
+*                out     = réceptacle disponible pour ces données. [OUT]      *
+*                                                                             *
+*  Description : Fournit une portion des données représentées.                *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool py_binary_content_read_raw_wrapper(const GBinContent *content, vmpa2t *addr, phys_t length, bin_t *out)
+{
+    bool result;                            /* Bilan à remonter            */
+    PyGILState_STATE gstate;                /* Sauvegarde d'environnement  */
+    PyObject *addr_obj;                     /* Position en version Python  */
+    PyObject *args;                         /* Arguments pour l'appel      */
+    PyObject *pyobj;                        /* Objet Python concerné       */
+    PyObject *pyret;                        /* Bilan de consultation       */
+    int ret;                                /* Validité d'une conversion   */
+    const char *data;                       /* Données brutes à copier     */
+
+#define BINARY_CONTENT_READ_RAW_WRAPPER PYTHON_WRAPPER_DEF      \
+(                                                               \
+    _read_raw, "$self, addr, length",                                   \
+    METH_VARARGS,                                               \
+    "Abstract method used to provide the bytes read from a given position.\n"   \
+    "\n"                                                        \
+    "The description is returned as a string."                  \
+)
+
+    result = false;
+
+    gstate = PyGILState_Ensure();
+
+    pyobj = pygobject_new(G_OBJECT(content));
+
+    if (has_python_method(pyobj, "_read_raw"))
+    {
+        addr_obj = build_from_internal_vmpa(addr);
+
+        args = PyTuple_New(2);
+        PyTuple_SetItem(args, 0, addr_obj);
+        PyTuple_SetItem(args, 1, PyLong_FromUnsignedLongLong(length));
+
+        pyret = run_python_method(pyobj, "_read_raw", args);
+
+        if (pyret != NULL)
+        {
+            ret = PyUnicode_Check(pyret);
+
+            if (ret)
+            {
+                assert((phys_t)PyBytes_Size(pyret) == length);
+
+                if ((phys_t)PyBytes_Size(pyret) == length)
+                {
+                    /* Avancement de la tête de lecture */
+
+                    copy_vmpa(addr, get_internal_vmpa(addr_obj));
+
+                    /* Récupération des données */
+
+                    data = PyBytes_AsString(pyret);
+
+                    memcpy(out, data, length);
+
+                    /* Bilan à retenir */
+
+                    result = true;
+
+                }
+
+            }
+
+            Py_DECREF(pyret);
+
+        }
+
+        Py_DECREF(args);
+
+    }
+
+    Py_DECREF(pyobj);
+
+    PyGILState_Release(gstate);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = contenu binaire à venir lire.                      *
+*                addr    = position de la tête de lecture.                    *
+*                val     = lieu d'enregistrement de la lecture. [OUT]         *
+*                                                                             *
+*  Description : Lit un nombre non signé sur un octet.                        *
+*                                                                             *
+*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool py_binary_content_read_u8_wrapper(const GBinContent *content, vmpa2t *addr, uint8_t *val)
+{
+    bool result;                            /* Bilan à remonter            */
+    PyGILState_STATE gstate;                /* Sauvegarde d'environnement  */
+    PyObject *addr_obj;                     /* Position en version Python  */
+    PyObject *args;                         /* Arguments pour l'appel      */
+    PyObject *pyobj;                        /* Objet Python concerné       */
+    PyObject *pyret;                        /* Bilan de consultation       */
+    int ret;                                /* Validité d'une conversion   */
+
+#define BINARY_CONTENT_READ_U8_WRAPPER PYTHON_WRAPPER_DEF               \
+(                                                                       \
+    _read_u8, "$self, addr",                                            \
+    METH_VARARGS,                                                       \
+    "Abstract method used to read an unsigned bytes from a given"       \
+    " position.\n"                                                      \
+    "\n"                                                                \
+    "The location of the data to read is a pychrysalide.arch.vmpa"      \
+    " instance.\n"                                                      \
+    "\n"                                                                \
+    "The returned value is the read data or None is case of error."     \
+)
+
+    result = false;
+
+    gstate = PyGILState_Ensure();
+
+    pyobj = pygobject_new(G_OBJECT(content));
+
+    if (has_python_method(pyobj, "_read_u8"))
+    {
+        addr_obj = build_from_internal_vmpa(addr);
+
+        args = PyTuple_New(1);
+        PyTuple_SetItem(args, 0, addr_obj);
+
+        pyret = run_python_method(pyobj, "_read_u8", args);
+
+        if (pyret != NULL)
+        {
+            ret = PyLong_Check(pyret);
+
+            if (ret)
+            {
+                /* Avancement de la tête de lecture */
+
+                copy_vmpa(addr, get_internal_vmpa(addr_obj));
+
+                /* Récupération des données */
+
+                *val = PyLong_AsUnsignedLong(pyret);
+
+                /* Bilan à retenir */
+
+                result = true;
+
+            }
+
+            Py_DECREF(pyret);
+
+        }
+
+        Py_DECREF(args);
+
+    }
+
+    Py_DECREF(pyobj);
+
+    PyGILState_Release(gstate);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = contenu binaire à venir lire.                      *
+*                addr    = position de la tête de lecture.                    *
+*                endian  = ordre des bits dans la source.                     *
+*                val     = lieu d'enregistrement de la lecture. [OUT]         *
+*                                                                             *
+*  Description : Lit un nombre non signé sur deux octets.                     *
+*                                                                             *
+*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool py_binary_content_read_u16_wrapper(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint16_t *val)
+{
+    bool result;                            /* Bilan à remonter            */
+    PyGILState_STATE gstate;                /* Sauvegarde d'environnement  */
+    PyObject *addr_obj;                     /* Position en version Python  */
+    PyObject *endianness_obj;               /* Boutisme en version Python  */
+    PyObject *args;                         /* Arguments pour l'appel      */
+    PyObject *pyobj;                        /* Objet Python concerné       */
+    PyObject *pyret;                        /* Bilan de consultation       */
+    int ret;                                /* Validité d'une conversion   */
+
+#define BINARY_CONTENT_READ_U16_WRAPPER PYTHON_WRAPPER_DEF              \
+(                                                                       \
+    _read_u16, "$self, addr, endian",                                   \
+    METH_VARARGS,                                                       \
+    "Abstract method used to read two unsigned bytes from a given"      \
+    " position.\n"                                                      \
+    "\n"                                                                \
+    "The location of the data to read is a pychrysalide.arch.vmpa"      \
+    " instance. The endianness of the data can be provided using"       \
+    " pychrysalide.analysis.BinContent.SourceEndian values.\n"          \
+    "\n"                                                                \
+    "The returned value is the read data or None is case of error."     \
+)
+
+    result = false;
+
+    gstate = PyGILState_Ensure();
+
+    pyobj = pygobject_new(G_OBJECT(content));
+
+    if (has_python_method(pyobj, "_read_u16"))
+    {
+        addr_obj = build_from_internal_vmpa(addr);
+        endianness_obj = cast_with_constants_group_from_type(get_python_binary_content_type(),
+                                                             "SourceEndian", endian);
+
+        args = PyTuple_New(2);
+        PyTuple_SetItem(args, 0, addr_obj);
+        PyTuple_SetItem(args, 1, endianness_obj);
+
+        pyret = run_python_method(pyobj, "_read_u16", args);
+
+        if (pyret != NULL)
+        {
+            ret = PyLong_Check(pyret);
+
+            if (ret)
+            {
+                /* Avancement de la tête de lecture */
+
+                copy_vmpa(addr, get_internal_vmpa(addr_obj));
+
+                /* Récupération des données */
+
+                *val = PyLong_AsUnsignedLong(pyret);
+
+                /* Bilan à retenir */
+
+                result = true;
+
+            }
+
+            Py_DECREF(pyret);
+
+        }
+
+        Py_DECREF(args);
+
+    }
+
+    Py_DECREF(pyobj);
+
+    PyGILState_Release(gstate);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = contenu binaire à venir lire.                      *
+*                addr    = position de la tête de lecture.                    *
+*                endian  = ordre des bits dans la source.                     *
+*                val     = lieu d'enregistrement de la lecture. [OUT]         *
+*                                                                             *
+*  Description : Lit un nombre non signé sur quatre octets.                   *
+*                                                                             *
+*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool py_binary_content_read_u32_wrapper(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint32_t *val)
+{
+    bool result;                            /* Bilan à remonter            */
+    PyGILState_STATE gstate;                /* Sauvegarde d'environnement  */
+    PyObject *addr_obj;                     /* Position en version Python  */
+    PyObject *endianness_obj;               /* Boutisme en version Python  */
+    PyObject *args;                         /* Arguments pour l'appel      */
+    PyObject *pyobj;                        /* Objet Python concerné       */
+    PyObject *pyret;                        /* Bilan de consultation       */
+    int ret;                                /* Validité d'une conversion   */
+
+#define BINARY_CONTENT_READ_U32_WRAPPER PYTHON_WRAPPER_DEF              \
+(                                                                       \
+    _read_u32, "$self, addr, endian",                                   \
+    METH_VARARGS,                                                       \
+    "Abstract method used to read four unsigned bytes from a given"     \
+    " position.\n"                                                      \
+    "\n"                                                                \
+    "The location of the data to read is a pychrysalide.arch.vmpa"      \
+    " instance. The endianness of the data can be provided using"       \
+    " pychrysalide.analysis.BinContent.SourceEndian values.\n"          \
+    "\n"                                                                \
+    "The returned value is the read data or None is case of error."     \
+)
+
+    result = false;
+
+    gstate = PyGILState_Ensure();
+
+    pyobj = pygobject_new(G_OBJECT(content));
+
+    if (has_python_method(pyobj, "_read_u32"))
+    {
+        addr_obj = build_from_internal_vmpa(addr);
+        endianness_obj = cast_with_constants_group_from_type(get_python_binary_content_type(),
+                                                             "SourceEndian", endian);
+
+        args = PyTuple_New(2);
+        PyTuple_SetItem(args, 0, addr_obj);
+        PyTuple_SetItem(args, 1, endianness_obj);
+
+        pyret = run_python_method(pyobj, "_read_u32", args);
+
+        if (pyret != NULL)
+        {
+            ret = PyLong_Check(pyret);
+
+            if (ret)
+            {
+                /* Avancement de la tête de lecture */
+
+                copy_vmpa(addr, get_internal_vmpa(addr_obj));
+
+                /* Récupération des données */
+
+                *val = PyLong_AsUnsignedLong(pyret);
+
+                /* Bilan à retenir */
+
+                result = true;
+
+            }
+
+            Py_DECREF(pyret);
+
+        }
+
+        Py_DECREF(args);
+
+    }
+
+    Py_DECREF(pyobj);
+
+    PyGILState_Release(gstate);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = contenu binaire à venir lire.                      *
+*                addr    = position de la tête de lecture.                    *
+*                endian  = ordre des bits dans la source.                     *
+*                val     = lieu d'enregistrement de la lecture. [OUT]         *
+*                                                                             *
+*  Description : Lit un nombre non signé sur huit octets.                     *
+*                                                                             *
+*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool py_binary_content_read_u64_wrapper(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint64_t *val)
+{
+    bool result;                            /* Bilan à remonter            */
+    PyGILState_STATE gstate;                /* Sauvegarde d'environnement  */
+    PyObject *addr_obj;                     /* Position en version Python  */
+    PyObject *endianness_obj;               /* Boutisme en version Python  */
+    PyObject *args;                         /* Arguments pour l'appel      */
+    PyObject *pyobj;                        /* Objet Python concerné       */
+    PyObject *pyret;                        /* Bilan de consultation       */
+    int ret;                                /* Validité d'une conversion   */
+
+#define BINARY_CONTENT_READ_U64_WRAPPER PYTHON_WRAPPER_DEF              \
+(                                                                       \
+    _read_u64, "$self, addr, endian",                                   \
+    METH_VARARGS,                                                       \
+    "Abstract method used to read eight unsigned bytes from a given"    \
+    " position.\n"                                                      \
+    "\n"                                                                \
+    "The location of the data to read is a pychrysalide.arch.vmpa"      \
+    " instance. The endianness of the data can be provided using"       \
+    " pychrysalide.analysis.BinContent.SourceEndian values.\n"          \
+    "\n"                                                                \
+    "The returned value is the read data or None is case of error."     \
+)
+
+    result = false;
+
+    gstate = PyGILState_Ensure();
+
+    pyobj = pygobject_new(G_OBJECT(content));
+
+    if (has_python_method(pyobj, "_read_u64"))
+    {
+        addr_obj = build_from_internal_vmpa(addr);
+        endianness_obj = cast_with_constants_group_from_type(get_python_binary_content_type(),
+                                                             "SourceEndian", endian);
+
+        args = PyTuple_New(2);
+        PyTuple_SetItem(args, 0, addr_obj);
+        PyTuple_SetItem(args, 1, endianness_obj);
+
+        pyret = run_python_method(pyobj, "_read_u64", args);
+
+        if (pyret != NULL)
+        {
+            ret = PyLong_Check(pyret);
+
+            if (ret)
+            {
+                /* Avancement de la tête de lecture */
+
+                copy_vmpa(addr, get_internal_vmpa(addr_obj));
+
+                /* Récupération des données */
+
+                *val = PyLong_AsUnsignedLongLong(pyret);
+
+                /* Bilan à retenir */
+
+                result = true;
+
+            }
+
+            Py_DECREF(pyret);
+
+        }
+
+        Py_DECREF(args);
+
+    }
+
+    Py_DECREF(pyobj);
+
+    PyGILState_Release(gstate);
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                           CONNEXION AVEC L'API DE PYTHON                           */
+/* ---------------------------------------------------------------------------------- */
+
+
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : self = contenu binaire à manipuler.                          *
@@ -114,7 +737,7 @@ static PyObject *py_binary_content_describe(PyObject *self, PyObject *args)
     int full;                               /* Description complète ?      */
     int ret;                                /* Bilan de lecture des args.  */
     GBinContent *content;                   /* Version GLib du format      */
-    const char *desc;                       /* Description obtenue         */
+    char *desc;                             /* Description obtenue         */
 
 #define BINARY_CONTENT_DESCRIBE_METHOD PYTHON_METHOD_DEF                \
 (                                                                       \
@@ -134,6 +757,8 @@ static PyObject *py_binary_content_describe(PyObject *self, PyObject *args)
 
     result = PyUnicode_FromString(desc);
 
+    free(desc);
+
     return result;
 
 }
@@ -219,6 +844,11 @@ static PyObject *py_binary_content_read_u8(PyObject *self, PyObject *args)
     read_u8, "$self, addr, /",                                          \
     METH_VARARGS, py_binary_content,                                    \
     "Read an unsigned byte from a given position."                      \
+    "\n"                                                                \
+    "The location of the data to read is a pychrysalide.arch.vmpa"      \
+    " instance.\n"                                                      \
+    "\n"                                                                \
+    "The returned value is the read data or None is case of error."     \
 )
 
     ret = PyArg_ParseTuple(args, "O&", convert_any_to_vmpa, &addr);
@@ -274,8 +904,11 @@ static PyObject *py_binary_content_read_u16(PyObject *self, PyObject *args)
     METH_VARARGS, py_binary_content,                                    \
     "Read two unsigned bytes from a given position."                    \
     "\n"                                                                \
-    "The endianness of the data can be provided using"                  \
-    " pychrysalide.analysis.BinContent.SourceEndian values."            \
+    "The location of the data to read is a pychrysalide.arch.vmpa"      \
+    " instance. The endianness of the data can be provided using"       \
+    " pychrysalide.analysis.BinContent.SourceEndian values.\n"          \
+    "\n"                                                                \
+    "The returned value is the read data or None is case of error."     \
 )
 
     ret = PyArg_ParseTuple(args, "O&k", convert_any_to_vmpa, &addr, &endianness);
@@ -331,8 +964,11 @@ static PyObject *py_binary_content_read_u32(PyObject *self, PyObject *args)
     METH_VARARGS, py_binary_content,                                    \
     "Read four unsigned bytes from a given position."                   \
     "\n"                                                                \
-    "The endianness of the data can be provided using"                  \
-    " pychrysalide.analysis.BinContent.SourceEndian values."            \
+    "The location of the data to read is a pychrysalide.arch.vmpa"      \
+    " instance. The endianness of the data can be provided using"       \
+    " pychrysalide.analysis.BinContent.SourceEndian values.\n"          \
+    "\n"                                                                \
+    "The returned value is the read data or None is case of error."     \
 )
 
     ret = PyArg_ParseTuple(args, "O&k", convert_any_to_vmpa, &addr, &endianness);
@@ -385,10 +1021,13 @@ static PyObject *py_binary_content_read_u64(PyObject *self, PyObject *args)
 (                                                                       \
     read_u64, "$self, addr, endian, /",                                 \
     METH_VARARGS, py_binary_content,                                    \
-    "Read eight unsigned bytes from a given position."                  \
+    "Read eight unsigned bytes from a given position.\n"                \
+    "\n"                                                                \
+    "The location of the data to read is a pychrysalide.arch.vmpa"      \
+    " instance. The endianness of the data can be provided using"       \
+    " pychrysalide.analysis.BinContent.SourceEndian values.\n"          \
     "\n"                                                                \
-    "The endianness of the data can be provided using"                  \
-    " pychrysalide.analysis.BinContent.SourceEndian values."            \
+    "The returned value is the read data or None is case of error."     \
 )
 
     ret = PyArg_ParseTuple(args, "O&k", convert_any_to_vmpa, &addr, &endianness);
@@ -691,6 +1330,12 @@ static PyObject *py_binary_content_get_data(PyObject *self, void *closure)
 PyTypeObject *get_python_binary_content_type(void)
 {
     static PyMethodDef py_binary_content_methods[] = {
+        BINARY_CONTENT_DESCRIBE_WRAPPER,
+        BINARY_CONTENT_READ_RAW_WRAPPER,
+        BINARY_CONTENT_READ_U8_WRAPPER,
+        BINARY_CONTENT_READ_U16_WRAPPER,
+        BINARY_CONTENT_READ_U32_WRAPPER,
+        BINARY_CONTENT_READ_U64_WRAPPER,
         BINARY_CONTENT_DESCRIBE_METHOD,
         BINARY_CONTENT_READ_RAW_METHOD,
         BINARY_CONTENT_READ_U8_METHOD,
@@ -749,6 +1394,14 @@ bool ensure_python_binary_content_is_registered(void)
     PyObject *module;                       /* Module à recompléter        */
     PyObject *dict;                         /* Dictionnaire du module      */
 
+    static GInterfaceInfo info = {          /* Paramètres d'inscription    */
+
+        .interface_init = (GInterfaceInitFunc)py_binary_content_interface_init,
+        .interface_finalize = NULL,
+        .interface_data = NULL,
+
+    };
+
     type = get_python_binary_content_type();
 
     if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
@@ -757,7 +1410,7 @@ bool ensure_python_binary_content_is_registered(void)
 
         dict = PyModule_GetDict(module);
 
-        if (!register_interface_for_pygobject(dict, G_TYPE_BIN_CONTENT, type))
+        if (!register_interface_for_pygobject_2(dict, G_TYPE_BIN_CONTENT, type, &info))
             return false;
 
         if (!define_analysis_content_constants(type))
diff --git a/plugins/ropgadgets/select.c b/plugins/ropgadgets/select.c
index aebe433..9df71bb 100644
--- a/plugins/ropgadgets/select.c
+++ b/plugins/ropgadgets/select.c
@@ -474,7 +474,7 @@ static GtkWidget *load_and_populate_current_project_binaries(GObject *ref, gint
     GLoadedContent **contents;              /* Liste de contenus chargés   */
     size_t count;                           /* Taille de cette liste       */
     size_t i;                               /* Boucle de parcours          */
-    GLoadedBinary *binary;                  /* Contenu de code binaire     */ 
+    char *desc;                             /* Description de contenu      */
     GtkTreeIter iter;                       /* Point d'insertion           */
     GtkCellRenderer *renderer;              /* Moteur de rendu de colonne  */
 
@@ -498,15 +498,17 @@ static GtkWidget *load_and_populate_current_project_binaries(GObject *ref, gint
         {
             if (G_IS_LOADED_BINARY(contents[i]))
             {
-                binary = G_LOADED_BINARY(contents[i]);
+                desc = g_loaded_content_describe(contents[i], true);
 
                 gtk_list_store_append(store, &iter);
                 gtk_list_store_set(store, &iter,
-                                   CPB_BINARY, binary,
-                                   CPB_FILENAME, g_loaded_binary_get_name(binary, true),
+                                   CPB_BINARY, contents[i],
+                                   CPB_FILENAME, desc,
                                    -1);
 
-                if (binary == (GLoadedBinary *)current)
+                free(desc);
+
+                if (contents[i] == current)
                     *selected = i;
 
             }
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index aee4499..c671827 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -400,35 +400,6 @@ GLoadedContent *g_loaded_binary_new(GExeFormat *format)
 }
 
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : binary = élément binaire à consulter.                        *
-*                full   = précise s'il s'agit d'une version longue ou non.    *
-*                                                                             *
-*  Description : Fournit le nom associé à l'élément binaire.                  *
-*                                                                             *
-*  Retour      : Nom de fichier avec chemin absolu.                           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-const char *g_loaded_binary_get_name(const GLoadedBinary *binary, bool full)
-{
-    const char *result;                     /* Description à retourner     */
-    GBinContent *content;                   /* Contenu binaire mannipulé   */
-
-    content = g_known_format_get_content(G_KNOWN_FORMAT(binary->format));
-
-    result = g_binary_content_describe(content, full);
-
-    g_object_unref(G_OBJECT(content));
-
-    return result;
-
-}
-
-
 
 /* ---------------------------------------------------------------------------------- */
 /*                           INFORMATIONS D'ENREGISTREMENTS                           */
diff --git a/src/analysis/binary.h b/src/analysis/binary.h
index 74c5f7f..178d186 100644
--- a/src/analysis/binary.h
+++ b/src/analysis/binary.h
@@ -76,9 +76,6 @@ GType g_loaded_binary_get_type(void);
 /* Interprète un contenu binaire chargé. */
 GLoadedContent *g_loaded_binary_new(GExeFormat *);
 
-/* Fournit le nom associé à l'élément binaire. */
-const char *g_loaded_binary_get_name(const GLoadedBinary *, bool);
-
 
 
 /* ------------------------- INFORMATIONS D'ENREGISTREMENTS ------------------------- */
diff --git a/src/analysis/content-int.h b/src/analysis/content-int.h
index ad13b8d..886c196 100644
--- a/src/analysis/content-int.h
+++ b/src/analysis/content-int.h
@@ -39,7 +39,7 @@ typedef GContentAttributes * (* get_content_attributes) (const GBinContent *);
 typedef GBinContent * (* get_content_root_fc) (GBinContent *);
 
 /* Fournit le nom associé au contenu binaire. */
-typedef const char * (* describe_content_fc) (const GBinContent *, bool);
+typedef char * (* describe_content_fc) (const GBinContent *, bool);
 
 /* Ecrit une sauvegarde de contenu binaire dans un fichier XML. */
 typedef bool (* save_content_fc) (const GBinContent *, xmlDocPtr, xmlXPathContextPtr, const char *, const char *);
diff --git a/src/analysis/content.c b/src/analysis/content.c
index 86fa490..8b83261 100644
--- a/src/analysis/content.c
+++ b/src/analysis/content.c
@@ -197,14 +197,14 @@ GBinContent *g_binary_content_get_root(GBinContent *content)
 *                                                                             *
 ******************************************************************************/
 
-const char *g_binary_content_describe(const GBinContent *content, bool full)
+char *g_binary_content_describe(const GBinContent *content, bool full)
 {
     char *result;                           /* Description à retourner     */
     GBinContentIface *iface;                /* Interface utilisée          */
 
     iface = G_BIN_CONTENT_GET_IFACE(content);
 
-    result = strdup(iface->describe(content, full));
+    result = iface->describe(content, full);
 
     return result;
 
@@ -418,11 +418,14 @@ const bin_t *g_binary_content_get_raw_access(const GBinContent *content, vmpa2t
 
 bool g_binary_content_read_raw(const GBinContent *content, vmpa2t *addr, phys_t length, bin_t *out)
 {
+    bool result;                            /* Bilan à remonter            */
     GBinContentIface *iface;                /* Interface utilisée          */
 
     iface = G_BIN_CONTENT_GET_IFACE(content);
 
-    return iface->read_raw(content, addr, length, out);
+    result = iface->read_raw(content, addr, length, out);
+
+    return result;
 
 }
 
@@ -444,11 +447,14 @@ bool g_binary_content_read_raw(const GBinContent *content, vmpa2t *addr, phys_t
 
 bool g_binary_content_read_u4(const GBinContent *content, vmpa2t *addr, bool *low, uint8_t *val)
 {
+    bool result;                            /* Bilan à remonter            */
     GBinContentIface *iface;                /* Interface utilisée          */
 
     iface = G_BIN_CONTENT_GET_IFACE(content);
 
-    return iface->read_u4(content, addr, low, val);
+    result = iface->read_u4(content, addr, low, val);
+
+    return result;
 
 }
 
@@ -470,11 +476,14 @@ bool g_binary_content_read_u4(const GBinContent *content, vmpa2t *addr, bool *lo
 
 bool g_binary_content_read_u8(const GBinContent *content, vmpa2t *addr, uint8_t *val)
 {
+    bool result;                            /* Bilan à remonter            */
     GBinContentIface *iface;                /* Interface utilisée          */
 
     iface = G_BIN_CONTENT_GET_IFACE(content);
 
-    return iface->read_u8(content, addr, val);
+    result = iface->read_u8(content, addr, val);
+
+    return result;
 
 }
 
@@ -496,11 +505,14 @@ bool g_binary_content_read_u8(const GBinContent *content, vmpa2t *addr, uint8_t
 
 bool g_binary_content_read_u16(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint16_t *val)
 {
+    bool result;                            /* Bilan à remonter            */
     GBinContentIface *iface;                /* Interface utilisée          */
 
     iface = G_BIN_CONTENT_GET_IFACE(content);
 
-    return iface->read_u16(content, addr, endian, val);
+    result = iface->read_u16(content, addr, endian, val);
+
+    return result;
 
 }
 
@@ -522,11 +534,14 @@ bool g_binary_content_read_u16(const GBinContent *content, vmpa2t *addr, SourceE
 
 bool g_binary_content_read_u32(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint32_t *val)
 {
+    bool result;                            /* Bilan à remonter            */
     GBinContentIface *iface;                /* Interface utilisée          */
 
     iface = G_BIN_CONTENT_GET_IFACE(content);
 
-    return iface->read_u32(content, addr, endian, val);
+    result = iface->read_u32(content, addr, endian, val);
+
+    return result;
 
 }
 
@@ -548,11 +563,14 @@ bool g_binary_content_read_u32(const GBinContent *content, vmpa2t *addr, SourceE
 
 bool g_binary_content_read_u64(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint64_t *val)
 {
+    bool result;                            /* Bilan à remonter            */
     GBinContentIface *iface;                /* Interface utilisée          */
 
     iface = G_BIN_CONTENT_GET_IFACE(content);
 
-    return iface->read_u64(content, addr, endian, val);
+    result = iface->read_u64(content, addr, endian, val);
+
+    return result;
 
 }
 
@@ -573,11 +591,14 @@ bool g_binary_content_read_u64(const GBinContent *content, vmpa2t *addr, SourceE
 
 bool g_binary_content_read_uleb128(const GBinContent *content, vmpa2t *addr, uleb128_t *val)
 {
+    bool result;                            /* Bilan à remonter            */
     GBinContentIface *iface;                /* Interface utilisée          */
 
     iface = G_BIN_CONTENT_GET_IFACE(content);
 
-    return iface->read_uleb128(content, addr, val);
+    result = iface->read_uleb128(content, addr, val);
+
+    return result;
 
 }
 
@@ -598,10 +619,13 @@ bool g_binary_content_read_uleb128(const GBinContent *content, vmpa2t *addr, ule
 
 bool g_binary_content_read_leb128(const GBinContent *content, vmpa2t *addr, leb128_t *val)
 {
+    bool result;                            /* Bilan à remonter            */
     GBinContentIface *iface;                /* Interface utilisée          */
 
     iface = G_BIN_CONTENT_GET_IFACE(content);
 
-    return iface->read_leb128(content, addr, val);
+    result = iface->read_leb128(content, addr, val);
+
+    return result;
 
 }
diff --git a/src/analysis/content.h b/src/analysis/content.h
index 9f901e7..d7f5536 100644
--- a/src/analysis/content.h
+++ b/src/analysis/content.h
@@ -68,7 +68,7 @@ GContentAttributes *g_binary_content_get_attributes(const GBinContent *);
 GBinContent *g_binary_content_get_root(GBinContent *);
 
 /* Fournit le nom associé au contenu binaire. */
-const char *g_binary_content_describe(const GBinContent *, bool);
+char *g_binary_content_describe(const GBinContent *, bool);
 
 /* Ecrit une sauvegarde de contenu binaire dans un fichier XML. */
 bool g_binary_content_save(const GBinContent *, xmlDocPtr, xmlXPathContextPtr, const char *, const char *);
diff --git a/src/analysis/contents/encapsulated.c b/src/analysis/contents/encapsulated.c
index 569df10..59b0c9e 100644
--- a/src/analysis/contents/encapsulated.c
+++ b/src/analysis/contents/encapsulated.c
@@ -74,7 +74,7 @@ static void g_encaps_content_finalize(GEncapsContent *);
 static GBinContent *g_encaps_content_get_root(GEncapsContent *);
 
 /* Fournit le nom associé au contenu binaire. */
-static const char *g_encaps_content_describe(const GEncapsContent *, bool);
+static char *g_encaps_content_describe(const GEncapsContent *, bool);
 
 /* Ecrit une sauvegarde de contenu binaire dans un fichier XML. */
 static bool g_encaps_content_save(const GEncapsContent *, xmlDocPtr, xmlXPathContextPtr, const char *, const char *);
@@ -296,7 +296,7 @@ GBinContent *g_encaps_content_new(GBinContent *base, const char *path, GBinConte
 
     /* Description complète */
 
-    result->full_desc = stradd(result->full_desc, g_binary_content_describe(result->base, true));
+    result->full_desc = g_binary_content_describe(result->base, true);
 
     result->full_desc = stradd(result->full_desc, G_DIR_SEPARATOR_S);
 
@@ -416,14 +416,14 @@ static GBinContent *g_encaps_content_get_root(GEncapsContent *content)
 *                                                                             *
 ******************************************************************************/
 
-static const char *g_encaps_content_describe(const GEncapsContent *content, bool full)
+static char *g_encaps_content_describe(const GEncapsContent *content, bool full)
 {
-    const char *result;                     /* Description à retourner     */
+    char *result;                           /* Description à retourner     */
 
     if (full)
-        result = content->full_desc;
+        result = strdup(content->full_desc);
     else
-        result = content->desc;
+        result = strdup(content->desc);
 
     return result;
 
diff --git a/src/analysis/contents/file.c b/src/analysis/contents/file.c
index b133336..7bb0be8 100644
--- a/src/analysis/contents/file.c
+++ b/src/analysis/contents/file.c
@@ -86,7 +86,7 @@ static GContentAttributes *g_file_content_get_attributes(const GFileContent *);
 static GBinContent *g_file_content_get_root(GFileContent *);
 
 /* Fournit le nom associé au contenu binaire. */
-static const char *g_file_content_describe(const GFileContent *, bool);
+static char *g_file_content_describe(const GFileContent *, bool);
 
 /* Ecrit une sauvegarde de contenu binaire dans un fichier XML. */
 static bool g_file_content_save(const GFileContent *, xmlDocPtr, xmlXPathContextPtr, const char *, const char *);
@@ -489,22 +489,23 @@ static GBinContent *g_file_content_get_root(GFileContent *content)
 *                                                                             *
 ******************************************************************************/
 
-static const char *g_file_content_describe(const GFileContent *content, bool full)
+static char *g_file_content_describe(const GFileContent *content, bool full)
 {
-    const char *result;                     /* Description à retourner     */
+    char *result;                           /* Description à retourner     */
+    const char *sep;                        /* Caractère de séparation     */
 
     if (full)
-        result = content->filename;
+        result = strdup(content->filename);
 
     else
     {
-        result = strrchr(content->filename, G_DIR_SEPARATOR);
+        sep = strrchr(content->filename, G_DIR_SEPARATOR);
 
-        if (result == NULL)
-            result = content->filename;
+        if (sep == NULL)
+            result = strdup(content->filename);
 
         else
-            result++;
+            result = strdup(++sep);
 
     }
 
diff --git a/src/analysis/contents/memory.c b/src/analysis/contents/memory.c
index 232a41d..a37a7d4 100644
--- a/src/analysis/contents/memory.c
+++ b/src/analysis/contents/memory.c
@@ -77,7 +77,7 @@ static void g_memory_content_finalize(GMemoryContent *);
 static GBinContent *g_memory_content_get_root(GMemoryContent *);
 
 /* Fournit le nom associé au contenu binaire. */
-static const char *g_memory_content_describe(const GMemoryContent *, bool);
+static char *g_memory_content_describe(const GMemoryContent *, bool);
 
 /* Ecrit une sauvegarde de contenu binaire dans un fichier XML. */
 static bool g_memory_content_save(const GMemoryContent *, xmlDocPtr, xmlXPathContextPtr, const char *, const char *);
@@ -399,11 +399,11 @@ static GBinContent *g_memory_content_get_root(GMemoryContent *content)
 *                                                                             *
 ******************************************************************************/
 
-static const char *g_memory_content_describe(const GMemoryContent *content, bool full)
+static char *g_memory_content_describe(const GMemoryContent *content, bool full)
 {
-    const char *result;                     /* Description à retourner     */
+    char *result;                           /* Description à retourner     */
 
-    result = "In-memory content";
+    result = strdup("In-memory content");
 
     return result;
 
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index 607f1e4..af67fdf 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -389,7 +389,7 @@ void output_disassembly(GLoadedBinary *binary, GProcContext *context, GtkStatusS
     GBinContent *content;                   /* Contenu bianire manipulé    */
     GCodingLanguage *lang;                  /* Langage de sortie préféré   */
     char **text;                            /* Contenu brute à imprimer    */
-    const char *desc;                       /* Désignation du binaire      */
+    char *desc;                             /* Désignation du binaire      */
     const gchar *checksum;                  /* Identifiant de binaire      */
     GIntroGenerator *generator;             /* Générateur constitué        */
 
@@ -420,6 +420,8 @@ void output_disassembly(GLoadedBinary *binary, GProcContext *context, GtkStatusS
 
     asprintf(&text[2], "%s%s", _("Source: "), desc);
 
+    free(desc);
+
     /* Checksum SHA256 */
 
     checksum = g_binary_content_get_checksum(content);
diff --git a/src/gui/dialogs/export_disass.c b/src/gui/dialogs/export_disass.c
index beaa3c8..314b9cf 100644
--- a/src/gui/dialogs/export_disass.c
+++ b/src/gui/dialogs/export_disass.c
@@ -875,7 +875,7 @@ static void register_output_panel(GtkAssistant *assistant)
     GtkWidget *entry;                       /* Zone de saisie de texte     */
     GtkWidget *button;                      /* Sélection de fichier        */
     GLoadedBinary *binary;                  /* Binaire chargé à parcourir  */
-    const char *filename;                   /* Chemin d'accès par défaut   */
+    char *filename;                         /* Chemin d'accès par défaut   */
 
     vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8);
     qck_set_margins(vbox, 8, 8, 8, 8);
@@ -907,11 +907,13 @@ static void register_output_panel(GtkAssistant *assistant)
     /* Choix par défaut */
 
     binary = G_LOADED_BINARY(g_object_get_data(G_OBJECT(assistant), "binary"));
-    filename = g_loaded_binary_get_name(binary, true);
+    filename = g_loaded_content_describe(G_LOADED_CONTENT(binary), true);
 
     gtk_entry_set_text(GTK_ENTRY(entry), filename);
     gtk_editable_insert_text(GTK_EDITABLE(entry), ".html", -1, (gint []) { strlen(filename) });
 
+    free(filename);
+
     g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(on_export_filename_changed), assistant);
 
 }
diff --git a/src/gui/panels/bintree.c b/src/gui/panels/bintree.c
index 220a31d..a949b0d 100644
--- a/src/gui/panels/bintree.c
+++ b/src/gui/panels/bintree.c
@@ -688,6 +688,7 @@ static void reload_portions_for_new_tree_view(const GBintreePanel *panel, GtkSta
     GBinPortion *portions;                  /* Couche première de portions */
     size_t count;                           /* Compteur de portions        */
     GtkTreeIter top;                        /* Racine de l'arborescence    */
+    char *desc;                             /* Description de contenu      */
     gint max_depth;                         /* Profondeur maximale         */
     GtkSpinButton *depth_spin;              /* Bouton de variation         */
     GtkTreeView *treeview;                  /* Arborescence constituée     */
@@ -708,11 +709,15 @@ static void reload_portions_for_new_tree_view(const GBintreePanel *panel, GtkSta
 
     gtk_tree_store_append(store, &top, NULL);
 
+    desc = g_loaded_content_describe(G_LOADED_CONTENT(panel->binary), false);
+
     gtk_tree_store_set(store, &top,
                        BTC_ICON, NULL,
-                       BTC_CAPTION, g_loaded_binary_get_name(panel->binary, false),
+                       BTC_CAPTION, desc,
                        -1);
 
+    free(desc);
+
     data->panel = panel;
     data->top = &top;
     data->status = status;
-- 
cgit v0.11.2-87-g4458