From 627560def907ec62c38839457e6a018af27b6640 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 14 Apr 2019 23:04:32 +0200
Subject: Provided a link to routines from Dex methods.

---
 plugins/dex/Makefile.am                 |   3 +-
 plugins/dex/method.c                    |   3 +
 plugins/dex/pool.c                      |   3 +-
 plugins/dex/python/Makefile.am          |   1 +
 plugins/dex/python/module.c             |   2 +
 plugins/dex/python/routine.c            | 204 ++++++++++++++++++++++++++++++
 plugins/dex/python/routine.h            |  45 +++++++
 plugins/dex/routine.c                   | 215 ++++++++++++++++++++++++++++++++
 plugins/dex/routine.h                   |  64 ++++++++++
 plugins/pychrysalide/analysis/routine.c |  45 +++++++
 plugins/pychrysalide/analysis/routine.h |   3 +
 src/analysis/Makefile.am                |   1 +
 src/analysis/routine-int.h              |  67 ++++++++++
 src/analysis/routine.c                  |  35 +-----
 14 files changed, 655 insertions(+), 36 deletions(-)
 create mode 100644 plugins/dex/python/routine.c
 create mode 100644 plugins/dex/python/routine.h
 create mode 100644 plugins/dex/routine.c
 create mode 100644 plugins/dex/routine.h
 create mode 100644 src/analysis/routine-int.h

diff --git a/plugins/dex/Makefile.am b/plugins/dex/Makefile.am
index 7bdf930..8a092d5 100644
--- a/plugins/dex/Makefile.am
+++ b/plugins/dex/Makefile.am
@@ -34,7 +34,8 @@ libdex_la_SOURCES =						\
 	format.h format.c					\
 	loading.h loading.c					\
 	method.h method.c					\
-	pool.h pool.c
+	pool.h pool.c						\
+	routine.h routine.c
 
 libdex_la_LIBADD =						\
 	$(PYTHON3_LIBADD)
diff --git a/plugins/dex/method.c b/plugins/dex/method.c
index d5f765a..7f0d0f8 100644
--- a/plugins/dex/method.c
+++ b/plugins/dex/method.c
@@ -34,6 +34,7 @@
 
 #include "dex-int.h"
 #include "pool.h"
+#include "routine.h"
 
 
 
@@ -288,6 +289,8 @@ GDexMethod *g_dex_method_new_callable(GDexFormat *format, const method_id_item *
 
     result->routine = routine;
 
+    g_dex_routine_attach_method(G_DEX_ROUTINE(routine), result);
+
  gdmne_exit:
 
     return result;
diff --git a/plugins/dex/pool.c b/plugins/dex/pool.c
index fb710f3..90c991b 100644
--- a/plugins/dex/pool.c
+++ b/plugins/dex/pool.c
@@ -37,6 +37,7 @@
 
 #include "dex-int.h"
 #include "loading.h"
+#include "routine.h"
 
 
 
@@ -660,7 +661,7 @@ GBinRoutine *get_prototype_from_dex_pool(GDexFormat *format, uint32_t index)
     type = get_type_from_dex_pool(format, proto_id.return_type_idx);
     if (type == NULL) goto grfdp_error;
 
-    result = g_binary_routine_new();
+    result = G_BIN_ROUTINE(g_dex_routine_new());
 
     g_binary_routine_set_return_type(result, type);
 
diff --git a/plugins/dex/python/Makefile.am b/plugins/dex/python/Makefile.am
index 2bf98bc..b371b87 100644
--- a/plugins/dex/python/Makefile.am
+++ b/plugins/dex/python/Makefile.am
@@ -8,6 +8,7 @@ libdexpython_la_SOURCES =				\
 	format.h format.c					\
 	method.h method.c					\
 	module.h module.c					\
+	routine.h routine.c					\
 	translate.h translate.c
 
 libdexpython_la_LDFLAGS = 
diff --git a/plugins/dex/python/module.c b/plugins/dex/python/module.c
index aedbc0f..007b794 100644
--- a/plugins/dex/python/module.c
+++ b/plugins/dex/python/module.c
@@ -36,6 +36,7 @@
 #include "field.h"
 #include "format.h"
 #include "method.h"
+#include "routine.h"
 
 
 
@@ -80,6 +81,7 @@ bool add_format_dex_module_to_python_module(void)
     if (result) result = register_python_dex_field(module);
     if (result) result = register_python_dex_format(module);
     if (result) result = register_python_dex_method(module);
+    if (result) result = register_python_dex_routine(module);
 
     assert(result);
 
diff --git a/plugins/dex/python/routine.c b/plugins/dex/python/routine.c
new file mode 100644
index 0000000..ef85cc7
--- /dev/null
+++ b/plugins/dex/python/routine.c
@@ -0,0 +1,204 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * routine.c - équivalent Python du fichier "plugins/dex/routine.c"
+ *
+ * Copyright (C) 2019 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 "routine.h"
+
+
+#include <pygobject.h>
+
+
+#include <plugins/pychrysalide/helpers.h>
+#include <plugins/pychrysalide/analysis/routine.h>
+
+
+#include "../routine.h"
+
+
+
+/* Fournit la méthode liée à une routine d'origine Dex. */
+static PyObject *py_dex_routine_get_method(PyObject *, void *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Fournit la méthode liée à une routine d'origine Dex.         *
+*                                                                             *
+*  Retour      : Méthode Dex liée à la routine ou None.                       *
+*                                                                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_dex_routine_get_method(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Valeur à retourner          */
+    GDexRoutine *routine;                   /* Version native              */
+    GDexMethod *method;                     /* Méthode correspondante      */
+
+    routine = G_DEX_ROUTINE(pygobject_get(self));
+
+    method = g_dex_routine_get_method(routine);
+
+    if (method != NULL)
+    {
+        result = pygobject_new(G_OBJECT(method));
+
+        g_object_unref(G_OBJECT(method));
+
+    }
+    else
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+
+    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_dex_routine_type(void)
+{
+    static PyMethodDef py_dex_routine_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_dex_routine_getseters[] = {
+        {
+            "method", py_dex_routine_get_method, NULL,
+            "Dex method attached to the Dex routine.", NULL
+        },
+        { NULL }
+    };
+
+    static PyTypeObject py_dex_routine_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.format.dex.DexRoutine",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT,
+
+        .tp_doc         = "PyChrysalide Dex routine.",
+
+        .tp_methods     = py_dex_routine_methods,
+        .tp_getset      = py_dex_routine_getseters
+
+    };
+
+    return &py_dex_routine_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide.format.dex.DexRoutine'.*
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool register_python_dex_routine(PyObject *module)
+{
+    PyTypeObject *type;                     /* Type Python 'DexRoutine'     */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_dex_routine_type();
+
+    dict = PyModule_GetDict(module);
+
+    if (!register_class_for_pygobject(dict, G_TYPE_DEX_ROUTINE, type, get_python_binary_routine_type()))
+        return false;
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : arg = argument quelconque à tenter de convertir.             *
+*                dst = destination des valeurs récupérées en cas de succès.   *
+*                                                                             *
+*  Description : Tente de convertir en routine de fichier Dex.                *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_dex_routine(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_dex_routine_type());
+
+    switch (result)
+    {
+        case -1:
+            /* L'exception est déjà fixée par Python */
+            result = 0;
+            break;
+
+        case 0:
+            PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to dex routine");
+            break;
+
+        case 1:
+            *((GDexRoutine **)dst) = G_DEX_ROUTINE(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/dex/python/routine.h b/plugins/dex/python/routine.h
new file mode 100644
index 0000000..7653731
--- /dev/null
+++ b/plugins/dex/python/routine.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * routine.h - prototypes pour l'équivalent Python du fichier "plugins/dex/routine.h"
+ *
+ * Copyright (C) 2019 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_DEX_PYTHON_ROUTINE_H
+#define _PLUGINS_DEX_PYTHON_ROUTINE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_dex_routine_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.format.dex.DexRoutine'. */
+bool register_python_dex_routine(PyObject *module);
+
+/* Tente de convertir en routine de fichier Dex. */
+int convert_to_dex_routine(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_DEX_PYTHON_ROUTINE_H */
diff --git a/plugins/dex/routine.c b/plugins/dex/routine.c
new file mode 100644
index 0000000..340531a
--- /dev/null
+++ b/plugins/dex/routine.c
@@ -0,0 +1,215 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * routine.c - prototypes pour la manipulation des routines du format Dex
+ *
+ * Copyright (C) 2019 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 "routine.h"
+
+
+#include <analysis/routine-int.h>
+
+
+
+/* Représentation de routine Dex (instance) */
+struct _GDexRoutine
+{
+    GBinRoutine parent;                     /* A laisser en premier        */
+
+    GDexMethod *method;                     /* Lien circulaire !           */
+
+};
+
+
+/* Représentation de routine Dex (classe) */
+struct _GDexRoutineClass
+{
+    GBinRoutineClass parent;                /* A laisser en premier        */
+
+};
+
+
+
+/* Initialise la classe des représentation de routine. */
+static void g_dex_routine_class_init(GDexRoutineClass *);
+
+/* Initialise une instance représentation de routine. */
+static void g_dex_routine_init(GDexRoutine *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_dex_routine_finalize(GDexRoutine *);
+
+/* Supprime toutes les références externes. */
+static void g_dex_routine_dispose(GDexRoutine *);
+
+
+
+/* Indique le type défini pour une représentation de routine. */
+G_DEFINE_TYPE(GDexRoutine, g_dex_routine, G_TYPE_BIN_ROUTINE);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des représentation de routine.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_dex_routine_class_init(GDexRoutineClass *klass)
+{
+    GObjectClass *object;                   /* Version de base de la classe*/
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_dex_routine_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_dex_routine_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : routine = instance à initialiser.                            *
+*                                                                             *
+*  Description : Initialise une instance représentation de routine.           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_dex_routine_init(GDexRoutine *routine)
+{
+    routine->method = NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : routine = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_dex_routine_dispose(GDexRoutine *routine)
+{
+    G_OBJECT_CLASS(g_dex_routine_parent_class)->dispose(G_OBJECT(routine));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : routine = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_dex_routine_finalize(GDexRoutine *routine)
+{
+    G_OBJECT_CLASS(g_dex_routine_parent_class)->finalize(G_OBJECT(routine));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Crée une représentation de routine.                          *
+*                                                                             *
+*  Retour      : Adresse de la structure mise en place.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GDexRoutine *g_dex_routine_new(void)
+{
+    GDexRoutine *result;                    /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_DEX_ROUTINE, NULL);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : routine = routine ayant pour origine un fichier Dex.         *
+*                method  = méthode Dex définissant la routine.                *
+*                                                                             *
+*  Description : Lie une routine à sa méthode Dex d'origine.                  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_dex_routine_attach_method(GDexRoutine *routine, GDexMethod *method)
+{
+    routine->method = method;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : routine = routine ayant pour origine un fichier Dex.         *
+*                                                                             *
+*  Description : Fournit la méthode liée à une routine d'origine Dex.         *
+*                                                                             *
+*  Retour      : Méthode Dex liée à la routine ou NULL.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GDexMethod *g_dex_routine_get_method(const GDexRoutine *routine)
+{
+    GDexMethod *result;                     /* Méthode à retourner         */
+
+    result = routine->method;
+
+    if (result != NULL)
+        g_object_ref(G_OBJECT(result));
+
+    return result;
+
+}
diff --git a/plugins/dex/routine.h b/plugins/dex/routine.h
new file mode 100644
index 0000000..4b4c12d
--- /dev/null
+++ b/plugins/dex/routine.h
@@ -0,0 +1,64 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * routine.h - prototypes pour la manipulation des routines du format Dex
+ *
+ * Copyright (C) 2019 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 _PLUGINS_DEX_ROUTINE_H
+#define _PLUGINS_DEX_ROUTINE_H
+
+
+#include <glib-object.h>
+
+
+#include "method.h"
+
+
+
+#define G_TYPE_DEX_ROUTINE            g_dex_routine_get_type()
+#define G_DEX_ROUTINE(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DEX_ROUTINE, GDexRoutine))
+#define G_IS_DEX_ROUTINE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_DEX_ROUTINE))
+#define G_DEX_ROUTINE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DEX_ROUTINE, GDexRoutineClass))
+#define G_IS_DEX_ROUTINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DEX_ROUTINE))
+#define G_DEX_ROUTINE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DEX_ROUTINE, GDexRoutineClass))
+
+
+/* Représentation de routine Dex (instance) */
+typedef struct _GDexRoutine GDexRoutine;
+
+/* Représentation de routine Dex (classe) */
+typedef struct _GDexRoutineClass GDexRoutineClass;
+
+
+/* Indique le type défini pour une représentation de routine. */
+GType g_dex_routine_get_type(void);
+
+/* Crée une représentation de routine. */
+GDexRoutine *g_dex_routine_new(void);
+
+/* Lie une routine à sa méthode Dex d'origine. */
+void g_dex_routine_attach_method(GDexRoutine *, GDexMethod *);
+
+/* Fournit la méthode liée à une routine d'origine Dex. */
+GDexMethod *g_dex_routine_get_method(const GDexRoutine *);
+
+
+
+#endif  /* _PLUGINS_DEX_ROUTINE_H */
diff --git a/plugins/pychrysalide/analysis/routine.c b/plugins/pychrysalide/analysis/routine.c
index d8b0eb7..0dea2a0 100644
--- a/plugins/pychrysalide/analysis/routine.c
+++ b/plugins/pychrysalide/analysis/routine.c
@@ -689,3 +689,48 @@ bool ensure_python_binary_routine_is_registered(void)
     return true;
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : arg = argument quelconque à tenter de convertir.             *
+*                dst = destination des valeurs récupérées en cas de succès.   *
+*                                                                             *
+*  Description : Tente de convertir en routine de binaire.                    *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_binary_routine(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_binary_routine_type());
+
+    switch (result)
+    {
+        case -1:
+            /* L'exception est déjà fixée par Python */
+            result = 0;
+            break;
+
+        case 0:
+            PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to loaded binary");
+            break;
+
+        case 1:
+            *((GBinRoutine **)dst) = G_BIN_ROUTINE(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/routine.h b/plugins/pychrysalide/analysis/routine.h
index 702cbd8..bb85ff0 100644
--- a/plugins/pychrysalide/analysis/routine.h
+++ b/plugins/pychrysalide/analysis/routine.h
@@ -37,6 +37,9 @@ PyTypeObject *get_python_binary_routine_type(void);
 /* Prend en charge l'objet 'pychrysalide.analysis.BinRoutine'. */
 bool ensure_python_binary_routine_is_registered(void);
 
+/* Tente de convertir en routine de binaire. */
+int convert_to_binary_routine(PyObject *, void *);
+
 
 
 #endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_ROUTINE_H */
diff --git a/src/analysis/Makefile.am b/src/analysis/Makefile.am
index e1e15e4..c4a66de 100644
--- a/src/analysis/Makefile.am
+++ b/src/analysis/Makefile.am
@@ -11,6 +11,7 @@ libanalysis_la_SOURCES =				\
 	loaded.h loaded.c					\
 	loading.h loading.c					\
 	project.h project.c					\
+	routine-int.h						\
 	routine.h routine.c					\
 	type-int.h							\
 	type.h type.c						\
diff --git a/src/analysis/routine-int.h b/src/analysis/routine-int.h
new file mode 100644
index 0000000..02362ce
--- /dev/null
+++ b/src/analysis/routine-int.h
@@ -0,0 +1,67 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * loaded-int.h - définitions internes propres aux définitions de routine
+ *
+ * Copyright (C) 2019 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_ROUTINE_INT_H
+#define _ANALYSIS_ROUTINE_INT_H
+
+
+#include "routine.h"
+#include "../format/symbol-int.h"
+
+
+
+/* Représentation générique de routine (instance) */
+struct _GBinRoutine
+{
+    GBinSymbol parent;                      /* A laisser en premier        */
+
+    RoutineType type;                       /* Type de routine             */
+
+    GDataType *ret_type;                    /* Type retourné               */
+
+    GDataType *namespace;                   /* Espace de noms / classe     */
+    char *ns_sep;                           /* Séparateur d'éléments       */
+    char *name;                             /* Désignation humaine         */
+    GDataType *full_name;                   /* Désignation très complète   */
+
+    GBinVariable **args;                    /* Arguments de la routines    */
+    size_t args_count;                      /* Nombre d'arguments          */
+
+    GBinVariable **locals;                  /* Variables locales du code   */
+    size_t locals_count;                    /* Nombre de variables locales */
+
+    GBlockList *blocks;                     /* Blocs basiques d'instruct°  */
+
+};
+
+
+/* Représentation générique de routine (classe) */
+struct _GBinRoutineClass
+{
+    GBinSymbolClass parent;                 /* A laisser en premier        */
+
+};
+
+
+
+#endif  /* _ANALYSIS_ROUTINE_INT_H */
diff --git a/src/analysis/routine.c b/src/analysis/routine.c
index 222bfea..41e314c 100644
--- a/src/analysis/routine.c
+++ b/src/analysis/routine.c
@@ -34,47 +34,14 @@
 #include <i18n.h>
 
 
+#include "routine-int.h"
 #include "../arch/raw.h"
 #include "../common/extstr.h"
 #include "../core/params.h"
-#include "../format/symbol-int.h"
 #include "../glibext/gbinarycursor.h"
 
 
 
-/* Représentation générique de routine (instance) */
-struct _GBinRoutine
-{
-    GBinSymbol parent;                      /* A laisser en premier        */
-
-    RoutineType type;                       /* Type de routine             */
-
-    GDataType *ret_type;                    /* Type retourné               */
-
-    GDataType *namespace;                   /* Espace de noms / classe     */
-    char *ns_sep;                           /* Séparateur d'éléments       */
-    char *name;                             /* Désignation humaine         */
-    GDataType *full_name;                   /* Désignation très complète   */
-
-    GBinVariable **args;                    /* Arguments de la routines    */
-    size_t args_count;                      /* Nombre d'arguments          */
-
-    GBinVariable **locals;                  /* Variables locales du code   */
-    size_t locals_count;                    /* Nombre de variables locales */
-
-    GBlockList *blocks;                     /* Blocs basiques d'instruct°  */
-
-};
-
-
-/* Représentation générique de routine (classe) */
-struct _GBinRoutineClass
-{
-    GBinSymbolClass parent;                 /* A laisser en premier        */
-
-};
-
-
 /* Initialise la classe des représentation de routine. */
 static void g_bin_routine_class_init(GBinRoutineClass *);
 
-- 
cgit v0.11.2-87-g4458