From ea090774bf3b5849422de9af8c294b3e9d00105b Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 18 Nov 2018 23:21:14 +0100
Subject: Extended the Python bindings dealing with code blocks.

---
 configure.ac                                     |   1 +
 plugins/pychrysalide/analysis/Makefile.am        |   3 +-
 plugins/pychrysalide/analysis/block.c            | 292 +++++++++++++++++------
 plugins/pychrysalide/analysis/block.h            |  20 +-
 plugins/pychrysalide/analysis/disass/Makefile.am |  21 ++
 plugins/pychrysalide/analysis/disass/block.c     | 127 ++++++++++
 plugins/pychrysalide/analysis/disass/block.h     |  45 ++++
 plugins/pychrysalide/analysis/disass/module.c    | 100 ++++++++
 plugins/pychrysalide/analysis/disass/module.h    |  42 ++++
 plugins/pychrysalide/analysis/module.c           |   6 +-
 plugins/pychrysalide/analysis/routine.c          |   2 +-
 src/analysis/block.c                             |   2 +-
 src/analysis/block.h                             |   2 +-
 src/analysis/disass/block.c                      |   2 +-
 tests/analysis/disass/Makefile                   |  10 +
 tests/analysis/disass/__init__.py                |   0
 tests/analysis/disass/block.py                   |  74 ++++++
 tests/analysis/disass/hello.c                    |  12 +
 18 files changed, 674 insertions(+), 87 deletions(-)
 create mode 100644 plugins/pychrysalide/analysis/disass/Makefile.am
 create mode 100644 plugins/pychrysalide/analysis/disass/block.c
 create mode 100644 plugins/pychrysalide/analysis/disass/block.h
 create mode 100644 plugins/pychrysalide/analysis/disass/module.c
 create mode 100644 plugins/pychrysalide/analysis/disass/module.h
 create mode 100644 tests/analysis/disass/Makefile
 create mode 100644 tests/analysis/disass/__init__.py
 create mode 100644 tests/analysis/disass/block.py
 create mode 100644 tests/analysis/disass/hello.c

diff --git a/configure.ac b/configure.ac
index bc1bd69..d3ba94d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -370,6 +370,7 @@ AC_CONFIG_FILES([Makefile
                  plugins/pychrysalide/analysis/contents/Makefile
                  plugins/pychrysalide/analysis/db/Makefile
                  plugins/pychrysalide/analysis/db/items/Makefile
+                 plugins/pychrysalide/analysis/disass/Makefile
                  plugins/pychrysalide/analysis/types/Makefile
                  plugins/pychrysalide/arch/Makefile
                  plugins/pychrysalide/common/Makefile
diff --git a/plugins/pychrysalide/analysis/Makefile.am b/plugins/pychrysalide/analysis/Makefile.am
index 3d7ac51..0405243 100644
--- a/plugins/pychrysalide/analysis/Makefile.am
+++ b/plugins/pychrysalide/analysis/Makefile.am
@@ -16,6 +16,7 @@ libpychrysaanalysis_la_SOURCES =		\
 libpychrysaanalysis_la_LIBADD =			\
 	contents/libpychrysaanalysiscontents.la	\
 	db/libpychrysaanalysisdb.la			\
+	disass/libpychrysaanalysisdisass.la	\
 	types/libpychrysaanalysistypes.la
 
 libpychrysaanalysis_la_LDFLAGS = 
@@ -31,4 +32,4 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJE
 
 AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
 
-SUBDIRS = contents db types
+SUBDIRS = contents db disass types
diff --git a/plugins/pychrysalide/analysis/block.c b/plugins/pychrysalide/analysis/block.c
index 010efd4..a091a6d 100644
--- a/plugins/pychrysalide/analysis/block.c
+++ b/plugins/pychrysalide/analysis/block.c
@@ -33,141 +33,273 @@
 
 #include "../access.h"
 #include "../helpers.h"
+#include "../arch/vmpa.h"
 
 
-//////////////////////////////////////////////////////////
-#if 0
 
+/* ----------------------------- BLOC DE CODE GENERIQUE ----------------------------- */
+
+
+/* Indique l'indice d'intégration du bloc dans une liste. */
+static PyObject *py_code_block_get_index(PyObject *, void *);
+
+/* Fournit le rang du bloc de code dans le flot d'exécution. */
+static PyObject *py_code_block_get_rank(PyObject *, void *);
 
-/* Permet la jonction entre C et Python lors des visites */
-typedef struct _py_block_vdata
-{
-    PyObject *func;                         /* Fonction à appeler          */
-    PyObject *user;                         /* Donnée à faire suivre       */
 
-} py_block_vdata;
 
+/* ------------------------- REGROUPEMENT EN LISTE DE BLOCS ------------------------- */
 
-/* Parcourt le bloc d'instructions dans un ordre donné. */
-static bool py_block_visitor_glue(GInstrBlock *, BlockVisitOrder, py_block_vdata *);
 
-/* Parcourt tous les blocs d'instructions dans un ordre donné. */
-static PyObject *py_instructions_block_visit(PyObject *, PyObject *);
+/* Recherche un bloc de code débutant à une adresse donnée. */
+static PyObject *py_block_list_find_by_starting_addr(PyObject *, PyObject *);
 
-/* Fournit l'ensemble contenant les blocs liés. */
-static PyObject *py_instructions_block_get_links_block(PyObject *, PyObject *);
+/* Fournit l'ensemble des blocs de code inclus dans une liste. */
+static PyObject *py_block_list_get_items(PyObject *, void *);
 
-/* Définit les constantes pour les blocs basiques. */
-static bool py_instructions_block_define_constants(PyTypeObject *);
 
 
+/* ---------------------------------------------------------------------------------- */
+/*                               BLOC DE CODE GENERIQUE                               */
+/* ---------------------------------------------------------------------------------- */
+
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : block = bloc d'instructions concerné par la visite.          *
-*                order = indication sur la position dans le parcours.         *
-*                data  = donnée utilisateur à associer au parcours.           *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
 *                                                                             *
-*  Description : Parcourt le bloc d'instructions dans un ordre donné.         *
+*  Description : Indique l'indice d'intégration du bloc dans une liste.       *
 *                                                                             *
-*  Retour      : true si le parcours a été jusqu'à son terme, false sinon.    *
+*  Retour      : Indice valide dans une liste.                                *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static bool py_block_visitor_glue(GInstrBlock *block, BlockVisitOrder order, py_block_vdata *data)
+static PyObject *py_code_block_get_index(PyObject *self, void *closure)
 {
-    bool result;                            /* Bilan à retourner           */
-    PyObject *args;                         /* Arguments pour l'appel      */
-    PyObject *value;                        /* Retour obtenu               */
+    PyObject *result;                       /* Trouvailles à retourner     */
+    GCodeBlock *block;                      /* Bloc de code à consulter    */
+    size_t value;                           /* Valeur à transmettre        */
+
+    block = G_CODE_BLOCK(pygobject_get(self));
 
-    Py_INCREF(data->user);
+    value = g_code_block_get_index(block);
 
-    args = PyTuple_New(3);
-    PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(block)));
-    PyTuple_SetItem(args, 1, PyLong_FromLong(order));
-    PyTuple_SetItem(args, 2, data->user);
+    result = PyLong_FromSize_t(value);
 
-    value = _run_python_method(data->func, args);
-    result = (value == Py_True);
+    return result;
 
-    Py_XDECREF(value);
-    Py_DECREF(args);
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Fournit le rang du bloc de code dans le flot d'exécution.    *
+*                                                                             *
+*  Retour      : Indice supérieur ou égal à zéro.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_code_block_get_rank(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Trouvailles à retourner     */
+    GCodeBlock *block;                      /* Bloc de code à consulter    */
+    size_t value;                           /* Valeur à transmettre        */
+
+    block = G_CODE_BLOCK(pygobject_get(self));
+
+    value = g_code_block_get_rank(block);
+
+    result = PyLong_FromSize_t(value);
 
     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_code_block_type(void)
+{
+    static PyMethodDef py_code_block_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_code_block_getseters[] = {
+        {
+            "index", py_code_block_get_index, NULL,
+            "Index of the code block in the parent list, if any.", NULL
+        },
+        {
+            "rank", py_code_block_get_rank, NULL,
+            "Rang of the code block.", NULL
+        },
+        { NULL }
+    };
+
+    static PyTypeObject py_code_block_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.CodeBlock",
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = "PyChrysalide code block",
+
+        .tp_methods     = py_code_block_methods,
+        .tp_getset      = py_code_block_getseters,
+
+    };
+
+    return &py_code_block_type;
+
+}
+
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : self = classe représentant un binaire.                       *
-*                args = arguments fournis à l'appel.                          *
+*  Paramètres  : -                                                            *
 *                                                                             *
-*  Description : Parcourt tous les blocs d'instructions dans un ordre donné.  *
+*  Description : Prend en charge l'objet 'pychrysalide.analysis.CodeBlock'.   *
 *                                                                             *
-*  Retour      : True si le parcours a été jusqu'à son terme, False sinon.    *
+*  Retour      : Bilan de l'opération.                                        *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static PyObject *py_instructions_block_visit(PyObject *self, PyObject *args)
+bool ensure_python_code_block_is_registered(void)
 {
-    PyObject *result;                       /* Conclusion à retourner      */
-    py_block_vdata data;                    /* Transition entre C et Python*/
-    int ret;                                /* Bilan de lecture des args.  */
-    GInstrBlock *block;                     /* Point de départ des visites */
-    bool status;                            /* Bilan du parcours           */
+    PyTypeObject *type;                     /* Type Python 'InstrBlock'    */
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
 
-    ret = PyArg_ParseTuple(args, "OO", &data.func, &data.user);
-    if (!ret) Py_RETURN_NONE;
+    type = get_python_code_block_type();
 
-    if (PyCallable_Check(data.func) != 1) return NULL;
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.analysis");
 
-    block = G_INSTR_BLOCK(pygobject_get(self));
-    status = g_instr_block_visit(block, (instr_block_visitor_cb)py_block_visitor_glue, &data);
+        dict = PyModule_GetDict(module);
 
-    result = (status ? Py_True : Py_False);
-    Py_INCREF(result);
+        if (!register_class_for_pygobject(dict, G_TYPE_CODE_BLOCK, type, &PyGObject_Type))
+            return false;
 
-    return result;
+    }
+
+    return true;
 
 }
 
 
+
+/* ---------------------------------------------------------------------------------- */
+/*                           REGROUPEMENT EN LISTE DE BLOCS                           */
+/* ---------------------------------------------------------------------------------- */
+
+
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : self = classe représentant un binaire.                       *
+*  Paramètres  : self = classe représentant une liste de blocs de code.       *
 *                args = arguments fournis à l'appel.                          *
 *                                                                             *
-*  Description : Fournit l'ensemble contenant les blocs liés.                 *
+*  Description : Recherche un bloc de code débutant à une adresse donnée.     *
 *                                                                             *
-*  Retour      : Bloc contenant les blocs liés au bloc.                       *
+*  Retour      : Bloc de code trouvé ou None si aucun.                        *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static PyObject *py_instructions_block_get_links_block(PyObject *self, PyObject *args)
+static PyObject *py_block_list_find_by_starting_addr(PyObject *self, PyObject *args)
 {
     PyObject *result;                       /* Conclusion à retourner      */
-    GInstrBlock *block;                     /* Point de départ des visites */
+    vmpa2t addr;                            /* Emplacement ciblé           */
+    int ret;                                /* Bilan de lecture des args.  */
+    GBlockList *list;                       /* Liste de blocs manipulée    */
+    GCodeBlock *found;                      /* Eventuel bloc trouvé        */
 
-    block = G_INSTR_BLOCK(pygobject_get(self));
+    ret = PyArg_ParseTuple(args, "O&", convert_any_to_vmpa, &addr);
+    if (!ret) return NULL;
 
-    block = g_instr_block_get_links_block(block);
+    list = G_BLOCK_LIST(pygobject_get(self));
 
-    result = pygobject_new(G_OBJECT(block));
+    found = g_block_list_find_by_starting_addr(list, &addr);
+
+    if (found != NULL)
+    {
+        result = pygobject_new(G_OBJECT(found));
+        g_object_unref(G_OBJECT(found));
+    }
+    else
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
 
     return result;
 
 }
 
 
-#endif
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Fournit l'ensemble des blocs de code inclus dans une liste.  *
+*                                                                             *
+*  Retour      : Liste de blocs de code.                                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_block_list_get_items(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Trouvailles à retourner     */
+    GBlockList *list;                       /* Liste de blocs manipulée    */
+    size_t count;                           /* Nombre de blocs présents    */
+    size_t i;                               /* Boucle de parcours          */
+    GCodeBlock *block;                      /* Bloc de code à intégrer     */
+
+    list = G_BLOCK_LIST(pygobject_get(self));
+
+    count = g_block_list_count_blocks(list);
+
+    result = PyTuple_New(count);
+
+    for (i = 0; i < count; i++)
+    {
+        block = g_block_list_get_block(list, i);
+
+        PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(block)));
+
+        g_object_unref(G_OBJECT(block));
+
+    }
+
+    return result;
+
+}
 
 
 /******************************************************************************
@@ -182,46 +314,50 @@ static PyObject *py_instructions_block_get_links_block(PyObject *self, PyObject
 *                                                                             *
 ******************************************************************************/
 
-PyTypeObject *get_python_instr_block_type(void)
+PyTypeObject *get_python_block_list_type(void)
 {
-    static PyMethodDef py_instr_block_methods[] = {
-#if 0
+    static PyMethodDef py_block_list_methods[] = {
         {
-            "get_links_block", (PyCFunction)py_instructions_block_get_links_block,
+            "find_by_starting_addr", py_block_list_find_by_starting_addr,
             METH_VARARGS,
-            "get_links_block($self, /)\n--\n\nGet the block containing all blocks linked to the caller."
+            "find_by_starting_addr($self, addr, /)\n--\n\nFind a code block starting at a given address."
         },
-#endif
         { NULL }
     };
 
-    static PyGetSetDef py_instr_block_getseters[] = {
+    static PyGetSetDef py_block_list_getseters[] = {
+        {
+            "items", py_block_list_get_items, NULL,
+            "All code blocks included in the list.", NULL
+        },
         { NULL }
     };
 
-    static PyTypeObject py_instr_block_type = {
+    static PyTypeObject py_block_list_type = {
 
         PyVarObject_HEAD_INIT(NULL, 0)
 
-        .tp_name        = "pychrysalide.analysis.InstrBlock",
+        .tp_name        = "pychrysalide.analysis.BlockList",
 
         .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
 
         .tp_doc         = "PyChrysalide basic block",
 
-        .tp_methods     = py_instr_block_methods,
-        .tp_getset      = py_instr_block_getseters,
+        .tp_methods     = py_block_list_methods,
+        .tp_getset      = py_block_list_getseters,
 
     };
 
-    return &py_instr_block_type;
+    return &py_block_list_type;
 
 }
+
+
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : -                                                            *
 *                                                                             *
-*  Description : Prend en charge l'objet 'pychrysalide.analysis.InstrBlock'.  *
+*  Description : Prend en charge l'objet 'pychrysalide.analysis.BlockList'.   *
 *                                                                             *
 *  Retour      : Bilan de l'opération.                                        *
 *                                                                             *
@@ -229,13 +365,13 @@ PyTypeObject *get_python_instr_block_type(void)
 *                                                                             *
 ******************************************************************************/
 
-bool ensure_python_instr_block_is_registered(void)
+bool ensure_python_block_list_is_registered(void)
 {
-    PyTypeObject *type;                     /* Type Python 'InstrBlock'    */
+    PyTypeObject *type;                     /* Type Python 'BlockList'     */
     PyObject *module;                       /* Module à recompléter        */
     PyObject *dict;                         /* Dictionnaire du module      */
 
-    type = get_python_instr_block_type();
+    type = get_python_block_list_type();
 
     if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
     {
@@ -243,7 +379,7 @@ bool ensure_python_instr_block_is_registered(void)
 
         dict = PyModule_GetDict(module);
 
-        if (!register_class_for_pygobject(dict, G_TYPE_CODE_BLOCK, type, &PyGObject_Type))
+        if (!register_class_for_pygobject(dict, G_TYPE_BLOCK_LIST, type, &PyGObject_Type))
             return false;
 
     }
diff --git a/plugins/pychrysalide/analysis/block.h b/plugins/pychrysalide/analysis/block.h
index 84ff679..8bae464 100644
--- a/plugins/pychrysalide/analysis/block.h
+++ b/plugins/pychrysalide/analysis/block.h
@@ -31,11 +31,25 @@
 
 
 
+/* ----------------------------- BLOC DE CODE GENERIQUE ----------------------------- */
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_code_block_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.CodeBlock'. */
+bool ensure_python_code_block_is_registered(void);
+
+
+
+/* ------------------------- REGROUPEMENT EN LISTE DE BLOCS ------------------------- */
+
+
 /* Fournit un accès à une définition de type à diffuser. */
-PyTypeObject *get_python_instr_block_type(void);
+PyTypeObject *get_python_block_list_type(void);
 
-/* Prend en charge l'objet 'pychrysalide.analysis.InstrBlock'. */
-bool ensure_python_instr_block_is_registered(void);
+/* Prend en charge l'objet 'pychrysalide.analysis.BlockList'. */
+bool ensure_python_block_list_is_registered(void);
 
 
 
diff --git a/plugins/pychrysalide/analysis/disass/Makefile.am b/plugins/pychrysalide/analysis/disass/Makefile.am
new file mode 100644
index 0000000..874ee6b
--- /dev/null
+++ b/plugins/pychrysalide/analysis/disass/Makefile.am
@@ -0,0 +1,21 @@
+
+noinst_LTLIBRARIES = libpychrysaanalysisdisass.la
+
+libpychrysaanalysisdisass_la_SOURCES =	\
+	block.h block.c						\
+	module.h module.c
+
+libpychrysaanalysisdisass_la_LDFLAGS = 
+
+
+devdir = $(includedir)/chrysalide-$(subdir)
+
+dev_HEADERS = $(libpychrysaanalysisdisass_la_SOURCES:%c=)
+
+
+AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+	-I$(top_srcdir)/src
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
+
+SUBDIRS = 
diff --git a/plugins/pychrysalide/analysis/disass/block.c b/plugins/pychrysalide/analysis/disass/block.c
new file mode 100644
index 0000000..6855368
--- /dev/null
+++ b/plugins/pychrysalide/analysis/disass/block.c
@@ -0,0 +1,127 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * block.c - équivalent Python du fichier "analysis/disass/block.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 "block.h"
+
+
+#include <pygobject.h>
+
+
+#include <analysis/disass/block.h>
+
+
+#include "../block.h"
+#include "../../access.h"
+#include "../../helpers.h"
+
+
+
+/* ------------------------ MISE EN PLACE DES BLOCS BASIQUES ------------------------ */
+
+
+
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                          MISE EN PLACE DES BLOCS BASIQUES                          */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit un accès à une définition de type à diffuser.        *
+*                                                                             *
+*  Retour      : Définition d'objet pour Python.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyTypeObject *get_python_basic_block_type(void)
+{
+    static PyMethodDef py_basic_block_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_basic_block_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_basic_block_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.disass.BasicBlock",
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = "PyChrysalide basic block",
+
+        .tp_methods     = py_basic_block_methods,
+        .tp_getset      = py_basic_block_getseters,
+
+    };
+
+    return &py_basic_block_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide.....BasicBlock'.       *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_python_basic_block_is_registered(void)
+{
+    PyTypeObject *type;                     /* Type Python 'InstrBlock'    */
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_basic_block_type();
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.analysis.disass");
+
+        dict = PyModule_GetDict(module);
+
+        if (!register_class_for_pygobject(dict, G_TYPE_BASIC_BLOCK, type, get_python_code_block_type()))
+            return false;
+
+    }
+
+    return true;
+
+}
diff --git a/plugins/pychrysalide/analysis/disass/block.h b/plugins/pychrysalide/analysis/disass/block.h
new file mode 100644
index 0000000..5f0fc78
--- /dev/null
+++ b/plugins/pychrysalide/analysis/disass/block.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * block.h - prototypes pour l'équivalent Python du fichier "analysis/disass/block.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_DISASS_BLOCK_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_DISASS_BLOCK_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* ------------------------ MISE EN PLACE DES BLOCS BASIQUES ------------------------ */
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_basic_block_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.disass.BasicBlock'. */
+bool ensure_python_basic_block_is_registered(void);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_DISASS_BLOCK_H */
diff --git a/plugins/pychrysalide/analysis/disass/module.c b/plugins/pychrysalide/analysis/disass/module.c
new file mode 100644
index 0000000..b02b031
--- /dev/null
+++ b/plugins/pychrysalide/analysis/disass/module.c
@@ -0,0 +1,100 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire disass en tant que module
+ *
+ * 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 "module.h"
+
+
+#include <assert.h>
+
+
+#include "block.h"
+#include "../../helpers.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : super = module dont la définition est à compléter.           *
+*                                                                             *
+*  Description : Ajoute le module 'analysis.disass' à un module Python.       *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool add_analysis_disass_module(PyObject *super)
+{
+    bool result;                            /* Bilan à retourner           */
+    PyObject *module;                       /* Sous-module mis en place    */
+
+    static PyModuleDef py_chrysalide_analysis_disass_module = {
+
+        .m_base = PyModuleDef_HEAD_INIT,
+
+        .m_name = "pychrysalide.analysis.disass",
+        .m_doc = "Python module for Chrysalide.analysis.disass",
+
+        .m_size = -1,
+
+    };
+
+    module = build_python_module(super, &py_chrysalide_analysis_disass_module);
+
+    result = (module != NULL);
+
+    if (!result)
+        Py_XDECREF(module);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Intègre les objets du module 'analysis.disass'.              *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool populate_analysis_disass_module(void)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = true;
+
+    if (result) result = ensure_python_basic_block_is_registered();
+
+    assert(result);
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/disass/module.h b/plugins/pychrysalide/analysis/disass/module.h
new file mode 100644
index 0000000..7f6b9bf
--- /dev/null
+++ b/plugins/pychrysalide/analysis/disass/module.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire disass en tant que module
+ *
+ * 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_DISASS_MODULE_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_DISASS_MODULE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Ajoute le module 'analysis.disass' à un module Python. */
+bool add_analysis_disass_module(PyObject *);
+
+/* Intègre les objets du module 'analysis.disass'. */
+bool populate_analysis_disass_module(void);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_DISASS_MODULE_H */
diff --git a/plugins/pychrysalide/analysis/module.c b/plugins/pychrysalide/analysis/module.c
index cafb4fa..cf0671e 100644
--- a/plugins/pychrysalide/analysis/module.c
+++ b/plugins/pychrysalide/analysis/module.c
@@ -39,6 +39,7 @@
 #include "variable.h"
 #include "contents/module.h"
 #include "db/module.h"
+#include "disass/module.h"
 #include "types/module.h"
 #include "../helpers.h"
 
@@ -78,6 +79,7 @@ bool add_analysis_module(PyObject *super)
 
     if (result) result = add_analysis_contents_module(module);
     if (result) result = add_analysis_db_module(module);
+    if (result) result = add_analysis_disass_module(module);
     if (result) result = add_analysis_types_module(module);
 
     if (!result)
@@ -107,7 +109,8 @@ bool populate_analysis_module(void)
     result = true;
 
     if (result) result = ensure_python_loaded_binary_is_registered();
-    if (result) result = ensure_python_instr_block_is_registered();
+    if (result) result = ensure_python_code_block_is_registered();
+    if (result) result = ensure_python_block_list_is_registered();
     if (result) result = ensure_python_binary_content_is_registered();
     if (result) result = ensure_python_loaded_content_is_registered();
     if (result) result = ensure_python_content_explorer_is_registered();
@@ -119,6 +122,7 @@ bool populate_analysis_module(void)
 
     if (result) result = populate_analysis_contents_module();
     if (result) result = populate_analysis_db_module();
+    if (result) result = populate_analysis_disass_module();
     if (result) result = populate_analysis_types_module();
 
     assert(result);
diff --git a/plugins/pychrysalide/analysis/routine.c b/plugins/pychrysalide/analysis/routine.c
index efac248..e57b919 100644
--- a/plugins/pychrysalide/analysis/routine.c
+++ b/plugins/pychrysalide/analysis/routine.c
@@ -568,7 +568,7 @@ static int py_binary_routine_set_basic_blocks(PyObject *self, PyObject *value, v
     int ret;                                /* Bilan de lecture des args.  */
     GBlockList *blocks;                     /* Blocs basiques à intégrer   */
 
-    ret = PyObject_IsInstance(value, (PyObject *)get_python_instr_block_type());
+    ret = PyObject_IsInstance(value, (PyObject *)get_python_block_list_type());
     if (!ret) return -1;
 
     routine = G_BIN_ROUTINE(pygobject_get(self));
diff --git a/src/analysis/block.c b/src/analysis/block.c
index 8c80177..a23634c 100644
--- a/src/analysis/block.c
+++ b/src/analysis/block.c
@@ -937,7 +937,7 @@ GCodeBlock *g_block_list_get_block(const GBlockList *list, size_t index)
 *                                                                             *
 ******************************************************************************/
 
-GCodeBlock *g_block_list_find_by_starting_instr(const GBlockList *list, const vmpa2t *addr)
+GCodeBlock *g_block_list_find_by_starting_addr(const GBlockList *list, const vmpa2t *addr)
 {
     GCodeBlock *result;                     /* Trouvaille à retourner      */
     size_t i;                               /* Boucle de parcours          */
diff --git a/src/analysis/block.h b/src/analysis/block.h
index 9087abf..21eaaa5 100644
--- a/src/analysis/block.h
+++ b/src/analysis/block.h
@@ -158,7 +158,7 @@ void g_block_list_resolve_links(const GBlockList *);
 GCodeBlock *g_block_list_get_block(const GBlockList *, size_t);
 
 /* Recherche un bloc de code débutant à une adresse donnée. */
-GCodeBlock *g_block_list_find_by_starting_instr(const GBlockList *, const vmpa2t *);
+GCodeBlock *g_block_list_find_by_starting_addr(const GBlockList *, const vmpa2t *);
 
 
 
diff --git a/src/analysis/disass/block.c b/src/analysis/disass/block.c
index b22c547..3641aea 100644
--- a/src/analysis/disass/block.c
+++ b/src/analysis/disass/block.c
@@ -276,7 +276,7 @@ static void g_basic_block_resolve_links(GBasicBlock *block, const GBlockList *li
 
         range = g_arch_instruction_get_range(dest->linked);
 
-        target = g_block_list_find_by_starting_instr(list, get_mrange_addr(range));
+        target = g_block_list_find_by_starting_addr(list, get_mrange_addr(range));
 
         /**
          * Les sauts ne se font pas toujours à l'intérieur d'une même fonction.
diff --git a/tests/analysis/disass/Makefile b/tests/analysis/disass/Makefile
new file mode 100644
index 0000000..6f12036
--- /dev/null
+++ b/tests/analysis/disass/Makefile
@@ -0,0 +1,10 @@
+
+EXECUTABLES=hello
+
+all: $(EXECUTABLES)
+
+hello: hello.c
+	$(ARM_CROSS)gcc $< -o $@
+
+clean:
+	rm -f $(EXECUTABLES)
diff --git a/tests/analysis/disass/__init__.py b/tests/analysis/disass/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/analysis/disass/block.py b/tests/analysis/disass/block.py
new file mode 100644
index 0000000..8de44e1
--- /dev/null
+++ b/tests/analysis/disass/block.py
@@ -0,0 +1,74 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+
+# S'assure du bon fonctionnement des blocs basiques
+
+
+from chrysacase import ChrysalideTestCase
+from pychrysalide.analysis.contents import FileContent
+from pychrysalide.analysis import LoadedBinary
+from pychrysalide.format.elf import ElfFormat
+import os
+import sys
+
+
+class TestBasicBlocks(ChrysalideTestCase):
+    """TestCase for basic blocks."""
+
+    @classmethod
+    def setUpClass(cls):
+
+        super(TestBasicBlocks, cls).setUpClass()
+
+        cls.log('Compile binary "hello" if needed...')
+
+        fullname = sys.modules[cls.__module__].__file__
+        dirpath = os.path.dirname(fullname)
+
+        os.system('make -C %s hello 2>&1 > /dev/null' % dirpath)
+
+
+    @classmethod
+    def tearDownClass(cls):
+
+        super(TestBasicBlocks, cls).tearDownClass()
+
+        cls.log('Delete built binaries...')
+
+        fullname = sys.modules[cls.__module__].__file__
+        dirpath = os.path.dirname(fullname)
+
+        os.system('make -C %s clean 2>&1 > /dev/null' % dirpath)
+
+
+    def testBlockList(self):
+        """Check basic tests for basic block list."""
+
+        fullname = sys.modules[self.__class__.__module__].__file__
+        filename = os.path.basename(fullname)
+
+        baselen = len(fullname) - len(filename)
+
+        cnt = FileContent(fullname[:baselen] + 'hello')
+        self.assertIsNotNone(cnt)
+
+        fmt = ElfFormat(cnt)
+        self.assertIsNotNone(fmt)
+
+        binary = LoadedBinary(fmt)
+        self.assertIsNotNone(binary)
+
+        binary.analyze_and_wait()
+
+        sym = fmt.find_symbol_by_label('main')
+        self.assertIsNotNone(sym)
+
+        found = sym.basic_blocks.find_by_starting_addr(sym.range.addr)
+        self.assertIsNotNone(found)
+
+        self.assertEqual(found, sym.basic_blocks.items[0])
+
+        self.assertEqual(found.index, 0)
+
+        self.assertEqual(found.rank, 0)
diff --git a/tests/analysis/disass/hello.c b/tests/analysis/disass/hello.c
new file mode 100644
index 0000000..c226e8a
--- /dev/null
+++ b/tests/analysis/disass/hello.c
@@ -0,0 +1,12 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+int main(void)
+{
+    printf("Hello World!\n");
+
+    return EXIT_SUCCESS;
+
+}
-- 
cgit v0.11.2-87-g4458