From 22c06200eca1ecda455a8d68bf73ec4fc458f59f Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 8 Oct 2023 01:27:24 +0200
Subject: Create some glue between ROST and Kaitai.

---
 configure.ac                               |   2 +
 plugins/kaitai/Makefile.am                 |   4 +-
 plugins/kaitai/core.c                      |   4 +-
 plugins/kaitai/python/Makefile.am          |   5 +-
 plugins/kaitai/python/module.c             |   3 +
 plugins/kaitai/python/rost/Makefile.am     |  14 +
 plugins/kaitai/python/rost/module.c        | 115 +++++++
 plugins/kaitai/python/rost/module.h        |  41 +++
 plugins/kaitai/python/rost/trigger.c       | 236 ++++++++++++++
 plugins/kaitai/python/rost/trigger.h       |  45 +++
 plugins/kaitai/rost/Makefile.am            |  18 ++
 plugins/kaitai/rost/browser-int.h          |  58 ++++
 plugins/kaitai/rost/browser.c              | 474 +++++++++++++++++++++++++++++
 plugins/kaitai/rost/browser.h              |  58 ++++
 plugins/kaitai/rost/core.c                 |  66 ++++
 plugins/kaitai/rost/core.h                 |  37 +++
 plugins/kaitai/rost/space-int.h            |  55 ++++
 plugins/kaitai/rost/space.c                | 240 +++++++++++++++
 plugins/kaitai/rost/space.h                |  59 ++++
 plugins/kaitai/rost/trigger-int.h          |  59 ++++
 plugins/kaitai/rost/trigger.c              | 320 +++++++++++++++++++
 plugins/kaitai/rost/trigger.h              |  58 ++++
 plugins/pychrysalide/analysis/scan/space.c |   2 +-
 src/analysis/scan/exprs/Makefile.am        |   2 +
 src/analysis/scan/exprs/call.c             |   2 +-
 src/analysis/scan/exprs/extract-int.h      |  57 ++++
 src/analysis/scan/exprs/extract.c          | 396 ++++++++++++++++++++++++
 src/analysis/scan/exprs/extract.h          |  56 ++++
 src/analysis/scan/grammar.y                | 139 +++++----
 src/analysis/scan/item-int.h               |   5 +
 src/analysis/scan/item.c                   |  33 ++
 src/analysis/scan/item.h                   |   3 +
 src/analysis/scan/space.c                  |   1 -
 tests/plugins/kaitai/__init__.py           |   0
 tests/plugins/kaitai/rost.py               | 170 +++++++++++
 35 files changed, 2766 insertions(+), 71 deletions(-)
 create mode 100644 plugins/kaitai/python/rost/Makefile.am
 create mode 100644 plugins/kaitai/python/rost/module.c
 create mode 100644 plugins/kaitai/python/rost/module.h
 create mode 100644 plugins/kaitai/python/rost/trigger.c
 create mode 100644 plugins/kaitai/python/rost/trigger.h
 create mode 100644 plugins/kaitai/rost/Makefile.am
 create mode 100644 plugins/kaitai/rost/browser-int.h
 create mode 100644 plugins/kaitai/rost/browser.c
 create mode 100644 plugins/kaitai/rost/browser.h
 create mode 100644 plugins/kaitai/rost/core.c
 create mode 100644 plugins/kaitai/rost/core.h
 create mode 100644 plugins/kaitai/rost/space-int.h
 create mode 100644 plugins/kaitai/rost/space.c
 create mode 100644 plugins/kaitai/rost/space.h
 create mode 100644 plugins/kaitai/rost/trigger-int.h
 create mode 100644 plugins/kaitai/rost/trigger.c
 create mode 100644 plugins/kaitai/rost/trigger.h
 create mode 100644 src/analysis/scan/exprs/extract-int.h
 create mode 100644 src/analysis/scan/exprs/extract.c
 create mode 100644 src/analysis/scan/exprs/extract.h
 create mode 100644 tests/plugins/kaitai/__init__.py
 create mode 100644 tests/plugins/kaitai/rost.py

diff --git a/configure.ac b/configure.ac
index 7673a96..3ecd8de 100644
--- a/configure.ac
+++ b/configure.ac
@@ -680,9 +680,11 @@ AC_CONFIG_FILES([Makefile
                  plugins/kaitai/Makefile
                  plugins/kaitai/parsers/Makefile
                  plugins/kaitai/records/Makefile
+                 plugins/kaitai/rost/Makefile
                  plugins/kaitai/python/Makefile
                  plugins/kaitai/python/parsers/Makefile
                  plugins/kaitai/python/records/Makefile
+                 plugins/kaitai/python/rost/Makefile
                  plugins/libcsem/Makefile
                  plugins/lnxsyscalls/Makefile
                  plugins/mobicore/Makefile
diff --git a/plugins/kaitai/Makefile.am b/plugins/kaitai/Makefile.am
index cbc0f25..6c612ba 100644
--- a/plugins/kaitai/Makefile.am
+++ b/plugins/kaitai/Makefile.am
@@ -67,6 +67,7 @@ libkaitai_la_SOURCES =						\
 libkaitai_la_LIBADD =						\
 	parsers/libkaitaiparsers.la				\
 	records/libkaitairecords.la				\
+	rost/libkaitairost.la					\
 	$(PYTHON3_LIBADD)
 
 libkaitai_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) -I$(top_srcdir)/src
@@ -88,5 +89,4 @@ CLEANFILES = grammar.h grammar.c grammar.output tokens.c tokens.h
 EXTRA_DIST = tokens.h
 
 
-# misc
-SUBDIRS = parsers records $(PYTHON3_SUBDIRS)
+SUBDIRS = parsers records rost $(PYTHON3_SUBDIRS)
diff --git a/plugins/kaitai/core.c b/plugins/kaitai/core.c
index 7483fbc..c41d96d 100644
--- a/plugins/kaitai/core.c
+++ b/plugins/kaitai/core.c
@@ -30,6 +30,8 @@
 #ifdef INCLUDE_PYTHON3_BINDINGS
 #   include "python/module.h"
 #endif
+#include "rost/core.h"
+
 
 
 #ifdef INCLUDE_PYTHON3_BINDINGS
@@ -62,7 +64,7 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin)
 {
     bool result;                            /* Bilan à retourner           */
 
-    result = true;
+    result = add_kaitai_support_to_rost();
 
 #ifdef INCLUDE_PYTHON3_BINDINGS
 
diff --git a/plugins/kaitai/python/Makefile.am b/plugins/kaitai/python/Makefile.am
index ab40744..f222a66 100644
--- a/plugins/kaitai/python/Makefile.am
+++ b/plugins/kaitai/python/Makefile.am
@@ -11,7 +11,8 @@ libkaitaipython_la_SOURCES =				\
 
 libkaitaipython_la_LIBADD =					\
 	parsers/libkaitaipythonparsers.la		\
-	records/libkaitaipythonrecords.la
+	records/libkaitaipythonrecords.la		\
+	rost/libkaitaipythonrost.la
 
 libkaitaipython_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
 	-I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
@@ -22,4 +23,4 @@ devdir = $(includedir)/chrysalide-$(subdir)
 dev_HEADERS = $(libkaitaipython_la_SOURCES:%c=)
 
 
-SUBDIRS = parsers records
+SUBDIRS = parsers records rost
diff --git a/plugins/kaitai/python/module.c b/plugins/kaitai/python/module.c
index fa1f9c2..07fb962 100644
--- a/plugins/kaitai/python/module.c
+++ b/plugins/kaitai/python/module.c
@@ -39,6 +39,7 @@
 #include "stream.h"
 #include "parsers/module.h"
 #include "records/module.h"
+#include "rost/module.h"
 
 
 
@@ -89,6 +90,7 @@ bool add_kaitai_module_to_python_module(void)
 
     if (result) result = add_kaitai_parsers_module();
     if (result) result = add_kaitai_records_module();
+    if (result) result = add_kaitai_rost_module();
 
     if (!result)
         Py_XDECREF(module);
@@ -124,6 +126,7 @@ bool populate_kaitai_module(void)
 
     if (result) result = populate_kaitai_parsers_module();
     if (result) result = populate_kaitai_records_module();
+    if (result) result = populate_kaitai_rost_module();
 
     assert(result);
 
diff --git a/plugins/kaitai/python/rost/Makefile.am b/plugins/kaitai/python/rost/Makefile.am
new file mode 100644
index 0000000..cae0419
--- /dev/null
+++ b/plugins/kaitai/python/rost/Makefile.am
@@ -0,0 +1,14 @@
+
+noinst_LTLIBRARIES = libkaitaipythonrost.la
+
+libkaitaipythonrost_la_SOURCES = 			\
+	module.h module.c						\
+	trigger.h trigger.c
+
+libkaitaipythonrost_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+	-I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
+
+
+devdir = $(includedir)/chrysalide-$(subdir)
+
+dev_HEADERS = $(libkaitaipythonrost_la_SOURCES:%c=)
diff --git a/plugins/kaitai/python/rost/module.c b/plugins/kaitai/python/rost/module.c
new file mode 100644
index 0000000..66a5a82
--- /dev/null
+++ b/plugins/kaitai/python/rost/module.c
@@ -0,0 +1,115 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire rost en tant que module
+ *
+ * Copyright (C) 2023 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 <Python.h>
+
+
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+
+
+#include "trigger.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Ajoute le module 'plugins.kaitai.rost' au module Python.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool add_kaitai_rost_module(void)
+{
+    bool result;                            /* Bilan à retourner           */
+    PyObject *super;                        /* Module à compléter          */
+    PyObject *module;                       /* Sous-module mis en place    */
+
+#define PYCHRYSALIDE_PLUGINS_KAITAI_ROST_DOC                    \
+    "This module creates some glue to extend the ROST features" \
+    " using Kaitai definitions for analyzing and filtering"     \
+    " contents."
+
+    static PyModuleDef py_chrysalide_kaitai_rost_module = {
+
+        .m_base = PyModuleDef_HEAD_INIT,
+
+        .m_name = "pychrysalide.plugins.kaitai.rost",
+        .m_doc = PYCHRYSALIDE_PLUGINS_KAITAI_ROST_DOC,
+
+        .m_size = -1,
+
+    };
+
+    result = false;
+
+    super = get_access_to_python_module("pychrysalide.plugins.kaitai");
+
+    module = build_python_module(super, &py_chrysalide_kaitai_rost_module);
+
+    result = (module != NULL);
+
+    assert(result);
+
+    if (!result)
+        Py_XDECREF(module);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Intègre les objets du module 'plugins.kaitai.rost'.          *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool populate_kaitai_rost_module(void)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = true;
+
+    if (result) result = ensure_python_kaitai_trigger_is_registered();
+
+    assert(result);
+
+    return result;
+
+}
diff --git a/plugins/kaitai/python/rost/module.h b/plugins/kaitai/python/rost/module.h
new file mode 100644
index 0000000..8415c2e
--- /dev/null
+++ b/plugins/kaitai/python/rost/module.h
@@ -0,0 +1,41 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire rost en tant que module
+ *
+ * Copyright (C) 2023 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_KAITAI_PYTHON_ROST_MODULE_H
+#define _PLUGINS_KAITAI_PYTHON_ROST_MODULE_H
+
+
+#include <stdbool.h>
+
+
+
+/* Ajoute le module 'plugins.kaitai.rost' au module Python. */
+bool add_kaitai_rost_module(void);
+
+/* Intègre les objets du module 'plugins.kaitai.rost'. */
+bool populate_kaitai_rost_module(void);
+
+
+
+#endif  /* _PLUGINS_KAITAI_PYTHON_ROST_MODULE_H */
diff --git a/plugins/kaitai/python/rost/trigger.c b/plugins/kaitai/python/rost/trigger.c
new file mode 100644
index 0000000..180ef6e
--- /dev/null
+++ b/plugins/kaitai/python/rost/trigger.c
@@ -0,0 +1,236 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * trigger.c - équivalent Python du fichier "plugins/kaitai/rost/trigger.c"
+ *
+ * Copyright (C) 2023 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 "trigger.h"
+
+
+#include <assert.h>
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+#include <plugins/pychrysalide/analysis/scan/item.h>
+
+
+#include "../parsers/struct.h"
+#include "../../parsers/struct.h"
+#include "../../rost/trigger-int.h"
+
+
+
+CREATE_DYN_CONSTRUCTOR(kaitai_trigger, G_TYPE_KAITAI_TRIGGER);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_kaitai_trigger_init(PyObject *, PyObject *, PyObject *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = objet à initialiser (théoriquement).                  *
+*                args = arguments fournis à l'appel.                          *
+*                kwds = arguments de type key=val fournis.                    *
+*                                                                             *
+*  Description : Initialise une instance sur la base du dérivé de GObject.    *
+*                                                                             *
+*  Retour      : 0.                                                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int py_kaitai_trigger_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    GKaitaiStruct *kstruct;                 /* Définition Kaitai en place  */
+    int ret;                                /* Bilan de lecture des args.  */
+    GKaitaiTrigger *trigger;                /* Création GLib à transmettre */
+
+#define KAITAI_TRIGGER_DOC                                                      \
+    "The KaitaiTrigger object store an access to a loaded Kaitai definition"    \
+    " creates as many as required instances from it when ROST filters contents" \
+    " with the help of the Kaitai module.\n"                                    \
+    "\n"                                                                        \
+    "Instances can be created using following constructor:\n"                   \
+    "\n"                                                                        \
+    "    KaitaiTrigger(kstruct)"                                                \
+    "\n"                                                                        \
+    "Where *kstruct* is a pychrysalide.plugins.kaitai.parsers.KaitaiStruct"     \
+    " instance loaded with a valid Kaitai definition."
+
+    /* Récupération des paramètres */
+
+    ret = PyArg_ParseTuple(args, "O&", convert_to_kaitai_structure, &kstruct);
+    if (!ret) return -1;
+
+    /* Initialisation d'un objet GLib */
+
+    ret = forward_pygobjet_init(self);
+    if (ret == -1) return -1;
+
+    /* Eléments de base */
+
+    trigger = G_KAITAI_TRIGGER(pygobject_get(self));
+
+    if (!g_kaitai_trigger_create(trigger, kstruct))
+    {
+        PyErr_SetString(PyExc_ValueError, _("Unable to create Kaitai stream."));
+        return -1;
+
+    }
+
+    return 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit un accès à une définition de type à diffuser.        *
+*                                                                             *
+*  Retour      : Définition d'objet pour Python.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyTypeObject *get_python_kaitai_trigger_type(void)
+{
+    static PyMethodDef py_kaitai_trigger_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_kaitai_trigger_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_kaitai_trigger_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.plugins.kaitai.rost.KaitaiTrigger",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = KAITAI_TRIGGER_DOC,
+
+        .tp_methods     = py_kaitai_trigger_methods,
+        .tp_getset      = py_kaitai_trigger_getseters,
+
+        .tp_init        = py_kaitai_trigger_init,
+        .tp_new         = py_kaitai_trigger_new,
+
+    };
+
+    return &py_kaitai_trigger_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide....rost.KaitaiTrigger. *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_python_kaitai_trigger_is_registered(void)
+{
+    PyTypeObject *type;                     /* Type Python 'RecordEmpty'   */
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_kaitai_trigger_type();
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.plugins.kaitai.rost");
+
+        dict = PyModule_GetDict(module);
+
+        if (!ensure_python_scan_registered_item_is_registered())
+            return false;
+
+        if (!register_class_for_pygobject(dict, G_TYPE_KAITAI_TRIGGER, 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 accès à une définition Kaitai.         *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_kaitai_trigger(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_kaitai_trigger_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 Kaitai trigger");
+            break;
+
+        case 1:
+            *((GKaitaiTrigger **)dst) = G_KAITAI_TRIGGER(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/kaitai/python/rost/trigger.h b/plugins/kaitai/python/rost/trigger.h
new file mode 100644
index 0000000..44776f7
--- /dev/null
+++ b/plugins/kaitai/python/rost/trigger.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * trigger.h - prototypes pour l'équivalent Python du fichier "plugins/kaitai/rost/trigger.h"
+ *
+ * Copyright (C) 2023 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_KAITAI_PYTHON_ROST_TRIGGER_H
+#define _PLUGINS_KAITAI_PYTHON_ROST_TRIGGER_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_kaitai_trigger_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.plugins.kaitai.rost.KaitaiTrigger'. */
+bool ensure_python_kaitai_trigger_is_registered(void);
+
+/* Tente de convertir en accès à une définition Kaitai. */
+int convert_to_kaitai_trigger(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_KAITAI_PYTHON_ROST_TRIGGER_H */
diff --git a/plugins/kaitai/rost/Makefile.am b/plugins/kaitai/rost/Makefile.am
new file mode 100644
index 0000000..c7ea84a
--- /dev/null
+++ b/plugins/kaitai/rost/Makefile.am
@@ -0,0 +1,18 @@
+
+noinst_LTLIBRARIES = libkaitairost.la
+
+libkaitairost_la_SOURCES =					\
+	browser-int.h							\
+	browser.h browser.c						\
+	core.h core.c							\
+	space-int.h								\
+	space.h space.c							\
+	trigger-int.h							\
+	trigger.h trigger.c
+
+libkaitairost_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) -I$(top_srcdir)/src
+
+
+devdir = $(includedir)/chrysalide-$(subdir)
+
+dev_HEADERS = $(libkaitairost_la_SOURCES:%c=)
diff --git a/plugins/kaitai/rost/browser-int.h b/plugins/kaitai/rost/browser-int.h
new file mode 100644
index 0000000..4b49680
--- /dev/null
+++ b/plugins/kaitai/rost/browser-int.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * browser-int.h - prototypes internes pour le parcours des résultats d'analyse Kaitai pour ROST
+ *
+ * Copyright (C) 2023 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_KAITAI_ROST_BROWSER_INT_H
+#define PLUGINS_KAITAI_ROST_BROWSER_INT_H
+
+
+#include <analysis/scan/item-int.h>
+
+
+#include "browser.h"
+
+
+
+/* Parcours des résultats d'une analyse Kaitai pour ROST (instance) */
+struct _GKaitaiBrowser
+{
+    GScanRegisteredItem parent;             /* A laisser en premier        */
+
+    char *path;                             /* Chamin vers l'enregistrement*/
+    GMatchRecord *record;                   /* Correspondance à parcourir  */
+
+};
+
+/* Parcours des résultats d'une analyse Kaitai pour ROST (classe) */
+struct _GKaitaiBrowserClass
+{
+    GScanRegisteredItemClass parent;        /* A laisser en premier        */
+
+};
+
+
+/* Met en place un nouveau parcours de correspondances Kaitai. */
+bool g_kaitai_browser_create(GKaitaiBrowser *, const char *, GMatchRecord *);
+
+
+
+#endif  /* PLUGINS_KAITAI_ROST_BROWSER_INT_H */
diff --git a/plugins/kaitai/rost/browser.c b/plugins/kaitai/rost/browser.c
new file mode 100644
index 0000000..075c5ff
--- /dev/null
+++ b/plugins/kaitai/rost/browser.c
@@ -0,0 +1,474 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * browser.c - accès à des définitions Kaitai depuis ROST
+ *
+ * Copyright (C) 2023 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 "browser.h"
+
+
+#include <assert.h>
+#include <string.h>
+
+
+#include <analysis/scan/exprs/literal.h>
+
+
+#include "browser-int.h"
+#include "../records/item.h"
+#include "../records/list.h"
+#include "../records/value.h"
+
+
+
+/* ---------------------- PARCOURS DE CORRESPONDANCES ETABLIES ---------------------- */
+
+
+/* Initialise la classe des parcours de correspondances Kaitai. */
+static void g_kaitai_browser_class_init(GKaitaiBrowserClass *);
+
+/* Initialise un parcours de correspondances Kaitai. */
+static void g_kaitai_browser_init(GKaitaiBrowser *);
+
+/* Supprime toutes les références externes. */
+static void g_kaitai_browser_dispose(GKaitaiBrowser *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_kaitai_browser_finalize(GKaitaiBrowser *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Indique le nom associé à une expression d'évaluation. */
+static char *g_kaitai_browser_get_name(const GKaitaiBrowser *);
+
+/* Lance une résolution d'élément à solliciter. */
+static bool g_kaitai_browser_resolve(GKaitaiBrowser *, const char *, GScanContext *, GScanScope *, GScanRegisteredItem **);
+
+/* Réduit une expression à une forme plus simple. */
+static bool g_kaitai_browser_reduce(GKaitaiBrowser *, GScanContext *, GScanScope *, GScanExpression **);
+
+/* Effectue une extraction d'élément à partir d'une série. */
+static GObject *g_kaitai_browser_extract_at(GKaitaiBrowser *, const GScanExpression *, GScanContext *, GScanScope *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                        PARCOURS DE CORRESPONDANCES ETABLIES                        */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un parcours de correspondances Kaitai pour ROST. */
+G_DEFINE_TYPE(GKaitaiBrowser, g_kaitai_browser, G_TYPE_SCAN_REGISTERED_ITEM);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des parcours de correspondances Kaitai. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_kaitai_browser_class_init(GKaitaiBrowserClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GScanRegisteredItemClass *registered;   /* Version de classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_kaitai_browser_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_kaitai_browser_finalize;
+
+    registered = G_SCAN_REGISTERED_ITEM_CLASS(klass);
+
+    registered->get_name = (get_registered_item_name_fc)g_kaitai_browser_get_name;
+    registered->resolve = (resolve_registered_item_fc)g_kaitai_browser_resolve;
+    registered->reduce = (reduce_registered_item_fc)g_kaitai_browser_reduce;
+    registered->extract = (extract_registered_item_at)g_kaitai_browser_extract_at;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : browser = instance à initialiser.                            *
+*                                                                             *
+*  Description : Initialise un parcours de correspondances Kaitai.            *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_kaitai_browser_init(GKaitaiBrowser *browser)
+{
+    browser->path = NULL;
+    browser->record = NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : browser = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_kaitai_browser_dispose(GKaitaiBrowser *browser)
+{
+    g_clear_object(&browser->record);
+
+    G_OBJECT_CLASS(g_kaitai_browser_parent_class)->dispose(G_OBJECT(browser));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : browser = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_kaitai_browser_finalize(GKaitaiBrowser *browser)
+{
+    if (browser->path != NULL)
+        free(browser->path);
+
+    G_OBJECT_CLASS(g_kaitai_browser_parent_class)->finalize(G_OBJECT(browser));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : path   = chemin vers l'enregistrement fourni.                *
+*                record = correspondance racine à considérer.                 *
+*                                                                             *
+*  Description : Crée un nouveau parcours de correspondances Kaitai.          *
+*                                                                             *
+*  Retour      : Instance mise en place ou NULL en cas d'échec.               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GKaitaiBrowser *g_kaitai_browser_new(const char *path, GMatchRecord *record)
+{
+    GKaitaiBrowser *result;                 /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_KAITAI_BROWSER, NULL);
+
+    if (!g_kaitai_browser_create(result, path, record))
+        g_clear_object(&result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : browser = encadrement d'un parcours de correspondances.      *
+*                path    = chemin vers l'enregistrement fourni.               *
+*                record  = correspondance racine à considérer.                *
+*                                                                             *
+*  Description : Met en place un nouveau parcours de correspondances Kaitai.  *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_kaitai_browser_create(GKaitaiBrowser *browser, const char *path, GMatchRecord *record)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = true;
+
+    if (path != NULL)
+        browser->path = strdup(path);
+
+    browser->record = record;
+    g_object_ref(G_OBJECT(browser->record));
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item = élément d'appel à consulter.                          *
+*                                                                             *
+*  Description : Indique le nom associé à une expression d'évaluation.        *
+*                                                                             *
+*  Retour      : Désignation humaine de l'expression d'évaluation.            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *g_kaitai_browser_get_name(const GKaitaiBrowser *item)
+{
+    char *result;                           /* Désignation à retourner     */
+    int ret;                                /* Statut de construction      */
+
+    if (item->path == NULL)
+        result = strdup("kaitai://");
+
+    else
+    {
+        ret = asprintf(&result, "kaitai://%s", item->path);
+        assert(ret > 0);
+
+        if (ret <= 0)
+            result = strdup("kaitai://???");
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item   = élément d'appel à consulter.                        *
+*                target = désignation de l'objet d'appel à identifier.        *
+*                ctx    = contexte de suivi de l'analyse courante.            *
+*                scope  = portée courante des variables locales.              *
+*                out    = zone d'enregistrement de la résolution opérée. [OUT]*
+*                                                                             *
+*  Description : Lance une résolution d'élément à solliciter.                 *
+*                                                                             *
+*  Retour      : Bilan de l'opération : false en cas d'erreur irrécupérable.  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_kaitai_browser_resolve(GKaitaiBrowser *item, const char *target, GScanContext *ctx, GScanScope *scope, GScanRegisteredItem **out)
+{
+    bool result;                            /* Bilan à retourner           */
+    GMatchRecord *found;                    /* Correspondance trouvée      */
+    char *path;
+    int ret;                                /* Statut de construction      */
+
+    found = g_match_record_find_by_name(item->record, target, strlen(target), 1);
+    result = (found != NULL);
+
+    if (result)
+    {
+        ret = asprintf(&path, "%s.%s", item->path, target);
+        assert(ret > 0);
+
+        if (ret <= 0)
+            path = strdup("!?");
+
+        *out = G_SCAN_REGISTERED_ITEM(g_kaitai_browser_new(path, found));
+
+        free(path);
+        g_object_unref(G_OBJECT(found));
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item  = élément d'appel à consulter.                         *
+*                ctx   = contexte de suivi de l'analyse courante.             *
+*                scope = portée courante des variables locales.               *
+*                out   = zone d'enregistrement de la réduction opérée. [OUT]  *
+*                                                                             *
+*  Description : Réduit une expression à une forme plus simple.               *
+*                                                                             *
+*  Retour      : Bilan de l'opération : false en cas d'erreur irrécupérable.  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_kaitai_browser_reduce(GKaitaiBrowser *item, GScanContext *ctx, GScanScope *scope, GScanExpression **out)
+{
+    bool result;                            /* Bilan à retourner           */
+    size_t count;                           /* Décompte total à considérer */
+    resolved_value_t value;                 /* Valeur brute à transformer  */
+
+    if (G_IS_RECORD_LIST(item->record))
+    {
+        count = g_record_list_count_records(G_RECORD_LIST(item->record));
+
+        *out = g_scan_literal_expression_new(LVT_BOOLEAN, (bool []){ count > 0 });
+
+        result = true;
+
+    }
+
+    else
+    {
+        if (G_IS_RECORD_ITEM(item->record))
+            result = g_record_item_get_value(G_RECORD_ITEM(item->record), &value);
+
+        else if (G_IS_RECORD_VALUE(item->record))
+            result = g_record_value_compute_and_aggregate_value(G_RECORD_VALUE(item->record), &value);
+
+        else
+            result = false;
+
+        if (result)
+        {
+            switch (value.type)
+            {
+                case GVT_UNSIGNED_INTEGER:
+                    *out = g_scan_literal_expression_new(LVT_UNSIGNED_INTEGER, &value.unsigned_integer);
+                    break;
+
+                case GVT_SIGNED_INTEGER:
+                    *out = g_scan_literal_expression_new(LVT_SIGNED_INTEGER, &value.signed_integer);
+                    break;
+
+                case GVT_FLOAT:
+                    /* TODO */
+                    break;
+
+                case GVT_BOOLEAN:
+                    *out = g_scan_literal_expression_new(LVT_BOOLEAN, &value.status);
+                    break;
+
+                case GVT_BYTES:
+                    *out = g_scan_literal_expression_new(LVT_STRING, &value.bytes);
+                    break;
+
+                default:
+                    break;
+
+            }
+
+            EXIT_RESOLVED_VALUE(value);
+
+        }
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item  = élément d'appel à consulter.                         *
+*                index = indice de l'élément à cibler.                        *
+*                ctx   = contexte de suivi de l'analyse courante.             *
+*                scope = portée courante des variables locales.               *
+*                                                                             *
+*  Description : Effectue une extraction d'élément à partir d'une série.      *
+*                                                                             *
+*  Retour      : Elément de série obtenu ou NULL si erreur irrécupérable.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GObject *g_kaitai_browser_extract_at(GKaitaiBrowser *item, const GScanExpression *index, GScanContext *ctx, GScanScope *scope)
+{
+    GObject *result;                        /* Elément récupéré à renvoyer */
+    GScanLiteralExpression *literal;        /* Accès direct à l'indice     */
+    LiteralValueType vtype;                 /* Type de valeur portée       */
+    unsigned long long at;                  /* Valeur concrète du point    */
+    bool status;                            /* Bilan d'obtention d'indice  */
+    GRecordList *list;                      /* Accès direct à la liste     */
+    size_t count;                           /* Décompte total à considérer */
+    GMatchRecord *found;                    /* Correspondance trouvée      */
+    char *path;
+    int ret;                                /* Statut de construction      */
+
+    result = NULL;
+
+    /* Validations préliminaires */
+
+    if (!G_IS_RECORD_LIST(item->record)) goto exit;
+    if (!G_IS_SCAN_LITERAL_EXPRESSION(index)) goto exit;
+
+    literal = G_SCAN_LITERAL_EXPRESSION(index);
+
+    vtype = g_scan_literal_expression_get_value_type(literal);
+    if (vtype != LVT_UNSIGNED_INTEGER) goto exit;
+
+    status = g_scan_literal_expression_get_unsigned_integer_value(literal, &at);
+    if (!status) goto exit;
+
+    list = G_RECORD_LIST(item->record);
+
+    count = g_record_list_count_records(list);
+    if (at >= count) goto exit;
+
+    /* Récupération de l'élément visé */
+
+    found = g_record_list_get_record(list, at);
+    if (found == NULL) goto exit;
+
+    ret = asprintf(&path, "%s[%llu]", item->path, at);
+    assert(ret > 0);
+
+    if (ret <= 0)
+        path = strdup("!?");
+
+    result = G_OBJECT(g_kaitai_browser_new(path, found));
+
+    free(path);
+    g_object_unref(G_OBJECT(found));
+
+ exit:
+
+    return result;
+
+}
diff --git a/plugins/kaitai/rost/browser.h b/plugins/kaitai/rost/browser.h
new file mode 100644
index 0000000..89b9f6f
--- /dev/null
+++ b/plugins/kaitai/rost/browser.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * browser.h - prototypes pour le parcours des résultats d'analyse Kaitai pour ROST
+ *
+ * Copyright (C) 2023 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_KAITAI_ROST_BROWSER_H
+#define PLUGINS_KAITAI_ROST_BROWSER_H
+
+
+#include <glib-object.h>
+
+
+#include "../record.h"
+
+
+
+#define G_TYPE_KAITAI_BROWSER            g_kaitai_browser_get_type()
+#define G_KAITAI_BROWSER(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_KAITAI_BROWSER, GKaitaiBrowser))
+#define G_IS_KAITAI_BROWSER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_KAITAI_BROWSER))
+#define G_KAITAI_BROWSER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_KAITAI_BROWSER, GKaitaiBrowserClass))
+#define G_IS_KAITAI_BROWSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_KAITAI_BROWSER))
+#define G_KAITAI_BROWSER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_KAITAI_BROWSER, GKaitaiBrowserClass))
+
+
+/* Parcours des résultats d'une analyse Kaitai pour ROST (instance) */
+typedef struct _GKaitaiBrowser GKaitaiBrowser;
+
+/* Parcours des résultats d'une analyse Kaitai pour ROST (classe) */
+typedef struct _GKaitaiBrowserClass GKaitaiBrowserClass;
+
+
+/* Indique le type défini pour un parcours de correspondances Kaitai pour ROST. */
+GType g_kaitai_browser_get_type(void);
+
+/* Crée un nouveau parcours de correspondances Kaitai. */
+GKaitaiBrowser *g_kaitai_browser_new(const char *, GMatchRecord *);
+
+
+
+#endif  /* PLUGINS_KAITAI_ROST_BROWSER_H */
diff --git a/plugins/kaitai/rost/core.c b/plugins/kaitai/rost/core.c
new file mode 100644
index 0000000..8271389
--- /dev/null
+++ b/plugins/kaitai/rost/core.c
@@ -0,0 +1,66 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * core.c - mise à disposition d'un support Kaitai pour ROST
+ *
+ * Copyright (C) 2023 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 "core.h"
+
+
+#include <core/global.h>
+
+
+#include "space.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Intègre un support de Kaitai pour ROST.                      *
+*                                                                             *
+*  Retour      : Bilan du chargement mené.                                    *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool add_kaitai_support_to_rost(void)
+{
+    bool result;                            /* Bilan à retourner           */
+    GScanNamespace *root_ns;                /* Espace de noms ROST racine  */
+    GScanNamespace *kaitai_ns;              /* Espace de noms pour Kaitai  */
+
+    result = true;
+
+    root_ns = get_rost_root_namespace();
+
+    kaitai_ns = g_kaitai_namespace_new();
+
+    result = g_scan_namespace_register_item(root_ns, G_SCAN_REGISTERED_ITEM(kaitai_ns));
+
+    g_object_unref(G_OBJECT(kaitai_ns));
+
+    g_object_unref(G_OBJECT(root_ns));
+
+    return result;
+
+}
diff --git a/plugins/kaitai/rost/core.h b/plugins/kaitai/rost/core.h
new file mode 100644
index 0000000..6f810eb
--- /dev/null
+++ b/plugins/kaitai/rost/core.h
@@ -0,0 +1,37 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * core.h - prototypes pour la mise à disposition d'un support Kaitai pour ROST
+ *
+ * Copyright (C) 2023 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_KAITAI_ROST_CORE_H
+#define _PLUGINS_KAITAI_ROST_CORE_H
+
+
+#include <stdbool.h>
+
+
+
+/* Intègre un support de Kaitai pour ROST. */
+bool add_kaitai_support_to_rost(void);
+
+
+
+#endif  /* _PLUGINS_KAITAI_ROST_CORE_H */
diff --git a/plugins/kaitai/rost/space-int.h b/plugins/kaitai/rost/space-int.h
new file mode 100644
index 0000000..47ec707
--- /dev/null
+++ b/plugins/kaitai/rost/space-int.h
@@ -0,0 +1,55 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * space-int.h - prototypes internes pour la définition d'un espace de noms pour les fonctions de scan
+ *
+ * Copyright (C) 2022 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _PLUGINS_KAITAI_ROST_SPACE_INT_H
+#define _PLUGINS_KAITAI_ROST_SPACE_INT_H
+
+
+#include "space.h"
+
+
+#include <analysis/scan/space-int.h>
+
+
+
+/* Espace de noms avec chargement dynamique de définitions Kaitai (instance) */
+struct _GKaitaiNamespace
+{
+    GScanNamespace parent;                  /* A laisser en premier        */
+
+};
+
+/* Espace de noms avec chargement dynamique de définitions Kaitai (classe) */
+struct _GKaitaiNamespaceClass
+{
+    GScanNamespaceClass parent;             /* A laisser en premier        */
+
+};
+
+
+/* Met en place un nouvel espace de noms pour scan. */
+bool g_kaitai_namespace_create(GKaitaiNamespace *);
+
+
+
+#endif  /* _PLUGINS_KAITAI_ROST_SPACE_INT_H */
diff --git a/plugins/kaitai/rost/space.c b/plugins/kaitai/rost/space.c
new file mode 100644
index 0000000..ed24562
--- /dev/null
+++ b/plugins/kaitai/rost/space.c
@@ -0,0 +1,240 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * space.c - définition d'un espace de noms pour les fonctions de scan
+ *
+ * Copyright (C) 2022 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "space.h"
+
+
+#include <string.h>
+
+
+#include "space-int.h"
+
+
+
+/* ------------------------- SOCLE POUR LES ESPACES DE NOMS ------------------------- */
+
+
+/* Initialise la classe des espaces de noms dynamiques Kaitai. */
+static void g_kaitai_namespace_class_init(GKaitaiNamespaceClass *);
+
+/* Initialise une instance d'espace de noms dynamiques Kaitai. */
+static void g_kaitai_namespace_init(GKaitaiNamespace *);
+
+/* Supprime toutes les références externes. */
+static void g_kaitai_namespace_dispose(GKaitaiNamespace *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_kaitai_namespace_finalize(GKaitaiNamespace *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Lance une résolution d'élément à solliciter. */
+static bool g_kaitai_namespace_resolve(GKaitaiNamespace *, const char *, GScanContext *, GScanScope *, GScanRegisteredItem **);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                           SOCLE POUR LES ESPACES DE NOMS                           */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une définition d'espace de noms dynamique Kaitai. */
+G_DEFINE_TYPE(GKaitaiNamespace, g_kaitai_namespace, G_TYPE_SCAN_NAMESPACE);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des espaces de noms dynamiques Kaitai.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_kaitai_namespace_class_init(GKaitaiNamespaceClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GScanRegisteredItemClass *registered;   /* Version de classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_kaitai_namespace_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_kaitai_namespace_finalize;
+
+    registered = G_SCAN_REGISTERED_ITEM_CLASS(klass);
+
+    registered->resolve = (resolve_registered_item_fc)g_kaitai_namespace_resolve;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : space = instance à initialiser.                              *
+*                                                                             *
+*  Description : Initialise une instance d'espace de noms dynamiques Kaitai.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_kaitai_namespace_init(GKaitaiNamespace *space)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : space = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_kaitai_namespace_dispose(GKaitaiNamespace *space)
+{
+    G_OBJECT_CLASS(g_kaitai_namespace_parent_class)->dispose(G_OBJECT(space));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : space = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_kaitai_namespace_finalize(GKaitaiNamespace *space)
+{
+    G_OBJECT_CLASS(g_kaitai_namespace_parent_class)->finalize(G_OBJECT(space));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Construit un nouvel espace de noms dynamique pour Kaitai.    *
+*                                                                             *
+*  Retour      : Adresse de la structure mise en place.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanNamespace *g_kaitai_namespace_new(void)
+{
+    GScanNamespace *result;                 /* Instance à retourner        */
+
+    result = g_object_new(G_TYPE_KAITAI_NAMESPACE, NULL);
+
+    if (!g_kaitai_namespace_create(G_KAITAI_NAMESPACE(result)))
+        g_clear_object(&result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : space = instance d'espace de noms à initialiser.             *
+*                name  = désignation du futur espace de noms.                 *
+*                                                                             *
+*  Description : Met en place un nouvel espace de noms pour scan.             *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_kaitai_namespace_create(GKaitaiNamespace *space)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = g_scan_namespace_create(G_SCAN_NAMESPACE(space), "kaitai");
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item   = élément d'appel à consulter.                        *
+*                target = désignation de l'objet d'appel à identifier.        *
+*                ctx    = contexte de suivi de l'analyse courante.            *
+*                scope  = portée courante des variables locales.              *
+*                out    = zone d'enregistrement de la résolution opérée. [OUT]*
+*                                                                             *
+*  Description : Lance une résolution d'élément à solliciter.                 *
+*                                                                             *
+*  Retour      : Bilan de l'opération : false en cas d'erreur irrécupérable.  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_kaitai_namespace_resolve(GKaitaiNamespace *item, const char *target, GScanContext *ctx, GScanScope *scope, GScanRegisteredItem **out)
+{
+    bool result;                            /* Bilan à retourner           */
+    GScanRegisteredItemClass *parent;       /* Version de classe parente   */
+
+    parent = G_SCAN_REGISTERED_ITEM_CLASS(g_kaitai_namespace_parent_class);
+
+    result = parent->resolve(G_SCAN_REGISTERED_ITEM(item), target, ctx, scope, out);
+
+
+    if (!result)
+        printf("NEED external def!!!!\n");
+
+    return result;
+
+}
diff --git a/plugins/kaitai/rost/space.h b/plugins/kaitai/rost/space.h
new file mode 100644
index 0000000..5dcea5e
--- /dev/null
+++ b/plugins/kaitai/rost/space.h
@@ -0,0 +1,59 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * space.h - prototypes pour la définition d'un espace de noms pour les fonctions de scan
+ *
+ * Copyright (C) 2022 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _PLUGINS_KAITAI_ROST_SPACE_H
+#define _PLUGINS_KAITAI_ROST_SPACE_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+
+
+#include <analysis/scan/space.h>
+
+
+
+#define G_TYPE_KAITAI_NAMESPACE            g_kaitai_namespace_get_type()
+#define G_KAITAI_NAMESPACE(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_KAITAI_NAMESPACE, GKaitaiNamespace))
+#define G_IS_KAITAI_NAMESPACE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_KAITAI_NAMESPACE))
+#define G_KAITAI_NAMESPACE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_KAITAI_NAMESPACE, GKaitaiNamespaceClass))
+#define G_IS_KAITAI_NAMESPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_KAITAI_NAMESPACE))
+#define G_KAITAI_NAMESPACE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_KAITAI_NAMESPACE, GKaitaiNamespaceClass))
+
+
+/* Espace de noms avec chargement dynamique de définitions Kaitai (instance) */
+typedef struct _GKaitaiNamespace GKaitaiNamespace;
+
+/* Espace de noms avec chargement dynamique de définitions Kaitai (classe) */
+typedef struct _GKaitaiNamespaceClass GKaitaiNamespaceClass;
+
+
+/* Indique le type défini pour une définition d'espace de noms dynamique Kaitai. */
+GType g_kaitai_namespace_get_type(void);
+
+/* Construit un nouvel espace de noms dynamique pour Kaitai. */
+GScanNamespace *g_kaitai_namespace_new(void);
+
+
+
+#endif  /* _PLUGINS_KAITAI_ROST_SPACE_H */
diff --git a/plugins/kaitai/rost/trigger-int.h b/plugins/kaitai/rost/trigger-int.h
new file mode 100644
index 0000000..6830cd7
--- /dev/null
+++ b/plugins/kaitai/rost/trigger-int.h
@@ -0,0 +1,59 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * trigger-int.h - prototypes internes pour l'accès à des définitions Kaitai depuis ROST
+ *
+ * Copyright (C) 2023 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_KAITAI_ROST_TRIGGER_INT_H
+#define _PLUGINS_KAITAI_ROST_TRIGGER_INT_H
+
+
+#include <analysis/scan/item-int.h>
+
+
+#include "trigger.h"
+
+
+
+/* Accès à une définition et déclenchement d'une analyse Kaitai depuis ROST (instance) */
+struct _GKaitaiTrigger
+{
+    GScanRegisteredItem parent;             /* A laisser en premier        */
+
+    char *name;                             /* Désignation arbitraire      */
+
+    GKaitaiStruct *kstruct;                 /* Définition à décliner       */
+
+};
+
+/* Accès à une définition et déclenchement d'une analyse Kaitai depuis ROST (classe) */
+struct _GKaitaiTriggerClass
+{
+    GScanRegisteredItemClass parent;        /* A laisser en premier        */
+
+};
+
+
+/* Met en place un accès à une définition Kaitai pour ROST. */
+bool g_kaitai_trigger_create(GKaitaiTrigger *, GKaitaiStruct *);
+
+
+
+#endif  /* _PLUGINS_KAITAI_ROST_TRIGGER_INT_H */
diff --git a/plugins/kaitai/rost/trigger.c b/plugins/kaitai/rost/trigger.c
new file mode 100644
index 0000000..64e6fe4
--- /dev/null
+++ b/plugins/kaitai/rost/trigger.c
@@ -0,0 +1,320 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * trigger.c - accès à des définitions Kaitai depuis ROST
+ *
+ * Copyright (C) 2023 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 "trigger.h"
+
+
+#include <string.h>
+
+
+#include "browser.h"
+#include "trigger-int.h"
+
+
+
+/* ---------------------- ACCES ET DECLENCHEMENT D'UNE ANALYSE ---------------------- */
+
+
+/* Initialise la classe des accès aux définitions Kaitai. */
+static void g_kaitai_trigger_class_init(GKaitaiTriggerClass *);
+
+/* Initialise un accès à une définition Kaitai. */
+static void g_kaitai_trigger_init(GKaitaiTrigger *);
+
+/* Supprime toutes les références externes. */
+static void g_kaitai_trigger_dispose(GKaitaiTrigger *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_kaitai_trigger_finalize(GKaitaiTrigger *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Indique le nom associé à une expression d'évaluation. */
+static char *g_kaitai_trigger_get_name(const GKaitaiTrigger *);
+
+/* Lance une résolution d'élément à solliciter. */
+static bool g_kaitai_trigger_resolve(GKaitaiTrigger *, const char *, GScanContext *, GScanScope *, GScanRegisteredItem **);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                        ACCES ET DECLENCHEMENT D'UNE ANALYSE                        */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un accès à une définition Kaitai pour ROST. */
+G_DEFINE_TYPE(GKaitaiTrigger, g_kaitai_trigger, G_TYPE_SCAN_REGISTERED_ITEM);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des accès aux définitions Kaitai.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_kaitai_trigger_class_init(GKaitaiTriggerClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GScanRegisteredItemClass *registered;   /* Version de classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_kaitai_trigger_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_kaitai_trigger_finalize;
+
+    registered = G_SCAN_REGISTERED_ITEM_CLASS(klass);
+
+    registered->get_name = (get_registered_item_name_fc)g_kaitai_trigger_get_name;
+    registered->resolve = (resolve_registered_item_fc)g_kaitai_trigger_resolve;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : trigger = instance à initialiser.                            *
+*                                                                             *
+*  Description : Initialise un accès à une définition Kaitai.                 *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_kaitai_trigger_init(GKaitaiTrigger *trigger)
+{
+    trigger->name = NULL;
+
+    trigger->kstruct = NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : trigger = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_kaitai_trigger_dispose(GKaitaiTrigger *trigger)
+{
+    g_clear_object(&trigger->kstruct);
+
+    G_OBJECT_CLASS(g_kaitai_trigger_parent_class)->dispose(G_OBJECT(trigger));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : trigger = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_kaitai_trigger_finalize(GKaitaiTrigger *trigger)
+{
+    if (trigger->name != NULL)
+        free(trigger->name);
+
+    G_OBJECT_CLASS(g_kaitai_trigger_parent_class)->finalize(G_OBJECT(trigger));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : kstruct = définition Kaitai à manipuler avec du contenu.     *
+*                                                                             *
+*  Description : Crée un nouvel accès à une définition Kaitai à instancier.   *
+*                                                                             *
+*  Retour      : Instance mise en place ou NULL en cas d'échec.               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GKaitaiTrigger *g_kaitai_trigger_new(GKaitaiStruct *kstruct)
+{
+    GKaitaiTrigger *result;                 /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_KAITAI_TRIGGER, NULL);
+
+    if (!g_kaitai_trigger_create(result, kstruct))
+        g_clear_object(&result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : trigger = lien vers une définition Kaitai à instancier.      *
+*                kstruct = définition Kaitai à manipuler avec du contenu.     *
+*                                                                             *
+*  Description : Met en place un accès à une définition Kaitai pour ROST.     *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_kaitai_trigger_create(GKaitaiTrigger *trigger, GKaitaiStruct *kstruct)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = true;
+
+    trigger->kstruct = kstruct;
+    g_object_ref(G_OBJECT(trigger->kstruct));
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : trigger = élément d'appel à consulter.                       *
+*                                                                             *
+*  Description : Indique le nom associé à une expression d'évaluation.        *
+*                                                                             *
+*  Retour      : Désignation humaine de l'expression d'évaluation.            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *g_kaitai_trigger_get_name(const GKaitaiTrigger *trigger)
+{
+    char *result;                           /* Désignation à retourner     */
+    GKaitaiMeta *meta;                      /* Eventuelles métadonnées     */
+    const char *id;                         /* Identifiant de définition   */
+
+    if (trigger->name != NULL)
+        result = strdup(trigger->name);
+
+    else
+    {
+        result = NULL;
+
+        meta = g_kaitai_structure_get_meta(trigger->kstruct);
+        if (meta == NULL) goto done;
+
+        id = g_kaitai_meta_get_id(meta);
+        if (id == NULL) goto done;
+
+        result = strdup(id);
+
+        g_object_unref(G_OBJECT(meta));
+
+ done:
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item   = élément d'appel à consulter.                        *
+*                target = désignation de l'objet d'appel à identifier.        *
+*                ctx    = contexte de suivi de l'analyse courante.            *
+*                scope  = portée courante des variables locales.              *
+*                out    = zone d'enregistrement de la résolution opérée. [OUT]*
+*                                                                             *
+*  Description : Lance une résolution d'élément à solliciter.                 *
+*                                                                             *
+*  Retour      : Bilan de l'opération : false en cas d'erreur irrécupérable.  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_kaitai_trigger_resolve(GKaitaiTrigger *item, const char *target, GScanContext *ctx, GScanScope *scope, GScanRegisteredItem **out)
+{
+    bool result;                            /* Bilan à retourner           */
+    GKaitaiBrowser *browser;                /* Navigateur pour résultats   */
+    GBinContent *content;                   /* Contenu binaire à analyser  */
+    GMatchRecord *record;                   /* Premier niveau de résultats */
+
+    browser = g_object_get_data(G_OBJECT(item), "kaitai_browser");
+
+    if (browser == NULL)
+    {
+        content = g_scan_context_get_content(ctx);
+
+        record = g_kaitai_structure_parse(item->kstruct, content);
+
+        g_object_unref(G_OBJECT(content));
+
+        if (record != NULL)
+        {
+            browser = g_kaitai_browser_new(NULL, record);
+
+            g_object_set_data_full(G_OBJECT(item), "kaitai_browser", browser, g_object_unref);
+
+        }
+
+    }
+
+    if (browser == NULL)
+        result = false;
+
+    else
+        result = g_scan_registered_item_resolve(G_SCAN_REGISTERED_ITEM(browser), target, ctx, scope, out);
+
+    return result;
+
+}
diff --git a/plugins/kaitai/rost/trigger.h b/plugins/kaitai/rost/trigger.h
new file mode 100644
index 0000000..3de2e8d
--- /dev/null
+++ b/plugins/kaitai/rost/trigger.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * trigger.h - prototypes pour l'accès à des définitions Kaitai depuis ROST
+ *
+ * Copyright (C) 2023 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_KAITAI_ROST_TRIGGER_H
+#define PLUGINS_KAITAI_ROST_TRIGGER_H
+
+
+#include <glib-object.h>
+
+
+#include "../parsers/struct.h"
+
+
+
+#define G_TYPE_KAITAI_TRIGGER            g_kaitai_trigger_get_type()
+#define G_KAITAI_TRIGGER(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_KAITAI_TRIGGER, GKaitaiTrigger))
+#define G_IS_KAITAI_TRIGGER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_KAITAI_TRIGGER))
+#define G_KAITAI_TRIGGER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_KAITAI_TRIGGER, GKaitaiTriggerClass))
+#define G_IS_KAITAI_TRIGGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_KAITAI_TRIGGER))
+#define G_KAITAI_TRIGGER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_KAITAI_TRIGGER, GKaitaiTriggerClass))
+
+
+/* Accès à une définition et déclenchement d'une analyse Kaitai depuis ROST (instance) */
+typedef struct _GKaitaiTrigger GKaitaiTrigger;
+
+/* Accès à une définition et déclenchement d'une analyse Kaitai depuis ROST (classe) */
+typedef struct _GKaitaiTriggerClass GKaitaiTriggerClass;
+
+
+/* Indique le type défini pour un accès à une définition Kaitai pour ROST. */
+GType g_kaitai_trigger_get_type(void);
+
+/* Crée un nouvel accès à une définition Kaitai à instancier. */
+GKaitaiTrigger *g_kaitai_trigger_new(GKaitaiStruct *);
+
+
+
+#endif  /* PLUGINS_KAITAI_ROST_TRIGGER_H */
diff --git a/plugins/pychrysalide/analysis/scan/space.c b/plugins/pychrysalide/analysis/scan/space.c
index c901cd9..6ea87b8 100644
--- a/plugins/pychrysalide/analysis/scan/space.c
+++ b/plugins/pychrysalide/analysis/scan/space.c
@@ -185,7 +185,7 @@ PyTypeObject *get_python_scan_namespace_type(void)
         .tp_name        = "pychrysalide.analysis.scan.ScanNamespace",
         .tp_basicsize   = sizeof(PyGObject),
 
-        .tp_flags       = Py_TPFLAGS_DEFAULT,
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
 
         .tp_doc         = SCAN_NAMESPACE_DOC,
 
diff --git a/src/analysis/scan/exprs/Makefile.am b/src/analysis/scan/exprs/Makefile.am
index a0b2f3d..37f4133 100644
--- a/src/analysis/scan/exprs/Makefile.am
+++ b/src/analysis/scan/exprs/Makefile.am
@@ -11,6 +11,8 @@ libanalysisscanexprs_la_SOURCES =			\
 	call.h call.c							\
 	counter-int.h							\
 	counter.h counter.c						\
+	extract-int.h							\
+	extract.h extract.c						\
 	handler-int.h							\
 	handler.h handler.c						\
 	intersect-int.h							\
diff --git a/src/analysis/scan/exprs/call.c b/src/analysis/scan/exprs/call.c
index 74e0cba..e335933 100644
--- a/src/analysis/scan/exprs/call.c
+++ b/src/analysis/scan/exprs/call.c
@@ -271,9 +271,9 @@ static ScanReductionState g_scan_pending_call_reduce(const GScanPendingCall *exp
     ScanReductionState state;               /* Etat synthétisé d'un élément*/
     size_t k;                               /* Boucle de parcours #2       */
     GScanExpression **new_args;             /* Nouvelle séquence d'args.   */
-    GScanExpression *new_next;              /* Nouvelle version du suivant */
     GObject *final;                         /* Expression ou élément ?     */
     bool valid;                             /* Validité de l'élément       */
+    GScanExpression *new_next;              /* Nouvelle version du suivant */
 
     access = G_SCAN_NAMED_ACCESS(expr);
 
diff --git a/src/analysis/scan/exprs/extract-int.h b/src/analysis/scan/exprs/extract-int.h
new file mode 100644
index 0000000..562e537
--- /dev/null
+++ b/src/analysis/scan/exprs/extract-int.h
@@ -0,0 +1,57 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * extract-int.h - prototypes internes pour l'organisation d'une extraction d'un élément d'une série interne
+ *
+ * Copyright (C) 2023 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_SCAN_EXPRS_EXTRACT_INT_H
+#define _ANALYSIS_SCAN_EXPRS_EXTRACT_INT_H
+
+
+#include "extract.h"
+
+
+#include "access-int.h"
+
+
+
+/* Extraction d'un élément donné au sein d'une série interne (instance) */
+struct _GScanPendingExtraction
+{
+    GScanNamedAccess parent;                /* A laisser en premier        */
+
+    GScanExpression *index;                 /* Arguments d'appel fournis   */
+
+};
+
+/* Extraction d'un élément donné au sein d'une série interne (classe) */
+struct _GScanPendingExtractionClass
+{
+    GScanNamedAccessClass parent;           /* A laisser en premier        */
+
+};
+
+
+/* Met en place une expression d'extraction d'élément interne. */
+bool g_scan_pending_extraction_create(GScanPendingExtraction *, const sized_string_t *, GScanExpression *);
+
+
+
+#endif  /* _ANALYSIS_SCAN_EXPRS_EXTRACT_INT_H */
diff --git a/src/analysis/scan/exprs/extract.c b/src/analysis/scan/exprs/extract.c
new file mode 100644
index 0000000..b140ed9
--- /dev/null
+++ b/src/analysis/scan/exprs/extract.c
@@ -0,0 +1,396 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * extract.c - organisation d'une extraction d'un élément d'une série interne
+ *
+ * Copyright (C) 2023 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "extract.h"
+
+
+#include <assert.h>
+#include <string.h>
+
+
+#include "extract-int.h"
+#include "../../../core/global.h"
+
+
+
+/* --------------------- INTRODUCTION D'UNE NOUVELLE EXPRESSION --------------------- */
+
+
+/* Initialise la classe des extractions d'éléments internes. */
+static void g_scan_pending_extraction_class_init(GScanPendingExtractionClass *);
+
+/* Initialise une instance d'extraction d'élément interne. */
+static void g_scan_pending_extraction_init(GScanPendingExtraction *);
+
+/* Supprime toutes les références externes. */
+static void g_scan_pending_extraction_dispose(GScanPendingExtraction *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_scan_pending_extraction_finalize(GScanPendingExtraction *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Réduit une expression à une forme plus simple. */
+static ScanReductionState g_scan_pending_extraction_reduce(const GScanPendingExtraction *, GScanContext *, GScanScope *, GScanExpression **);
+
+/* Reproduit un accès en place dans une nouvelle instance. */
+static void g_scan_pending_extraction_copy(GScanPendingExtraction *, const GScanPendingExtraction *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       INTRODUCTION D'UNE NOUVELLE EXPRESSION                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une extraction d'élément de série interne. */
+G_DEFINE_TYPE(GScanPendingExtraction, g_scan_pending_extraction, G_TYPE_SCAN_NAMED_ACCESS);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des extractions d'éléments internes.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_pending_extraction_class_init(GScanPendingExtractionClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GScanExpressionClass *expr;             /* Version de classe parente   */
+    GScanNamedAccessClass *access;          /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_pending_extraction_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_scan_pending_extraction_finalize;
+
+    expr = G_SCAN_EXPRESSION_CLASS(klass);
+
+    expr->cmp_rich = (compare_expr_rich_fc)NULL;
+    expr->reduce = (reduce_expr_fc)g_scan_pending_extraction_reduce;
+
+    access = G_SCAN_NAMED_ACCESS_CLASS(klass);
+
+    access->copy = (copy_scan_access_fc)g_scan_pending_extraction_copy;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : extract = instance à initialiser.                            *
+*                                                                             *
+*  Description : Initialise une instance d'extraction d'élément interne.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_pending_extraction_init(GScanPendingExtraction *extract)
+{
+    extract->index = NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : extract = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_pending_extraction_dispose(GScanPendingExtraction *extract)
+{
+    g_clear_object(&extract->index);
+
+    G_OBJECT_CLASS(g_scan_pending_extraction_parent_class)->dispose(G_OBJECT(extract));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : extract = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_pending_extraction_finalize(GScanPendingExtraction *extract)
+{
+    G_OBJECT_CLASS(g_scan_pending_extraction_parent_class)->finalize(G_OBJECT(extract));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : target = désignation de l'objet d'appel à identifier.        *
+*                index  = indice de l'élément à extraire.                     *
+*                                                                             *
+*  Description : Organise l'extraction d'un élément d'une série interne.      *
+*                                                                             *
+*  Retour      : Fonction mise en place.                                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanExpression *g_scan_pending_extraction_new(const sized_string_t *target, GScanExpression *index)
+{
+    GScanExpression *result;                /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_SCAN_PENDING_EXTRACTION, NULL);
+
+    if (!g_scan_pending_extraction_create(G_SCAN_PENDING_EXTRACTION(result), target, index))
+        g_clear_object(&result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : extract = instance à initialiser pleinement.                 *
+*                target  = désignation de l'objet d'appel à identifier.       *
+*                index   = indice de l'élément à extraire.                    *
+*                                                                             *
+*  Description : Met en place une expression d'extraction d'élément interne.  *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_scan_pending_extraction_create(GScanPendingExtraction *extract, const sized_string_t *target, GScanExpression *index)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = g_scan_named_access_create(G_SCAN_NAMED_ACCESS(extract), target);
+    if (!result) goto exit;
+
+    extract->index = index;
+    g_object_ref(G_OBJECT(index));
+
+ exit:
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr  = expression à consulter.                              *
+*                ctx   = contexte de suivi de l'analyse courante.             *
+*                scope = portée courante des variables locales.               *
+*                out   = zone d'enregistrement de la réduction opérée. [OUT]  *
+*                                                                             *
+*  Description : Réduit une expression à une forme plus simple.               *
+*                                                                             *
+*  Retour      : Bilan de l'opération : false en cas d'erreur irrécupérable.  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static ScanReductionState g_scan_pending_extraction_reduce(const GScanPendingExtraction *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out)
+{
+    ScanReductionState result;              /* Etat synthétisé à retourner */
+    GScanNamedAccess *access;               /* Autre vision de l'expression*/
+    GScanRegisteredItem *resolved;          /* Cible concrète obtenue      */
+    GScanExpression *new;                   /* Nouvelle réduction obtenue  */
+    GObject *final;                         /* Expression ou élément ?     */
+    GScanExpression *new_next;              /* Nouvelle version du suivant */
+
+    access = G_SCAN_NAMED_ACCESS(expr);
+
+    resolved = _g_scan_named_access_prepare_reduction(access, ctx, scope);
+
+    if (resolved == NULL)
+        result = SRS_UNRESOLVABLE;
+
+    else
+    {
+        /* Actualisation nécessaire des arguments ? */
+
+        result = g_scan_expression_reduce(expr->index, ctx, scope, &new);
+
+        /* Suite des traitements */
+
+        if (result == SRS_WAIT_FOR_SCAN)
+        {
+            /**
+             * Si changement il y a eu...
+             */
+            if (new != expr->index)
+            {
+                *out = g_scan_pending_extraction_new(NULL, new);
+
+                /**
+                 * Fonctionnement équivalent de :
+                 *    g_scan_named_access_set_base(G_SCAN_NAMED_ACCESS(*out), resolved);
+                 */
+                G_SCAN_NAMED_ACCESS(*out)->resolved = resolved;
+                g_object_ref(G_OBJECT(resolved));
+
+                if (G_SCAN_NAMED_ACCESS(expr)->next != NULL)
+                    g_scan_named_access_attach_next(G_SCAN_NAMED_ACCESS(*out), G_SCAN_NAMED_ACCESS(expr)->next);
+
+            }
+
+        }
+
+        else if (result == SRS_REDUCED)
+        {
+            final = g_scan_registered_item_extract_at(resolved, new, ctx, scope);
+
+            if (final != NULL)
+            {
+                /**
+                 * Si le produit de l'appel à la fonction est une expression d'évaluation
+                 * classique, alors ce produit constitue la réduction finale de la chaîne.
+                 *
+                 * Ce cas de figure ne se rencontre normalement qu'en bout de chaîne.
+                 */
+                if (!G_IS_SCAN_REGISTERED_ITEM(final))
+                {
+                    if (access->next != NULL)
+                        result = SRS_UNRESOLVABLE;
+
+                    else
+                    {
+                        *out = G_SCAN_EXPRESSION(final);
+                        g_object_ref(G_OBJECT(final));
+
+                        result = SRS_REDUCED;
+
+                    }
+
+                }
+                else
+                {
+                    if (access->next != NULL)
+                    {
+                        new_next = g_scan_named_access_duplicate(access->next, G_SCAN_REGISTERED_ITEM(final));
+
+                        result = g_scan_expression_reduce(new_next, ctx, scope, out);
+
+                        g_object_unref(G_OBJECT(new_next));
+
+                    }
+
+                    /**
+                     * Le cas ci-après est typique de l'extension Kaitai : field[n]
+                     * renvoie vers une instance GScanRegisteredItem (GKaitaiBrowser).
+                     *
+                     * Il n'y a donc pas d'expression en jeu, et l'élément est le dernier
+                     * de la liste.
+                     */
+                    else
+                    {
+                        if (g_scan_registered_item_reduce(G_SCAN_REGISTERED_ITEM(final), ctx, scope, out))
+                            result = SRS_REDUCED;
+                        else
+                            result = SRS_UNRESOLVABLE;
+
+                    }
+
+                }
+
+            }
+
+            else
+                result = SRS_UNRESOLVABLE;
+
+            g_clear_object(&final);
+
+        }
+
+        /* Libération locale des arguments reconstruits */
+
+        g_clear_object(&new);
+
+        g_object_unref(G_OBJECT(resolved));
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : dest = emplacement d'enregistrement à constituer. [OUT]      *
+*                src  = expression source à copier.                           *
+*                                                                             *
+*  Description : Reproduit un accès en place dans une nouvelle instance.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_pending_extraction_copy(GScanPendingExtraction *dest, const GScanPendingExtraction *src)
+{
+    GScanNamedAccessClass *class;           /* Classe parente à solliciter */
+
+    class = G_SCAN_NAMED_ACCESS_CLASS(g_scan_pending_extraction_parent_class);
+
+    class->copy(G_SCAN_NAMED_ACCESS(dest), G_SCAN_NAMED_ACCESS(src));
+
+    dest->index = src->index;
+    g_object_ref(G_OBJECT(src->index));
+
+}
diff --git a/src/analysis/scan/exprs/extract.h b/src/analysis/scan/exprs/extract.h
new file mode 100644
index 0000000..8ed1cfa
--- /dev/null
+++ b/src/analysis/scan/exprs/extract.h
@@ -0,0 +1,56 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * extract.h - prototypes pour l'organisation d'une extraction d'un élément d'une série interne
+ *
+ * Copyright (C) 2023 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_SCAN_EXPRS_EXTRACT_H
+#define _ANALYSIS_SCAN_EXPRS_EXTRACT_H
+
+
+#include "../expr.h"
+#include "../../../common/szstr.h"
+
+
+
+#define G_TYPE_SCAN_PENDING_EXTRACTION            g_scan_pending_extraction_get_type()
+#define G_SCAN_PENDING_EXTRACTION(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_PENDING_EXTRACTION, GScanPendingExtraction))
+#define G_IS_SCAN_PENDING_EXTRACTION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_PENDING_EXTRACTION))
+#define G_SCAN_PENDING_EXTRACTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_PENDING_EXTRACTION, GScanPendingExtractionClass))
+#define G_IS_SCAN_PENDING_EXTRACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_PENDING_EXTRACTION))
+#define G_SCAN_PENDING_EXTRACTION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_PENDING_EXTRACTION, GScanPendingExtractionClass))
+
+
+/* Extraction d'un élément donné au sein d'une série interne (instance) */
+typedef struct _GScanPendingExtraction GScanPendingExtraction;
+
+/* Extraction d'un élément donné au sein d'une série interne (classe) */
+typedef struct _GScanPendingExtractionClass GScanPendingExtractionClass;
+
+
+/* Indique le type défini pour une extraction d'élément de série interne. */
+GType g_scan_pending_extraction_get_type(void);
+
+/* Organise l'extraction d'un élément d'une série interne. */
+GScanExpression *g_scan_pending_extraction_new(const sized_string_t *, GScanExpression *);
+
+
+
+#endif  /* _ANALYSIS_SCAN_EXPRS_EXTRACT_H */
diff --git a/src/analysis/scan/grammar.y b/src/analysis/scan/grammar.y
index c63dda7..2863e21 100644
--- a/src/analysis/scan/grammar.y
+++ b/src/analysis/scan/grammar.y
@@ -31,6 +31,7 @@ typedef void *yyscan_t;
 #include "exprs/arithmetic.h"
 #include "exprs/call.h"
 #include "exprs/counter.h"
+#include "exprs/extract.h"
 #include "exprs/handler.h"
 #include "exprs/intersect.h"
 #include "exprs/item.h"
@@ -274,7 +275,8 @@ YY_DECL;
 %type <expr> cexpression _cexpression
 
 %type <expr> literal
-%type <expr> item_chain
+%type <expr> chain_items
+%type <expr> chain_item
 %type <args_list> call_args
 %type <expr> logical_expr
 %type <expr> relational_expr
@@ -285,9 +287,9 @@ YY_DECL;
 %type <expr> pattern_set_items
 %type <expr> set
 %type <expr> set_items
-%type <expr> set_access
 %type <expr> intersection
 %type <expr> pattern_handler
+%type <expr> _pattern_handler
 
 
 
@@ -942,14 +944,13 @@ YY_DECL;
     cexpression : _cexpression { $$ = $1; if ($$ == NULL) { printf("ERROR !!!\n"); YYERROR; } }
 
       _cexpression : literal { $$ = $1; }
-                   | item_chain { $$ = $1; }
+                   | chain_items { $$ = $1; }
                    | logical_expr { $$ = $1; }
                    | relational_expr { $$ = $1; }
                    | string_op { $$ = $1; }
                    | arithm_expr { $$ = $1; }
                    | set_match_counter { $$ = $1; }
                    | set { $$ = $1; }
-                   | set_access { $$ = $1; }
                    | intersection { $$ = $1; }
                    | pattern_handler { $$ = $1; }
                    | "(" cexpression ")" { $$ = $2; }
@@ -993,42 +994,48 @@ YY_DECL;
                 {
                     $$ = g_scan_literal_expression_new(LVT_STRING, &$1);
                 }
+                | STRING "[" cexpression "]"
+                {
+                    GScanExpression *__src;
+                    __src = g_scan_literal_expression_new(LVT_STRING, &$1);
+                    $$ = g_scan_set_item_new(__src, $3);
+                    g_object_unref(G_OBJECT(__src));
+                    g_object_unref(G_OBJECT($3));
+                }
                 ;
 
-     item_chain : NAME { $$ = g_scan_named_access_new(&$1); }
-                | NAME "(" ")" { $$ = g_scan_pending_call_new(&$1, NULL, 0); }
-                | NAME "(" call_args ")"
+
+    chain_items : chain_item
                 {
-                    size_t __i;
-                    $$ = g_scan_pending_call_new(&$1, $3.args, $3.count);
-                    for (__i = 0; __i < $3.count; __i++)
-                        g_object_unref(G_OBJECT($3.args[__i]));
-                    free($3.args);
+                    $$ = $1;
                 }
-                | item_chain "." NAME
+                | chain_items "." chain_item
                 {
-                    GScanExpression *__next;
-                    __next = g_scan_named_access_new(&$3);
-                    g_scan_named_access_attach_next(G_SCAN_NAMED_ACCESS($1), G_SCAN_NAMED_ACCESS(__next));
+                    g_scan_named_access_attach_next(G_SCAN_NAMED_ACCESS($1), G_SCAN_NAMED_ACCESS($3));
                     $$ = $1;
                 }
-                | item_chain "." NAME "(" ")"
+                ;
+
+     chain_item : NAME
+                {
+                    $$ = g_scan_named_access_new(&$1);
+                }
+                | NAME "(" ")"
                 {
-                    GScanExpression *__next;
-                    __next = g_scan_pending_call_new(&$3, NULL, 0);
-                    g_scan_named_access_attach_next(G_SCAN_NAMED_ACCESS($1), G_SCAN_NAMED_ACCESS(__next));
-                    $$ = $1;
+                    $$ = g_scan_pending_call_new(&$1, NULL, 0);
                 }
-                | item_chain "." NAME "(" call_args ")"
+                | NAME "(" call_args ")"
                 {
-                    GScanExpression *__next;
                     size_t __i;
-                    __next = g_scan_pending_call_new(&$3, $5.args, $5.count);
-                    for (__i = 0; __i < $5.count; __i++)
-                        g_object_unref(G_OBJECT($5.args[__i]));
-                    free($5.args);
-                    g_scan_named_access_attach_next(G_SCAN_NAMED_ACCESS($1), G_SCAN_NAMED_ACCESS(__next));
-                    $$ = $1;
+                    $$ = g_scan_pending_call_new(&$1, $3.args, $3.count);
+                    for (__i = 0; __i < $3.count; __i++)
+                        g_object_unref(G_OBJECT($3.args[__i]));
+                    free($3.args);
+                }
+                | NAME "[" cexpression "]"
+                {
+                    $$ = g_scan_pending_extraction_new(&$1, $3);
+                    g_object_unref(G_OBJECT($3));
                 }
                 ;
 
@@ -1307,46 +1314,39 @@ relational_expr : cexpression "<" cexpression  { $$ = g_scan_relational_operatio
                    ;
 
 
-            set : "(" ")"
-                {
-                    $$ = g_scan_generic_set_new();
-                }
-                | "(" cexpression "," ")"
-                {
-                    $$ = g_scan_generic_set_new();
-                    g_scan_generic_set_add_item(G_SCAN_GENERIC_SET($$), $2);
-                    g_object_unref(G_OBJECT($2));
-                }
-                | "(" set_items ")"
-                {
-                    $$ = $2;
-                }
-                ;
-
-      set_items : cexpression "," cexpression
-                {
-                    $$ = g_scan_generic_set_new();
-                    g_scan_generic_set_add_item(G_SCAN_GENERIC_SET($$), $1);
-                    g_object_unref(G_OBJECT($1));
-                    g_scan_generic_set_add_item(G_SCAN_GENERIC_SET($$), $3);
-                    g_object_unref(G_OBJECT($3));
-                }
-                | set_items "," cexpression
-                {
-                    $$ = $1;
-                    g_scan_generic_set_add_item(G_SCAN_GENERIC_SET($$), $3);
-                    g_object_unref(G_OBJECT($3));
-                }
-                ;
+               set : "(" ")"
+                   {
+                       $$ = g_scan_generic_set_new();
+                   }
+                   | "(" cexpression "," ")"
+                   {
+                       $$ = g_scan_generic_set_new();
+                       g_scan_generic_set_add_item(G_SCAN_GENERIC_SET($$), $2);
+                       g_object_unref(G_OBJECT($2));
+                   }
+                   | "(" set_items ")"
+                   {
+                       $$ = $2;
+                   }
+                   ;
 
-        set_access : cexpression "[" cexpression "]"
+         set_items : cexpression "," cexpression
                    {
-                       $$ = g_scan_set_item_new($1, $3);
+                       $$ = g_scan_generic_set_new();
+                       g_scan_generic_set_add_item(G_SCAN_GENERIC_SET($$), $1);
                        g_object_unref(G_OBJECT($1));
+                       g_scan_generic_set_add_item(G_SCAN_GENERIC_SET($$), $3);
+                       g_object_unref(G_OBJECT($3));
+                   }
+                   | set_items "," cexpression
+                   {
+                       $$ = $1;
+                       g_scan_generic_set_add_item(G_SCAN_GENERIC_SET($$), $3);
                        g_object_unref(G_OBJECT($3));
                    }
                    ;
 
+
       intersection : cexpression "in" cexpression
                    {
                        $$ = g_scan_sets_intersection_new($1, $3);
@@ -1355,7 +1355,20 @@ relational_expr : cexpression "<" cexpression  { $$ = g_scan_relational_operatio
                    }
                    ;
 
-   pattern_handler : BYTES_ID
+
+   pattern_handler : _pattern_handler
+                   {
+                       $$ = $1;
+                   }
+                   | pattern_handler "[" cexpression "]"
+                   {
+                       $$ = g_scan_set_item_new($1, $3);
+                       g_object_unref(G_OBJECT($1));
+                       g_object_unref(G_OBJECT($3));
+                   }
+                   ;
+
+  _pattern_handler : BYTES_ID
                    {
                        GSearchPattern *__pat;
                        __pat = g_scan_rule_get_local_variable(*built_rule, $1.data);
diff --git a/src/analysis/scan/item-int.h b/src/analysis/scan/item-int.h
index 76431c9..a04b861 100644
--- a/src/analysis/scan/item-int.h
+++ b/src/analysis/scan/item-int.h
@@ -44,6 +44,9 @@ typedef bool (* reduce_registered_item_fc) (GScanRegisteredItem *, GScanContext
 /* Effectue un appel à une fonction enregistrée. */
 typedef bool (* run_registered_item_call_fc) (GScanRegisteredItem *, GScanExpression **, size_t, GScanContext *, GScanScope *, GObject **);
 
+/* Effectue une extraction d'élément à partir d'une série. */
+typedef GObject * (* extract_registered_item_at) (GScanRegisteredItem *, GScanExpression *, GScanContext *, GScanScope *);
+
 
 /* Expression d'évaluation généraliste (instance) */
 struct _GScanRegisteredItem
@@ -58,9 +61,11 @@ struct _GScanRegisteredItemClass
     GObjectClass parent;                    /* A laisser en premier        */
 
     get_registered_item_name_fc get_name;   /* Obtention du nom associé    */
+
     resolve_registered_item_fc resolve;     /* Opération de résolution     */
     reduce_registered_item_fc reduce;       /* Opération de réduction      */
     run_registered_item_call_fc run_call;   /* Appel à une fonction connue */
+    extract_registered_item_at extract;     /* Extraction d'un élément     */
 
 };
 
diff --git a/src/analysis/scan/item.c b/src/analysis/scan/item.c
index 930a334..509ad28 100644
--- a/src/analysis/scan/item.c
+++ b/src/analysis/scan/item.c
@@ -290,3 +290,36 @@ bool g_scan_registered_item_run_call(GScanRegisteredItem *item, GScanExpression
     return result;
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item  = élément d'appel à consulter.                         *
+*                index = indice de l'élément à cibler.                        *
+*                ctx   = contexte de suivi de l'analyse courante.             *
+*                scope = portée courante des variables locales.               *
+*                                                                             *
+*  Description : Effectue une extraction d'élément à partir d'une série.      *
+*                                                                             *
+*  Retour      : Elément de série obtenu ou NULL si erreur irrécupérable.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GObject *g_scan_registered_item_extract_at(GScanRegisteredItem *item, GScanExpression *index, GScanContext *ctx, GScanScope *scope)
+{
+    GObject *result;                        /* Elément récupéré à renvoyer */
+    GScanRegisteredItemClass *class;        /* Classe à activer            */
+
+    class = G_SCAN_REGISTERED_ITEM_GET_CLASS(item);
+
+    if (class->extract == NULL)
+        result = NULL;
+
+    else
+        result = class->extract(item, index, ctx, scope);
+
+    return result;
+
+}
diff --git a/src/analysis/scan/item.h b/src/analysis/scan/item.h
index 904064e..a6c56c3 100644
--- a/src/analysis/scan/item.h
+++ b/src/analysis/scan/item.h
@@ -64,6 +64,9 @@ bool g_scan_registered_item_reduce(GScanRegisteredItem *, GScanContext *, GScanS
 /* Effectue un appel à une fonction enregistrée. */
 bool g_scan_registered_item_run_call(GScanRegisteredItem *, GScanExpression **, size_t, GScanContext *, GScanScope *, GObject **);
 
+/* Effectue une extraction d'élément à partir d'une série. */
+GObject *g_scan_registered_item_extract_at(GScanRegisteredItem *, GScanExpression *, GScanContext *, GScanScope *);
+
 
 
 #endif  /* _ANALYSIS_SCAN_ITEM_H */
diff --git a/src/analysis/scan/space.c b/src/analysis/scan/space.c
index e4d5049..909b96d 100644
--- a/src/analysis/scan/space.c
+++ b/src/analysis/scan/space.c
@@ -24,7 +24,6 @@
 #include "space.h"
 
 
-#include <assert.h>
 #include <string.h>
 
 
diff --git a/tests/plugins/kaitai/__init__.py b/tests/plugins/kaitai/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/plugins/kaitai/rost.py b/tests/plugins/kaitai/rost.py
new file mode 100644
index 0000000..1950222
--- /dev/null
+++ b/tests/plugins/kaitai/rost.py
@@ -0,0 +1,170 @@
+#!/usr/bin/python3-dbg
+# -*- coding: utf-8 -*-
+
+import locale
+
+from chrysacase import ChrysalideTestCase
+from pychrysalide.analysis.contents import MemoryContent
+from pychrysalide.analysis.scan import ContentScanner
+from pychrysalide.analysis.scan import ScanOptions
+from pychrysalide.analysis.scan.patterns.backends import AcismBackend
+from pychrysalide import core
+from pychrysalide.plugins.kaitai.parsers import KaitaiStruct
+from pychrysalide.plugins.kaitai.rost import KaitaiTrigger
+
+
+class TestScansWithKaitai(ChrysalideTestCase):
+    """TestCase for ROST scan with the KaitaiStruct parsing."""
+
+    @classmethod
+    def setUpClass(cls):
+
+        super(TestScansWithKaitai, cls).setUpClass()
+
+        cls._options = ScanOptions()
+        cls._options.backend_for_data = AcismBackend
+
+
+    def ZZZtestSimpleKaitaiDefinitionForScanning(self):
+        """Rely on basic Kaitai simple definition for scanning."""
+
+        definitions = '''
+meta:
+  id: basic_test
+seq:
+  - id: field0
+    type: u1
+'''
+
+        kstruct = KaitaiStruct(definitions)
+
+        trigger = KaitaiTrigger(kstruct)
+
+        root_ns = core.get_rost_root_namespace()
+
+        ns = root_ns.resolve('kaitai')
+        ns.register_item(trigger)
+
+        ns = ns.resolve('basic_test')
+        self.assertEqual(ns, trigger)
+
+        cnt = MemoryContent(b'\x01\x02\x03')
+
+        rule = '''
+rule testing {
+
+   condition:
+      kaitai.basic_test.field0 == 1
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertIsNotNone(ctx)
+
+        self.assertFalse(ctx.has_match_for_rule('no_such_rule'))
+
+        self.assertTrue(ctx.has_match_for_rule('testing'))
+
+
+        definitions = '''
+meta:
+  id: other_basic_test
+seq:
+  - id: field0
+    type: u1
+  - id: field1
+    type: u1
+'''
+
+        kstruct = KaitaiStruct(definitions)
+
+        trigger = KaitaiTrigger(kstruct)
+
+        root_ns = core.get_rost_root_namespace()
+
+        ns = root_ns.resolve('kaitai')
+        ns.register_item(trigger)
+
+        ns = ns.resolve('other_basic_test')
+        self.assertEqual(ns, trigger)
+
+        cnt = MemoryContent(b'\x01\x02\x03')
+
+        rule = '''
+rule testing {
+
+   condition:
+      kaitai.other_basic_test.field0 == 1 and kaitai.other_basic_test.field1 == 2
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertIsNotNone(ctx)
+
+        self.assertTrue(ctx.has_match_for_rule('testing'))
+
+
+        rule = '''
+rule testing {
+
+   condition:
+      kaitai.other_basic_test.field0 == 1 and kaitai.other_basic_testXXXX.field1 == 2
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertIsNotNone(ctx)
+
+        self.assertFalse(ctx.has_match_for_rule('testing'))
+
+
+    def testKaitaiDefinitionWithListForScanning(self):
+        """Access list items from Kaitai definition when scanning with ROST."""
+
+        definitions = '''
+meta:
+  id: test_with_list
+seq:
+  - id: field0
+    type: u1
+    repeat: eos
+'''
+
+        kstruct = KaitaiStruct(definitions)
+
+        trigger = KaitaiTrigger(kstruct)
+
+        root_ns = core.get_rost_root_namespace()
+
+        ns = root_ns.resolve('kaitai')
+        ns.register_item(trigger)
+
+        ns = ns.resolve('test_with_list')
+        self.assertEqual(ns, trigger)
+
+        cnt = MemoryContent(b'\x01\x02\x03')
+
+        rule = '''
+rule testing {
+
+   condition:
+      kaitai.test_with_list.field0[0] == 1 and kaitai.test_with_list.field0[1] == 2 and kaitai.test_with_list.field0[2] == 3
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertIsNotNone(ctx)
+
+        self.assertTrue(ctx.has_match_for_rule('testing'))
-- 
cgit v0.11.2-87-g4458