From 8ef9431730c489dcfd10edb052b4c2efbe34c921 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Wed, 11 Apr 2018 14:24:56 +0200
Subject: Created definitions for memory and encapsulated contents.

---
 plugins/pychrysalide/analysis/contents/Makefile.am |   2 +
 .../pychrysalide/analysis/contents/encapsulated.c  | 160 +++++
 .../pychrysalide/analysis/contents/encapsulated.h  |  42 ++
 plugins/pychrysalide/analysis/contents/memory.c    | 154 +++++
 plugins/pychrysalide/analysis/contents/memory.h    |  42 ++
 plugins/pychrysalide/analysis/contents/module.c    |   8 +-
 plugins/pychrysalide/analysis/module.c             |   2 +-
 src/analysis/contents/Makefile.am                  |   2 +
 src/analysis/contents/encapsulated.c               | 747 ++++++++++++++++++++
 src/analysis/contents/encapsulated.h               |  61 ++
 src/analysis/contents/file.c                       |  43 +-
 src/analysis/contents/file.h                       |  12 +-
 src/analysis/contents/memory.c                     | 758 +++++++++++++++++++++
 src/analysis/contents/memory.h                     |  61 ++
 src/common/io.c                                    |   3 +
 tests/analysis/contents/memory.py                  |  65 ++
 16 files changed, 2138 insertions(+), 24 deletions(-)
 create mode 100644 plugins/pychrysalide/analysis/contents/encapsulated.c
 create mode 100644 plugins/pychrysalide/analysis/contents/encapsulated.h
 create mode 100644 plugins/pychrysalide/analysis/contents/memory.c
 create mode 100644 plugins/pychrysalide/analysis/contents/memory.h
 create mode 100644 src/analysis/contents/encapsulated.c
 create mode 100644 src/analysis/contents/encapsulated.h
 create mode 100644 src/analysis/contents/memory.c
 create mode 100644 src/analysis/contents/memory.h
 create mode 100644 tests/analysis/contents/memory.py

diff --git a/plugins/pychrysalide/analysis/contents/Makefile.am b/plugins/pychrysalide/analysis/contents/Makefile.am
index 3cd00a6..b7e2f43 100644
--- a/plugins/pychrysalide/analysis/contents/Makefile.am
+++ b/plugins/pychrysalide/analysis/contents/Makefile.am
@@ -2,7 +2,9 @@
 noinst_LTLIBRARIES = libpychrysaanalysiscontents.la
 
 libpychrysaanalysiscontents_la_SOURCES = \
+	encapsulated.h encapsulated.c		\
 	file.h file.c						\
+	memory.h memory.c					\
 	module.h module.c					\
 	restricted.h restricted.c
 
diff --git a/plugins/pychrysalide/analysis/contents/encapsulated.c b/plugins/pychrysalide/analysis/contents/encapsulated.c
new file mode 100644
index 0000000..a81e45b
--- /dev/null
+++ b/plugins/pychrysalide/analysis/contents/encapsulated.c
@@ -0,0 +1,160 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * encapsulated.c - prototypes pour l'équivalent Python du fichier "analysis/contents/encapsulated.c"
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 "encapsulated.h"
+
+
+#include <pygobject.h>
+
+
+#include <analysis/contents/encapsulated.h>
+
+
+#include "../content.h"
+#include "../../helpers.h"
+
+
+
+/* Crée un nouvel objet Python de type 'BinContent'. */
+static PyObject *py_encaps_content_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 'BinContent'.            *
+*                                                                             *
+*  Retour      : Instance Python mise en place.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_encaps_content_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    PyObject *base_obj;                     /* Base en Python              */
+    const char *path;                       /* Chemin vers le contenu final*/
+    PyObject *endpoint_obj;                 /* Contenu final en Python     */
+    int ret;                                /* Bilan de lecture des args.  */
+    GBinContent *base;                      /* Base de l'extraction        */
+    GBinContent *endpoint;                  /* Contenu accessible au final */
+    GBinContent *content;                   /* Version GLib du contenu     */
+
+    ret = PyArg_ParseTuple(args, "O!sO!",
+                           get_python_binary_content_type(), &base_obj,
+                           &path,
+                           get_python_binary_content_type(), &endpoint_obj);
+    if (!ret) Py_RETURN_NONE;
+
+    base = G_BIN_CONTENT(pygobject_get(base_obj));
+    endpoint = G_BIN_CONTENT(pygobject_get(endpoint_obj));
+
+    content = g_encaps_content_new(base, path, endpoint);
+
+    result = pygobject_new(G_OBJECT(content));
+
+    if (content != NULL)
+        g_object_unref(content);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit un accès à une définition de type à diffuser.        *
+*                                                                             *
+*  Retour      : Définition d'objet pour Python.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyTypeObject *get_python_encaps_content_type(void)
+{
+    static PyMethodDef py_encaps_content_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_encaps_content_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_encaps_content_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.contents.EncapsulatedContent",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = "PyChrysalide binary encapsulated content",
+
+        .tp_methods     = py_encaps_content_methods,
+        .tp_getset      = py_encaps_content_getseters,
+        .tp_new         = (newfunc)py_encaps_content_new
+
+    };
+
+    return &py_encaps_content_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide...EncapsulatedContent'.*
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool register_python_encaps_content(PyObject *module)
+{
+    PyTypeObject *py_encaps_content_type;   /* Type 'EncapsulatedContent'  */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    py_encaps_content_type = get_python_encaps_content_type();
+
+    dict = PyModule_GetDict(module);
+
+    if (!register_class_for_pygobject(dict, G_TYPE_ENCAPS_CONTENT, py_encaps_content_type, &PyGObject_Type))
+        return false;
+
+    return true;
+
+}
diff --git a/plugins/pychrysalide/analysis/contents/encapsulated.h b/plugins/pychrysalide/analysis/contents/encapsulated.h
new file mode 100644
index 0000000..ebd760c
--- /dev/null
+++ b/plugins/pychrysalide/analysis/contents/encapsulated.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * encapsulated.h - prototypes pour l'équivalent Python du fichier "analysis/contents/encapsulated.h"
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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_PYCHRYSALIDE_ANALYSIS_CONTENTS_ENCAPSULATED_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_CONTENTS_ENCAPSULATED_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_encaps_content_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.contents.EncapsulatedContent'. */
+bool register_python_encaps_content(PyObject *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_CONTENTS_ENCAPSULATED_H */
diff --git a/plugins/pychrysalide/analysis/contents/memory.c b/plugins/pychrysalide/analysis/contents/memory.c
new file mode 100644
index 0000000..fadc9bf
--- /dev/null
+++ b/plugins/pychrysalide/analysis/contents/memory.c
@@ -0,0 +1,154 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * memory.c - prototypes pour l'équivalent Python du fichier "analysis/contents/memory.c"
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 "memory.h"
+
+
+#include <pygobject.h>
+
+
+#include <analysis/contents/memory.h>
+
+
+#include "../../helpers.h"
+
+
+
+/* Crée un nouvel objet Python de type 'BinContent'. */
+static PyObject *py_memory_content_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 'BinContent'.            *
+*                                                                             *
+*  Retour      : Instance Python mise en place.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_memory_content_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    PyObject *data;                         /* Données brutes à charger    */
+    int ret;                                /* Bilan de lecture des args.  */
+    char *buffer;                           /* Tampon interne de Python    */
+    Py_ssize_t length;                      /* Taille utilisé de ce tampon */
+    GBinContent *content;                   /* Version GLib du contenu     */
+
+    ret = PyArg_ParseTuple(args, "S", &data);
+    if (!ret) Py_RETURN_NONE;
+
+    ret = PyBytes_AsStringAndSize(data, &buffer, &length);
+    if (ret == -1) Py_RETURN_NONE;
+
+    content = g_memory_content_new((bin_t *)buffer, length);
+
+    result = pygobject_new(G_OBJECT(content));
+
+    if (content != NULL)
+        g_object_unref(content);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit un accès à une définition de type à diffuser.        *
+*                                                                             *
+*  Retour      : Définition d'objet pour Python.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyTypeObject *get_python_memory_content_type(void)
+{
+    static PyMethodDef py_memory_content_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_memory_content_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_memory_content_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.contents.MemoryContent",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = "PyChrysalide binary memory content",
+
+        .tp_methods     = py_memory_content_methods,
+        .tp_getset      = py_memory_content_getseters,
+        .tp_new         = (newfunc)py_memory_content_new
+
+    };
+
+    return &py_memory_content_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide.....MemoryContent'.    *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool register_python_memory_content(PyObject *module)
+{
+    PyTypeObject *py_memory_content_type;   /* Type Python 'MemoryContent' */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    py_memory_content_type = get_python_memory_content_type();
+
+    dict = PyModule_GetDict(module);
+
+    if (!register_class_for_pygobject(dict, G_TYPE_MEMORY_CONTENT, py_memory_content_type, &PyGObject_Type))
+        return false;
+
+    return true;
+
+}
diff --git a/plugins/pychrysalide/analysis/contents/memory.h b/plugins/pychrysalide/analysis/contents/memory.h
new file mode 100644
index 0000000..f3db9a7
--- /dev/null
+++ b/plugins/pychrysalide/analysis/contents/memory.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * memory.h - prototypes pour l'équivalent Python du fichier "analysis/contents/memory.h"
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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_PYCHRYSALIDE_ANALYSIS_CONTENTS_MEMORY_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_CONTENTS_MEMORY_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_memory_content_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.contents.MemoryContent'. */
+bool register_python_memory_content(PyObject *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_CONTENTS_MEMORY_H */
diff --git a/plugins/pychrysalide/analysis/contents/module.c b/plugins/pychrysalide/analysis/contents/module.c
index 2daa62c..53fcdc8 100644
--- a/plugins/pychrysalide/analysis/contents/module.c
+++ b/plugins/pychrysalide/analysis/contents/module.c
@@ -28,7 +28,9 @@
 #include <assert.h>
 
 
+#include "encapsulated.h"
 #include "file.h"
+#include "memory.h"
 #include "restricted.h"
 #include "../../access.h"
 
@@ -45,7 +47,7 @@
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
-#include "../content.h"
+
 bool add_analysis_contents_module_to_python_module(PyObject *super)
 {
     bool result;                            /* Bilan à retourner           */
@@ -80,9 +82,9 @@ bool add_analysis_contents_module_to_python_module(PyObject *super)
 
     result = true;
 
-    result &= register_python_binary_content(module);
-
+    result &= register_python_encaps_content(module);
     result &= register_python_file_content(module);
+    result &= register_python_memory_content(module);
     result &= register_python_restricted_content(module);
 
     if (result)
diff --git a/plugins/pychrysalide/analysis/module.c b/plugins/pychrysalide/analysis/module.c
index c9a9276..309083c 100644
--- a/plugins/pychrysalide/analysis/module.c
+++ b/plugins/pychrysalide/analysis/module.c
@@ -86,11 +86,11 @@ bool add_analysis_module_to_python_module(PyObject *super)
 
     result = true;
 
+    result &= register_python_binary_content(module);
     result &= register_python_loaded_content(module);
 
     result &= register_python_loaded_binary(module);
     result &= register_python_instr_block(module);
-    //result &= register_python_binary_content(module);
     result &= register_python_binary_routine(module);
     result &= register_python_data_type(module);
 
diff --git a/src/analysis/contents/Makefile.am b/src/analysis/contents/Makefile.am
index 2580357..a7de73f 100755
--- a/src/analysis/contents/Makefile.am
+++ b/src/analysis/contents/Makefile.am
@@ -2,7 +2,9 @@
 noinst_LTLIBRARIES  = libanalysiscontents.la
 
 libanalysiscontents_la_SOURCES =		\
+	encapsulated.h encapsulated.c		\
 	file.h file.c						\
+	memory.h memory.c					\
 	restricted.h restricted.c
 
 libanalysiscontents_la_LIBADD =	
diff --git a/src/analysis/contents/encapsulated.c b/src/analysis/contents/encapsulated.c
new file mode 100644
index 0000000..1fd4203
--- /dev/null
+++ b/src/analysis/contents/encapsulated.c
@@ -0,0 +1,747 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * encapsulated.c - chargement de données binaires à partir d'un fichier
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 Chrysalide.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "encapsulated.h"
+
+
+#include <malloc.h>
+#include <string.h>
+
+
+#include "../content-int.h"
+#include "../../common/extstr.h"
+
+
+
+/* Contenu de issu d'un contenu plus global (instance) */
+struct _GEncapsContent
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    GBinContent *base;                      /* Base offrant une extraction */
+    char *path;                             /* Chemin vers le contenu ciblé*/
+    GBinContent *endpoint;                  /* Contenu ciblé               */
+
+    char *full_desc;                        /* Description de l'ensemble   */
+    char *desc;                             /* Description de l'ensemble   */
+
+};
+
+/* Contenu de issu d'un contenu plus global (classe) */
+struct _GEncapsContentClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+};
+
+
+/* Initialise la classe des contenus de données encapsulés. */
+static void g_encaps_content_class_init(GEncapsContentClass *);
+
+/* Initialise une instance de contenu de données encapsulé. */
+static void g_encaps_content_init(GEncapsContent *);
+
+/* Procède à l'initialisation de l'interface de lecture. */
+static void g_encaps_content_interface_init(GBinContentInterface *);
+
+/* Supprime toutes les références externes. */
+static void g_encaps_content_dispose(GEncapsContent *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_encaps_content_finalize(GEncapsContent *);
+
+/* Fournit le nom associé au contenu binaire. */
+static const 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 *);
+
+/* Fournit une empreinte unique (SHA256) pour les données. */
+static void g_encaps_content_compute_checksum(GEncapsContent *, GChecksum *);
+
+/* Détermine le nombre d'octets lisibles. */
+static phys_t g_encaps_content_compute_size(const GEncapsContent *);
+
+/* Avance la tête de lecture d'une certaine quantité de données. */
+static bool g_encaps_content_seek(const GEncapsContent *, vmpa2t *, phys_t);
+
+/* Donne accès à une portion des données représentées. */
+static const bin_t *g_encaps_content_get_raw_access(const GEncapsContent *, vmpa2t *, phys_t);
+
+/* Fournit une portion des données représentées. */
+static bool g_encaps_content_read_raw(const GEncapsContent *, vmpa2t *, phys_t, bin_t *);
+
+/* Lit un nombre non signé sur quatre bits. */
+static bool g_encaps_content_read_u4(const GEncapsContent *, vmpa2t *, bool *, uint8_t *);
+
+/* Lit un nombre non signé sur un octet. */
+static bool g_encaps_content_read_u8(const GEncapsContent *, vmpa2t *, uint8_t *);
+
+/* Lit un nombre non signé sur deux octets. */
+static bool g_encaps_content_read_u16(const GEncapsContent *, vmpa2t *, SourceEndian, uint16_t *);
+
+/* Lit un nombre non signé sur quatre octets. */
+static bool g_encaps_content_read_u32(const GEncapsContent *, vmpa2t *, SourceEndian, uint32_t *);
+
+/* Lit un nombre non signé sur huit octets. */
+static bool g_encaps_content_read_u64(const GEncapsContent *, vmpa2t *, SourceEndian, uint64_t *);
+
+/* Lit un nombre non signé encodé au format LEB128. */
+static bool g_encaps_content_read_uleb128(const GEncapsContent *, vmpa2t *, uleb128_t *);
+
+/* Lit un nombre signé encodé au format LEB128. */
+static bool g_encaps_content_read_leb128(const GEncapsContent *, vmpa2t *, leb128_t *);
+
+
+
+/* Indique le type défini par la GLib pour les contenus encapsulés. */
+G_DEFINE_TYPE_WITH_CODE(GEncapsContent, g_encaps_content, G_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE(G_TYPE_BIN_CONTENT, g_encaps_content_interface_init));
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des contenus de données encapsulés.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_encaps_content_class_init(GEncapsContentClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_encaps_content_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_encaps_content_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = instance à initialiser.                            *
+*                                                                             *
+*  Description : Initialise une instance de contenu de données encapsulé.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_encaps_content_init(GEncapsContent *content)
+{
+    content->base = NULL;
+    content->path = NULL;
+    content->endpoint = NULL;
+
+    content->full_desc = NULL;
+    content->desc = NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iface = interface GLib à initialiser.                        *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de lecture.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_encaps_content_interface_init(GBinContentInterface *iface)
+{
+    iface->describe = (describe_content_fc)g_encaps_content_describe;
+
+    iface->save = (save_content_fc)g_encaps_content_save;
+
+    iface->compute_checksum = (compute_checksum_fc)g_encaps_content_compute_checksum;
+
+    iface->compute_size = (compute_size_fc)g_encaps_content_compute_size;
+
+    iface->seek = (seek_fc)g_encaps_content_seek;
+
+    iface->get_raw_access = (get_raw_access_fc)g_encaps_content_get_raw_access;
+
+    iface->read_raw = (read_raw_fc)g_encaps_content_read_raw;
+    iface->read_u4 = (read_u4_fc)g_encaps_content_read_u4;
+    iface->read_u8 = (read_u8_fc)g_encaps_content_read_u8;
+    iface->read_u16 = (read_u16_fc)g_encaps_content_read_u16;
+    iface->read_u32 = (read_u32_fc)g_encaps_content_read_u32;
+    iface->read_u64 = (read_u64_fc)g_encaps_content_read_u64;
+
+    iface->read_uleb128 = (read_uleb128_fc)g_encaps_content_read_uleb128;
+    iface->read_leb128 = (read_leb128_fc)g_encaps_content_read_leb128;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_encaps_content_dispose(GEncapsContent *content)
+{
+    if (content->base != NULL)
+        g_object_unref(content->base);
+
+    if (content->endpoint != NULL)
+        g_object_unref(content->endpoint);
+
+    G_OBJECT_CLASS(g_encaps_content_parent_class)->dispose(G_OBJECT(content));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_encaps_content_finalize(GEncapsContent *content)
+{
+    if (content->desc != NULL)
+        free(content->desc);
+
+    if (content->full_desc != NULL)
+        free(content->full_desc);
+
+    G_OBJECT_CLASS(g_encaps_content_parent_class)->finalize(G_OBJECT(content));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : base     = contenu binaire d'où réaliser une extraction.     *
+*                path     = chemin vers le contenu finalement ciblé.          *
+*                endpoint = contenu final rendu accessible.                   *
+*                                                                             *
+*  Description : Charge en mémoire un contenu binaire encapsulé.              *
+*                                                                             *
+*  Retour      : Représentation de contenu à manipuler ou NULL en cas d'échec.*
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBinContent *g_encaps_content_new(GBinContent *base, const char *path, GBinContent *endpoint)
+{
+    GEncapsContent *result;                 /* Structure à retourner      */
+
+    result = g_object_new(G_TYPE_ENCAPS_CONTENT, NULL);
+
+    result->base = base;
+    result->path = strdup(path);
+    result->endpoint = endpoint;
+
+    /* Description complète */
+
+    result->full_desc = stradd(result->full_desc, g_binary_content_describe(result->base, true));
+
+    result->full_desc = stradd(result->full_desc, G_DIR_SEPARATOR_S);
+
+    result->full_desc = stradd(result->full_desc, path);
+
+    /* Description partielle */
+
+    result->desc = strdup(path);
+
+    return G_BIN_CONTENT(result);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : context = contexte pour les recherches XPath.                *
+*                path    = chemin d'accès au noeud XML à lire.                *
+*                base    = référence au lieu d'enregistrement du projet.      *
+*                                                                             *
+*  Description : Charge en mémoire un contenu encapsulé à partir d'XML.       *
+*                                                                             *
+*  Retour      : Adresse de la représentation ou NULL en cas d'échec.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBinContent *g_encaps_content_new_from_xml(xmlXPathContextPtr context, const char *path, const char *base)
+{
+    GBinContent *result;                    /* Adresse à retourner         */
+    char *access;                           /* Chemin d'accès à un élément */
+    GBinContent *original;                  /* Base offrant une extraction */
+    char *target;                           /* Chemin vers le contenu ciblé*/
+    GBinContent *endpoint;                  /* Contenu ciblé               */
+
+    result = NULL;
+
+    /* Base de l'extraction */
+
+    access = strdup(path);
+    access = stradd(access, "/Base");
+
+    original = g_binary_content_new_from_xml(context, access, base);
+
+    free(access);
+
+    /* Référence au contenu encapsulé */
+
+    if (original != NULL)
+    {
+        access = strdup(path);
+        access = stradd(access, "/Path");
+
+        target = get_node_text_value(context, access);
+
+        if (target != NULL)
+        {
+            endpoint = NULL;/// TODO
+
+            if (endpoint != NULL)
+                result = g_encaps_content_new(original, target, endpoint);
+
+            else
+                g_object_unref(G_OBJECT(original));
+
+        }
+        else
+            g_object_unref(G_OBJECT(original));
+
+
+        free(target);
+        free(access);
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = contenu binaire à 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 const char *g_encaps_content_describe(const GEncapsContent *content, bool full)
+{
+    const char *result;                     /* Description à retourner     */
+
+    if (full)
+        result = content->full_desc;
+    else
+        result = content->desc;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = contenu binaire à traiter.                         *
+*                xdoc    = structure XML en cours d'édition.                  *
+*                context = contexte à utiliser pour les recherches.           *
+*                path    = chemin d'accès réservé au binaire.                 *
+*                base    = référence au lieu d'enregistrement du projet.      *
+*                                                                             *
+*  Description : Ecrit une sauvegarde de contenu binaire dans un fichier XML. *
+*                                                                             *
+*  Retour      : true si l'opération a bien tourné, false sinon.              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_encaps_content_save(const GEncapsContent *content, xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path, const char *base)
+{
+    bool result;                            /* Bilan à faire remonter      */
+    char *access;                           /* Chemin d'accès à un élément */
+
+    /* Type */
+
+    result = add_string_attribute_to_node(xdoc, context, path, "type", "encaps");
+    if (!result) goto gecs_exit;
+
+    /* Base de l'extraction */
+
+    access = strdup(path);
+    access = stradd(access, "/Base");
+
+    result = g_binary_content_save(content->base, xdoc, context, access, base);
+
+    free(access);
+
+    if (!result) goto gecs_exit;
+
+    /* Référence au contenu encapsulé */
+
+    access = strdup(path);
+    access = stradd(access, "/Path");
+
+    result = add_content_to_node(xdoc, context, access, content->path);
+
+    free(access);
+
+ gecs_exit:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content  = contenu binaire à venir lire.                     *
+*                checksum = empreinte de zone mémoire à compléter.            *
+*                                                                             *
+*  Description : Calcule une empreinte unique (SHA256) pour les données.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_encaps_content_compute_checksum(GEncapsContent *content, GChecksum *checksum)
+{
+    GBinContentIface *iface;                /* Interface utilisée          */
+
+    iface = G_BIN_CONTENT_GET_IFACE(content->endpoint);
+
+    iface->compute_checksum(content->endpoint, checksum);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = contenu binaire à venir lire.                      *
+*                                                                             *
+*  Description : Détermine le nombre d'octets lisibles.                       *
+*                                                                             *
+*  Retour      : Quantité représentée.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static phys_t g_encaps_content_compute_size(const GEncapsContent *content)
+{
+    phys_t result;                          /* Quantité trouvée à retourner*/
+
+    result = g_binary_content_compute_size(content->endpoint);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = contenu binaire à venir lire.                      *
+*                addr    = position de la tête de lecture.                    *
+*                length  = quantité d'octets à provisionner.                  *
+*                                                                             *
+*  Description : Avance la tête de lecture d'une certaine quantité de données.*
+*                                                                             *
+*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_encaps_content_seek(const GEncapsContent *content, vmpa2t *addr, phys_t length)
+{
+    bool result;                            /* Bilan d'opération à renvoyer*/
+
+    result = g_binary_content_seek(content->endpoint, addr, length);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = contenu binaire à venir lire.                      *
+*                addr    = position de la tête de lecture.                    *
+*                length  = quantité d'octets à lire.                          *
+*                                                                             *
+*  Description : Donne accès à une portion des données représentées.          *
+*                                                                             *
+*  Retour      : Pointeur vers les données à lire ou NULL en cas d'échec.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static const bin_t *g_encaps_content_get_raw_access(const GEncapsContent *content, vmpa2t *addr, phys_t length)
+{
+    const bin_t *result;                    /* Accès brut à retourner      */
+
+    result = g_binary_content_get_raw_access(content->endpoint, addr, length);
+
+    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 g_encaps_content_read_raw(const GEncapsContent *content, vmpa2t *addr, phys_t length, bin_t *out)
+{
+    bool result;                            /* Bilan à remonter            */
+
+    result = g_binary_content_read_raw(content->endpoint, addr, length, out);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = contenu binaire à venir lire.                      *
+*                addr    = position de la tête de lecture.                    *
+*                low     = position éventuelle des 4 bits visés. [OUT]        *
+*                val     = lieu d'enregistrement de la lecture. [OUT]         *
+*                                                                             *
+*  Description : Lit un nombre non signé sur quatre bits.                     *
+*                                                                             *
+*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_encaps_content_read_u4(const GEncapsContent *content, vmpa2t *addr, bool *low, uint8_t *val)
+{
+    bool result;                            /* Bilan de lecture à renvoyer */
+
+    result = g_binary_content_read_u4(content->endpoint, addr, low, val);
+
+    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 g_encaps_content_read_u8(const GEncapsContent *content, vmpa2t *addr, uint8_t *val)
+{
+    bool result;                            /* Bilan de lecture à renvoyer */
+
+    result = g_binary_content_read_u8(content->endpoint, addr, val);
+
+    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 g_encaps_content_read_u16(const GEncapsContent *content, vmpa2t *addr, SourceEndian endian, uint16_t *val)
+{
+    bool result;                            /* Bilan de lecture à renvoyer */
+
+    result = g_binary_content_read_u16(content->endpoint, addr, endian, val);
+
+    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 g_encaps_content_read_u32(const GEncapsContent *content, vmpa2t *addr, SourceEndian endian, uint32_t *val)
+{
+    bool result;                            /* Bilan de lecture à renvoyer */
+
+    result = g_binary_content_read_u32(content->endpoint, addr, endian, val);
+
+    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 g_encaps_content_read_u64(const GEncapsContent *content, vmpa2t *addr, SourceEndian endian, uint64_t *val)
+{
+    bool result;                            /* Bilan de lecture à renvoyer */
+
+    result = g_binary_content_read_u64(content->endpoint, addr, endian, val);
+
+    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é encodé au format LEB128.             *
+*                                                                             *
+*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_encaps_content_read_uleb128(const GEncapsContent *content, vmpa2t *addr, uleb128_t *val)
+{
+    bool result;                            /* Bilan de lecture à renvoyer */
+
+    result = g_binary_content_read_uleb128(content->endpoint, addr, val);
+
+    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 signé encodé au format LEB128.                 *
+*                                                                             *
+*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_encaps_content_read_leb128(const GEncapsContent *content, vmpa2t *addr, leb128_t *val)
+{
+    bool result;                            /* Bilan de lecture à renvoyer */
+
+    result = g_binary_content_read_leb128(content->endpoint, addr, val);
+
+    return result;
+
+}
diff --git a/src/analysis/contents/encapsulated.h b/src/analysis/contents/encapsulated.h
new file mode 100644
index 0000000..5d21a18
--- /dev/null
+++ b/src/analysis/contents/encapsulated.h
@@ -0,0 +1,61 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * encapsulated.h - prototypes pour le chargement de données binaires à partir d'un fichier
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 Chrysalide.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_CONTENTS_ENCAPSULATED_H
+#define _ANALYSIS_CONTENTS_ENCAPSULATED_H
+
+
+#include <glib-object.h>
+
+
+#include "../content.h"
+
+
+
+#define G_TYPE_ENCAPS_CONTENT            (g_encaps_content_get_type())
+#define G_ENCAPS_CONTENT(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ENCAPS_CONTENT, GEncapsContent))
+#define G_IS_ENCAPS_CONTENT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ENCAPS_CONTENT))
+#define G_ENCAPS_CONTENT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ENCAPS_CONTENT, GEncapsContentClass))
+#define G_IS_ENCAPS_CONTENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ENCAPS_CONTENT))
+#define G_ENCAPS_CONTENT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ENCAPS_CONTENT, GEncapsContentClass))
+
+
+/* Contenu de issu d'un contenu plus global (instance) */
+typedef struct _GEncapsContent GEncapsContent;
+
+/* Contenu de issu d'un contenu plus global (classe) */
+typedef struct _GEncapsContentClass GEncapsContentClass;
+
+
+/* Indique le type défini par la GLib pour les contenus encapsulés. */
+GType g_encaps_content_get_type(void);
+
+/* Charge en mémoire un contenu binaire encapsulé. */
+GBinContent *g_encaps_content_new(GBinContent *, const char *, GBinContent *);
+
+/* Charge en mémoire un contenu encapsulé à partir d'XML. */
+GBinContent *g_encaps_content_new_from_xml(xmlXPathContextPtr, const char *, const char *);
+
+
+
+#endif  /* _ANALYSIS_CONTENTS_ENCAPSULATED_H */
diff --git a/src/analysis/contents/file.c b/src/analysis/contents/file.c
index 3519be3..31acb6f 100644
--- a/src/analysis/contents/file.c
+++ b/src/analysis/contents/file.c
@@ -354,14 +354,18 @@ GBinContent *g_file_content_new_from_xml(xmlXPathContextPtr context, const char
 
     /* Chargement */
 
-    absolute = build_absolute_filename(base, filename);
+    if (filename != NULL)
+    {
+        absolute = build_absolute_filename(base, filename);
 
-    if (filename != NULL) free(filename);
+        free(filename);
+
+        if (absolute != NULL)
+        {
+            result = g_file_content_new(absolute);
+            free(absolute);
+        }
 
-    if (absolute != NULL)
-    {
-        result = g_file_content_new(absolute);
-        free(absolute);
     }
 
     return result;
@@ -428,11 +432,10 @@ static bool g_file_content_save(const GFileContent *content, xmlDocPtr xdoc, xml
     char *access;                           /* Chemin d'accès à un élément */
     char *relative;                         /* Chemin d'accès relatif      */
 
-    result = true;
-
     /* Type */
 
-    result &= add_string_attribute_to_node(xdoc, context, path, "type", "file");
+    result = add_string_attribute_to_node(xdoc, context, path, "type", "file");
+    if (!result) goto gfcs_exit;
 
     /* Nom du fichier associé */
 
@@ -441,11 +444,13 @@ static bool g_file_content_save(const GFileContent *content, xmlDocPtr xdoc, xml
 
     relative = build_relative_filename(base, content->filename);
 
-    result &= add_content_to_node(xdoc, context, access, relative);
+    result = add_content_to_node(xdoc, context, access, relative);
 
     free(relative);
     free(access);
 
+ gfcs_exit:
+
     return result;
 
 }
@@ -530,19 +535,26 @@ static void g_file_content_compute_end_pos(const GFileContent *content, vmpa2t *
 
 static bool g_file_content_seek(const GFileContent *content, vmpa2t *addr, phys_t length)
 {
+    bool result;                            /* Bilan à retourner           */
     phys_t offset;                          /* Emplacement de départ       */
 
+    result = false;
+
     offset = get_phy_addr(addr);
 
     if (length > get_mrange_length(&content->range))
-        return false;
+        goto gfcs_done;
 
     if (offset > (get_mrange_length(&content->range) - length))
-        return false;
+        goto gfcs_done;
 
     advance_vmpa(addr, length);
 
-    return true;
+    result = true;
+
+ gfcs_done:
+
+    return result;
 
 }
 
@@ -563,6 +575,7 @@ static bool g_file_content_seek(const GFileContent *content, vmpa2t *addr, phys_
 
 static const bin_t *g_file_content_get_raw_access(const GFileContent *content, vmpa2t *addr, phys_t length)
 {
+    const bin_t *result;                    /* Données utiles à renvoyer   */
     phys_t offset;                          /* Emplacement de départ       */
     bool allowed;                           /* Capacité d'avancer ?        */
 
@@ -570,7 +583,9 @@ static const bin_t *g_file_content_get_raw_access(const GFileContent *content, v
 
     allowed = g_file_content_seek(content, addr, length);
 
-    return (allowed ? &content->data[offset] : NULL);
+    result = (allowed ? &content->data[offset] : NULL);
+
+    return result;
 
 }
 
diff --git a/src/analysis/contents/file.h b/src/analysis/contents/file.h
index e1fc7a9..b68d466 100644
--- a/src/analysis/contents/file.h
+++ b/src/analysis/contents/file.h
@@ -32,12 +32,12 @@
 
 
 
-#define G_TYPE_FILE_CONTENT             (g_file_content_get_type())
-#define G_FILE_CONTENT(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_FILE_CONTENT, GFileContent))
-#define G_IS_FILE_CONTENT(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_FILE_CONTENT))
-#define G_FILE_CONTENT_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_FILE_CONTENT, GFileContentClass))
-#define G_IS_FILE_CONTENT_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_FILE_CONTENT))
-#define G_FILE_CONTENT_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_FILE_CONTENT, GFileContentClass))
+#define G_TYPE_FILE_CONTENT            (g_file_content_get_type())
+#define G_FILE_CONTENT(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_FILE_CONTENT, GFileContent))
+#define G_IS_FILE_CONTENT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_FILE_CONTENT))
+#define G_FILE_CONTENT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_FILE_CONTENT, GFileContentClass))
+#define G_IS_FILE_CONTENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_FILE_CONTENT))
+#define G_FILE_CONTENT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_FILE_CONTENT, GFileContentClass))
 
 
 /* Contenu de données binaires issues d'un fichier (instance) */
diff --git a/src/analysis/contents/memory.c b/src/analysis/contents/memory.c
new file mode 100644
index 0000000..a7bdbea
--- /dev/null
+++ b/src/analysis/contents/memory.c
@@ -0,0 +1,758 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * memory.c - chargement de données binaires à partir de la mémoire
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 Chrysalide.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "memory.h"
+
+
+#include <assert.h>
+#include <malloc.h>
+#include <string.h>
+#include <unistd.h>
+
+
+#include <i18n.h>
+
+
+#include "file.h"
+#include "../content-int.h"
+#include "../../common/extstr.h"
+#include "../../common/io.h"
+
+
+
+/* Contenu de données binaires résidant en mémoire (instance) */
+struct _GMemoryContent
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    char *storage;                          /* Conservation des données    */
+    GBinContent *backend;                   /* Exploitation des données    */
+
+};
+
+/* Contenu de données binaires résidant en mémoire (classe) */
+struct _GMemoryContentClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+};
+
+
+/* Initialise la classe des contenus de données en mémoire. */
+static void g_memory_content_class_init(GMemoryContentClass *);
+
+/* Initialise une instance de contenu de données en mémoire. */
+static void g_memory_content_init(GMemoryContent *);
+
+/* Procède à l'initialisation de l'interface de lecture. */
+static void g_memory_content_interface_init(GBinContentInterface *);
+
+/* Supprime toutes les références externes. */
+static void g_memory_content_dispose(GMemoryContent *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_memory_content_finalize(GMemoryContent *);
+
+/* Fournit le nom associé au contenu binaire. */
+static const 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 *);
+
+/* Fournit une empreinte unique (SHA256) pour les données. */
+static void g_memory_content_compute_checksum(GMemoryContent *, GChecksum *);
+
+/* Détermine le nombre d'octets lisibles. */
+static phys_t g_memory_content_compute_size(const GMemoryContent *);
+
+/* Détermine la position finale d'un contenu. */
+static void g_memory_content_compute_end_pos(const GMemoryContent *, vmpa2t *);
+
+/* Avance la tête de lecture d'une certaine quantité de données. */
+static bool g_memory_content_seek(const GMemoryContent *, vmpa2t *, phys_t);
+
+/* Donne accès à une portion des données représentées. */
+static const bin_t *g_memory_content_get_raw_access(const GMemoryContent *, vmpa2t *, phys_t);
+
+/* Fournit une portion des données représentées. */
+static bool g_memory_content_read_raw(const GMemoryContent *, vmpa2t *, phys_t, bin_t *);
+
+/* Lit un nombre non signé sur quatre bits. */
+static bool g_memory_content_read_u4(const GMemoryContent *, vmpa2t *, bool *, uint8_t *);
+
+/* Lit un nombre non signé sur un octet. */
+static bool g_memory_content_read_u8(const GMemoryContent *, vmpa2t *, uint8_t *);
+
+/* Lit un nombre non signé sur deux octets. */
+static bool g_memory_content_read_u16(const GMemoryContent *, vmpa2t *, SourceEndian, uint16_t *);
+
+/* Lit un nombre non signé sur quatre octets. */
+static bool g_memory_content_read_u32(const GMemoryContent *, vmpa2t *, SourceEndian, uint32_t *);
+
+/* Lit un nombre non signé sur huit octets. */
+static bool g_memory_content_read_u64(const GMemoryContent *, vmpa2t *, SourceEndian, uint64_t *);
+
+/* Lit un nombre non signé encodé au format LEB128. */
+static bool g_memory_content_read_uleb128(const GMemoryContent *, vmpa2t *, uleb128_t *);
+
+/* Lit un nombre signé encodé au format LEB128. */
+static bool g_memory_content_read_leb128(const GMemoryContent *, vmpa2t *, leb128_t *);
+
+
+
+/* Indique le type défini par la GLib pour les contenus de données en mémoire. */
+G_DEFINE_TYPE_WITH_CODE(GMemoryContent, g_memory_content, G_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE(G_TYPE_BIN_CONTENT, g_memory_content_interface_init));
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des contenus de données en mémoire.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_memory_content_class_init(GMemoryContentClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_memory_content_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_memory_content_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = instance à initialiser.                            *
+*                                                                             *
+*  Description : Initialise une instance de contenu de données en mémoire.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_memory_content_init(GMemoryContent *content)
+{
+    content->storage = NULL;
+    content->backend = NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iface = interface GLib à initialiser.                        *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de lecture.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_memory_content_interface_init(GBinContentInterface *iface)
+{
+    iface->describe = (describe_content_fc)g_memory_content_describe;
+
+    iface->save = (save_content_fc)g_memory_content_save;
+
+    iface->compute_checksum = (compute_checksum_fc)g_memory_content_compute_checksum;
+
+    iface->compute_size = (compute_size_fc)g_memory_content_compute_size;
+    iface->compute_end_pos = (compute_end_pos_fc)g_memory_content_compute_end_pos;
+
+    iface->seek = (seek_fc)g_memory_content_seek;
+
+    iface->get_raw_access = (get_raw_access_fc)g_memory_content_get_raw_access;
+
+    iface->read_raw = (read_raw_fc)g_memory_content_read_raw;
+    iface->read_u4 = (read_u4_fc)g_memory_content_read_u4;
+    iface->read_u8 = (read_u8_fc)g_memory_content_read_u8;
+    iface->read_u16 = (read_u16_fc)g_memory_content_read_u16;
+    iface->read_u32 = (read_u32_fc)g_memory_content_read_u32;
+    iface->read_u64 = (read_u64_fc)g_memory_content_read_u64;
+
+    iface->read_uleb128 = (read_uleb128_fc)g_memory_content_read_uleb128;
+    iface->read_leb128 = (read_leb128_fc)g_memory_content_read_leb128;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_memory_content_dispose(GMemoryContent *content)
+{
+    if (content->backend)
+        g_object_unref(G_OBJECT(content->backend));
+
+    G_OBJECT_CLASS(g_memory_content_parent_class)->dispose(G_OBJECT(content));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_memory_content_finalize(GMemoryContent *content)
+{
+    if (content->storage != NULL)
+    {
+        unlink(content->storage);
+        free(content->storage);
+    }
+
+    G_OBJECT_CLASS(g_memory_content_parent_class)->finalize(G_OBJECT(content));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : data = données du contenu volatile.                          *
+*                size = quantité de ces données.                              *
+*                                                                             *
+*  Description : Charge en mémoire le contenu de données brutes.              *
+*                                                                             *
+*  Retour      : Représentation de contenu à manipuler ou NULL en cas d'échec.*
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBinContent *g_memory_content_new(bin_t *data, phys_t size)
+{
+    GMemoryContent *result;                 /* Structure à retourner      */
+    int fd;                                 /* Descripteur du fichier      */
+    bool status;                            /* Bilan des écritures         */
+
+    result = g_object_new(G_TYPE_MEMORY_CONTENT, NULL);
+
+    fd = make_tmp_file("memcnt", &result->storage);
+    if (fd == -1) goto gmcn_error;
+
+    status = safe_write(fd, data, size);
+
+    close(fd);
+
+    if (!status) goto gmcn_error;
+
+    result->backend = g_file_content_new(result->storage);
+    if (result->backend == NULL) goto gmcn_error;
+
+    return G_BIN_CONTENT(result);
+
+ gmcn_error:
+
+    g_object_unref(G_OBJECT(result));
+
+    return NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : context = contexte pour les recherches XPath.                *
+*                path    = chemin d'accès au noeud XML à lire.                *
+*                base    = référence au lieu d'enregistrement du projet.      *
+*                                                                             *
+*  Description : Charge des données à laisser en mémoire à partir d'XML.      *
+*                                                                             *
+*  Retour      : Adresse de la représentation ou NULL en cas d'échec.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBinContent *g_memory_content_new_from_xml(xmlXPathContextPtr context, const char *path, const char *base)
+{
+    GBinContent *result;                    /* Adresse à retourner         */
+    char *access;                           /* Chemin pour une sous-config.*/
+    char *encoded;                          /* Données encodées à charger  */
+    guchar *data;                           /* Données brutes à charger    */
+    gsize size;                             /* Quantité de ces données     */
+
+    result = NULL;
+
+    /* Chemin du fichier à retrouver */
+
+    access = strdup(path);
+    access = stradd(access, "/Data");
+
+    encoded = get_node_text_value(context, access);
+
+    free(access);
+
+    /* Chargement */
+
+    if (encoded != NULL)
+    {
+        data = g_base64_decode(encoded, &size);
+
+        free(encoded);
+
+        if (data != NULL)
+        {
+            result = g_memory_content_new(data, size);
+            g_free(data);
+        }
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = contenu binaire à 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 const char *g_memory_content_describe(const GMemoryContent *content, bool full)
+{
+    const char *result;                     /* Description à retourner     */
+
+    result = "In-memory content";
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = contenu binaire à traiter.                         *
+*                xdoc    = structure XML en cours d'édition.                  *
+*                context = contexte à utiliser pour les recherches.           *
+*                path    = chemin d'accès réservé au binaire.                 *
+*                base    = référence au lieu d'enregistrement du projet.      *
+*                                                                             *
+*  Description : Ecrit une sauvegarde de contenu binaire dans un fichier XML. *
+*                                                                             *
+*  Retour      : true si l'opération a bien tourné, false sinon.              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_memory_content_save(const GMemoryContent *content, xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path, const char *base)
+{
+    bool result;                            /* Bilan à faire remonter      */
+    char *access;                           /* Chemin d'accès à un élément */
+    vmpa2t start;                           /* Tête de lecture initiale    */
+    phys_t length;                          /* Nombre d'octets disponibles */
+    const bin_t *data;                      /* Données brutes à sauvegarder*/
+    gchar *encoded;                         /* Données encodées à écrire   */
+
+    /* Type */
+
+    result = add_string_attribute_to_node(xdoc, context, path, "type", "memory");
+    if (!result) goto gmcs_exit;
+
+    /* Données en mémoire associées */
+
+    access = strdup(path);
+    access = stradd(access, "/Data");
+
+    init_vmpa(&start, 0, VMPA_NO_VIRTUAL);
+
+    length = g_binary_content_compute_size(content->backend);
+
+    data = g_binary_content_get_raw_access(content->backend, &start, length);
+    assert(data != NULL);
+
+    encoded = g_base64_encode((const guchar *)data, length);
+    assert(encoded != NULL);
+
+    result = add_content_to_node(xdoc, context, access, encoded);
+
+    g_free(encoded);
+    free(access);
+
+ gmcs_exit:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content  = contenu binaire à venir lire.                     *
+*                checksum = empreinte de zone mémoire à compléter.            *
+*                                                                             *
+*  Description : Calcule une empreinte unique (SHA256) pour les données.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_memory_content_compute_checksum(GMemoryContent *content, GChecksum *checksum)
+{
+    GBinContentIface *iface;                /* Interface utilisée          */
+
+    iface = G_BIN_CONTENT_GET_IFACE(content->backend);
+
+    iface->compute_checksum(content->backend, checksum);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = contenu binaire à venir lire.                      *
+*                                                                             *
+*  Description : Détermine le nombre d'octets lisibles.                       *
+*                                                                             *
+*  Retour      : Quantité représentée.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static phys_t g_memory_content_compute_size(const GMemoryContent *content)
+{
+    phys_t result;                          /* Quantité trouvée à retourner*/
+
+    result = g_binary_content_compute_size(content->backend);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = contenu binaire à venir lire.                      *
+*                pos     = position finale (exclusive). [OUT]                 *
+*                                                                             *
+*  Description : Détermine la position finale d'un contenu.                   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_memory_content_compute_end_pos(const GMemoryContent *content, vmpa2t *pos)
+{
+    g_binary_content_compute_end_pos(content->backend, pos);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = contenu binaire à venir lire.                      *
+*                addr    = position de la tête de lecture.                    *
+*                length  = quantité d'octets à provisionner.                  *
+*                                                                             *
+*  Description : Avance la tête de lecture d'une certaine quantité de données.*
+*                                                                             *
+*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_memory_content_seek(const GMemoryContent *content, vmpa2t *addr, phys_t length)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = g_binary_content_seek(content->backend, addr, length);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = contenu binaire à venir lire.                      *
+*                addr    = position de la tête de lecture.                    *
+*                length  = quantité d'octets à lire.                          *
+*                                                                             *
+*  Description : Donne accès à une portion des données représentées.          *
+*                                                                             *
+*  Retour      : Pointeur vers les données à lire ou NULL en cas d'échec.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static const bin_t *g_memory_content_get_raw_access(const GMemoryContent *content, vmpa2t *addr, phys_t length)
+{
+    const bin_t *result;                    /* Données utiles à renvoyer   */
+
+    result = g_binary_content_get_raw_access(content->backend, addr, length);
+
+    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 g_memory_content_read_raw(const GMemoryContent *content, vmpa2t *addr, phys_t length, bin_t *out)
+{
+    bool result;                            /* Bilan à remonter            */
+
+    result = g_binary_content_read_raw(content->backend, addr, length, out);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = contenu binaire à venir lire.                      *
+*                addr    = position de la tête de lecture.                    *
+*                low     = position éventuelle des 4 bits visés. [OUT]        *
+*                val     = lieu d'enregistrement de la lecture. [OUT]         *
+*                                                                             *
+*  Description : Lit un nombre non signé sur quatre bits.                     *
+*                                                                             *
+*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_memory_content_read_u4(const GMemoryContent *content, vmpa2t *addr, bool *low, uint8_t *val)
+{
+    bool result;                            /* Bilan de lecture à renvoyer */
+
+    result = g_binary_content_read_u4(content->backend, addr, low, val);
+
+    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 g_memory_content_read_u8(const GMemoryContent *content, vmpa2t *addr, uint8_t *val)
+{
+    bool result;                            /* Bilan de lecture à renvoyer */
+
+    result = g_binary_content_read_u8(content->backend, addr, val);
+
+    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 g_memory_content_read_u16(const GMemoryContent *content, vmpa2t *addr, SourceEndian endian, uint16_t *val)
+{
+    bool result;                            /* Bilan de lecture à renvoyer */
+
+    result = g_binary_content_read_u16(content->backend, addr, endian, val);
+
+    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 g_memory_content_read_u32(const GMemoryContent *content, vmpa2t *addr, SourceEndian endian, uint32_t *val)
+{
+    bool result;                            /* Bilan de lecture à renvoyer */
+
+    result = g_binary_content_read_u32(content->backend, addr, endian, val);
+
+    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 g_memory_content_read_u64(const GMemoryContent *content, vmpa2t *addr, SourceEndian endian, uint64_t *val)
+{
+    bool result;                            /* Bilan de lecture à renvoyer */
+
+    result = g_binary_content_read_u64(content->backend, addr, endian, val);
+
+    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é encodé au format LEB128.             *
+*                                                                             *
+*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_memory_content_read_uleb128(const GMemoryContent *content, vmpa2t *addr, uleb128_t *val)
+{
+    bool result;                            /* Bilan de lecture à renvoyer */
+
+    result = g_binary_content_read_uleb128(content->backend, addr, val);
+
+    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 signé encodé au format LEB128.                 *
+*                                                                             *
+*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_memory_content_read_leb128(const GMemoryContent *content, vmpa2t *addr, leb128_t *val)
+{
+    bool result;                            /* Bilan de lecture à renvoyer */
+
+    result = g_binary_content_read_leb128(content->backend, addr, val);
+
+    return result;
+
+}
diff --git a/src/analysis/contents/memory.h b/src/analysis/contents/memory.h
new file mode 100644
index 0000000..769282c
--- /dev/null
+++ b/src/analysis/contents/memory.h
@@ -0,0 +1,61 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * memory.h - prototypes pour le chargement de données binaires à partir de la mémoire
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 Chrysalide.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_CONTENTS_MEMORY_H
+#define _ANALYSIS_CONTENTS_MEMORY_H
+
+
+#include <glib-object.h>
+
+
+#include "../content.h"
+
+
+
+#define G_TYPE_MEMORY_CONTENT            (g_memory_content_get_type())
+#define G_MEMORY_CONTENT(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_MEMORY_CONTENT, GMemoryContent))
+#define G_IS_MEMORY_CONTENT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_MEMORY_CONTENT))
+#define G_MEMORY_CONTENT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_MEMORY_CONTENT, GMemoryContentClass))
+#define G_IS_MEMORY_CONTENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_MEMORY_CONTENT))
+#define G_MEMORY_CONTENT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_MEMORY_CONTENT, GMemoryContentClass))
+
+
+/* Contenu de données binaires résidant en mémoire (instance) */
+typedef struct _GMemoryContent GMemoryContent;
+
+/* Contenu de données binaires résidant en mémoire (classe) */
+typedef struct _GMemoryContentClass GMemoryContentClass;
+
+
+/* Indique le type défini par la GLib pour les contenus de données en mémoire. */
+GType g_memory_content_get_type(void);
+
+/* Charge en mémoire le contenu de données brutes. */
+GBinContent *g_memory_content_new(bin_t *, phys_t);
+
+/* Charge des données à laisser en mémoire à partir d'XML. */
+GBinContent *g_memory_content_new_from_xml(xmlXPathContextPtr, const char *, const char *);
+
+
+
+#endif  /* _ANALYSIS_CONTENTS_MEMORY_H */
diff --git a/src/common/io.c b/src/common/io.c
index 85be44c..457e3c5 100644
--- a/src/common/io.c
+++ b/src/common/io.c
@@ -363,7 +363,10 @@ int make_tmp_file(const char *base, char **filename)
     }
 
     if (result == -1)
+    {
         free(*filename);
+        *filename = NULL;
+    }
 
     return result;
 
diff --git a/tests/analysis/contents/memory.py b/tests/analysis/contents/memory.py
new file mode 100644
index 0000000..e8ba6b5
--- /dev/null
+++ b/tests/analysis/contents/memory.py
@@ -0,0 +1,65 @@
+#!/usr/bin/python3-dbg
+# -*- coding: utf-8 -*-
+
+
+# Tests minimalistes pour valider l'intégration des contenus résidant
+# en mémoire depuis Python.
+
+
+from chrysacase import ChrysalideTestCase
+from pychrysalide.analysis.contents import MemoryContent
+from pychrysalide.arch import vmpa, mrange
+
+
+class TestMemoryContent(ChrysalideTestCase):
+    """TestCase for analysis.contents.MemoryContent."""
+
+    def testSimpleAccess(self):
+        """Check valid accesses to memory content."""
+
+        data  = b'\x01\x02\x03\x04'
+        data += b'\x05\x06\x07\x08'
+        data += b'\x11\x12\x13\x00'
+        data += b'\x15\x16\x17\x18'
+        data += b'\x21\x22\x23\x24'
+        data += b'\x25\x26\x27\x28'
+        data += b'\x31\x32\x00\x34'
+        data += b'\x35\x36\x37\x38'
+
+        cnt = MemoryContent(data)
+
+        start = vmpa(4, vmpa.VMPA_NO_VIRTUAL)
+
+        val = cnt.read_u8(start)
+        self.assertEqual(val, 0x05)
+
+        val = cnt.read_u8(start)
+        self.assertEqual(val, 0x06)
+
+        start = vmpa(14, vmpa.VMPA_NO_VIRTUAL)
+
+        val = cnt.read_u16(start, vmpa.SRE_LITTLE)
+        self.assertEqual(val, 0x1817)
+
+        start = vmpa(10, vmpa.VMPA_NO_VIRTUAL)
+
+        val = cnt.read_u32(start, vmpa.SRE_LITTLE)
+        self.assertEqual(val, 0x16150013)
+
+
+    def testWrongAccess(self):
+        """Check invalid accesses to memory content."""
+
+        data = b'\x35'
+
+        cnt = MemoryContent(data)
+
+        with self.assertRaisesRegex(Exception, 'Invalid read access.'):
+
+            start = vmpa(1, vmpa.VMPA_NO_VIRTUAL)
+            val = cnt.read_u8(start)
+
+        with self.assertRaisesRegex(Exception, 'Invalid read access.'):
+
+            start = vmpa(0, vmpa.VMPA_NO_VIRTUAL)
+            val = cnt.read_u16(start, vmpa.SRE_LITTLE)
-- 
cgit v0.11.2-87-g4458