From db3b204dd7a71b2f74a4e69b2159a96e3ab66614 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Mon, 30 Jan 2023 07:59:35 +0100
Subject: Save an initial version of rost.

---
 .gitignore                                         |    1 +
 configure.ac                                       |   40 +-
 plugins/pychrysalide/analysis/Makefile.am          |    3 +-
 plugins/pychrysalide/analysis/scan/Makefile.am     |   26 +
 plugins/pychrysalide/analysis/scan/constants.c     |  131 +
 plugins/pychrysalide/analysis/scan/constants.h     |   42 +
 plugins/pychrysalide/analysis/scan/context.c       |  266 ++
 plugins/pychrysalide/analysis/scan/context.h       |   45 +
 plugins/pychrysalide/analysis/scan/expr.c          |  349 +++
 plugins/pychrysalide/analysis/scan/expr.h          |   45 +
 plugins/pychrysalide/analysis/scan/func.c          |  207 ++
 plugins/pychrysalide/analysis/scan/func.h          |   45 +
 plugins/pychrysalide/analysis/scan/module.c        |  119 +
 plugins/pychrysalide/analysis/scan/module.h        |   42 +
 plugins/pychrysalide/analysis/scan/options.c       |  355 +++
 plugins/pychrysalide/analysis/scan/options.h       |   45 +
 .../analysis/scan/patterns/Makefile.am             |   20 +
 .../pychrysalide/analysis/scan/patterns/backend.c  |  202 ++
 .../pychrysalide/analysis/scan/patterns/backend.h  |   45 +
 .../analysis/scan/patterns/backends/Makefile.am    |   15 +
 .../analysis/scan/patterns/backends/acism.c        |  214 ++
 .../analysis/scan/patterns/backends/acism.h        |   45 +
 .../analysis/scan/patterns/backends/bitap.c        |  214 ++
 .../analysis/scan/patterns/backends/bitap.h        |   45 +
 .../analysis/scan/patterns/backends/module.c       |  106 +
 .../analysis/scan/patterns/backends/module.h       |   42 +
 .../pychrysalide/analysis/scan/patterns/module.c   |  109 +
 .../pychrysalide/analysis/scan/patterns/module.h   |   42 +
 plugins/pychrysalide/analysis/scan/scanner.c       |  313 +++
 plugins/pychrysalide/analysis/scan/scanner.h       |   45 +
 plugins/pychrysalide/analysis/scan/space.c         |  297 +++
 plugins/pychrysalide/analysis/scan/space.h         |   45 +
 src/Makefile.am                                    |   53 +-
 src/analysis/Makefile.am                           |    3 +-
 src/analysis/scan/Makefile.am                      |   67 +
 src/analysis/scan/cond-int.h                       |   63 +
 src/analysis/scan/cond.c                           |  220 ++
 src/analysis/scan/cond.h                           |   65 +
 src/analysis/scan/conds/Makefile.am                |   16 +
 src/analysis/scan/conds/binop-int.h                |   54 +
 src/analysis/scan/conds/binop.c                    |  265 ++
 src/analysis/scan/conds/binop.h                    |   68 +
 src/analysis/scan/conds/counter-int.h              |   53 +
 src/analysis/scan/conds/counter.c                  |  232 ++
 src/analysis/scan/conds/counter.h                  |   58 +
 src/analysis/scan/context-int.h                    |   87 +
 src/analysis/scan/context.c                        |  546 ++++
 src/analysis/scan/context.h                        |  100 +
 src/analysis/scan/core.c                           |   67 +
 src/analysis/scan/core.h                           |   37 +
 src/analysis/scan/decl.h                           |   40 +
 src/analysis/scan/expr-int.h                       |   78 +
 src/analysis/scan/expr.c                           |  331 +++
 src/analysis/scan/expr.h                           |   84 +
 src/analysis/scan/exprs/Makefile.am                |   24 +
 src/analysis/scan/exprs/arithmop-int.h             |   60 +
 src/analysis/scan/exprs/arithmop.c                 |  414 +++
 src/analysis/scan/exprs/arithmop.h                 |   67 +
 src/analysis/scan/exprs/boolop-int.h               |   60 +
 src/analysis/scan/exprs/boolop.c                   |  450 ++++
 src/analysis/scan/exprs/boolop.h                   |   65 +
 src/analysis/scan/exprs/call-int.h                 |   63 +
 src/analysis/scan/exprs/call.c                     |  426 +++
 src/analysis/scan/exprs/call.h                     |   59 +
 src/analysis/scan/exprs/literal-int.h              |   73 +
 src/analysis/scan/exprs/literal.c                  |  605 +++++
 src/analysis/scan/exprs/literal.h                  |   70 +
 src/analysis/scan/exprs/relop-int.h                |   60 +
 src/analysis/scan/exprs/relop.c                    |  374 +++
 src/analysis/scan/exprs/relop.h                    |   56 +
 src/analysis/scan/exprs/str-int.h                  |   61 +
 src/analysis/scan/exprs/str.c                      |  437 ++++
 src/analysis/scan/exprs/str.h                      |   67 +
 src/analysis/scan/func-int.h                       |   51 +
 src/analysis/scan/func.c                           |  126 +
 src/analysis/scan/func.h                           |   52 +
 src/analysis/scan/funcs/Makefile.am                |   15 +
 src/analysis/scan/funcs/datasize.c                 |  214 ++
 src/analysis/scan/funcs/datasize.h                 |   55 +
 src/analysis/scan/funcs/uint-int.h                 |   54 +
 src/analysis/scan/funcs/uint.c                     |  266 ++
 src/analysis/scan/funcs/uint.h                     |   56 +
 src/analysis/scan/grammar.y                        |  487 ++++
 src/analysis/scan/item-int.h                       |   61 +
 src/analysis/scan/item.c                           |  199 ++
 src/analysis/scan/item.h                           |   63 +
 src/analysis/scan/match-int.h                      |   56 +
 src/analysis/scan/match.c                          |  177 ++
 src/analysis/scan/match.h                          |   61 +
 src/analysis/scan/matches/Makefile.am              |   15 +
 src/analysis/scan/matches/bytes-int.h              |   60 +
 src/analysis/scan/matches/bytes.c                  |  286 ++
 src/analysis/scan/matches/bytes.h                  |   59 +
 src/analysis/scan/matches/pending.c                |  202 ++
 src/analysis/scan/matches/pending.h                |   76 +
 src/analysis/scan/options-int.h                    |   52 +
 src/analysis/scan/options.c                        |  238 ++
 src/analysis/scan/options.h                        |   68 +
 src/analysis/scan/pattern-int.h                    |   56 +
 src/analysis/scan/pattern.c                        |  210 ++
 src/analysis/scan/pattern.h                        |   65 +
 src/analysis/scan/patterns/Makefile.am             |   23 +
 src/analysis/scan/patterns/backend-int.h           |   70 +
 src/analysis/scan/patterns/backend.c               |  254 ++
 src/analysis/scan/patterns/backend.h               |   73 +
 src/analysis/scan/patterns/backends/Makefile.am    |   27 +
 src/analysis/scan/patterns/backends/acism-int.h    |  160 ++
 src/analysis/scan/patterns/backends/acism.c        | 1295 +++++++++
 src/analysis/scan/patterns/backends/acism.h        |   59 +
 src/analysis/scan/patterns/backends/bitap-int.h    |  118 +
 src/analysis/scan/patterns/backends/bitap.c        | 2766 ++++++++++++++++++++
 src/analysis/scan/patterns/backends/bitap.h        |   59 +
 src/analysis/scan/patterns/token-int.h             |   61 +
 src/analysis/scan/patterns/token.c                 |  193 ++
 src/analysis/scan/patterns/token.h                 |   62 +
 src/analysis/scan/patterns/tokens/Makefile.am      |   13 +
 src/analysis/scan/patterns/tokens/plain.c          |  374 +++
 src/analysis/scan/patterns/tokens/plain.h          |   67 +
 src/analysis/scan/rule-int.h                       |   59 +
 src/analysis/scan/rule.c                           |  383 +++
 src/analysis/scan/rule.h                           |   77 +
 src/analysis/scan/scanner-int.h                    |   63 +
 src/analysis/scan/scanner.c                        |  342 +++
 src/analysis/scan/scanner.h                        |   77 +
 src/analysis/scan/space-int.h                      |   55 +
 src/analysis/scan/space.c                          |  310 +++
 src/analysis/scan/space.h                          |   62 +
 src/analysis/scan/tokens.l                         |  306 +++
 src/core/core.c                                    |    9 +
 src/core/global.c                                  |   51 +
 src/core/global.h                                  |    7 +
 src/rost.c                                         |  316 +++
 tests/analysis/scan/expr.py                        |  169 ++
 tests/analysis/scan/exprs.py                       |  122 +
 tests/analysis/scan/func.py                        |   16 +
 tests/analysis/scan/grammar.py                     |  286 ++
 tests/analysis/scan/options.py                     |   16 +
 137 files changed, 21392 insertions(+), 26 deletions(-)
 create mode 100644 plugins/pychrysalide/analysis/scan/Makefile.am
 create mode 100644 plugins/pychrysalide/analysis/scan/constants.c
 create mode 100644 plugins/pychrysalide/analysis/scan/constants.h
 create mode 100644 plugins/pychrysalide/analysis/scan/context.c
 create mode 100644 plugins/pychrysalide/analysis/scan/context.h
 create mode 100644 plugins/pychrysalide/analysis/scan/expr.c
 create mode 100644 plugins/pychrysalide/analysis/scan/expr.h
 create mode 100644 plugins/pychrysalide/analysis/scan/func.c
 create mode 100644 plugins/pychrysalide/analysis/scan/func.h
 create mode 100644 plugins/pychrysalide/analysis/scan/module.c
 create mode 100644 plugins/pychrysalide/analysis/scan/module.h
 create mode 100644 plugins/pychrysalide/analysis/scan/options.c
 create mode 100644 plugins/pychrysalide/analysis/scan/options.h
 create mode 100644 plugins/pychrysalide/analysis/scan/patterns/Makefile.am
 create mode 100644 plugins/pychrysalide/analysis/scan/patterns/backend.c
 create mode 100644 plugins/pychrysalide/analysis/scan/patterns/backend.h
 create mode 100644 plugins/pychrysalide/analysis/scan/patterns/backends/Makefile.am
 create mode 100644 plugins/pychrysalide/analysis/scan/patterns/backends/acism.c
 create mode 100644 plugins/pychrysalide/analysis/scan/patterns/backends/acism.h
 create mode 100644 plugins/pychrysalide/analysis/scan/patterns/backends/bitap.c
 create mode 100644 plugins/pychrysalide/analysis/scan/patterns/backends/bitap.h
 create mode 100644 plugins/pychrysalide/analysis/scan/patterns/backends/module.c
 create mode 100644 plugins/pychrysalide/analysis/scan/patterns/backends/module.h
 create mode 100644 plugins/pychrysalide/analysis/scan/patterns/module.c
 create mode 100644 plugins/pychrysalide/analysis/scan/patterns/module.h
 create mode 100644 plugins/pychrysalide/analysis/scan/scanner.c
 create mode 100644 plugins/pychrysalide/analysis/scan/scanner.h
 create mode 100644 plugins/pychrysalide/analysis/scan/space.c
 create mode 100644 plugins/pychrysalide/analysis/scan/space.h
 create mode 100644 src/analysis/scan/Makefile.am
 create mode 100644 src/analysis/scan/cond-int.h
 create mode 100644 src/analysis/scan/cond.c
 create mode 100644 src/analysis/scan/cond.h
 create mode 100644 src/analysis/scan/conds/Makefile.am
 create mode 100644 src/analysis/scan/conds/binop-int.h
 create mode 100644 src/analysis/scan/conds/binop.c
 create mode 100644 src/analysis/scan/conds/binop.h
 create mode 100644 src/analysis/scan/conds/counter-int.h
 create mode 100644 src/analysis/scan/conds/counter.c
 create mode 100644 src/analysis/scan/conds/counter.h
 create mode 100644 src/analysis/scan/context-int.h
 create mode 100644 src/analysis/scan/context.c
 create mode 100644 src/analysis/scan/context.h
 create mode 100644 src/analysis/scan/core.c
 create mode 100644 src/analysis/scan/core.h
 create mode 100644 src/analysis/scan/decl.h
 create mode 100644 src/analysis/scan/expr-int.h
 create mode 100644 src/analysis/scan/expr.c
 create mode 100644 src/analysis/scan/expr.h
 create mode 100644 src/analysis/scan/exprs/Makefile.am
 create mode 100644 src/analysis/scan/exprs/arithmop-int.h
 create mode 100644 src/analysis/scan/exprs/arithmop.c
 create mode 100644 src/analysis/scan/exprs/arithmop.h
 create mode 100644 src/analysis/scan/exprs/boolop-int.h
 create mode 100644 src/analysis/scan/exprs/boolop.c
 create mode 100644 src/analysis/scan/exprs/boolop.h
 create mode 100644 src/analysis/scan/exprs/call-int.h
 create mode 100644 src/analysis/scan/exprs/call.c
 create mode 100644 src/analysis/scan/exprs/call.h
 create mode 100644 src/analysis/scan/exprs/literal-int.h
 create mode 100644 src/analysis/scan/exprs/literal.c
 create mode 100644 src/analysis/scan/exprs/literal.h
 create mode 100644 src/analysis/scan/exprs/relop-int.h
 create mode 100644 src/analysis/scan/exprs/relop.c
 create mode 100644 src/analysis/scan/exprs/relop.h
 create mode 100644 src/analysis/scan/exprs/str-int.h
 create mode 100644 src/analysis/scan/exprs/str.c
 create mode 100644 src/analysis/scan/exprs/str.h
 create mode 100644 src/analysis/scan/func-int.h
 create mode 100644 src/analysis/scan/func.c
 create mode 100644 src/analysis/scan/func.h
 create mode 100644 src/analysis/scan/funcs/Makefile.am
 create mode 100644 src/analysis/scan/funcs/datasize.c
 create mode 100644 src/analysis/scan/funcs/datasize.h
 create mode 100644 src/analysis/scan/funcs/uint-int.h
 create mode 100644 src/analysis/scan/funcs/uint.c
 create mode 100644 src/analysis/scan/funcs/uint.h
 create mode 100644 src/analysis/scan/grammar.y
 create mode 100644 src/analysis/scan/item-int.h
 create mode 100644 src/analysis/scan/item.c
 create mode 100644 src/analysis/scan/item.h
 create mode 100644 src/analysis/scan/match-int.h
 create mode 100644 src/analysis/scan/match.c
 create mode 100644 src/analysis/scan/match.h
 create mode 100644 src/analysis/scan/matches/Makefile.am
 create mode 100644 src/analysis/scan/matches/bytes-int.h
 create mode 100644 src/analysis/scan/matches/bytes.c
 create mode 100644 src/analysis/scan/matches/bytes.h
 create mode 100644 src/analysis/scan/matches/pending.c
 create mode 100644 src/analysis/scan/matches/pending.h
 create mode 100644 src/analysis/scan/options-int.h
 create mode 100644 src/analysis/scan/options.c
 create mode 100644 src/analysis/scan/options.h
 create mode 100644 src/analysis/scan/pattern-int.h
 create mode 100644 src/analysis/scan/pattern.c
 create mode 100644 src/analysis/scan/pattern.h
 create mode 100644 src/analysis/scan/patterns/Makefile.am
 create mode 100644 src/analysis/scan/patterns/backend-int.h
 create mode 100644 src/analysis/scan/patterns/backend.c
 create mode 100644 src/analysis/scan/patterns/backend.h
 create mode 100644 src/analysis/scan/patterns/backends/Makefile.am
 create mode 100644 src/analysis/scan/patterns/backends/acism-int.h
 create mode 100644 src/analysis/scan/patterns/backends/acism.c
 create mode 100644 src/analysis/scan/patterns/backends/acism.h
 create mode 100644 src/analysis/scan/patterns/backends/bitap-int.h
 create mode 100644 src/analysis/scan/patterns/backends/bitap.c
 create mode 100644 src/analysis/scan/patterns/backends/bitap.h
 create mode 100644 src/analysis/scan/patterns/token-int.h
 create mode 100644 src/analysis/scan/patterns/token.c
 create mode 100644 src/analysis/scan/patterns/token.h
 create mode 100644 src/analysis/scan/patterns/tokens/Makefile.am
 create mode 100644 src/analysis/scan/patterns/tokens/plain.c
 create mode 100644 src/analysis/scan/patterns/tokens/plain.h
 create mode 100644 src/analysis/scan/rule-int.h
 create mode 100644 src/analysis/scan/rule.c
 create mode 100644 src/analysis/scan/rule.h
 create mode 100644 src/analysis/scan/scanner-int.h
 create mode 100644 src/analysis/scan/scanner.c
 create mode 100644 src/analysis/scan/scanner.h
 create mode 100644 src/analysis/scan/space-int.h
 create mode 100644 src/analysis/scan/space.c
 create mode 100644 src/analysis/scan/space.h
 create mode 100644 src/analysis/scan/tokens.l
 create mode 100644 src/rost.c
 create mode 100644 tests/analysis/scan/expr.py
 create mode 100644 tests/analysis/scan/exprs.py
 create mode 100644 tests/analysis/scan/func.py
 create mode 100644 tests/analysis/scan/grammar.py
 create mode 100644 tests/analysis/scan/options.py

diff --git a/.gitignore b/.gitignore
index 58ea9c8..dd160e3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -69,6 +69,7 @@ resources.[ch]
 # Binaries
 src/chrysalide
 src/chrysalide-hub
+src/rost
 tools/d2c/d2c
 
 # Misc
diff --git a/configure.ac b/configure.ac
index 492634b..9e4375c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,8 +6,8 @@
 
 m4_include([gitrev.m4])
 
-AC_PREREQ(2.59)
-AC_INIT([chrysalide], [gitversion], [nocbos@gmail.com])
+AC_PREREQ([2.71])
+AC_INIT([chrysalide],[gitversion],[nocbos@gmail.com])
 
 AC_CONFIG_HEADERS([config.h])
 AC_CONFIG_MACRO_DIR([m4])
@@ -33,7 +33,9 @@ AC_PROG_LEX
 AC_PROG_YACC
 AC_PROG_INSTALL
 AC_PROG_MAKE_SET
-AC_PROG_LIBTOOL
+LT_INIT
+
+CFLAGS=""
 
 AC_EGREP_CPP(yes,
 [#ifdef __PIE__
@@ -58,7 +60,15 @@ AC_CHECK_LIB([dl], [dlopen])
 
 AC_HEADER_DIRENT
 AC_HEADER_STDBOOL
-AC_HEADER_STDC
+m4_warn([obsolete],
+[The preprocessor macro `STDC_HEADERS' is obsolete.
+  Except in unusual embedded environments, you can safely include all
+  ISO C90 headers unconditionally.])dnl
+# Autoupdate added the next two lines to ensure that your configure
+# script's behavior did not change.  They are probably safe to remove.
+AC_CHECK_INCLUDES_DEFAULT
+AC_PROG_EGREP
+
 AC_CHECK_HEADERS([malloc.h])
 AC_CHECK_HEADERS([netdb.h])
 AC_CHECK_HEADERS([stdlib.h])
@@ -292,7 +302,7 @@ if test "x$enable_debug" = "xyes"; then
    DEBUG_CPPFLAGS="-DDEBUG"
    DEBUG_CFLAGS="-O0 -ggdb -gdwarf-2"
 else
-   DEBUG_CPPFLAGS="-DNDEBUG"
+   DEBUG_CPPFLAGS="-Ofast -DNDEBUG"
 fi
 
 
@@ -305,6 +315,7 @@ WARNING_CFLAGS="-Wall -Wimplicit -Wreturn-type -Wunused -Wswitch -Wcomment -Wuni
 # _BSD_SOURCE: htobe64, be64toh
 # _XOPEN_SOURCE: strdup, snprintf
 # _ISOC99_SOURCE: INFINITY; NAN
+# _GNU_SOURCE: strcasestr
 # GTK_DISABLE_DEPRECATED: on reste conforme au C99
 #COMPLIANCE_FLAGS="-D_BSD_SOURCE -D_GNU_SOURCE -DGTK_DISABLE_DEPRECATED"
 COMPLIANCE_CPPFLAGS="-D_DEFAULT_SOURCE -D_GNU_SOURCE"
@@ -617,6 +628,9 @@ AC_CONFIG_FILES([Makefile
                  plugins/pychrysalide/analysis/db/Makefile
                  plugins/pychrysalide/analysis/db/items/Makefile
                  plugins/pychrysalide/analysis/disass/Makefile
+                 plugins/pychrysalide/analysis/scan/Makefile
+                 plugins/pychrysalide/analysis/scan/patterns/Makefile
+                 plugins/pychrysalide/analysis/scan/patterns/backends/Makefile
                  plugins/pychrysalide/analysis/storage/Makefile
                  plugins/pychrysalide/analysis/types/Makefile
                  plugins/pychrysalide/arch/Makefile
@@ -658,6 +672,14 @@ AC_CONFIG_FILES([Makefile
                  src/analysis/disass/Makefile
                  src/analysis/human/Makefile
                  src/analysis/human/asm/Makefile
+                 src/analysis/scan/Makefile
+                 src/analysis/scan/conds/Makefile
+                 src/analysis/scan/exprs/Makefile
+                 src/analysis/scan/funcs/Makefile
+                 src/analysis/scan/matches/Makefile
+                 src/analysis/scan/patterns/Makefile
+                 src/analysis/scan/patterns/backends/Makefile
+                 src/analysis/scan/patterns/tokens/Makefile
                  src/analysis/storage/Makefile
                  src/analysis/types/Makefile
                  src/arch/Makefile
@@ -709,7 +731,7 @@ echo -n $PACKAGE r
 echo AC_PACKAGE_VERSION
 
 echo
-echo The GLib and object library.................. : $libgobj_version
+echo The GLib type, object and signal library..... : $libgobj_version
 echo The thread support for GLib.................. : $libgthread_version
 echo The dynamic module loader for GLib........... : $libgmod_version
 echo The GNU Image Manipulation Program Toolkit... : $libgtk_version
@@ -733,6 +755,12 @@ else
    disable_gtk_support="yes"
 fi
 
+if test "x$enable_curl_support" = "xyes"; then
+   disable_curl_support="no"
+else
+   disable_curl_support="yes"
+fi
+
 if test "x$enable_python_bindings" = "xyes"; then
    disable_python_bindings="no"
 else
diff --git a/plugins/pychrysalide/analysis/Makefile.am b/plugins/pychrysalide/analysis/Makefile.am
index 67cf373..43e8ed2 100644
--- a/plugins/pychrysalide/analysis/Makefile.am
+++ b/plugins/pychrysalide/analysis/Makefile.am
@@ -19,6 +19,7 @@ libpychrysaanalysis_la_LIBADD =				\
 	contents/libpychrysaanalysiscontents.la	\
 	db/libpychrysaanalysisdb.la				\
 	disass/libpychrysaanalysisdisass.la		\
+	scan/libpychrysaanalysisscan.la			\
 	storage/libpychrysaanalysisstorage.la	\
 	types/libpychrysaanalysistypes.la
 
@@ -31,4 +32,4 @@ devdir = $(includedir)/chrysalide/$(subdir)
 dev_HEADERS = $(libpychrysaanalysis_la_SOURCES:%c=)
 
 
-SUBDIRS = contents db disass storage types
+SUBDIRS = contents db disass scan storage types
diff --git a/plugins/pychrysalide/analysis/scan/Makefile.am b/plugins/pychrysalide/analysis/scan/Makefile.am
new file mode 100644
index 0000000..80cfa8c
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/Makefile.am
@@ -0,0 +1,26 @@
+
+noinst_LTLIBRARIES = libpychrysaanalysisscan.la
+
+libpychrysaanalysisscan_la_SOURCES =		\
+	constants.h constants.c					\
+	context.h context.c						\
+	expr.h expr.c							\
+	func.h func.c							\
+	module.h module.c						\
+	options.h options.c						\
+	scanner.h scanner.c						\
+	space.h space.c
+
+libpychrysaanalysisscan_la_LIBADD =			\
+	patterns/libpychrysaanalysisscanpatterns.la
+
+libpychrysaanalysisscan_la_CFLAGS = $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) $(TOOLKIT_CFLAGS) \
+	-I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
+
+
+devdir = $(includedir)/chrysalide/$(subdir)
+
+dev_HEADERS = $(libpychrysaanalysisscan_la_SOURCES:%c=)
+
+
+SUBDIRS = patterns
diff --git a/plugins/pychrysalide/analysis/scan/constants.c b/plugins/pychrysalide/analysis/scan/constants.c
new file mode 100644
index 0000000..87f3ae8
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/constants.c
@@ -0,0 +1,131 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants.c - ajout des constantes de base pour les types
+ *
+ * Copyright (C) 2020 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 "constants.h"
+
+
+#include <analysis/scan/expr.h>
+
+
+#include "../../helpers.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type = type dont le dictionnaire est à compléter.            *
+*                                                                             *
+*  Description : Définit les constantes relatives aux expressions de scan.    *
+*                                                                             *
+*  Retour      : true en cas de succès de l'opération, false sinon.           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool define_expression_value_type_constants(PyTypeObject *type)
+{
+    bool result;                            /* Bilan à retourner           */
+    PyObject *values;                       /* Groupe de valeurs à établir */
+
+    values = PyDict_New();
+
+    result = add_const_to_group(values, "BOOLEAN", EVT_BOOLEAN);
+    if (result) result = add_const_to_group(values, "INTEGER", EVT_INTEGER);
+    if (result) result = add_const_to_group(values, "STRING", EVT_STRING);
+    if (result) result = add_const_to_group(values, "REG_EXPR", EVT_REG_EXPR);
+    if (result) result = add_const_to_group(values, "COUNT", EVT_COUNT);
+    if (result) result = add_const_to_group(values, "PENDING", EVT_PENDING);
+    if (result) result = add_const_to_group(values, "UNRESOLVABLE", EVT_UNRESOLVABLE);
+
+    if (!result)
+    {
+        Py_DECREF(values);
+        goto exit;
+    }
+
+    result = attach_constants_group_to_type(type, false, "ExprValueType", values,
+                                            "Natural type equivalent to a given scan expression.");
+
+ exit:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  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 constante ExprValueType.               *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_expression_value_type(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+    unsigned long value;                    /* Valeur transcrite           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)&PyLong_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 ExprValueType");
+            break;
+
+        case 1:
+            value = PyLong_AsUnsignedLong(arg);
+
+            if (value > EVT_COUNT)
+            {
+                PyErr_SetString(PyExc_TypeError, "invalid value for ExprValueType");
+                result = 0;
+            }
+
+            else
+                *((ExprValueType *)dst) = value;
+
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/scan/constants.h b/plugins/pychrysalide/analysis/scan/constants.h
new file mode 100644
index 0000000..65eb7bc
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/constants.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants.h - prototypes pour l'ajout des constantes de base pour les types
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_CONSTANTS_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_CONSTANTS_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Définit les constantes relatives aux expressions de scan. */
+bool define_expression_value_type_constants(PyTypeObject *);
+
+/* Tente de convertir en constante ExprValueType. */
+int convert_to_expression_value_type(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_CONSTANTS_H */
diff --git a/plugins/pychrysalide/analysis/scan/context.c b/plugins/pychrysalide/analysis/scan/context.c
new file mode 100644
index 0000000..1b418ea
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/context.c
@@ -0,0 +1,266 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * context.c - équivalent Python du fichier "analysis/scan/context.c"
+ *
+ * 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "context.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <analysis/content.h>
+#include <analysis/scan/context-int.h>
+#include <analysis/scan/expr.h>
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+#include <plugins/pychrysalide/analysis/content.h>
+#include <plugins/pychrysalide/analysis/scan/expr.h>
+
+
+
+CREATE_DYN_CONSTRUCTOR(scan_context, G_TYPE_SCAN_CONTEXT);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_scan_context_init(PyObject *, PyObject *, PyObject *);
+
+/* Indique si une correspondance globale a pu être établie. */
+static PyObject *py_scan_context_has_match_for_rule(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_scan_context_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    int ret;                                /* Bilan de lecture des args.  */
+
+#define SCAN_CONTEXT_DOC                                            \
+    "A ScanContext object tracks results of a run analysis process" \
+    " against binary contents.\n"                                   \
+    "\n"                                                            \
+    "Instances can be created using the following constructor:\n"   \
+    "\n"                                                            \
+    "    ScanContext()"
+
+    /* Récupération des paramètres */
+
+    ret = PyArg_ParseTuple(args, "");
+    if (!ret) return -1;
+
+    /* Initialisation d'un objet GLib */
+
+    ret = forward_pygobjet_init(self);
+    if (ret == -1) return -1;
+
+    return 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe représentant un format.                        *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Indique si une correspondance globale a pu être établie.     *
+*                                                                             *
+*  Retour      : Bilan final d'une analyse (False par défaut).                *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_scan_context_has_match_for_rule(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Contexte de suivi à renvoyer*/
+    const char *name;                       /* Désignation de règle        */
+    int ret;                                /* Bilan de lecture des args.  */
+    GScanContext *context;                  /* Contexte de suivi d'analyse */
+    bool matched;                           /* Bilan d'analyse à renvoyer  */
+
+#define SCAN_CONTEXT_HAS_MATCH_FOR_RULE_METHOD PYTHON_METHOD_DEF    \
+(                                                                   \
+    has_match_for_rule, "$self, name, /",                           \
+    METH_VARARGS, py_scan_context,                                  \
+    "Provide the match status for a given scan rule.\n"             \
+    "\n"                                                            \
+    "The *name* argument points to the registered rule to query.\n" \
+    "\n"                                                            \
+    "The method returns the scan final status as a boolean: *True*" \
+    " in case of match, *False* otherwise."                         \
+)
+
+    ret = PyArg_ParseTuple(args, "s", &name);
+    if (!ret) return NULL;
+
+    context = G_SCAN_CONTEXT(pygobject_get(self));
+
+    matched = g_scan_context_has_match_for_rule(context, name);
+
+    result = matched ? Py_True : Py_False;
+    Py_INCREF(result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit un accès à une définition de type à diffuser.        *
+*                                                                             *
+*  Retour      : Définition d'objet pour Python.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyTypeObject *get_python_scan_context_type(void)
+{
+    static PyMethodDef py_scan_context_methods[] = {
+        SCAN_CONTEXT_HAS_MATCH_FOR_RULE_METHOD,
+        { NULL }
+    };
+
+    static PyGetSetDef py_scan_context_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_scan_context_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.scan.ScanContext",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = SCAN_CONTEXT_DOC,
+
+        .tp_methods     = py_scan_context_methods,
+        .tp_getset      = py_scan_context_getseters,
+
+        .tp_init        = py_scan_context_init,
+        .tp_new         = py_scan_context_new,
+
+    };
+
+    return &py_scan_context_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide.....scan.ScanContext.  *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_python_scan_context_is_registered(void)
+{
+    PyTypeObject *type;                     /* Type Python 'ScanContext'   */
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_scan_context_type();
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.analysis.scan");
+
+        dict = PyModule_GetDict(module);
+
+        if (!register_class_for_pygobject(dict, G_TYPE_SCAN_CONTEXT, type, &PyGObject_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 contexte de suivi d'analyse.           *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_scan_context(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_scan_context_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 scan context");
+            break;
+
+        case 1:
+            *((GScanContext **)dst) = G_SCAN_CONTEXT(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/scan/context.h b/plugins/pychrysalide/analysis/scan/context.h
new file mode 100644
index 0000000..477205b
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/context.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * context.h - prototypes pour l'équivalent Python du fichier "analysis/scan/context.h"
+ *
+ * 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_CONTEXT_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_CONTEXT_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_scan_context_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.scan.ScanContext'. */
+bool ensure_python_scan_context_is_registered(void);
+
+/* Tente de convertir en contexte de suivi d'analyse. */
+int convert_to_scan_context(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_CONTEXT_H */
diff --git a/plugins/pychrysalide/analysis/scan/expr.c b/plugins/pychrysalide/analysis/scan/expr.c
new file mode 100644
index 0000000..14d536f
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/expr.c
@@ -0,0 +1,349 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * expr.c - équivalent Python du fichier "analysis/scan/expr.c"
+ *
+ * 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "expr.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <analysis/content.h>
+#include <analysis/scan/expr-int.h>
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+#include <plugins/pychrysalide/analysis/content.h>
+#include <plugins/pychrysalide/glibext/comparison.h>
+
+
+#include "constants.h"
+
+
+
+/* Initialise la classe générique des expressions d'évaluation. */
+static void py_scan_expression_init_gclass(GScanExpressionClass *, gpointer);
+
+CREATE_DYN_ABSTRACT_CONSTRUCTOR(scan_expression, G_TYPE_SCAN_EXPRESSION, py_scan_expression_init_gclass);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_scan_expression_init(PyObject *, PyObject *, PyObject *);
+
+/* Réalise une comparaison entre objets selon un critère précis. */
+static bool py_scan_expression_compare_rich_wrapper(const GScanExpression *, const GScanExpression *, RichCmpOperation, bool *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : class  = classe à initialiser.                               *
+*                unused = données non utilisées ici.                          *
+*                                                                             *
+*  Description : Initialise la classe générique des expressions d'évaluation. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void py_scan_expression_init_gclass(GScanExpressionClass *class, gpointer unused)
+{
+    class->cmp_rich = py_scan_expression_compare_rich_wrapper;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  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_scan_expression_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    ExprValueType vtype;                    /* Type de valeur représentée  */
+    int ret;                                /* Bilan de lecture des args.  */
+    GScanExpression *expr;                  /* Création GLib à transmettre */
+
+    static char *kwlist[] = { "vtype", NULL };
+
+#define SCAN_EXPRESSION_DOC                                             \
+    "A ScanExpression is an abstract object which defines an expression"\
+    " involved in data matching when running a scan.\n"                 \
+    "\n"                                                                \
+    "Calls to the *__init__* constructor of this abstract object expect"\
+    " the following arguments as keyword parameters:\n"                 \
+    "* *vtype*: type of the value carried by the expression, as a"      \
+    " pychrysalide.analysis.scan.ScanExpression.ExprValueType value."   \
+    "\n"                                                                \
+    "The following methods have to be defined for new classes:\n"       \
+    "* pychrysalide.analysis.scan.ScanExpression._cmp_rich().\n"
+
+    /* Récupération des paramètres */
+
+    ret = PyArg_ParseTupleAndKeywords(args, kwds, "O&", kwlist, convert_to_expression_value_type, &vtype);
+    if (!ret) return -1;
+
+    /* Initialisation d'un objet GLib */
+
+    ret = forward_pygobjet_init(self);
+    if (ret == -1) return -1;
+
+    /* Eléments de base */
+
+    expr = G_SCAN_EXPRESSION(pygobject_get(self));
+
+    if (!g_scan_expression_create(expr, vtype))
+    {
+        PyErr_SetString(PyExc_ValueError, _("Unable to create scan expression."));
+        return -1;
+    }
+
+    return 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item   = premier objet à cnsulter pour une comparaison.      *
+*                other  = second objet à cnsulter pour une comparaison.       *
+*                op     = opération de comparaison à réaliser.                *
+*                status = bilan des opérations de comparaison. [OUT]          *
+*                                                                             *
+*  Description : Réalise une comparaison entre objets selon un critère précis.*
+*                                                                             *
+*  Retour      : true si la comparaison a pu être effectuée, false sinon.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool py_scan_expression_compare_rich_wrapper(const GScanExpression *item, const GScanExpression *other, RichCmpOperation op, bool *status)
+{
+    bool result;                            /* Etat à retourner            */
+    PyGILState_STATE gstate;                /* Sauvegarde d'environnement  */
+    PyObject *pyobj;                        /* Objet Python concerné       */
+    PyObject *args;                         /* Arguments pour l'appel      */
+    PyObject *pyret;                        /* Bilan de consultation       */
+    int ret;                                /* Bilan d'une conversion      */
+
+#define SCAN_EXPRESSION_CMP_RICH_WRAPPER PYTHON_WRAPPER_DEF             \
+(                                                                       \
+    _cmp_rich, "$self, other, op, /",                                   \
+    METH_VARARGS,                                                       \
+    "Abstract method used to compare the expression against another"    \
+    " one.\n"                                                           \
+    "\n"                                                                \
+    "The second *other* instance is built from the same type as *self*."\
+    " The *op* argument points to a"                                    \
+    " pychrysalide.glibext.ComparableItem.RichCmpOperation mode"        \
+    " describing the expected comparison.\n"                            \
+    "\n"                                                                \
+    "The result is a boolean status or *None* if the comparison"        \
+    " process is undefined."                                            \
+)
+
+    result = false;
+
+    gstate = PyGILState_Ensure();
+
+    pyobj = pygobject_new(G_OBJECT(item));
+
+    if (has_python_method(pyobj, "_cmp_rich"))
+    {
+        args = PyTuple_New(2);
+        PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(other)));
+        PyTuple_SetItem(args, 1, cast_with_constants_group_from_type(get_python_comparable_item_type(),
+                                                                     "RichCmpOperation", op));
+
+        pyret = run_python_method(pyobj, "_cmp_rich", args);
+
+        if (pyret != NULL)
+        {
+            ret = PyBool_Check(pyret);
+
+            if (ret)
+            {
+                *status = (pyret == Py_True);
+                result = true;
+            }
+
+            Py_DECREF(pyret);
+
+        }
+
+        Py_DECREF(args);
+
+    }
+
+    Py_DECREF(pyobj);
+
+    PyGILState_Release(gstate);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit un accès à une définition de type à diffuser.        *
+*                                                                             *
+*  Retour      : Définition d'objet pour Python.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyTypeObject *get_python_scan_expression_type(void)
+{
+    static PyMethodDef py_scan_expression_methods[] = {
+        SCAN_EXPRESSION_CMP_RICH_WRAPPER,
+        { NULL }
+    };
+
+    static PyGetSetDef py_scan_expression_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_scan_expression_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.scan.ScanExpression",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = SCAN_EXPRESSION_DOC,
+
+        .tp_methods     = py_scan_expression_methods,
+        .tp_getset      = py_scan_expression_getseters,
+
+        .tp_init        = py_scan_expression_init,
+        .tp_new         = py_scan_expression_new,
+
+    };
+
+    return &py_scan_expression_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide...scan.ScanExpression'.*
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_python_scan_expression_is_registered(void)
+{
+    PyTypeObject *type;                     /* Type Python 'ScanExpression'*/
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_scan_expression_type();
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.analysis.scan");
+
+        dict = PyModule_GetDict(module);
+
+        if (!ensure_python_comparable_item_is_registered())
+            return false;
+
+        if (!register_class_for_pygobject(dict, G_TYPE_SCAN_EXPRESSION, type, &PyGObject_Type))
+            return false;
+
+        if (!define_expression_value_type_constants(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 expression d'évaluation généraliste.   *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_scan_expression(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_scan_expression_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 match expression");
+            break;
+
+        case 1:
+            *((GScanExpression **)dst) = G_SCAN_EXPRESSION(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/scan/expr.h b/plugins/pychrysalide/analysis/scan/expr.h
new file mode 100644
index 0000000..00ab28d
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/expr.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * expr.h - prototypes pour l'équivalent Python du fichier "analysis/scan/expr.h"
+ *
+ * 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_EXPR_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_EXPR_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_scan_expression_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.scan.ScanExpression'. */
+bool ensure_python_scan_expression_is_registered(void);
+
+/* Tente de convertir en fonction d'analyse pour scan. */
+int convert_to_scan_expression(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_EXPR_H */
diff --git a/plugins/pychrysalide/analysis/scan/func.c b/plugins/pychrysalide/analysis/scan/func.c
new file mode 100644
index 0000000..61731ec
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/func.c
@@ -0,0 +1,207 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * func.c - équivalent Python du fichier "analysis/scan/func.c"
+ *
+ * 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "func.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <analysis/content.h>
+#include <analysis/scan/func-int.h>
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+#include <plugins/pychrysalide/analysis/content.h>
+
+
+
+CREATE_DYN_ABSTRACT_CONSTRUCTOR(scan_function, G_TYPE_SCAN_FUNCTION, NULL);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_scan_function_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_scan_function_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    int ret;                                /* Bilan de lecture des args.  */
+
+#define SCAN_FUNCTION_DOC                                               \
+    "A ScanFunction instance introduces a new method to analyze data"   \
+    " while scanning binary content.\n"                                 \
+    "\n"                                                                \
+    "Instances can be created using the following constructor:\n"       \
+    "\n"                                                                \
+    "    ScanFunction()"
+
+    /* Initialisation d'un objet GLib */
+
+    ret = forward_pygobjet_init(self);
+    if (ret == -1) 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_scan_function_type(void)
+{
+    static PyMethodDef py_scan_function_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_scan_function_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_scan_function_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.scan.ScanFunction",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT,
+
+        .tp_doc         = SCAN_FUNCTION_DOC,
+
+        .tp_methods     = py_scan_function_methods,
+        .tp_getset      = py_scan_function_getseters,
+
+        .tp_init        = py_scan_function_init,
+        .tp_new         = py_scan_function_new,
+
+    };
+
+    return &py_scan_function_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide....scan.ScanFunction'. *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_python_scan_function_is_registered(void)
+{
+    PyTypeObject *type;                     /* Type Python 'ScanFunction'  */
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_scan_function_type();
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.analysis.scan");
+
+        dict = PyModule_GetDict(module);
+
+        if (!register_class_for_pygobject(dict, G_TYPE_SCAN_FUNCTION, type, &PyGObject_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 fonction d'analyse pour scan.          *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_scan_function(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_scan_function_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 scan function");
+            break;
+
+        case 1:
+            *((GScanFunction **)dst) = G_SCAN_FUNCTION(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/scan/func.h b/plugins/pychrysalide/analysis/scan/func.h
new file mode 100644
index 0000000..d5d59f0
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/func.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * func.h - prototypes pour l'équivalent Python du fichier "analysis/scan/func.h"
+ *
+ * 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_FUNC_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_FUNC_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_scan_function_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.scan.ScanFunction'. */
+bool ensure_python_scan_function_is_registered(void);
+
+/* Tente de convertir en fonction d'analyse pour scan. */
+int convert_to_scan_function(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_FUNC_H */
diff --git a/plugins/pychrysalide/analysis/scan/module.c b/plugins/pychrysalide/analysis/scan/module.c
new file mode 100644
index 0000000..48b7100
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/module.c
@@ -0,0 +1,119 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire scan en tant que module
+ *
+ * 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "module.h"
+
+
+#include <assert.h>
+
+
+#include "context.h"
+#include "expr.h"
+#include "func.h"
+#include "options.h"
+#include "scanner.h"
+#include "space.h"
+#include "patterns/module.h"
+#include "../../helpers.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : super = module dont la définition est à compléter.           *
+*                                                                             *
+*  Description : Ajoute le module 'analysis.scan' à un module Python.         *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool add_analysis_scan_module(PyObject *super)
+{
+    bool result;                            /* Bilan à retourner           */
+    PyObject *module;                       /* Sous-module mis en place    */
+
+#define PYCHRYSALIDE_ANALYSIS_SCAN_MODULE_DOC                   \
+    "This module provide all the features useful for scanning"  \
+    " binary contents."
+
+    static PyModuleDef py_chrysalide_analysis_scan_module = {
+
+        .m_base = PyModuleDef_HEAD_INIT,
+
+        .m_name = "pychrysalide.analysis.scan",
+        .m_doc = PYCHRYSALIDE_ANALYSIS_SCAN_MODULE_DOC,
+
+        .m_size = -1,
+
+    };
+
+    module = build_python_module(super, &py_chrysalide_analysis_scan_module);
+
+    result = (module != NULL);
+
+    if (result) result = add_analysis_scan_patterns_module(module);
+
+    if (!result)
+        Py_XDECREF(module);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Intègre les objets du module 'analysis.scan'.                *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool populate_analysis_scan_module(void)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = true;
+
+    if (result) result = ensure_python_content_scanner_is_registered();
+    if (result) result = ensure_python_scan_context_is_registered();
+    if (result) result = ensure_python_scan_expression_is_registered();
+    if (result) result = ensure_python_scan_function_is_registered();
+    if (result) result = ensure_python_scan_options_is_registered();
+    if (result) result = ensure_python_scan_namespace_is_registered();
+
+    if (result) result = populate_analysis_scan_patterns_module();
+
+    assert(result);
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/scan/module.h b/plugins/pychrysalide/analysis/scan/module.h
new file mode 100644
index 0000000..a5e84b5
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/module.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire scan en tant que module
+ *
+ * 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_MODULE_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_MODULE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Ajoute le module 'analysis.scan' à un module Python. */
+bool add_analysis_scan_module(PyObject *);
+
+/* Intègre les objets du module 'analysis.scan'. */
+bool populate_analysis_scan_module(void);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_MODULE_H */
diff --git a/plugins/pychrysalide/analysis/scan/options.c b/plugins/pychrysalide/analysis/scan/options.c
new file mode 100644
index 0000000..c3b29e9
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/options.c
@@ -0,0 +1,355 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * options.c - équivalent Python du fichier "analysis/scan/options.c"
+ *
+ * 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "options.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <analysis/scan/options-int.h>
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+
+
+
+CREATE_DYN_CONSTRUCTOR(scan_options, G_TYPE_SCAN_OPTIONS);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_scan_options_init(PyObject *, PyObject *, PyObject *);
+
+/* Indique le type d'un moteur d'analyse de données sélectionné. */
+static PyObject *py_scan_options_get_backend_for_data(PyObject *, void *);
+
+/* Sélectionne un type de moteur d'analyse pour données brutes. */
+static int py_scan_options_set_backend_for_data(PyObject *, PyObject *, void *);
+
+/* Indique un besoin de statistiques en fin de compilation. */
+static PyObject *py_scan_options_get_print_stats(PyObject *, void *);
+
+/* Mémorise un besoin de statistiques en fin de compilation. */
+static int py_scan_options_set_print_stats(PyObject *, PyObject *, void *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  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_scan_options_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    int ret;                                /* Bilan de lecture des args.  */
+
+#define SCAN_OPTIONS_DOC                                            \
+    "The *ScanOptions* class stores all parameters used to tune"    \
+    " a scanning process..\n"                                       \
+    "\n"                                                            \
+    "Instances can be created using the following constructor:\n"   \
+    "\n"                                                            \
+    "    ScanOptions()"
+
+    /* Initialisation d'un objet GLib */
+
+    ret = forward_pygobjet_init(self);
+    if (ret == -1) return -1;
+
+    return 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = classe représentant un format Axml.                *
+*                closure = adresse non utilisée ici.                          *
+*                                                                             *
+*  Description : Indique le type d'un moteur d'analyse de données sélectionné.*
+*                                                                             *
+*  Retour      : Type d'objet, idéalement valide.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_scan_options_get_backend_for_data(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Liste éventuelle à renvoyer */
+    GScanOptions *options;                  /* Version native              */
+    GType type;                             /* Type à transcrire           */
+
+#define SCAN_OPTIONS_BACKEND_FOR_DATA_ATTRIB PYTHON_GETSET_DEF_FULL \
+(                                                                   \
+    backend_for_data, py_scan_options,                              \
+    "Type of the selected scan algorithm."                          \
+)
+
+    options = G_SCAN_OPTIONS(pygobject_get(self));
+
+    type = g_scan_options_get_backend_for_data(options);
+
+    result = pyg_type_wrapper_new(type);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                value   = valeur fournie à intégrer ou prendre en compte.    *
+*                closure = adresse non utilisée ici.                          *
+*                                                                             *
+*  Description : Sélectionne un type de moteur d'analyse pour données brutes. *
+*                                                                             *
+*  Retour      : Bilan de l'opération pour Python.                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int py_scan_options_set_backend_for_data(PyObject *self, PyObject *value, void *closure)
+{
+    GType type;                             /* Type à transcrit            */
+    GScanOptions *options;                  /* Version native              */
+
+    type = pyg_type_from_object(value);
+
+    options = G_SCAN_OPTIONS(pygobject_get(self));
+
+    g_scan_options_set_backend_for_data(options, type);
+
+    return 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = classe représentant un format Axml.                *
+*                closure = adresse non utilisée ici.                          *
+*                                                                             *
+*  Description : Indique un besoin de statistiques en fin de compilation.     *
+*                                                                             *
+*  Retour      : Etat de l'option visée à conservé.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_scan_options_get_print_stats(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Liste éventuelle à renvoyer */
+    GScanOptions *options;                  /* Version native              */
+    bool state;                             /* Etat courant à consulter    */
+
+#define SCAN_OPTIONS_PRINT_STATS_ATTRIB PYTHON_GETSET_DEF_FULL  \
+(                                                               \
+    print_stats, py_scan_options,                               \
+    "Control the output of final statistics afer a scan."       \
+)
+
+    options = G_SCAN_OPTIONS(pygobject_get(self));
+
+    state = g_scan_options_get_print_stats(options);
+
+    result = state ? Py_True : Py_False;
+    Py_INCREF(result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                value   = valeur fournie à intégrer ou prendre en compte.    *
+*                closure = adresse non utilisée ici.                          *
+*                                                                             *
+*  Description : Mémorise un besoin de statistiques en fin de compilation.    *
+*                                                                             *
+*  Retour      : Bilan de l'opération pour Python.                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int py_scan_options_set_print_stats(PyObject *self, PyObject *value, void *closure)
+{
+    bool state;                             /* Nouvel état à définir       */
+    GScanOptions *options;                  /* Version native              */
+
+    if (value != Py_True && value != Py_False)
+        return -1;
+
+    state = (value == Py_True);
+
+    options = G_SCAN_OPTIONS(pygobject_get(self));
+
+    g_scan_options_set_print_stats(options, state);
+
+    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_scan_options_type(void)
+{
+    static PyMethodDef py_scan_options_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_scan_options_getseters[] = {
+        SCAN_OPTIONS_BACKEND_FOR_DATA_ATTRIB,
+        SCAN_OPTIONS_PRINT_STATS_ATTRIB,
+        { NULL }
+    };
+
+    static PyTypeObject py_scan_options_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.scan.ScanOptions",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT,
+
+        .tp_doc         = SCAN_OPTIONS_DOC,
+
+        .tp_methods     = py_scan_options_methods,
+        .tp_getset      = py_scan_options_getseters,
+
+        .tp_init        = py_scan_options_init,
+        .tp_new         = py_scan_options_new,
+
+    };
+
+    return &py_scan_options_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide...scan.ScanOptions'. *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_python_scan_options_is_registered(void)
+{
+    PyTypeObject *type;                     /* Type Python 'ScanOptions' */
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_scan_options_type();
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.analysis.scan");
+
+        dict = PyModule_GetDict(module);
+
+        if (!register_class_for_pygobject(dict, G_TYPE_SCAN_OPTIONS, type, &PyGObject_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 ensemble d'options d'analyses.         *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_scan_options(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_scan_options_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 scan options");
+            break;
+
+        case 1:
+            *((GScanOptions **)dst) = G_SCAN_OPTIONS(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/scan/options.h b/plugins/pychrysalide/analysis/scan/options.h
new file mode 100644
index 0000000..3e83880
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/options.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * options.h - prototypes pour l'équivalent Python du fichier "analysis/scan/options.h"
+ *
+ * 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_OPTIONS_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_OPTIONS_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_scan_options_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.scan.ScanOptions'. */
+bool ensure_python_scan_options_is_registered(void);
+
+/* Tente de convertir en ensemble d'options d'analyses. */
+int convert_to_scan_options(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_OPTIONS_H */
diff --git a/plugins/pychrysalide/analysis/scan/patterns/Makefile.am b/plugins/pychrysalide/analysis/scan/patterns/Makefile.am
new file mode 100644
index 0000000..612f34b
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/patterns/Makefile.am
@@ -0,0 +1,20 @@
+
+noinst_LTLIBRARIES = libpychrysaanalysisscanpatterns.la
+
+libpychrysaanalysisscanpatterns_la_SOURCES = \
+	backend.h backend.c						\
+	module.h module.c
+
+libpychrysaanalysisscanpatterns_la_LIBADD = \
+	backends/libpychrysaanalysisscanpatternsbackends.la
+
+libpychrysaanalysisscanpatterns_la_CFLAGS = $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) $(TOOLKIT_CFLAGS) \
+	-I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
+
+
+devdir = $(includedir)/chrysalide/$(subdir)
+
+dev_HEADERS = $(libpychrysaanalysisscanpatterns_la_SOURCES:%c=)
+
+
+SUBDIRS = backends
diff --git a/plugins/pychrysalide/analysis/scan/patterns/backend.c b/plugins/pychrysalide/analysis/scan/patterns/backend.c
new file mode 100644
index 0000000..6d668f4
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/patterns/backend.c
@@ -0,0 +1,202 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * backend.c - équivalent Python du fichier "analysis/scan/backend.c"
+ *
+ * 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "backend.h"
+
+
+#include <pygobject.h>
+
+
+#include <analysis/scan/patterns/backend-int.h>
+
+
+#include "../../../access.h"
+#include "../../../helpers.h"
+
+
+
+CREATE_DYN_ABSTRACT_CONSTRUCTOR(engine_backend, G_TYPE_ENGINE_BACKEND, NULL);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_engine_backend_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_engine_backend_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    int ret;                                /* Bilan de lecture des args.  */
+
+#define ENGINE_BACKEND_DOC                                              \
+    "An *EngineBackend* object is the root class of all scan algorithm" \
+    " looking for data patterns."
+
+    /* Initialisation d'un objet GLib */
+
+    ret = forward_pygobjet_init(self);
+    if (ret == -1) 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_engine_backend_type(void)
+{
+    static PyMethodDef py_engine_backend_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_engine_backend_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_engine_backend_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.scan.patterns.EngineBackend",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT,
+
+        .tp_doc         = ENGINE_BACKEND_DOC,
+
+        .tp_methods     = py_engine_backend_methods,
+        .tp_getset      = py_engine_backend_getseters,
+
+        .tp_init        = py_engine_backend_init,
+        .tp_new         = py_engine_backend_new,
+
+    };
+
+    return &py_engine_backend_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide....EngineBackend'.     *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_python_engine_backend_is_registered(void)
+{
+    PyTypeObject *type;                     /* Type Python 'ScanNamespace' */
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_engine_backend_type();
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.analysis.scan");
+
+        dict = PyModule_GetDict(module);
+
+        if (!register_class_for_pygobject(dict, G_TYPE_ENGINE_BACKEND, type, &PyGObject_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 méthode de recherches.                 *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_engine_backend(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_engine_backend_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 engine backend");
+            break;
+
+        case 1:
+            *((GEngineBackend **)dst) = G_ENGINE_BACKEND(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/scan/patterns/backend.h b/plugins/pychrysalide/analysis/scan/patterns/backend.h
new file mode 100644
index 0000000..6b1f4cd
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/patterns/backend.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * backend.h - prototypes pour l'équivalent Python du fichier "analysis/scan/backend.h"
+ *
+ * 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_BACKEND_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_BACKEND_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_engine_backend_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.scan.patterns.EngineBackend'. */
+bool ensure_python_engine_backend_is_registered(void);
+
+/* Tente de convertir en méthode de recherches. */
+int convert_to_engine_backend(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_BACKEND_H */
diff --git a/plugins/pychrysalide/analysis/scan/patterns/backends/Makefile.am b/plugins/pychrysalide/analysis/scan/patterns/backends/Makefile.am
new file mode 100644
index 0000000..cccfc2d
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/patterns/backends/Makefile.am
@@ -0,0 +1,15 @@
+
+noinst_LTLIBRARIES = libpychrysaanalysisscanpatternsbackends.la
+
+libpychrysaanalysisscanpatternsbackends_la_SOURCES =		\
+	acism.h acism.c							\
+	bitap.h bitap.c							\
+	module.h module.c
+
+libpychrysaanalysisscanpatternsbackends_la_CFLAGS = $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) $(TOOLKIT_CFLAGS) \
+	-I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
+
+
+devdir = $(includedir)/chrysalide/$(subdir)
+
+dev_HEADERS = $(libpychrysaanalysisscanpatternsbackends_la_SOURCES:%c=)
diff --git a/plugins/pychrysalide/analysis/scan/patterns/backends/acism.c b/plugins/pychrysalide/analysis/scan/patterns/backends/acism.c
new file mode 100644
index 0000000..63e653a
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/patterns/backends/acism.c
@@ -0,0 +1,214 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * acism.c - équivalent Python du fichier "analysis/scan/patterns/backends/acism.c"
+ *
+ * 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acism.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <analysis/scan/patterns/backends/acism-int.h>
+
+
+#include "../backend.h"
+#include "../../../../access.h"
+#include "../../../../helpers.h"
+
+
+
+CREATE_DYN_CONSTRUCTOR(acism_backend, G_TYPE_ACISM_BACKEND);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_acism_backend_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_acism_backend_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    int ret;                                /* Bilan de lecture des args.  */
+
+#define ACISM_BACKEND_DOC                                                 \
+    "A *AcismBackend* class provide an implementation of the Aho-Corasick"  \
+    "  search algorithm with Interleaved State-transition Matrix (ACISM)."  \
+    "\n"                                                                    \
+    "Instances can be created using the following constructor:\n"           \
+    "\n"                                                                    \
+    "    AcismBackend()"                                                    \
+    "\n"                                                                    \
+    "See the relative white paper for more information:"                    \
+    " https://docs.google.com/document/d/1e9Qbn22__togYgQ7PNyCz3YzIIVPKvrf8PCrFa74IFM"
+
+    /* Initialisation d'un objet GLib */
+
+    ret = forward_pygobjet_init(self);
+    if (ret == -1) 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_acism_backend_type(void)
+{
+    static PyMethodDef py_acism_backend_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_acism_backend_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_acism_backend_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.scan.patterns.backends.AcismBackend",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = ACISM_BACKEND_DOC,
+
+        .tp_methods     = py_acism_backend_methods,
+        .tp_getset      = py_acism_backend_getseters,
+
+        .tp_init        = py_acism_backend_init,
+        .tp_new         = py_acism_backend_new,
+
+    };
+
+    return &py_acism_backend_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide....AcismBackend'.      *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_python_acism_backend_is_registered(void)
+{
+    PyTypeObject *type;                     /* Type Python 'AcismBackend'*/
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_acism_backend_type();
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.analysis.scan.patterns.backends");
+
+        dict = PyModule_GetDict(module);
+
+        if (!ensure_python_engine_backend_is_registered())
+            return false;
+
+        if (!register_class_for_pygobject(dict, G_TYPE_ACISM_BACKEND, type, &PyGObject_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 méthode de recherche ACISM.            *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_acism_backend(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_acism_backend_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 ACISM backend");
+            break;
+
+        case 1:
+            *((GAcismBackend **)dst) = G_ACISM_BACKEND(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/scan/patterns/backends/acism.h b/plugins/pychrysalide/analysis/scan/patterns/backends/acism.h
new file mode 100644
index 0000000..9ed61fa
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/patterns/backends/acism.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * acism.h - prototypes pour l'équivalent Python du fichier "analysis/scan/patterns/backends/acism.h"
+ *
+ * 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_PATTERNS_BACKENDS_ACISM_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_PATTERNS_BACKENDS_ACISM_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_acism_backend_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.scan.patterns.backends.AcismBackend'. */
+bool ensure_python_acism_backend_is_registered(void);
+
+/* Tente de convertir en méthode de recherche ACISM. */
+int convert_to_acism_backend(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_PATTERNS_BACKENDS_ACISM_H */
diff --git a/plugins/pychrysalide/analysis/scan/patterns/backends/bitap.c b/plugins/pychrysalide/analysis/scan/patterns/backends/bitap.c
new file mode 100644
index 0000000..f961bf7
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/patterns/backends/bitap.c
@@ -0,0 +1,214 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * bitap.c - équivalent Python du fichier "analysis/scan/patterns/backends/bitap.c"
+ *
+ * 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "bitap.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <analysis/scan/patterns/backends/bitap-int.h>
+
+
+#include "../backend.h"
+#include "../../../../access.h"
+#include "../../../../helpers.h"
+
+
+
+CREATE_DYN_CONSTRUCTOR(bitap_backend, G_TYPE_BITAP_BACKEND);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_bitap_backend_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_bitap_backend_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    int ret;                                /* Bilan de lecture des args.  */
+
+#define BITAP_BACKEND_DOC                                           \
+    "A *BitapBackend* class provide an implementation of the Bitap" \
+    "  search algorithm."                                           \
+    "\n"                                                            \
+    "Instances can be created using the following constructor:\n"   \
+    "\n"                                                            \
+    "    BitapBackend()"                                            \
+    "\n"                                                            \
+    "See the relative white paper for more information:"            \
+    " https://en.wikipedia.org/wiki/Bitap_algorithm"
+
+    /* Initialisation d'un objet GLib */
+
+    ret = forward_pygobjet_init(self);
+    if (ret == -1) 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_bitap_backend_type(void)
+{
+    static PyMethodDef py_bitap_backend_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_bitap_backend_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_bitap_backend_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.scan.patterns.backends.BitapBackend",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = BITAP_BACKEND_DOC,
+
+        .tp_methods     = py_bitap_backend_methods,
+        .tp_getset      = py_bitap_backend_getseters,
+
+        .tp_init        = py_bitap_backend_init,
+        .tp_new         = py_bitap_backend_new,
+
+    };
+
+    return &py_bitap_backend_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide....BitapBackend'.      *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_python_bitap_backend_is_registered(void)
+{
+    PyTypeObject *type;                     /* Type Python 'BitapBackend'*/
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_bitap_backend_type();
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.analysis.scan.patterns.backends");
+
+        dict = PyModule_GetDict(module);
+
+        if (!ensure_python_engine_backend_is_registered())
+            return false;
+
+        if (!register_class_for_pygobject(dict, G_TYPE_BITAP_BACKEND, type, &PyGObject_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 méthode de recherche BITAP.            *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_bitap_backend(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_bitap_backend_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 Bitap backend");
+            break;
+
+        case 1:
+            *((GBitapBackend **)dst) = G_BITAP_BACKEND(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/scan/patterns/backends/bitap.h b/plugins/pychrysalide/analysis/scan/patterns/backends/bitap.h
new file mode 100644
index 0000000..f7853d4
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/patterns/backends/bitap.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * bitap.h - prototypes pour l'équivalent Python du fichier "analysis/scan/patterns/backends/bitap.h"
+ *
+ * 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_PATTERNS_BACKENDS_BITAP_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_PATTERNS_BACKENDS_BITAP_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_bitap_backend_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.scan.patterns.backends.BitapBackend'. */
+bool ensure_python_bitap_backend_is_registered(void);
+
+/* Tente de convertir en méthode de recherche Bitap. */
+int convert_to_bitap_backend(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_PATTERNS_BACKENDS_BITAP_H */
diff --git a/plugins/pychrysalide/analysis/scan/patterns/backends/module.c b/plugins/pychrysalide/analysis/scan/patterns/backends/module.c
new file mode 100644
index 0000000..f4a0293
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/patterns/backends/module.c
@@ -0,0 +1,106 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire backends en tant que module
+ *
+ * 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "module.h"
+
+
+#include <assert.h>
+
+
+#include "acism.h"
+#include "bitap.h"
+#include "../../../../helpers.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : super = module dont la définition est à compléter.           *
+*                                                                             *
+*  Description : Ajoute le module 'analysis.....backends' à un module Python. *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool add_analysis_scan_patterns_backends_module(PyObject *super)
+{
+    bool result;                            /* Bilan à retourner           */
+    PyObject *module;                       /* Sous-module mis en place    */
+
+#define PYCHRYSALIDE_ANALYSIS_SCAN_PATTERNS_BACKENDS_MODULE_DOC                   \
+    "This module provide all the features useful for scanning"  \
+    " binary contents."
+
+    static PyModuleDef py_chrysalide_analysis_scan_patterns_backends_module = {
+
+        .m_base = PyModuleDef_HEAD_INIT,
+
+        .m_name = "pychrysalide.analysis.scan.patterns.backends",
+        .m_doc = PYCHRYSALIDE_ANALYSIS_SCAN_PATTERNS_BACKENDS_MODULE_DOC,
+
+        .m_size = -1,
+
+    };
+
+    module = build_python_module(super, &py_chrysalide_analysis_scan_patterns_backends_module);
+
+    result = (module != NULL);
+
+    if (!result)
+        Py_XDECREF(module);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Intègre les objets du module 'analysis....patterns.backends'.*
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool populate_analysis_scan_patterns_backends_module(void)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = true;
+
+    if (result) result = ensure_python_acism_backend_is_registered();
+    if (result) result = ensure_python_bitap_backend_is_registered();
+
+    assert(result);
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/scan/patterns/backends/module.h b/plugins/pychrysalide/analysis/scan/patterns/backends/module.h
new file mode 100644
index 0000000..ab1aad5
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/patterns/backends/module.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire backends en tant que module
+ *
+ * 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_PATTERNS_BACKENDS_MODULE_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_PATTERNS_BACKENDS_MODULE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Ajoute le module 'analysis.scan.patterns.backends' à un module Python. */
+bool add_analysis_scan_patterns_backends_module(PyObject *);
+
+/* Intègre les objets du module 'analysis.scan.patterns.backends'. */
+bool populate_analysis_scan_patterns_backends_module(void);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_PATTERNS_BACKENDS_MODULE_H */
diff --git a/plugins/pychrysalide/analysis/scan/patterns/module.c b/plugins/pychrysalide/analysis/scan/patterns/module.c
new file mode 100644
index 0000000..f8db49e
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/patterns/module.c
@@ -0,0 +1,109 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire patterns en tant que module
+ *
+ * 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "module.h"
+
+
+#include <assert.h>
+
+
+#include "backend.h"
+#include "backends/module.h"
+#include "../../../helpers.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : super = module dont la définition est à compléter.           *
+*                                                                             *
+*  Description : Ajoute le module 'analysis.scan.patterns' à un module Python.*
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool add_analysis_scan_patterns_module(PyObject *super)
+{
+    bool result;                            /* Bilan à retourner           */
+    PyObject *module;                       /* Sous-module mis en place    */
+
+#define PYCHRYSALIDE_ANALYSIS_SCAN_PATTERNS_MODULE_DOC                   \
+    "This module provide all the features useful for scanning"  \
+    " binary contents."
+
+    static PyModuleDef py_chrysalide_analysis_scan_patterns_module = {
+
+        .m_base = PyModuleDef_HEAD_INIT,
+
+        .m_name = "pychrysalide.analysis.scan.patterns",
+        .m_doc = PYCHRYSALIDE_ANALYSIS_SCAN_PATTERNS_MODULE_DOC,
+
+        .m_size = -1,
+
+    };
+
+    module = build_python_module(super, &py_chrysalide_analysis_scan_patterns_module);
+
+    result = (module != NULL);
+
+    if (result) result = add_analysis_scan_patterns_backends_module(module);
+
+    if (!result)
+        Py_XDECREF(module);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Intègre les objets du module 'analysis.scan.patterns'.       *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool populate_analysis_scan_patterns_module(void)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = true;
+
+    if (result) result = ensure_python_engine_backend_is_registered();
+
+    if (result) result = populate_analysis_scan_patterns_backends_module();
+
+    assert(result);
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/scan/patterns/module.h b/plugins/pychrysalide/analysis/scan/patterns/module.h
new file mode 100644
index 0000000..bc25129
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/patterns/module.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire patterns en tant que module
+ *
+ * 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_PATTERNS_MODULE_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_PATTERNS_MODULE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Ajoute le module 'analysis.scan.patterns' à un module Python. */
+bool add_analysis_scan_patterns_module(PyObject *);
+
+/* Intègre les objets du module 'analysis.scan.patterns'. */
+bool populate_analysis_scan_patterns_module(void);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_PATTERNS_MODULE_H */
diff --git a/plugins/pychrysalide/analysis/scan/scanner.c b/plugins/pychrysalide/analysis/scan/scanner.c
new file mode 100644
index 0000000..8eb36a7
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/scanner.c
@@ -0,0 +1,313 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * scanner.c - équivalent Python du fichier "analysis/scan/scanner.c"
+ *
+ * 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "scanner.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <analysis/content.h>
+#include <analysis/scan/context.h>
+#include <analysis/scan/scanner-int.h>
+
+
+#include "options.h"
+#include "../content.h"
+#include "../../access.h"
+#include "../../helpers.h"
+
+
+
+CREATE_DYN_CONSTRUCTOR(content_scanner, G_TYPE_CONTENT_SCANNER);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_content_scanner_init(PyObject *, PyObject *, PyObject *);
+
+/* Lance une analyse d'un contenu binaire. */
+static PyObject *py_content_scanner_analyze(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_content_scanner_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    const char *text;                       /* Contenu de règles à traiter */
+    const char *filename;                   /* Fichier de définitions      */
+    int ret;                                /* Bilan de lecture des args.  */
+    GContentScanner *scanner;               /* Création GLib à transmettre */
+
+    static char *kwlist[] = { "text", "filename", NULL };
+
+#define CONTENT_SCANNER_DOC                                         \
+    "A ContentScanner object provides support for rules processing" \
+    " against binary contents.\n"                                   \
+    "\n"                                                            \
+    "Instances can be created using one of the following"           \
+    " constructors:\n"                                              \
+    "\n"                                                            \
+    "    ContentScanner(text=str)"                                  \
+    "    ContentScanner(filename=str)"                              \
+    "\n"                                                            \
+    "Where *text* is a string for the rules definitions and"        \
+    " *filename* an alternative string for a path pointing to a"    \
+    " definition file."
+
+    /* Récupération des paramètres */
+
+    text = NULL;
+    filename = NULL;
+
+    ret = PyArg_ParseTupleAndKeywords(args, kwds, "|ss", kwlist, &text, &filename);
+    if (!ret) return -1;
+
+    /* Initialisation d'un objet GLib */
+
+    ret = forward_pygobjet_init(self);
+    if (ret == -1) return -1;
+
+    /* Eléments de base */
+
+    scanner = G_CONTENT_SCANNER(pygobject_get(self));
+
+    if (text != NULL)
+    {
+        if (!g_content_scanner_create_from_text(scanner, text))
+        {
+            PyErr_SetString(PyExc_ValueError, _("Unable to create content scanner."));
+            return -1;
+        }
+
+    }
+
+    else if (filename != NULL)
+    {
+        if (!g_content_scanner_create_from_file(scanner, filename))
+        {
+            PyErr_SetString(PyExc_ValueError, _("Unable to create content scanner."));
+            return -1;
+        }
+
+    }
+
+    else
+    {
+        PyErr_SetString(PyExc_ValueError, _("Unable to create empty content scanner."));
+        return -1;
+    }
+
+    return 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe représentant un format.                        *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Lance une analyse d'un contenu binaire.                      *
+*                                                                             *
+*  Retour      : Contexte de suivi pour l'analyse menée.                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_content_scanner_analyze(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Contexte de suivi à renvoyer*/
+    GScanOptions *options;                  /* Paramètres d'analyse        */
+    GBinContent *content;                   /* Contenu binaire à traiter   */
+    int ret;                                /* Bilan de lecture des args.  */
+    GContentScanner *scanner;               /* Encadrement de recherche    */
+    GScanContext *context;                  /* Contexte de suivi           */
+
+#define CONTENT_SCANNER_ANALYZE_METHOD PYTHON_METHOD_DEF            \
+(                                                                   \
+    analyze, "$self, options, content, /",                          \
+    METH_VARARGS, py_content_scanner,                               \
+    "Run a scan against a binary content.\n"                        \
+    "\n"                                                            \
+    "The *content* argument is a pychrysalide.analysis.BinContent"  \
+    " object pointing to data to analyze.\n"                        \
+    "\n"                                                            \
+    "The method returns a pychrysalide.analysis.scan.ScanContext"   \
+    " object tracking all the scan results."                        \
+)
+
+    ret = PyArg_ParseTuple(args, "O&O&", convert_to_scan_options, &options, convert_to_binary_content, &content);
+    if (!ret) return NULL;
+
+    scanner = G_CONTENT_SCANNER(pygobject_get(self));
+
+    context = g_content_scanner_analyze(scanner, options, content);
+
+    result = pygobject_new(G_OBJECT(context));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit un accès à une définition de type à diffuser.        *
+*                                                                             *
+*  Retour      : Définition d'objet pour Python.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyTypeObject *get_python_content_scanner_type(void)
+{
+    static PyMethodDef py_content_scanner_methods[] = {
+        CONTENT_SCANNER_ANALYZE_METHOD,
+        { NULL }
+    };
+
+    static PyGetSetDef py_content_scanner_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_content_scanner_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.scan.ContentScanner",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = CONTENT_SCANNER_DOC,
+
+        .tp_methods     = py_content_scanner_methods,
+        .tp_getset      = py_content_scanner_getseters,
+
+        .tp_init        = py_content_scanner_init,
+        .tp_new         = py_content_scanner_new,
+
+    };
+
+    return &py_content_scanner_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide...scan.ContentScanner. *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_python_content_scanner_is_registered(void)
+{
+    PyTypeObject *type;                     /* Type Python 'ContentScanner'*/
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_content_scanner_type();
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.analysis.scan");
+
+        dict = PyModule_GetDict(module);
+
+        if (!register_class_for_pygobject(dict, G_TYPE_CONTENT_SCANNER, type, &PyGObject_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 scanner de contenus binaires.          *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_content_scanner(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_content_scanner_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 content scanner");
+            break;
+
+        case 1:
+            *((GContentScanner **)dst) = G_CONTENT_SCANNER(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/scan/scanner.h b/plugins/pychrysalide/analysis/scan/scanner.h
new file mode 100644
index 0000000..b3b1baf
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/scanner.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * scanner.h - prototypes pour l'équivalent Python du fichier "analysis/scan/scanner.h"
+ *
+ * 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_SCANNER_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_SCANNER_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_content_scanner_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.scan.ContentScanner'. */
+bool ensure_python_content_scanner_is_registered(void);
+
+/* Tente de convertir en scanner de contenus binaires. */
+int convert_to_content_scanner(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_SCANNER_H */
diff --git a/plugins/pychrysalide/analysis/scan/space.c b/plugins/pychrysalide/analysis/scan/space.c
new file mode 100644
index 0000000..9f29829
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/space.c
@@ -0,0 +1,297 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * space.c - équivalent Python du fichier "analysis/scan/space.c"
+ *
+ * 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "space.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <analysis/content.h>
+#include <analysis/scan/space-int.h>
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+#include <plugins/pychrysalide/analysis/content.h>
+
+
+
+CREATE_DYN_CONSTRUCTOR(scan_namespace, G_TYPE_SCAN_NAMESPACE);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_scan_namespace_init(PyObject *, PyObject *, PyObject *);
+
+/* Indique le nom attribué à un espace de noms. */
+static PyObject *py_scan_namespace_get_name(PyObject *, void *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  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_scan_namespace_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    int ret;                                /* Bilan de lecture des args.  */
+
+#define SCAN_NAMESPACE_DOC                                              \
+    "ScanNamespace defines a group of properties and functions for a"   \
+    " given scan theme.\n"                                              \
+    "\n"                                                                \
+    "Instances can be created using the following constructor:\n"       \
+    "\n"                                                                \
+    "    ScanNamespace()"
+
+    /* Initialisation d'un objet GLib */
+
+    ret = forward_pygobjet_init(self);
+    if (ret == -1) return -1;
+
+    return 0;
+
+}
+
+#if 0
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = objet représentant une table de chaînes.              *
+*                args = arguments fournis pour l'opération.                   *
+*                                                                             *
+*  Description : Remplace les propriétés renvoyant à des ressources.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_scan_namespace_resolve(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Bilan à retourner           */
+    GResourceTable *table;                  /* Table de ressources         */
+    int ret;                                /* Bilan de lecture des args.  */
+    GScanNamespace *format;                    /* Version native              */
+
+#define SCAN_NAMESPACE_RESOLVE_METHOD PYTHON_METHOD_DEF    \
+(                                                       \
+    resolve, "$self, table, /",                         \
+    METH_VARARGS, py_scan_namespace,                       \
+    "Resolve all XML node attribute values pointing to" \
+    " resource entries. Such values are identifiers"    \
+    " of the forme '@0x...'.\n"                         \
+    "\n"                                                \
+    "The *table* argument has to be a loaded"           \
+     " pychrysalide.format.androidfw.ResourceTable"     \
+    " instance.\n"                                      \
+)
+
+    ret = PyArg_ParseTuple(args, "O&", convert_to_resource_table, &table);
+    if (!ret) return NULL;
+
+    format = G_SCAN_NAMESPACE(pygobject_get(self));
+
+    g_scan_namespace_resvolve(format, table);
+
+    result = Py_None;
+    Py_INCREF(result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = classe représentant un format Axml.                *
+*                closure = adresse non utilisée ici.                          *
+*                                                                             *
+*  Description : Indique le nom attribué à un espace de noms.                 *
+*                                                                             *
+*  Retour      : Désignation associée.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_scan_namespace_get_name(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Liste éventuelle à renvoyer */
+    GScanNamespace *space;                  /* Version native              */
+    const char *name;                       /* Désignation à exporter      */
+
+#define SCAN_NAMESPACE_NAME_ATTRIB PYTHON_GET_DEF_FULL  \
+(                                                       \
+    name, py_scan_namespace,                            \
+    "Name provided for the namespace."                  \
+)
+
+    space = G_SCAN_NAMESPACE(pygobject_get(self));
+
+    name = g_scan_namespace_get_name(space);
+
+    result = PyUnicode_FromString(name);
+
+    return result;
+
+}
+#endif
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit un accès à une définition de type à diffuser.        *
+*                                                                             *
+*  Retour      : Définition d'objet pour Python.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyTypeObject *get_python_scan_namespace_type(void)
+{
+    static PyMethodDef py_scan_namespace_methods[] = {
+        //SCAN_NAMESPACE_RESOLVE_METHOD,
+        { NULL }
+    };
+
+    static PyGetSetDef py_scan_namespace_getseters[] = {
+        //SCAN_NAMESPACE_NAME_ATTRIB,
+        { NULL }
+    };
+
+    static PyTypeObject py_scan_namespace_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.scan.ScanNamespace",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT,
+
+        .tp_doc         = SCAN_NAMESPACE_DOC,
+
+        .tp_methods     = py_scan_namespace_methods,
+        .tp_getset      = py_scan_namespace_getseters,
+
+        .tp_init        = py_scan_namespace_init,
+        .tp_new         = py_scan_namespace_new,
+
+    };
+
+    return &py_scan_namespace_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide...scan.ScanNamespace'. *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_python_scan_namespace_is_registered(void)
+{
+    PyTypeObject *type;                     /* Type Python 'ScanNamespace' */
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_scan_namespace_type();
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.analysis.scan");
+
+        dict = PyModule_GetDict(module);
+
+        if (!register_class_for_pygobject(dict, G_TYPE_SCAN_NAMESPACE, type, &PyGObject_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 espace de noms pour scan.              *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_scan_namespace(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_scan_namespace_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 scan namespace");
+            break;
+
+        case 1:
+            *((GScanNamespace **)dst) = G_SCAN_NAMESPACE(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/scan/space.h b/plugins/pychrysalide/analysis/scan/space.h
new file mode 100644
index 0000000..0166c04
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/space.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * space.h - prototypes pour l'équivalent Python du fichier "analysis/scan/space.h"
+ *
+ * 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_SPACE_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_SPACE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_scan_namespace_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.scan.ScanNamespace'. */
+bool ensure_python_scan_namespace_is_registered(void);
+
+/* Tente de convertir en espace de noms pour scan. */
+int convert_to_scan_namespace(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_SPACE_H */
diff --git a/src/Makefile.am b/src/Makefile.am
index 8f746d6..1fe76bc 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,7 +1,7 @@
 
 lib_LTLIBRARIES = libchrysacore.la
 
-bin_PROGRAMS = chrysalide chrysalide-hub
+bin_PROGRAMS = chrysalide chrysalide-hub rost
 
 
 AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/intl
@@ -20,6 +20,7 @@ GOBJECT_LEAKS_SOURCES = gleak.h gleak.c
 
 endif
 
+libchrysacore_la_SOURCES =
 
 if BUILD_GTK_SUPPORT
 
@@ -38,8 +39,19 @@ if BUILD_GTK_SUPPORT
 endif
 
 
-libchrysacore_la_SOURCES = 					\
-	$(GOBJECT_LEAKS_SOURCES)
+libchrysacore_la_LIBADD =					\
+	analysis/libanalysis.la					\
+	arch/libarch.la							\
+	common/libcommon.la						\
+	core/libcore.la							\
+	debug/libdebug.la						\
+	format/libformat.la						\
+	glibext/libglibext.la					\
+	$(GTKEXT_LIBADD)						\
+	$(GUI_LIBADD)							\
+	mangling/libmangling.la					\
+	plugins/libplugins.la
+
 
 # -ldl: dladdr(), dlerror()
 libchrysacore_la_LDFLAGS =					\
@@ -54,28 +66,16 @@ libchrysacore_la_LDFLAGS += $(LIBCURL_LIBS)
 
 endif
 
-libchrysacore_la_LIBADD =					\
-	analysis/libanalysis.la					\
-	arch/libarch.la							\
-	common/libcommon.la						\
-	core/libcore.la							\
-	debug/libdebug.la						\
-	format/libformat.la						\
-	glibext/libglibext.la					\
-	$(GTKEXT_LIBADD)						\
-	$(GUI_LIBADD)							\
-	mangling/libmangling.la					\
-	plugins/libplugins.la
-
 
 
 ############################################################
 # Programme principal
 ############################################################
 
-EXTRA_chrysalide_DEPENDENCIES = $(lib_LTLIBRARIES)
+EXTRA_chrysalide_DEPENDENCIES = libchrysacore.la
 
 chrysalide_SOURCES = 					\
+	$(GOBJECT_LEAKS_SOURCES)			\
 	main.c
 
 
@@ -92,9 +92,10 @@ chrysalide_LDADD = $(LIBINTL)
 # Gestionnaire de serveurs distants
 ############################################################
 
-EXTRA_chrysalide_hub_DEPENDENCIES = $(lib_LTLIBRARIES)
+EXTRA_chrysalide_hub_DEPENDENCIES = libchrysacore.la
 
 chrysalide_hub_SOURCES =				\
+	$(GOBJECT_LEAKS_SOURCES)			\
 	hub.c
 
 chrysalide_hub_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS)
@@ -104,6 +105,22 @@ chrysalide_hub_LDFLAGS = $(TOOLKIT_LIBS) $(LIBXML_LIBS) -L.libs -lchrysacore
 
 
 ############################################################
+# Détecteur de motifs
+############################################################
+
+EXTRA_rost_DEPENDENCIES = libchrysacore.la
+
+rost_SOURCES =							\
+	$(GOBJECT_LEAKS_SOURCES)			\
+	rost.c
+
+rost_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS)
+
+rost_LDFLAGS = $(LIBGOBJ_LIBS) -L.libs -lchrysacore
+
+
+
+############################################################
 # Le reste du monde
 ############################################################
 
diff --git a/src/analysis/Makefile.am b/src/analysis/Makefile.am
index 39dd2dd..909ced9 100644
--- a/src/analysis/Makefile.am
+++ b/src/analysis/Makefile.am
@@ -25,6 +25,7 @@ libanalysis_la_LIBADD =					\
 	db/libanalysisdb.la					\
 	disass/libanalysisdisass.la			\
 	human/libanalysishuman.la			\
+	scan/libanalysisscan.la				\
 	storage/libanalysisstorage.la		\
 	types/libanalysistypes.la
 
@@ -34,4 +35,4 @@ devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
 dev_HEADERS = $(libanalysis_la_SOURCES:%c=)
 
 
-SUBDIRS = contents db disass human storage types
+SUBDIRS = contents db disass human scan storage types
diff --git a/src/analysis/scan/Makefile.am b/src/analysis/scan/Makefile.am
new file mode 100644
index 0000000..bcec986
--- /dev/null
+++ b/src/analysis/scan/Makefile.am
@@ -0,0 +1,67 @@
+
+BUILT_SOURCES = grammar.h
+
+
+# On évite d'utiliser les variables personnalisées de type *_la_[YL]FLAGS
+# afin de conserver des noms de fichiers simples, ie sans le nom de la
+# bibliothèque de sortie en préfixe.
+
+AM_YFLAGS = -v -d -p rost_ -Wno-yacc -Wcounterexamples
+
+AM_LFLAGS = -P rost_ -o lex.yy.c --header-file=tokens.h    		\
+                        -Dyyget_lineno=rost_get_lineno          \
+                        -Dyy_scan_bytes=rost__scan_bytes        \
+                        -Dyy_delete_buffer=rost__delete_buffer
+
+noinst_LTLIBRARIES  = libanalysisscan.la
+
+
+libanalysisscan_la_SOURCES =				\
+	cond-int.h								\
+	cond.h cond.c							\
+	context-int.h							\
+	context.h context.c						\
+	core.h core.c							\
+	expr-int.h								\
+	expr.h expr.c							\
+	func-int.h								\
+	func.h func.c							\
+	item-int.h								\
+	item.h item.c							\
+	match-int.h								\
+	match.h match.c							\
+	options-int.h							\
+	options.h options.c						\
+	pattern-int.h							\
+	pattern.h pattern.c						\
+	rule-int.h								\
+	rule.h rule.c							\
+	scanner-int.h							\
+	scanner.h scanner.c						\
+	space-int.h								\
+	space.h space.c							\
+	tokens.l								\
+	grammar.y
+
+libanalysisscan_la_LIBADD = 				\
+	exprs/libanalysisscanexprs.la			\
+	funcs/libanalysisscanfuncs.la			\
+	matches/libanalysisscanmatches.la		\
+	patterns/libanalysisscanpatterns.la
+
+libanalysisscan_la_CFLAGS = $(LIBGOBJ_CFLAGS)
+
+
+devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
+
+dev_HEADERS = $(libanalysisscan_la_SOURCES:%c=)
+
+
+# Automake fait les choses à moitié
+CLEANFILES = grammar.h grammar.c grammar.output tokens.c tokens.h
+
+# Pareil : de tous les fichiers générés, seule la sortie de Flex saute pour les distributions !
+EXTRA_DIST = tokens.h
+
+
+SUBDIRS = exprs funcs matches patterns
diff --git a/src/analysis/scan/cond-int.h b/src/analysis/scan/cond-int.h
new file mode 100644
index 0000000..aeb3fc9
--- /dev/null
+++ b/src/analysis/scan/cond-int.h
@@ -0,0 +1,63 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * cond-int.h - prototypes internes pour le parcours de contenus à la recherche de motifs
+ *
+ * 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 _ANALYSIS_SCAN_COND_INT_H
+#define _ANALYSIS_SCAN_COND_INT_H
+
+
+#include "cond.h"
+
+
+
+/* Indique le statut d'une condition de validation. */
+typedef bool (* resolve_cond_fc) (const GMatchCondition *);
+
+/* Indique le statut d'une condition de validation. */
+typedef unsigned long long (* resolve_cond_as_number_fc) (const GMatchCondition *);
+
+/* Avance vers la validation d'une condition, si besoin est. */
+typedef void (* analyze_cond_fc) (const GMatchCondition *, const bin_t *, phys_t, phys_t, bool);
+
+
+
+/* Expression conditionnelle manipulant des motifs (instance) */
+struct _GMatchCondition
+{
+    GObject parent;                         /* A laisser en premier        */
+
+};
+
+/* Expression conditionnelle manipulant des motifs (classe) */
+struct _GMatchConditionClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+    resolve_cond_fc resolve;                /* Réduction en booléen        */
+    resolve_cond_as_number_fc resolve_as_num;   /* Réduction en nombre     */
+    analyze_cond_fc analyze;                /* Analyse selon une position  */
+
+};
+
+
+
+#endif  /* _ANALYSIS_SCAN_COND_INT_H */
diff --git a/src/analysis/scan/cond.c b/src/analysis/scan/cond.c
new file mode 100644
index 0000000..be5b3cb
--- /dev/null
+++ b/src/analysis/scan/cond.c
@@ -0,0 +1,220 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * cond.c - expression conditionnelle validant la présence de motifs donnés
+ *
+ * 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 "cond.h"
+
+
+#include "cond-int.h"
+
+
+
+/* Initialise la classe des recherches dans du binaire. */
+static void g_match_condition_class_init(GMatchConditionClass *);
+
+/* Initialise une instance de recherche dans du binaire. */
+static void g_match_condition_init(GMatchCondition *);
+
+/* Supprime toutes les références externes. */
+static void g_match_condition_dispose(GMatchCondition *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_match_condition_finalize(GMatchCondition *);
+
+
+
+/* Indique le type défini pour une expression de validation. */
+G_DEFINE_TYPE(GMatchCondition, g_match_condition, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des recherches dans du binaire.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_match_condition_class_init(GMatchConditionClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    klass->resolve = NULL;
+    klass->resolve_as_num = NULL;
+    klass->analyze = NULL;
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_match_condition_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_match_condition_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cond = instance à initialiser.                               *
+*                                                                             *
+*  Description : Initialise une instance de recherche dans du binaire.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_match_condition_init(GMatchCondition *cond)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cond = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_match_condition_dispose(GMatchCondition *cond)
+{
+    G_OBJECT_CLASS(g_match_condition_parent_class)->dispose(G_OBJECT(cond));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cond = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_match_condition_finalize(GMatchCondition *cond)
+{
+    G_OBJECT_CLASS(g_match_condition_parent_class)->finalize(G_OBJECT(cond));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cond = condition à consulter.                                *
+*                                                                             *
+*  Description : Indique le statut d'une condition de validation.             *
+*                                                                             *
+*  Retour      : Validation de la condition considérée.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_match_condition_resolve(const GMatchCondition *cond)
+{
+    bool result;                            /* Bilan à retourner           */
+    GMatchConditionClass *class;            /* Classe à activer            */
+    unsigned long long number;              /* Valeur à considérer         */
+
+    class = G_MATCH_CONDITION_GET_CLASS(cond);
+
+    if (class->resolve != NULL)
+        result = class->resolve(cond);
+
+    else if (class->resolve_as_num != NULL)
+    {
+        number = class->resolve_as_num(cond);
+        result = (number > 0);
+    }
+
+    else
+        result = false;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cond = condition à consulter.                                *
+*                                                                             *
+*  Description : Indique le statut d'une condition de validation.             *
+*                                                                             *
+*  Retour      : Forme numérique de la condition considérée pour validation.  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+unsigned long long g_match_condition_resolve_as_number(const GMatchCondition *cond)
+{
+    unsigned long long result;              /* Valeur à retourner          */
+    GMatchConditionClass *class;            /* Classe à activer            */
+
+    class = G_MATCH_CONDITION_GET_CLASS(cond);
+
+    result = class->resolve_as_num(cond);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cond = condition à considérer.                               *
+*                data = données binaires brutes à considérer.                 *
+*                size = quantité de ces données.                              *
+*                pos  = position du point d'étude courant.                    *
+*                full = force une recherche pleine et entière.                *
+*                                                                             *
+*  Description : Avance vers la validation d'une condition, si besoin est.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_match_condition_analyze(const GMatchCondition *cond, const bin_t *data, phys_t size, phys_t pos, bool full)
+{
+    GMatchConditionClass *class;            /* Classe à activer            */
+
+    class = G_MATCH_CONDITION_GET_CLASS(cond);
+
+    class->analyze(cond, data, size, pos, full);
+
+}
diff --git a/src/analysis/scan/cond.h b/src/analysis/scan/cond.h
new file mode 100644
index 0000000..7a5d3c4
--- /dev/null
+++ b/src/analysis/scan/cond.h
@@ -0,0 +1,65 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * cond.h - prototypes pour l'expression conditionnelle validant la présence de motifs donnés
+ *
+ * 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 _ANALYSIS_SCAN_COND_H
+#define _ANALYSIS_SCAN_COND_H
+
+
+#include <glib-object.h>
+
+
+#include "../../arch/archbase.h"
+#include "../../arch/vmpa.h"
+
+
+
+#define G_TYPE_MATCH_CONDITION            g_match_condition_get_type()
+#define G_MATCH_CONDITION(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_MATCH_CONDITION, GMatchCondition))
+#define G_IS_MATCH_CONDITION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_MATCH_CONDITION))
+#define G_MATCH_CONDITION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_MATCH_CONDITION, GMatchConditionClass))
+#define G_IS_MATCH_CONDITION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_MATCH_CONDITION))
+#define G_MATCH_CONDITION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_MATCH_CONDITION, GMatchConditionClass))
+
+
+/* Expression conditionnelle manipulant des motifs (instance) */
+typedef struct _GMatchCondition GMatchCondition;
+
+/* Expression conditionnelle manipulant des motifs (classe) */
+typedef struct _GMatchConditionClass GMatchConditionClass;
+
+
+/* Indique le type défini pour une expression de validation. */
+GType g_match_condition_get_type(void);
+
+/* Indique le statut d'une condition de validation. */
+bool g_match_condition_resolve(const GMatchCondition *);
+
+/* Indique le statut d'une condition de validation. */
+unsigned long long g_match_condition_resolve_as_number(const GMatchCondition *);
+
+/* Avance vers la validation d'une condition, si besoin est. */
+void g_match_condition_analyze(const GMatchCondition *, const bin_t *, phys_t, phys_t, bool);
+
+
+
+#endif  /* _ANALYSIS_SCAN_COND_H */
diff --git a/src/analysis/scan/conds/Makefile.am b/src/analysis/scan/conds/Makefile.am
new file mode 100644
index 0000000..402deac
--- /dev/null
+++ b/src/analysis/scan/conds/Makefile.am
@@ -0,0 +1,16 @@
+
+noinst_LTLIBRARIES  = libanalysisscanconds.la
+
+
+libanalysisscanconds_la_SOURCES =			\
+	binop-int.h								\
+	binop.h binop.c							\
+	counter-int.h							\
+	counter.h counter.c
+
+libanalysisscanconds_la_CFLAGS = $(LIBGOBJ_CFLAGS)
+
+
+devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
+
+dev_HEADERS = $(libanalysisscanconds_la_SOURCES:%c=)
diff --git a/src/analysis/scan/conds/binop-int.h b/src/analysis/scan/conds/binop-int.h
new file mode 100644
index 0000000..0fc5940
--- /dev/null
+++ b/src/analysis/scan/conds/binop-int.h
@@ -0,0 +1,54 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * binop-int.h - prototypes internes pour les opérations booléennes impliquant deux opérandes
+ *
+ * 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 _ANALYSIS_SCAN_CONDS_BINOP_INT_H
+#define _ANALYSIS_SCAN_CONDS_BINOP_INT_H
+
+
+#include "binop.h"
+
+
+#include "../cond-int.h"
+
+
+
+/* Opération booléenne impliquant deux opérandes (instance) */
+struct _GBinaryOperation
+{
+    GMatchCondition parent;                 /* A laisser en premier        */
+
+    GMatchCondition *conds[2];              /* Opérandes à manipuler       */
+    BinOpType type;                         /* Type de manipulation        */
+
+};
+
+/* Opération booléenne impliquant deux opérandes (classe) */
+struct _GBinaryOperationClass
+{
+    GMatchConditionClass parent;            /* A laisser en premier        */
+
+};
+
+
+
+#endif  /* _ANALYSIS_SCAN_CONDS_BINOP_INT_H */
diff --git a/src/analysis/scan/conds/binop.c b/src/analysis/scan/conds/binop.c
new file mode 100644
index 0000000..01e99d9
--- /dev/null
+++ b/src/analysis/scan/conds/binop.c
@@ -0,0 +1,265 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * binop.c - opérations booléennes impliquant deux opérandes
+ *
+ * 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 "binop.h"
+
+
+#include "binop-int.h"
+
+
+
+/* --------------------- INSTANCIATION D'UNE FORME DE CONDITION --------------------- */
+
+
+/* Initialise la classe des opérations booléennes. */
+static void g_binary_operation_class_init(GBinaryOperationClass *);
+
+/* Initialise une instance d'opération booléenne. */
+static void g_binary_operation_init(GBinaryOperation *);
+
+/* Supprime toutes les références externes. */
+static void g_binary_operation_dispose(GBinaryOperation *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_binary_operation_finalize(GBinaryOperation *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Indique le statut d'une condition de validation. */
+static bool g_binary_operation_resolve(const GBinaryOperation *);
+
+/* Lance l'analyse de contenu binaire selon un motif donné. */
+static void g_binary_operation_analyze(const GBinaryOperation *, const bin_t *, phys_t, phys_t, bool);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       INSTANCIATION D'UNE FORME DE CONDITION                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une opération booléenne de validation. */
+G_DEFINE_TYPE(GBinaryOperation, g_binary_operation, G_TYPE_MATCH_CONDITION);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des opérations booléennes.              *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_binary_operation_class_init(GBinaryOperationClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GMatchConditionClass *cond;             /* Classe parente directe      */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_binary_operation_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_binary_operation_finalize;
+
+    cond = G_MATCH_CONDITION_CLASS(klass);
+
+    cond->resolve = (resolve_cond_fc)g_binary_operation_resolve;
+    cond->analyze = (analyze_cond_fc)g_binary_operation_analyze;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op = instance à initialiser.                                 *
+*                                                                             *
+*  Description : Initialise une instance d'opération booléenne.               *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_binary_operation_init(GBinaryOperation *op)
+{
+    op->conds[0] = NULL;
+    op->conds[1] = NULL;
+
+    op->type = BOT_AND;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op = instance d'objet GLib à traiter.                        *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_binary_operation_dispose(GBinaryOperation *op)
+{
+    g_clear_object(&op->conds[0]);
+    g_clear_object(&op->conds[1]);
+
+    G_OBJECT_CLASS(g_binary_operation_parent_class)->dispose(G_OBJECT(op));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op = instance d'objet GLib à traiter.                        *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_binary_operation_finalize(GBinaryOperation *op)
+{
+    G_OBJECT_CLASS(g_binary_operation_parent_class)->finalize(G_OBJECT(op));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op1  = premier opérande à intégrer.                          *
+*                op2  = second opérande à intégrer.                           *
+*                type = type d'opération à prendre en compte.                 *
+*                                                                             *
+*  Description : Met en place une représentation d'opération booléenne.       *
+*                                                                             *
+*  Retour      : Condition mise en place.                                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBinaryOperation *g_binary_operation_new(GMatchCondition *op1, GMatchCondition *op2, BinOpType type)
+{
+    GBinaryOperation *result;                  /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_BINARY_OPERATION, NULL);
+
+    result->conds[0] = op1;
+    g_object_ref(G_OBJECT(op1));
+
+    result->conds[1] = op2;
+    g_object_ref(G_OBJECT(op2));
+
+    result->type = type;
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op = condition à consulter.                                  *
+*                                                                             *
+*  Description : Indique le statut d'une condition de validation.             *
+*                                                                             *
+*  Retour      : Validation de la condition considérée.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_binary_operation_resolve(const GBinaryOperation *op)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = g_match_condition_resolve(op->conds[0]);
+
+    switch (op->type)
+    {
+        case BOT_AND:
+        default:
+            if (result)
+                result = g_match_condition_resolve(op->conds[1]);
+            break;
+
+        case BOT_OR:
+            if (!result)
+                result = g_match_condition_resolve(op->conds[1]);
+            break;
+
+        case BOT_XOR:
+            result ^= g_match_condition_resolve(op->conds[1]);
+            break;
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op   = condition à considérer.                               *
+*                data = données binaires brutes à considérer.                 *
+*                size = quantité de ces données.                              *
+*                pos  = position du point d'étude courant.                    *
+*                full = force une recherche pleine et entière.                *
+*                                                                             *
+*  Description : Lance l'analyse de contenu binaire selon un motif donné.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_binary_operation_analyze(const GBinaryOperation *op, const bin_t *data, phys_t size, phys_t pos, bool full)
+{
+    g_match_condition_analyze(op->conds[0], data, size, pos, full);
+
+    if (full || !g_binary_operation_resolve(op))
+        g_match_condition_analyze(op->conds[1], data, size, pos, full);
+
+}
diff --git a/src/analysis/scan/conds/binop.h b/src/analysis/scan/conds/binop.h
new file mode 100644
index 0000000..55cb515
--- /dev/null
+++ b/src/analysis/scan/conds/binop.h
@@ -0,0 +1,68 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * binop.h - prototypes pour les opérations booléennes impliquant deux opérandes
+ *
+ * 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 _ANALYSIS_SCAN_CONDS_BINOP_H
+#define _ANALYSIS_SCAN_CONDS_BINOP_H
+
+
+#include <glib-object.h>
+
+
+#include "../cond.h"
+
+
+
+#define G_TYPE_BINARY_OPERATION            g_binary_operation_get_type()
+#define G_BINARY_OPERATION(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_BINARY_OPERATION, GBinaryOperation))
+#define G_IS_BINARY_OPERATION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_BINARY_OPERATION))
+#define G_BINARY_OPERATION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BINARY_OPERATION, GBinaryOperationClass))
+#define G_IS_BINARY_OPERATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BINARY_OPERATION))
+#define G_BINARY_OPERATION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BINARY_OPERATION, GBinaryOperationClass))
+
+
+/* Opération booléenne impliquant deux opérandes (instance) */
+typedef struct _GBinaryOperation GBinaryOperation;
+
+/* Opération booléenne impliquant deux opérandes (classe) */
+typedef struct _GBinaryOperationClass GBinaryOperationClass;
+
+
+/* Types d'opérations booléennes disponibles */
+typedef enum _BinOpType
+{
+    BOT_AND,
+    BOT_OR,
+    BOT_XOR,
+
+} BinOpType;
+
+
+/* Indique le type défini pour une opération booléenne de validation. */
+GType g_binary_operation_get_type(void);
+
+/* Met en place une représentation d'opération booléenne. */
+GBinaryOperation *g_binary_operation_new(GMatchCondition *, GMatchCondition *, BinOpType);
+
+
+
+#endif  /* _ANALYSIS_SCAN_CONDS_BINOP_H */
diff --git a/src/analysis/scan/conds/counter-int.h b/src/analysis/scan/conds/counter-int.h
new file mode 100644
index 0000000..a706fca
--- /dev/null
+++ b/src/analysis/scan/conds/counter-int.h
@@ -0,0 +1,53 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * counter-int.h - prototypes internes pour le décompte de correspondances identifiées dans du contenu binaire
+ *
+ * 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 _ANALYSIS_SCAN_CONDS_COUNTER_INT_H
+#define _ANALYSIS_SCAN_CONDS_COUNTER_INT_H
+
+
+#include "counter.h"
+
+
+#include "../cond-int.h"
+
+
+
+/* Décompte des identifications de motifs (instance) */
+struct _GMatchCounter
+{
+    GMatchCondition parent;                 /* A laisser en premier        */
+
+    GSearchPattern *pattern;                /* Motif associé               */
+
+};
+
+/* Décompte des identifications de motifs (classe) */
+struct _GMatchCounterClass
+{
+    GMatchConditionClass parent;            /* A laisser en premier        */
+
+};
+
+
+
+#endif  /* _ANALYSIS_SCAN_CONDS_COUNTER_INT_H */
diff --git a/src/analysis/scan/conds/counter.c b/src/analysis/scan/conds/counter.c
new file mode 100644
index 0000000..7cf36b8
--- /dev/null
+++ b/src/analysis/scan/conds/counter.c
@@ -0,0 +1,232 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * counter.c - décompte de correspondances identifiées dans du contenu binaire
+ *
+ * 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 "counter.h"
+
+
+#include "counter-int.h"
+
+
+
+/* --------------------- INSTANCIATION D'UNE FORME DE CONDITION --------------------- */
+
+
+/* Initialise la classe des opérations booléennes. */
+static void g_match_counter_class_init(GMatchCounterClass *);
+
+/* Initialise une instance d'opération booléenne. */
+static void g_match_counter_init(GMatchCounter *);
+
+/* Supprime toutes les références externes. */
+static void g_match_counter_dispose(GMatchCounter *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_match_counter_finalize(GMatchCounter *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Indique le statut d'une condition de validation. */
+static unsigned long long g_match_counter_resolve_as_number(const GMatchCounter *);
+
+/* Lance l'analyse de contenu binaire selon un motif donné. */
+static void g_match_counter_analyze(const GMatchCounter *, const bin_t *, phys_t, phys_t, bool);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       INSTANCIATION D'UNE FORME DE CONDITION                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un décompte de résultats lors d'une recherche de motifs. */
+G_DEFINE_TYPE(GMatchCounter, g_match_counter, G_TYPE_MATCH_CONDITION);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des opérations booléennes.              *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_match_counter_class_init(GMatchCounterClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GMatchConditionClass *cond;             /* Classe parente directe      */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_match_counter_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_match_counter_finalize;
+
+    cond = G_MATCH_CONDITION_CLASS(klass);
+
+    cond->resolve_as_num = (resolve_cond_as_number_fc)g_match_counter_resolve_as_number;
+    cond->analyze = (analyze_cond_fc)g_match_counter_analyze;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op = instance à initialiser.                                 *
+*                                                                             *
+*  Description : Initialise une instance d'opération booléenne.               *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_match_counter_init(GMatchCounter *counter)
+{
+    counter->pattern = NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op = instance d'objet GLib à traiter.                        *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_match_counter_dispose(GMatchCounter *counter)
+{
+    g_clear_object(&counter->pattern);
+
+    G_OBJECT_CLASS(g_match_counter_parent_class)->dispose(G_OBJECT(counter));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op = instance d'objet GLib à traiter.                        *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_match_counter_finalize(GMatchCounter *counter)
+{
+    G_OBJECT_CLASS(g_match_counter_parent_class)->finalize(G_OBJECT(counter));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : pattern = motif à impliquer.                                 *
+*                                                                             *
+*  Description : Met en place un décompte de correspondances obtenues.        *
+*                                                                             *
+*  Retour      : Condition mise en place.                                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GMatchCounter *g_match_counter_new(GSearchPattern *pattern)
+{
+    GMatchCounter *result;                  /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_MATCH_COUNTER, NULL);
+
+    result->pattern = pattern;
+    g_object_ref(G_OBJECT(pattern));
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op = condition à consulter.                                  *
+*                                                                             *
+*  Description : Indique le statut d'une condition de validation.             *
+*                                                                             *
+*  Retour      : Forme numérique de la condition considérée pour validation.  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static unsigned long long g_match_counter_resolve_as_number(const GMatchCounter *counter)
+{
+    unsigned long long result;              /* Valeur à retourner          */
+
+    result = g_search_pattern_count_matchs(counter->pattern);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : counter = condition à considérer.                            *
+*                data    = données binaires brutes à considérer.              *
+*                size    = quantité de ces données.                           *
+*                pos     = position du point d'étude courant.                 *
+*                full    = force une recherche pleine et entière.             *
+*                                                                             *
+*  Description : Lance l'analyse de contenu binaire selon un motif donné.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_match_counter_analyze(const GMatchCounter *counter, const bin_t *data, phys_t size, phys_t pos, bool full)
+{
+    //g_search_pattern_analyze(counter->pattern, data, size, pos);
+
+}
diff --git a/src/analysis/scan/conds/counter.h b/src/analysis/scan/conds/counter.h
new file mode 100644
index 0000000..033ac99
--- /dev/null
+++ b/src/analysis/scan/conds/counter.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * counter.h - prototypes pour le décompte de correspondances identifiées dans du contenu binaire
+ *
+ * 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 _ANALYSIS_SCAN_CONDS_COUNTER_H
+#define _ANALYSIS_SCAN_CONDS_COUNTER_H
+
+
+#include <glib-object.h>
+
+
+#include "../pattern.h"
+
+
+
+#define G_TYPE_MATCH_COUNTER            g_match_counter_get_type()
+#define G_MATCH_COUNTER(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_MATCH_COUNTER, GMatchCounter))
+#define G_IS_MATCH_COUNTER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_MATCH_COUNTER))
+#define G_MATCH_COUNTER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_MATCH_COUNTER, GMatchCounterClass))
+#define G_IS_MATCH_COUNTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_MATCH_COUNTER))
+#define G_MATCH_COUNTER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_MATCH_COUNTER, GMatchCounterClass))
+
+
+/* Décompte des identifications de motifs (instance) */
+typedef struct _GMatchCounter GMatchCounter;
+
+/* Décompte des identifications de motifs (classe) */
+typedef struct _GMatchCounterClass GMatchCounterClass;
+
+
+/* Indique le type défini pour un décompte de résultats lors d'une recherche de motifs. */
+GType g_match_counter_get_type(void);
+
+/* Met en place une représentation d'opération booléenne. */
+GMatchCounter *g_match_counter_new(GSearchPattern *);
+
+
+
+#endif  /* _ANALYSIS_SCAN_CONDS_COUNTER_H */
diff --git a/src/analysis/scan/context-int.h b/src/analysis/scan/context-int.h
new file mode 100644
index 0000000..94302bf
--- /dev/null
+++ b/src/analysis/scan/context-int.h
@@ -0,0 +1,87 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * context-int.h - prototypes internes pour un suivi d'analyses via contextes
+ *
+ * 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 _ANALYSIS_SCAN_CONTEXT_INT_H
+#define _ANALYSIS_SCAN_CONTEXT_INT_H
+
+
+#include "context.h"
+
+
+#include "expr.h"
+
+
+
+/* Mémorisation des correspondances partielles */
+typedef struct _atom_match_tracker_t
+{
+    phys_t *matches;                        /* Correspondances à confirmer */
+    size_t allocated;                       /* Taille du talbeau préparé   */
+    size_t used;                            /* Nombre d'éléments présents  */
+
+} atom_match_tracker_t;
+
+#define ALLOCATION_STEP 10
+
+/* Condition définissant une règle de correspondance */
+typedef struct _rule_condition_t
+{
+    char *name;                             /* Désignation de la règle     */
+
+    GScanExpression *expr;                  /* Condition de correspondance */
+    bool final_reduced;                     /* Réduction finale tentée ?   */
+
+} rule_condition_t;
+
+/* Contexte de suivi d'une analyse en cours (instance) */
+struct _GScanContext
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    GScanOptions *options;                  /* Options d'analyses          */
+
+    GBinContent *content;                   /* Contenu binaire traité      */
+
+    patid_t next_patid;                     /* Prochain indice utilisable  */
+
+    atom_match_tracker_t *atom_trackers;    /* Correspondances partielles  */
+
+    GScanMatch **full_matches;              /* Correspondances confirmées  */
+    size_t full_allocated;                  /* Taille du talbeau préparé   */
+    size_t full_used;                       /* Nombre d'éléments présents  */
+
+    rule_condition_t *conditions;           /* Ensemble de règles suivies  */
+    size_t cond_count;                      /* Quantité de ces conditions  */
+
+};
+
+/* Contexte de suivi d'une analyse en cours (classe) */
+struct _GScanContextClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+};
+
+
+
+#endif  /* _ANALYSIS_SCAN_CONTEXT_INT_H */
diff --git a/src/analysis/scan/context.c b/src/analysis/scan/context.c
new file mode 100644
index 0000000..aec654a
--- /dev/null
+++ b/src/analysis/scan/context.c
@@ -0,0 +1,546 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * context.c - suivi d'analyses via contextes
+ *
+ * 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 "context.h"
+
+
+#include <assert.h>
+#include <string.h>
+
+
+#include "context-int.h"
+#include "exprs/literal.h"
+
+
+
+/* Initialise la classe des contextes de suivi d'analyses. */
+static void g_scan_context_class_init(GScanContextClass *);
+
+/* Initialise une instance de contexte de suivi d'analyse. */
+static void g_scan_context_init(GScanContext *);
+
+/* Supprime toutes les références externes. */
+static void g_scan_context_dispose(GScanContext *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_scan_context_finalize(GScanContext *);
+
+
+
+/* Indique le type défini pour un contexte de suivi d'analyse. */
+G_DEFINE_TYPE(GScanContext, g_scan_context, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des contextes de suivi d'analyses.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_context_class_init(GScanContextClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_context_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_scan_context_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : context = instance à initialiser.                            *
+*                                                                             *
+*  Description : Initialise une instance de contexte de suivi d'analyse.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_context_init(GScanContext *context)
+{
+    context->options = NULL;
+
+    context->content = NULL;
+
+    context->next_patid = 0;
+
+    context->atom_trackers = NULL;
+
+    context->full_matches = NULL;
+    context->full_allocated = 0;
+    context->full_used = 0;
+
+    context->conditions = NULL;
+    context->cond_count = 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : context = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_context_dispose(GScanContext *context)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    g_clear_object(&context->options);
+
+    g_clear_object(&context->content);
+
+    for (i = 0; i < context->full_used; i++)
+        g_clear_object(&context->full_matches[i]);
+
+    for (i = 0; i < context->cond_count; i++)
+        g_clear_object(&context->conditions[i].expr);
+
+    G_OBJECT_CLASS(g_scan_context_parent_class)->dispose(G_OBJECT(context));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : context = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_context_finalize(GScanContext *context)
+{
+    size_t i;                               /* Boucle de parcours          */
+    atom_match_tracker_t *atracker;         /* Conservateur à manipuler #1 */
+
+    if (context->atom_trackers != NULL)
+    {
+        for (i = 0; i < context->next_patid; i++)
+        {
+            atracker = context->atom_trackers + i;
+
+            if (atracker->matches != NULL)
+                free(atracker->matches);
+
+        }
+
+        free(context->atom_trackers);
+
+    }
+
+    if (context->full_matches != NULL)
+        free(context->full_matches);
+
+    if (context->conditions != NULL)
+    {
+        for (i = 0; i < context->cond_count; i++)
+            free(context->conditions[i].name);
+
+        free(context->conditions);
+
+    }
+
+    G_OBJECT_CLASS(g_scan_context_parent_class)->finalize(G_OBJECT(context));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : options = ensemble d'options d'analyses à respecter.         *
+*                                                                             *
+*  Description : Définit un contexte pour suivi d'analyse.                    *
+*                                                                             *
+*  Retour      : Fonction mise en place.                                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanContext *g_scan_context_new(GScanOptions *options)
+{
+    GScanContext *result;                   /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_SCAN_CONTEXT, NULL);
+
+    result->options = options;
+    g_object_ref(G_OBJECT(options));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : context = instance à consulter.                              *
+*                                                                             *
+*  Description : Fournit l'ensemble des options à respecter pour les analyses.*
+*                                                                             *
+*  Retour      : Ensemble d'options en vigueur.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanOptions *g_scan_context_get_options(GScanContext *context)
+{
+    GScanOptions *result;                   /* Ensemble à retourner        */
+
+    result = context->options;
+
+    g_object_ref(G_OBJECT(result));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : context = instance à consulter.                              *
+*                                                                             *
+*  Description : Fournit un identifiant unique pour un motif recherché.       *
+*                                                                             *
+*  Retour      : Identifiant nouveau à utiliser.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+patid_t g_scan_context_get_new_pattern_id(GScanContext *context)
+{
+    patid_t result;                         /* Identifiant à retourner     */
+
+    result = context->next_patid++;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : context = instance à consulter.                              *
+*                content = contenu binaire en cours d'analyse.                *
+*                                                                             *
+*  Description : Définit le contenu principal à analyser.                     *
+*                                                                             *
+*  Retour      : Content binaire associé au context.                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_scan_context_set_content(GScanContext *context, GBinContent *content)
+{
+    g_clear_object(&context->content);
+
+    context->content = content;
+
+    g_object_ref(G_OBJECT(content));
+
+    context->atom_trackers = calloc(context->next_patid, sizeof(atom_match_tracker_t));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : context = instance à consulter.                              *
+*                                                                             *
+*  Description : Fournit une référence au contenu principal analysé.          *
+*                                                                             *
+*  Retour      : Content binaire associé au context.                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBinContent *g_scan_context_get_content(const GScanContext *context)
+{
+    GBinContent *result;                    /* Instance à retourner        */
+
+    result = context->content;
+
+    g_object_ref(G_OBJECT(result));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : context = instance à mettre à jour.                          *
+*                id      = identifiant du motif trouvé.                       *
+*                offset  = localisation du motif au sein d'un contenu.        *
+*                                                                             *
+*  Description : Enregistre une correspondance partielle dans un contenu.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_scan_context_register_atom_match(GScanContext *context, patid_t id, phys_t offset)
+{
+    atom_match_tracker_t *tracker;          /* Gestionnaire concerné       */
+
+    tracker = &context->atom_trackers[id];
+
+    if (tracker->used == tracker->allocated)
+    {
+        tracker->allocated += ALLOCATION_STEP;
+        tracker->matches = realloc(tracker->matches, tracker->allocated * sizeof(phys_t));
+    }
+
+    tracker->matches[tracker->used++] = offset;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : context = instance à mettre à jour.                          *
+*                id      = identifiant du motif trouvé.                       *
+*                count   = nombre de localisations renvoyées. [OUT]           *
+*                                                                             *
+*  Description : Retourne tous les correspondances partielles notées.         *
+*                                                                             *
+*  Retour      : Liste interne des localisations conservées.                  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+const phys_t *g_scan_context_get_atom_matches(const GScanContext *context, patid_t id, size_t *count)
+{
+    const phys_t *result;                   /* Liste constituée à renvoyer */
+    atom_match_tracker_t *tracker;          /* Gestionnaire concerné       */
+
+    tracker = &context->atom_trackers[id];
+
+    result = tracker->matches;
+    *count = tracker->used;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : context = instance à mettre à jour.                          *
+*                match   = représentation d'une plein ecorrespondance.        *
+*                                                                             *
+*  Description : Enregistre une correspondance complète avec un contenu.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_scan_context_register_full_match(GScanContext *context, GScanMatch *match)
+{
+    if (context->full_used == context->full_allocated)
+    {
+        context->full_allocated += ALLOCATION_STEP;
+        context->full_matches = realloc(context->full_matches, context->full_allocated * sizeof(GScanMatch *));
+    }
+
+    context->full_matches[context->full_used++] = match;
+    g_object_ref(G_OBJECT(match));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : context = mémoire de résultats d'analyse à consulter.        *
+*                                                                             *
+*  Description : Affiche les correspondances identifiées.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_scan_context_display(const GScanContext *context)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    for (i = 0; i < context->full_used; i++)
+        g_scan_match_display(context->full_matches[i]);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : context = mémoire de résultats d'analyse à compléter.        *
+*                name    = désignation de la règle ciblée.                    *
+*                expr    = expression de condition à réduire.                 *
+*                                                                             *
+*  Description : Intègre une condition de correspondance pour règle.          *
+*                                                                             *
+*  Retour      : Bilan final d'une intégration (false si nom déjà présent).   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_scan_context_set_rule_condition(GScanContext *context, const char *name, const GScanExpression *expr)
+{
+    bool result;                            /* Bilan à retourner           */
+    size_t i;                               /* Boucle de parcours          */
+    rule_condition_t *new;                  /* Nouvel élément à intégrer   */
+
+    result = true;
+
+    /* Recherche d'antécédent */
+
+    for (i = 0; context->cond_count; i++)
+        if (strcmp(name, context->conditions[i].name) == 0)
+        {
+            result = false;
+            break;
+        }
+
+    /* Ajout d'un nouvel élément ? */
+
+    if (result)
+    {
+        context->conditions = realloc(context->conditions, ++context->cond_count * sizeof(rule_condition_t));
+
+        new = &context->conditions[context->cond_count - 1];
+
+        new->name = strdup(name);
+
+        new->expr = g_scan_expression_duplicate(expr);
+        new->final_reduced = false;
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : context = mémoire de résultats d'analyse à consulter.        *
+*                name    = désignation de la règle ciblée.                    *
+*                                                                             *
+*  Description : Indique si une correspondance globale a pu être établie.     *
+*                                                                             *
+*  Retour      : Bilan final d'une analyse (false par défaut).                *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_scan_context_has_match_for_rule(GScanContext *context, const char *name)
+{
+    bool result;                            /* Bilan à retourner           */
+    size_t i;                               /* Boucle de parcours          */
+    rule_condition_t *cond;                 /* Condition à considérer      */
+    GScanExpression *new;                   /* Nouvelle expression réduite */
+    bool valid;                             /* Validité d'une récupération */
+
+    result = false;
+
+    /* Recherche de la règle visée */
+
+    cond = NULL;
+
+    for (i = 0; context->cond_count; i++)
+        if (strcmp(name, context->conditions[i].name) == 0)
+        {
+            cond = &context->conditions[i];
+            break;
+        }
+
+    if (cond == NULL)
+        goto exit;
+
+    /* Tentative de réduction finale */
+
+    if (!cond->final_reduced)
+    {
+        new = g_scan_expression_reduce(cond->expr, context, false);
+
+        if (new != NULL)
+        {
+            g_object_unref(G_OBJECT(cond->expr));
+            cond->expr = new;
+        }
+
+        cond->final_reduced = true;
+
+    }
+
+    /* Tentative de récupération d'un bilan final */
+
+    if (G_IS_LITERAL_EXPRESSION(cond->expr))
+    {
+        valid = g_literal_expression_get_boolean_value(G_LITERAL_EXPRESSION(cond->expr), &result);
+
+        if (!valid)
+        {
+            assert(!result);
+            result = false;
+        }
+
+    }
+
+ exit:
+
+    return result;
+
+}
diff --git a/src/analysis/scan/context.h b/src/analysis/scan/context.h
new file mode 100644
index 0000000..92522f8
--- /dev/null
+++ b/src/analysis/scan/context.h
@@ -0,0 +1,100 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * context.h - prototypes pour le suivi d'analyses via contextes
+ *
+ * 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 _ANALYSIS_SCAN_CONTEXT_H
+#define _ANALYSIS_SCAN_CONTEXT_H
+
+
+#include <glib-object.h>
+
+
+#include "match.h"
+#include "options.h"
+#include "../content.h"
+
+
+
+/* Depuis expr.h : expression d'évaluation généraliste (instance) */
+typedef struct _GScanExpression GScanExpression;
+
+
+#define G_TYPE_SCAN_CONTEXT            g_scan_context_get_type()
+#define G_SCAN_CONTEXT(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_CONTEXT, GScanContext))
+#define G_IS_SCAN_CONTEXT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_CONTEXT))
+#define G_SCAN_CONTEXT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_CONTEXT, GScanContextClass))
+#define G_IS_SCAN_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_CONTEXT))
+#define G_SCAN_CONTEXT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_CONTEXT, GScanContextClass))
+
+
+/* Contexte de suivi d'une analyse en cours (instance) */
+typedef struct _GScanContext GScanContext;
+
+/* Contexte de suivi d'une analyse en cours (classe) */
+typedef struct _GScanContextClass GScanContextClass;
+
+
+/* Identifiant de motif intégré */
+typedef uint64_t patid_t;
+
+#define INVALID_PATTERN_ID 0xffffffffffffffff
+
+
+/* Indique le type défini pour un contexte de suivi d'analyse. */
+GType g_scan_context_get_type(void);
+
+/* Définit un contexte pour suivi d'analyse. */
+GScanContext *g_scan_context_new(GScanOptions *);
+
+/* Fournit l'ensemble des options à respecter pour les analyses. */
+GScanOptions *g_scan_context_get_options(GScanContext *);
+
+/* Fournit un identifiant unique pour un motif recherché. */
+patid_t g_scan_context_get_new_pattern_id(GScanContext *);
+
+/* Définit le contenu principal à analyser. */
+void g_scan_context_set_content(GScanContext *, GBinContent *);
+
+/* Fournit une référence au contenu principal analysé. */
+GBinContent *g_scan_context_get_content(const GScanContext *);
+
+/* Enregistre une correspondance partielle dans un contenu. */
+void g_scan_context_register_atom_match(GScanContext *, patid_t, phys_t);
+
+/* Retourne tous les correspondances partielles notées. */
+const phys_t *g_scan_context_get_atom_matches(const GScanContext *, patid_t, size_t *);
+
+/* Enregistre une correspondance complète avec un contenu. */
+void g_scan_context_register_full_match(GScanContext *, GScanMatch *);
+
+/* Affiche les correspondances identifiées. */
+void g_scan_context_display(const GScanContext *);
+
+/* Intègre une condition de correspondance pour règle. */
+bool g_scan_context_set_rule_condition(GScanContext *, const char *, const GScanExpression *);
+
+/* Indique si une correspondance globale a pu être établie. */
+bool g_scan_context_has_match_for_rule(GScanContext *, const char *);
+
+
+
+#endif  /* _ANALYSIS_SCAN_CONTEXT_H */
diff --git a/src/analysis/scan/core.c b/src/analysis/scan/core.c
new file mode 100644
index 0000000..3b6c2c9
--- /dev/null
+++ b/src/analysis/scan/core.c
@@ -0,0 +1,67 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * core.c - enregistrement des fonctions principales
+ *
+ * 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 "core.h"
+
+
+#include "funcs/datasize.h"
+#include "funcs/uint.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : space = espace de noms à composer.                           *
+*                                                                             *
+*  Description : Inscrit les principales fonctions dans l'espace racine.      *
+*                                                                             *
+*  Retour      : Bilan des enregistrements effectués.                         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool populate_main_scan_namespace(GScanNamespace *space)
+{
+    bool result;
+
+    result = true;
+
+#define REGISTER_FUNC(s, f, n)                                              \
+    ({                                                                      \
+        bool __result;                                                      \
+        __result = g_scan_namespace_register(s, G_REGISTERED_ITEM(f), n);   \
+        __result;                                                           \
+    })
+
+    if (result) result = REGISTER_FUNC(space, g_datasize_function_new(), "datasize");
+    if (result) result = REGISTER_FUNC(space, g_datasize_function_new(), "filesize"); /* Alias */
+
+    if (result) result = REGISTER_FUNC(space, g_uint_function_new(MDS_8_BITS_UNSIGNED), "uint8");
+    if (result) result = REGISTER_FUNC(space, g_uint_function_new(MDS_16_BITS_UNSIGNED), "uint16");
+    if (result) result = REGISTER_FUNC(space, g_uint_function_new(MDS_32_BITS_UNSIGNED), "uint32");
+    if (result) result = REGISTER_FUNC(space, g_uint_function_new(MDS_64_BITS_UNSIGNED), "uint64");
+
+    return result;
+
+}
diff --git a/src/analysis/scan/core.h b/src/analysis/scan/core.h
new file mode 100644
index 0000000..21d6e7c
--- /dev/null
+++ b/src/analysis/scan/core.h
@@ -0,0 +1,37 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * core.h - prototypes pour l'enregistrement des fonctions principales
+ *
+ * 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 _ANALYSIS_SCAN_CORE_H
+#define _ANALYSIS_SCAN_CORE_H
+
+
+#include "space.h"
+
+
+
+/* Inscrit les principales fonctions dans l'espace racine. */
+bool populate_main_scan_namespace(GScanNamespace *);
+
+
+
+#endif  /* _ANALYSIS_SCAN_CORE_H */
diff --git a/src/analysis/scan/decl.h b/src/analysis/scan/decl.h
new file mode 100644
index 0000000..ab70368
--- /dev/null
+++ b/src/analysis/scan/decl.h
@@ -0,0 +1,40 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * decl.h - déclarations de prototypes utiles
+ *
+ * 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 Chrysalide.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_SCAN_DECL_H
+#define _ANALYSIS_SCAN_DECL_H
+
+
+#include <stdbool.h>
+
+
+#include "scanner.h"
+
+
+
+/* Complète une recherche de motifs avec des règles. */
+bool process_rules_definitions(GContentScanner *, const char *, size_t);
+
+
+
+#endif  /* _ANALYSIS_SCAN_DECL_H */
diff --git a/src/analysis/scan/expr-int.h b/src/analysis/scan/expr-int.h
new file mode 100644
index 0000000..4323693
--- /dev/null
+++ b/src/analysis/scan/expr-int.h
@@ -0,0 +1,78 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * expr-int.h - prototypes internes pour la définition d'une expression servant aux conditions de correspondance
+ *
+ * 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 _ANALYSIS_SCAN_EXPR_INT_H
+#define _ANALYSIS_SCAN_EXPR_INT_H
+
+
+#include "expr.h"
+
+
+#include <stdbool.h>
+
+
+#include "../../glibext/comparison-int.h"
+
+
+
+/* Réalise une comparaison entre objets selon un critère précis. */
+typedef bool (* compare_expr_rich_fc) (const GScanExpression *, const GScanExpression *, RichCmpOperation, bool *);
+
+/* Vérifie la validité d'une expression. */
+typedef bool (* check_expr_validity_fc) (const GScanExpression *);
+
+/* Reproduit une expression en place dans une nouvelle instance. */
+typedef GScanExpression * (* dup_expr_fc) (const GScanExpression *);
+
+/* Réduit une expression à une forme plus simple. */
+typedef GScanExpression * (* reduce_expr_fc) (GScanExpression *, GScanContext *, bool);
+
+
+/* Expression d'évaluation généraliste (instance) */
+struct _GScanExpression
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    ExprValueType value_type;               /* Type de valeur portée       */
+
+};
+
+/* Expression d'évaluation généraliste (classe) */
+struct _GScanExpressionClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+    compare_expr_rich_fc cmp_rich;          /* Comparaison de façon précise*/
+    check_expr_validity_fc check;           /* Validation de la cohérence  */
+    dup_expr_fc dup;                        /* Reproduction d'expression   */
+    reduce_expr_fc reduce;                  /* Simplification d'expression */
+
+};
+
+
+/* Met en place une expression d'évaluation pour analyse. */
+bool g_scan_expression_create(GScanExpression *, ExprValueType);
+
+
+
+#endif  /* _ANALYSIS_SCAN_EXPR_INT_H */
diff --git a/src/analysis/scan/expr.c b/src/analysis/scan/expr.c
new file mode 100644
index 0000000..0b81e01
--- /dev/null
+++ b/src/analysis/scan/expr.c
@@ -0,0 +1,331 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * expr.c - définition d'une expression servant aux conditions de correspondance
+ *
+ * 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 "expr.h"
+
+
+#include "expr-int.h"
+
+
+
+/* ----------------------- BASES D'OBJET POUR LE SYSTEME GLIB ----------------------- */
+
+
+/* Initialise la classe des expressions de validation. */
+static void g_scan_expression_class_init(GScanExpressionClass *);
+
+/* Initialise une instance d'expression de validation. */
+static void g_scan_expression_init(GScanExpression *);
+
+/* Procède à l'initialisation de l'interface de comparaison. */
+static void g_scan_expression_cmp_interface_init(GComparableItemInterface *);
+
+/* Supprime toutes les références externes. */
+static void g_scan_expression_dispose(GScanExpression *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_scan_expression_finalize(GScanExpression *);
+
+
+/* ----------------------- INTERFACE OFFRANT DES COMPARAISONS ----------------------- */
+
+
+/* Réalise une comparaison entre objets selon un critère précis. */
+static bool g_scan_expression_compare_rich(const GScanExpression *, const GScanExpression *, RichCmpOperation, bool *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                         BASES D'OBJET POUR LE SYSTEME GLIB                         */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une expression de validation. */
+G_DEFINE_TYPE_WITH_CODE(GScanExpression, g_scan_expression, G_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE(G_TYPE_COMPARABLE_ITEM, g_scan_expression_cmp_interface_init));
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des expressions de validation.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_expression_class_init(GScanExpressionClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_expression_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_scan_expression_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = instance à initialiser.                               *
+*                                                                             *
+*  Description : Initialise une instance d'expression de validation.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_expression_init(GScanExpression *expr)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iface = interface GLib à initialiser.                        *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de comparaison.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_expression_cmp_interface_init(GComparableItemInterface *iface)
+{
+    iface->cmp_rich = (compare_rich_fc)g_scan_expression_compare_rich;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_expression_dispose(GScanExpression *expr)
+{
+    G_OBJECT_CLASS(g_scan_expression_parent_class)->dispose(G_OBJECT(expr));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_expression_finalize(GScanExpression *expr)
+{
+    G_OBJECT_CLASS(g_scan_expression_parent_class)->finalize(G_OBJECT(expr));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr  = instance à initialiser pleinement.                   *
+*                vtype = type de valeur associée par l'expression.            *
+*                                                                             *
+*  Description : Met en place une expression d'évaluation pour analyse.       *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_scan_expression_create(GScanExpression *expr, ExprValueType vtype)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = true;
+
+    expr->value_type = vtype;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = expression à consulter.                               *
+*                                                                             *
+*  Description : Indique le type de valeur portée par une expression.         *
+*                                                                             *
+*  Retour      : Type de valeur associée à l'expression.                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+ExprValueType g_scan_expression_get_value_type(const GScanExpression *expr)
+{
+    ExprValueType result;                   /* Type à retourner            */
+
+    result = expr->value_type;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = expression à consulter.                               *
+*                                                                             *
+*  Description : Vérifie la validité d'une expression.                        *
+*                                                                             *
+*  Retour      : Validation de l'usage de l'expression.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_scan_expression_check_validity(const GScanExpression *expr)
+{
+    bool result;                            /* Bilan à retourner           */
+    GScanExpressionClass *class;            /* Classe à activer            */
+
+    class = G_SCAN_EXPRESSION_GET_CLASS(expr);
+
+    result = class->check(expr);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = expression à copier.                                  *
+*                                                                             *
+*  Description : Reproduit une expression en place dans une nouvelle instance.*
+*                                                                             *
+*  Retour      : Nouvelle instance d'expression.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanExpression *g_scan_expression_duplicate(const GScanExpression *expr)
+{
+    GScanExpression *result;                /* Instance copiée à retourner */
+    GScanExpressionClass *class;            /* Classe à activer            */
+
+    class = G_SCAN_EXPRESSION_GET_CLASS(expr);
+
+    result = class->dup(expr);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr  = expression à consulter.                              *
+*                ctx   = contexte de suivi de l'analyse courante.             *
+*                final = indique une ultime conversion dans le cycle en cours.*
+*                                                                             *
+*  Description : Réduit une expression à une forme plus simple.               *
+*                                                                             *
+*  Retour      : Réduction correspondante, expression déjà réduite, ou NULL.  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanExpression *g_scan_expression_reduce(GScanExpression *expr, GScanContext *ctx, bool final)
+{
+    GScanExpression *result;                /* Instance à renvoyer         */
+    GScanExpressionClass *class;            /* Classe à activer            */
+
+    class = G_SCAN_EXPRESSION_GET_CLASS(expr);
+
+    result = class->reduce(expr, ctx, final);
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                         INTERFACE OFFRANT DES COMPARAISONS                         */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item   = premier objet à cnsulter pour une comparaison.      *
+*                other  = second objet à cnsulter pour une comparaison.       *
+*                op     = opération de comparaison à réaliser.                *
+*                status = bilan des opérations de comparaison. [OUT]          *
+*                                                                             *
+*  Description : Réalise une comparaison entre objets selon un critère précis.*
+*                                                                             *
+*  Retour      : true si la comparaison a pu être effectuée, false sinon.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_scan_expression_compare_rich(const GScanExpression *item, const GScanExpression *other, RichCmpOperation op, bool *status)
+{
+    bool result;                            /* Etat à retourner            */
+    GScanExpressionClass *class;            /* Classe à activer            */
+
+    class = G_SCAN_EXPRESSION_GET_CLASS(item);
+
+    if (class->cmp_rich != NULL)
+        result = class->cmp_rich(item, other, op, status);
+    else
+        result = false;
+
+    return result;
+
+}
diff --git a/src/analysis/scan/expr.h b/src/analysis/scan/expr.h
new file mode 100644
index 0000000..98e7f7d
--- /dev/null
+++ b/src/analysis/scan/expr.h
@@ -0,0 +1,84 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * expr.h - prototypes pour la définition d'une expression servant aux conditions de correspondance
+ *
+ * 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 _ANALYSIS_SCAN_EXPR_H
+#define _ANALYSIS_SCAN_EXPR_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+
+
+#include "context.h"
+
+
+
+#define G_TYPE_SCAN_EXPRESSION            g_scan_expression_get_type()
+#define G_SCAN_EXPRESSION(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_EXPRESSION, GScanExpression))
+#define G_IS_SCAN_EXPRESSION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_EXPRESSION))
+#define G_SCAN_EXPRESSION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_EXPRESSION, GScanExpressionClass))
+#define G_IS_SCAN_EXPRESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_EXPRESSION))
+#define G_SCAN_EXPRESSION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_EXPRESSION, GScanExpressionClass))
+
+
+/* Expression d'évaluation généraliste (instance) */
+typedef struct _GScanExpression GScanExpression;
+
+/* Expression d'évaluation généraliste (classe) */
+typedef struct _GScanExpressionClass GScanExpressionClass;
+
+
+/* Types naturel équivalant à l'expression */
+typedef enum _ExprValueType
+{
+    EVT_BOOLEAN,                            /* Valeur booléenne            */
+    EVT_INTEGER,                            /* Nombre entier 64 bits       */
+    EVT_STRING,                             /* Chaîne de caractères        */
+    EVT_REG_EXPR,                           /* Expression rationnelle      */
+
+    EVT_COUNT,
+
+    EVT_PENDING,                            /* Nature à déterminer         */
+    EVT_UNRESOLVABLE,                       /* Nature indéterminable       */
+
+} ExprValueType;
+
+
+/* Indique le type défini pour une expression de validation. */
+GType g_scan_expression_get_type(void);
+
+/* Indique le type de valeur portée par une expression. */
+ExprValueType g_scan_expression_get_value_type(const GScanExpression *);
+
+/* Vérifie la validité d'une expression. */
+bool g_scan_expression_check_validity(const GScanExpression *);
+
+/* Reproduit une expression en place dans une nouvelle instance. */
+GScanExpression *g_scan_expression_duplicate(const GScanExpression *);
+
+/* Réduit une expression à une forme plus simple. */
+GScanExpression *g_scan_expression_reduce(GScanExpression *, GScanContext *, bool);
+
+
+
+#endif  /* _ANALYSIS_SCAN_EXPR_H */
diff --git a/src/analysis/scan/exprs/Makefile.am b/src/analysis/scan/exprs/Makefile.am
new file mode 100644
index 0000000..f164864
--- /dev/null
+++ b/src/analysis/scan/exprs/Makefile.am
@@ -0,0 +1,24 @@
+
+noinst_LTLIBRARIES  = libanalysisscanexprs.la
+
+
+libanalysisscanexprs_la_SOURCES =			\
+	arithmop-int.h							\
+	arithmop.h arithmop.c					\
+	boolop-int.h							\
+	boolop.h boolop.c						\
+	call-int.h								\
+	call.h call.c							\
+	literal-int.h							\
+	literal.h literal.c						\
+	relop-int.h								\
+	relop.h relop.c							\
+	str-int.h								\
+	str.h str.c
+
+libanalysisscanexprs_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS)
+
+
+devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
+
+dev_HEADERS = $(libanalysisscanexprs_la_SOURCES:%c=)
diff --git a/src/analysis/scan/exprs/arithmop-int.h b/src/analysis/scan/exprs/arithmop-int.h
new file mode 100644
index 0000000..75f1dbb
--- /dev/null
+++ b/src/analysis/scan/exprs/arithmop-int.h
@@ -0,0 +1,60 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * arithmop-int.h - prototypes internes pour la gestion des opérations arithmétiques
+ *
+ * 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 _ANALYSIS_SCAN_EXPRS_ARITHMOP_INT_H
+#define _ANALYSIS_SCAN_EXPRS_ARITHMOP_INT_H
+
+
+#include "arithmop.h"
+
+
+#include "../expr-int.h"
+
+
+
+/* Opération arithmétique impliquant deux opérandes (instance) */
+struct _GArithmOperation
+{
+    GScanExpression parent;                 /* A laisser en premier        */
+
+    ArithmeticExpressionOperator operator;  /* Type d'opération menée      */
+
+    GScanExpression *first;                 /* Expression impactée #1      */
+    GScanExpression *second;                /* Expression impactée #2      */
+
+};
+
+/* Opération arithmétique impliquant deux opérandes (classe) */
+struct _GArithmOperationClass
+{
+    GScanExpressionClass parent;            /* A laisser en premier        */
+
+};
+
+
+/* Met en place une opération arithmétique entre expressions. */
+bool g_arithmetic_operation_create(GArithmOperation *, ArithmeticExpressionOperator, GScanExpression *, GScanExpression *);
+
+
+
+#endif  /* _ANALYSIS_SCAN_EXPRS_ARITHMOP_INT_H */
diff --git a/src/analysis/scan/exprs/arithmop.c b/src/analysis/scan/exprs/arithmop.c
new file mode 100644
index 0000000..f57e260
--- /dev/null
+++ b/src/analysis/scan/exprs/arithmop.c
@@ -0,0 +1,414 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * arithmop.c - gestion des opérations arithmétiques
+ *
+ * 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 "arithmop.h"
+
+
+#include "arithmop-int.h"
+#include "literal.h"
+
+
+
+/* --------------------- INTRODUCTION D'UNE NOUVELLE EXPRESSION --------------------- */
+
+
+/* Initialise la classe des opérations arithmétiques. */
+static void g_arithmetic_operation_class_init(GArithmOperationClass *);
+
+/* Initialise une instance d'opération arithmétique. */
+static void g_arithmetic_operation_init(GArithmOperation *);
+
+/* Supprime toutes les références externes. */
+static void g_arithmetic_operation_dispose(GArithmOperation *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_arithmetic_operation_finalize(GArithmOperation *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Réalise une comparaison entre objets selon un critère précis. */
+static bool g_arithmetic_operation_compare_rich(const GArithmOperation *, const GArithmOperation *, RichCmpOperation, bool *);
+
+/* Initialise une instance d'opération de relation. */
+static GScanExpression *g_arithmetic_operation_duplicate(const GArithmOperation *);
+
+/* Réduit une expression à une forme plus simple. */
+GScanExpression *g_arithmetic_operation_reduce(GArithmOperation *, GScanContext *, bool);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       INTRODUCTION D'UNE NOUVELLE EXPRESSION                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une opération de relation entre expressions. */
+G_DEFINE_TYPE(GArithmOperation, g_arithmetic_operation, G_TYPE_SCAN_EXPRESSION);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des opérations arithmétiques.           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_arithmetic_operation_class_init(GArithmOperationClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GScanExpressionClass *expr;             /* Version de classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_arithmetic_operation_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_arithmetic_operation_finalize;
+
+    expr = G_SCAN_EXPRESSION_CLASS(klass);
+
+    expr->cmp_rich = (compare_expr_rich_fc)g_arithmetic_operation_compare_rich;
+    expr->dup = (dup_expr_fc)g_arithmetic_operation_duplicate;
+    expr->reduce = (reduce_expr_fc)g_arithmetic_operation_reduce;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op = instance à initialiser.                                 *
+*                                                                             *
+*  Description : Initialise une instance d'opération arithmétique.            *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_arithmetic_operation_init(GArithmOperation *op)
+{
+    op->first = NULL;
+    op->second = NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op = instance d'objet GLib à traiter.                        *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_arithmetic_operation_dispose(GArithmOperation *op)
+{
+    g_clear_object(&op->first);
+    g_clear_object(&op->second);
+
+    G_OBJECT_CLASS(g_arithmetic_operation_parent_class)->dispose(G_OBJECT(op));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op = instance d'objet GLib à traiter.                        *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_arithmetic_operation_finalize(GArithmOperation *op)
+{
+    G_OBJECT_CLASS(g_arithmetic_operation_parent_class)->finalize(G_OBJECT(op));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : operator = type d'opération arithmétique à représenter.      *
+*                first    = premier opérande concerné.                        *
+*                second   = éventuel second opérande impliqué ou NULL.        *
+*                                                                             *
+*  Description : Organise une opération arithmétique entre expressions.       *
+*                                                                             *
+*  Retour      : Fonction mise en place.                                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanExpression *g_arithmetic_operation_new(ArithmeticExpressionOperator operator, GScanExpression *first, GScanExpression *second)
+{
+    GScanExpression *result;                /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_ARITHMETIC_OPERATION, NULL);
+
+    if (!g_arithmetic_operation_create(G_ARITHMETIC_OPERATION(result), operator, first, second))
+        g_clear_object(&result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op       = instance à initialiser pleinement.                *
+*                operator = type d'opération booléenne à représenter.         *
+*                first    = premier opérande concerné.                        *
+*                second   = éventuel second opérande impliqué ou NULL.        *
+*                                                                             *
+*  Description : Met en place une opération arithmétique entre expressions.   *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_arithmetic_operation_create(GArithmOperation *op, ArithmeticExpressionOperator operator, GScanExpression *first, GScanExpression *second)
+{
+    bool result;                            /* Bilan à retourner           */
+    ExprValueType vtype;                    /* Type de valeur portée       */
+
+    result = false;
+
+    vtype = g_scan_expression_get_value_type(first);
+
+    if (vtype != EVT_INTEGER && vtype != EVT_PENDING)
+        goto exit;
+
+    vtype = g_scan_expression_get_value_type(second);
+
+    if (vtype != EVT_INTEGER && vtype != EVT_PENDING)
+        goto exit;
+
+    if (!g_scan_expression_create(G_SCAN_EXPRESSION(op), EVT_INTEGER))
+        goto exit;
+
+    op->operator = operator;
+
+    op->first = first;
+    g_object_ref(G_OBJECT(op->first));
+
+    op->second = second;
+    g_object_ref(G_OBJECT(op->second));
+
+    result = true;
+
+ exit:
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item   = premier objet à consulter pour une comparaison.     *
+*                other  = second objet à consulter pour une comparaison.      *
+*                op     = opération de comparaison à réaliser.                *
+*                status = bilan des opérations de comparaison. [OUT]          *
+*                                                                             *
+*  Description : Réalise une comparaison entre objets selon un critère précis.*
+*                                                                             *
+*  Retour      : true si la comparaison a pu être effectuée, false sinon.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_arithmetic_operation_compare_rich(const GArithmOperation *item, const GArithmOperation *other, RichCmpOperation op, bool *status)
+{
+    bool result;                            /* Etat à retourner            */
+    bool equal;                             /* Bilan intermédiaire         */
+
+    result = true; // TODO : cmp parent()->type
+
+    if (item->operator != other->operator)
+    {
+        result = compare_rich_integer_values(item->operator, other->operator, op);
+        goto done;
+    }
+
+    equal = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item), G_COMPARABLE_ITEM(other), RCO_EQ, status);
+
+    if (!equal)
+    {
+        result = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->first),
+                                                G_COMPARABLE_ITEM(other->first),
+                                                op, status);
+        goto done;
+    }
+
+    result = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->second),
+                                            G_COMPARABLE_ITEM(other->second),
+                                            op, status);
+
+ done:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = expression à copier.                                  *
+*                                                                             *
+*  Description : Reproduit une expression en place dans une nouvelle instance.*
+*                                                                             *
+*  Retour      : Nouvelle instance d'expression.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GScanExpression *g_arithmetic_operation_duplicate(const GArithmOperation *expr)
+{
+    GScanExpression *result;                /* Instance copiée à retourner */
+
+    result = g_arithmetic_operation_new(expr->operator, expr->first, expr->second);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr  = expression à consulter.                              *
+*                ctx   = contexte de suivi de l'analyse courante.             *
+*                final = impose une conversion finale de dernier tour.        *
+*                                                                             *
+*  Description : Réduit une expression à une forme plus simple.               *
+*                                                                             *
+*  Retour      : Réduction correspondante, expression déjà réduite, ou NULL.  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanExpression *g_arithmetic_operation_reduce(GArithmOperation *expr, GScanContext *ctx, bool final)
+{
+    GScanExpression *result;                /* Instance à renvoyer         */
+    GScanExpression *new;                   /* Nouvelle expression obtenue */
+    unsigned long long val_1;               /* Première valeur à traiter   */
+    unsigned long long val_2;               /* Second valeur à traiter     */
+    bool valid;                             /* Validité de ce bilan obtenu */
+    unsigned long long reduced;             /* Valeur réduite finale       */
+
+    result = NULL;
+
+    /* Réduction des éléments considérés */
+
+    new = g_scan_expression_reduce(expr->first, ctx, final);
+
+    if (new != NULL)
+    {
+        g_object_unref(G_OBJECT(expr->first));
+        expr->first = new;
+    }
+
+    if (expr->second != NULL)
+    {
+        new = g_scan_expression_reduce(expr->second, ctx, final);
+
+        if (new != NULL)
+        {
+            g_object_unref(G_OBJECT(expr->second));
+            expr->second = new;
+        }
+
+    }
+
+    /* Construction d'une réduction locale ? */
+
+    if (G_IS_LITERAL_EXPRESSION(expr->first) && G_IS_LITERAL_EXPRESSION(expr->second))
+    {
+        valid = g_literal_expression_get_integer_value(G_LITERAL_EXPRESSION(expr->first), &val_1);
+
+        if (valid)
+            valid = g_literal_expression_get_integer_value(G_LITERAL_EXPRESSION(expr->second), &val_2);
+
+        if (valid)
+            switch (expr->operator)
+            {
+                case AEO_PLUS:
+                    reduced = val_1 + val_2;
+                    break;
+
+                case AEO_MINUS:
+                    reduced = val_1 - val_2;
+                    break;
+
+                case AEO_MUL:
+                    reduced = val_1 * val_2;
+                    break;
+
+                case AEO_DIV:
+                    valid = (val_2 != 0);
+                    if (valid)
+                        reduced = val_1 / val_2;
+                    break;
+
+                case AEO_MOD:
+                    valid = (val_2 != 0);
+                    if (valid)
+                        reduced = val_1 % val_2;
+                    break;
+
+            }
+
+        if (valid)
+            result = g_literal_expression_new(EVT_INTEGER, &reduced);
+
+    }
+
+    return result;
+
+}
diff --git a/src/analysis/scan/exprs/arithmop.h b/src/analysis/scan/exprs/arithmop.h
new file mode 100644
index 0000000..dcc8bf8
--- /dev/null
+++ b/src/analysis/scan/exprs/arithmop.h
@@ -0,0 +1,67 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * arithmop.h - prototypes pour la gestion des opérations arithmétiques
+ *
+ * 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 _ANALYSIS_SCAN_EXPRS_ARITHMOP_H
+#define _ANALYSIS_SCAN_EXPRS_ARITHMOP_H
+
+
+#include "../expr.h"
+
+
+
+#define G_TYPE_ARITHMETIC_OPERATION            g_arithmetic_operation_get_type()
+#define G_ARITHMETIC_OPERATION(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARITHMETIC_OPERATION, GArithmOperation))
+#define G_IS_ARITHMETIC_OPERATION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARITHMETIC_OPERATION))
+#define G_ARITHMETIC_OPERATION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARITHMETIC_OPERATION, GArithmOperationClass))
+#define G_IS_ARITHMETIC_OPERATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARITHMETIC_OPERATION))
+#define G_ARITHMETIC_OPERATION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARITHMETIC_OPERATION, GArithmOperationClass))
+
+
+/* Opération arithmétique impliquant deux opérandes (instance) */
+typedef struct _GArithmOperation GArithmOperation;
+
+/* Opération arithmétique impliquant deux opérandes (classe) */
+typedef struct _GArithmOperationClass GArithmOperationClass;
+
+
+/* Type d'opération arithmétique */
+typedef enum _ArithmeticExpressionOperator
+{
+    AEO_PLUS,                               /* Opération binaire "+"       */
+    AEO_MINUS,                              /* Opération binaire "-"       */
+    AEO_MUL,                                /* Opération binaire "*"       */
+    AEO_DIV,                                /* Opération binaire "\"       */
+    AEO_MOD,                                /* Opération binaire "%"       */
+
+} ArithmeticExpressionOperator;
+
+
+/* Indique le type défini pour une opération arithmétique entre expressions. */
+GType g_arithmetic_operation_get_type(void);
+
+/* Organise une opération arithmétique entre expressions. */
+GScanExpression *g_arithmetic_operation_new(ArithmeticExpressionOperator, GScanExpression *, GScanExpression *);
+
+
+
+#endif  /* _ANALYSIS_SCAN_EXPRS_ARITHMOP_H */
diff --git a/src/analysis/scan/exprs/boolop-int.h b/src/analysis/scan/exprs/boolop-int.h
new file mode 100644
index 0000000..c381cfe
--- /dev/null
+++ b/src/analysis/scan/exprs/boolop-int.h
@@ -0,0 +1,60 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * boolop-int.h - prototypes internes pour la gestion des opérations booléennes
+ *
+ * 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 _ANALYSIS_SCAN_EXPRS_BOOLOP_INT_H
+#define _ANALYSIS_SCAN_EXPRS_BOOLOP_INT_H
+
+
+#include "boolop.h"
+
+
+#include "../expr-int.h"
+
+
+
+/* Opération booléenne avec un ou deux opérandes (instance) */
+struct _GBoolOperation
+{
+    GScanExpression parent;                 /* A laisser en premier        */
+
+    BooleanOperationType type;              /* Type d'opération menée      */
+
+    GScanExpression *first;                 /* Expression impactée #1      */
+    GScanExpression *second;                /* Expression impactée #2      */
+
+};
+
+/* Opération booléenne avec un ou deux opérandes (classe) */
+struct _GBoolOperationClass
+{
+    GScanExpressionClass parent;            /* A laisser en premier        */
+
+};
+
+
+/* Met en place une expression d'opération booléenne. */
+bool g_boolean_operation_create(GBoolOperation *, BooleanOperationType, GScanExpression *, GScanExpression *);
+
+
+
+#endif  /* _ANALYSIS_SCAN_EXPRS_BOOLOP_INT_H */
diff --git a/src/analysis/scan/exprs/boolop.c b/src/analysis/scan/exprs/boolop.c
new file mode 100644
index 0000000..2902fdd
--- /dev/null
+++ b/src/analysis/scan/exprs/boolop.c
@@ -0,0 +1,450 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * boolop.c - gestion des opérations booléennes
+ *
+ * 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 "boolop.h"
+
+
+#include <assert.h>
+
+
+#include "boolop-int.h"
+#include "literal.h"
+
+
+
+/* --------------------- INTRODUCTION D'UNE NOUVELLE EXPRESSION --------------------- */
+
+
+/* Initialise la classe des opérations booléennes. */
+static void g_boolean_operation_class_init(GBoolOperationClass *);
+
+/* Initialise une instance d'opération booléenne. */
+static void g_boolean_operation_init(GBoolOperation *);
+
+/* Supprime toutes les références externes. */
+static void g_boolean_operation_dispose(GBoolOperation *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_boolean_operation_finalize(GBoolOperation *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Réalise une comparaison entre objets selon un critère précis. */
+static bool g_boolean_operation_compare_rich(const GBoolOperation *, const GBoolOperation *, RichCmpOperation, bool *);
+
+/* Reproduit une expression en place dans une nouvelle instance. */
+static GScanExpression *g_boolean_operation_duplicate(const GBoolOperation *);
+
+/* Réduit une expression à une forme plus simple. */
+GScanExpression *g_boolean_operation_reduce(GBoolOperation *, GScanContext *, bool);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       INTRODUCTION D'UNE NOUVELLE EXPRESSION                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une opération booléenne sur expression(s). */
+G_DEFINE_TYPE(GBoolOperation, g_boolean_operation, G_TYPE_SCAN_EXPRESSION);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des opérations booléennes.              *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_boolean_operation_class_init(GBoolOperationClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GScanExpressionClass *expr;             /* Version de classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_boolean_operation_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_boolean_operation_finalize;
+
+    expr = G_SCAN_EXPRESSION_CLASS(klass);
+
+    expr->cmp_rich = (compare_expr_rich_fc)g_boolean_operation_compare_rich;
+    expr->dup = (dup_expr_fc)g_boolean_operation_duplicate;
+    expr->reduce = (reduce_expr_fc)g_boolean_operation_reduce;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op = instance à initialiser.                                 *
+*                                                                             *
+*  Description : Initialise une instance d'opération booléenne.               *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_boolean_operation_init(GBoolOperation *op)
+{
+    op->first = NULL;
+    op->second = NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op = instance d'objet GLib à traiter.                        *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_boolean_operation_dispose(GBoolOperation *op)
+{
+    g_clear_object(&op->first);
+    g_clear_object(&op->second);
+
+    G_OBJECT_CLASS(g_boolean_operation_parent_class)->dispose(G_OBJECT(op));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op = instance d'objet GLib à traiter.                        *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_boolean_operation_finalize(GBoolOperation *op)
+{
+    G_OBJECT_CLASS(g_boolean_operation_parent_class)->finalize(G_OBJECT(op));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type   = type d'opération booléenne à représenter.           *
+*                first  = premier opérande concerné.                          *
+*                second = éventuel second opérande impliqué ou NULL.          *
+*                                                                             *
+*  Description : Organise un appel de fonction avec ses arguments.            *
+*                                                                             *
+*  Retour      : Fonction mise en place.                                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanExpression *g_boolean_operation_new(BooleanOperationType type, GScanExpression *first, GScanExpression *second)
+{
+    GScanExpression *result;                /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_BOOLEAN_OPERATION, NULL);
+
+    if (!g_boolean_operation_create(G_BOOLEAN_OPERATION(result), type, first, second))
+        g_clear_object(&result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr   = instance à initialiser pleinement.                  *
+*                type   = type d'opération booléenne à représenter.           *
+*                first  = premier opérande concerné.                          *
+*                second = éventuel second opérande impliqué ou NULL.          *
+*                                                                             *
+*  Description : Met en place une expression d'opération booléenne.           *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_boolean_operation_create(GBoolOperation *op, BooleanOperationType type, GScanExpression *first, GScanExpression *second)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = false;
+
+    if (g_scan_expression_get_value_type(first) != EVT_BOOLEAN)
+        goto exit;
+
+    if (g_scan_expression_get_value_type(second) != EVT_BOOLEAN)
+        goto exit;
+
+    if (!g_scan_expression_create(G_SCAN_EXPRESSION(op), EVT_BOOLEAN))
+        goto exit;
+
+    op->type = type;
+
+    switch (type)
+    {
+        case BOT_AND:
+        case BOT_OR:
+            op->first = first;
+            g_object_ref(G_OBJECT(op->first));
+
+            op->second = second;
+            g_object_ref(G_OBJECT(op->second));
+
+            result = true;
+            break;
+
+        case BOT_NOT:
+            op->first = first;
+            g_object_ref(G_OBJECT(op->first));
+
+            result = (second == NULL);
+            assert(second != NULL);
+            break;
+
+    }
+
+ exit:
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item   = premier objet à consulter pour une comparaison.     *
+*                other  = second objet à consulter pour une comparaison.      *
+*                op     = opération de comparaison à réaliser.                *
+*                status = bilan des opérations de comparaison. [OUT]          *
+*                                                                             *
+*  Description : Réalise une comparaison entre objets selon un critère précis.*
+*                                                                             *
+*  Retour      : true si la comparaison a pu être effectuée, false sinon.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_boolean_operation_compare_rich(const GBoolOperation *item, const GBoolOperation *other, RichCmpOperation op, bool *status)
+{
+    bool result;                            /* Etat à retourner            */
+    bool equal;                             /* Bilan intermédiaire         */
+
+    result = true;
+
+    if (item->type != other->type)
+    {
+        *status = compare_rich_integer_values(item->type, other->type, op);
+        goto done;
+    }
+
+    equal = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item), G_COMPARABLE_ITEM(other), RCO_EQ, status);
+
+    if (!equal)
+    {
+        *status = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->first),
+                                                 G_COMPARABLE_ITEM(other->first),
+                                                 op, status);
+        goto done;
+    }
+
+    if (item->second == NULL)
+    {
+        assert(other->second == NULL);
+
+        switch (op)
+        {
+            case RCO_LT:
+            case RCO_NE:
+            case RCO_GT:
+                *status = false;
+                break;
+
+            case RCO_LE:
+            case RCO_EQ:
+            case RCO_GE:
+                *status = true;
+                break;
+
+        }
+
+    }
+
+    else
+        *status = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->second),
+                                                 G_COMPARABLE_ITEM(other->second),
+                                                 op, status);
+
+ done:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = expression à copier.                                  *
+*                                                                             *
+*  Description : Reproduit une expression en place dans une nouvelle instance.*
+*                                                                             *
+*  Retour      : Nouvelle instance d'expression.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GScanExpression *g_boolean_operation_duplicate(const GBoolOperation *expr)
+{
+    GScanExpression *result;                /* Instance copiée à retourner */
+
+    result = g_boolean_operation_new(expr->type, expr->first, expr->second);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr  = expression à consulter.                              *
+*                ctx   = contexte de suivi de l'analyse courante.             *
+*                final = impose une conversion finale de dernier tour.        *
+*                                                                             *
+*  Description : Réduit une expression à une forme plus simple.               *
+*                                                                             *
+*  Retour      : Réduction correspondante, expression déjà réduite, ou NULL.  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanExpression *g_boolean_operation_reduce(GBoolOperation *expr, GScanContext *ctx, bool final)
+{
+    GScanExpression *result;                /* Instance à renvoyer         */
+    GScanExpression *new;                   /* Nouvelle expression obtenue */
+    bool values[2];                         /* Valeurs des éléments portés */
+    bool valid[2];                          /* Validité de ces valeurs     */
+
+    result = NULL;
+
+    /* Réduction des éléments considérés */
+
+    new = g_scan_expression_reduce(expr->first, ctx, final);
+
+    if (new != NULL)
+    {
+        g_object_unref(G_OBJECT(expr->first));
+        expr->first = new;
+    }
+
+    if (expr->second != NULL)
+    {
+        new = g_scan_expression_reduce(expr->second, ctx, final);
+
+        if (new != NULL)
+        {
+            g_object_unref(G_OBJECT(expr->second));
+            expr->second = new;
+        }
+
+    }
+
+    /* Construction d'une réduction locale ? */
+
+    switch (expr->type)
+    {
+        case BOT_AND:
+            if (G_IS_LITERAL_EXPRESSION(expr->first) && G_IS_LITERAL_EXPRESSION(expr->second))
+            {
+                valid[0] = g_literal_expression_get_boolean_value(G_LITERAL_EXPRESSION(expr->first), &values[0]);
+                valid[1] = g_literal_expression_get_boolean_value(G_LITERAL_EXPRESSION(expr->second), &values[1]);
+
+                if (valid[0] && valid[1])
+                    result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { values[0] && values[1] });
+
+                else
+                    /* Etre malin si 0 && x => bilan (si ctx->quick) */
+                    ;
+
+            }
+            break;
+
+        case BOT_OR:
+            if (G_IS_LITERAL_EXPRESSION(expr->first) && G_IS_LITERAL_EXPRESSION(expr->second))
+            {
+                valid[0] = g_literal_expression_get_boolean_value(G_LITERAL_EXPRESSION(expr->first), &values[0]);
+                valid[1] = g_literal_expression_get_boolean_value(G_LITERAL_EXPRESSION(expr->second), &values[1]);
+
+                if (valid[0] && valid[1])
+                    result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { values[0] || values[1] });
+
+            }
+            break;
+
+        case BOT_NOT:
+            if (G_IS_LITERAL_EXPRESSION(expr->first))
+            {
+                valid[0] = g_literal_expression_get_boolean_value(G_LITERAL_EXPRESSION(expr->first), &values[0]);
+
+                if (valid[0])
+                    result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { !values[1] });
+
+            }
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/src/analysis/scan/exprs/boolop.h b/src/analysis/scan/exprs/boolop.h
new file mode 100644
index 0000000..4add5a1
--- /dev/null
+++ b/src/analysis/scan/exprs/boolop.h
@@ -0,0 +1,65 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * boolop.h - prototypes pour la gestion des opérations booléennes
+ *
+ * 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 _ANALYSIS_SCAN_EXPRS_BOOLOP_H
+#define _ANALYSIS_SCAN_EXPRS_BOOLOP_H
+
+
+#include "../expr.h"
+
+
+
+#define G_TYPE_BOOLEAN_OPERATION            g_boolean_operation_get_type()
+#define G_BOOLEAN_OPERATION(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_BOOLEAN_OPERATION, GBoolOperation))
+#define G_IS_BOOLEAN_OPERATION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_BOOLEAN_OPERATION))
+#define G_BOOLEAN_OPERATION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BOOLEAN_OPERATION, GBoolOperationClass))
+#define G_IS_BOOLEAN_OPERATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BOOLEAN_OPERATION))
+#define G_BOOLEAN_OPERATION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BOOLEAN_OPERATION, GBoolOperationClass))
+
+
+/* Opération booléenne avec un ou deux opérandes (instance) */
+typedef struct _GBoolOperation GBoolOperation;
+
+/* Opération booléenne avec un ou deux opérandes (classe) */
+typedef struct _GBoolOperationClass GBoolOperationClass;
+
+
+/* Types d'opérations booléennes supportées */
+typedef enum _BooleanOperationType
+{
+    BOT_AND,                                /* Opérateur binaire "and"     */
+    BOT_OR,                                 /* Opérateur binaire "or"      */
+    BOT_NOT,                                /* Opérateur unaire "not"      */
+
+} BooleanOperationType;
+
+
+/* Indique le type défini pour une opération booléenne sur expression(s). */
+GType g_boolean_operation_get_type(void);
+
+/* Organise un appel de fonction avec ses arguments. */
+GScanExpression *g_boolean_operation_new(BooleanOperationType, GScanExpression *, GScanExpression *);
+
+
+
+#endif  /* _ANALYSIS_SCAN_EXPRS_BOOLOP_H */
diff --git a/src/analysis/scan/exprs/call-int.h b/src/analysis/scan/exprs/call-int.h
new file mode 100644
index 0000000..d68977f
--- /dev/null
+++ b/src/analysis/scan/exprs/call-int.h
@@ -0,0 +1,63 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * call-int.h - prototypes internes pour l'organisation d'un appel à un élément de scan enregistré
+ *
+ * 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 _ANALYSIS_SCAN_EXPRS_CALL_INT_H
+#define _ANALYSIS_SCAN_EXPRS_CALL_INT_H
+
+
+#include "call.h"
+
+
+#include "../expr-int.h"
+
+
+
+/* Exécution d'une fonction auxiliaire d'analyse (instance) */
+struct _GPendingCall
+{
+    GScanExpression parent;                 /* A laisser en premier        */
+
+    GRegisteredItem *base;                  /* Base de recherche           */
+    char *target;                           /* Cible dans l'espace         */
+
+    GScanExpression **args;                 /* Arguments d'appel fournis   */
+    size_t count;                           /* Quantité de ces arguments   */
+
+    struct _GPendingCall *next;             /* Evnetuel prochain élément   */
+
+};
+
+/* Exécution d'une fonction auxiliaire d'analyse (classe) */
+struct _GPendingCallClass
+{
+    GScanExpressionClass parent;            /* A laisser en premier        */
+
+};
+
+
+/* Met en place une expression d'appel. */
+bool g_pending_call_create(GPendingCall *, const char *, size_t, GScanExpression **, size_t);
+
+
+
+#endif  /* _ANALYSIS_SCAN_EXPRS_CALL_INT_H */
diff --git a/src/analysis/scan/exprs/call.c b/src/analysis/scan/exprs/call.c
new file mode 100644
index 0000000..76f5fc3
--- /dev/null
+++ b/src/analysis/scan/exprs/call.c
@@ -0,0 +1,426 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * call.c - organisation d'un appel à un élément de scan enregistré
+ *
+ * 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 "call.h"
+
+
+#include <malloc.h>
+#include <string.h>
+
+
+#include "call-int.h"
+#include "../../../core/global.h"
+
+
+
+/* --------------------- INTRODUCTION D'UNE NOUVELLE EXPRESSION --------------------- */
+
+
+/* Initialise la classe des appels de fonction avec arguments. */
+static void g_pending_call_class_init(GPendingCallClass *);
+
+/* Initialise une instance d'appel de fonction avec arguments. */
+static void g_pending_call_init(GPendingCall *);
+
+/* Supprime toutes les références externes. */
+static void g_pending_call_dispose(GPendingCall *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_pending_call_finalize(GPendingCall *);
+
+/* Définit une base de recherche pour la cible d'appel. */
+static void g_pending_call_set_base(GPendingCall *, GRegisteredItem *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Reproduit une expression en place dans une nouvelle instance. */
+static GScanExpression *g_pending_call_duplicate(const GPendingCall *);
+
+/* Réduit une expression à une forme plus simple. */
+GScanExpression *g_pending_call_reduce(GPendingCall *, GScanContext *, bool);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       INTRODUCTION D'UNE NOUVELLE EXPRESSION                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un appel de fonction enregistrée. */
+G_DEFINE_TYPE(GPendingCall, g_pending_call, G_TYPE_SCAN_EXPRESSION);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des appels de fonction avec arguments.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_pending_call_class_init(GPendingCallClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GScanExpressionClass *expr;             /* Version de classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_pending_call_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_pending_call_finalize;
+
+    expr = G_SCAN_EXPRESSION_CLASS(klass);
+
+    expr->cmp_rich = (compare_expr_rich_fc)NULL;
+    expr->dup = (dup_expr_fc)g_pending_call_duplicate;
+    expr->reduce = (reduce_expr_fc)g_pending_call_reduce;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : call = instance à initialiser.                               *
+*                                                                             *
+*  Description : Initialise une instance d'appel de fonction avec arguments.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_pending_call_init(GPendingCall *call)
+{
+    call->base = NULL;
+    call->target = NULL;
+
+    call->args = NULL;
+    call->count = 0;
+
+    call->next = NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : call = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_pending_call_dispose(GPendingCall *call)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    g_clear_object(&call->base);
+
+    for (i = 0; i < call->count; i++)
+        g_clear_object(&call->args[i]);
+
+    g_clear_object(&call->next);
+
+    G_OBJECT_CLASS(g_pending_call_parent_class)->dispose(G_OBJECT(call));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : call = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_pending_call_finalize(GPendingCall *call)
+{
+    if (call->target != NULL)
+        free(call->target);
+
+    if (call->args != NULL)
+        free(call->args);
+
+    G_OBJECT_CLASS(g_pending_call_parent_class)->finalize(G_OBJECT(call));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : target = désignation de l'objet d'appel à identifier.        *
+*                len    = taille de cette désignation.                        *
+*                args   = éventuelle liste d'arguments à actionner.           *
+*                count  = quantité de ces arguments.                          *
+*                                                                             *
+*  Description : Organise un appel de fonction avec ses arguments.            *
+*                                                                             *
+*  Retour      : Fonction mise en place.                                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanExpression *g_pending_call_new(const char *target, size_t len, GScanExpression **args, size_t count)
+{
+    GScanExpression *result;                /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_PENDING_CALL, NULL);
+
+    if (!g_pending_call_create(G_PENDING_CALL(result), target, len, args, count))
+        g_clear_object(&result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : call   = instance à initialiser pleinement.                  *
+*                target = désignation de l'objet d'appel à identifier.        *
+*                len    = taille de cette désignation.                        *
+*                args   = éventuelle liste d'arguments à actionner.           *
+*                count  = quantité de ces arguments.                          *
+*                                                                             *
+*  Description : Met en place une expression d'appel.                         *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_pending_call_create(GPendingCall *call, const char *target, size_t len, GScanExpression **args, size_t count)
+{
+    bool result;                            /* Bilan à retourner           */
+    size_t i;                               /* Boucle de parcours          */
+
+    result = g_scan_expression_create(G_SCAN_EXPRESSION(call), EVT_PENDING);
+    if (!result) goto exit;
+
+    call->target = strndup(target, len);
+
+    call->args = malloc(count * sizeof(GScanExpression *));
+    call->count = count;
+
+    for (i = 0; i < count; i++)
+    {
+        call->args[i] = args[i];
+        g_object_ref(G_OBJECT(args[i]));
+    }
+
+ exit:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : call = expression d'appel à actualiser.                      *
+*                base   = zone de recherche pour la résolution à venir.       *
+*                                                                             *
+*  Description : Définit une base de recherche pour la cible d'appel.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_pending_call_set_base(GPendingCall *call, GRegisteredItem *base)
+{
+    call->base = base;
+    g_object_ref(G_OBJECT(base));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : call = expression d'appel à compléter.                       *
+*                next = expression d'appel suivante dans la chaîne.           *
+*                                                                             *
+*  Description : Complète la chaine d'expressions d'appel.                    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_pending_call_attach_next(GPendingCall *call, GPendingCall *next)
+{
+    call->next = next;
+    g_object_ref(G_OBJECT(next));
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = expression à copier.                                  *
+*                                                                             *
+*  Description : Reproduit une expression en place dans une nouvelle instance.*
+*                                                                             *
+*  Retour      : Nouvelle instance d'expression.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GScanExpression *g_pending_call_duplicate(const GPendingCall *expr)
+{
+    GScanExpression *result;                /* Instance copiée à retourner */
+
+    result = g_pending_call_new(expr->target, strlen(expr->target), expr->args, expr->count);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr  = expression à consulter.                              *
+*                ctx   = contexte de suivi de l'analyse courante.             *
+*                final = indique une ultime conversion dans le cycle en cours.*
+*                                                                             *
+*  Description : Réduit une expression à une forme plus simple.               *
+*                                                                             *
+*  Retour      : Réduction correspondante, expression déjà réduite, ou NULL.  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanExpression *g_pending_call_reduce(GPendingCall *expr, GScanContext *ctx, bool final)
+{
+    GScanExpression *result;                /* Instance à renvoyer         */
+    size_t i;                               /* Boucle de parcours          */
+    GScanExpression *new;                   /* Nouvelle expression obtenue */
+    bool last;                              /* Détection de fin de chaîne  */
+    GRegisteredItem *base;                  /* Base de recherche courante  */
+    GRegisteredItem *rebase;                /* Nouvelle base résolue       */
+    GScanExpression *new_next;              /* Nouvelle version du suivant */
+
+    for (i = 0; i < expr->count; i++)
+    {
+        new = g_scan_expression_reduce(expr->args[i], ctx, final);
+
+        if (new != NULL)
+        {
+            g_object_unref(G_OBJECT(expr->args[i]));
+            expr->args[i] = new;
+        }
+
+    }
+
+    last = (expr->next == NULL);
+
+    if (!last)
+        new_next = g_scan_expression_duplicate(G_SCAN_EXPRESSION(expr->next));
+    else
+        new_next = NULL;
+
+    if (expr->target != NULL)
+    {
+        if (expr->base != NULL)
+        {
+            base = expr->base;
+            g_object_ref(G_OBJECT(base));
+        }
+        else
+            base = G_REGISTERED_ITEM(get_rost_root_namespace());
+
+        rebase = g_registered_item_resolve(base, expr->target, ctx,
+                                           last ? NULL : expr->args, last ? 0 : expr->count,
+                                           last, final);
+
+        g_object_unref(G_OBJECT(base));
+
+        if (rebase == NULL)
+        {
+            result = NULL;
+            goto done;
+        }
+
+        if (last)
+        {
+            g_pending_call_set_base(expr, rebase);
+
+            free(expr->target);
+            expr->target = NULL;
+
+        }
+        else
+            g_pending_call_set_base(G_PENDING_CALL(new_next), rebase);
+
+    }
+
+    if (last)
+        result = g_registered_item_reduce(expr->base, ctx, expr->args, expr->count, final);
+
+    else
+    {
+        result = g_scan_expression_reduce(new_next, ctx, final);
+
+        if (result == NULL)
+        {
+            g_object_ref(G_OBJECT(new_next));
+            result = new_next;
+        }
+
+    }
+
+ done:
+
+    g_clear_object(&new_next);
+
+    return result;
+
+}
diff --git a/src/analysis/scan/exprs/call.h b/src/analysis/scan/exprs/call.h
new file mode 100644
index 0000000..b69ca85
--- /dev/null
+++ b/src/analysis/scan/exprs/call.h
@@ -0,0 +1,59 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * call.h - prototypes pour l'organisation d'un appel à un élément de scan enregistré
+ *
+ * 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 _ANALYSIS_SCAN_EXPRS_CALL_H
+#define _ANALYSIS_SCAN_EXPRS_CALL_H
+
+
+#include "../expr.h"
+#include "../item.h"
+
+
+
+#define G_TYPE_PENDING_CALL            g_pending_call_get_type()
+#define G_PENDING_CALL(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_PENDING_CALL, GPendingCall))
+#define G_IS_PENDING_CALL(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_PENDING_CALL))
+#define G_PENDING_CALL_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_PENDING_CALL, GPendingCallClass))
+#define G_IS_PENDING_CALL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_PENDING_CALL))
+#define G_PENDING_CALL_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_PENDING_CALL, GPendingCallClass))
+
+
+/* Exécution d'une fonction auxiliaire d'analyse (instance) */
+typedef struct _GPendingCall GPendingCall;
+
+/* Exécution d'une fonction auxiliaire d'analyse (classe) */
+typedef struct _GPendingCallClass GPendingCallClass;
+
+
+/* Indique le type défini pour un appel de fonction enregistrée. */
+GType g_pending_call_get_type(void);
+
+/* Organise un appel de fonction avec ses arguments. */
+GScanExpression *g_pending_call_new(const char *, size_t, GScanExpression **, size_t);
+
+/* Complète la chaine d'expressions d'appel. */
+void g_pending_call_attach_next(GPendingCall *, GPendingCall *);
+
+
+
+#endif  /* _ANALYSIS_SCAN_EXPRS_CALL_H */
diff --git a/src/analysis/scan/exprs/literal-int.h b/src/analysis/scan/exprs/literal-int.h
new file mode 100644
index 0000000..d803d30
--- /dev/null
+++ b/src/analysis/scan/exprs/literal-int.h
@@ -0,0 +1,73 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * literal-int.h - prototypes internes pour la représentation d'une valeur concrète
+ *
+ * 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 _ANALYSIS_SCAN_EXPRS_LITERAL_INT_H
+#define _ANALYSIS_SCAN_EXPRS_LITERAL_INT_H
+
+
+#include "literal.h"
+
+
+#include <stdbool.h>
+
+
+#include "../expr-int.h"
+
+
+
+/* Expression portant une valeur concrète (instance) */
+struct _GLiteralExpression
+{
+    GScanExpression parent;                 /* A laisser en premier        */
+
+    ExprValueType value_type;               /* Type de valeur portée       */
+
+    union
+    {
+        bool boolean;                       /* Valeur booléenne            */
+        unsigned long long integer;         /* Valeur entière 64 bits      */
+        char *string;                       /* Chaîne de caractères        */
+        struct
+        {
+            char *regex;                    /* Formulation d'origine       */
+            regex_t preg;                   /* Expression rationnelle      */
+        };
+
+    } value;
+
+};
+
+/* Expression portant une valeur concrète (classe) */
+struct _GLiteralExpressionClass
+{
+    GScanExpressionClass parent;            /* A laisser en premier        */
+
+};
+
+
+/* Met en place une expression de valeur concrête. */
+bool g_literal_expression_create(GLiteralExpression *, ExprValueType, ...);
+
+
+
+#endif  /* _ANALYSIS_SCAN_EXPRS_LITERAL_INT_H */
diff --git a/src/analysis/scan/exprs/literal.c b/src/analysis/scan/exprs/literal.c
new file mode 100644
index 0000000..f40747d
--- /dev/null
+++ b/src/analysis/scan/exprs/literal.c
@@ -0,0 +1,605 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * literal.c - représentation d'une valeur concrète
+ *
+ * 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 "literal.h"
+
+
+#include <assert.h>
+#include <stdarg.h>
+#include <string.h>
+
+
+#include "literal-int.h"
+
+
+
+/* --------------------- INTRODUCTION D'UNE NOUVELLE EXPRESSION --------------------- */
+
+
+/* Initialise la classe des expressions de valeur concrète. */
+static void g_literal_expression_class_init(GLiteralExpressionClass *);
+
+/* Initialise une instance d'expression de valeur concrète. */
+static void g_literal_expression_init(GLiteralExpression *);
+
+/* Supprime toutes les références externes. */
+static void g_literal_expression_dispose(GLiteralExpression *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_literal_expression_finalize(GLiteralExpression *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Réalise une comparaison entre objets selon un critère précis. */
+static bool g_literal_expression_compare_rich(const GLiteralExpression *, const GLiteralExpression *, RichCmpOperation, bool *);
+
+/* Reproduit une expression en place dans une nouvelle instance. */
+static GScanExpression *g_literal_expression_duplicate(const GLiteralExpression *);
+
+/* Réduit une expression à une forme plus simple. */
+GScanExpression *g_literal_expression_reduce(GLiteralExpression *, GScanContext *, bool);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       INTRODUCTION D'UNE NOUVELLE EXPRESSION                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un appel de fonction enregistrée. */
+G_DEFINE_TYPE(GLiteralExpression, g_literal_expression, G_TYPE_SCAN_EXPRESSION);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des expressions de valeur concrète.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_literal_expression_class_init(GLiteralExpressionClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GScanExpressionClass *expr;             /* Version de classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_literal_expression_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_literal_expression_finalize;
+
+    expr = G_SCAN_EXPRESSION_CLASS(klass);
+
+    expr->cmp_rich = (compare_expr_rich_fc)g_literal_expression_compare_rich;
+    expr->dup = (dup_expr_fc)g_literal_expression_duplicate;
+    expr->reduce = (reduce_expr_fc)g_literal_expression_reduce;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = instance à initialiser.                               *
+*                                                                             *
+*  Description : Initialise une instance d'expression de valeur concrète.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_literal_expression_init(GLiteralExpression *expr)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_literal_expression_dispose(GLiteralExpression *expr)
+{
+    G_OBJECT_CLASS(g_literal_expression_parent_class)->dispose(G_OBJECT(expr));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_literal_expression_finalize(GLiteralExpression *expr)
+{
+    G_OBJECT_CLASS(g_literal_expression_parent_class)->finalize(G_OBJECT(expr));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : vtype = type de valeur associée par l'expression.            *
+*                ...   = valeur concrête à intégrer.                          *
+*                                                                             *
+*  Description : Organise un appel de fonction avec ses arguments.            *
+*                                                                             *
+*  Retour      : Fonction mise en place.                                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanExpression *g_literal_expression_new(ExprValueType vtype, ...)
+{
+    GScanExpression *result;                /* Structure à retourner       */
+    va_list ap;                             /* Liste d'arguements          */
+    void *ptr;                              /* Vision générique de valeur  */
+
+    result = g_object_new(G_TYPE_LITERAL_EXPRESSION, NULL);
+
+    va_start(ap, vtype);
+
+    ptr = va_arg(ap, void *);
+
+    if (!g_literal_expression_create(G_LITERAL_EXPRESSION(result), vtype, ptr))
+        g_clear_object(&result);
+
+    va_end(ap);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr  = instance à initialiser pleinement.                   *
+*                vtype = type de valeur associée par l'expression.            *
+*                ...   = valeur concrête à intégrer.                          *
+*                                                                             *
+*  Description : Met en place une expression de valeur concrête.              *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_literal_expression_create(GLiteralExpression *expr, ExprValueType vtype, ...)
+{
+    bool result;                            /* Bilan à retourner           */
+    va_list ap;                             /* Liste d'arguements          */
+    const bool *boolean;                    /* Valeur booléenne            */
+    const unsigned long long *integer;      /* Valeur entière 64 bits      */
+    const char *string;                     /* Chaîne de caractères        */
+    size_t len;                             /* Taille de la chaîne         */
+    int cflags;                             /* Détails de compilation      */
+    unsigned int i;                         /* Boucle de parcours          */
+    char *tmp;                              /* Zone de travail temporaire  */
+    int ret;                                /* Bilan d'une opération       */
+
+    result = g_scan_expression_create(G_SCAN_EXPRESSION(expr), vtype);
+
+    if (result)
+    {
+        va_start(ap, vtype);
+
+        switch (vtype)
+        {
+            case EVT_BOOLEAN:
+                boolean = va_arg(ap, const bool *);
+                expr->value.boolean = *boolean;
+                break;
+
+            case EVT_INTEGER:
+                integer = va_arg(ap, const unsigned long long *);
+                expr->value.integer = *integer;
+                break;
+
+            case EVT_STRING:
+                string = va_arg(ap, const char *);
+                expr->value.string = strdup(string);
+                break;
+
+            case EVT_REG_EXPR:
+                string = va_arg(ap, const char *);
+                len = strlen(string);
+
+                result = (len > 2 && string[0] == '/');
+
+                cflags = REG_EXTENDED | REG_NOSUB;
+
+                for (i = 0; i < 2 && result; i++)
+                {
+                    result = (len > 2);
+
+                    if (string[len - 1] == 'i')
+                    {
+                        cflags |= REG_ICASE;
+                        len -= 1;
+                    }
+
+                    else if (string[len - 1] == 's')
+                    {
+                        cflags |= REG_NEWLINE;
+                        len -= 1;
+                    }
+
+                    else if (string[len - 1] == '/')
+                        break;
+
+                }
+
+                if (result)
+                    result = (string[len - 1] == '/');
+
+                if (result)
+                {
+                    assert(len > 2);
+
+                    tmp = strndup(&string[1], len - 2);
+                    ret = regcomp(&expr->value.preg, tmp, cflags);
+                    free(tmp);
+
+                    result = (ret == 0);
+
+                    if (result)
+                        expr->value.regex = strdup(string);
+
+                }
+
+                break;
+
+            default:
+                result = false;
+                break;
+
+        }
+
+        va_end(ap);
+
+    }
+
+    expr->value_type = vtype;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item  = premier objet à consulter pour une comparaison.      *
+*                value = valeur portée portée par l'expression. [OUT]         *
+*                                                                             *
+*  Description : Indique la valeur portée par une expression booléenne.       *
+*                                                                             *
+*  Retour      : true si l'expression est de type booléen, false sinon.       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_literal_expression_get_boolean_value(const GLiteralExpression *item, bool *value)
+{
+    bool result;                            /* Etat à retourner            */
+
+    result = (item->value_type == EVT_BOOLEAN);
+
+    if (result)
+        *value = item->value.boolean;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item  = premier objet à consulter pour une comparaison.      *
+*                value = valeur portée portée par l'expression. [OUT]         *
+*                                                                             *
+*  Description : Indique la valeur portée par une expression d'entier.        *
+*                                                                             *
+*  Retour      : true si l'expression est de type entier, false sinon.        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_literal_expression_get_integer_value(const GLiteralExpression *item, unsigned long long *value)
+{
+    bool result;                            /* Etat à retourner            */
+
+    result = (item->value_type == EVT_INTEGER);
+
+    if (result)
+        *value = item->value.integer;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item  = premier objet à consulter pour une comparaison.      *
+*                value = valeur portée portée par l'expression. [OUT]         *
+*                                                                             *
+*  Description : Indique la valeur portée par une expression de chaîne.       *
+*                                                                             *
+*  Retour      : true si l'expression est de type entier, false sinon.        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_literal_expression_get_string_value(const GLiteralExpression *item, const char **value)
+{
+    bool result;                            /* Etat à retourner            */
+
+    result = (item->value_type == EVT_STRING);
+
+    if (result)
+        *value = item->value.string;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item  = premier objet à consulter pour une comparaison.      *
+*                value = valeur portée portée par l'expression. [OUT]         *
+*                                                                             *
+*  Description : Indique la valeur portée par une expression rationnelle.     *
+*                                                                             *
+*  Retour      : true si l'expression est de type entier, false sinon.        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_literal_expression_get_regex_value(const GLiteralExpression *item, const regex_t **value)
+{
+    bool result;                            /* Etat à retourner            */
+
+    result = (item->value_type == EVT_REG_EXPR);
+
+    if (result)
+        *value = &item->value.preg;
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item   = premier objet à consulter pour une comparaison.     *
+*                other  = second objet à consulter pour une comparaison.      *
+*                op     = opération de comparaison à réaliser.                *
+*                status = bilan des opérations de comparaison. [OUT]          *
+*                                                                             *
+*  Description : Réalise une comparaison entre objets selon un critère précis.*
+*                                                                             *
+*  Retour      : true si la comparaison a pu être effectuée, false sinon.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_literal_expression_compare_rich(const GLiteralExpression *item, const GLiteralExpression *other, RichCmpOperation op, bool *status)
+{
+    bool result;                            /* Etat à retourner            */
+    int cmp;                                /* Bilan intermédiaire         */
+
+    if (item->value_type != other->value_type)
+    {
+        *status = compare_rich_integer_values(item->value_type, other->value_type, op);
+        result = true;
+        goto done;
+    }
+
+    switch (item->value_type)
+    {
+        case EVT_BOOLEAN:
+            switch (op)
+            {
+                case RCO_EQ:
+                    *status = (item->value.boolean == other->value.boolean);
+                    result = true;
+                    break;
+
+                case RCO_NE:
+                    *status = (item->value.boolean != other->value.boolean);
+                    result = true;
+                    break;
+
+                default:
+                    result = false;
+                    break;
+
+            };
+            break;
+
+        case EVT_INTEGER:
+            *status = compare_rich_integer_values(item->value.integer, other->value.integer, op);
+            result = true;
+            break;
+
+        case EVT_STRING:
+            cmp = strcmp(item->value.string, other->value.string);
+            *status = compare_rich_integer_values(cmp, 0, op);
+            result = true;
+            break;
+
+        case EVT_REG_EXPR:
+            cmp = strcmp(item->value.regex, other->value.regex);
+            *status = compare_rich_integer_values(cmp, 0, op);
+            result = true;
+            break;
+
+        default:
+            result = false;
+            break;
+
+    }
+
+ done:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = expression à copier.                                  *
+*                                                                             *
+*  Description : Reproduit une expression en place dans une nouvelle instance.*
+*                                                                             *
+*  Retour      : Nouvelle instance d'expression.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GScanExpression *g_literal_expression_duplicate(const GLiteralExpression *expr)
+{
+    GScanExpression *result;                /* Instance copiée à retourner */
+    const void *ptr;                        /* Pointeur vers des données   */
+
+    switch (expr->value_type)
+    {
+        case EVT_BOOLEAN:
+            ptr = &expr->value.boolean;
+            break;
+
+        case EVT_INTEGER:
+            ptr = &expr->value.integer;
+            break;
+
+        case EVT_STRING:
+            ptr = &expr->value.string;
+            break;
+
+        case EVT_REG_EXPR:
+            ptr = &expr->value.regex;
+            break;
+
+        default:
+            ptr = NULL;
+            break;
+
+    }
+
+    assert(ptr != NULL);
+
+    result = g_literal_expression_new(expr->value_type, ptr);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr  = expression à consulter.                              *
+*                ctx   = contexte de suivi de l'analyse courante.             *
+*                force = impose une conversion en booléen si possible.        *
+*                                                                             *
+*  Description : Réduit une expression à une forme plus simple.               *
+*                                                                             *
+*  Retour      : Réduction correspondante, expression déjà réduite, ou NULL.  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanExpression *g_literal_expression_reduce(GLiteralExpression *expr, GScanContext *ctx, bool force)
+{
+    GScanExpression *result;                /* Instance à renvoyer         */
+
+    if (!force)
+        result = NULL;
+
+    else
+        switch (expr->value_type)
+        {
+            case EVT_BOOLEAN:
+                result = NULL;
+                break;
+
+            case EVT_INTEGER:
+                result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { expr->value.integer > 0 });
+                break;
+
+            case EVT_STRING:
+                result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { strlen(expr->value.string) > 0 });
+                break;
+
+            case EVT_REG_EXPR:
+                result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { strlen(expr->value.regex) > 0 });
+                break;
+
+            default:
+                result = NULL;
+                break;
+
+        }
+
+    return result;
+
+}
diff --git a/src/analysis/scan/exprs/literal.h b/src/analysis/scan/exprs/literal.h
new file mode 100644
index 0000000..ac5724f
--- /dev/null
+++ b/src/analysis/scan/exprs/literal.h
@@ -0,0 +1,70 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * literal.h - prototypes pour la représentation d'une valeur concrète
+ *
+ * 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 _ANALYSIS_SCAN_EXPRS_LITERAL_H
+#define _ANALYSIS_SCAN_EXPRS_LITERAL_H
+
+
+#include <regex.h>
+
+
+#include "../expr.h"
+
+
+
+#define G_TYPE_LITERAL_EXPRESSION            g_literal_expression_get_type()
+#define G_LITERAL_EXPRESSION(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_LITERAL_EXPRESSION, GLiteralExpression))
+#define G_IS_LITERAL_EXPRESSION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_LITERAL_EXPRESSION))
+#define G_LITERAL_EXPRESSION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_LITERAL_EXPRESSION, GLiteralExpressionClass))
+#define G_IS_LITERAL_EXPRESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_LITERAL_EXPRESSION))
+#define G_LITERAL_EXPRESSION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_LITERAL_EXPRESSION, GLiteralExpressionClass))
+
+
+/* Expression portant une valeur concrète (instance) */
+typedef struct _GLiteralExpression GLiteralExpression;
+
+/* Expression portant une valeur concrète (classe) */
+typedef struct _GLiteralExpressionClass GLiteralExpressionClass;
+
+
+/* Indique le type défini pour un appel de fonction enregistrée. */
+GType g_literal_expression_get_type(void);
+
+/* Organise un appel de fonction avec ses arguments. */
+GScanExpression *g_literal_expression_new(ExprValueType, ...);
+
+/* Indique la valeur portée par une expression booléenne. */
+bool g_literal_expression_get_boolean_value(const GLiteralExpression *, bool *);
+
+/* Indique la valeur portée par une expression d'entier. */
+bool g_literal_expression_get_integer_value(const GLiteralExpression *, unsigned long long *);
+
+/* Indique la valeur portée par une expression de chaîne. */
+bool g_literal_expression_get_string_value(const GLiteralExpression *, const char **);
+
+/* Indique la valeur portée par une expression rationnelle. */
+bool g_literal_expression_get_regex_value(const GLiteralExpression *, const regex_t **);
+
+
+
+#endif  /* _ANALYSIS_SCAN_EXPRS_LITERAL_H */
diff --git a/src/analysis/scan/exprs/relop-int.h b/src/analysis/scan/exprs/relop-int.h
new file mode 100644
index 0000000..273b543
--- /dev/null
+++ b/src/analysis/scan/exprs/relop-int.h
@@ -0,0 +1,60 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * relop-int.h - prototypes internes pour la gestion des opérations relationnelles
+ *
+ * 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 _ANALYSIS_SCAN_EXPRS_RELOP_INT_H
+#define _ANALYSIS_SCAN_EXPRS_RELOP_INT_H
+
+
+#include "relop.h"
+
+
+#include "../expr-int.h"
+
+
+
+/* Opération relationnelle impliquant deux opérandes (instance) */
+struct _GRelOperation
+{
+    GScanExpression parent;                 /* A laisser en premier        */
+
+    RichCmpOperation rel_type;              /* Type de relation étudiée    */
+
+    GScanExpression *first;                 /* Expression impactée #1      */
+    GScanExpression *second;                /* Expression impactée #2      */
+
+};
+
+/* Opération relationnelle impliquant deux opérandes (classe) */
+struct _GRelOperationClass
+{
+    GScanExpressionClass parent;            /* A laisser en premier        */
+
+};
+
+
+/* Met en place une opération relationnelle entre expressions. */
+bool g_relational_operation_create(GRelOperation *, RichCmpOperation, GScanExpression *, GScanExpression *);
+
+
+
+#endif  /* _ANALYSIS_SCAN_EXPRS_RELOP_INT_H */
diff --git a/src/analysis/scan/exprs/relop.c b/src/analysis/scan/exprs/relop.c
new file mode 100644
index 0000000..94ce77d
--- /dev/null
+++ b/src/analysis/scan/exprs/relop.c
@@ -0,0 +1,374 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * relop.c - gestion des opérations relationnelles
+ *
+ * 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 "relop.h"
+
+
+#include "relop-int.h"
+#include "literal.h"
+
+
+
+/* --------------------- INTRODUCTION D'UNE NOUVELLE EXPRESSION --------------------- */
+
+
+/* Initialise la classe des opérations de relations. */
+static void g_relational_operation_class_init(GRelOperationClass *);
+
+/* Initialise une instance d'opération de relation. */
+static void g_relational_operation_init(GRelOperation *);
+
+/* Supprime toutes les références externes. */
+static void g_relational_operation_dispose(GRelOperation *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_relational_operation_finalize(GRelOperation *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Réalise une comparaison entre objets selon un critère précis. */
+static bool g_relational_operation_compare_rich(const GRelOperation *, const GRelOperation *, RichCmpOperation, bool *);
+
+/* Initialise une instance d'opération de relation. */
+static GScanExpression *g_relational_operation_duplicate(const GRelOperation *);
+
+/* Réduit une expression à une forme plus simple. */
+GScanExpression *g_relational_operation_reduce(GRelOperation *, GScanContext *, bool);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       INTRODUCTION D'UNE NOUVELLE EXPRESSION                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une opération de relation entre expressions. */
+G_DEFINE_TYPE(GRelOperation, g_relational_operation, G_TYPE_SCAN_EXPRESSION);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des opérations de relations.            *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_relational_operation_class_init(GRelOperationClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GScanExpressionClass *expr;             /* Version de classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_relational_operation_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_relational_operation_finalize;
+
+    expr = G_SCAN_EXPRESSION_CLASS(klass);
+
+    expr->cmp_rich = (compare_expr_rich_fc)g_relational_operation_compare_rich;
+    expr->dup = (dup_expr_fc)g_relational_operation_duplicate;
+    expr->reduce = (reduce_expr_fc)g_relational_operation_reduce;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op = instance à initialiser.                                 *
+*                                                                             *
+*  Description : Initialise une instance d'opération de relation.             *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_relational_operation_init(GRelOperation *op)
+{
+    op->first = NULL;
+    op->second = NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op = instance d'objet GLib à traiter.                        *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_relational_operation_dispose(GRelOperation *op)
+{
+    g_clear_object(&op->first);
+    g_clear_object(&op->second);
+
+    G_OBJECT_CLASS(g_relational_operation_parent_class)->dispose(G_OBJECT(op));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op = instance d'objet GLib à traiter.                        *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_relational_operation_finalize(GRelOperation *op)
+{
+    G_OBJECT_CLASS(g_relational_operation_parent_class)->finalize(G_OBJECT(op));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type   = type d'opération booléenne à représenter.           *
+*                first  = premier opérande concerné.                          *
+*                second = éventuel second opérande impliqué ou NULL.          *
+*                                                                             *
+*  Description : Organise une opération relationnelle entre expressions.      *
+*                                                                             *
+*  Retour      : Fonction mise en place.                                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanExpression *g_relational_operation_new(RichCmpOperation type, GScanExpression *first, GScanExpression *second)
+{
+    GScanExpression *result;                /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_RELATIONAL_OPERATION, NULL);
+
+    if (!g_relational_operation_create(G_RELATIONAL_OPERATION(result), type, first, second))
+        g_clear_object(&result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op     = instance à initialiser pleinement.                  *
+*                type   = type d'opération booléenne à représenter.           *
+*                first  = premier opérande concerné.                          *
+*                second = éventuel second opérande impliqué ou NULL.          *
+*                                                                             *
+*  Description : Met en place une opération relationnelle entre expressions.  *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_relational_operation_create(GRelOperation *op, RichCmpOperation type, GScanExpression *first, GScanExpression *second)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = false;
+
+    if (g_scan_expression_get_value_type(first) != g_scan_expression_get_value_type(first))
+        goto exit;
+
+    if (!g_scan_expression_create(G_SCAN_EXPRESSION(op), EVT_BOOLEAN))
+        goto exit;
+
+    op->rel_type = type;
+
+    op->first = first;
+    g_object_ref(G_OBJECT(op->first));
+
+    op->second = second;
+    g_object_ref(G_OBJECT(op->second));
+
+    result = true;
+
+ exit:
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item   = premier objet à consulter pour une comparaison.     *
+*                other  = second objet à consulter pour une comparaison.      *
+*                op     = opération de comparaison à réaliser.                *
+*                status = bilan des opérations de comparaison. [OUT]          *
+*                                                                             *
+*  Description : Réalise une comparaison entre objets selon un critère précis.*
+*                                                                             *
+*  Retour      : true si la comparaison a pu être effectuée, false sinon.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_relational_operation_compare_rich(const GRelOperation *item, const GRelOperation *other, RichCmpOperation op, bool *status)
+{
+    bool result;                            /* Etat à retourner            */
+    bool equal;                             /* Bilan intermédiaire         */
+
+    result = true; // TODO : cmp parent()->type
+
+    if (item->rel_type != other->rel_type)
+    {
+        result = compare_rich_integer_values(item->rel_type, other->rel_type, op);
+        goto done;
+    }
+
+    equal = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item), G_COMPARABLE_ITEM(other), RCO_EQ, status);
+
+    if (!equal)
+    {
+        result = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->first),
+                                                G_COMPARABLE_ITEM(other->first),
+                                                op, status);
+        goto done;
+    }
+
+    result = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->second),
+                                            G_COMPARABLE_ITEM(other->second),
+                                            op, status);
+
+ done:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = expression à copier.                                  *
+*                                                                             *
+*  Description : Reproduit une expression en place dans une nouvelle instance.*
+*                                                                             *
+*  Retour      : Nouvelle instance d'expression.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GScanExpression *g_relational_operation_duplicate(const GRelOperation *expr)
+{
+    GScanExpression *result;                /* Instance copiée à retourner */
+
+    result = g_relational_operation_new(expr->rel_type, expr->first, expr->second);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr  = expression à consulter.                              *
+*                ctx   = contexte de suivi de l'analyse courante.             *
+*                final = impose une conversion finale de dernier tour.        *
+*                                                                             *
+*  Description : Réduit une expression à une forme plus simple.               *
+*                                                                             *
+*  Retour      : Réduction correspondante, expression déjà réduite, ou NULL.  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanExpression *g_relational_operation_reduce(GRelOperation *expr, GScanContext *ctx, bool final)
+{
+    GScanExpression *result;                /* Instance à renvoyer         */
+    GScanExpression *new;                   /* Nouvelle expression obtenue */
+    bool status;                            /* Bilan d'une comparaison     */
+    bool valid;                             /* Validité de ce bilan obtenu */
+
+    result = NULL;
+
+    /* Réduction des éléments considérés */
+
+    new = g_scan_expression_reduce(expr->first, ctx, final);
+
+    if (new != NULL)
+    {
+        g_object_unref(G_OBJECT(expr->first));
+        expr->first = new;
+    }
+
+    if (expr->second != NULL)
+    {
+        new = g_scan_expression_reduce(expr->second, ctx, final);
+
+        if (new != NULL)
+        {
+            g_object_unref(G_OBJECT(expr->second));
+            expr->second = new;
+        }
+
+    }
+
+    /* Construction d'une réduction locale ? */
+
+    if (G_IS_LITERAL_EXPRESSION(expr->first) && G_IS_LITERAL_EXPRESSION(expr->second))
+    {
+        valid = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(expr->first),
+                                               G_COMPARABLE_ITEM(expr->second),
+                                               expr->rel_type, &status);
+
+        if (valid)
+            result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { status });
+
+    }
+
+    return result;
+
+}
diff --git a/src/analysis/scan/exprs/relop.h b/src/analysis/scan/exprs/relop.h
new file mode 100644
index 0000000..ecbc8ef
--- /dev/null
+++ b/src/analysis/scan/exprs/relop.h
@@ -0,0 +1,56 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * relop.h - prototypes pour la gestion des opérations relationnelles
+ *
+ * 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 _ANALYSIS_SCAN_EXPRS_RELOP_H
+#define _ANALYSIS_SCAN_EXPRS_RELOP_H
+
+
+#include "../expr.h"
+#include "../../../glibext/comparison.h"
+
+
+
+#define G_TYPE_RELATIONAL_OPERATION            g_relational_operation_get_type()
+#define G_RELATIONAL_OPERATION(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_RELATIONAL_OPERATION, GRelOperation))
+#define G_IS_RELATIONAL_OPERATION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_RELATIONAL_OPERATION))
+#define G_RELATIONAL_OPERATION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_RELATIONAL_OPERATION, GRelOperationClass))
+#define G_IS_RELATIONAL_OPERATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_RELATIONAL_OPERATION))
+#define G_RELATIONAL_OPERATION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_RELATIONAL_OPERATION, GRelOperationClass))
+
+
+/* Opération relationnelle impliquant deux opérandes (instance) */
+typedef struct _GRelOperation GRelOperation;
+
+/* Opération relationnelle impliquant deux opérandes (classe) */
+typedef struct _GRelOperationClass GRelOperationClass;
+
+
+/* Indique le type défini pour une opération de relation entre expressions. */
+GType g_relational_operation_get_type(void);
+
+/* Organise une opération relationnelle entre expressions. */
+GScanExpression *g_relational_operation_new(RichCmpOperation, GScanExpression *, GScanExpression *);
+
+
+
+#endif  /* _ANALYSIS_SCAN_EXPRS_RELOP_H */
diff --git a/src/analysis/scan/exprs/str-int.h b/src/analysis/scan/exprs/str-int.h
new file mode 100644
index 0000000..9bed5cf
--- /dev/null
+++ b/src/analysis/scan/exprs/str-int.h
@@ -0,0 +1,61 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * str-int.h - prototypes internes pour la gestion des opérations booléennes
+ *
+ * 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 _ANALYSIS_SCAN_EXPRS_STR_INT_H
+#define _ANALYSIS_SCAN_EXPRS_STR_INT_H
+
+
+#include "str.h"
+
+
+#include "../expr-int.h"
+
+
+
+/* Opération booléenne avec un ou deux opérandes (instance) */
+struct _GStringOperation
+{
+    GScanExpression parent;                 /* A laisser en premier        */
+
+    StringOperationType type;               /* Type d'opération menée      */
+    bool case_sensitive;                    /* Respect de la casse ?       */
+
+    GScanExpression *first;                 /* Expression impactée #1      */
+    GScanExpression *second;                /* Expression impactée #2      */
+
+};
+
+/* Opération booléenne avec un ou deux opérandes (classe) */
+struct _GStringOperationClass
+{
+    GScanExpressionClass parent;            /* A laisser en premier        */
+
+};
+
+
+/* Met en place une expression d'opération traite une chaîne. */
+bool g_string_operation_create(GStringOperation *, StringOperationType, GScanExpression *, GScanExpression *, bool);
+
+
+
+#endif  /* _ANALYSIS_SCAN_EXPRS_STR_INT_H */
diff --git a/src/analysis/scan/exprs/str.c b/src/analysis/scan/exprs/str.c
new file mode 100644
index 0000000..675b2f6
--- /dev/null
+++ b/src/analysis/scan/exprs/str.c
@@ -0,0 +1,437 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * str.c - gestion des opérations booléennes
+ *
+ * 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 "str.h"
+
+
+#include <assert.h>
+#include <string.h>
+#include <strings.h>
+
+
+#include "str-int.h"
+#include "literal.h"
+
+
+
+/* --------------------- INTRODUCTION D'UNE NOUVELLE EXPRESSION --------------------- */
+
+
+/* Initialise la classe des opérations visant des chaînes. */
+static void g_string_operation_class_init(GStringOperationClass *);
+
+/* Initialise une instance d'opération visant une chaîne. */
+static void g_string_operation_init(GStringOperation *);
+
+/* Supprime toutes les références externes. */
+static void g_string_operation_dispose(GStringOperation *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_string_operation_finalize(GStringOperation *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Reproduit une expression en place dans une nouvelle instance. */
+static GScanExpression *g_string_operation_duplicate(const GStringOperation *);
+
+/* Réduit une expression à une forme plus simple. */
+GScanExpression *g_string_operation_reduce(GStringOperation *, GScanContext *, bool);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       INTRODUCTION D'UNE NOUVELLE EXPRESSION                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une opération traitant une chaîne de caractères. */
+G_DEFINE_TYPE(GStringOperation, g_string_operation, G_TYPE_SCAN_EXPRESSION);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des opérations visant des chaînes.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_string_operation_class_init(GStringOperationClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GScanExpressionClass *expr;             /* Version de classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_string_operation_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_string_operation_finalize;
+
+    expr = G_SCAN_EXPRESSION_CLASS(klass);
+
+    expr->cmp_rich = (compare_expr_rich_fc)NULL;
+    expr->dup = (dup_expr_fc)g_string_operation_duplicate;
+    expr->reduce = (reduce_expr_fc)g_string_operation_reduce;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op = instance à initialiser.                                 *
+*                                                                             *
+*  Description : Initialise une instance d'opération visant une chaîne.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_string_operation_init(GStringOperation *op)
+{
+    op->first = NULL;
+    op->second = NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op = instance d'objet GLib à traiter.                        *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_string_operation_dispose(GStringOperation *op)
+{
+    g_clear_object(&op->first);
+    g_clear_object(&op->second);
+
+    G_OBJECT_CLASS(g_string_operation_parent_class)->dispose(G_OBJECT(op));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op = instance d'objet GLib à traiter.                        *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_string_operation_finalize(GStringOperation *op)
+{
+    G_OBJECT_CLASS(g_string_operation_parent_class)->finalize(G_OBJECT(op));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type      = type d'opération booléenne à représenter.        *
+*                first     = premier opérande concerné.                       *
+*                second    = éventuel second opérande impliqué ou NULL.       *
+*                sensitive =  détermine la prise en compte de la casse.       *
+*                                                                             *
+*  Description : Organise un appel de fonction avec ses arguments.            *
+*                                                                             *
+*  Retour      : Fonction mise en place.                                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanExpression *g_string_operation_new(StringOperationType type, GScanExpression *first, GScanExpression *second, bool sensitive)
+{
+    GScanExpression *result;                /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_STRING_OPERATION, NULL);
+
+    if (!g_string_operation_create(G_STRING_OPERATION(result), type, first, second, sensitive))
+        g_clear_object(&result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op        = instance à initialiser pleinement.               *
+*                type      = type d'opération booléenne à représenter.        *
+*                first     = premier opérande concerné.                       *
+*                second    = éventuel second opérande impliqué ou NULL.       *
+*                sensitive =  détermine la prise en compte de la casse.       *
+*                                                                             *
+*  Description : Met en place une expression d'opération traite une chaîne.   *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_string_operation_create(GStringOperation *op, StringOperationType type, GScanExpression *first, GScanExpression *second, bool sensitive)
+{
+    bool result;                            /* Bilan à retourner           */
+    ExprValueType vtype;                    /* Type de valeur portée       */
+
+    result = false;
+
+    vtype = g_scan_expression_get_value_type(first);
+
+    if (vtype != EVT_STRING && vtype != EVT_PENDING)
+        goto exit;
+
+    vtype = g_scan_expression_get_value_type(second);
+
+    if (vtype != EVT_STRING && vtype != EVT_REG_EXPR && vtype != EVT_PENDING)
+        goto exit;
+
+    op->type = type;
+
+    switch (type)
+    {
+        case SOT_CONTAINS:
+        case SOT_STARTSWITH:
+        case SOT_ENDSWITH:
+            op->case_sensitive = sensitive;
+            break;
+
+        case SOT_MATCHES:
+            break;
+
+        case SOT_IEQUALS:
+            assert(!sensitive);
+            op->case_sensitive = false;
+            break;
+
+    }
+
+    op->first = first;
+    g_object_ref(G_OBJECT(op->first));
+
+    op->second = second;
+    g_object_ref(G_OBJECT(op->second));
+
+    result = true;
+
+ exit:
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op = expression à copier.                                    *
+*                                                                             *
+*  Description : Reproduit une expression en place dans une nouvelle instance.*
+*                                                                             *
+*  Retour      : Nouvelle instance d'expression.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GScanExpression *g_string_operation_duplicate(const GStringOperation *op)
+{
+    GScanExpression *result;                /* Instance copiée à retourner */
+
+    result = g_string_operation_new(op->type, op->first, op->second, op->case_sensitive);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : op    = expression à consulter.                              *
+*                ctx   = contexte de suivi de l'analyse courante.             *
+*                final = impose une conversion finale de dernier tour.        *
+*                                                                             *
+*  Description : Réduit une expression à une forme plus simple.               *
+*                                                                             *
+*  Retour      : Réduction correspondante, expression déjà réduite, ou NULL.  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanExpression *g_string_operation_reduce(GStringOperation *op, GScanContext *ctx, bool final)
+{
+    GScanExpression *result;                /* Instance à renvoyer         */
+    GScanExpression *new;                   /* Nouvelle expression obtenue */
+    const char *strings[2];                 /* Chaînes en jeu              */
+    bool status;                            /* Bilan intermédiaire         */
+    char *found;                            /* Eventuelle portion trouvée  */
+    size_t len[2];                          /* Tailles max. de comparaison */
+    int ret;                                /* Bilan de comparaison        */
+    const regex_t *preg;                    /* Expression rationnelle      */
+
+    result = NULL;
+
+    /* Réduction des éléments considérés */
+
+    new = g_scan_expression_reduce(op->first, ctx, final);
+
+    if (new != NULL)
+    {
+        g_object_unref(G_OBJECT(op->first));
+        op->first = new;
+    }
+
+    new = g_scan_expression_reduce(op->second, ctx, final);
+
+    if (new != NULL)
+    {
+        g_object_unref(G_OBJECT(op->second));
+        op->second = new;
+    }
+
+    /* Construction d'une réduction locale ? */
+
+    if (!G_IS_LITERAL_EXPRESSION(op->first))
+        goto exit;
+
+    if (!G_IS_LITERAL_EXPRESSION(op->second))
+        goto exit;
+
+    status = g_literal_expression_get_string_value(G_LITERAL_EXPRESSION(op->first), &strings[0]);
+    if (!status) goto exit;
+
+    switch (op->type)
+    {
+        case SOT_CONTAINS:
+
+            status = g_literal_expression_get_string_value(G_LITERAL_EXPRESSION(op->second), &strings[1]);
+            if (!status) goto exit;
+
+            if (op->case_sensitive)
+                found = strstr(strings[0], strings[1]);
+            else
+                found = strcasestr(strings[0], strings[1]);
+
+            result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { found != NULL });
+            break;
+
+        case SOT_STARTSWITH:
+
+            status = g_literal_expression_get_string_value(G_LITERAL_EXPRESSION(op->second), &strings[1]);
+            if (!status) goto exit;
+
+            len[1] = strlen(strings[1]);
+
+            if (op->case_sensitive)
+                ret = strncmp(strings[0], strings[1], len[1]);
+            else
+                ret = strncasecmp(strings[0], strings[1], len[1]);
+
+            result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { ret == 0 });
+            break;
+
+        case SOT_ENDSWITH:
+
+            len[0] = strlen(strings[0]);
+
+            status = g_literal_expression_get_string_value(G_LITERAL_EXPRESSION(op->second), &strings[1]);
+            if (!status) goto exit;
+
+            len[1] = strlen(strings[1]);
+
+            if (len[0] < len[1])
+                result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { false });
+
+            else
+            {
+                if (op->case_sensitive)
+                    ret = strncmp(strings[0] + (len[0] - len[1]), strings[1], len[1]);
+                else
+                    ret = strncasecmp(strings[0] + (len[0] - len[1]), strings[1], len[1]);
+
+                result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { ret == 0 });
+
+            }
+            break;
+
+        case SOT_MATCHES:
+
+            status = g_literal_expression_get_regex_value(G_LITERAL_EXPRESSION(op->second), &preg);
+            if (!status) goto exit;
+
+            ret = regexec(preg, strings[0], 0, NULL, 0);
+
+            result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { ret != REG_NOMATCH });
+            break;
+
+        case SOT_IEQUALS:
+
+            len[0] = strlen(strings[0]);
+
+            status = g_literal_expression_get_string_value(G_LITERAL_EXPRESSION(op->second), &strings[1]);
+            if (!status) goto exit;
+
+            len[1] = strlen(strings[1]);
+
+            if (len[0] != len[1])
+                result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { false });
+
+            else
+            {
+                ret = strcasecmp(strings[0], strings[1]);
+                result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { ret == 0 });
+            }
+            break;
+
+    }
+
+ exit:
+
+    return result;
+
+}
diff --git a/src/analysis/scan/exprs/str.h b/src/analysis/scan/exprs/str.h
new file mode 100644
index 0000000..195f941
--- /dev/null
+++ b/src/analysis/scan/exprs/str.h
@@ -0,0 +1,67 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * str.h - prototypes pour la gestion des opérations booléennes
+ *
+ * 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 _ANALYSIS_SCAN_EXPRS_STR_H
+#define _ANALYSIS_SCAN_EXPRS_STR_H
+
+
+#include "../expr.h"
+
+
+
+#define G_TYPE_STRING_OPERATION            g_string_operation_get_type()
+#define G_STRING_OPERATION(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_STRING_OPERATION, GStringOperation))
+#define G_IS_STRING_OPERATION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_STRING_OPERATION))
+#define G_STRING_OPERATION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_STRING_OPERATION, GStringOperationClass))
+#define G_IS_STRING_OPERATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_STRING_OPERATION))
+#define G_STRING_OPERATION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_STRING_OPERATION, GStringOperationClass))
+
+
+/* Opération booléenne avec un ou deux opérandes (instance) */
+typedef struct _GStringOperation GStringOperation;
+
+/* Opération booléenne avec un ou deux opérandes (classe) */
+typedef struct _GStringOperationClass GStringOperationClass;
+
+
+/* Types d'opérations booléennes supportées */
+typedef enum _StringOperationType
+{
+    SOT_CONTAINS,                           /* Opérateurs "[i]contains"    */
+    SOT_STARTSWITH,                         /* Opérateurs "[i]startswith"  */
+    SOT_ENDSWITH,                           /* Opérateurs "[i]endswith"    */
+    SOT_MATCHES,                            /* Opérateur "matches"         */
+    SOT_IEQUALS,                            /* Opérateur "iequals"         */
+
+} StringOperationType;
+
+
+/* Indique le type défini pour une opération traitant une chaîne de caractères. */
+GType g_string_operation_get_type(void);
+
+/* Organise un appel de fonction avec ses arguments. */
+GScanExpression *g_string_operation_new(StringOperationType, GScanExpression *, GScanExpression *, bool);
+
+
+
+#endif  /* _ANALYSIS_SCAN_EXPRS_STR_H */
diff --git a/src/analysis/scan/func-int.h b/src/analysis/scan/func-int.h
new file mode 100644
index 0000000..6591ba4
--- /dev/null
+++ b/src/analysis/scan/func-int.h
@@ -0,0 +1,51 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * func-int.h - prototypes internes pour la définition d'une fonction ciblant une propriété pendant un 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 _ANALYSIS_SCAN_FUNC_INT_H
+#define _ANALYSIS_SCAN_FUNC_INT_H
+
+
+#include "func.h"
+
+
+#include "item-int.h"
+
+
+
+/* Fonction apportant un support d'analyse pendant un scan (instance) */
+struct _GScanFunction
+{
+    GRegisteredItem parent;                 /* A laisser en premier        */
+
+};
+
+/* Fonction apportant un support d'analyse pendant un scan (classe) */
+struct _GScanFunctionClass
+{
+    GRegisteredItemClass parent;            /* A laisser en premier        */
+
+};
+
+
+
+#endif  /* _ANALYSIS_SCAN_FUNC_INT_H */
diff --git a/src/analysis/scan/func.c b/src/analysis/scan/func.c
new file mode 100644
index 0000000..b839d1d
--- /dev/null
+++ b/src/analysis/scan/func.c
@@ -0,0 +1,126 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * func.c - définition d'une fonction ciblant une propriété pendant un 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 "func.h"
+
+
+#include "func-int.h"
+
+
+
+/* Initialise la classe des fonctions de support pour scan. */
+static void g_scan_function_class_init(GScanFunctionClass *);
+
+/* Initialise une instance de fonction de support pour scan. */
+static void g_scan_function_init(GScanFunction *);
+
+/* Supprime toutes les références externes. */
+static void g_scan_function_dispose(GScanFunction *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_scan_function_finalize(GScanFunction *);
+
+
+
+/* Indique le type défini pour une définition de fonction de scan. */
+G_DEFINE_TYPE(GScanFunction, g_scan_function, G_TYPE_REGISTERED_ITEM);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des fonctions de support pour scan.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_function_class_init(GScanFunctionClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_function_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_scan_function_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : func = instance à initialiser.                               *
+*                                                                             *
+*  Description : Initialise une instance de fonction de support pour scan.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_function_init(GScanFunction *func)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : func = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_function_dispose(GScanFunction *func)
+{
+    G_OBJECT_CLASS(g_scan_function_parent_class)->dispose(G_OBJECT(func));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : func = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_function_finalize(GScanFunction *func)
+{
+    G_OBJECT_CLASS(g_scan_function_parent_class)->finalize(G_OBJECT(func));
+
+}
diff --git a/src/analysis/scan/func.h b/src/analysis/scan/func.h
new file mode 100644
index 0000000..bfc823a
--- /dev/null
+++ b/src/analysis/scan/func.h
@@ -0,0 +1,52 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * func.h - prototypes pour la définition d'une fonction ciblant une propriété pendant un 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 _ANALYSIS_SCAN_FUNC_H
+#define _ANALYSIS_SCAN_FUNC_H
+
+
+#include <glib-object.h>
+
+
+
+#define G_TYPE_SCAN_FUNCTION            g_scan_function_get_type()
+#define G_SCAN_FUNCTION(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_FUNCTION, GScanFunction))
+#define G_IS_SCAN_FUNCTION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_FUNCTION))
+#define G_SCAN_FUNCTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_FUNCTION, GScanFunctionClass))
+#define G_IS_SCAN_FUNCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_FUNCTION))
+#define G_SCAN_FUNCTION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_FUNCTION, GScanFunctionClass))
+
+
+/* Fonction apportant un support d'analyse pendant un scan (instance) */
+typedef struct _GScanFunction GScanFunction;
+
+/* Fonction apportant un support d'analyse pendant un scan (classe) */
+typedef struct _GScanFunctionClass GScanFunctionClass;
+
+
+/* Indique le type défini pour une définition de fonction de scan. */
+GType g_scan_function_get_type(void);
+
+
+
+#endif  /* _ANALYSIS_SCAN_FUNC_H */
diff --git a/src/analysis/scan/funcs/Makefile.am b/src/analysis/scan/funcs/Makefile.am
new file mode 100644
index 0000000..be370ba
--- /dev/null
+++ b/src/analysis/scan/funcs/Makefile.am
@@ -0,0 +1,15 @@
+
+noinst_LTLIBRARIES  = libanalysisscanfuncs.la
+
+
+libanalysisscanfuncs_la_SOURCES =			\
+	datasize.h datasize.c					\
+	uint-int.h								\
+	uint.h uint.c
+
+libanalysisscanfuncs_la_CFLAGS = $(LIBGOBJ_CFLAGS)
+
+
+devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
+
+dev_HEADERS = $(libanalysisscanfuncs_la_SOURCES:%c=)
diff --git a/src/analysis/scan/funcs/datasize.c b/src/analysis/scan/funcs/datasize.c
new file mode 100644
index 0000000..7e63095
--- /dev/null
+++ b/src/analysis/scan/funcs/datasize.c
@@ -0,0 +1,214 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * datasize.c - récupération de la taille du contenu scanné
+ *
+ * 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 "datasize.h"
+
+
+#include "../func-int.h"
+#include "../exprs/literal.h"
+
+
+
+/* ---------------------- INTRODUCTION D'UNE NOUVELLE FONCTION ---------------------- */
+
+
+/* Initialise la classe des mesures de quantité de données. */
+static void g_datasize_function_class_init(GDatasizeFunctionClass *);
+
+/* Initialise une instance de mesure de quantité de données. */
+static void g_datasize_function_init(GDatasizeFunction *);
+
+/* Supprime toutes les références externes. */
+static void g_datasize_function_dispose(GDatasizeFunction *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_datasize_function_finalize(GDatasizeFunction *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Réduit une expression à une forme plus simple. */
+static GScanExpression *g_datasize_function_reduce(GDatasizeFunction *, GScanContext *, GScanExpression **, size_t, bool);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                        INTRODUCTION D'UNE NOUVELLE FONCTION                        */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une mesure de quantité de données scannées. */
+G_DEFINE_TYPE(GDatasizeFunction, g_datasize_function, G_TYPE_SCAN_FUNCTION);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des mesures de quantité de données.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_datasize_function_class_init(GDatasizeFunctionClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GRegisteredItemClass *registered;       /* Version de classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_datasize_function_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_datasize_function_finalize;
+
+    registered = G_REGISTERED_ITEM_CLASS(klass);
+
+    registered->reduce = (reduce_registered_item_fc)g_datasize_function_reduce;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : func = instance à initialiser.                               *
+*                                                                             *
+*  Description : Initialise une instance de mesure de quantité de données.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_datasize_function_init(GDatasizeFunction *func)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : func = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_datasize_function_dispose(GDatasizeFunction *func)
+{
+    G_OBJECT_CLASS(g_datasize_function_parent_class)->dispose(G_OBJECT(func));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : func = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_datasize_function_finalize(GDatasizeFunction *func)
+{
+    G_OBJECT_CLASS(g_datasize_function_parent_class)->finalize(G_OBJECT(func));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Constitue une fonction de récupération de taille de données. *
+*                                                                             *
+*  Retour      : Fonction mise en place.                                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanFunction *g_datasize_function_new(void)
+{
+    GScanFunction *result;                  /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_DATASIZE_FUNCTION, NULL);
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : func   = élément d'appel à consulter.                        *
+*                target = désignation de l'objet d'appel à identifier.        *
+*                ctx    = contexte de suivi de l'analyse courante.            *
+*                args   = liste d'éventuels arguments fournis.                *
+*                count  = taille de cette liste.                              *
+*                last   = l'élément est-il le dernier d'une chaîne d'appels ? *
+*                final = indique une ultime conversion dans le cycle en cours.*
+*                                                                             *
+*  Description : Réduit une expression à une forme plus simple.               *
+*                                                                             *
+*  Retour      : Réduction correspondante, expression déjà réduite, ou NULL.  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GScanExpression *g_datasize_function_reduce(GDatasizeFunction *func, GScanContext *ctx, GScanExpression **args, size_t count, bool final)
+{
+    GScanExpression *result;                /* Instance à renvoyer         */
+    GBinContent *content;                   /* Contenu à manipuler         */
+    phys_t size;                            /* Quantité de données liées   */
+
+    content = g_scan_context_get_content(ctx);
+
+    size = g_binary_content_compute_size(content);
+
+    result = g_literal_expression_new(EVT_INTEGER, (unsigned long long []){ size });
+
+    g_object_unref(G_OBJECT(content));
+
+    return result;
+
+}
diff --git a/src/analysis/scan/funcs/datasize.h b/src/analysis/scan/funcs/datasize.h
new file mode 100644
index 0000000..bdd813d
--- /dev/null
+++ b/src/analysis/scan/funcs/datasize.h
@@ -0,0 +1,55 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * datasize.h - prototypes pour la récupération de la taille du contenu scanné
+ *
+ * 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 _ANALYSIS_SCAN_FUNCS_DATASIZE_H
+#define _ANALYSIS_SCAN_FUNCS_DATASIZE_H
+
+
+#include "../func.h"
+
+
+
+#define G_TYPE_DATASIZE_FUNCTION            g_datasize_function_get_type()
+#define G_DATASIZE_FUNCTION(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DATASIZE_FUNCTION, GDatasizeFunction))
+#define G_IS_DATASIZE_FUNCTION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_DATASIZE_FUNCTION))
+#define G_DATASIZE_FUNCTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DATASIZE_FUNCTION, GDatasizeFunctionClass))
+#define G_IS_DATASIZE_FUNCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DATASIZE_FUNCTION))
+#define G_DATASIZE_FUNCTION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DATASIZE_FUNCTION, GDatasizeFunctionClass))
+
+
+/* Mesure de la quantité de données scannées (instance) */
+typedef GScanFunction GDatasizeFunction;
+
+/* Mesure de la quantité de données scannées (classe) */
+typedef GScanFunctionClass GDatasizeFunctionClass;
+
+
+/* Indique le type défini pour une mesure de quantité de données scannées. */
+GType g_datasize_function_get_type(void);
+
+/* Constitue une fonction de récupération de taille de données. */
+GScanFunction *g_datasize_function_new(void);
+
+
+
+#endif  /* _ANALYSIS_SCAN_FUNCS_DATASIZE_H */
diff --git a/src/analysis/scan/funcs/uint-int.h b/src/analysis/scan/funcs/uint-int.h
new file mode 100644
index 0000000..0817805
--- /dev/null
+++ b/src/analysis/scan/funcs/uint-int.h
@@ -0,0 +1,54 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * uint-int.h - prototypes internes pour la lecture d'un mot à partir de données binaires
+ *
+ * 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 _ANALYSIS_SCAN_FUNCS_UINT_INT_H
+#define _ANALYSIS_SCAN_FUNCS_UINT_INT_H
+
+
+#include "uint.h"
+
+
+#include "../func-int.h"
+
+
+
+/* Fonction conduisant à la lecture d'un mot (instance) */
+struct _GUintFunction
+{
+    GScanFunction parent;                   /* A laisser en premier        */
+
+    MemoryDataSize size;                    /* Taille du mot à lire        */
+    SourceEndian endian;                    /* Boutisme à respecter        */
+
+};
+
+/* Fonction conduisant à la lecture d'un mot (classe) */
+struct _GUintFunctionClass
+{
+    GScanFunctionClass parent;              /* A laisser en premier        */
+
+};
+
+
+
+#endif  /* _ANALYSIS_SCAN_FUNCS_UINT_INT_H */
diff --git a/src/analysis/scan/funcs/uint.c b/src/analysis/scan/funcs/uint.c
new file mode 100644
index 0000000..6421f52
--- /dev/null
+++ b/src/analysis/scan/funcs/uint.c
@@ -0,0 +1,266 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * uint.c - lecture d'un mot à partir de données binaires
+ *
+ * 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 "uint.h"
+
+
+#include "uint-int.h"
+#include "../exprs/literal.h"
+
+
+
+/* ---------------------- INTRODUCTION D'UNE NOUVELLE FONCTION ---------------------- */
+
+
+/* Initialise la classe des lectures de valeurs entières. */
+static void g_uint_function_class_init(GUintFunctionClass *);
+
+/* Initialise une instance de lecture de valeur entière. */
+static void g_uint_function_init(GUintFunction *);
+
+/* Supprime toutes les références externes. */
+static void g_uint_function_dispose(GUintFunction *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_uint_function_finalize(GUintFunction *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Réduit une expression à une forme plus simple. */
+static GScanExpression *g_uint_function_reduce(GUintFunction *, GScanContext *, GScanExpression **, size_t, bool);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                        INTRODUCTION D'UNE NOUVELLE FONCTION                        */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une lecture de mot à partir de données binaires. */
+G_DEFINE_TYPE(GUintFunction, g_uint_function, G_TYPE_SCAN_FUNCTION);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des lectures de valeurs entières.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_uint_function_class_init(GUintFunctionClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GRegisteredItemClass *registered;       /* Version de classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_uint_function_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_uint_function_finalize;
+
+    registered = G_REGISTERED_ITEM_CLASS(klass);
+
+    registered->reduce = (reduce_registered_item_fc)g_uint_function_reduce;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : func = instance à initialiser.                               *
+*                                                                             *
+*  Description : Initialise une instance de lecture de valeur entière.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_uint_function_init(GUintFunction *func)
+{
+    func->size = MDS_UNDEFINED;
+    func->endian = SRE_LITTLE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : func = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_uint_function_dispose(GUintFunction *func)
+{
+    G_OBJECT_CLASS(g_uint_function_parent_class)->dispose(G_OBJECT(func));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : func = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_uint_function_finalize(GUintFunction *func)
+{
+    G_OBJECT_CLASS(g_uint_function_parent_class)->finalize(G_OBJECT(func));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : size = taille du mot à venir lire dans les données.          *
+*                                                                             *
+*  Description : Constitue une fonction de lecture de valeur entière.         *
+*                                                                             *
+*  Retour      : Fonction mise en place.                                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanFunction *g_uint_function_new(MemoryDataSize size)
+{
+    GScanFunction *result;                  /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_UINT_FUNCTION, NULL);
+
+    G_UINT_FUNCTION(result)->size = size;
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : func   = élément d'appel à consulter.                        *
+*                target = désignation de l'objet d'appel à identifier.        *
+*                ctx    = contexte de suivi de l'analyse courante.            *
+*                args   = liste d'éventuels arguments fournis.                *
+*                count  = taille de cette liste.                              *
+*                last   = l'élément est-il le dernier d'une chaîne d'appels ? *
+*                final = indique une ultime conversion dans le cycle en cours.*
+*                                                                             *
+*  Description : Réduit une expression à une forme plus simple.               *
+*                                                                             *
+*  Retour      : Réduction correspondante, expression déjà réduite, ou NULL.  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GScanExpression *g_uint_function_reduce(GUintFunction *func, GScanContext *ctx, GScanExpression **args, size_t count, bool final)
+{
+    GScanExpression *result;                /* Instance à renvoyer         */
+    unsigned long long offset;              /* Position du mot ciblé       */
+    bool status;                            /* Bilan d'une opération       */
+    GBinContent *content;                   /* Contenu à manipuler         */
+    vmpa2t pos;                             /* Tête de lecture             */
+    uint8_t val_8;                          /* Valeur entière sur 8 bits   */
+    uint16_t val_16;                        /* Valeur entière sur 16 bits  */
+    uint32_t val_32;                        /* Valeur entière sur 32 bits  */
+    uint64_t val_64;                        /* Valeur entière sur 64 bits  */
+
+    result = NULL;
+
+    if (count == 1 && G_IS_LITERAL_EXPRESSION(args[0]))
+    {
+        status = g_literal_expression_get_integer_value(G_LITERAL_EXPRESSION(args[0]), &offset);
+        if (!status) goto exit;
+
+        content = g_scan_context_get_content(ctx);
+
+        g_binary_content_compute_start_pos(content, &pos);
+        advance_vmpa(&pos, offset);
+
+        switch (func->size)
+        {
+            case MDS_8_BITS_UNSIGNED:
+                status = g_binary_content_read_u8(content, &pos, &val_8);
+                if (status)
+                    result = g_literal_expression_new(EVT_INTEGER, (unsigned long long []){ val_8 });
+                break;
+
+            case MDS_16_BITS_UNSIGNED:
+                status = g_binary_content_read_u16(content, &pos, func->endian, &val_16);
+                if (status)
+                    result = g_literal_expression_new(EVT_INTEGER, (unsigned long long []){ val_16 });
+                break;
+
+            case MDS_32_BITS_UNSIGNED:
+                status = g_binary_content_read_u32(content, &pos, func->endian, &val_32);
+                if (status)
+                    result = g_literal_expression_new(EVT_INTEGER, (unsigned long long []){ val_32 });
+                break;
+
+
+            case MDS_64_BITS_UNSIGNED:
+                status = g_binary_content_read_u64(content, &pos, func->endian, &val_64);
+                if (status)
+                    result = g_literal_expression_new(EVT_INTEGER, (unsigned long long []){ val_64 });
+                break;
+
+            default:
+                break;
+
+        }
+
+        g_object_unref(G_OBJECT(content));
+
+    }
+
+ exit:
+
+    return result;
+
+}
diff --git a/src/analysis/scan/funcs/uint.h b/src/analysis/scan/funcs/uint.h
new file mode 100644
index 0000000..fe6cb52
--- /dev/null
+++ b/src/analysis/scan/funcs/uint.h
@@ -0,0 +1,56 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * uint.h - prototypes pour la lecture d'un mot à partir de données binaires
+ *
+ * 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 _ANALYSIS_SCAN_FUNCS_UINT_H
+#define _ANALYSIS_SCAN_FUNCS_UINT_H
+
+
+#include "../func.h"
+#include "../../../arch/archbase.h"
+
+
+
+#define G_TYPE_UINT_FUNCTION            g_uint_function_get_type()
+#define G_UINT_FUNCTION(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_UINT_FUNCTION, GUintFunction))
+#define G_IS_UINT_FUNCTION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_UINT_FUNCTION))
+#define G_UINT_FUNCTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_UINT_FUNCTION, GUintFunctionClass))
+#define G_IS_UINT_FUNCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_UINT_FUNCTION))
+#define G_UINT_FUNCTION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_UINT_FUNCTION, GUintFunctionClass))
+
+
+/* Fonction conduisant à la lecture d'un mot (instance) */
+typedef struct _GUintFunction GUintFunction;
+
+/* Fonction conduisant à la lecture d'un mot (classe) */
+typedef struct _GUintFunctionClass GUintFunctionClass;
+
+
+/* Indique le type défini pour une lecture de mot à partir de données binaires. */
+GType g_uint_function_get_type(void);
+
+/* Constitue une fonction de lecture de valeur entière. */
+GScanFunction *g_uint_function_new(MemoryDataSize);
+
+
+
+#endif  /* _ANALYSIS_SCAN_FUNCS_UINT_H */
diff --git a/src/analysis/scan/grammar.y b/src/analysis/scan/grammar.y
new file mode 100644
index 0000000..ab64ad8
--- /dev/null
+++ b/src/analysis/scan/grammar.y
@@ -0,0 +1,487 @@
+
+%{
+
+#include "decl.h"
+#include "tokens.h"
+
+
+/* Affiche un message d'erreur suite à l'analyse en échec. */
+static int yyerror(GContentScanner *, yyscan_t, GScanRule **, void/*GBytesPattern*/ **, char **, size_t *, size_t *, char *);
+
+%}
+
+
+%code requires {
+
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void *yyscan_t;
+
+#include "scanner.h"
+#include "conds/counter.h"
+#include "exprs/arithmop.h"
+#include "exprs/boolop.h"
+#include "exprs/call.h"
+#include "exprs/literal.h"
+#include "exprs/str.h"
+#include "exprs/relop.h"
+#include "patterns/tokens/plain.h"
+
+
+#if 0 /////////////////////////////////////////////////////////////////////////::
+#define handle_coder_conversions(c, r)                              \
+    ({                                                              \
+        encoding_spec *__spec;                                      \
+        encoding_syntax *__syntax;                                  \
+        conv_list *__list;                                          \
+        bool __status;                                              \
+        __spec = get_current_encoding_spec(c);                      \
+        __syntax = get_current_encoding_syntax(__spec);             \
+        __list = get_conversions_in_encoding_syntax(__syntax);      \
+        __status = load_convs_from_raw_block(__list, r);            \
+        if (!__status) YYABORT;                                     \
+    })
+#endif ///////////////////////////////////////////////////////////////////////////
+
+}
+
+%union {
+
+    //char *string;                           /* Chaîne de caractères #1     */
+    const char *cstring;                    /* Chaîne de caractères #2     */
+    unsigned long long integer;             /* Valeur entière              */
+
+    struct {
+        const char *cstring;                /* Chaîne de caractères #3     */
+        size_t len;                         /* Taille correspondante       */
+    } sized_cstring;
+
+    GScanRule *rule;                        /* Nouvelle règle à intégrer   */
+    void/*GBytesPattern*/ *pattern;                 /* Nouveau motif à considérer  */
+    GScanExpression *expr;                  /* Expression de condition     */
+
+    struct {
+        GScanExpression **args;             /* Liste d'arguments à fournir */
+        size_t count;                       /* Quantité de ces arguments   */
+    } args_list;
+
+}
+
+
+/**
+ * Cf.
+ * http://stackoverflow.com/questions/34418381/how-to-reference-lex-or-parse-parameters-in-flex-rules/34420950
+ */
+
+%define api.pure full
+
+%parse-param { GContentScanner *scanner } { yyscan_t yyscanner } { GScanRule **built_rule } { void /*GBytesPattern*/ **built_pattern } { char **buf } { size_t *allocated } { size_t *used }
+%lex-param { yyscan_t yyscanner } { void/*GBytesPattern*/ **built_pattern } { char **buf } { size_t *allocated } { size_t *used }
+
+%code provides {
+
+#define YY_DECL \
+    int rost_lex(YYSTYPE *yylval_param, yyscan_t yyscanner, void/*GBytesPattern*/ **built_pattern, char **buf, size_t *allocated, size_t *used)
+
+YY_DECL;
+
+}
+
+
+%token RAW_RULE
+%token RULE_NAME
+
+%token STRINGS CONDITION
+%token IDENTIFIER
+%token NAME
+
+%token BRACE_IN BRACE_OUT ASSIGN COLON
+
+
+%token RAW_BLOCK
+
+%token PLAIN_STRING
+%token MASKED_STRING
+
+%token TRUE_            "true"
+%token FALSE_           "false"
+%token INTEGER
+%token STRING
+
+%token KB MB GB
+
+%token AND              "and"
+%token OR               "or"
+%token NOT              "not"
+
+%token LT               "<"
+%token LE               "<="
+%token EQ               "=="
+%token NE               "!="
+%token GT               ">"
+%token GE               ">="
+
+%token CONTAINS     "contains"
+%token STARTSWITH   "startswith"
+%token ENDSWITH     "endswith"
+%token MATCHES      "matches"
+%token ICONTAINS    "icontains"
+%token ISTARTSWITH  "istartswith"
+%token IENDSWITH    "iendswith"
+%token IEQUALS      "iequals"
+
+%token PLUS             "+"
+%token MINUS            "-"
+%token MUL              "*"
+%token DIV              "\\"
+%token MOD              "%"
+
+%token PAREN_O          "("
+%token PAREN_C          ")"
+%token COMMA            ","
+%token DOT              "."
+
+%token NONE             "none"
+%token ANY              "any"
+%token ALL              "all"
+%token OF               "of"
+%token THEM             "them"
+
+
+%type <cstring> RULE_NAME
+%type <cstring> RAW_BLOCK
+
+
+%type <sized_cstring> IDENTIFIER
+%type <sized_cstring> NAME
+
+
+%type <integer> INTEGER
+%type <cstring> STRING
+
+%type <rule> rule
+
+%type <sized_cstring> PLAIN_STRING
+%type <pattern> MASKED_STRING
+
+%type <expr> cexpression
+%type <expr> literal
+%type <expr> callable
+%type <args_list> call_args
+%type <expr> bool_expr
+%type <expr> rel_expr
+%type <expr> str_expr
+%type <expr> arithm_expr
+%type <expr> set_counter
+
+
+
+%left OR
+%left AND
+%left EQ NE
+%left CONTAINS STARTSWITH ENDSWITH MATCHES ICONTAINS ISTARTSWITH IENDSWITH IEQUALS
+%left LT LE GT GE
+%left PLUS MINUS
+%left MUL DIV MOD
+%right NOT
+
+
+
+
+%destructor { printf("-------- Discarding symbol %p.\n", $$); } <rule>
+
+
+%%
+
+
+
+ /*
+
+
+<raw_block>[ \t\n]+             { }
+<raw_block>"{"                  {
+                                    read_block(temp);
+                                    yylvalp->cstring = temp; return RAW_BLOCK;
+                                }
+<raw_block>"}"                  { yy_pop_state(); }
+
+  */
+
+
+rules : /* empty */
+      | rule rules { g_content_scanner_add_rule(scanner, $1); }
+
+        //rule : RAW_RULE RULE_NAME { printf("RULE %s\n", $2); } RAW_BLOCK { printf("BLOCK: %s\n", $4); }
+
+rule : RAW_RULE RULE_NAME
+     {
+         *built_rule = g_scan_rule_new($2);
+         $<rule>$ = *built_rule;
+     }
+     BRACE_IN strings condition BRACE_OUT
+     {
+         $$ = $<rule>3;
+         //printf("RULE %s -> %p\n", $2, $$);
+     } 
+
+
+
+
+strings : /* empty */
+        | STRINGS COLON string_decls
+        ;
+
+
+string_decls : string_decl
+             | string_decls string_decl
+             ;
+
+string_decl : IDENTIFIER ASSIGN PLAIN_STRING
+            {
+                GSearchPattern *__pat;
+                __pat = g_plain_bytes_new((uint8_t *)$3.cstring, $3.len);
+                g_search_pattern_set_name(__pat, $1.cstring, $1.len);
+                g_scan_rule_add_local_variable(*built_rule, __pat);
+                g_object_unref(G_OBJECT(__pat));
+
+                /*
+                string_token_t *__token;
+                //printf("built plain %s\n", $3.cstring);
+                GBytesPattern *__pat;
+                __token = create_plain_string_token($3.cstring, $3.len);
+                printf("token: %p\n", __token);
+                __pat = g_bytes_pattern_new();
+                g_bytes_pattern_append_string(__pat, $3.cstring, $3.len);
+                g_scan_rule_add_local_variable(*built_rule, $1, G_SEARCH_PATTERN(__pat));
+                g_object_unref(G_OBJECT(__pat));
+                */
+            }
+            | IDENTIFIER ASSIGN MASKED_STRING
+            {
+                printf("built %p\n", $3);
+                /*
+                GBytesPattern *__pat;
+                __pat = g_bytes_pattern_new();
+                g_search_pattern_set_name(__pat, $1.cstring, $1.len);
+                g_bytes_pattern_append_string(__pat, "\xd9\x74\x24\xf4", 4);
+                g_scan_rule_add_local_variable(*built_rule, G_SEARCH_PATTERN(__pat));
+                */
+                /*
+                GSearchPattern *__pat;
+                __pat = G_SEARCH_PATTERN($3);
+                if (g_search_pattern_prepare(__pat))
+                    g_scan_rule_add_local_variable(*built_rule, $1, __pat);
+                g_clear_object(built_pattern);
+                */
+            }
+            ;
+
+condition : /* empty */
+          | CONDITION COLON cexpression
+          {
+              g_scan_rule_set_match_condition(*built_rule, $3);
+              g_object_ref(G_OBJECT($3));
+          }
+          ;
+
+cexpression : IDENTIFIER
+            {
+                printf("named var: %s\n", "$1");
+                /*
+                   GSearchPattern *__pat;
+                   GMatchCounter *__counter;
+                   __pat = g_scan_rule_get_local_variable(*built_rule, $1);
+                   if (__pat != NULL)
+                   {
+                       __counter = g_match_counter_new(__pat);
+                       g_scan_rule_add_condition(*built_rule, G_MATCH_CONDITION(__counter));
+                       g_object_unref(G_OBJECT(__counter));
+                       g_object_unref(G_OBJECT(__pat));
+                   }
+                */
+            }
+            | literal { $$ = $1; }
+            | callable { $$ = $1; }
+            | bool_expr { $$ = $1; }
+            | rel_expr { $$ = $1; }
+            | str_expr { $$ = $1; }
+            | arithm_expr { $$ = $1; }
+            | set_counter { $$ = $1; }
+            | "(" cexpression ")" { $$ = $2; }
+            ;
+
+literal : "true" { $$ = g_literal_expression_new(EVT_BOOLEAN, (bool []){ true }); }
+        | "false" { $$ = g_literal_expression_new(EVT_BOOLEAN, (bool []){ false }); }
+        | INTEGER { $$ = g_literal_expression_new(EVT_INTEGER, &$1); }
+        | INTEGER KB { $$ = g_literal_expression_new(EVT_INTEGER, (unsigned long long []){ $1 * 1024 }); }
+        | INTEGER MB { $$ = g_literal_expression_new(EVT_INTEGER, (unsigned long long []){ $1 * 1048576 }); }
+        | INTEGER GB { $$ = g_literal_expression_new(EVT_INTEGER, (unsigned long long []){ $1 * 1073741824 }); }
+        | STRING { $$ = g_literal_expression_new(EVT_STRING, $1); }
+        ;
+
+callable : NAME { $$ = g_pending_call_new($1.cstring, $1.len, NULL, 0); }
+         | NAME "(" ")" { $$ = g_pending_call_new($1.cstring, $1.len, NULL, 0); }
+         | NAME "(" call_args ")"
+         {
+             size_t __i;
+             $$ = g_pending_call_new($1.cstring, $1.len, $3.args, $3.count);
+             for (__i = 0; __i < $3.count; __i++)
+                 g_object_unref(G_OBJECT($3.args[__i]));
+             free($3.args);
+         }
+         | callable "." NAME
+         {
+             GScanExpression *__next;
+             __next = g_pending_call_new($3.cstring, $3.len, NULL, 0);
+             g_pending_call_attach_next(G_PENDING_CALL($1), G_PENDING_CALL(__next));
+             $$ = $1;
+         }
+         | callable "." NAME "(" ")"
+         {
+             GScanExpression *__next;
+             __next = g_pending_call_new($3.cstring, $3.len, NULL, 0);
+             g_pending_call_attach_next(G_PENDING_CALL($1), G_PENDING_CALL(__next));
+             $$ = $1;
+         }
+         | callable "." NAME "(" call_args ")"
+         {
+             GScanExpression *__next;
+             size_t __i;
+             __next = g_pending_call_new($3.cstring, $3.len, $5.args, $5.count);
+             for (__i = 0; __i < $5.count; __i++)
+                 g_object_unref(G_OBJECT($5.args[__i]));
+             free($5.args);
+             g_pending_call_attach_next(G_PENDING_CALL($1), G_PENDING_CALL(__next));
+             $$ = $1;
+         }
+         ;
+
+call_args : cexpression
+          {
+              $$.count = 1;
+              $$.args = malloc(sizeof(GScanExpression *));
+              $$.args[0] = $1;
+          }
+          | call_args "," cexpression
+          {
+              $1.count++;
+              $1.args = realloc($1.args, $1.count * sizeof(GScanExpression *));
+              $1.args[$1.count - 1] = $3;
+              $$ = $1;
+          }
+          ;
+
+bool_expr : cexpression "and" cexpression { $$ = g_boolean_operation_new(BOT_AND, $1, $3); }
+          | cexpression "or" cexpression  { $$ = g_boolean_operation_new(BOT_OR, $1, $3); }
+          | "not" "(" cexpression ")"     { $$ = g_boolean_operation_new(BOT_NOT, $3, NULL); }
+          ;
+
+rel_expr : cexpression "<" cexpression  { $$ = g_relational_operation_new(RCO_LT, $1, $3); }
+         | cexpression "<=" cexpression { $$ = g_relational_operation_new(RCO_LE, $1, $3); }
+         | cexpression "==" cexpression { $$ = g_relational_operation_new(RCO_EQ, $1, $3); }
+         | cexpression "!=" cexpression { $$ = g_relational_operation_new(RCO_NE, $1, $3); }
+         | cexpression ">" cexpression  { $$ = g_relational_operation_new(RCO_GT, $1, $3); }
+         | cexpression ">=" cexpression { $$ = g_relational_operation_new(RCO_GT, $1, $3); }
+         ;
+
+str_expr : cexpression "contains" cexpression    { $$ = g_string_operation_new(SOT_CONTAINS, $1, $3, true); }
+         | cexpression "startswith" cexpression  { $$ = g_string_operation_new(SOT_STARTSWITH, $1, $3, true); }
+         | cexpression "endswith" cexpression    { $$ = g_string_operation_new(SOT_ENDSWITH, $1, $3, true); }
+         | cexpression "matches" cexpression     { $$ = g_string_operation_new(SOT_MATCHES, $1, $3, true); }
+         | cexpression "icontains" cexpression   { $$ = g_string_operation_new(SOT_CONTAINS, $1, $3, false); }
+         | cexpression "istartswith" cexpression { $$ = g_string_operation_new(SOT_STARTSWITH, $1, $3, false); }
+         | cexpression "iendswith" cexpression   { $$ = g_string_operation_new(SOT_ENDSWITH, $1, $3, false); }
+         | cexpression "iequals" cexpression     { $$ = g_string_operation_new(SOT_IEQUALS, $1, $3, false); }
+         ;
+
+arithm_expr : cexpression "+" cexpression  { $$ = g_arithmetic_operation_new(AEO_PLUS, $1, $3); }
+            | cexpression "-" cexpression  { $$ = g_arithmetic_operation_new(AEO_MINUS, $1, $3); }
+            | cexpression "*" cexpression  { $$ = g_arithmetic_operation_new(AEO_MUL, $1, $3); }
+            | cexpression "\\" cexpression { $$ = g_arithmetic_operation_new(AEO_DIV, $1, $3); }
+            | cexpression "%" cexpression  { $$ = g_arithmetic_operation_new(AEO_MOD, $1, $3); }
+            ;
+
+set_counter : "none" "of" "them"  { $$ = g_literal_expression_new(EVT_BOOLEAN, (bool []){ true }); }
+            | "any" "of" "them"  { $$ = g_literal_expression_new(EVT_BOOLEAN, (bool []){ true }); }
+            | "all" "of" "them"  { $$ = g_literal_expression_new(EVT_BOOLEAN, (bool []){ true }); }
+            ;
+
+%%
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : scanner = décodeur impliqué dans le processus.               *
+*                temp    = zone de travail à destination des lectures.        *
+*                msg     = message d'erreur.                                  *
+*                                                                             *
+*  Description : Affiche un message d'erreur suite à l'analyse en échec.      *
+*                                                                             *
+*  Retour      : 0                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int yyerror(GContentScanner *scanner, yyscan_t yyscanner, GScanRule **built_rule, void/*GBytesPattern*/ **built_pattern, char **buf, size_t *allocated, size_t *used, char *msg)
+{
+	printf("YYERROR line %d: %s\n", yyget_lineno(yyscanner), msg);
+
+	return 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : scanner = chercheur de motifs à préparer.                    *
+*                text    = définitions des règles à charger.                  *
+*                length  = longueur de ces définitions.                       *
+*                                                                             *
+*  Description : Complète une recherche de motifs avec des règles.            *
+*                                                                             *
+*  Retour      : Bilan à retourner.                                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool process_rules_definitions(GContentScanner *scanner, const char *text, size_t length)
+{
+    bool result;                            /* Bilan à renvoyer            */
+    GScanRule *built_rule;                  /* Règle en construction       */
+    void /*GBytesPattern*/ *built_pattern;           /* Motif en construction       */
+    char *buf;                              /* Zone de travail temporaire  */
+    size_t allocated;                       /* Taille de mémoire allouée   */
+    size_t used;                            /* Quantité utilisée           */
+    yyscan_t lexstate;                      /* Gestion d'analyse lexicale  */
+    YY_BUFFER_STATE state;                  /* Contexte d'analyse          */
+    int status;                             /* Bilan d'une analyse         */
+
+    result = false;
+
+    built_rule = NULL;
+    built_pattern = NULL;
+
+    allocated = 256;
+    used = 0;
+
+    buf = malloc(allocated * sizeof(char));
+    buf[0] = '\0';
+
+    rost_lex_init(&lexstate);
+
+    state = rost__scan_bytes(text, length, lexstate);
+
+    status = yyparse(scanner, lexstate, &built_rule, &built_pattern, &buf, &allocated, &used);
+
+    result = (status == EXIT_SUCCESS);
+
+    yy_delete_buffer(state, lexstate);
+
+    rost_lex_destroy(lexstate);
+
+    free(buf);
+
+    return result;
+
+}
diff --git a/src/analysis/scan/item-int.h b/src/analysis/scan/item-int.h
new file mode 100644
index 0000000..d1151f2
--- /dev/null
+++ b/src/analysis/scan/item-int.h
@@ -0,0 +1,61 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * item-int.h - prototypes internes pour la définition d'un élément appelable lors de l'exécution d'une règle
+ *
+ * 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 _ANALYSIS_SCAN_ITEM_INT_H
+#define _ANALYSIS_SCAN_ITEM_INT_H
+
+
+#include "item.h"
+
+
+#include <stdbool.h>
+
+
+
+/* Lance une résolution d'élément à appeler. */
+typedef GRegisteredItem * (* resolve_registered_item_fc) (GRegisteredItem *, const char *, GScanContext *, GScanExpression **, size_t, bool, bool);
+
+/* Réduit une expression à une forme plus simple. */
+typedef GScanExpression * (* reduce_registered_item_fc) (GRegisteredItem *, GScanContext *, GScanExpression **, size_t, bool);
+
+
+/* Expression d'évaluation généraliste (instance) */
+struct _GRegisteredItem
+{
+    GObject parent;                         /* A laisser en premier        */
+
+};
+
+/* Expression d'évaluation généraliste (classe) */
+struct _GRegisteredItemClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+    resolve_registered_item_fc resolve;     /* Opération de résolution     */
+    reduce_registered_item_fc reduce;       /* Opération de réduction      */
+
+};
+
+
+
+#endif  /* _ANALYSIS_SCAN_ITEM_INT_H */
diff --git a/src/analysis/scan/item.c b/src/analysis/scan/item.c
new file mode 100644
index 0000000..c0b1532
--- /dev/null
+++ b/src/analysis/scan/item.c
@@ -0,0 +1,199 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * item.c - définition d'un élément appelable lors de l'exécution d'une règle
+ *
+ * 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 "item.h"
+
+
+#include "item-int.h"
+
+
+
+/* ----------------------- BASES D'OBJET POUR LE SYSTEME GLIB ----------------------- */
+
+
+/* Initialise la classe des éléments appelables enregistrés. */
+static void g_registered_item_class_init(GRegisteredItemClass *);
+
+/* Initialise une instance d'élément appelable enregistré. */
+static void g_registered_item_init(GRegisteredItem *);
+
+/* Supprime toutes les références externes. */
+static void g_registered_item_dispose(GRegisteredItem *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_registered_item_finalize(GRegisteredItem *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                         BASES D'OBJET POUR LE SYSTEME GLIB                         */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un élément appelable et enregistré. */
+G_DEFINE_TYPE(GRegisteredItem, g_registered_item, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des éléments appelables enregistrés.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_registered_item_class_init(GRegisteredItemClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_registered_item_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_registered_item_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item = instance à initialiser.                               *
+*                                                                             *
+*  Description : Initialise une instance d'élément appelable enregistré.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_registered_item_init(GRegisteredItem *item)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_registered_item_dispose(GRegisteredItem *item)
+{
+    G_OBJECT_CLASS(g_registered_item_parent_class)->dispose(G_OBJECT(item));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_registered_item_finalize(GRegisteredItem *item)
+{
+    G_OBJECT_CLASS(g_registered_item_parent_class)->finalize(G_OBJECT(item));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  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.            *
+*                args   = liste d'éventuels arguments fournis.                *
+*                count  = taille de cette liste.                              *
+*                last   = l'élément est-il le dernier d'une chaîne d'appels ? *
+*                final = indique une ultime conversion dans le cycle en cours.*
+*                                                                             *
+*  Description : Lance une résolution d'élément à appeler.                    *
+*                                                                             *
+*  Retour      : Nouvel élément d'appel identifié ou NULL.                    *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GRegisteredItem *g_registered_item_resolve(GRegisteredItem *item, const char *target, GScanContext *ctx, GScanExpression **args, size_t count, bool last, bool final)
+{
+    GRegisteredItem *result;                /* Instance à renvoyer         */
+    GRegisteredItemClass *class;            /* Classe à activer            */
+
+    class = G_REGISTERED_ITEM_GET_CLASS(item);
+
+    if (class->resolve == NULL)
+        result = NULL;
+    else
+        result = class->resolve(item, target, ctx, args, count, last, final);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item   = élément d'appel à consulter.                        *
+*                ctx    = contexte de suivi de l'analyse courante.            *
+*                args   = liste d'éventuels arguments fournis.                *
+*                count  = taille de cette liste.                              *
+*                final = indique une ultime conversion dans le cycle en cours.*
+*                                                                             *
+*  Description : Réduit une expression à une forme plus simple.               *
+*                                                                             *
+*  Retour      : Réduction correspondante, expression déjà réduite, ou NULL.  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanExpression *g_registered_item_reduce(GRegisteredItem *item, GScanContext *ctx, GScanExpression **args, size_t count, bool final)
+{
+    GScanExpression *result;                /* Instance à renvoyer         */
+    GRegisteredItemClass *class;            /* Classe à activer            */
+
+    class = G_REGISTERED_ITEM_GET_CLASS(item);
+
+    result = class->reduce(item, ctx, args, count, final);
+
+    return result;
+
+}
diff --git a/src/analysis/scan/item.h b/src/analysis/scan/item.h
new file mode 100644
index 0000000..e3e02e6
--- /dev/null
+++ b/src/analysis/scan/item.h
@@ -0,0 +1,63 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * item.h - prototypes pour la définition d'un élément appelable lors de l'exécution d'une règle
+ *
+ * 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 _ANALYSIS_SCAN_ITEM_H
+#define _ANALYSIS_SCAN_ITEM_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+
+
+#include "context.h"
+#include "expr.h"
+
+
+
+#define G_TYPE_REGISTERED_ITEM            g_registered_item_get_type()
+#define G_REGISTERED_ITEM(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_REGISTERED_ITEM, GRegisteredItem))
+#define G_IS_REGISTERED_ITEM(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_REGISTERED_ITEM))
+#define G_REGISTERED_ITEM_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_REGISTERED_ITEM, GRegisteredItemClass))
+#define G_IS_REGISTERED_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_REGISTERED_ITEM))
+#define G_REGISTERED_ITEM_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_REGISTERED_ITEM, GRegisteredItemClass))
+
+
+/* Expression d'évaluation généraliste (instance) */
+typedef struct _GRegisteredItem GRegisteredItem;
+
+/* Expression d'évaluation généraliste (classe) */
+typedef struct _GRegisteredItemClass GRegisteredItemClass;
+
+
+/* Indique le type défini pour un élément appelable et enregistré. */
+GType g_registered_item_get_type(void);
+
+/* Lance une résolution d'élément à appeler. */
+GRegisteredItem *g_registered_item_resolve(GRegisteredItem *, const char *, GScanContext *, GScanExpression **, size_t, bool, bool);
+
+/* Réduit une expression à une forme plus simple. */
+GScanExpression *g_registered_item_reduce(GRegisteredItem *, GScanContext *, GScanExpression **, size_t, bool);
+
+
+
+#endif  /* _ANALYSIS_SCAN_ITEM_H */
diff --git a/src/analysis/scan/match-int.h b/src/analysis/scan/match-int.h
new file mode 100644
index 0000000..9030d75
--- /dev/null
+++ b/src/analysis/scan/match-int.h
@@ -0,0 +1,56 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * match-int.h - prototypes internes pour la sauvegarde d'une correspondance identifiée de motif
+ *
+ * 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 _ANALYSIS_SCAN_MATCH_INT_H
+#define _ANALYSIS_SCAN_MATCH_INT_H
+
+
+#include "match.h"
+
+
+
+/* Affiche une correspondance sur la sortie standard. */
+typedef void (* display_scan_match_fc) (const GScanMatch *);
+
+
+/* Correspondance trouvée avec un motif (instance) */
+struct _GScanMatch
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    GSearchPattern *source;                 /* Motif d'origine recherché   */
+
+};
+
+/* Correspondance trouvée avec un motif (classe) */
+struct _GScanMatchClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+    display_scan_match_fc display;          /* Impression des résultats    */
+
+};
+
+
+
+#endif  /* _ANALYSIS_SCAN_MATCH_INT_H */
diff --git a/src/analysis/scan/match.c b/src/analysis/scan/match.c
new file mode 100644
index 0000000..c7e2a78
--- /dev/null
+++ b/src/analysis/scan/match.c
@@ -0,0 +1,177 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * match.c - sauvegarde d'une correspondance identifiée de motif
+ *
+ * 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 "match.h"
+
+
+#include "match-int.h"
+
+
+
+/* Initialise la classe des correspondances de motifs. */
+static void g_scan_match_class_init(GScanMatchClass *);
+
+/* Initialise une instance de correspondance de motif trouvée. */
+static void g_scan_match_init(GScanMatch *);
+
+/* Supprime toutes les références externes. */
+static void g_scan_match_dispose(GScanMatch *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_scan_match_finalize(GScanMatch *);
+
+
+
+/* Indique le type défini pour un correspondance de motif identifiée. */
+G_DEFINE_TYPE(GScanMatch, g_scan_match, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des correspondances de motifs.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_match_class_init(GScanMatchClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_match_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_scan_match_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : match = instance à initialiser.                              *
+*                                                                             *
+*  Description : Initialise une instance de correspondance de motif trouvée.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_match_init(GScanMatch *match)
+{
+    match->source = NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : match = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_match_dispose(GScanMatch *match)
+{
+    g_clear_object(&match->source);
+
+    G_OBJECT_CLASS(g_scan_match_parent_class)->dispose(G_OBJECT(match));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : match = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_match_finalize(GScanMatch *match)
+{
+    G_OBJECT_CLASS(g_scan_match_parent_class)->finalize(G_OBJECT(match));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : match = définition de correspondance à consulter.            *
+*                                                                             *
+*  Description : Indique la source du motif d'origine recherché.              *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GSearchPattern *g_scan_match_get_source(const GScanMatch *match)
+{
+    GSearchPattern *result;                 /* Source à retourner          */
+
+    result = match->source;
+
+    g_object_ref(G_OBJECT(result));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : match = définition de correspondance à manipuler.            *
+*                                                                             *
+*  Description : Affiche une correspondance sur la sortie standard.           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_scan_match_display(const GScanMatch *match)
+{
+    GScanMatchClass *class;                 /* Classe à activer            */
+
+    class = G_SCAN_MATCH_GET_CLASS(match);
+
+    class->display(match);
+
+}
diff --git a/src/analysis/scan/match.h b/src/analysis/scan/match.h
new file mode 100644
index 0000000..0990ae0
--- /dev/null
+++ b/src/analysis/scan/match.h
@@ -0,0 +1,61 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * match.h - prototypes pour la sauvegarde d'une correspondance identifiée de motif
+ *
+ * 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 _ANALYSIS_SCAN_MATCH_H
+#define _ANALYSIS_SCAN_MATCH_H
+
+
+#include <glib-object.h>
+
+
+#include "pattern.h"
+
+
+
+#define G_TYPE_SCAN_MATCH            g_scan_match_get_type()
+#define G_SCAN_MATCH(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_MATCH, GScanMatch))
+#define G_IS_SCAN_MATCH(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_MATCH))
+#define G_SCAN_MATCH_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_MATCH, GScanMatchClass))
+#define G_IS_SCAN_MATCH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_MATCH))
+#define G_SCAN_MATCH_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_MATCH, GScanMatchClass))
+
+
+/* Correspondance trouvée avec un motif (instance) */
+typedef struct _GScanMatch GScanMatch;
+
+/* Correspondance trouvée avec un motif (classe) */
+typedef struct _GScanMatchClass GScanMatchClass;
+
+
+/* Indique le type défini pour un correspondance de motif identifiée. */
+GType g_scan_match_get_type(void);
+
+/* Indique la source du motif d'origine recherché. */
+GSearchPattern *g_scan_match_get_source(const GScanMatch *);
+
+/* Affiche une correspondance sur la sortie standard. */
+void g_scan_match_display(const GScanMatch *);
+
+
+
+#endif  /* _ANALYSIS_SCAN_MATCH_H */
diff --git a/src/analysis/scan/matches/Makefile.am b/src/analysis/scan/matches/Makefile.am
new file mode 100644
index 0000000..d6b51c6
--- /dev/null
+++ b/src/analysis/scan/matches/Makefile.am
@@ -0,0 +1,15 @@
+
+noinst_LTLIBRARIES  = libanalysisscanmatches.la
+
+
+libanalysisscanmatches_la_SOURCES =		\
+	bytes-int.h							\
+	bytes.h bytes.c						\
+	pending.h pending.c
+
+libanalysisscanmatches_la_CFLAGS = $(LIBGOBJ_CFLAGS)
+
+
+devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
+
+dev_HEADERS = $(libanalysisscanmatches_la_SOURCES:%c=)
diff --git a/src/analysis/scan/matches/bytes-int.h b/src/analysis/scan/matches/bytes-int.h
new file mode 100644
index 0000000..c983aa3
--- /dev/null
+++ b/src/analysis/scan/matches/bytes-int.h
@@ -0,0 +1,60 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * bytes-int.h - prototypes internes pour la sauvegarde d'une correspondance identifiée de suite d'octets
+ *
+ * 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 _ANALYSIS_SCAN_MATCHES_BYTES_INT_H
+#define _ANALYSIS_SCAN_MATCHES_BYTES_INT_H
+
+
+#include "bytes.h"
+
+
+#include "../match-int.h"
+
+
+
+/* Correspondance trouvée avec une chaîne (instance) */
+struct _GBytesMatch
+{
+    GScanMatch parent;                      /* A laisser en premier        */
+
+    GBinContent *content;                   /* Contenu binaire de référence*/
+
+    phys_t start;                           /* Début du motif représenté   */
+    phys_t len;                             /* Taille du motif représenté  */
+
+};
+
+/* Correspondance trouvée avec une chaîne (classe) */
+struct _GBytesMatchClass
+{
+    GScanMatchClass parent;                 /* A laisser en premier        */
+
+};
+
+
+/* Met en place une correspondance trouvée avec un motif. */
+bool g_bytes_match_create(GBytesMatch *, GSearchPattern *, GBinContent *, phys_t, phys_t);
+
+
+
+#endif  /* _ANALYSIS_SCAN_MATCHES_BYTES_INT_H */
diff --git a/src/analysis/scan/matches/bytes.c b/src/analysis/scan/matches/bytes.c
new file mode 100644
index 0000000..90fa27d
--- /dev/null
+++ b/src/analysis/scan/matches/bytes.c
@@ -0,0 +1,286 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * bytes.h - sauvegarde d'une correspondance identifiée de suite d'octets
+ *
+ * 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 "bytes.h"
+
+
+#include <ctype.h>
+
+
+#include "bytes-int.h"
+
+
+
+/* --------------------- CORRESPONDANCE AVEC UNE SUITE D'OCTETS --------------------- */
+
+
+/* Initialise la classe des correspondances de chaînes. */
+static void g_bytes_match_class_init(GBytesMatchClass *);
+
+/* Initialise une instance de correspondance de chaîne trouvée. */
+static void g_bytes_match_init(GBytesMatch *);
+
+/* Supprime toutes les références externes. */
+static void g_bytes_match_dispose(GBytesMatch *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_bytes_match_finalize(GBytesMatch *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Affiche une correspondance sur la sortie standard. */
+static void g_bytes_match_display(const GBytesMatch *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       CORRESPONDANCE AVEC UNE SUITE D'OCTETS                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un correspondance de chaîne identifiée. */
+G_DEFINE_TYPE(GBytesMatch, g_bytes_match, G_TYPE_SCAN_MATCH);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des correspondances de chaînes.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_bytes_match_class_init(GBytesMatchClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GScanMatchClass *match;                 /* Version parente de la classe*/
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_bytes_match_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_bytes_match_finalize;
+
+    match = G_SCAN_MATCH_CLASS(klass);
+
+    match->display = (display_scan_match_fc)g_bytes_match_display;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : match = instance à initialiser.                              *
+*                                                                             *
+*  Description : Initialise une instance de correspondance de chaîne trouvée. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_bytes_match_init(GBytesMatch *match)
+{
+    match->content = NULL;
+
+    match->start = VMPA_NO_PHYSICAL;
+    match->len = VMPA_NO_PHYSICAL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : match = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_bytes_match_dispose(GBytesMatch *match)
+{
+    g_clear_object(&match->content);
+
+    G_OBJECT_CLASS(g_bytes_match_parent_class)->dispose(G_OBJECT(match));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : match = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_bytes_match_finalize(GBytesMatch *match)
+{
+    G_OBJECT_CLASS(g_bytes_match_parent_class)->finalize(G_OBJECT(match));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : source  = lien vers le motif recherché d'origine.            *
+*                content = contenu binaire présentant un motif reconnu.       *
+*                start   = position de départ d'un motif détecté.             *
+*                len     = taille du motif repéré.                            *
+*                                                                             *
+*  Description : Prend note d'une correspondance trouvée avec un motif.       *
+*                                                                             *
+*  Retour      : Correspondance mise en place.                                *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanMatch *g_bytes_match_new(GSearchPattern *source, GBinContent *content, phys_t start, phys_t len)
+{
+    GScanMatch *result;                     /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_BYTES_MATCH, NULL);
+
+    if (!g_bytes_match_create(G_BYTES_MATCH(result), source, content, start, len))
+        g_clear_object(&result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : match   = instance à initialiser pleinement.                 *
+*                source  = lien vers le motif recherché d'origine.            *
+*                content = contenu binaire présentant un motif reconnu.       *
+*                start   = position de départ d'un motif détecté.             *
+*                len     = taille du motif repéré.                            *
+*                                                                             *
+*  Description : Met en place une correspondance trouvée avec un motif.       *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_bytes_match_create(GBytesMatch *match, GSearchPattern *source, GBinContent *content, phys_t start, phys_t len)
+{
+    bool result;                            /* Bilan à retourner           */
+    GScanMatch *base;                       /* Lien vers les infos de base */
+
+    result = true;
+
+    base = G_SCAN_MATCH(match);
+
+    base->source = source;
+    g_object_ref(G_OBJECT(source));
+
+    match->content = content;
+    g_object_ref(G_OBJECT(content));
+
+    match->start = start;
+    match->len = len;
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : match = définition de correspondance à manipuler.            *
+*                                                                             *
+*  Description : Affiche une correspondance sur la sortie standard.           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_bytes_match_display(const GBytesMatch *match)
+{
+    GScanMatch *base;                       /* Lien vers les infos de base */
+    const char *name;                       /* Désignation du motif ciblé  */
+    vmpa2t pos;                             /* Tête de lecture             */
+    const bin_t *data;                      /* Accès aux données brutes    */
+    phys_t i;                               /* Boucle de parcours          */
+
+    /* Affichage d'un repère */
+
+    base = G_SCAN_MATCH(match);
+
+    name = g_search_pattern_get_name(base->source);
+
+    /**
+     * Les fonctionnalités Yara d'origine autorisent les variables anonymes '$'.
+     *
+     * Cette absence de nom est supportée ici.
+     */
+
+    if (name == NULL)
+        name = "";
+
+    printf("0x%llx:$%s: ", (unsigned long long)match->start, name);
+
+    /* Affichage du contenu */
+
+    init_vmpa(&pos, match->start, VMPA_NO_VIRTUAL);
+
+    data = g_binary_content_get_raw_access(match->content, &pos, match->len);
+
+    for (i = 0; i < match->len; i++)
+    {
+        if (isprint(data[i]))
+            printf("%c", data[i]);
+        else
+            printf("\\x%02hhx", data[i]);
+    }
+
+    printf("\n");
+
+}
diff --git a/src/analysis/scan/matches/bytes.h b/src/analysis/scan/matches/bytes.h
new file mode 100644
index 0000000..22e76a6
--- /dev/null
+++ b/src/analysis/scan/matches/bytes.h
@@ -0,0 +1,59 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * bytes.h - prototypes pour la sauvegarde d'une correspondance identifiée de suite d'octets
+ *
+ * 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 _ANALYSIS_SCAN_MATCHES_BYTES_H
+#define _ANALYSIS_SCAN_MATCHES_BYTES_H
+
+
+#include <glib-object.h>
+
+
+#include "../match.h"
+#include "../../content.h"
+
+
+
+#define G_TYPE_BYTES_MATCH            g_bytes_match_get_type()
+#define G_BYTES_MATCH(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_BYTES_MATCH, GBytesMatch))
+#define G_IS_BYTES_MATCH(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_BYTES_MATCH))
+#define G_BYTES_MATCH_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BYTES_MATCH, GBytesMatchClass))
+#define G_IS_BYTES_MATCH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BYTES_MATCH))
+#define G_BYTES_MATCH_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BYTES_MATCH, GBytesMatchClass))
+
+
+/* Correspondance trouvée avec une chaîne (instance) */
+typedef struct _GBytesMatch GBytesMatch;
+
+/* Correspondance trouvée avec une chaîne (classe) */
+typedef struct _GBytesMatchClass GBytesMatchClass;
+
+
+/* Indique le type défini pour un correspondance de chaîne identifiée. */
+GType g_bytes_match_get_type(void);
+
+/* Prend note d'une correspondance trouvée avec un motif. */
+GScanMatch *g_bytes_match_new(GSearchPattern *, GBinContent *, phys_t, phys_t);
+
+
+
+#endif  /* _ANALYSIS_SCAN_MATCHES_BYTES_H */
diff --git a/src/analysis/scan/matches/pending.c b/src/analysis/scan/matches/pending.c
new file mode 100644
index 0000000..700b868
--- /dev/null
+++ b/src/analysis/scan/matches/pending.c
@@ -0,0 +1,202 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * pending.c - consolidation de correspondances partielles
+ *
+ * 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 "pending.h"
+
+
+#include <assert.h>
+#include <malloc.h>
+#include <string.h>
+
+
+#define PENDING_ALLOC_SIZE 10
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : matches = suivi de correspondances à initialiser.            *
+*                                                                             *
+*  Description : Initialise une structure de consolidation de correspondances.*
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void init_pending_matches(pending_matches_t *matches)
+{
+    matches->areas = NULL;
+    matches->allocated = 0;
+    matches->used = 0;
+
+    matches->initialized = false;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : matches = suivi de correspondances à purger.                 *
+*                                                                             *
+*  Description : Libère la mémoire utilisée par une consolidation.            *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void exit_pending_matches(pending_matches_t *matches)
+{
+    if (matches->areas != NULL)
+        free(matches->areas);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : matches = suivi de correspondances à consulter.              *
+*                start   = point de départ d'une suite pour de correspondance.*
+*                mindex  = indice de départ et d'arrivée. [OUT]               *
+*                                                                             *
+*  Description : Détermine la zone de correspondance idéale pour complément.  *
+*                                                                             *
+*  Retour      : Bilan de l'opération : true en cas de succès des recherches. *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool find_target_in_pending_matches(pending_matches_t *matches, phys_t start, size_t *target)
+{
+    bool result;                            /* Bilan à retourner           */
+    size_t i;                               /* Boucle de parcours          */
+    match_area_t *area;                     /* Zone à initialiser          */
+
+    assert(mindex <= matches->used);
+
+    result = false;
+
+    for (i = *target; i < matches->used; i++)
+    {
+        area = &matches->areas[i];
+
+        if ((area->start + area->length) == start)
+        {
+            *target = i;
+            result = true;
+            break;
+        }
+
+    }
+
+    return result;
+
+}
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : matches = suivi de correspondances à compléter.              *
+*                start   = point de départ d'une nouvelle correspondance.     *
+*                length  = taille de la zone couverte.                        *
+*                                                                             *
+*  Description : Ajoute au suivi la définition d'une nouvelle correspondance. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void add_pending_matches(pending_matches_t *matches, phys_t start, phys_t length)
+{
+    match_area_t *area;                     /* Zone à initialiser          */
+
+    if (matches->used == matches->allocated)
+    {
+        matches->allocated += PENDING_ALLOC_SIZE;
+
+        matches->areas = realloc(matches->areas, matches->allocated * sizeof(match_area_t));
+
+    }
+
+    area = &matches->areas[matches->used++];
+
+    area->start = start;
+    area->length = length;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : matches = suivi de correspondances à compléter.              *
+*                target  = indice de la zone de correspondance concernée.     *
+*                length  = taille de la zone couverte supplémentaire.         *
+*                                                                             *
+*  Description : Etend une zone couverte dans le suivi des correspondances.   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void extend_pending_matches(pending_matches_t *matches, size_t target, phys_t length)
+{
+    assert(target < matches->used);
+
+    matches->areas[target].length += length;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : matches = suivi de correspondances à modifier.               *
+*                target  = indice de la zone de correspondance concernée.     *
+*                                                                             *
+*  Description : Retire une correspondance finalement non établie du suivi.   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void remove_pending_matches(pending_matches_t *matches, size_t target)
+{
+    assert(target < matches->used);
+
+    if ((target + 1) < matches->used)
+        memmove(&matches->areas[target], &matches->areas[target + 1],
+                (matches->used - target - 1) * sizeof(match_area_t));
+
+    matches->used--;
+
+}
diff --git a/src/analysis/scan/matches/pending.h b/src/analysis/scan/matches/pending.h
new file mode 100644
index 0000000..de2fd5f
--- /dev/null
+++ b/src/analysis/scan/matches/pending.h
@@ -0,0 +1,76 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * pending.h - prototypes pour la consolidation de correspondances partielles
+ *
+ * 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_MATCHES_PENDING_H
+#define _ANALYSIS_SCAN_MATCHES_PENDING_H
+
+
+#include "../../content.h"
+
+
+
+/* Couverture d'une correspondance */
+typedef struct _match_area_t
+{
+    phys_t start;                           /* Point de départ             */
+    phys_t length;                          /* Taille de la zone couverte  */
+
+} match_area_t;
+
+/* Suivi de correspondances */
+typedef struct _pending_matches_t
+{
+    match_area_t *areas;                    /* Zones couvertes             */
+    size_t allocated;                       /* Nombre d'allocations        */
+    size_t used;                            /* Nombre de zones             */
+
+    bool initialized;                       /* Etat du suivi               */
+
+} pending_matches_t;
+
+
+/* Initialise une structure de consolidation de correspondances. */
+void init_pending_matches(pending_matches_t *);
+
+/* Libère la mémoire utilisée par une consolidation. */
+void exit_pending_matches(pending_matches_t *);
+
+#define are_pending_matches_initialized(pm) pm->initialized
+
+#define set_pending_matches_initialized(pm) pm->initialized = true
+
+/* Détermine la zone de correspondance idéale pour complément. */
+bool find_target_in_pending_matches(pending_matches_t *, phys_t, size_t *);
+
+/*  Ajoute au suivi la définition d'une nouvelle correspondance. */
+void add_pending_matches(pending_matches_t *, phys_t, phys_t);
+
+/* Etend une zone couverte dans le suivi des correspondances. */
+void extend_pending_matches(pending_matches_t *, size_t, phys_t);
+
+/* Retire une correspondance finalement non établie du suivi. */
+void remove_pending_matches(pending_matches_t *, size_t);
+
+
+
+#endif  /* _ANALYSIS_SCAN_MATCHES_PENDING_H */
diff --git a/src/analysis/scan/options-int.h b/src/analysis/scan/options-int.h
new file mode 100644
index 0000000..a7772ed
--- /dev/null
+++ b/src/analysis/scan/options-int.h
@@ -0,0 +1,52 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * options-int.h - prototypes internes pour le rassemblement des options d'analyse communiquées par le donneur d'ordre
+ *
+ * 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_OPTIONS_INT_H
+#define _ANALYSIS_SCAN_OPTIONS_INT_H
+
+
+#include "options.h"
+
+
+
+/* Rassemblement d'options d'analyses (instance) */
+struct _GScanOptions
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    GType data_backend;                     /* Choix du moteur d'analyse   */
+
+    bool print_stats;                       /* Affichage de statistiques ? */
+
+};
+
+/* Rassemblement d'options d'analyses (classe) */
+struct _GScanOptionsClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+};
+
+
+
+#endif  /* _ANALYSIS_SCAN_OPTIONS_INT_H */
diff --git a/src/analysis/scan/options.c b/src/analysis/scan/options.c
new file mode 100644
index 0000000..89e411e
--- /dev/null
+++ b/src/analysis/scan/options.c
@@ -0,0 +1,238 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * options.c - rassemblement des options d'analyse communiquées par le donneur d'ordre
+ *
+ * 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 "options.h"
+
+
+#include "options-int.h"
+
+
+
+/* Initialise la classe des ensembles d'options d'analyses. */
+static void g_scan_options_class_init(GScanOptionsClass *);
+
+/* Initialise une instance de groupe d'options d'analyse. */
+static void g_scan_options_init(GScanOptions *);
+
+/* Supprime toutes les références externes. */
+static void g_scan_options_dispose(GScanOptions *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_scan_options_finalize(GScanOptions *);
+
+
+
+/* Indique le type défini pour un ensemble d'options d'analyses. */
+G_DEFINE_TYPE(GScanOptions, g_scan_options, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des ensembles d'options d'analyses.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_options_class_init(GScanOptionsClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_options_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_scan_options_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : options = instance à initialiser.                            *
+*                                                                             *
+*  Description : Initialise une instance de groupe d'options d'analyse.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_options_init(GScanOptions *options)
+{
+    options->data_backend = G_TYPE_INVALID;
+
+    options->print_stats = false;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : options = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_options_dispose(GScanOptions *options)
+{
+    G_OBJECT_CLASS(g_scan_options_parent_class)->dispose(G_OBJECT(options));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : options = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_options_finalize(GScanOptions *options)
+{
+    G_OBJECT_CLASS(g_scan_options_parent_class)->finalize(G_OBJECT(options));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Crée un réceptacle pour diverses options d'analyse.          *
+*                                                                             *
+*  Retour      : Point de collecte mise en place.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanOptions *g_scan_options_new(void)
+{
+    GScanOptions *result;                   /* Instance à retourner        */
+
+    result = g_object_new(G_TYPE_SCAN_OPTIONS, NULL);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : options = ensemble d'options d'analyses à consulter.         *
+*                                                                             *
+*  Description : Indique le type d'un moteur d'analyse de données sélectionné.*
+*                                                                             *
+*  Retour      : Type d'objet, idéalement valide.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GType g_scan_options_get_backend_for_data(const GScanOptions *options)
+{
+    GType result;                           /* Type à retourner            */
+
+    result = options->data_backend;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : options = ensemble d'options d'analyses à modifier.          *
+*                backend = type du moteur sélectionné.                        *
+*                                                                             *
+*  Description : Sélectionne un type de moteur d'analyse pour données brutes. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_scan_options_set_backend_for_data(GScanOptions *options, GType backend)
+{
+    options->data_backend = backend;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : options = ensemble d'options d'analyses à consulter.         *
+*                                                                             *
+*  Description : Indique un besoin de statistiques en fin de compilation.     *
+*                                                                             *
+*  Retour      : Etat de l'option visée à conservé.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_scan_options_get_print_stats(const GScanOptions *options)
+{
+    bool result;                            /* Statut à retourner          */
+
+    result = options->print_stats;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : options = ensemble d'options d'analyses à modifier.          *
+*                state   = état de l'option visée à conserver.                *
+*                                                                             *
+*  Description : Mémorise un besoin de statistiques en fin de compilation.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_scan_options_set_print_stats(GScanOptions *options, bool state)
+{
+    options->print_stats = state;
+
+}
diff --git a/src/analysis/scan/options.h b/src/analysis/scan/options.h
new file mode 100644
index 0000000..a7931c5
--- /dev/null
+++ b/src/analysis/scan/options.h
@@ -0,0 +1,68 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * options.h - prototypes pour le rassemblement des options d'analyse communiquées par le donneur d'ordre
+ *
+ * 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_OPTIONS_H
+#define _ANALYSIS_SCAN_OPTIONS_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+
+
+
+#define G_TYPE_SCAN_OPTIONS            g_scan_options_get_type()
+#define G_SCAN_OPTIONS(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_OPTIONS, GScanOptions))
+#define G_IS_SCAN_OPTIONS(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_OPTIONS))
+#define G_SCAN_OPTIONS_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_OPTIONS, GScanOptionsClass))
+#define G_IS_SCAN_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_OPTIONS))
+#define G_SCAN_OPTIONS_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_OPTIONS, GScanOptionsClass))
+
+
+/* Rassemblement d'options d'analyses (instance) */
+typedef struct _GScanOptions GScanOptions;
+
+/* Rassemblement d'options d'analyses (classe) */
+typedef struct _GScanOptionsClass GScanOptionsClass;
+
+
+/* Indique le type défini pour un ensemble d'options d'analyses. */
+GType g_scan_options_get_type(void);
+
+/* Crée un réceptacle pour diverses options d'analyse. */
+GScanOptions *g_scan_options_new(void);
+
+/* Indique le type d'un moteur d'analyse de données sélectionné. */
+GType g_scan_options_get_backend_for_data(const GScanOptions *);
+
+/* Sélectionne un type de moteur d'analyse pour données brutes. */
+void g_scan_options_set_backend_for_data(GScanOptions *, GType);
+
+/* Indique un besoin de statistiques en fin de compilation. */
+bool g_scan_options_get_print_stats(const GScanOptions *);
+
+/* Mémorise un besoin de statistiques en fin de compilation. */
+void g_scan_options_set_print_stats(GScanOptions *, bool);
+
+
+
+#endif  /* _ANALYSIS_SCAN_OPTIONS_H */
diff --git a/src/analysis/scan/pattern-int.h b/src/analysis/scan/pattern-int.h
new file mode 100644
index 0000000..03af30f
--- /dev/null
+++ b/src/analysis/scan/pattern-int.h
@@ -0,0 +1,56 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * pattern-int.h - prototypes internes pour la définition de motif à rechercher
+ *
+ * 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 _ANALYSIS_SCAN_PATTERN_INT_H
+#define _ANALYSIS_SCAN_PATTERN_INT_H
+
+
+#include "pattern.h"
+
+
+
+/* Décompte le nombre de correspondances identifiées. */
+typedef size_t (* count_pattern_matchs_fc) (const GSearchPattern *);
+
+
+/* Motif à rechercher au sein d'un contenu (instance) */
+struct _GSearchPattern
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    char *name;                             /* Eventuelle désignation      */
+
+};
+
+/* Motif à rechercher au sein d'un contenu (classe) */
+struct _GSearchPatternClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+    count_pattern_matchs_fc count;          /* Décompte des résultats      */
+
+};
+
+
+
+#endif  /* _ANALYSIS_SCAN_PATTERN_INT_H */
diff --git a/src/analysis/scan/pattern.c b/src/analysis/scan/pattern.c
new file mode 100644
index 0000000..53a2662
--- /dev/null
+++ b/src/analysis/scan/pattern.c
@@ -0,0 +1,210 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * pattern.c - définition de motif à localiser dans du contenu binaire
+ *
+ * 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 "pattern.h"
+
+
+#include <malloc.h>
+#include <string.h>
+
+
+#include "pattern-int.h"
+
+
+
+/* Initialise la classe des motifs à localiser dans du binaire. */
+static void g_search_pattern_class_init(GSearchPatternClass *);
+
+/* Initialise une instance de motif à localiser dans du binaire. */
+static void g_search_pattern_init(GSearchPattern *);
+
+/* Supprime toutes les références externes. */
+static void g_search_pattern_dispose(GSearchPattern *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_search_pattern_finalize(GSearchPattern *);
+
+
+
+/* Indique le type défini pour un motif à localiser. */
+G_DEFINE_TYPE(GSearchPattern, g_search_pattern, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des motifs à localiser dans du binaire. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_search_pattern_class_init(GSearchPatternClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_search_pattern_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_search_pattern_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : pattern = instance à initialiser.                            *
+*                                                                             *
+*  Description : Initialise une instance de motif à localiser dans du binaire.*
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_search_pattern_init(GSearchPattern *pattern)
+{
+    pattern->name = NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : pattern = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_search_pattern_dispose(GSearchPattern *pattern)
+{
+    G_OBJECT_CLASS(g_search_pattern_parent_class)->dispose(G_OBJECT(pattern));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : pattern = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_search_pattern_finalize(GSearchPattern *pattern)
+{
+    if (pattern->name != NULL)
+        free(pattern->name);
+
+    G_OBJECT_CLASS(g_search_pattern_parent_class)->finalize(G_OBJECT(pattern));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : pattern = définition de motif à consulter.                   *
+*                                                                             *
+*  Description : Fournit la désignation attribuée à un motif de recherche.    *
+*                                                                             *
+*  Retour      : Eventuelle étiquette associée ou NULL.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+const char *g_search_pattern_get_name(const GSearchPattern *pattern)
+{
+    char *result;                           /* Désignation à retourner     */
+
+    result = pattern->name;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : pattern = définition de motif à consulter.                   *
+*                name    = désignation en tant que variable locale.           *
+*                len     = taille de cette désignation.                       *
+*                                                                             *
+*  Description : Inscrit la désignation attribuée à un motif de recherche.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_search_pattern_set_name(GSearchPattern *pattern, const char *name, size_t len)
+{
+    if (pattern->name != NULL)
+        free(pattern->name);
+
+    if (name == NULL)
+        pattern->name = NULL;
+    else
+        pattern->name = strndup(name, len);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : pattern = définition de motif à consulter.                   *
+*                                                                             *
+*  Description : Décompte le nombre de correspondances identifiées.           *
+*                                                                             *
+*  Retour      : Quantité d'identifications réalisées.                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+size_t g_search_pattern_count_matchs(const GSearchPattern *pattern)
+{
+    size_t result;                          /* Décompte à retourner        */
+    GSearchPatternClass *class;             /* Classe à activer            */
+
+    class = G_SEARCH_PATTERN_GET_CLASS(pattern);
+
+    result = 0;//class->count(pattern);
+
+    return result;
+
+}
diff --git a/src/analysis/scan/pattern.h b/src/analysis/scan/pattern.h
new file mode 100644
index 0000000..9ea66d3
--- /dev/null
+++ b/src/analysis/scan/pattern.h
@@ -0,0 +1,65 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * pattern.h - prototypes pour la définition de motif à localiser dans du contenu binaire
+ *
+ * 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 _ANALYSIS_SCAN_PATTERN_H
+#define _ANALYSIS_SCAN_PATTERN_H
+
+
+#include <glib-object.h>
+
+
+#include "../../arch/archbase.h"
+#include "../../arch/vmpa.h"
+
+
+
+#define G_TYPE_SEARCH_PATTERN            g_search_pattern_get_type()
+#define G_SEARCH_PATTERN(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SEARCH_PATTERN, GSearchPattern))
+#define G_IS_SEARCH_PATTERN(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SEARCH_PATTERN))
+#define G_SEARCH_PATTERN_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SEARCH_PATTERN, GSearchPatternClass))
+#define G_IS_SEARCH_PATTERN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SEARCH_PATTERN))
+#define G_SEARCH_PATTERN_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SEARCH_PATTERN, GSearchPatternClass))
+
+
+/* Motif à rechercher au sein d'un contenu (instance) */
+typedef struct _GSearchPattern GSearchPattern;
+
+/* Motif à rechercher au sein d'un contenu (classe) */
+typedef struct _GSearchPatternClass GSearchPatternClass;
+
+
+/* Indique le type défini pour un motif à localiser. */
+GType g_search_pattern_get_type(void);
+
+/* Fournit la désignation attribuée à un motif de recherche. */
+const char *g_search_pattern_get_name(const GSearchPattern *);
+
+/* Inscrit la désignation attribuée à un motif de recherche. */
+void g_search_pattern_set_name(GSearchPattern *, const char *, size_t);
+
+/* Décompte le nombre de correspondances identifiées. */
+size_t g_search_pattern_count_matchs(const GSearchPattern *);
+
+
+
+#endif  /* _ANALYSIS_SCAN_PATTERN_H */
diff --git a/src/analysis/scan/patterns/Makefile.am b/src/analysis/scan/patterns/Makefile.am
new file mode 100644
index 0000000..4082275
--- /dev/null
+++ b/src/analysis/scan/patterns/Makefile.am
@@ -0,0 +1,23 @@
+
+noinst_LTLIBRARIES  = libanalysisscanpatterns.la
+
+
+libanalysisscanpatterns_la_SOURCES =		\
+	backend-int.h							\
+	backend.h backend.c						\
+	token-int.h								\
+	token.h token.c
+
+libanalysisscanpatterns_la_LIBADD = 		\
+	backends/libanalysisscanpatternsbackends.la \
+	tokens/libanalysisscanpatternstokens.la
+
+libanalysisscanpatterns_la_CFLAGS = $(LIBGOBJ_CFLAGS)
+
+
+devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
+
+dev_HEADERS = $(libanalysisscanpatterns_la_SOURCES:%c=)
+
+
+SUBDIRS = backends tokens
diff --git a/src/analysis/scan/patterns/backend-int.h b/src/analysis/scan/patterns/backend-int.h
new file mode 100644
index 0000000..698ba5f
--- /dev/null
+++ b/src/analysis/scan/patterns/backend-int.h
@@ -0,0 +1,70 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * backend-int.h - prototypes internes pour une méthode de recherches au sein d'un contenu binaire
+ *
+ * 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 _ANALYSIS_SCAN_PATTERNS_BACKEND_INT_H
+#define _ANALYSIS_SCAN_PATTERNS_BACKEND_INT_H
+
+
+#include "backend.h"
+
+
+
+/* Indique la taille maximale des suites d'octets recherchées. */
+typedef size_t (* get_backend_atom_max_size_fc) (const GEngineBackend *);
+
+/* Inscrit dans le moteur une chaîne de caractères à rechercher. */
+typedef patid_t (* enroll_plain_into_backend_fc) (GEngineBackend *, GScanContext *, const uint8_t *, size_t);
+
+/* Met en ordre les derniers détails avant un premier scan. */
+typedef void (* warm_up_backend_fc) (GEngineBackend *);
+
+/* Parcours un contenu binaire à la recherche de motifs. */
+typedef void (* run_backend_scan_fc) (const GEngineBackend *, GScanContext *, GBinContent *);
+
+/* Imprime quelques faits quant aux éléments mis en place. */
+typedef void (* output_backend_stats_fc) (const GEngineBackend *);
+
+
+/* Méthode de traitement d'un contenu binaire pour recherches (instance) */
+struct _GEngineBackend
+{
+    GObject parent;                         /* A laisser en premier        */
+
+};
+
+/* Méthode de traitement d'un contenu binaire pour recherches (classe) */
+struct _GEngineBackendClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+    get_backend_atom_max_size_fc get_max_size;  /* Taille maximale d'atome */
+    enroll_plain_into_backend_fc enroll_plain;  /* Inscription simple      */
+    warm_up_backend_fc warm_up;             /* Préchauffage avant analyse  */
+    run_backend_scan_fc run_scan;           /* Lancement d'une analyse     */
+    output_backend_stats_fc output;         /* Impression de statistiques  */
+
+};
+
+
+
+#endif  /* _ANALYSIS_SCAN_PATTERNS_BACKEND_INT_H */
diff --git a/src/analysis/scan/patterns/backend.c b/src/analysis/scan/patterns/backend.c
new file mode 100644
index 0000000..800d0aa
--- /dev/null
+++ b/src/analysis/scan/patterns/backend.c
@@ -0,0 +1,254 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * backend.c - méthode de recherches au sein d'un contenu binaire
+ *
+ * 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 "backend.h"
+
+
+#include "backend-int.h"
+
+
+
+/* Initialise la classe des méthodes de recherche pour binaire. */
+static void g_engine_backend_class_init(GEngineBackendClass *);
+
+/* Initialise une instance de méthode de recherche pour binaire. */
+static void g_engine_backend_init(GEngineBackend *);
+
+/* Supprime toutes les références externes. */
+static void g_engine_backend_dispose(GEngineBackend *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_engine_backend_finalize(GEngineBackend *);
+
+
+
+/* Indique le type défini pour une méthode de recherche dans du binaire. */
+G_DEFINE_TYPE(GEngineBackend, g_engine_backend, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des méthodes de recherche pour binaire. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_engine_backend_class_init(GEngineBackendClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_engine_backend_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_engine_backend_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = instance à initialiser.                            *
+*                                                                             *
+*  Description : Initialise une instance de méthode de recherche pour binaire.*
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_engine_backend_init(GEngineBackend *backend)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_engine_backend_dispose(GEngineBackend *backend)
+{
+    G_OBJECT_CLASS(g_engine_backend_parent_class)->dispose(G_OBJECT(backend));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_engine_backend_finalize(GEngineBackend *backend)
+{
+    G_OBJECT_CLASS(g_engine_backend_parent_class)->finalize(G_OBJECT(backend));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à consulter.                   *
+*                                                                             *
+*  Description : Indique la taille maximale des suites d'octets recherchées.  *
+*                                                                             *
+*  Retour      : Valeur strictement positive.                                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+size_t g_engine_backend_get_atom_max_size(const GEngineBackend *backend)
+{
+    size_t result;                          /* Taille à faire connaître    */
+    GEngineBackendClass *class;             /* Classe à activer            */
+
+    class = G_ENGINE_BACKEND_GET_CLASS(backend);
+
+    result = class->get_max_size(backend);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à manipuler.                   *
+*                context = contexte de l'analyse à mener.                     *
+*                plain   = chaîne de caractères classique à intégrer.         *
+*                len     = taille de cette chaîne.                            *
+*                                                                             *
+*  Description : Inscrit dans le moteur une chaîne de caractères à rechercher.*
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+patid_t g_engine_backend_enroll_plain_pattern(GEngineBackend *backend, GScanContext *context, const uint8_t *plain, size_t len)
+{
+    patid_t result;                         /* Identifiant à retourner     */
+    GEngineBackendClass *class;             /* Classe à activer            */
+
+    class = G_ENGINE_BACKEND_GET_CLASS(backend);
+
+    result = class->enroll_plain(backend, context, plain, len);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à préparer.                    *
+*                                                                             *
+*  Description : Met en ordre les derniers détails avant un premier scan.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_engine_backend_warm_up(GEngineBackend *backend)
+{
+    GEngineBackendClass *class;             /* Classe à activer            */
+
+    class = G_ENGINE_BACKEND_GET_CLASS(backend);
+
+    if (class->warm_up != NULL)
+        class->warm_up(backend);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à manipuler.                   *
+*                context = lieu d'enregistrement des résultats.               *
+*                content = données binaires à analyser.                       *
+*                                                                             *
+*  Description : Parcours un contenu binaire à la recherche de motifs.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_engine_backend_run_scan(const GEngineBackend *backend, GScanContext *context, GBinContent *content)
+{
+    GEngineBackendClass *class;             /* Classe à activer            */
+
+    class = G_ENGINE_BACKEND_GET_CLASS(backend);
+
+    class->run_scan(backend, context, content);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à consulter.                   *
+*                                                                             *
+*  Description : Imprime quelques faits quant aux éléments mis en place.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_engine_backend_output_stats(const GEngineBackend *backend)
+{
+    GEngineBackendClass *class;             /* Classe à activer            */
+
+    class = G_ENGINE_BACKEND_GET_CLASS(backend);
+
+    if (class->output != NULL)
+        class->output(backend);
+
+}
diff --git a/src/analysis/scan/patterns/backend.h b/src/analysis/scan/patterns/backend.h
new file mode 100644
index 0000000..700366e
--- /dev/null
+++ b/src/analysis/scan/patterns/backend.h
@@ -0,0 +1,73 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * backend.h - prototypes pour une méthode de recherches au sein d'un contenu binaire
+ *
+ * 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 _ANALYSIS_SCAN_PATTERNS_BACKEND_H
+#define _ANALYSIS_SCAN_PATTERNS_BACKEND_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+
+#include "../context.h"
+#include "../../content.h"
+
+
+
+#define G_TYPE_ENGINE_BACKEND            g_engine_backend_get_type()
+#define G_ENGINE_BACKEND(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ENGINE_BACKEND, GEngineBackend))
+#define G_IS_ENGINE_BACKEND(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ENGINE_BACKEND))
+#define G_ENGINE_BACKEND_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ENGINE_BACKEND, GEngineBackendClass))
+#define G_IS_ENGINE_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ENGINE_BACKEND))
+#define G_ENGINE_BACKEND_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ENGINE_BACKEND, GEngineBackendClass))
+
+
+/* Méthode de traitement d'un contenu binaire pour recherches (instance) */
+typedef struct _GEngineBackend GEngineBackend;
+
+/* Méthode de traitement d'un contenu binaire pour recherches (classe) */
+typedef struct _GEngineBackendClass GEngineBackendClass;
+
+
+/* Indique le type défini pour une méthode de recherche dans du binaire. */
+GType g_engine_backend_get_type(void);
+
+/* Indique la taille maximale des suites d'octets recherchées. */
+size_t g_engine_backend_get_atom_max_size(const GEngineBackend *);
+
+/* Inscrit dans le moteur une chaîne de caractères à rechercher. */
+patid_t g_engine_backend_enroll_plain_pattern(GEngineBackend *, GScanContext *, const uint8_t *, size_t);
+
+/* Met en ordre les derniers détails avant un premier scan. */
+void g_engine_backend_warm_up(GEngineBackend *);
+
+/* Parcours un contenu binaire à la recherche de motifs. */
+void g_engine_backend_run_scan(const GEngineBackend *, GScanContext *, GBinContent *);
+
+/* Imprime quelques faits quant aux éléments mis en place. */
+void g_engine_backend_output_stats(const GEngineBackend *);
+
+
+
+#endif  /* _ANALYSIS_SCAN_PATTERNS_BACKEND_H */
diff --git a/src/analysis/scan/patterns/backends/Makefile.am b/src/analysis/scan/patterns/backends/Makefile.am
new file mode 100644
index 0000000..672b7ff
--- /dev/null
+++ b/src/analysis/scan/patterns/backends/Makefile.am
@@ -0,0 +1,27 @@
+
+noinst_LTLIBRARIES  = libanalysisscanpatternsbackends.la
+
+
+libanalysisscanpatternsbackends_la_SOURCES =	\
+	acism-int.h								\
+	acism.h acism.c							\
+	bitap-int.h								\
+	bitap.h bitap.c
+
+# Cf. https://www.gnu.org/software/automake/manual/html_node/Per_002dObject-Flags.html
+
+AM_CFLAGS = $(LIBGOBJ_CFLAGS)
+
+
+
+#AM_CFLAGS:=$(filter-out -O2,$(AM_CFLAGS))
+
+
+#bitap.lo: AM_CFLAGS += -Ofast -march=native -falign-functions=1 -falign-jumps=1 -falign-loops=1 -falign-labels=1 #-mavx512bw
+#bitap.lo: AM_CFLAGS += -O3 -march=native -falign-functions=1 -falign-jumps=1 -falign-loops=1 -falign-labels=1 #-mavx512bw
+bitap.lo: AM_CFLAGS += -g -march=native -mno-vzeroupper -falign-functions=1 -falign-jumps=1 -falign-loops=1 -falign-labels=1
+
+
+devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
+
+dev_HEADERS = $(libanalysisscanpatternsbackends_la_SOURCES:%c=)
diff --git a/src/analysis/scan/patterns/backends/acism-int.h b/src/analysis/scan/patterns/backends/acism-int.h
new file mode 100644
index 0000000..57c3c73
--- /dev/null
+++ b/src/analysis/scan/patterns/backends/acism-int.h
@@ -0,0 +1,160 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * acism-int.h - prototypes internes pour la méthode de recherche basée sur l'algorithme Aho-Corasick Interleaved State-transition Matrix
+ *
+ * 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 _ANALYSIS_SCAN_PATTERNS_BACKENDS_ACISM_INT_H
+#define _ANALYSIS_SCAN_PATTERNS_BACKENDS_ACISM_INT_H
+
+
+#include "acism.h"
+
+
+#include <stdint.h>
+
+
+#include "../backend-int.h"
+#include "../../../../common/bits.h"
+
+
+
+//#define __USE_BYTE_FREQ
+//#define __SORT_BEFORE_BITMASK
+
+
+#define ACSIM_ATOM_SIZE 7
+
+
+
+/* Définition d'une portion de cible */
+typedef struct _acism_source_t
+{
+    const uint8_t *atoms;                   /* Motif remarquable           */
+    size_t len;                             /* Nombre d'octets considérés  */
+
+    patid_t pid;                            /* Identifiant de suivi        */
+
+} acism_source_t;
+
+/* Etude de la fréquence des octets pour attribution des codes */
+typedef struct _acism_freq_rank_t
+{
+    unsigned int frequency;                 /* Occurrences d'un octet      */
+    uint8_t rank;                           /* Valeur dudit octet          */
+
+} acism_freq_rank_t;
+
+/* Identifiant unique pour une valeur 8 bits donnée (max 257) */
+typedef uint16_t acism_code_t;
+
+#define MIN_ACISM_CODE 0
+#define MAX_ACISM_CODE 0xffff
+
+/* Noeud de l'arborescence brute */
+typedef struct _acism_trie_node_t
+{
+    struct _acism_trie_node_t *parent;      /* Noeud parent pour remontée  */
+    struct _acism_trie_node_t *sibling;     /* Noeud de même niveau suivant*/
+    struct _acism_trie_node_t *child;       /* Noeud de lecture suivant    */
+    struct _acism_trie_node_t *suffix_link; /* Retour en cas d'échec       */
+
+    bin_t data;                             /* Donnée brute représentée    */
+    acism_code_t code;                      /* Identifiant du noeud        */
+
+    patid_t pid;                            /* Identifiant de suivi        */
+
+    acism_code_t min_child_code;            /* Plus petit code suivant     */
+    acism_code_t max_child_code;            /* Plus grand code suivant     */
+    size_t children_count;                  /* Nombre de codes suivants    */
+
+    size_t matched_atom;                    /* Indice de correspondance    */
+
+    size_t state_index;                     /* Indice de le tableau final  */
+
+} acism_trie_node_t;
+
+/* Cellule du tableau compressé final */
+typedef union _acism_state_t
+{
+    uint32_t raw;                           /* Valeur brute                */
+
+    struct
+    {
+        union
+        {
+            /* Indice 0 */
+            struct
+            {
+                unsigned int match : 1;     /* Correspondance ici          */
+                unsigned int suffix : 1;    /* Correspondance ailleurs     */
+                unsigned int unused : 4;    /* Espace encore disponible    */
+                unsigned int atom_size : 3; /* Taille d'atome représenté   */
+            };
+
+            /* Indice 1 et + */
+            unsigned int code : 9;          /* Position depuis la base     */
+
+        };
+
+        unsigned int index : 23;            /* Indice de saut              */
+
+    };
+
+} acism_state_t;
+
+/* Méthode de recherche basée sur l'algorithme Acism (instance) */
+struct _GAcismBackend
+{
+    GEngineBackend parent;                  /* A laisser en premier        */
+
+#ifdef __USE_BYTE_FREQ
+    acism_code_t codes_for_bytes[256];      /* Traduction octets -> codes  */
+    acism_code_t codes_count;               /* Quantité de traductions     */
+#endif
+
+    acism_source_t *sources;                /* Liste de motifs remarquables*/
+    size_t sources_count;                   /* Quantité de ces motifs      */
+
+    size_t nchars;                          /* Taille cumulée des motifs   */
+
+#ifdef __USE_BYTE_FREQ
+    acism_freq_rank_t frequencies[256];     /* Fréquences des octets       */
+#endif
+
+    acism_trie_node_t *nodes;               /* Liste de noeuds             */
+    size_t nodes_used;                      /* Nombre de noeuds utilisés   */
+
+    bitfield_t *bitmap_usage;               /* Localisation des usages     */
+    acism_state_t *states;                  /* Tableau de transitions      */
+    patid_t *pids;                          /* Identifiants de motifs      */
+
+};
+
+/* Méthode de recherche basée sur l'algorithme Acism (classe) */
+struct _GAcismBackendClass
+{
+    GEngineBackendClass parent;             /* A laisser en premier        */
+
+};
+
+
+
+#endif  /* _ANALYSIS_SCAN_PATTERNS_BACKENDS_ACISM_INT_H */
diff --git a/src/analysis/scan/patterns/backends/acism.c b/src/analysis/scan/patterns/backends/acism.c
new file mode 100644
index 0000000..12339f2
--- /dev/null
+++ b/src/analysis/scan/patterns/backends/acism.c
@@ -0,0 +1,1295 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * acism.c - méthode de recherche basée sur l'algorithme Aho-Corasick Interleaved State-transition Matrix
+ *
+ * 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 "acism.h"
+
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#include "acism-int.h"
+#include "../../../../common/sort.h"
+
+
+
+/* ---------------------- IMPLANTATION D'UNE NOUVELLE APPROCHE ---------------------- */
+
+
+/* Initialise la classe des méthodes basée sur Bitmap. */
+static void g_acism_backend_class_init(GAcismBackendClass *);
+
+/* Initialise une instance de méthodes basée sur Bitmap. */
+static void g_acism_backend_init(GAcismBackend *);
+
+/* Supprime toutes les références externes. */
+static void g_acism_backend_dispose(GAcismBackend *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_acism_backend_finalize(GAcismBackend *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Indique la taille maximale des suites d'octets recherchées. */
+size_t g_acism_backend_get_atom_max_size(const GAcismBackend *);
+
+/* Intègre un motif limité de contenu à rechercher. */
+static patid_t g_acism_backend_setup_for(GAcismBackend *, GScanContext *, const uint8_t *, size_t);
+
+/* Inscrit dans le moteur une chaîne de caractères à rechercher. */
+static patid_t g_acism_backend_enroll_plain_pattern(GAcismBackend *, GScanContext *, const uint8_t *, size_t);
+
+#ifdef __USE_BYTE_FREQ
+
+/* Compare un niveau de fréquence avec un autre. */
+static int compare_byte_frequencies(const acism_freq_rank_t *, const acism_freq_rank_t *);
+
+/* Détermine les identifiants de chaque valeur 8 bits utile. */
+static void g_acism_backend_define_codes(GAcismBackend *);
+
+#endif
+
+/* Construit l'arborescence de noeuds de lecture. */
+static void g_acism_backend_build_trie(GAcismBackend *);
+
+/* Construit l'arborescence de noeuds de lecture. */
+static void g_acism_backend_build_suffix_links(GAcismBackend *);
+
+#ifdef __SORT_BEFORE_BITMASK
+
+/* Compare des noeuds selon l'espace de codes couvert. */
+static int compare_node_according_to_code_range(const acism_trie_node_t **, const acism_trie_node_t **);
+
+#endif
+
+/* Organise la convertion de l'arborescence en tableau. */
+static void g_acism_backend_prepare_interleave_array(GAcismBackend *);
+
+/* Compresse l'arborescence dans un tableau de position. */
+static void g_acism_backend_build_interleave_array(GAcismBackend *);
+
+/* Met en ordre les derniers détails avant un premier scan. */
+static void g_acism_backend_warm_up(GAcismBackend *);
+
+/* Parcours un contenu binaire à la recherche de motifs. */
+static void g_acism_backend_run_scan(const GAcismBackend *, GScanContext *, GBinContent *);
+
+/* Affiche les caractéristques d'un noeud et de ses enfants. */
+static void visit_and_output_node(const acism_trie_node_t *, unsigned int);
+
+/* Imprime quelques faits quant aux éléments mis en place. */
+static void g_acism_backend_output_stats(const GAcismBackend *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                        IMPLANTATION D'UNE NOUVELLE APPROCHE                        */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un moteur de recherche pour données. */
+G_DEFINE_TYPE(GAcismBackend, g_acism_backend, G_TYPE_ENGINE_BACKEND);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des méthodes basée sur Bitmap.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_acism_backend_class_init(GAcismBackendClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GEngineBackendClass *backend;           /* Version de classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_acism_backend_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_acism_backend_finalize;
+
+    backend = G_ENGINE_BACKEND_CLASS(klass);
+
+    backend->get_max_size = (get_backend_atom_max_size_fc)g_acism_backend_get_atom_max_size;
+    backend->enroll_plain = (enroll_plain_into_backend_fc)g_acism_backend_enroll_plain_pattern;
+    backend->warm_up = (warm_up_backend_fc)g_acism_backend_warm_up;
+    backend->run_scan = (run_backend_scan_fc)g_acism_backend_run_scan;
+    backend->output = (output_backend_stats_fc)g_acism_backend_output_stats;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = instance à initialiser.                            *
+*                                                                             *
+*  Description : Initialise une instance de méthodes basée sur Bitmap.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_acism_backend_init(GAcismBackend *backend)
+{
+#ifdef __USE_BYTE_FREQ
+    size_t i;                               /* Boucle de parcours #1       */
+    acism_freq_rank_t *iter;                /* Boucle de parcours #2       */
+#endif
+
+#ifdef __USE_BYTE_FREQ
+    memset(backend->codes_for_bytes, 0, 256 * sizeof(acism_code_t));
+#endif
+
+    backend->nchars = 0;
+
+#ifdef __USE_BYTE_FREQ
+    for (i = 0, iter = backend->frequencies; i < 256; i++, iter++)
+    {
+        iter->frequency = 0;
+        iter->rank = i;
+    }
+#endif
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_acism_backend_dispose(GAcismBackend *backend)
+{
+    G_OBJECT_CLASS(g_acism_backend_parent_class)->dispose(G_OBJECT(backend));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_acism_backend_finalize(GAcismBackend *backend)
+{
+    G_OBJECT_CLASS(g_acism_backend_parent_class)->finalize(G_OBJECT(backend));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Crée une méthode de recherche basée sur l'algorithme Acism.  *
+*                                                                             *
+*  Retour      : Méthode mise en place.                                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GEngineBackend *g_acism_backend_new(void)
+{
+    GAcismBackend *result;                  /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_ACISM_BACKEND, NULL);
+
+    return G_ENGINE_BACKEND(result);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à consulter.                   *
+*                                                                             *
+*  Description : Indique la taille maximale des suites d'octets recherchées.  *
+*                                                                             *
+*  Retour      : Valeur strictement positive.                                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+size_t g_acism_backend_get_atom_max_size(const GAcismBackend *backend)
+{
+    size_t result;                          /* Taille à faire connaître    */
+
+    result = ACSIM_ATOM_SIZE;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à préparer.                    *
+*                context = contexte de l'analyse à mener.                     *
+*                plain   = chaîne de caractères classique à intégrer.         *
+*                len     = taille de cette chaîne.                            *
+*                                                                             *
+*  Description : Intègre un motif limité de contenu à rechercher.             *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static patid_t g_acism_backend_setup_for(GAcismBackend *backend, GScanContext *context, const uint8_t *pattern, size_t len)
+{
+    patid_t result;                         /* Identifiant à retourner     */
+    size_t i;                               /* Boucle de parcours          */
+    int ret;                                /* Bilan d'une comparaison     */
+    acism_source_t *source;                 /* Définition à mémoriser      */
+
+    result = INVALID_PATTERN_ID;
+
+    /*Recherche d'un motif déjà sollicité */
+
+    /**
+     * '\x00\x00\x00\x00abcd1234' '\x01\x01\x01\x01abcd1234' peuvent en effet
+     * constituer deux cibles différentes, mais elles comportent normalement
+     * la même séquence atomique à rechercher : 'abcd1234'.
+     */
+
+    for (i = 0; i < backend->sources_count; i++)
+    {
+        source = backend->sources + i;
+
+        if (source->len != len)
+            continue;
+
+        ret = memcmp(source->atoms, pattern, len);
+
+        if (ret == 0)
+        {
+            result = source->pid;
+            break;
+        }
+
+    }
+
+    /* Introduction d'un nouveau motif au besoin */
+
+    if (result == INVALID_PATTERN_ID)
+    {
+        backend->sources = realloc(backend->sources, ++backend->sources_count * sizeof(acism_source_t));
+
+        source = &backend->sources[backend->sources_count - 1];
+
+        source->atoms = pattern;
+        source->len = len;
+
+        result = g_scan_context_get_new_pattern_id(context);
+        source->pid = result;
+
+        backend->nchars += len;
+
+#ifdef __USE_BYTE_FREQ
+        for (i = 0; i < len; i++)
+            backend->frequencies[pattern[i]].frequency++;
+#endif
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à manipuler.                   *
+*                context = contexte de l'analyse à mener.                     *
+*                plain   = chaîne de caractères classique à intégrer.         *
+*                len     = taille de cette chaîne.                            *
+*                                                                             *
+*  Description : Inscrit dans le moteur une chaîne de caractères à rechercher.*
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static patid_t g_acism_backend_enroll_plain_pattern(GAcismBackend *backend, GScanContext *context, const uint8_t *plain, size_t len)
+{
+    patid_t result;                         /* Identifiant à retourner     */
+
+    assert(len <= ACSIM_ATOM_SIZE);
+
+    /**
+     * Le traitement différé des chaînes à rechercher permet deux choses :
+     *   - la construction d'une table de permutation ;
+     *   - le décompte des noeuds à allouer (en une seule fois).
+     *
+     * Si l'intention du premier point est louable (densifier les champs de bits
+     * pour allouer moins et tenir plus facilement dans le cache du CPU), la
+     * permetutation est extrèmement coûteuse pendant la phase de scan
+     * (une lecture supplémentaire par octet de données scannées).
+     *
+     * Le second point reste valable (à priori).
+     *
+     * L'appel à la fonction g_acism_backend_setup_for() demeure donc, et l'arbre
+     * est construit dans un second temps. La distinction de cette fonction avec
+     * la procédure d'enrôlement permet potentiellement d'étuer une bascule à
+     * moindre coût un jour.
+     */
+
+    result = g_acism_backend_setup_for(backend, context, plain, len);
+
+    return result;
+
+}
+
+
+#ifdef __USE_BYTE_FREQ
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : a = premier élément à comparer.                              *
+*                b = second élément à comparer.                               *
+*                                                                             *
+*  Description : Compare un niveau de fréquence avec un autre.                *
+*                                                                             *
+*  Retour      : Bilan de la comparaison.                                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int compare_byte_frequencies(const acism_freq_rank_t *a, const acism_freq_rank_t *b)
+{
+    int result;                             /* Bilan à retourner           */
+
+    /**
+     * Afin d'obtenir les plus grosses fréquences en premier,
+     * l'ordre de comparaison est inversé : b < a ?
+     */
+
+    result = sort_unsigned_long(b->frequency, a->frequency);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à préparer.                    *
+*                                                                             *
+*  Description : Détermine les identifiants de chaque valeur 8 bits utile.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_acism_backend_define_codes(GAcismBackend *backend)
+{
+    size_t i;                               /* Boucle de parcours #1       */
+    acism_freq_rank_t *iter;                /* Boucle de parcours #2       */
+
+    /**
+     * La redistribution des valeurs d'octet va permettre de compacter
+     * par la suite les masques de cellules utilisées pour construire
+     * le plus petit tableau des états.
+     *
+     * L'idée est de grouper le plus possible les états (représentés
+     * par un indice) autour de l'état 0.
+     */
+
+    qsort(backend->frequencies, 256, sizeof(acism_freq_rank_t), (__compar_fn_t)compare_byte_frequencies);
+
+    /* 0 == racine */
+    backend->codes_count++;
+
+#if 0
+    for (i = 0, iter = backend->frequencies; i < 256; i++, iter++)
+    {
+        if (iter->frequency == 0)
+            break;
+
+        backend->codes_for_bytes[iter->rank] = backend->codes_count++;
+
+    }
+#else
+    for (i = 0; i < 256; i++)
+        backend->codes_for_bytes[i] = backend->codes_count++;
+#endif
+
+}
+
+
+#endif
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à préparer.                    *
+*                                                                             *
+*  Description : Construit l'arborescence de noeuds de lecture.               *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_acism_backend_build_trie(GAcismBackend *backend)
+{
+    size_t i;                               /* Boucle de parcours #1       */
+    acism_trie_node_t *next;                /* Prochain noeud disponible   */
+    acism_trie_node_t *node;                /* Tête de parcours            */
+    acism_source_t *source;                 /* Définition à mémoriser      */
+    size_t k;                               /* Boucle de parcours #2       */
+    acism_code_t code;                      /* Identifiant de symbole      */
+    acism_trie_node_t *parent;              /* Sauvegarde d'un accès       */
+
+    backend->nodes = calloc(backend->nchars + 1, sizeof(acism_trie_node_t));
+
+    for (i = 0; i < (backend->nchars + 1); i++)
+    {
+        backend->nodes[i].min_child_code = MAX_ACISM_CODE;
+        backend->nodes[i].max_child_code = MIN_ACISM_CODE;
+    }
+
+    next = backend->nodes + 1;
+
+    for (i = 0; i < backend->sources_count; i++)
+    {
+        node = backend->nodes;
+
+        source = &backend->sources[i];
+
+        for (k = 0; k < source->len && node->child != NULL; k++)
+        {
+#ifdef __USE_BYTE_FREQ
+            code = backend->codes_for_bytes[source->atoms[k]];
+#else
+            code = 1 + source->atoms[k];
+#endif
+
+            /* Insertion d'un nouveau noeud au début des enfants */
+            if (code < node->child->code)
+            {
+                next->parent = node;
+                next->suffix_link = node;
+                next->data = source->atoms[k];
+                next->code = code;
+
+                next->sibling = node->child;
+                node->child = next++;
+
+                if (code < node->min_child_code) node->min_child_code = code;
+                if (code > node->max_child_code) node->max_child_code = code;
+                node->children_count++;
+
+                node = node->child;
+
+                k++;
+                break;
+
+            }
+
+            parent = node;
+
+            /* Recherche du point d'insertion idéal */
+            for (node = node->child;
+                 node->sibling != NULL && code >= node->sibling->code;
+                 node = node->sibling);
+
+            /* Si le noeud idéal n'existe pas, insertion ordonnée */
+            if (code > node->code)
+            {
+                next->parent = parent;
+                next->suffix_link = parent;
+                next->data = source->atoms[k];
+                next->code = code;
+
+                next->sibling = node->sibling;
+                node->sibling = next++;
+
+                if (code < parent->min_child_code) parent->min_child_code = code;
+                if (code > parent->max_child_code) parent->max_child_code = code;
+                parent->children_count++;
+
+                node = node->sibling;
+
+                k++;
+                break;
+
+            }
+
+        }
+
+        /* Creéation d'une nouvelle branche avec le reliquat */
+        for (; k < source->len; k++)
+        {
+#ifdef __USE_BYTE_FREQ
+            code = backend->codes_for_bytes[source->atoms[k]];
+#else
+            code = 1 + source->atoms[k];
+#endif
+
+            next->parent = node;
+            next->suffix_link = node;
+            next->data = source->atoms[k];
+            next->code = code;
+
+            node->child = next++;
+
+            if (code < node->min_child_code) node->min_child_code = code;
+            if (code > node->max_child_code) node->max_child_code = code;
+            node->children_count++;
+
+            node = node->child;
+
+        }
+
+        node->matched_atom = i + 1;
+
+    }
+
+    backend->nodes_used = next - backend->nodes;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à préparer.                    *
+*                                                                             *
+*  Description : Construit l'arborescence de noeuds de lecture.               *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_acism_backend_build_suffix_links(GAcismBackend *backend)
+{
+    size_t max_pos;                         /* Tête de lecture finale      */
+    acism_trie_node_t **stack;              /* Pile des noeuds à traiter   */
+    size_t rd_pos;                          /* Tête de lecture             */
+    size_t wr_pos;                          /* Tête d'écriture             */
+    acism_trie_node_t *node;                /* Noeud à traiter             */
+    acism_trie_node_t *parent;              /* Noeud parent de la chaîne   */
+    acism_trie_node_t *iter;                /* Boucle de parcours          */
+
+    max_pos = backend->nodes_used;
+
+    stack = calloc(max_pos, sizeof(acism_trie_node_t *));
+
+    /* Initialisation du parcours */
+
+    rd_pos = 0;
+    wr_pos = 0;
+
+    stack[wr_pos++] = &backend->nodes[0];
+
+    assert(backend->nodes->sibling == NULL);
+
+    /* Traitement manuel de démarrage pour éviter une condition en [0] */
+
+    for (iter = backend->nodes->child; iter != NULL; iter = iter->sibling)
+        stack[wr_pos++] = iter;
+
+    rd_pos++;
+
+    /* Suivi des liens déjà en place */
+
+    while (rd_pos < max_pos)
+    {
+        assert(rd_pos < wr_pos);
+
+        node = stack[rd_pos++];
+
+        /* Remontée jusqu'à la découverte d'un lien d'intérêt */
+
+        for (parent = node->suffix_link; parent != NULL; parent = parent->suffix_link)
+        {
+            for (iter = parent->child; iter != NULL; iter = iter->sibling)
+                if (iter->code == node->code && iter != node)
+                {
+                    node->suffix_link = iter;
+                    break;
+                }
+
+            if (iter != NULL)
+                break;
+
+        }
+
+        if (parent == NULL /* && node != &backend->nodes [0] */)
+            node->suffix_link = backend->nodes;
+
+        /* Inscription des noeuds suivants */
+
+        for (iter = node->child; iter != NULL; iter = iter->sibling)
+            stack[wr_pos++] = iter;
+
+    }
+
+    /* Sortie propre */
+
+    free(stack);
+
+}
+
+
+#ifdef __SORT_BEFORE_BITMASK
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : a = premier élément à comparer.                              *
+*                b = second élément à comparer.                               *
+*                                                                             *
+*  Description : Compare des noeuds selon l'espace de codes couvert.          *
+*                                                                             *
+*  Retour      : Bilan de la comparaison.                                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int compare_node_according_to_code_range(const acism_trie_node_t **a, const acism_trie_node_t **b)
+{
+    int result;                             /* Bilan à retourner           */
+    const acism_trie_node_t *_a;            /* Autre vision de l'élément #1*/
+    const acism_trie_node_t *_b;            /* Autre vision de l'élément #1*/
+    acism_code_t range_a;                   /* Espacement des codes #1     */
+    acism_code_t range_b;                   /* Espacement des codes #2     */
+
+    result = 0;
+
+    _a = *a;
+    _b = *b;
+
+    if (_a->child == NULL)
+        result = (_b->child == NULL ? 0 : 1);
+
+    else if (_b->child == NULL)
+        result = (_a->child == NULL ? 0 : -1);
+
+    else
+    {
+        assert(_a->min_child_code <= _a->max_child_code);
+        range_a = _a->max_child_code - _a->min_child_code;
+
+        assert(_b->min_child_code <= _b->max_child_code);
+        range_b = _b->max_child_code - _b->min_child_code;
+
+        result = sort_unsigned_long(range_b, range_a);
+
+        if (result == 0)
+            result = sort_unsigned_long(_b->children_count, _a->children_count);
+
+
+
+
+    }
+
+    return result;
+
+}
+
+
+#endif
+
+
+#if 1
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à préparer.                    *
+*                                                                             *
+*  Description : Organise la convertion de l'arborescence en tableau.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_acism_backend_prepare_interleave_array(GAcismBackend *backend)
+{
+#ifdef __SORT_BEFORE_BITMASK
+    acism_trie_node_t **list;               /* Liste de noeuds alloués     */
+#endif
+    size_t i;                               /* Boucle de parcours #1       */
+    size_t last_free_state;                 /* Dernier emplacement dispo.  */
+    size_t full_size;                       /* Cartographie entière        */
+    bitfield_t *global_usage;               /* Cartographie des usages     */
+    bitfield_t *usage;                      /* Cartographie locale         */
+    acism_trie_node_t *node;                /* Noeud en cours de traitement*/
+    acism_trie_node_t *iter;                /* Boucle de parcours #2       */
+    size_t free_state;                      /* Emplacement libre trouvé    */
+    bool found;                             /* Bilan de recherche          */
+
+    size_t bsum;
+
+    /* Préparation de la liste de noeuds à inscrire */
+
+#ifdef __SORT_BEFORE_BITMASK
+
+    list = calloc(backend->nodes_used, sizeof(acism_trie_node_t *));
+
+    for (i = 0; i < backend->nodes_used; i++)
+        list[i] = backend->nodes + i;
+
+    qsort(list + 1, backend->nodes_used - 1, sizeof(acism_trie_node_t *),
+          (__compar_fn_t)compare_node_according_to_code_range);
+
+#endif
+
+    /* Insertion des noeuds dans l'ordre prévu */
+
+    last_free_state = 257;
+    full_size = last_free_state + 257;
+    global_usage = create_bit_field(full_size, false);
+
+    bsum = 0;
+
+    usage = create_bit_field(257, false);
+
+    for (i = 0; i < backend->nodes_used; i++)
+    {
+#ifdef __SORT_BEFORE_BITMASK
+        node = list[i];
+#else
+        node = backend->nodes + i;
+#endif
+
+        /* Préparation du masque du noeud */
+
+        reset_all_in_bit_field(usage);
+
+        set_in_bit_field(usage, 0, 1);
+
+        for (iter = node->child; iter != NULL; iter = iter->sibling)
+            set_in_bit_field(usage, iter->code, 1);
+
+        assert(popcount_for_bit_field(usage) == (node->children_count + 1));
+
+        /* Recherche d'une position idéale */
+
+        if (i == 0)
+            free_state = 0;
+
+        else
+            for (free_state = 1; free_state < last_free_state; free_state++)
+            {
+                found = test_zeros_within_bit_field(global_usage, free_state, usage);
+                if (found) break;
+            }
+
+        /* Suivi global */
+
+        assert(!test_in_bit_field(global_usage, free_state));
+
+        or_bit_field_at(global_usage, usage, free_state);
+
+        bsum += node->children_count + 1;
+        assert(popcount_for_bit_field(global_usage) == bsum);
+
+        node->state_index = free_state;
+
+        if ((free_state + 257) > last_free_state)
+        {
+            last_free_state += 257;
+            full_size += 257;
+            resize_bit_field(&global_usage, full_size);
+        }
+
+    }
+
+    /* Sotie encadrée */
+
+    backend->bitmap_usage = global_usage;
+
+    delete_bit_field(usage);
+
+#ifdef __SORT_BEFORE_BITMASK
+    free(list);
+#endif
+
+}
+
+
+#else
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à préparer.                    *
+*                                                                             *
+*  Description : Organise la convertion de l'arborescence en tableau.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_acism_backend_prepare_interleave_array(GAcismBackend *backend)
+{
+    size_t max_pos;                         /* Tête de lecture finale      */
+    acism_trie_node_t **stack;              /* Pile des noeuds à traiter   */
+    size_t last_free_state;                 /* Dernier emplacement dispo.  */
+    size_t full_size;                       /* Cartographie entière        */
+    bitfield_t *global_usage;               /* Cartographie des usages     */
+    bitfield_t *usage;                      /* Cartographie locale         */
+    size_t rd_pos;                          /* Tête de lecture             */
+    size_t wr_pos;                          /* Tête d'écriture             */
+    acism_trie_node_t *node;                /* Noeud à traiter             */
+    acism_trie_node_t *iter;                /* Boucle de parcours          */
+    size_t free_state;                      /* Emplacement libre trouvé    */
+    bool found;                             /* Bilan de recherche          */
+
+    max_pos = backend->nodes_used;
+
+    stack = calloc(max_pos, sizeof(acism_trie_node_t *));
+
+    last_free_state = 257;
+    full_size = last_free_state + 257;
+    global_usage = create_bit_field(full_size, false);
+
+    usage = create_bit_field(257, false);
+
+    /* Initialisation du parcours */
+
+    rd_pos = 0;
+    wr_pos = 0;
+
+    stack[wr_pos++] = &backend->nodes[0];
+
+    assert(backend->nodes->sibling == NULL);
+
+    /* Traitement manuel de démarrage pour éviter une condition en [0] */
+
+    set_in_bit_field(global_usage, 0, 1);
+
+    for (iter = backend->nodes->child; iter != NULL; iter = iter->sibling)
+    {
+        set_in_bit_field(global_usage, iter->code, 1);
+        stack[wr_pos++] = iter;
+    }
+
+    rd_pos++;
+
+    /* Suivi des liens déjà en place */
+
+    while (rd_pos < max_pos)
+    {
+        assert(rd_pos < wr_pos);
+
+        node = stack[rd_pos++];
+
+        /* Préparation du masque du noeud et inscription des noeuds suivants */
+
+        reset_all_in_bit_field(usage);
+
+        set_in_bit_field(usage, 0, 1);
+
+        for (iter = node->child; iter != NULL; iter = iter->sibling)
+        {
+            set_in_bit_field(usage, iter->code, 1);
+            stack[wr_pos++] = iter;
+        }
+
+        assert(popcount_for_bit_field(usage) == (node->children_count + 1));
+
+        /* Recherche d'une position idéale */
+
+        for (free_state = 1; free_state < last_free_state; free_state++)
+        {
+            found = test_zeros_within_bit_field(global_usage, free_state, usage);
+            if (found) break;
+        }
+
+        /* Suivi global */
+
+        assert(!test_in_bit_field(global_usage, free_state));
+
+        or_bit_field_at(global_usage, usage, free_state);
+
+        node->state_index = free_state;
+
+        if ((free_state + 257) > last_free_state)
+        {
+            last_free_state += 257;
+            full_size += 257;
+            resize_bit_field(&global_usage, full_size);
+        }
+
+    }
+
+    /* Sotie encadrée */
+
+    backend->bitmap_usage = global_usage;
+
+    delete_bit_field(usage);
+
+    free(stack);
+
+}
+
+
+#endif
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à préparer.                    *
+*                                                                             *
+*  Description : Compresse l'arborescence dans un tableau de position.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_acism_backend_build_interleave_array(GAcismBackend *backend)
+{
+    size_t maxsize;                         /* Taille maximale du tableau  */
+    size_t i;                               /* Boucle de parcours #1       */
+    acism_trie_node_t *node;                /* Noeud à transcrire          */
+    acism_state_t *base;                    /* Base d'une série de cellules*/
+    acism_trie_node_t *iter;                /* Sous-noeud à inscrire #2    */
+    acism_trie_node_t *child;               /* Sous-noeud à inscrire #3    */
+    uint16_t offset;                        /* Décalage local              */
+
+    maxsize = get_bit_field_size(backend->bitmap_usage);
+
+    backend->states = calloc(maxsize, sizeof(acism_state_t));
+    backend->pids = calloc(maxsize, sizeof(patid_t));
+
+    for (i = 0; i < backend->nodes_used; i++)
+    {
+        node = &backend->nodes[i];
+        base = backend->states + node->state_index;
+
+        assert(base[0].code == 0);
+        assert(base[0].index == 0);
+
+        if (node->matched_atom > 0)
+        {
+            base[0].match = 1;
+            base[0].atom_size = backend->sources[node->matched_atom - 1].len;
+
+            backend->pids[node->state_index] = backend->sources[node->matched_atom - 1].pid;
+
+            for (iter = node->parent->suffix_link; iter != NULL; iter = iter->suffix_link)
+            {
+                for (child = iter->child; child != NULL; child = child->sibling)
+                    if (child->code == node->code && child->matched_atom > 0)
+                        break;
+
+                if (child != NULL)
+                {
+                    base[0].suffix = 1;
+                    break;
+                }
+
+            }
+
+        }
+        base[0].index = i == 0 ? 0 : node->suffix_link->state_index;
+
+        for (child = node->child; child != NULL; child = child->sibling)
+        {
+            offset = child->code;
+
+            assert(base[offset].code == 0);
+            assert(base[offset].index == 0);
+
+            base[offset].code = child->code;
+            base[offset].index = child->state_index;
+
+        }
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à préparer.                    *
+*                                                                             *
+*  Description : Met en ordre les derniers détails avant un premier scan.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_acism_backend_warm_up(GAcismBackend *backend)
+{
+#ifdef __USE_BYTE_FREQ
+
+    /**
+     * Attribue un identifiant unique pour chaque octet présent dans les
+     * motifs recherchés.
+     */
+    g_acism_backend_define_codes(backend);
+
+#endif
+
+    /**
+     * Construit une arborescence de lecture à partir des différents
+     * octets présents dans les motifs.
+     */
+    g_acism_backend_build_trie(backend);
+
+    /**
+     * Met en place les liens suivis en cas d'échec de correspondance
+     * lors de la lecture d'un octet supplémentaire.
+     */
+    g_acism_backend_build_suffix_links(backend);
+
+    /**
+     * Conversion de l'arborescence en tableau plat et compressé.
+     */
+
+    g_acism_backend_prepare_interleave_array(backend);
+
+    g_acism_backend_build_interleave_array(backend);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à manipuler.                   *
+*                context = lieu d'enregistrement des résultats.               *
+*                content = données binaires à analyser.                       *
+*                                                                             *
+*  Description : Parcours un contenu binaire à la recherche de motifs.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_acism_backend_run_scan(const GAcismBackend *backend, GScanContext *context, GBinContent *content)
+{
+    phys_t dlen;                            /* Quantité de données         */
+    vmpa2t pos;                             /* Point de départ ciblé       */
+    const bin_t *data;                      /* Données à analyser          */
+#ifdef __USE_BYTE_FREQ
+    acism_code_t *codes_for_bytes;
+#endif
+    acism_state_t *root;                    /* Racine de l'arborescence    */
+    acism_state_t *state;                   /* Tête de lecture courante    */
+    phys_t i;                               /* Boucle de parcours #1       */
+    acism_code_t code;                      /* Code du caractère courant   */
+    acism_state_t *next;                    /* Prochaine tête à valider    */
+    acism_state_t *iter;                    /* Boucle de parcours #2       */
+    acism_state_t *test;                    /* Test de validité alternative*/
+
+    dlen = g_binary_content_compute_size(content);
+
+    g_binary_content_compute_start_pos(content, &pos);
+    data = g_binary_content_get_raw_access(content, &pos, dlen);
+
+    /* Suivi via l'arborescence aplatie */
+
+#ifdef __USE_BYTE_FREQ
+    codes_for_bytes = backend->codes_for_bytes;
+#endif
+
+    root = backend->states;
+
+    state = root;
+
+    for (i = 0; i < dlen; i++)
+    {
+#ifdef __USE_BYTE_FREQ
+        code = 1 + codes_for_bytes[data[i]];
+#else
+        code = 1 + data[i];
+#endif
+
+        /* Déplacement de la tête de lecture dans l'arborescence */
+
+ retry:
+
+        next = state + code;
+
+        if (next->code == code)
+            next = root + next->index;
+
+        else if (state != root)
+        {
+            state = root + state->index;
+            goto retry;
+        }
+
+        else
+            continue;
+
+        /* Remontée d'éventuels résultats */
+
+        if (next->match)
+        {
+            g_scan_context_register_atom_match(context,
+                                               backend->pids[next - root],
+                                               i + 1 - next->atom_size);
+
+            if (next->suffix)
+            {
+                for (iter = root + state->index; ; iter = root + iter->index)
+                {
+                    test = iter + code;
+
+                    if (test->code == code)
+                    {
+                        test = root + test->index;
+
+                        if (test->match)
+                        {
+                            assert(test->atom_size < next->atom_size);
+
+                            g_scan_context_register_atom_match(context,
+                                                               backend->pids[test - root],
+                                                               i + 1 - test->atom_size);
+
+                        }
+
+                    }
+
+                    if (iter == root)
+                        break;
+
+                }
+
+            }
+
+
+        }
+
+        /* Bascule au caractère suivant */
+
+        state = next;
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : node  = noeud d'arborescence à traiter.                      *
+*                level = profondeur courante.                                 *
+*                                                                             *
+*  Description : Affiche les caractéristques d'un noeud et de ses enfants.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void visit_and_output_node(const acism_trie_node_t *node, unsigned int level)
+{
+    unsigned int i;                         /* Boucle de parcours #1       */
+    acism_trie_node_t *iter;                /* Boucle de parcours #2       */
+
+    for (i = 0; i < level; i++)
+        printf("  ");
+
+    printf(" '%c' (code=%hhu)\n", node->data, node->code);
+
+    for (iter = node->child; iter != NULL; iter = iter->sibling)
+        visit_and_output_node(iter, level + 1);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à consulter.                   *
+*                                                                             *
+*  Description : Imprime quelques faits quant aux éléments mis en place.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_acism_backend_output_stats(const GAcismBackend *backend)
+{
+    printf("nodes used: %zu\n", backend->nodes_used);
+
+    printf("full_size: %zu (real: %zu)\n",
+           get_bit_field_size(backend->bitmap_usage),
+           popcount_for_bit_field(backend->bitmap_usage));
+
+    visit_and_output_node(backend->nodes, 0);
+
+}
diff --git a/src/analysis/scan/patterns/backends/acism.h b/src/analysis/scan/patterns/backends/acism.h
new file mode 100644
index 0000000..837022a
--- /dev/null
+++ b/src/analysis/scan/patterns/backends/acism.h
@@ -0,0 +1,59 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * acism.h - prototypes pour la méthode de recherche basée sur l'algorithme Aho-Corasick Interleaved State-transition Matrix
+ *
+ * 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 _ANALYSIS_SCAN_PATTERNS_BACKENDS_ACISM_H
+#define _ANALYSIS_SCAN_PATTERNS_BACKENDS_ACISM_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+
+
+#include "../backend.h"
+
+
+
+#define G_TYPE_ACISM_BACKEND            g_acism_backend_get_type()
+#define G_ACISM_BACKEND(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ACISM_BACKEND, GAcismBackend))
+#define G_IS_ACISM_BACKEND(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ACISM_BACKEND))
+#define G_ACISM_BACKEND_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ACISM_BACKEND, GAcismBackendClass))
+#define G_IS_ACISM_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ACISM_BACKEND))
+#define G_ACISM_BACKEND_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ACISM_BACKEND, GAcismBackendClass))
+
+
+/* Méthode de recherche basée sur l'algorithme Acism (instance) */
+typedef struct _GAcismBackend GAcismBackend;
+
+/* Méthode de recherche basée sur l'algorithme Acism (classe) */
+typedef struct _GAcismBackendClass GAcismBackendClass;
+
+
+/* Indique le type défini pour un moteur de recherche pour données. */
+GType g_acism_backend_get_type(void);
+
+/* Crée une méthode de recherche basée sur l'algorithme Acism. */
+GEngineBackend *g_acism_backend_new(void);
+
+
+
+#endif  /* _ANALYSIS_SCAN_PATTERNS_BACKENDS_ACISM_H */
diff --git a/src/analysis/scan/patterns/backends/bitap-int.h b/src/analysis/scan/patterns/backends/bitap-int.h
new file mode 100644
index 0000000..83ecc17
--- /dev/null
+++ b/src/analysis/scan/patterns/backends/bitap-int.h
@@ -0,0 +1,118 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * bitap-int.h - prototypes internes pour la méthode de recherche basée sur l'algorithme Bitap
+ *
+ * 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 _ANALYSIS_SCAN_PATTERNS_BACKENDS_BITAP_INT_H
+#define _ANALYSIS_SCAN_PATTERNS_BACKENDS_BITAP_INT_H
+
+
+#include "bitap.h"
+
+
+#include <immintrin.h>
+
+
+#include "../backend-int.h"
+#include "../../../../common/cpu.h"
+
+
+
+#define BITAP_ATOM_SIZE 7
+
+
+/* Suivi d'un groupe de chaînes */
+typedef struct _grouped_strings_avx2_t
+{
+    __m256i pattern_masks[256];             /* Programmation de détections */
+    __m256i found_masks;                    /* Masques multiples d'alerte  */
+
+    __m256i R;                              /* Résultats courants          */
+
+    size_t m[32];                           /* Taille des chaînes          */
+
+    patid_t found_id[32];                   /* Indice des résultats        */
+
+    size_t available;                       /* Nombre de places disponibles*/
+    size_t used;                            /* Quantité de places utilisées*/
+
+} grouped_strings_avx2_t;
+
+/* Suivi de l'ensemble de chaînes */
+typedef struct _group_manager_avx2_t
+{
+    grouped_strings_avx2_t **strings_8;     /* Chaînes de taille 8 max     */
+    size_t count_8;                         /* Quantité de ces chaînes     */
+
+} group_manager_avx2_t;
+
+
+/* Suivi d'un groupe de chaînes */
+typedef struct _grouped_strings_avx512_t
+{
+    __m512i pattern_masks[256];             /* Programmation de détections */
+    __m512i found_masks;                    /* Masques multiples d'alerte  */
+
+    __m512i R;                              /* Résultats courants          */
+
+    size_t m[64];                           /* Taille des chaînes          */
+
+    patid_t found_id[64];                   /* Indice des résultats        */
+
+    size_t used;                            /* Quantité de places utilisées*/
+    size_t available;                       /* Nombre de places disponibles*/
+
+} grouped_strings_avx512_t;
+
+/* Suivi de l'ensemble de chaînes */
+typedef struct _group_manager_avx512_t
+{
+    grouped_strings_avx512_t **strings_8;   /* Chaînes de taille 8 max     */
+    size_t count_8;                         /* Quantité de ces chaînes     */
+
+} group_manager_avx512_t;
+
+
+/* Méthode de recherche basée sur l'algorithme Bitap (instance) */
+struct _GBitapBackend
+{
+    GEngineBackend parent;                  /* A laisser en premier        */
+
+    CPUSMIDFeature optimization;            /* Mode de calculs             */
+
+    union
+    {
+        group_manager_avx2_t manager_avx2;  /* Gestionnaire pour AVX2      */
+        group_manager_avx512_t manager_avx512;/* Gestionnaire pour AVX-512 */
+    };
+
+};
+
+/* Méthode de recherche basée sur l'algorithme Bitap (classe) */
+struct _GBitapBackendClass
+{
+    GEngineBackendClass parent;             /* A laisser en premier        */
+
+};
+
+
+
+#endif  /* _ANALYSIS_SCAN_PATTERNS_BACKENDS_BITAP_INT_H */
diff --git a/src/analysis/scan/patterns/backends/bitap.c b/src/analysis/scan/patterns/backends/bitap.c
new file mode 100644
index 0000000..bd80fb0
--- /dev/null
+++ b/src/analysis/scan/patterns/backends/bitap.c
@@ -0,0 +1,2766 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * bitap.c - méthode de recherche basée sur l'algorithme Bitap
+ *
+ * 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 "bitap.h"
+
+
+#include <alloca.h>
+#include <assert.h>
+#include <sys/mman.h>
+#include <sched.h>
+
+
+#include "bitap-int.h"
+#include "../../../../core/logs.h"
+//#include "../../matches/bytes.h"
+
+
+
+/* ---------------------- IMPLANTATION D'UNE NOUVELLE APPROCHE ---------------------- */
+
+
+/* Initialise la classe des méthodes basée sur Bitmap. */
+static void g_bitap_backend_class_init(GBitapBackendClass *);
+
+/* Initialise une instance de méthodes basée sur Bitmap. */
+static void g_bitap_backend_init(GBitapBackend *);
+
+/* Supprime toutes les références externes. */
+static void g_bitap_backend_dispose(GBitapBackend *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_bitap_backend_finalize(GBitapBackend *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Indique la taille maximale des suites d'octets recherchées. */
+size_t g_bitap_backend_get_atom_max_size(const GBitapBackend *);
+
+/* Inscrit dans le moteur une chaîne de caractères à rechercher. */
+static patid_t g_bitap_backend_enroll_plain_pattern(GBitapBackend *, GScanContext *, const uint8_t *, size_t);
+
+/* Parcours un contenu binaire à la recherche de motifs. */
+static void g_bitap_backend_run_scan(const GBitapBackend *, GScanContext *, GBinContent *);
+
+/* Imprime quelques faits quant aux éléments mis en place. */
+static void g_bitap_backend_output_stats(const GBitapBackend *);
+
+
+
+/* ---------------------- OPTIMISATIONS POUR ARCHITECTURE AVX2 ---------------------- */
+
+
+/* Indique la valeur portée par une expression rationnelle. */
+static void extend_grouped_strings_avx2(grouped_strings_avx2_t ***, size_t *);
+
+/* Inscrit dans le moteur une chaîne de caractères à rechercher. */
+static patid_t enroll_plain_pattern_avx2(GBitapBackend *, GScanContext *, const bin_t *, size_t);
+
+/* Parcours un contenu binaire à la recherche de motifs. */
+static void run_scan_avx2(const GBitapBackend *, GScanContext *, GBinContent *);
+
+
+
+
+
+/* --------------------- OPTIMISATIONS POUR ARCHITECTURE AVX512 --------------------- */
+
+
+/* Indique la valeur portée par une expression rationnelle. */
+static void extend_grouped_strings_avx512(grouped_strings_avx512_t ***, size_t *);
+
+/* Inscrit dans le moteur une chaîne de caractères à rechercher. */
+static patid_t enroll_plain_pattern_avx512(GBitapBackend *, GScanContext *, const bin_t *, size_t);
+
+/* Parcours un contenu binaire à la recherche de motifs. */
+static void run_scan_avx512(const GBitapBackend *, GScanContext *, GBinContent *);
+
+
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                        IMPLANTATION D'UNE NOUVELLE APPROCHE                        */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un moteur de recherche pour données. */
+G_DEFINE_TYPE(GBitapBackend, g_bitap_backend, G_TYPE_ENGINE_BACKEND);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des méthodes basée sur Bitmap.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_bitap_backend_class_init(GBitapBackendClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GEngineBackendClass *backend;           /* Version de classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_bitap_backend_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_bitap_backend_finalize;
+
+    backend = G_ENGINE_BACKEND_CLASS(klass);
+
+    backend->get_max_size = (get_backend_atom_max_size_fc)g_bitap_backend_get_atom_max_size;
+    backend->enroll_plain = (enroll_plain_into_backend_fc)g_bitap_backend_enroll_plain_pattern;
+    backend->run_scan = (run_backend_scan_fc)g_bitap_backend_run_scan;
+    backend->output = (output_backend_stats_fc)g_bitap_backend_output_stats;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = instance à initialiser.                            *
+*                                                                             *
+*  Description : Initialise une instance de méthodes basée sur Bitmap.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_bitap_backend_init(GBitapBackend *backend)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_bitap_backend_dispose(GBitapBackend *backend)
+{
+    G_OBJECT_CLASS(g_bitap_backend_parent_class)->dispose(G_OBJECT(backend));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_bitap_backend_finalize(GBitapBackend *backend)
+{
+    G_OBJECT_CLASS(g_bitap_backend_parent_class)->finalize(G_OBJECT(backend));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Crée une méthode de recherche basée sur l'algorithme Bitap.  *
+*                                                                             *
+*  Retour      : Méthode mise en place.                                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GEngineBackend *g_bitap_backend_new(void)
+{
+    GBitapBackend *result;                  /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_BITAP_BACKEND, NULL);
+
+    return G_ENGINE_BACKEND(result);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à consulter.                   *
+*                                                                             *
+*  Description : Indique la taille maximale des suites d'octets recherchées.  *
+*                                                                             *
+*  Retour      : Valeur strictement positive.                                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+size_t g_bitap_backend_get_atom_max_size(const GBitapBackend *backend)
+{
+    size_t result;                          /* Taille à faire connaître    */
+
+    result = BITAP_ATOM_SIZE;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à manipuler.                   *
+*                context = contexte de l'analyse à mener.                     *
+*                plain   = chaîne de caractères classique à intégrer.         *
+*                len     = taille de cette chaîne.                            *
+*                                                                             *
+*  Description : Inscrit dans le moteur une chaîne de caractères à rechercher.*
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static patid_t g_bitap_backend_enroll_plain_pattern(GBitapBackend *backend, GScanContext *context, const uint8_t *plain, size_t len)
+{
+    patid_t result;                         /* Identifiant à retourner     */
+
+
+
+    result = INVALID_PATTERN_ID;
+
+
+
+
+    if (0)
+
+        result = enroll_plain_pattern_avx2(backend, context, plain, len);
+
+    else
+
+        result = enroll_plain_pattern_avx512(backend, context, plain, len);
+
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à manipuler.                   *
+*                context = lieu d'enregistrement des résultats.               *
+*                content = données binaires à analyser.                       *
+*                                                                             *
+*  Description : Parcours un contenu binaire à la recherche de motifs.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_bitap_backend_run_scan(const GBitapBackend *backend, GScanContext *context, GBinContent *content)
+{
+    cpu_set_t old_mask;                     /* Cartographie des CPU #1     */
+    int ret;                                /* Bilan d'un appel            */
+    unsigned int cpu;                       /* Processeur courant          */
+    cpu_set_t new_mask;                     /* Cartographie des CPU #2     */
+
+    ret = sched_getaffinity(0, sizeof(cpu_set_t), &old_mask);
+
+    if (ret != 0)
+    {
+        LOG_ERROR_N("sched_getaffinity");
+        goto exit;
+    }
+
+    ret = getcpu(&cpu, NULL);
+
+    if (ret != 0)
+    {
+        LOG_ERROR_N("get_cpu");
+        goto exit;
+    }
+
+    CPU_ZERO(&new_mask);
+    CPU_SET(cpu, &new_mask);
+
+    ret = sched_setaffinity(0, sizeof(cpu_set_t), &new_mask);
+
+    if (ret != 0)
+    {
+        LOG_ERROR_N("sched_setaffinity");
+        goto exit;
+    }
+
+
+
+    if (0)
+
+        run_scan_avx2(backend, context, content);
+
+    else
+
+        run_scan_avx512(backend, context, content);
+
+
+ exit:
+
+    ;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à consulter.                   *
+*                                                                             *
+*  Description : Imprime quelques faits quant aux éléments mis en place.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_bitap_backend_output_stats(const GBitapBackend *backend)
+{
+    printf("hello here!\n");
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                        OPTIMISATIONS POUR ARCHITECTURE AVX2                        */
+/* ---------------------------------------------------------------------------------- */
+
+
+/**
+ * Cf. https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#techs=AVX,AVX2
+ */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : strings = ensemble de groupes constitués. [OUT]              *
+*                count   = nombre de groupes courant. [OUT]                   *
+*                                                                             *
+*  Description : Indique la valeur portée par une expression rationnelle.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void extend_grouped_strings_avx2(grouped_strings_avx2_t ***strings, size_t *count)
+{
+    grouped_strings_avx2_t *new;            /* Zone supplémentaire         */
+    size_t i;                               /* Boucle de parcours          */
+
+    /* Définition d'un nouvel élément vierge */
+
+    new = aligned_alloc(256, sizeof(grouped_strings_avx2_t));
+
+    for (i = 0; i < 256; i++)
+        new->pattern_masks[i] = _mm256_set1_epi8(~0);
+
+    new->found_masks = _mm256_set1_epi8(~0);
+
+    new->R = _mm256_set1_epi8(~1);
+
+    for (i = 0; i < 32; i++)
+    {
+        new->m[i] = 0;
+
+        new->found_id[i] = INVALID_PATTERN_ID;
+
+    }
+
+    new->available = 32;
+    new->used = 0;
+
+    /* Inscription */
+
+    *strings = realloc(*strings, ++(*count) * sizeof(grouped_strings_avx2_t *));
+
+    (*strings)[*count - 1] = new;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend    = moteur de recherche à manipuler.                *
+*                context    = contexte de l'analyse à mener.                  *
+*                plain      = chaîne de caractères classique à intégrer.      *
+*                plen       = taille de cette chaîne.                         *
+*                                                                             *
+*  Description : Inscrit dans le moteur une chaîne de caractères à rechercher.*
+*                                                                             *
+*  Retour      : Indice de résultats pour le motif.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static patid_t enroll_plain_pattern_avx2(GBitapBackend *backend, GScanContext *context, const bin_t *plain, size_t plen)
+{
+    patid_t result;                         /* Identifiant à retourner     */
+    grouped_strings_avx2_t ***strings;      /* Groupe de chaînes visé      */
+    size_t *count;                          /* Taille de ce groupe         */
+    grouped_strings_avx2_t *last;           /* Dernier groupe à remplir    */
+    size_t n;                               /* Indice dans le groupe       */
+    size_t i;                               /* Boucle de parcours          */
+    __m256i *letter;                        /* Lettre à marquer            */
+
+    /* Sélection du groupe de travail adéquat */
+
+    strings = &backend->manager_avx2.strings_8;
+    count = &backend->manager_avx2.count_8;
+
+    /* Préparation de la place nécessaire */
+
+    if (*count == 0)
+    {
+        extend_grouped_strings_avx2(strings, count);
+
+        last = (*strings)[0];
+
+    }
+
+    else
+    {
+        last = (*strings)[*count - 1];
+
+        if (last->used == last->available)
+        {
+            extend_grouped_strings_avx2(strings, count);
+            last = (*strings)[*count - 1];
+        }
+
+    }
+
+    /* Intégration d'une nouvelle chaîne */
+
+    n = last->used++;
+
+    last->m[n] = plen;
+
+    result = g_scan_context_get_new_pattern_id(context);
+
+    last->found_id[n] = result;
+
+    ((uint8_t *)&last->found_masks)[n] = (1 << plen);
+
+    for (i = 0; i < plen; i++)
+    {
+        letter = last->pattern_masks + plain[i];
+        ((uint8_t *)letter)[n] &= ~(1 << i);
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à manipuler.                   *
+*                context = lieu d'enregistrement des résultats.               *
+*                content = données binaires à analyser.                       *
+*                                                                             *
+*  Description : Parcours un contenu binaire à la recherche de motifs.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void run_scan_avx2(const GBitapBackend *backend, GScanContext *context, GBinContent *content)
+{
+    const group_manager_avx2_t *manager;    /* Accès simplifié             */
+    phys_t dlen;                            /* Quantité de données         */
+    vmpa2t pos;                             /* Point de départ ciblé       */
+    const bin_t *data;                      /* Données à analyser          */
+
+    register __m256i zero asm("ymm11");                           /* Constante 0 sur 256 bits    */
+    size_t k;                               /* Boucle de parcours #1       */
+    grouped_strings_avx2_t group;           /* Copie pour accès locaux     */
+
+    register __m256i R asm("ymm12");                              /* Résultats courants          */
+    register __m256i found_masks asm("ymm10"); /* Vérifications accélérées  */
+
+    //__m256i pre_shift_mask;                 /* Préparation de décalage     */
+    //phys_t i;                               /* Boucle de parcours #2       */
+
+
+
+
+    const bin_t *iter;
+    const bin_t *maxiter;
+    //phys_t i;                               /* Boucle de parcours #2       */
+
+    volatile register __m256i xxxx;                           /* Test de correspondances     */
+
+
+    __m256i test;                           /* Test de correspondances     */
+    __m256i test2;                           /* Test de correspondances     */
+    __m256i status;                         /* Statut d'une comparaison    */
+
+    int masks[10];
+
+    int mask;                               /* Masque d'accès rapide       */
+    size_t j;                               /* Boucle de parcours #3       */
+
+
+    int ret;
+
+    //return;
+
+    /* Initialisations diverses */
+
+    manager = &backend->manager_avx2;
+
+    dlen = g_binary_content_compute_size(content);
+
+    g_binary_content_compute_start_pos(content, &pos);
+    data = g_binary_content_get_raw_access(content, &pos, dlen);
+
+    zero = _mm256_set1_epi16(0);
+
+    asm volatile ("nop;nop;nop;nop;nop;nop;nop;nop;nop;");
+
+    xxxx = _mm256_set1_epi8(~1);
+
+    asm volatile ("nop;nop;nop;nop;nop;nop;nop;nop;nop;");
+
+    /* Recherches des chaînes de moins de 8 caractères */
+
+    printf(" --- manager->count_8: %zu\n", manager->count_8);
+
+    ret = 0;
+
+    for (k = 0; k < manager->count_8; k++)
+    {
+        memcpy(&group, manager->strings_8[k], sizeof(grouped_strings_avx2_t));
+
+        //printf(" --- group.used: %zu\n", group.used);
+
+
+        asm volatile
+        (
+            /*
+             * R = _mm256_set1_epi8(~1);
+             *
+             */
+
+            "movabs         $0xfefefefefefefefe, %%rax ; "
+            "vpbroadcastq   %%rax, %[STATE] ; "
+
+            /*
+             *
+             */
+
+            "vmovdqa %[FOUND_SRC], %[FOUND_DST] ; "
+
+            : [STATE] "=v"(R),
+              [FOUND_DST] "=v"(found_masks)
+            : [FOUND_SRC] "m"(group.found_masks)
+            : "memory", "rax"
+
+         );
+
+
+
+
+        //pre_shift_mask = _mm256_set1_epi8(0xef);
+
+        maxiter = data + dlen;
+
+
+
+        for (iter = data; (iter + 10) < maxiter; iter += 10)
+        {
+
+            //printf("--- %llx <-> %c\n", (unsigned long long)(iter - data), *iter);
+
+
+            asm volatile
+            (
+#if 0
+
+                /*
+                 * R = _mm256_or_si256(R, group.pattern_masks[data[i]]);
+                 *
+                 * Latency : 1-9
+                 * Throughput : 0.5
+                 * #Uops : 1-2
+                 * Port Usage : 1*p015+1*p23
+                 *
+                 */
+
+                "vpor   %[PATTERN], %[STATE], %[STATE] ; "
+
+#else
+
+                /*
+                 * %ymm = group.pattern_masks[data[i]];
+                 *
+                 * Latency : 5-8
+                 * Throughput : 0.5
+                 * #Uops : 1
+                 * Port Usage : 1*p23
+                 *
+                 */
+
+                "vmovdqa    %[PATTERN0], %%ymm0 ; "
+                "vmovdqa    %[PATTERN1], %%ymm1 ; "
+                "vmovdqa    %[PATTERN2], %%ymm2 ; "
+                "vmovdqa    %[PATTERN3], %%ymm3 ; "
+                "vmovdqa    %[PATTERN4], %%ymm4 ; "
+                "vmovdqa    %[PATTERN5], %%ymm5 ; "
+                "vmovdqa    %[PATTERN6], %%ymm6 ; "
+                "vmovdqa    %[PATTERN7], %%ymm7 ; "
+                "vmovdqa    %[PATTERN7], %%ymm8 ; "
+                "vmovdqa    %[PATTERN7], %%ymm9 ; "
+
+                /*
+                 * R = _mm256_or_si256(R, %ymm);
+                 *
+                 * Latency : 1
+                 * Throughput : 0.33
+                 * #Uops : 1
+                 * Port Usage : 1*p015
+                 *
+                 */
+
+                "vpor   %%ymm0, %[STATE], %[STATE] ; "
+
+#endif
+
+                /*
+                 * R = _mm256_add_epi8(R, R);
+                 *
+                 * Latency : 1
+                 * Throughput : 0.3
+                 * #Uops : 1
+                 * Port Usage : 1*p015
+                 *
+                 */
+
+                "vpaddb %[STATE], %[STATE], %[STATE] ; "
+
+                /*
+                 * test = _mm256_and_si256(R, group.found_masks);
+                 *
+                 * Latency : 1
+                 * Throughput : 0.33
+                 * #Uops : 1
+                 * Port Usage : 1*p015
+                 *
+                 */
+
+                "vpand  %[FOUND], %[STATE], %%ymm0 ; "
+
+                /* Déroulemets... */
+
+                "vpor   %%ymm1, %[STATE], %[STATE] ; "
+                "vpaddb %[STATE], %[STATE], %[STATE] ; "
+
+                "vpor   %%ymm2, %[STATE], %[STATE] ; "
+                "vpaddb %[STATE], %[STATE], %[STATE] ; "
+
+                "vpor   %%ymm3, %[STATE], %[STATE] ; "
+                "vpaddb %[STATE], %[STATE], %[STATE] ; "
+
+                "vpor   %%ymm4, %[STATE], %[STATE] ; "
+                "vpaddb %[STATE], %[STATE], %[STATE] ; "
+
+                "vpor   %%ymm5, %[STATE], %[STATE] ; "
+                "vpaddb %[STATE], %[STATE], %[STATE] ; "
+
+                "vpor   %%ymm6, %[STATE], %[STATE] ; "
+                "vpaddb %[STATE], %[STATE], %[STATE] ; "
+
+                "vpor   %%ymm7, %[STATE], %[STATE] ; "
+                "vpaddb %[STATE], %[STATE], %[STATE] ; "
+
+                "vpor   %%ymm8, %[STATE], %[STATE] ; "
+                "vpaddb %[STATE], %[STATE], %[STATE] ; "
+
+                "vpor   %%ymm9, %[STATE], %[STATE] ; "
+                "vpaddb %[STATE], %[STATE], %[STATE] ; "
+
+                "vpand  %[FOUND], %[STATE], %%ymm1 ; "
+                "vpand  %[FOUND], %[STATE], %%ymm2 ; "
+                "vpand  %[FOUND], %[STATE], %%ymm3 ; "
+                "vpand  %[FOUND], %[STATE], %%ymm4 ; "
+                "vpand  %[FOUND], %[STATE], %%ymm5 ; "
+                "vpand  %[FOUND], %[STATE], %%ymm6 ; "
+                "vpand  %[FOUND], %[STATE], %%ymm7 ; "
+                "vpand  %[FOUND], %[STATE], %%ymm8 ; "
+                "vpand  %[FOUND], %[STATE], %%ymm9 ; "
+
+
+
+
+
+                /*
+                 * status = _mm256_cmpeq_epi8(test, zero);
+                 *
+                 * Latency : 1
+                 * Throughput : 0.5
+                 * #Uops : 1
+                 * Port Usage : 1*p01
+                 *
+                 */
+
+                "vpcmpeqb   %%ymm0, %[NUL], %%ymm0 ; "
+
+                /*
+                 * mask = _mm256_movemask_epi8(status);
+                 *
+                 * Latency : <5
+                 * Throughput : 1
+                 * #Uops : 1
+                 * Port Usage : 1*p0
+                 *
+                 */
+
+                "vpmovmskb  %%ymm0, %[MASK0] ; "
+
+
+
+
+
+                "vpcmpeqb   %%ymm1, %[NUL], %%ymm1 ; "
+                "vpcmpeqb   %%ymm2, %[NUL], %%ymm2 ; "
+                "vpcmpeqb   %%ymm3, %[NUL], %%ymm3 ; "
+                "vpcmpeqb   %%ymm4, %[NUL], %%ymm4 ; "
+                "vpcmpeqb   %%ymm5, %[NUL], %%ymm5 ; "
+                "vpcmpeqb   %%ymm6, %[NUL], %%ymm6 ; "
+                "vpcmpeqb   %%ymm7, %[NUL], %%ymm7 ; "
+                "vpcmpeqb   %%ymm8, %[NUL], %%ymm8 ; "
+                "vpcmpeqb   %%ymm9, %[NUL], %%ymm9 ; "
+
+
+                "vpmovmskb  %%ymm1, %[MASK1] ; "
+                "vpmovmskb  %%ymm2, %[MASK2] ; "
+                "vpmovmskb  %%ymm3, %[MASK3] ; "
+                "vpmovmskb  %%ymm4, %[MASK4] ; "
+                "vpmovmskb  %%ymm5, %[MASK5] ; "
+                "vpmovmskb  %%ymm6, %[MASK6] ; "
+                "vpmovmskb  %%ymm7, %[MASK7] ; "
+                "vpmovmskb  %%ymm8, %[MASK8] ; "
+                "vpmovmskb  %%ymm9, %[MASK9] ; "
+
+
+
+
+
+
+
+
+
+
+                //"vmovdqa  %%ymm7, %[OUTPUT] ; "
+
+                //"vmovdqa  %%ymm8, %[OUTPUT2] ; "
+
+                : [STATE] "+v"(R),
+                  [OUTPUT] "=v"(test),
+                  [OUTPUT2] "=v"(test2),
+                  [MASK0] "=r"(mask),
+                  [MASK1] "=r"(mask),
+                  [MASK2] "=r"(mask),
+                  [MASK3] "=r"(mask),
+                  [MASK4] "=r"(mask),
+                  [MASK5] "=r"(mask),
+                  [MASK6] "=r"(mask),
+                  [MASK7] "=r"(mask),
+                  [MASK8] "=r"(mask),
+                  [MASK9] "=r"(mask),
+                  [NUL] "+v"(zero)
+                : [PATTERN0] "m"(group./*manager->strings_8[k]->*/pattern_masks[*iter]),
+                  [PATTERN1] "m"(group./*manager->strings_8[k]->*/pattern_masks[*(iter + 1)]),
+                  [PATTERN2] "m"(group./*manager->strings_8[k]->*/pattern_masks[*(iter + 2)]),
+                  [PATTERN3] "m"(group./*manager->strings_8[k]->*/pattern_masks[*(iter + 3)]),
+                  [PATTERN4] "m"(group./*manager->strings_8[k]->*/pattern_masks[*(iter + 4)]),
+                  [PATTERN5] "m"(group./*manager->strings_8[k]->*/pattern_masks[*(iter + 5)]),
+                  [PATTERN6] "m"(group./*manager->strings_8[k]->*/pattern_masks[*(iter + 6)]),
+                  [PATTERN7] "m"(group./*manager->strings_8[k]->*/pattern_masks[*(iter + 7)]),
+                  [PATTERN8] "m"(group./*manager->strings_8[k]->*/pattern_masks[*(iter + 8)]),
+                  [PATTERN9] "m"(group./*manager->strings_8[k]->*/pattern_masks[*(iter + 9)]),
+                  [FOUND] "v"(found_masks)
+                : "memory", "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", "ymm8", "ymm9"
+
+             );
+
+
+            /*
+            printf("        test: %02hhx %02hhx %02hhx %02hhx   %02hhx %02hhx %02hhx %02hhx   ...   %02hhx %02hhx %02hhx %02hhx\n",
+                   ((uint8_t *)&test)[0],
+                   ((uint8_t *)&test)[1],
+                   ((uint8_t *)&test)[2],
+                   ((uint8_t *)&test)[3],
+                   ((uint8_t *)&test)[4],
+                   ((uint8_t *)&test)[5],
+                   ((uint8_t *)&test)[6],
+                   ((uint8_t *)&test)[7],
+                   ((uint8_t *)&test)[16],
+                   ((uint8_t *)&test)[17],
+                   ((uint8_t *)&test)[18],
+                   ((uint8_t *)&test)[19]);
+
+            printf("       test2: %02hhx %02hhx %02hhx %02hhx   %02hhx %02hhx %02hhx %02hhx   ...   %02hhx %02hhx %02hhx %02hhx\n",
+                   ((uint8_t *)&test2)[0],
+                   ((uint8_t *)&test2)[1],
+                   ((uint8_t *)&test2)[2],
+                   ((uint8_t *)&test2)[3],
+                   ((uint8_t *)&test2)[4],
+                   ((uint8_t *)&test2)[5],
+                   ((uint8_t *)&test2)[6],
+                   ((uint8_t *)&test2)[7],
+                   ((uint8_t *)&test2)[16],
+                   ((uint8_t *)&test2)[17],
+                   ((uint8_t *)&test2)[18],
+                   ((uint8_t *)&test2)[19]);
+            */
+
+#if 0
+            //printf(" > %c\n", data[i]);
+
+            R = _mm256_or_si256(R, group.pattern_masks[*iter]);
+
+            //printf("group pattern: %hhx\n", *((uint8_t *)&group.pattern_masks[data[i]]));
+
+            //printf("R:             %hhx\n", *((uint8_t *)&R));
+
+            //R = _mm256_and_si256(R, pre_shift_mask);
+
+            //printf("R after and:   %hhx\n", *((uint8_t *)&R));
+
+            R = _mm256_add_epi8(R, R);
+            //R = _mm256_slli_si256(R, 1);
+
+            //printf("R after shift: %hhx\n", *((uint8_t *)&R));
+
+            test = _mm256_and_si256(R, group.found_masks);
+
+#if 1
+            status = _mm256_cmpeq_epi8(test, zero);
+
+            mask = _mm256_movemask_epi8(status);
+#else
+            //mask = _mm256_movemask_epi8(test) ^ 0xffffffff;
+            mask = _mm256_movemask_epi8(test);
+#endif
+
+
+#endif
+
+
+            //printf("   mask : %x\n", mask);
+
+            if (mask != 0)
+                for (j = 0; j < group.used; j++)
+                {
+                    if ((mask & 0x1) == 1)
+                    {
+                        //assert((i + 1) >= group.m[j]);
+
+                        g_scan_context_register_atom_match(context,
+                                                           group.found_id[j],
+                                                           (iter - data) + 1 - group.m[j]);
+
+                    }
+
+                    mask >>= 1;
+
+                }
+
+        }
+
+
+
+
+
+#if 0
+        for (; iter < maxiter; iter++)
+        {
+
+            //printf("--- %llx <-> %c\n", (unsigned long long)(iter - data), *iter);
+
+
+            asm volatile
+            (
+                /*
+                 * R = _mm256_or_si256(R, group.pattern_masks[data[i]]);
+                 *
+                 * Latency : 1
+                 * Throughput : 0.33
+                 * #Uops : 1
+                 * Port Usage : 1*p015
+                 *
+                 */
+
+                "vpor   %[PATTERN], %[STATE], %[STATE] ; "
+
+                /*
+                 * R = _mm256_add_epi8(R, R);
+                 *
+                 * Latency : 1
+                 * Throughput : 0.3
+                 * #Uops : 1
+                 * Port Usage : 1*p015
+                 *
+                 */
+
+                "vpaddb %[STATE], %[STATE], %[STATE] ; "
+
+                /*
+                 * test = _mm256_and_si256(R, group.found_masks);
+                 *
+                 * Latency : 1
+                 * Throughput : 0.33
+                 * #Uops : 1
+                 * Port Usage : 1*p015
+                 *
+                 */
+
+                "vpand  %[FOUND], %[STATE], %%ymm7 ; "
+
+                /*
+                 * status = _mm256_cmpeq_epi8(test, zero);
+                 *
+                 * Latency : 1
+                 * Throughput : 0.5
+                 * #Uops : 1
+                 * Port Usage : 1*p01
+                 *
+                 */
+
+                "vpcmpeqb   %%ymm7, %[NUL], %%ymm8 ; "
+
+                /*
+                 * mask = _mm256_movemask_epi8(status);
+                 *
+                 * Latency : <5
+                 * Throughput : 1
+                 * #Uops : 1
+                 * Port Usage : 1*p0
+                 *
+                 */
+
+                "vpmovmskb  %%ymm8, %[MASK0] ; "
+
+
+                //"vmovdqa  %%ymm7, %[OUTPUT] ; "
+
+                //"vmovdqa  %%ymm8, %[OUTPUT2] ; "
+
+                : [STATE] "+v"(R),
+                  [OUTPUT] "=v"(test),
+                  [OUTPUT2] "=v"(test2),
+                  [MASK0] "=r"(mask),
+                  [NUL] "+v"(zero)
+                : [PATTERN] "m"(group./*manager->strings_8[k]->*/pattern_masks[*iter]),
+                  [FOUND] "v"(found_masks)
+                : "memory", "ymm7", "ymm8"
+
+             );
+
+
+            /*
+            printf("        test: %02hhx %02hhx %02hhx %02hhx   %02hhx %02hhx %02hhx %02hhx   ...   %02hhx %02hhx %02hhx %02hhx\n",
+                   ((uint8_t *)&test)[0],
+                   ((uint8_t *)&test)[1],
+                   ((uint8_t *)&test)[2],
+                   ((uint8_t *)&test)[3],
+                   ((uint8_t *)&test)[4],
+                   ((uint8_t *)&test)[5],
+                   ((uint8_t *)&test)[6],
+                   ((uint8_t *)&test)[7],
+                   ((uint8_t *)&test)[16],
+                   ((uint8_t *)&test)[17],
+                   ((uint8_t *)&test)[18],
+                   ((uint8_t *)&test)[19]);
+
+            printf("       test2: %02hhx %02hhx %02hhx %02hhx   %02hhx %02hhx %02hhx %02hhx   ...   %02hhx %02hhx %02hhx %02hhx\n",
+                   ((uint8_t *)&test2)[0],
+                   ((uint8_t *)&test2)[1],
+                   ((uint8_t *)&test2)[2],
+                   ((uint8_t *)&test2)[3],
+                   ((uint8_t *)&test2)[4],
+                   ((uint8_t *)&test2)[5],
+                   ((uint8_t *)&test2)[6],
+                   ((uint8_t *)&test2)[7],
+                   ((uint8_t *)&test2)[16],
+                   ((uint8_t *)&test2)[17],
+                   ((uint8_t *)&test2)[18],
+                   ((uint8_t *)&test2)[19]);
+            */
+
+#if 0
+            //printf(" > %c\n", data[i]);
+
+            R = _mm256_or_si256(R, group.pattern_masks[*iter]);
+
+            //printf("group pattern: %hhx\n", *((uint8_t *)&group.pattern_masks[data[i]]));
+
+            //printf("R:             %hhx\n", *((uint8_t *)&R));
+
+            //R = _mm256_and_si256(R, pre_shift_mask);
+
+            //printf("R after and:   %hhx\n", *((uint8_t *)&R));
+
+            R = _mm256_add_epi8(R, R);
+            //R = _mm256_slli_si256(R, 1);
+
+            //printf("R after shift: %hhx\n", *((uint8_t *)&R));
+
+            test = _mm256_and_si256(R, group.found_masks);
+
+#if 1
+            status = _mm256_cmpeq_epi8(test, zero);
+
+            mask = _mm256_movemask_epi8(status);
+#else
+            //mask = _mm256_movemask_epi8(test) ^ 0xffffffff;
+            mask = _mm256_movemask_epi8(test);
+#endif
+
+
+#endif
+
+
+            //printf("   mask : %x\n", mask);
+
+            if (mask != 0)
+                for (j = 0; j < group.used; j++)
+                {
+                    if ((mask & 0x1) == 1)
+                    {
+                        //assert((i + 1) >= group.m[j]);
+
+                        g_scan_context_register_atom_match(context,
+                                                           group.found_id[j],
+                                                           (iter - data) + 1 - group.m[j]);
+
+                    }
+
+                    mask >>= 1;
+
+                }
+
+        }
+
+#endif
+
+
+    }
+
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#if 0
+
+
+#if 0
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à manipuler.                   *
+*                context = lieu d'enregistrement des résultats.               *
+*                content = données binaires à analyser.                       *
+*                                                                             *
+*  Description : Parcours un contenu binaire à la recherche de motifs.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void run_scan_avx2(const GBitapBackend *backend, GScanContext *context, GBinContent *content)
+{
+    const group_manager_avx2_t *manager;    /* Accès simplifié             */
+
+    grouped_strings_avx2_t groups[10];           /* Copie pour accès locaux     */
+
+
+    phys_t dlen;                            /* Quantité de données         */
+    vmpa2t pos;                             /* Point de départ ciblé       */
+    const bin_t *data;                      /* Données à analyser          */
+    __m256i zero;                           /* Constante 0 sur 256 bits    */
+    size_t k;                               /* Boucle de parcours #1       */
+
+    grouped_strings_avx2_t group;          /* Copie pour accès locaux     */
+    __m256i R;                              /* Résultats courants          */
+    __m256i pre_shift_mask;                 /* Préparation de décalage     */
+    phys_t i;                               /* Boucle de parcours #2       */
+    __m256i test;                           /* Test de correspondances     */
+    __m256i status;                         /* Statut d'une comparaison    */
+    int mask;                               /* Masque d'accès rapide       */
+    size_t j;                               /* Boucle de parcours #3       */
+
+    uint32_t leaves;
+    int ret;
+
+
+    phys_t old_i;
+    phys_t p;
+
+    //return;
+
+    /* Initialisations diverses */
+
+    manager = &backend->manager_avx2;
+
+    dlen = g_binary_content_compute_size(content);
+
+    g_binary_content_compute_start_pos(content, &pos);
+    data = g_binary_content_get_raw_access(content, &pos, dlen);
+
+    zero = _mm256_set1_epi16(0);
+
+    /* Recherches des chaînes de moins de 8 caractères */
+
+    printf(" --- manager->count_8: %zu\n", manager->count_8);
+
+    ret = 0;
+
+    //for (k = 0; k < manager->count_8; k++)
+    //    memcpy(&groups[k], manager->strings_8[k], sizeof(grouped_strings_avx2_t));
+
+
+    for (i = 0; i < dlen; )
+    {
+
+        //printf(" --- %llx\n", (unsigned long long)i);
+
+        p = i + 4096;
+
+        if (p > dlen)
+            p = dlen;
+
+        old_i = i;
+
+        printf("old_i: %llx\n", (unsigned long long)old_i);
+
+        for (k = 0; k < manager->count_8; k++)
+        {
+
+            group = *manager->strings_8[k];
+
+            R = group.R;
+
+            for (i = old_i ; i < p; i++)
+            {
+
+                //group = &groups[k];
+
+                //printf(" k: %zu  i: %llx\n", k, (unsigned long long)i);
+
+                //R = group.R;//_mm256_set1_epi8(~1);
+
+                R = _mm256_or_si256(R, group.pattern_masks[data[i]]);
+
+                R = _mm256_add_epi8(R, R);
+
+                test = _mm256_and_si256(R, group.found_masks);
+
+#if 0
+                status = _mm256_cmpeq_epi8(test, zero);
+
+                mask = _mm256_movemask_epi8(status);
+#else
+                //mask = _mm256_movemask_epi8(test) ^ 0xffffffff;
+                mask = _mm256_movemask_epi8(test);
+#endif
+
+                if (mask != 0xffffffff)
+                {
+                    leaves = group.leaves;
+
+                    for (j = 0; j < group.used; j++)
+                    {
+                        if ((mask & 0x1) == 0)
+                        {
+                            if (leaves & 0x1) //group.leaves & (1u << j))
+                                ;//define_full_match_avx2(backend, context, content, &group, j, i + 1);
+
+                        }
+
+                        mask >>= 1;
+
+                        leaves >>= 1;
+
+                    }
+
+                }
+
+                group.R = R;//_mm256_set1_epi8(~1);
+
+                memcpy(manager->strings_8[k], &group, sizeof(grouped_strings_avx2_t));
+
+            }
+
+
+        }
+
+    }
+
+    printf("oh: %d\n", ret);
+
+
+}
+
+
+#else
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à manipuler.                   *
+*                context = lieu d'enregistrement des résultats.               *
+*                content = données binaires à analyser.                       *
+*                                                                             *
+*  Description : Parcours un contenu binaire à la recherche de motifs.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void run_scan_avx2(const GBitapBackend *backend, GScanContext *context, GBinContent *content)
+{
+    const group_manager_avx2_t *manager;    /* Accès simplifié             */
+    phys_t dlen;                            /* Quantité de données         */
+    vmpa2t pos;                             /* Point de départ ciblé       */
+    const bin_t *data;                      /* Données à analyser          */
+    __m256i zero;                           /* Constante 0 sur 256 bits    */
+    size_t k;                               /* Boucle de parcours #1       */
+    grouped_strings_avx2_t group;           /* Copie pour accès locaux     */
+    __m256i R;                              /* Résultats courants          */
+    __m256i pre_shift_mask;                 /* Préparation de décalage     */
+    phys_t i;                               /* Boucle de parcours #2       */
+    __m256i test;                           /* Test de correspondances     */
+    __m256i status;                         /* Statut d'une comparaison    */
+    int mask;                               /* Masque d'accès rapide       */
+    size_t j;                               /* Boucle de parcours #3       */
+
+    uint32_t leaves;
+    int ret;
+
+    //return;
+
+    /* Initialisations diverses */
+
+    manager = &backend->manager_avx2;
+
+    dlen = g_binary_content_compute_size(content);
+
+    g_binary_content_compute_start_pos(content, &pos);
+    data = g_binary_content_get_raw_access(content, &pos, dlen);
+
+    zero = _mm256_set1_epi16(0);
+
+    /* Recherches des chaînes de moins de 8 caractères */
+
+    printf(" --- manager->count_8: %zu\n", manager->count_8);
+
+    ret = 0;
+
+    for (k = 0; k < manager->count_8; k++)
+    {
+        memcpy(&group, manager->strings_8[k], sizeof(grouped_strings_avx2_t));
+
+        //printf(" --- group.used: %zu\n", group.used);
+
+        R = _mm256_set1_epi8(~1);
+
+        //pre_shift_mask = _mm256_set1_epi8(0xef);
+
+        for (i = 0; i < dlen; ++i)
+        {
+            //printf(" > %c\n", data[i]);
+
+            R = _mm256_or_si256(R, group.pattern_masks[data[i]]);
+
+            //printf("group pattern: %hhx\n", *((uint8_t *)&group.pattern_masks[data[i]]));
+
+            //printf("R:             %hhx\n", *((uint8_t *)&R));
+
+            //R = _mm256_and_si256(R, pre_shift_mask);
+
+            //printf("R after and:   %hhx\n", *((uint8_t *)&R));
+
+            R = _mm256_add_epi8(R, R);
+            //R = _mm256_slli_si256(R, 1);
+
+            //printf("R after shift: %hhx\n", *((uint8_t *)&R));
+
+            test = _mm256_and_si256(R, group.found_masks);
+
+#if 0
+            status = _mm256_cmpeq_epi8(test, zero);
+
+            mask = _mm256_movemask_epi8(status);
+#else
+            //mask = _mm256_movemask_epi8(test) ^ 0xffffffff;
+            mask = _mm256_movemask_epi8(test);
+#endif
+
+            if (mask != 0xffffffff)
+            {
+                leaves = group.leaves;
+
+                for (j = 0; j < group.used; j++)
+                {
+                    if ((mask & 0x1) == 0)
+                    {
+                        //assert((i + 1) >= group.m[j]);
+
+                        if (leaves & 0x1) //group.leaves & (1u << j))
+                            define_full_match_avx2(backend, context, content, &group, j, i + 1);
+                        //else
+                        //{
+                        //    ret++;
+                            //printf("%x\n", (unsigned int)i + 1);
+                        //}
+                        //else
+                            //  g_scan_context_register_sub_match(context, group.found_id[j], i + 1 - group.m[j]);
+
+                    }
+
+                    mask >>= 1;
+
+                    leaves >>= 1;
+
+                }
+
+            }
+
+        }
+
+    }
+
+    printf("oh: %d\n", ret);
+
+    /* Recherches des chaînes de moins de 16 caractères */
+
+    for (k = 0; k < manager->count_16; k++)
+    {
+        memcpy(&group, manager->strings_16[k], sizeof(grouped_strings_avx2_t));
+
+        R = _mm256_set1_epi16(~1);
+
+        for (i = 0; i < dlen; ++i)
+        {
+            R = _mm256_or_si256(R, group.pattern_masks[data[i]]);
+            R = _mm256_slli_epi16(R, 1);
+
+            test = _mm256_and_si256(R, group.found_masks);
+
+            status = _mm256_cmpeq_epi16(test, zero);
+
+            mask = _mm256_movemask_epi8(status);
+
+            if (mask != 0)
+                for (j = 0; j < group.used; j++)
+                {
+                    if (mask & 0x3)
+                    {
+                        assert((i + 1) >= group.m[j]);
+
+                        if (group.leaves & (1llu << j))
+                            define_full_match_avx2(backend, context, content, &group, j, i + 1);
+                        else
+                            ;//g_scan_context_register_sub_match(context, group.found_id[j], i + 1 - group.m[j]);
+
+                    }
+
+                    mask >>= 2;
+
+                }
+
+        }
+
+    }
+
+}
+
+#endif
+
+
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       OPTIMISATIONS POUR ARCHITECTURE AVX512                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/**
+ * Cf. https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#techs=AVX_512
+ *   - https://agner.org/optimize/
+ *   - https://uops.info/table.html
+ */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : strings = ensemble de groupes constitués. [OUT]              *
+*                count   = nombre de groupes courant. [OUT]                   *
+*                                                                             *
+*  Description : Indique la valeur portée par une expression rationnelle.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void extend_grouped_strings_avx512(grouped_strings_avx512_t ***strings, size_t *count)
+{
+    grouped_strings_avx512_t *new;          /* Zone supplémentaire         */
+    size_t i;                               /* Boucle de parcours          */
+
+    /* Définition d'un nouvel élément vierge */
+
+    new = aligned_alloc(0x1000, sizeof(grouped_strings_avx512_t));
+
+    for (i = 0; i < 256; i++)
+        new->pattern_masks[i] = _mm512_set1_epi8(~0);
+
+    new->found_masks = _mm512_set1_epi8(~0);
+
+    new->R = _mm512_set1_epi8(~1);
+
+    for (i = 0; i < 64; i++)
+    {
+        new->m[i] = 0;
+
+        new->found_id[i] = INVALID_PATTERN_ID;
+
+    }
+
+    new->available = 64;
+    new->used = 0;
+
+    /* Inscription */
+
+    *strings = realloc(*strings, ++(*count) * sizeof(grouped_strings_avx512_t *));
+
+    (*strings)[*count - 1] = new;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à manipuler.                   *
+*                context = contexte de l'analyse à mener.                     *
+*                plain   = chaîne de caractères classique à intégrer.         *
+*                plen    = taille de cette chaîne.                            *
+*                                                                             *
+*  Description : Inscrit dans le moteur une chaîne de caractères à rechercher.*
+*                                                                             *
+*  Retour      : Indice de résultats pour le motif.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static patid_t enroll_plain_pattern_avx512(GBitapBackend *backend, GScanContext *context, const bin_t *plain, size_t plen)
+{
+    patid_t result;                         /* Identifiant à retourner     */
+    grouped_strings_avx512_t ***strings;    /* Groupe de chaînes visé      */
+    size_t *count;                          /* Taille de ce groupe         */
+    grouped_strings_avx512_t *last;         /* Dernier groupe à remplir    */
+    size_t n;                               /* Indice dans le groupe       */
+    size_t i;                               /* Boucle de parcours          */
+    __m512i *letter;                        /* Lettre à marquer            */
+
+    /* Sélection du groupe de travail adéquat */
+
+    strings = &backend->manager_avx512.strings_8;
+    count = &backend->manager_avx512.count_8;
+
+    /* Préparation de la place nécessaire */
+
+    if (*count == 0)
+    {
+        extend_grouped_strings_avx512(strings, count);
+
+        last = (*strings)[0];
+
+    }
+
+    else
+    {
+        last = (*strings)[*count - 1];
+
+        if (last->used == last->available)
+        {
+            extend_grouped_strings_avx512(strings, count);
+            last = (*strings)[*count - 1];
+        }
+
+    }
+
+    /* Intégration d'une nouvelle chaîne */
+
+    n = last->used++;
+
+    last->m[n] = plen;
+
+    result = g_scan_context_get_new_pattern_id(context);
+
+    last->found_id[n] = result;
+
+    ((uint8_t *)&last->found_masks)[n] = (1 << plen);
+
+    for (i = 0; i < plen; i++)
+    {
+        letter = last->pattern_masks + plain[i];
+        ((uint8_t *)letter)[n] &= ~(1 << i);
+    }
+
+    return result;
+
+}
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à manipuler.                   *
+*                context = lieu d'enregistrement des résultats.               *
+*                content = données binaires à analyser.                       *
+*                                                                             *
+*  Description : Parcours un contenu binaire à la recherche de motifs.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void run_scan_avx512(const GBitapBackend *backend, GScanContext *context, GBinContent *content)
+{
+    const group_manager_avx512_t *manager;  /* Accès simplifié             */
+    phys_t dlen;                            /* Quantité de données         */
+    vmpa2t pos;                             /* Point de départ ciblé       */
+    const bin_t *data;                      /* Données à analyser          */
+
+    //register __m512i zero asm("zmm19");                           /* Constante 0 sur 512 bits    */
+
+    //__m512i shift8_mask;                    /* Masque pour décalage manuel */
+
+
+    size_t k;                               /* Boucle de parcours #1       */
+    /*__attribute__((aligned(0x1000)))*/ grouped_strings_avx512_t group;         /* Copie pour accès locaux     */
+    //void *grpptr;
+    //grouped_strings_avx512_t *_group;       /* Copie pour accès locaux     */
+
+    int ret;
+
+
+    register __m512i R asm("zmm28");                              /* Résultats courants          */
+    register __m512i found_masks asm("zmm21"); /* Vérifications accélérées  */
+
+
+    register __mmask64 test_mask asm("k6");
+
+
+    register const bin_t *iter asm("rsi");
+    register const bin_t *maxiter/* asm("rdi")*/;
+    //phys_t i;                               /* Boucle de parcours #2       */
+
+
+    //__m512i test;
+
+    __mmask64 mask;                         /* Masque d'accès rapide       */
+    size_t j;                               /* Boucle de parcours #3       */
+
+
+    /* Initialisations diverses */
+
+    manager = &backend->manager_avx512;
+
+    dlen = g_binary_content_compute_size(content);
+
+    g_binary_content_compute_start_pos(content, &pos);
+    data = g_binary_content_get_raw_access(content, &pos, dlen);
+
+
+
+    /* Recherches des chaînes de moins de 8 caractères */
+
+    //asm volatile ("nop; nop; nop; nop; nop; nop; nop; ");
+
+    //zero = _mm512_set1_epi8(0);
+
+    //asm volatile ("nop; nop; nop; nop; nop; nop; nop; ");
+
+    //shift8_mask = _mm512_set1_epi8(0x7f);
+
+
+
+#define WORK_ON_COPY
+
+    for (k = 0; k < manager->count_8; k++)
+    {
+#ifdef WORK_ON_COPY
+        memcpy(&group, manager->strings_8[k], sizeof(grouped_strings_avx512_t));
+
+#else
+
+        grpptr = alloca(sizeof(grouped_strings_avx512_t) + 0x1000);
+
+        _group = grpptr + 0x1000 - (((unsigned long)grpptr) % 0x1000);
+
+        //_group = manager->strings_8[k];
+
+        memcpy(_group, manager->strings_8[k], sizeof(grouped_strings_avx512_t));
+
+        ret = mlock(_group, sizeof(grouped_strings_avx512_t));
+
+        printf("ret = %d\n", ret);
+#endif
+
+
+
+        //printf(" --- group %p  --  used: %zu (sz: %zu)\n", &group, group.used, sizeof(grouped_strings_avx512_t));
+        //printf(" --- group.used: %zu (sz: %zu)\n", group.used, sizeof(grouped_strings_avx512_t));
+
+
+        asm volatile
+        (
+            /*
+             * R = _mm512_set1_epi8(~1);
+             *
+             */
+
+            "movabs         $0xfefefefefefefefe, %%rax ; "
+            "vpbroadcastq   %%rax, %[STATE] ; "
+
+            "movabs         $0xffffffffffffffff, %%rax ; "
+            "kmovq          %%rax, %[KMASK] ; "
+
+            /*
+             *
+             */
+
+            "vmovdqa64 %[FOUND_SRC], %[FOUND_DST] ; "
+
+            : [STATE] "=v"(R),
+              [KMASK] "=Yk"(test_mask),
+              [FOUND_DST] "=v"(found_masks)
+#ifdef WORK_ON_COPY
+            : [FOUND_SRC] "m"(group.found_masks)
+#else
+            : [FOUND_SRC] "m"(_group->found_masks)
+#endif
+            : "memory", "rax"
+
+         );
+
+
+
+
+
+
+
+        //for (i = 0; i < dlen; i++)
+
+        maxiter = data + dlen;
+
+        for (iter = data; iter < maxiter; iter++)
+        {
+
+            //printf("--- %llx <-> %c\n", (unsigned long long)(iter - data), *iter);
+
+
+            asm volatile goto
+            (
+                /*
+                 * R = _mm512_or_si512(R, group.pattern_masks[*iter]);
+                 *
+                 * Latency : 1-9
+                 * Throughput : 0.5
+                 * #Uops : 1-2
+                 * Port Usage : 1*p05+1*p23
+                 *
+                 */
+
+                "vpord  %[PATTERN], %[STATE], %[STATE] ; "
+
+                /*
+                 * R = _mm512_add_epi8(R, R);
+                 *
+                 * Latency : 1
+                 * Throughput : 0.5
+                 * #Uops : 1
+                 * Port Usage : 1*p05
+                 *
+                 */
+
+                "vpaddb %[STATE], %[STATE], %[STATE] ; "
+
+                /*
+                 * mask = _mm512_test_epi8_mask(R, group.found_masks);
+                 *
+                 * Latency : 3
+                 * Throughput : 1
+                 * #Uops : 2
+                 * Port Usage : 1*p23+1*p5
+                 *
+                 */
+
+                /******************************
+                 * Version 0
+
+                ******************/
+
+                //"vptestmb   %[FOUND], %[STATE], %%k7 ; "
+
+                /******************************
+                 * Version 1
+
+                "vmovdqa64  %[STATE], %%zmm12 ; "
+
+                "vptestmb   %[FOUND], %%zmm12, %%k7 ; "
+
+                ******************/
+
+                /******************************
+                 * Version 2
+
+                "vpandd     %[STATE], %[FOUND], %%zmm12 ; "
+
+                "vpcmpneqb  %[NUL], %%zmm12, %%k7 ; "
+
+                ******************/
+
+
+                "vmovdqa64  %[STATE], %%zmm12 ; "
+
+                "vptestmb   %[FOUND], %%zmm12, %%k7 ; "
+
+
+                "ktestq %[KMASK], %%k7 ; "
+
+                "jc %l[next_iter] ; "
+
+
+
+
+
+                /*
+                 * (suite)
+                 *
+                 * Latency : 3
+                 * Throughput : 1
+                 * #Uops : 1
+                 * Port Usage : 1*p5
+                 *
+                 */
+
+                "kmovq  %%k7, %[MASK0] ; "
+
+                //"vmovdqa64  %%zmm12, %[OUTPUT] ; "
+
+                //"nop; nop; nop; nop; nop; nop; nop; nop; "
+                //"nop; nop; nop; nop; nop; nop; nop; nop; "
+
+                : [STATE] "+v"(R),
+                  //[OUTPUT] "=v"(test),
+                  [MASK0] "=r"(mask)
+                  //[NUL] "=v"(zero)
+#ifdef WORK_ON_COPY
+                : [PATTERN] "m"(group.pattern_masks[*iter]),
+#else
+                : [PATTERN] "m"(_group->pattern_masks[*iter]),
+#endif
+                  [FOUND] "v"(found_masks),
+                  [KMASK] "Yk"(test_mask)
+                : "memory", "k7", "zmm12"
+                : next_iter
+
+             );
+
+
+
+
+            /*
+            printf("  found mask: %hhx %hhx %hhx %hhx   %hhx %hhx %hhx %hhx\n",
+                   ((uint8_t *)&group.found_masks)[0],
+                   ((uint8_t *)&group.found_masks)[1],
+                   ((uint8_t *)&group.found_masks)[2],
+                   ((uint8_t *)&group.found_masks)[3],
+                   ((uint8_t *)&group.found_masks)[4],
+                   ((uint8_t *)&group.found_masks)[5],
+                   ((uint8_t *)&group.found_masks)[6],
+                   ((uint8_t *)&group.found_masks)[7]);
+
+
+            printf("        test: %hhx %hhx %hhx %hhx   %hhx %hhx %hhx %hhx\n",
+                   ((uint8_t *)&test)[0],
+                   ((uint8_t *)&test)[1],
+                   ((uint8_t *)&test)[2],
+                   ((uint8_t *)&test)[3],
+                   ((uint8_t *)&test)[4],
+                   ((uint8_t *)&test)[5],
+                   ((uint8_t *)&test)[6],
+                   ((uint8_t *)&test)[7]);
+
+
+            printf("  -> mask: 0x%llx\n", (unsigned long long)mask);
+            */
+
+
+#ifdef WORK_ON_COPY
+
+            //if (mask != 0xffffffffffffffffllu)
+                for (j = 0; j < group.used; j++)
+                {
+                    if ((mask & 0x1) == 0)
+                    {
+                        //assert((i + 1) >= group.m[j]);
+
+                        g_scan_context_register_atom_match(context,
+                                                           group.found_id[j],
+                                                           (iter - data) + 1 - group.m[j]);
+
+                    }
+
+                    mask >>= 1;
+
+                }
+
+#else
+
+#   error "WEFEF"
+
+            if (mask != 0xffffffffffffffffllu)
+                for (j = 0; j < _group->used; j++)
+                {
+                    if ((mask & 0x1) == 0)
+                    {
+                        //assert((i + 1) >= group.m[j]);
+
+                        g_scan_context_register_atom_match(context,
+                                                           _group->found_id[j],
+                                                           (iter - data) + 1 - _group->m[j]);
+
+                    }
+
+                    mask >>= 1;
+
+                }
+
+#endif
+
+
+            next_iter:
+
+            //;
+
+            //iter++;
+
+        }
+
+    }
+
+}
+
+
+
+
+
+
+
+
+
+
+
+#if 0
+
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à manipuler.                   *
+*                context = lieu d'enregistrement des résultats.               *
+*                content = données binaires à analyser.                       *
+*                                                                             *
+*  Description : Parcours un contenu binaire à la recherche de motifs.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void run_scan_avx512____good_asm_perfs(const GBitapBackend *backend, GScanContext *context, GBinContent *content)
+{
+    const group_manager_avx512_t *manager;  /* Accès simplifié             */
+    phys_t dlen;                            /* Quantité de données         */
+    vmpa2t pos;                             /* Point de départ ciblé       */
+    const bin_t *data;                      /* Données à analyser          */
+
+
+    //__m512i shift8_mask;                    /* Masque pour décalage manuel */
+
+
+    size_t k;                               /* Boucle de parcours #1       */
+    grouped_strings_avx512_t group;         /* Copie pour accès locaux     */
+
+    register __m512i found_masks asm("zmm21"); /* Vérifications accélérées  */
+
+
+    //register volatile __m512i zero/* asm("zmm19")*/;                           /* Constante 0 sur 512 bits    */
+    register __m512i R asm("zmm28");                              /* Résultats courants          */
+
+    //int counter;
+
+    const bin_t *iter;
+    const bin_t *maxiter;
+    //phys_t i;                               /* Boucle de parcours #2       */
+
+
+    __m512i test;
+
+    __mmask64 mask;                         /* Masque d'accès rapide       */
+    size_t j;                               /* Boucle de parcours #3       */
+
+
+    //register __m512i z30 asm("zmm30");
+
+
+    //return;
+
+
+    //counter = 0;
+
+    //return;
+
+    /* Initialisations diverses */
+
+    manager = &backend->manager_avx512;
+
+    dlen = g_binary_content_compute_size(content);
+
+    g_binary_content_compute_start_pos(content, &pos);
+    data = g_binary_content_get_raw_access(content, &pos, dlen);
+
+    /* Recherches des chaînes de moins de 8 caractères */
+
+    printf(" --- manager512->count_8: %zu\n", manager->count_8);
+
+    asm volatile ("nop; nop; nop; nop; nop; nop; nop; ");
+
+    //zero = _mm512_set1_epi8(0);
+
+    asm volatile ("nop; nop; nop; nop; nop; nop; nop; ");
+
+    //shift8_mask = _mm512_set1_epi8(0x7f);
+
+
+    for (k = 0; k < manager->count_8; k++)
+    {
+        memcpy(&group, manager->strings_8[k], sizeof(grouped_strings_avx512_t));
+
+
+
+
+        //printf(" --- group %p  --  used: %zu (sz: %zu)\n", &group, group.used, sizeof(grouped_strings_avx512_t));
+        //printf(" --- group.used: %zu (sz: %zu)\n", group.used, sizeof(grouped_strings_avx512_t));
+
+
+        asm volatile
+        (
+            /*
+             * R = _mm512_set1_epi8(~1);
+             *
+             */
+
+            "movabs         $0xfefefefefefefefe, %%rax ; "
+            "vpbroadcastq   %%rax, %[STATE] ; "
+
+            /*
+             *
+             */
+
+            "vmovdqa64 %[FOUND_SRC], %[FOUND_DST] ; "
+
+            : [STATE] "=v"(R),
+              [FOUND_DST] "=v"(found_masks)
+            : [FOUND_SRC] "m"(group.found_masks)
+            : "memory", "rax"
+
+         );
+
+
+
+
+
+
+
+        //for (i = 0; i < dlen; i++)
+
+        maxiter = data + dlen;
+
+        for (iter = data; iter < maxiter; iter++)
+        {
+
+            //printf("--- %llx <-> %c\n", (unsigned long long)(iter - data), *iter);
+
+
+            asm volatile
+            (
+
+                /*
+                 * R = _mm512_or_si512(R, group.pattern_masks[*iter]);
+                 *
+                 * Latency : 1-9
+                 * Throughput : 0.5
+                 * #Uops : 1-2
+                 * Port Usage : 1*p05+1*p23
+                 *
+                 */
+
+                "vpord  %[PATTERN], %[STATE], %[STATE] ; "
+
+                /*
+                 * R = _mm512_add_epi8(R, R);
+                 *
+                 * Latency : 1
+                 * Throughput : 0.5
+                 * #Uops : 1
+                 * Port Usage : 1*p05
+                 *
+                 */
+
+                "vpaddb   %[STATE], %[STATE], %[STATE] ; "
+
+                /*
+                 * mask = _mm512_test_epi8_mask(R, group.found_masks);
+                 *
+                 * Latency : 3
+                 * Throughput : 1
+                 * #Uops : 2
+                 * Port Usage : 1*p23+1*p5
+                 *
+                 */
+
+                /******************************
+                 * Version 0
+
+                ******************/
+
+                "vptestmb   %[FOUND], %[STATE], %%k7 ; "
+
+                /******************************
+                 * Version 1
+
+                "vmovdqa64  %[STATE], %%zmm12 ; "
+
+                "vptestmb   %[FOUND], %%zmm12, %%k0 ; "
+
+                ******************/
+
+                /******************************
+                 * Version 2
+
+                "vpandd     %[STATE], %[FOUND], %%zmm12 ; "
+
+                "vpcmpneqb  %[NUL], %%zmm12, %%k7 ; "
+
+                ******************/
+
+                /*
+                 * (suite)
+                 *
+                 * Latency : 3
+                 * Throughput : 1
+                 * #Uops : 1
+                 * Port Usage : 1*p5
+                 *
+                 */
+
+                "kmovq  %%k7, %[MASK0] ; "
+
+                //"vmovdqa64  %%zmm12, %[OUTPUT] ; "
+
+                //"nop; nop; nop; nop; nop; nop; nop; nop; "
+                //"nop; nop; nop; nop; nop; nop; nop; nop; "
+
+                : [STATE] "+v"(R),
+                  [OUTPUT] "=v"(test),
+                  [MASK0] "=r"(mask)/*,
+                  [NUL] "+v"(zero)*/
+                : [PATTERN] "v"(group.pattern_masks[*iter]),
+                  [FOUND] "v"(found_masks)
+                : "memory", "k0", "zmm12"
+
+             );
+
+
+
+
+            /*
+            printf("  found mask: %hhx %hhx %hhx %hhx   %hhx %hhx %hhx %hhx\n",
+                   ((uint8_t *)&group.found_masks)[0],
+                   ((uint8_t *)&group.found_masks)[1],
+                   ((uint8_t *)&group.found_masks)[2],
+                   ((uint8_t *)&group.found_masks)[3],
+                   ((uint8_t *)&group.found_masks)[4],
+                   ((uint8_t *)&group.found_masks)[5],
+                   ((uint8_t *)&group.found_masks)[6],
+                   ((uint8_t *)&group.found_masks)[7]);
+
+
+            printf("        test: %hhx %hhx %hhx %hhx   %hhx %hhx %hhx %hhx\n",
+                   ((uint8_t *)&test)[0],
+                   ((uint8_t *)&test)[1],
+                   ((uint8_t *)&test)[2],
+                   ((uint8_t *)&test)[3],
+                   ((uint8_t *)&test)[4],
+                   ((uint8_t *)&test)[5],
+                   ((uint8_t *)&test)[6],
+                   ((uint8_t *)&test)[7]);
+
+
+            printf("  -> mask: 0x%llx\n", (unsigned long long)mask);
+            */
+
+#if 0
+
+            /*
+            printf("           R: %hhx %hhx %hhx %hhx   %hhx %hhx %hhx %hhx\n",
+                   ((uint8_t *)&R)[0],
+                   ((uint8_t *)&R)[1],
+                   ((uint8_t *)&R)[2],
+                   ((uint8_t *)&R)[3],
+                   ((uint8_t *)&R)[4],
+                   ((uint8_t *)&R)[5],
+                   ((uint8_t *)&R)[6],
+                   ((uint8_t *)&R)[7]);
+
+            printf("  found mask: %hhx %hhx %hhx %hhx   %hhx %hhx %hhx %hhx\n",
+                   ((uint8_t *)&group.found_masks)[0],
+                   ((uint8_t *)&group.found_masks)[1],
+                   ((uint8_t *)&group.found_masks)[2],
+                   ((uint8_t *)&group.found_masks)[3],
+                   ((uint8_t *)&group.found_masks)[4],
+                   ((uint8_t *)&group.found_masks)[5],
+                   ((uint8_t *)&group.found_masks)[6],
+                   ((uint8_t *)&group.found_masks)[7]);
+            */
+
+            /*
+
+            printf("        test: %hhx %hhx %hhx %hhx   %hhx %hhx %hhx %hhx\n",
+                   ((uint8_t *)&test)[0],
+                   ((uint8_t *)&test)[1],
+                   ((uint8_t *)&test)[2],
+                   ((uint8_t *)&test)[3],
+                   ((uint8_t *)&test)[4],
+                   ((uint8_t *)&test)[5],
+                   ((uint8_t *)&test)[6],
+                   ((uint8_t *)&test)[7]);
+
+            */
+
+#endif
+
+
+
+
+
+#   define TEST_MASK 0xffffffffffffffffllu
+#   define TEST_BIT 0
+
+
+            //printf("mask: %llx\n", (unsigned long long)mask);
+
+
+            if (mask != TEST_MASK)
+            {
+                //printf("mask: %llx\n", (unsigned long long)mask);
+
+                //counter++;
+                //printf("Ouhc: %p - %x\n", &group, *((uint8_t *)&mask));
+                //printf("Ouhc: %x\n", 1);
+                //asm("vzeroupper;");
+                //printf("Ouhc: %hhx\n", R[0]);
+                for (j = 0; j < group.used; j++)
+                {
+                    if ((mask & 0x1) == TEST_BIT)
+                    {
+                        //assert((i + 1) >= group.m[j]);
+
+                        //printf(">> FOUND %zu @ %x !!!!!!!!!!!!!!\n", j, (unsigned int)i + 1);
+                        printf(">> FOUND %zu @ %x !!!!!!!!!!!!!!\n", j, (unsigned int)(iter - data) + 1);
+
+
+                    }
+
+                    mask >>= 1;
+                    //printf("> mask: %llx\n", (unsigned long long)mask);
+
+                }
+
+
+
+            }
+
+
+
+        }
+
+        //printf("%hhx\n", ((uint8_t *)&R)[0], ((uint8_t *)&mask)[0]);
+
+    }
+
+    //printf("counter=%d\n", counter);
+
+
+}
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = moteur de recherche à manipuler.                   *
+*                context = lieu d'enregistrement des résultats.               *
+*                content = données binaires à analyser.                       *
+*                                                                             *
+*  Description : Parcours un contenu binaire à la recherche de motifs.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void run_scan_avx512_best_test(const GBitapBackend *backend, GScanContext *context, GBinContent *content)
+{
+    const group_manager_avx512_t *manager;  /* Accès simplifié             */
+    phys_t dlen;                            /* Quantité de données         */
+    vmpa2t pos;                             /* Point de départ ciblé       */
+    const bin_t *data;                      /* Données à analyser          */
+
+
+    //__m512i shift8_mask;                    /* Masque pour décalage manuel */
+
+
+    size_t k;                               /* Boucle de parcours #1       */
+    grouped_strings_avx512_t group;         /* Copie pour accès locaux     */
+
+    //register __m512i zero;                           /* Constante 0 sur 512 bits    */
+    register __m512i R;                              /* Résultats courants          */
+
+    //int counter;
+
+    const bin_t *iter;
+    const bin_t *maxiter;
+    //phys_t i;                               /* Boucle de parcours #2       */
+
+
+    //__m512i test;
+
+    __mmask64 mask;                         /* Masque d'accès rapide       */
+    size_t j;                               /* Boucle de parcours #3       */
+
+    //return;
+
+
+    //counter = 0;
+
+    //return;
+
+    /* Initialisations diverses */
+
+    manager = &backend->manager_avx512;
+
+    dlen = g_binary_content_compute_size(content);
+
+    g_binary_content_compute_start_pos(content, &pos);
+    data = g_binary_content_get_raw_access(content, &pos, dlen);
+
+    /* Recherches des chaînes de moins de 8 caractères */
+
+    printf(" --- manager512->count_8: %zu\n", manager->count_8);
+
+    //zero = _mm512_set1_epi8(0);
+
+    //shift8_mask = _mm512_set1_epi8(0x7f);
+
+
+
+    for (k = 0; k < manager->count_8; k++)
+    {
+        memcpy(&group, manager->strings_8[k], sizeof(grouped_strings_avx512_t));
+
+        //printf(" --- group %p  --  used: %zu (sz: %zu)\n", &group, group.used, sizeof(grouped_strings_avx512_t));
+        //printf(" --- group.used: %zu (sz: %zu)\n", group.used, sizeof(grouped_strings_avx512_t));
+
+        R = _mm512_set1_epi8(~1);
+
+
+
+        /* vpord zmm, zmm, zmm : latence 1, 1*p05 */
+        //R = _mm512_or_si512(R, group.pattern_masks[data[0]]);
+
+        //for (i = 0; i < dlen; i++)
+
+        maxiter = data + dlen;
+
+        for (iter = data; iter < maxiter; iter++)
+        {
+
+            //printf("--- %llx <-> %c\n", (unsigned long long)(iter - data), *iter);
+
+
+            //R = _mm512_or_si512(R, group.pattern_masks[data[i]]);
+            R = _mm512_or_si512(R, group.pattern_masks[*iter]);
+
+
+#if 1
+            /* vpaddb zmm, zmm, zmm : latence 1, 1*p05 */
+            R = _mm512_add_epi8(R, R);
+#else
+            /* vpandd zmm, zmm, zmm : latence 1, 1*p5 */
+            R = _mm512_and_si512(R, shift8_mask);
+            /* vpslldq zmm, zmm, imm8 : latence 1, 1*p5 */
+            R = _mm512_bslli_epi128(R, 1);
+
+#endif
+
+            /*
+            printf("           R: %hhx %hhx %hhx %hhx   %hhx %hhx %hhx %hhx\n",
+                   ((uint8_t *)&R)[0],
+                   ((uint8_t *)&R)[1],
+                   ((uint8_t *)&R)[2],
+                   ((uint8_t *)&R)[3],
+                   ((uint8_t *)&R)[4],
+                   ((uint8_t *)&R)[5],
+                   ((uint8_t *)&R)[6],
+                   ((uint8_t *)&R)[7]);
+
+            printf("  found mask: %hhx %hhx %hhx %hhx   %hhx %hhx %hhx %hhx\n",
+                   ((uint8_t *)&group.found_masks)[0],
+                   ((uint8_t *)&group.found_masks)[1],
+                   ((uint8_t *)&group.found_masks)[2],
+                   ((uint8_t *)&group.found_masks)[3],
+                   ((uint8_t *)&group.found_masks)[4],
+                   ((uint8_t *)&group.found_masks)[5],
+                   ((uint8_t *)&group.found_masks)[6],
+                   ((uint8_t *)&group.found_masks)[7]);
+            */
+
+#if 1
+            /* vptestmb k, zmm, zmm : latence 3, 1*p5 */
+            mask = _mm512_test_epi8_mask(R, group.found_masks);
+
+
+            //test = _mm512_add_epi64(R, zero);
+
+            //mask = _mm512_test_epi8_mask(test, group.found_masks);
+
+
+
+
+
+#   define TEST_MASK 0xffffffffffffffffllu
+#   define TEST_BIT 0
+
+            /* comparaison : != */
+
+
+#else
+            /* vpandd zmm, zmm, zmm : latence 1, 1*p05 */
+            test = _mm512_and_si512(R, group.found_masks);
+
+
+            printf("        test: %hhx %hhx %hhx %hhx   %hhx %hhx %hhx %hhx\n",
+                   ((uint8_t *)&test)[0],
+                   ((uint8_t *)&test)[1],
+                   ((uint8_t *)&test)[2],
+                   ((uint8_t *)&test)[3],
+                   ((uint8_t *)&test)[4],
+                   ((uint8_t *)&test)[5],
+                   ((uint8_t *)&test)[6],
+                   ((uint8_t *)&test)[7]);
+
+            /* vpmovb2m k, zmm : latence 3 (au lieu de 1 !?), 1*p0 */
+            //mask = _mm512_movepi8_mask(test);
+
+#   define TEST_MASK 0
+#   define TEST_BIT 0
+
+
+            //test = _mm512_popcnt_epi8(test);
+
+#endif
+
+
+            //printf("  final mask: %16llx\n", (unsigned long long)mask);
+
+
+
+            //R = _mm512_or_si512(R, group.pattern_masks[data[i + 1]]);
+
+#if 1
+
+
+            if (mask != TEST_MASK)
+            {
+                //counter++;
+                //printf("Ouhc: %p - %x\n", &group, *((uint8_t *)&mask));
+                printf("Ouhc: %p\n", &group);
+                //printf("Ouhc: %hhx\n", R[0]);
+                for (j = 0; j < group.used; j++)
+                {
+                    if ((mask & 0x1) == TEST_BIT)
+                    {
+                        //assert((i + 1) >= group.m[j]);
+
+                        //printf(">> FOUND %zu @ %x !!!!!!!!!!!!!!\n", j, (unsigned int)i + 1);
+                        printf(">> FOUND %zu @ %x !!!!!!!!!!!!!!\n", j, (unsigned int)(iter - data) + 1);
+
+
+                    }
+
+                    mask >>= 1;
+
+                }
+
+
+
+            }
+
+
+#else
+
+            if (_mm512_reduce_or_epi64(test) != 0)
+            {
+                for (j = 0; j < group.used; j++)
+                {
+                    if (((uint8_t *)&test)[j] == 0)
+                    {
+                        //assert((i + 1) >= group.m[j]);
+
+                        printf(">> FOUND %zu @ %x !!!!!!!!!!!!!!\n", j, (unsigned int)i + 1);
+
+                    }
+
+
+                }
+
+            }
+
+#endif
+
+
+        }
+
+        //printf("%hhx\n", ((uint8_t *)&R)[0], ((uint8_t *)&mask)[0]);
+
+    }
+
+    //printf("counter=%d\n", counter);
+
+
+}
+
+
+
+
+
+static void run_scan_avx512__saved(const GBitapBackend *backend, GScanContext *context, GBinContent *content)
+{
+    const group_manager_avx512_t *manager;  /* Accès simplifié             */
+    phys_t dlen;                            /* Quantité de données         */
+    vmpa2t pos;                             /* Point de départ ciblé       */
+    const bin_t *data;                      /* Données à analyser          */
+
+
+    __m512i shift8_mask;                    /* Masque pour décalage manuel */
+
+
+    size_t k;                               /* Boucle de parcours #1       */
+    grouped_strings_avx512_t group;         /* Copie pour accès locaux     */
+
+
+    __m512i R;                              /* Résultats courants          */
+
+    //int counter;
+
+    phys_t i;                               /* Boucle de parcours #2       */
+
+
+    __m512i test;
+
+    __mmask64 mask;                         /* Masque d'accès rapide       */
+    size_t j;                               /* Boucle de parcours #3       */
+
+
+
+    //counter = 0;
+
+    //return;
+
+    /* Initialisations diverses */
+
+    manager = &backend->manager_avx512;
+
+    dlen = g_binary_content_compute_size(content);
+
+    g_binary_content_compute_start_pos(content, &pos);
+    data = g_binary_content_get_raw_access(content, &pos, dlen);
+
+    /* Recherches des chaînes de moins de 8 caractères */
+
+    printf(" --- manager512->count_8: %zu\n", manager->count_8);
+
+
+
+    shift8_mask = _mm512_set1_epi8(0x7f);
+
+
+    for (k = 0; k < manager->count_8; k++)
+    {
+        memcpy(&group, manager->strings_8[k], sizeof(grouped_strings_avx512_t));
+
+        //printf(" --- group %p  --  used: %zu (sz: %zu)\n", &group, group.used, sizeof(grouped_strings_avx512_t));
+        //printf(" --- group.used: %zu (sz: %zu)\n", group.used, sizeof(grouped_strings_avx512_t));
+
+        R = _mm512_set1_epi8(~1);
+
+        /* vpord zmm, zmm, zmm : latence 1, 1*p05 */
+        R = _mm512_or_si512(R, group.pattern_masks[data[0]]);
+
+        for (i = 0; i < dlen; i++)
+        {
+
+            /*
+            printf("--- %llx <-> %c\n", (unsigned long long)i, data[i]);
+
+            printf("  R: %hhx %hhx %hhx %hhx\n",
+                   ((uint8_t *)&R)[0],
+                   ((uint8_t *)&R)[1],
+                   ((uint8_t *)&R)[2],
+                   ((uint8_t *)&R)[3]);
+
+            printf("  mask: %hhx %hhx %hhx %hhx\n",
+                   ((uint8_t *)&group.pattern_masks[data[i]])[0],
+                   ((uint8_t *)&group.pattern_masks[data[i]])[1],
+                   ((uint8_t *)&group.pattern_masks[data[i]])[2],
+                   ((uint8_t *)&group.pattern_masks[data[i]])[3]);
+            */
+
+            //R = _mm512_or_si512(R, group.pattern_masks[data[i]]);
+
+            /*
+            printf("  R: %hhx %hhx %hhx %hhx\n",
+                   ((uint8_t *)&R)[0],
+                   ((uint8_t *)&R)[1],
+                   ((uint8_t *)&R)[2],
+                   ((uint8_t *)&R)[3]);
+            */
+
+#if 1
+            /* vpaddb zmm, zmm, zmm : latence 1, 1*p05 */
+            R = _mm512_add_epi8(R, R);
+#else
+            /* vpandd zmm, zmm, zmm : latence 1, 1*p5 */
+            R = _mm512_and_si512(R, shift8_mask);
+            /* vpslldq zmm, zmm, imm8 : latence 1, 1*p5 */
+            R = _mm512_bslli_epi128(R, 1);
+
+#endif
+
+#if 1
+            /* vptestmb k, zmm, zmm : latence 3, 1*p5 */
+            mask = _mm512_test_epi8_mask(R, group.found_masks);
+#else
+            test = _mm512_and_si512(R, group.found_masks);
+            test = _mm512_popcnt_epi8(test);
+
+#endif
+
+            /*
+            printf("  found mask: %hhx %hhx %hhx %hhx\n",
+                   ((uint8_t *)&group.found_masks)[0],
+                   ((uint8_t *)&group.found_masks)[1],
+                   ((uint8_t *)&group.found_masks)[2],
+                   ((uint8_t *)&group.found_masks)[3]);
+
+            printf("  final mask: %16llx\n", (unsigned long long)mask);
+            */
+
+
+            R = _mm512_or_si512(R, group.pattern_masks[data[i + 1]]);
+
+#if 1
+
+            if (mask != 0xffffffffffffffffllu)
+            {
+                //counter++;
+                //printf("Ouhc: %p - %x\n", &group, *((uint8_t *)&mask));
+                //printf("Ouhc: %p\n", &group);
+                for (j = 0; j < group.used; j++)
+                {
+                    if ((mask & 0x1) == 0)
+                    {
+                        //assert((i + 1) >= group.m[j]);
+
+                        printf(">> FOUND %zu @ %x !!!!!!!!!!!!!!\n", j, (unsigned int)i + 1);
+
+
+                    }
+
+                    mask >>= 1;
+
+                }
+
+
+
+            }
+
+
+#else
+
+            if (_mm512_reduce_or_epi64(test) != 0)
+            {
+                for (j = 0; j < group.used; j++)
+                {
+                    if (((uint8_t *)&test)[j] == 0)
+                    {
+                        //assert((i + 1) >= group.m[j]);
+
+                        printf(">> FOUND %zu @ %x !!!!!!!!!!!!!!\n", j, (unsigned int)i + 1);
+
+                    }
+
+
+                }
+
+            }
+
+#endif
+
+
+        }
+
+        //printf("%hhx\n", ((uint8_t *)&R)[0], ((uint8_t *)&mask)[0]);
+
+    }
+
+    //printf("counter=%d\n", counter);
+
+
+}
+#endif
+
+
+
diff --git a/src/analysis/scan/patterns/backends/bitap.h b/src/analysis/scan/patterns/backends/bitap.h
new file mode 100644
index 0000000..1cb384c
--- /dev/null
+++ b/src/analysis/scan/patterns/backends/bitap.h
@@ -0,0 +1,59 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * bitap.h - prototypes pour la méthode de recherche basée sur l'algorithme Bitap
+ *
+ * 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 _ANALYSIS_SCAN_PATTERNS_BACKENDS_BITAP_H
+#define _ANALYSIS_SCAN_PATTERNS_BACKENDS_BITAP_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+
+
+#include "../backend.h"
+
+
+
+#define G_TYPE_BITAP_BACKEND            g_bitap_backend_get_type()
+#define G_BITAP_BACKEND(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_BITAP_BACKEND, GBitapBackend))
+#define G_IS_BITAP_BACKEND(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_BITAP_BACKEND))
+#define G_BITAP_BACKEND_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BITAP_BACKEND, GBitapBackendClass))
+#define G_IS_BITAP_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BITAP_BACKEND))
+#define G_BITAP_BACKEND_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BITAP_BACKEND, GBitapBackendClass))
+
+
+/* Méthode de recherche basée sur l'algorithme Bitap (instance) */
+typedef struct _GBitapBackend GBitapBackend;
+
+/* Méthode de recherche basée sur l'algorithme Bitap (classe) */
+typedef struct _GBitapBackendClass GBitapBackendClass;
+
+
+/* Indique le type défini pour un moteur de recherche pour données. */
+GType g_bitap_backend_get_type(void);
+
+/* Crée une méthode de recherche basée sur l'algorithme Bitap. */
+GEngineBackend *g_bitap_backend_new(void);
+
+
+
+#endif  /* _ANALYSIS_SCAN_PATTERNS_BACKENDS_BITAP_H */
diff --git a/src/analysis/scan/patterns/token-int.h b/src/analysis/scan/patterns/token-int.h
new file mode 100644
index 0000000..a9667c9
--- /dev/null
+++ b/src/analysis/scan/patterns/token-int.h
@@ -0,0 +1,61 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * token-int.h - prototypes internes pour les bribes de recherche textuelle
+ *
+ * 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_PATTERNS_TOKEN_INT_H
+#define _ANALYSIS_SCAN_PATTERNS_TOKEN_INT_H
+
+
+#include "token.h"
+
+
+#include "../pattern-int.h"
+
+
+
+/* Inscrit la définition d'un motif dans un moteur de recherche. */
+typedef bool (* enroll_token_fc) (GStringToken *, GScanContext *, GEngineBackend *, size_t);
+
+/* Transforme les correspondances locales en trouvailles. */
+typedef void (* check_token_fc) (const GStringToken *, GScanContext *, GBinContent *, pending_matches_t *);
+
+
+/* Encadrement d'une bribe de recherche textuelle (instance) */
+struct _GStringToken
+{
+    GSearchPattern parent;                  /* A laisser en premier        */
+
+};
+
+/* Encadrement d'une bribe de recherche textuelle (classe) */
+struct _GStringTokenClass
+{
+    GSearchPatternClass parent;             /* A laisser en premier        */
+
+    enroll_token_fc enroll;                 /* Inscription d'un motif      */
+    check_token_fc check;                   /* Conversion en trouvailles   */
+
+};
+
+
+
+#endif  /* _ANALYSIS_SCAN_PATTERNS_TOKEN_INT_H */
diff --git a/src/analysis/scan/patterns/token.c b/src/analysis/scan/patterns/token.c
new file mode 100644
index 0000000..d8a5cbc
--- /dev/null
+++ b/src/analysis/scan/patterns/token.c
@@ -0,0 +1,193 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * token.c - bribes de recherche textuelle
+ *
+ * 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 "token.h"
+
+
+#include <assert.h>
+
+
+#include "token-int.h"
+
+
+
+/* Initialise la classe des bribes de recherche textuelle. */
+static void g_string_token_class_init(GStringTokenClass *);
+
+/* Initialise une instance de bribe de recherche textuelle. */
+static void g_string_token_init(GStringToken *);
+
+/* Supprime toutes les références externes. */
+static void g_string_token_dispose(GStringToken *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_string_token_finalize(GStringToken *);
+
+
+
+/* Indique le type défini pour une bribe de recherche textuelle. */
+G_DEFINE_TYPE(GStringToken, g_string_token, G_TYPE_SEARCH_PATTERN);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des bribes de recherche textuelle.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_string_token_class_init(GStringTokenClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GSearchPatternClass *pattern;           /* Version de classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_string_token_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_string_token_finalize;
+
+    pattern = G_SEARCH_PATTERN_CLASS(klass);
+
+    //pattern->prepare = (prepare_pattern_fc)g_string_token_prepare;
+    //pattern->analyze = (analyze_pattern_fc)g_string_token_analyze;
+    //pattern->count = (count_pattern_matchs_fc);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : token = instance à initialiser.                              *
+*                                                                             *
+*  Description : Initialise une instance de bribe de recherche textuelle.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_string_token_init(GStringToken *token)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : token = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_string_token_dispose(GStringToken *token)
+{
+    G_OBJECT_CLASS(g_string_token_parent_class)->dispose(G_OBJECT(token));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : token = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_string_token_finalize(GStringToken *token)
+{
+    G_OBJECT_CLASS(g_string_token_parent_class)->finalize(G_OBJECT(token));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : token   = définition de la bribe à enregistrer.              *
+*                context = contexte de l'analyse à mener.                     *
+*                backend = moteur de recherche à préchauffer.                 *
+*                maxsize = taille max. des atomes (mise en commun optimisée). *
+*                                                                             *
+*  Description : Inscrit la définition d'un motif dans un moteur de recherche.*
+*                                                                             *
+*  Retour      : Bilan de l'opération à renvoyer.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_string_token_enroll(GStringToken *token, GScanContext *context, GEngineBackend *backend, size_t maxsize)
+{
+    bool result;                            /* Statut à retourner          */
+    GStringTokenClass *class;               /* Classe de l'instance        */
+
+    assert(g_engine_backend_get_atom_max_size(backend) == maxsize);
+
+    class = G_STRING_TOKEN_GET_CLASS(token);
+
+    result = class->enroll(token, context, backend, maxsize);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : token   = définition de la bribe à manipuler.                *
+*                context = contexte de l'analyse à mener.                     *
+*                content = accès au contenu brut pour vérifications (optim.)  *
+*                matches = suivi des correspondances à consolider.            *
+*                                                                             *
+*  Description : Transforme les correspondances locales en trouvailles.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_string_token_check(const GStringToken *token, GScanContext *context, GBinContent *content, pending_matches_t *matches)
+{
+    GStringTokenClass *class;               /* Classe de l'instance        */
+
+    class = G_STRING_TOKEN_GET_CLASS(token);
+
+    class->check(token, context, content, matches);
+
+}
diff --git a/src/analysis/scan/patterns/token.h b/src/analysis/scan/patterns/token.h
new file mode 100644
index 0000000..c1cb173
--- /dev/null
+++ b/src/analysis/scan/patterns/token.h
@@ -0,0 +1,62 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * token.h - prototypes pour les bribes de recherche textuelle
+ *
+ * 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_PATTERNS_TOKEN_H
+#define _ANALYSIS_SCAN_PATTERNS_TOKEN_H
+
+
+#include <glib-object.h>
+
+
+#include "backend.h"
+#include "../matches/pending.h"
+
+
+
+#define G_TYPE_STRING_TOKEN            g_string_token_get_type()
+#define G_STRING_TOKEN(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_STRING_TOKEN, GStringToken))
+#define G_IS_STRING_TOKEN(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_STRING_TOKEN))
+#define G_STRING_TOKEN_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_STRING_TOKEN, GStringTokenClass))
+#define G_IS_STRING_TOKEN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_STRING_TOKEN))
+#define G_STRING_TOKEN_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_STRING_TOKEN, GStringTokenClass))
+
+
+/* Encadrement d'une bribe de recherche textuelle (instance) */
+typedef struct _GStringToken GStringToken;
+
+/* Encadrement d'une bribe de recherche textuelle (classe) */
+typedef struct _GStringTokenClass GStringTokenClass;
+
+
+/* Indique le type défini pour une bribe de recherche textuelle. */
+GType g_string_token_get_type(void);
+
+/* Inscrit la définition d'un motif dans un moteur de recherche. */
+bool g_string_token_enroll(GStringToken *, GScanContext *, GEngineBackend *, size_t);
+
+/* Transforme les correspondances locales en trouvailles. */
+void g_string_token_check(const GStringToken *, GScanContext *, GBinContent *, pending_matches_t *);
+
+
+
+#endif  /* _ANALYSIS_SCAN_PATTERNS_TOKEN_H */
diff --git a/src/analysis/scan/patterns/tokens/Makefile.am b/src/analysis/scan/patterns/tokens/Makefile.am
new file mode 100644
index 0000000..00cff2a
--- /dev/null
+++ b/src/analysis/scan/patterns/tokens/Makefile.am
@@ -0,0 +1,13 @@
+
+noinst_LTLIBRARIES  = libanalysisscanpatternstokens.la
+
+
+libanalysisscanpatternstokens_la_SOURCES =	\
+	plain.h plain.c
+
+libanalysisscanpatternstokens_la_CFLAGS = $(LIBGOBJ_CFLAGS)
+
+
+devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
+
+dev_HEADERS = $(libanalysisscanpatternstokens_la_SOURCES:%c=)
diff --git a/src/analysis/scan/patterns/tokens/plain.c b/src/analysis/scan/patterns/tokens/plain.c
new file mode 100644
index 0000000..9eb731e
--- /dev/null
+++ b/src/analysis/scan/patterns/tokens/plain.c
@@ -0,0 +1,374 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * plain.c - recherche d'une chaîne de caractères brute
+ *
+ * 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 "plain.h"
+
+
+#include <malloc.h>
+#include <string.h>
+
+
+#include "../token-int.h"
+
+
+
+/* ----------------------- RECHERCHE D'UN MOTIF DE TEXTE BRUT ----------------------- */
+
+
+/* Encadrement d'une recherche de texte brut (instance) */
+struct _GPlainBytes
+{
+    GStringToken parent;                    /* A laisser en premier        */
+
+    uint8_t *raw;                           /* Octets recherchés           */
+    size_t allocated;                       /* Taille allouée              */
+    size_t used;                            /* Quantité d'octets utilisée  */
+
+    phys_t atom_pos;                        /* Début de sélection atomique */
+    phys_t atom_len;                        /* Taille de ladite sélection  */
+    phys_t atom_rem;                        /* Reste après l'atome         */
+    patid_t pid;                            /* Identifiant de la bribe     */
+
+};
+
+/* Encadrement d'une recherche de texte brut (classe) */
+struct _GPlainBytesClass
+{
+    GStringTokenClass parent;               /* A laisser en premier        */
+
+};
+
+
+/* Initialise la classe des recherches de texte brut. */
+static void g_plain_bytes_class_init(GPlainBytesClass *klass);
+
+/* Initialise une instance de recherche de texte brut. */
+static void g_plain_bytes_init(GPlainBytes *);
+
+/* Supprime toutes les références externes. */
+static void g_plain_bytes_dispose(GPlainBytes *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_plain_bytes_finalize(GPlainBytes *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Inscrit la définition d'un motif dans un moteur de recherche. */
+static bool g_plain_bytes_enroll(GPlainBytes *, GScanContext *, GEngineBackend *, size_t);
+
+/* Transforme les correspondances locales en trouvailles. */
+static void g_plain_bytes_check(const GPlainBytes *, GScanContext *, GBinContent *, pending_matches_t *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                         RECHERCHE D'UN MOTIF DE TEXTE BRUT                         */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une suite d'octets à retrouver dans un binaire. */
+G_DEFINE_TYPE(GPlainBytes, g_plain_bytes, G_TYPE_STRING_TOKEN);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des recherches de texte brut.           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_plain_bytes_class_init(GPlainBytesClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GSearchPatternClass *pattern;           /* Version de classe ancêtre   */
+    GStringTokenClass *token;               /* Version de classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_plain_bytes_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_plain_bytes_finalize;
+
+    pattern = G_SEARCH_PATTERN_CLASS(klass);
+
+    //pattern->prepare = (prepare_pattern_fc)g_plain_bytes_prepare;
+    //pattern->analyze = (analyze_pattern_fc)g_plain_bytes_analyze;
+    //pattern->count = (count_pattern_matchs_fc);
+
+    token = G_STRING_TOKEN_CLASS(klass);
+
+    token->enroll = (enroll_token_fc)g_plain_bytes_enroll;
+    token->check = (check_token_fc)g_plain_bytes_check;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : pattern = instance à initialiser.                            *
+*                                                                             *
+*  Description : Initialise une instance de recherche de texte brut.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_plain_bytes_init(GPlainBytes *bytes)
+{
+    bytes->raw = NULL;
+    bytes->allocated = 0;
+    bytes->used = 0;
+
+    bytes->atom_pos = 0;
+    bytes->atom_len = 0;
+    bytes->atom_rem = 0;
+    bytes->pid = INVALID_PATTERN_ID;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : bytes = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_plain_bytes_dispose(GPlainBytes *bytes)
+{
+    G_OBJECT_CLASS(g_plain_bytes_parent_class)->dispose(G_OBJECT(bytes));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : bytes = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_plain_bytes_finalize(GPlainBytes *bytes)
+{
+    if (bytes->raw != NULL)
+        free(bytes->raw);
+
+    G_OBJECT_CLASS(g_plain_bytes_parent_class)->finalize(G_OBJECT(bytes));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : text = texte brut à rechercher.                              *
+*                len  = longueur de ce texte.                                 *
+*                                                                             *
+*  Description : Construit un gestionnaire de recherche de texte brut.        *
+*                                                                             *
+*  Retour      : Mécanismes mis en place.                                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GSearchPattern *g_plain_bytes_new(const uint8_t *raw, size_t len)
+{
+    GPlainBytes *result;                    /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_PLAIN_BYTES, NULL);
+
+    result->raw = malloc(len);
+    result->allocated = len;
+    result->used = len;
+
+    memcpy(result->raw, raw, len);
+
+    return G_SEARCH_PATTERN(result);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : bytes   = définition de la bribe à enregistrer.              *
+*                context = contexte de l'analyse à mener.                     *
+*                backend = moteur de recherche à préchauffer.                 *
+*                maxsize = taille max. des atomes (mise en commun optimisée). *
+*                                                                             *
+*  Description : Inscrit la définition d'un motif dans un moteur de recherche.*
+*                                                                             *
+*  Retour      : Bilan de l'opération à renvoyer.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_plain_bytes_enroll(GPlainBytes *bytes, GScanContext *context, GEngineBackend *backend, size_t maxsize)
+{
+    bool result;                            /* Statut à retourner          */
+
+
+    result = true;
+
+
+
+    bytes->atom_pos = 0;
+
+    if (bytes->used > maxsize)  // Attention à la position de départ (à retrancher) !
+    {
+        bytes->atom_len = maxsize;
+        bytes->atom_rem = bytes->used - maxsize;
+    }
+    else
+    {
+        bytes->atom_len = bytes->used;
+        bytes->atom_rem = 0;
+    }
+
+
+    bytes->pid = g_engine_backend_enroll_plain_pattern(backend, context, bytes->raw, bytes->atom_len);
+
+
+
+    result = (bytes->pid != INVALID_PATTERN_ID);
+
+
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : bytes   = définition de la bribe à manipuler.                *
+*                context = contexte de l'analyse à mener.                     *
+*                content = accès au contenu brut pour vérifications (optim.)  *
+*                matches = suivi des correspondances à consolider.            *
+*                                                                             *
+*  Description : Transforme les correspondances locales en trouvailles.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_plain_bytes_check(const GPlainBytes *bytes, GScanContext *context, GBinContent *content, pending_matches_t *matches)
+{
+    bool initialized;                       /* Initialisation du suivi ?   */
+    size_t count;                           /* Quantité de bribes trouvées */
+    const phys_t *found;                    /* Localisations des bribes    */
+    size_t mindex;                          /* Indice d'élément à compléter*/
+    size_t i;                               /* Boucle de parcours          */
+    phys_t start;                           /* Point de départ             */
+    vmpa2t pos;                             /* Position dans les données   */
+    const bin_t *ptr;                       /* Accès aux données brutes    */
+    int ret;                                /* Bilan d'une comparaison     */
+
+    initialized = are_pending_matches_initialized(matches);
+
+    found = g_scan_context_get_atom_matches(context, bytes->pid, &count);
+
+    mindex = 0;
+
+    for (i = 0; i < count; i++)
+    {
+        start = found[i] - bytes->atom_pos;
+
+        /* Recherche d'un point de départ attendu et conforme ? */
+
+        if (initialized)
+            if (!find_target_in_pending_matches(matches, start, &mindex))
+                continue;
+
+        init_vmpa(&pos, start, VMPA_NO_VIRTUAL);
+
+        /* Validation du contenu avant l'atome */
+
+        if (bytes->atom_pos > 0)
+        {
+            ptr = g_binary_content_get_raw_access(content, &pos, bytes->atom_len);
+
+            ret = memcmp(bytes->raw + bytes->atom_pos, ptr, bytes->atom_len);
+            if (ret != 0) goto exclude_false_positive;
+
+        }
+
+        /* Validation du contenu après l'atome */
+
+        if (bytes->atom_rem > 0)
+        {
+            advance_vmpa(&pos, bytes->atom_len);
+
+            ptr = g_binary_content_get_raw_access(content, &pos, bytes->atom_rem);
+
+            ret = memcmp(bytes->raw + bytes->atom_pos + bytes->atom_len, ptr, bytes->atom_rem);
+            if (ret != 0) goto exclude_false_positive;
+
+        }
+
+        /* Mémorisation de la correspondance */
+
+        if (initialized)
+            extend_pending_matches(matches, mindex, bytes->used);
+        else
+            add_pending_matches(matches, start, bytes->used);
+
+        continue;
+
+ exclude_false_positive:
+
+        if (initialized)
+            remove_pending_matches(matches, mindex);
+
+    }
+
+    set_pending_matches_initialized(matches);
+
+}
diff --git a/src/analysis/scan/patterns/tokens/plain.h b/src/analysis/scan/patterns/tokens/plain.h
new file mode 100644
index 0000000..de1d4ec
--- /dev/null
+++ b/src/analysis/scan/patterns/tokens/plain.h
@@ -0,0 +1,67 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * plain.h - prototypes pour la recherche d'une chaîne de caractères brute
+ *
+ * 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_PATTERNS_TOKENS_PLAIN_H
+#define _ANALYSIS_SCAN_PATTERNS_TOKENS_PLAIN_H
+
+
+#include <glib-object.h>
+#include <stdint.h>
+
+
+#include "../../pattern.h"
+
+
+
+#define G_TYPE_PLAIN_BYTES            g_plain_bytes_get_type()
+#define G_PLAIN_BYTES(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_PLAIN_BYTES, GPlainBytes))
+#define G_IS_PLAIN_BYTES(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_PLAIN_BYTES))
+#define G_PLAIN_BYTES_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_PLAIN_BYTES, GPlainBytesClass))
+#define G_IS_PLAIN_BYTES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_PLAIN_BYTES))
+#define G_PLAIN_BYTES_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_PLAIN_BYTES, GPlainBytesClass))
+
+
+/* Représentation d'une suite d'octets à retrouver (instance) */
+typedef struct _GPlainBytes GPlainBytes;
+
+/* Représentation d'une suite d'octets à retrouver (classe) */
+typedef struct _GPlainBytesClass GPlainBytesClass;
+
+
+/* Propriétés d'un élément textuel à rechercher */
+typedef enum _StringTokenAttrib
+{
+    STP_CASE_INSENSITIVE,
+
+} StringTokenAttrib;
+
+
+/* Indique le type défini pour une suite d'octets à retrouver dans un binaire. */
+GType g_plain_bytes_get_type(void);
+
+/* Construit un gestionnaire de recherche de texte brut. */
+GSearchPattern *g_plain_bytes_new(const uint8_t *, size_t);
+
+
+
+#endif  /* _ANALYSIS_SCAN_PATTERNS_TOKENS_PLAIN_H */
diff --git a/src/analysis/scan/rule-int.h b/src/analysis/scan/rule-int.h
new file mode 100644
index 0000000..b43c20b
--- /dev/null
+++ b/src/analysis/scan/rule-int.h
@@ -0,0 +1,59 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * rule-int.h - prototypes internes pour la gestion d'une règle de détection par motifs
+ *
+ * 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 _ANALYSIS_SCAN_RULE_INT_H
+#define _ANALYSIS_SCAN_RULE_INT_H
+
+
+#include "rule.h"
+
+
+
+#define PATTERN_ALLOC_SIZE 20
+
+
+/* Représentation d'une règle de détection statique (instance) */
+struct _GScanRule
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    char *name;                             /* Désignation de la règle     */
+
+    GSearchPattern **data_locals;           /* Variables de données        */
+    size_t data_allocated;                  /* Taille allouée du tableau   */
+    size_t data_used;                       /* Nombre d'éléments présents  */
+
+    GScanExpression *condition;             /* Condition de correspondance */
+
+};
+
+/* Représentation d'une règle de détection statique (classe) */
+struct _GScanRuleClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+};
+
+
+
+#endif  /* _ANALYSIS_SCAN_RULE_INT_H */
diff --git a/src/analysis/scan/rule.c b/src/analysis/scan/rule.c
new file mode 100644
index 0000000..6c771fb
--- /dev/null
+++ b/src/analysis/scan/rule.c
@@ -0,0 +1,383 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * rule.c - parcours de contenus à la recherche de motifs
+ *
+ * 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 "rule.h"
+
+
+#include <assert.h>
+#include <strings.h>
+
+
+#include "rule-int.h"
+#include "matches/bytes.h"
+#include "patterns/token.h"
+
+
+
+/* Initialise la classe des règles de détection statique. */
+static void g_scan_rule_class_init(GScanRuleClass *);
+
+/* Initialise une instance de règle de détection statique. */
+static void g_scan_rule_init(GScanRule *);
+
+/* Supprime toutes les références externes. */
+static void g_scan_rule_dispose(GScanRule *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_scan_rule_finalize(GScanRule *);
+
+
+
+/* Indique le type défini pour une règle de détection par motifs. */
+G_DEFINE_TYPE(GScanRule, g_scan_rule, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des règles de détection statique.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_rule_class_init(GScanRuleClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_rule_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_scan_rule_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : rule = instance à initialiser.                               *
+*                                                                             *
+*  Description : Initialise une instance de règle de détection statique.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_rule_init(GScanRule *rule)
+{
+    rule->name = NULL;
+
+    rule->data_locals = NULL;
+    rule->data_allocated = 0;
+    rule->data_used = 0;
+
+    rule->condition = NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : rule = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_rule_dispose(GScanRule *rule)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    for (i = 0; i < rule->data_used; i++)
+        g_clear_object(&rule->data_locals[i]);
+
+    g_clear_object(&rule->condition);
+
+    G_OBJECT_CLASS(g_scan_rule_parent_class)->dispose(G_OBJECT(rule));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : rule = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_rule_finalize(GScanRule *rule)
+{
+    if (rule->name != NULL)
+        free(rule->name);
+
+    G_OBJECT_CLASS(g_scan_rule_parent_class)->finalize(G_OBJECT(rule));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : name = désignation à associer à la future règle.             *
+*                                                                             *
+*  Description : Crée une règle de détection statique à l'aide de motifs.     *
+*                                                                             *
+*  Retour      : Règle de détection mise en place.                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanRule *g_scan_rule_new(const char *name)
+{
+    GScanRule *result;                /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_SCAN_RULE, NULL);
+
+    result->name = strdup(name);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : rule    = règle de détection à compléter.                    *
+*                pattern = nouveau motif de détection.                        *
+*                                                                             *
+*  Description : Intègre une nouvelle variable locale à une règle.            *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_scan_rule_add_local_variable(GScanRule *rule, GSearchPattern *pattern)
+{
+    if (G_IS_STRING_TOKEN(pattern))
+    {
+        if (rule->data_used == rule->data_allocated)
+        {
+            rule->data_allocated += PATTERN_ALLOC_SIZE;
+            rule->data_locals = realloc(rule->data_locals, rule->data_allocated * sizeof(GSearchPattern *));
+        }
+
+        rule->data_locals[rule->data_used++] = pattern;
+        g_object_ref(G_OBJECT(pattern));
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : rule   = règle de détection à consulter.                     *
+*                target = nom d'une variable locale à retrouver.              *
+*                                                                             *
+*  Description : Fournit une variable locale à une règle selon un nom.        *
+*                                                                             *
+*  Retour      : Motif de détection retrouvé ou NULL en cas d'échec.          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GSearchPattern *g_scan_rule_get_local_variable(GScanRule *rule, const char *target)
+{
+    GSearchPattern *result;                 /* Variable à retourner        */
+    size_t i;                               /* Boucle de parcours          */
+    const char *name;                       /* Désignation d'un motif      */
+
+    result = NULL;
+
+    for (i = 0; i < rule->data_used; i++)
+    {
+        name = g_search_pattern_get_name(rule->data_locals[i]);
+
+        if (strcmp(name, target) == 0)
+        {
+            result = rule->data_locals[i];
+            break;
+        }
+
+    }
+
+    if (result != NULL)
+        g_object_ref(G_OBJECT(result));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : rule = règle de détection à compléter.                       *
+*                expr = expression de condition à satisfaire.                 *
+*                                                                             *
+*  Description : Définit l'expression d'une correspondance recherchée.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_scan_rule_set_match_condition(GScanRule *rule, GScanExpression *expr)
+{
+    rule->condition = expr;
+
+    g_object_ref(G_OBJECT(expr));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : rule    = règle de détection à considérer.                   *
+*                backend = moteur d'analyse pour données brutes.              *
+*                context = contexte de l'analyse à mener.                     *
+*                                                                             *
+*  Description : Prépare le suivi de recherche de motifs pour une règle.      *
+*                                                                             *
+*  Retour      : Bilan de l'opération à renvoyer.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_scan_rule_setup_backend(GScanRule *rule, GEngineBackend *backend, GScanContext *context)
+{
+    bool result;                            /* Statut à retourner          */
+    size_t maxsize;                         /* Taille maximale des atomes  */
+    GSearchPattern *pattern;                /* Motif à intégrer            */
+    GScanOptions *options;                  /* Options d'analyse           */
+    size_t i;                               /* Boucle de parcours          */
+
+    /* Suivi des conditions de correspondance */
+
+    result = g_scan_context_set_rule_condition(context, rule->name, rule->condition);
+    if (!result) goto exit;
+
+    /* Programmation des motifs recherchés */
+
+    maxsize = g_engine_backend_get_atom_max_size(backend);
+
+    for (i = 0; i < rule->data_used && result; i++)
+    {
+        pattern = rule->data_locals[i];
+        result = g_string_token_enroll(G_STRING_TOKEN(pattern), context, backend, maxsize);
+    }
+
+    g_engine_backend_warm_up(backend);
+
+    /* Affichage éventuel de statistiques */
+
+    options = g_scan_context_get_options(context);
+
+    if (g_scan_options_get_print_stats(options))
+        g_engine_backend_output_stats(backend);
+
+
+    g_object_unref(G_OBJECT(options));
+
+ exit:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : rule    = règle de détection à considérer.                   *
+*                backend = moteur d'analyse pour données brutes.              *
+*                context = contexte de l'analyse à mener.                     *
+*                                                                             *
+*  Description : Lance une analyse d'un contenu binaire selon une règle.      *
+*                                                                             *
+*  Retour      : Contexte de suivi pour l'analyse menée.                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_scan_rule_analyze(GScanRule *rule, GEngineBackend *backend, GScanContext *context)
+{
+    GBinContent *content;                   /* Contenu à manipuler         */
+    pending_matches_t matches;              /* Suivi de correspondances    */
+    size_t i;                               /* Boucle de parcours #1       */
+    GSearchPattern *pattern;                /* Motif à intégrer            */
+    size_t k;                               /* Boucle de parcours #2       */
+    match_area_t *area;                     /* Zone à initialiser          */
+    GScanMatch *match;                      /* Correspondance à mémoriser  */
+
+    content = g_scan_context_get_content(context);
+
+    g_engine_backend_run_scan(backend, context, content);
+
+    /* Consolidation des résultats */
+
+    for (i = 0; i < rule->data_used; i++)
+    {
+        init_pending_matches(&matches);
+
+        pattern = rule->data_locals[i];
+
+        g_string_token_check(G_STRING_TOKEN(pattern), context, content, &matches);
+
+        for (k = 0; k < matches.used; k++)
+        {
+            area = &matches.areas[k];
+
+            match = g_bytes_match_new(G_SEARCH_PATTERN(pattern), content, area->start, area->length);
+            g_scan_context_register_full_match(context, match);
+            g_object_unref(G_OBJECT(match));
+
+        }
+
+        exit_pending_matches(&matches);
+
+    }
+
+    /* Sortie propre */
+
+    g_object_unref(G_OBJECT(content));
+
+}
diff --git a/src/analysis/scan/rule.h b/src/analysis/scan/rule.h
new file mode 100644
index 0000000..edd57b3
--- /dev/null
+++ b/src/analysis/scan/rule.h
@@ -0,0 +1,77 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * scanner.h - prototypes pour le parcours de contenus à la recherche de motifs
+ *
+ * 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 _ANALYSIS_SCAN_RULE_H
+#define _ANALYSIS_SCAN_RULE_H
+
+
+#include <glib-object.h>
+
+
+#include "cond.h"
+#include "context.h"
+#include "pattern.h"
+#include "expr.h"
+#include "patterns/backend.h"
+
+
+
+#define G_TYPE_SCAN_RULE            g_scan_rule_get_type()
+#define G_SCAN_RULE(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_RULE, GScanRule))
+#define G_IS_SCAN_RULE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_RULE))
+#define G_SCAN_RULE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_RULE, GScanRuleClass))
+#define G_IS_SCAN_RULE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_RULE))
+#define G_SCAN_RULE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_RULE, GScanRuleClass))
+
+
+/* Représentation d'une règle de détection statique (instance) */
+typedef struct _GScanRule GScanRule;
+
+/* Représentation d'une règle de détection statique (classe) */
+typedef struct _GScanRuleClass GScanRuleClass;
+
+
+/* Indique le type défini pour une règle de détection par motifs. */
+GType g_scan_rule_get_type(void);
+
+/* Crée une règle de détection statique à l'aide de motifs. */
+GScanRule *g_scan_rule_new(const char *);
+
+/* Intègre une nouvelle variable locale à une règle. */
+void g_scan_rule_add_local_variable(GScanRule *, GSearchPattern *);
+
+/* Fournit une variable locale à une règle selon un nom. */
+GSearchPattern *g_scan_rule_get_local_variable(GScanRule *, const char *);
+
+/* Définit l'expression d'une correspondance recherchée. */
+void g_scan_rule_set_match_condition(GScanRule *, GScanExpression *);
+
+/* Prépare le suivi de recherche de motifs pour une règle. */
+bool g_scan_rule_setup_backend(GScanRule *, GEngineBackend *, GScanContext *);
+
+/* Lance une analyse d'un contenu binaire selon une règle. */
+void g_scan_rule_analyze(GScanRule *, GEngineBackend *, GScanContext *);
+
+
+
+#endif  /* _ANALYSIS_SCAN_RULE_H */
diff --git a/src/analysis/scan/scanner-int.h b/src/analysis/scan/scanner-int.h
new file mode 100644
index 0000000..54b4f62
--- /dev/null
+++ b/src/analysis/scan/scanner-int.h
@@ -0,0 +1,63 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * scanner-int.h - prototypes internes pour le parcours de contenus à la recherche de motifs
+ *
+ * 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 _ANALYSIS_SCAN_SCANNER_INT_H
+#define _ANALYSIS_SCAN_SCANNER_INT_H
+
+
+#include "scanner.h"
+
+
+#include "patterns/backend.h"
+
+
+
+/* Encadrement d'une recherche au sein de contenus binaires (instance) */
+struct _GContentScanner
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    GScanRule **rules;                      /* Règles de détection         */
+    size_t rule_count;                      /* Nombre de ces règles        */
+
+    GEngineBackend *data_backend;           /* Moteur pour les données     */
+
+};
+
+/* Encadrement d'une recherche au sein de contenus binaires (classe) */
+struct _GContentScannerClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+};
+
+
+/* Met en place un scanner de contenus binaires. */
+bool g_content_scanner_create_from_text(GContentScanner *, const char *);
+
+/* Met en place un scanner de contenus binaires. */
+bool g_content_scanner_create_from_file(GContentScanner *, const char *);
+
+
+
+#endif  /* _ANALYSIS_SCAN_SCANNER_INT_H */
diff --git a/src/analysis/scan/scanner.c b/src/analysis/scan/scanner.c
new file mode 100644
index 0000000..ae3cb9a
--- /dev/null
+++ b/src/analysis/scan/scanner.c
@@ -0,0 +1,342 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * scanner.c - parcours de contenus à la recherche de motifs
+ *
+ * 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 "scanner.h"
+
+
+#include <assert.h>
+
+
+#include "decl.h"
+#include "scanner-int.h"
+#include "../contents/file.h"
+
+
+
+/* Initialise la classe des recherches dans du binaire. */
+static void g_content_scanner_class_init(GContentScannerClass *);
+
+/* Initialise une instance de recherche dans du binaire. */
+static void g_content_scanner_init(GContentScanner *);
+
+/* Supprime toutes les références externes. */
+static void g_content_scanner_dispose(GContentScanner *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_content_scanner_finalize(GContentScanner *);
+
+
+
+/* Indique le type défini pour une recherche dans du binaire. */
+G_DEFINE_TYPE(GContentScanner, g_content_scanner, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des recherches dans du binaire.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_content_scanner_class_init(GContentScannerClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_content_scanner_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_content_scanner_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : scanner = instance à initialiser.                            *
+*                                                                             *
+*  Description : Initialise une instance de recherche dans du binaire.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_content_scanner_init(GContentScanner *scanner)
+{
+    scanner->rules = NULL;
+    scanner->rule_count = 0;
+
+    scanner->data_backend = NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : scanner = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_content_scanner_dispose(GContentScanner *scanner)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    for (i = 0; i < scanner->rule_count; i++)
+        g_clear_object(&scanner->rules[i]);
+
+    g_clear_object(&scanner->data_backend);
+
+    G_OBJECT_CLASS(g_content_scanner_parent_class)->dispose(G_OBJECT(scanner));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : scanner = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_content_scanner_finalize(GContentScanner *scanner)
+{
+    if (scanner->rules != NULL)
+        free(scanner->rules);
+
+    G_OBJECT_CLASS(g_content_scanner_parent_class)->finalize(G_OBJECT(scanner));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : text = définitions textuelles de règles de recherche.        *
+*                                                                             *
+*  Description : Prépare une recherche de motifs dans du contenu binaire.     *
+*                                                                             *
+*  Retour      : Mécanismes mis en place.                                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GContentScanner *g_content_scanner_new_from_text(const char *text)
+{
+    GContentScanner *result;                /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_CONTENT_SCANNER, NULL);
+
+    if (!g_content_scanner_create_from_text(result, text))
+        g_clear_object(&result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : scanner = scanner de contenus à initialiser pleinement.      *
+*                text    = définitions textuelles de règles de recherche.     *
+*                                                                             *
+*  Description : Met en place un scanner de contenus binaires.                *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_content_scanner_create_from_text(GContentScanner *scanner, const char *text)
+{
+    bool result;                            /* Bilan à retourner           */
+    size_t length;                          /* Taille de la définition     */
+
+    length = strlen(text);
+
+    result = process_rules_definitions(scanner, text, length);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : filename = chemin vers des définitions de règles.            *
+*                                                                             *
+*  Description : Prépare une recherche de motifs dans du contenu binaire.     *
+*                                                                             *
+*  Retour      : Mécanismes mis en place.                                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GContentScanner *g_content_scanner_new_from_file(const char *filename)
+{
+    GContentScanner *result;                /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_CONTENT_SCANNER, NULL);
+
+    if (!g_content_scanner_create_from_file(result, filename))
+        g_clear_object(&result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : scanner  = scanner de contenus à initialiser pleinement.     *
+*                filename = chemin vers des définitions de règles.            *
+*                                                                             *
+*  Description : Met en place un scanner de contenus binaires.                *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_content_scanner_create_from_file(GContentScanner *scanner, const char *filename)
+{
+    bool result;                            /* Bilan à retourner           */
+    GBinContent *content;                   /* Fichier à parcourir         */
+    phys_t size;                            /* Taille du contenu associé   */
+    vmpa2t start;                           /* Tête de lecture             */
+    const bin_t *data;                      /* Données à consulter         */
+
+    result = false;
+
+    content = g_file_content_new(filename);
+    if (content == NULL) goto no_content;
+
+    size = g_binary_content_compute_size(content);
+
+    g_binary_content_compute_start_pos(content, &start);
+    data = g_binary_content_get_raw_access(content, &start, size);
+
+    result = process_rules_definitions(scanner, (char *)data, size);
+
+    g_object_unref(G_OBJECT(content));
+
+ no_content:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : scanner = gestionnaire de recherche à compléter.             *
+*                rule    = règle de détection à intégrer.                     *
+*                                                                             *
+*  Description : Intègre une nouvelle règle de détection.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_content_scanner_add_rule(GContentScanner *scanner, GScanRule *rule)
+{
+    scanner->rules = realloc(scanner->rules, ++scanner->rule_count * sizeof(GScanRule *));
+
+    scanner->rules[scanner->rule_count - 1] = rule;
+
+    g_object_ref(G_OBJECT(rule));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : scanner = gestionnaire de recherche à compléter.             *
+*                options = ensemble des options d'analyses à respecter.       *
+*                content = contenu à parcourir et analyser.                   *
+*                                                                             *
+*  Description : Lance une analyse d'un contenu binaire.                      *
+*                                                                             *
+*  Retour      : Contexte de suivi pour l'analyse menée.                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanContext *g_content_scanner_analyze(GContentScanner *scanner, GScanOptions *options, GBinContent *content)
+{
+    GScanContext *result;                   /* Bilan global à retourner    */
+    bool status;                            /* Bilan d'opération locale    */
+    size_t i;                               /* Boucle de parcours          */
+
+    result = g_scan_context_new(options);
+
+    if (scanner->data_backend == NULL)
+    {
+        scanner->data_backend = g_object_new(g_scan_options_get_backend_for_data(options), NULL);
+        assert(scanner->data_backend != NULL);
+
+        status = (scanner->data_backend != NULL);
+
+        for (i = 0; i < scanner->rule_count && status; i++)
+            status = g_scan_rule_setup_backend(scanner->rules[i], scanner->data_backend, result);
+
+        if (!status)
+        {
+            g_clear_object(&result);
+            goto exit;
+        }
+
+    }
+
+    g_scan_context_set_content(result, content);
+
+    for (i = 0; i < scanner->rule_count; i++)
+        g_scan_rule_analyze(scanner->rules[i], scanner->data_backend, result);
+
+ exit:
+
+    return result;
+
+}
diff --git a/src/analysis/scan/scanner.h b/src/analysis/scan/scanner.h
new file mode 100644
index 0000000..8a3919a
--- /dev/null
+++ b/src/analysis/scan/scanner.h
@@ -0,0 +1,77 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * scanner.h - prototypes pour le parcours de contenus à la recherche de motifs
+ *
+ * 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 _ANALYSIS_SCAN_SCANNER_H
+#define _ANALYSIS_SCAN_SCANNER_H
+
+
+#include <glib-object.h>
+
+
+#include "context.h"
+#include "expr.h"
+#include "options.h"
+#include "rule.h"
+
+
+
+#define G_TYPE_CONTENT_SCANNER            g_content_scanner_get_type()
+#define G_CONTENT_SCANNER(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_CONTENT_SCANNER, GContentScanner))
+#define G_IS_CONTENT_SCANNER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_CONTENT_SCANNER))
+#define G_CONTENT_SCANNER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_CONTENT_SCANNER, GContentScannerClass))
+#define G_IS_CONTENT_SCANNER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_CONTENT_SCANNER))
+#define G_CONTENT_SCANNER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_CONTENT_SCANNER, GContentScannerClass))
+
+
+/* Encadrement d'une recherche au sein de contenus binaires (instance) */
+typedef struct _GContentScanner GContentScanner;
+
+/* Encadrement d'une recherche au sein de contenus binaires (classe) */
+typedef struct _GContentScannerClass GContentScannerClass;
+
+
+/* Indique le type défini pour une recherche dans du binaire. */
+GType g_content_scanner_get_type(void);
+
+/* Prépare une recherche de motifs dans du contenu binaire. */
+GContentScanner *g_content_scanner_new_from_text(const char *);
+
+/* Prépare une recherche de motifs dans du contenu binaire. */
+GContentScanner *g_content_scanner_new_from_file(const char *);
+
+/* Intègre une nouvelle règle de détection. */
+void g_content_scanner_add_rule(GContentScanner *, GScanRule *);
+
+/* Définit l'expression d'une correspondance recherchée. */
+GScanContext *g_content_scanner_analyze(GContentScanner *, GScanOptions *, GBinContent *);
+
+
+
+
+
+/* Lance une analyse d'un élément, fichier ou répertoire. */
+//void g_content_scanner_analyze(GContentScanner *, const char *);
+
+
+
+#endif  /* _ANALYSIS_SCAN_SCANNER_H */
diff --git a/src/analysis/scan/space-int.h b/src/analysis/scan/space-int.h
new file mode 100644
index 0000000..fa4437d
--- /dev/null
+++ b/src/analysis/scan/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 _ANALYSIS_SCAN_SPACE_INT_H
+#define _ANALYSIS_SCAN_SPACE_INT_H
+
+
+#include "space.h"
+
+
+#include "item-int.h"
+
+
+
+/* Espace de noms pour un groupe de fonctions (instance) */
+struct _GScanNamespace
+{
+    GRegisteredItem parent;                 /* A laisser en premier        */
+
+    GRegisteredItem **children;             /* Sous-éléments inscrits      */
+    char **names;                           /* Désignations correspondantes*/
+    size_t count;                           /* Quantité de sous-éléments   */
+
+};
+
+/* Espace de noms pour un groupe de fonctions (classe) */
+struct _GScanNamespaceClass
+{
+    GRegisteredItemClass parent;            /* A laisser en premier        */
+
+};
+
+
+
+#endif  /* _ANALYSIS_SCAN_SPACE_INT_H */
diff --git a/src/analysis/scan/space.c b/src/analysis/scan/space.c
new file mode 100644
index 0000000..f10424b
--- /dev/null
+++ b/src/analysis/scan/space.c
@@ -0,0 +1,310 @@
+
+/* 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 <assert.h>
+#include <string.h>
+
+
+#include "space-int.h"
+
+
+
+/* ------------------------- SOCLE POUR LES ESPACES DE NOMS ------------------------- */
+
+
+/* Initialise la classe des espaces de noms pour scan. */
+static void g_scan_namespace_class_init(GScanNamespaceClass *);
+
+/* Initialise une instance d'espace de noms pour scan. */
+static void g_scan_namespace_init(GScanNamespace *);
+
+/* Supprime toutes les références externes. */
+static void g_scan_namespace_dispose(GScanNamespace *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_scan_namespace_finalize(GScanNamespace *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Lance une résolution d'élément à appeler.                    *
+*                                                                             *
+*  Retour      : Nouvel élément d'appel identifié ou NULL.                    *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GRegisteredItem *g_scan_namespace_resolve(GScanNamespace *, const char *, GScanContext *, GScanExpression **, size_t, bool, bool);
+
+/* Réduit une expression à une forme plus simple. */
+GScanExpression *g_scan_namespace_reduce(GScanNamespace *, GScanContext *, GScanExpression **, size_t, bool);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                           SOCLE POUR LES ESPACES DE NOMS                           */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une définition d'espace de noms. */
+G_DEFINE_TYPE(GScanNamespace, g_scan_namespace, G_TYPE_REGISTERED_ITEM);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des espaces de noms pour scan.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_namespace_class_init(GScanNamespaceClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GRegisteredItemClass *registered;       /* Version de classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_namespace_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_scan_namespace_finalize;
+
+    registered = G_REGISTERED_ITEM_CLASS(klass);
+
+    registered->resolve = (resolve_registered_item_fc)g_scan_namespace_resolve;
+    registered->reduce = (reduce_registered_item_fc)g_scan_namespace_reduce;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : space = instance à initialiser.                              *
+*                                                                             *
+*  Description : Initialise une instance d'espace de noms pour scan.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_namespace_init(GScanNamespace *space)
+{
+    space->children = NULL;
+    space->names = NULL;
+    space->count = 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : space = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_namespace_dispose(GScanNamespace *space)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    for (i = 0; i < space->count; i++)
+        g_clear_object(&space->children[i]);
+
+    G_OBJECT_CLASS(g_scan_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_scan_namespace_finalize(GScanNamespace *space)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    if (space->children != NULL)
+        free(space->children);
+
+    for (i = 0; i < space->count; i++)
+        free(space->names[i]);
+
+    if (space->names != NULL)
+        free(space->names);
+
+    G_OBJECT_CLASS(g_scan_namespace_parent_class)->finalize(G_OBJECT(space));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Construit un nouvel espace de noms pour scan.                *
+*                                                                             *
+*  Retour      : Adresse de la structure mise en place.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanNamespace *g_scan_namespace_new(void)
+{
+    GScanNamespace *result;                 /* Instance à retourner        */
+
+    result = g_object_new(G_TYPE_SCAN_NAMESPACE, NULL);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : space = espace de noms à compléter.                          *
+*                type  = type d'élément à intégrer.                           *
+*                name  = nom du futur espace ou NULL pour une racine.         *
+*                                                                             *
+*  Description : Intègre un nouvel élément dans l'esapce de noms.             *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_scan_namespace_register(GScanNamespace *space, GRegisteredItem *child, const char *name)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = true;
+
+    space->count++;
+
+    space->children = realloc(space->children, space->count * sizeof(GRegisteredItem *));
+    space->children[space->count - 1] = child;
+
+    space->names = realloc(space->names, space->count * sizeof(char *));
+    space->names[space->count - 1] = strdup(name);
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : space  = élément d'appel à consulter.                        *
+*                target = désignation de l'objet d'appel à identifier.        *
+*                ctx    = contexte de suivi de l'analyse courante.            *
+*                args   = liste d'éventuels arguments fournis.                *
+*                count  = taille de cette liste.                              *
+*                last   = l'élément est-il le dernier d'une chaîne d'appels ? *
+*                final = indique une ultime conversion dans le cycle en cours.*
+*                                                                             *
+*  Description : Lance une résolution d'élément à appeler.                    *
+*                                                                             *
+*  Retour      : Nouvel élément d'appel identifié ou NULL.                    *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GRegisteredItem *g_scan_namespace_resolve(GScanNamespace *space, const char *target, GScanContext *ctx, GScanExpression **args, size_t count, bool last, bool final)
+{
+    GRegisteredItem *result;                /* Instance à renvoyer         */
+    size_t i;                               /* Boucle de parcours          */
+
+    result = NULL;
+
+    for (i = 0; i < space->count; i++)
+        if (strcmp(target, space->names[i]) == 0)
+        {
+            result = space->children[i];
+            g_object_ref(G_OBJECT(result));
+            break;
+        }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : space  = élément d'appel à consulter.                        *
+*                ctx    = contexte de suivi de l'analyse courante.            *
+*                args   = liste d'éventuels arguments fournis.                *
+*                count  = taille de cette liste.                              *
+*                final = indique une ultime conversion dans le cycle en cours.*
+*                                                                             *
+*  Description : Réduit une expression à une forme plus simple.               *
+*                                                                             *
+*  Retour      : Réduction correspondante, expression déjà réduite, ou NULL.  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanExpression *g_scan_namespace_reduce(GScanNamespace *space, GScanContext *ctx, GScanExpression **args, size_t count, bool final)
+{
+    GScanExpression *result;                /* Instance à renvoyer         */
+
+    assert(false);
+
+    result = NULL;
+
+    return result;
+
+}
diff --git a/src/analysis/scan/space.h b/src/analysis/scan/space.h
new file mode 100644
index 0000000..9058959
--- /dev/null
+++ b/src/analysis/scan/space.h
@@ -0,0 +1,62 @@
+
+/* 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 _ANALYSIS_SCAN_SPACE_H
+#define _ANALYSIS_SCAN_SPACE_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+
+
+#include "item.h"
+
+
+
+#define G_TYPE_SCAN_NAMESPACE            g_scan_namespace_get_type()
+#define G_SCAN_NAMESPACE(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_NAMESPACE, GScanNamespace))
+#define G_IS_SCAN_NAMESPACE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_NAMESPACE))
+#define G_SCAN_NAMESPACE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_NAMESPACE, GScanNamespaceClass))
+#define G_IS_SCAN_NAMESPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_NAMESPACE))
+#define G_SCAN_NAMESPACE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_NAMESPACE, GScanNamespaceClass))
+
+
+/* Espace de noms pour un groupe de fonctions (instance) */
+typedef struct _GScanNamespace GScanNamespace;
+
+/* Espace de noms pour un groupe de fonctions (classe) */
+typedef struct _GScanNamespaceClass GScanNamespaceClass;
+
+
+/* Indique le type défini pour une définition d'espace de noms. */
+GType g_scan_namespace_get_type(void);
+
+/* Construit un nouvel espace de noms pour scan. */
+GScanNamespace *g_scan_namespace_new(void);
+
+/* Intègre un nouvel élément dans l'esapce de noms. */
+bool g_scan_namespace_register(GScanNamespace *, GRegisteredItem *, const char *);
+
+
+
+#endif  /* _ANALYSIS_SCAN_SPACE_H */
diff --git a/src/analysis/scan/tokens.l b/src/analysis/scan/tokens.l
new file mode 100644
index 0000000..92a5340
--- /dev/null
+++ b/src/analysis/scan/tokens.l
@@ -0,0 +1,306 @@
+
+%top {
+
+#include "grammar.h"
+
+}
+
+
+%{
+
+//#include "manual.h"
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+
+#define read_block(tmp)                                                     \
+    ({                                                                      \
+        unsigned int __depth;                                               \
+        bool __is_string;                                                   \
+        char *__iter;                                                       \
+                                                                            \
+        __depth = 1;                                                        \
+        __is_string = false;                                                \
+                                                                            \
+        for (__iter = temp; __depth > 0; __iter += (__depth > 0 ? 1 : 0))   \
+        {                                                                   \
+            *__iter = input();                                              \
+                                                                            \
+            switch (*__iter)                                                \
+            {                                                               \
+                case '"':                                                   \
+                    __is_string = !__is_string;                             \
+                    break;                                                  \
+                                                                            \
+                case '{':                                                   \
+                    if (!__is_string) __depth++;                            \
+                    break;                                                  \
+                                                                            \
+                case '}':                                                   \
+                    if (!__is_string)                                       \
+                    {                                                       \
+                        __depth--;                                          \
+                        if (__depth == 0) unput('}');                       \
+                    }                                                       \
+                    break;                                                  \
+                                                                            \
+            }                                                               \
+                                                                            \
+        }                                                                   \
+                                                                            \
+        *__iter = '\0';                                                     \
+                                                                            \
+    })
+
+
+
+
+#define PUSH_STATE(s) yy_push_state(s, yyscanner)
+#define POP_STATE     yy_pop_state(yyscanner)
+
+
+
+#define EXTEND_BUFFER_IF_NEEDED(extra)      \
+    if ((*used + extra) > *allocated)       \
+    {                                       \
+        *allocated *= 2;                    \
+        *buf = realloc(*buf, *allocated);   \
+    }
+
+
+%}
+
+
+%option bison-bridge reentrant
+%option stack
+%option nounput
+%option noinput
+%option noyywrap
+%option noyy_top_state
+%option yylineno
+%option never-interactive
+
+
+%x rule_intro
+%x raw_block
+
+%x strings
+%x strval
+%x strval_raw
+%x strval_hex
+
+%x condition
+%x strlit
+
+%x wait_for_colon
+
+
+%x comment
+
+
+%%
+
+
+
+
+"rule"                          { PUSH_STATE(rule_intro); return RAW_RULE; }
+
+<rule_intro>[A-Za-z0-9_]+       {   yylval->cstring = yytext; return RULE_NAME; }
+
+<rule_intro>[ \t]*              {  }
+<rule_intro>"{"                 { POP_STATE; PUSH_STATE(raw_block); return BRACE_IN; }
+
+<raw_block>"strings"            { PUSH_STATE(strings); PUSH_STATE(wait_for_colon); return STRINGS; }
+<raw_block,strings>"condition"          { PUSH_STATE(condition); PUSH_STATE(wait_for_colon); return CONDITION; }
+
+
+
+
+
+
+<condition>"true"               { return TRUE_; }
+<condition>"false"              { return FALSE_; }
+
+<condition>(0|[1-9][0-9]*)      { yylval->integer = strtoull(yytext, NULL, 10); return INTEGER; }
+<condition>0x[0-9a-f]+          { yylval->integer = strtoull(yytext, NULL, 16); return INTEGER; }
+
+<condition>[kK][bB]             { return KB; }
+<condition>[mM][bB]             { return MB; }
+<condition>[gG][bB]             { return GB; }
+
+<condition>"\""                 {
+                                    *used = 0;
+                                    PUSH_STATE(strlit);
+                                }
+
+<strlit>"\""                    {
+                                    POP_STATE; 
+                                    EXTEND_BUFFER_IF_NEEDED(1);
+                                    (*buf)[(*used)++] = '\0';
+                                    yylval->cstring = *buf;
+                                    return STRING;
+                                }
+
+<strlit>"\\\""                  { EXTEND_BUFFER_IF_NEEDED(1); (*buf)[(*used)++] = '"'; }
+<strlit>"\\t"                   { EXTEND_BUFFER_IF_NEEDED(1); (*buf)[(*used)++] = '\t'; }
+<strlit>"\\r"                   { EXTEND_BUFFER_IF_NEEDED(1); (*buf)[(*used)++] = '\r'; }
+<strlit>"\\n"                   { EXTEND_BUFFER_IF_NEEDED(1); (*buf)[(*used)++] = '\n'; }
+<strlit>"\\\\"                  { EXTEND_BUFFER_IF_NEEDED(1); (*buf)[(*used)++] = '\\'; }
+
+<strlit>\\x[0-9a-fA-F]{2}       {
+                                    char __ch;
+                                    __ch = strtol(yytext + 2, NULL, 16);
+                                    EXTEND_BUFFER_IF_NEEDED(1);
+                                    (*buf)[(*used)++] = __ch;
+                                }
+
+<strlit>[^\\\"]+                {
+                                    size_t __len;
+                                    __len = strlen(yytext);
+                                    EXTEND_BUFFER_IF_NEEDED(__len);
+                                    strcpy(&(*buf)[*used], yytext);
+                                    *used += __len;
+                                }
+
+
+
+
+<condition>"and"                { return AND; }
+<condition>"or"                 { return OR; }
+<condition>"not"                { return NOT; }
+
+<condition>"<"                  { return LT; }
+<condition>"<="                 { return LE; }
+<condition>"=="                 { return EQ; }
+<condition>"!="                 { return NE; }
+<condition>">"                  { return GT; }
+<condition>">="                 { return GE; }
+
+<condition>"contains"           { return CONTAINS; }
+<condition>"startswith"         { return STARTSWITH; }
+<condition>"endswith"           { return ENDSWITH; }
+<condition>"matches"            { return MATCHES; }
+<condition>"icontains"          { return ICONTAINS; }
+<condition>"istartswith"        { return ISTARTSWITH; }
+<condition>"iendswith"          { return IENDSWITH; }
+<condition>"iequals"            { return IEQUALS; }
+
+<condition>"+"                  { return PLUS; }
+<condition>"-"                  { return MINUS; }
+<condition>"*"                  { return MUL; }
+<condition>"\\"                 { return DIV; }
+<condition>"%"                  { return MOD; }
+
+<condition>"("                  { return PAREN_O; }
+<condition>")"                  { return PAREN_C; }
+<condition>","                  { return COMMA; }
+<condition>"."                  { return DOT; }
+
+<condition>"none"               { return NONE; }
+<condition>"any"                { return ANY; }
+<condition>"all"                { return ALL; }
+<condition>"of"                 { return OF; }
+<condition>"them"               { return THEM; }
+
+
+<strings,condition>$[A-Za-z0-9_]* {
+                                    yylval->sized_cstring.cstring = yytext + 1;
+                                    yylval->sized_cstring.len = yyleng - 1;
+                                    return IDENTIFIER;
+                                }
+<condition>[A-Za-z_][A-Za-z0-9_]* {
+                                    yylval->sized_cstring.cstring = yytext;
+                                    yylval->sized_cstring.len = yyleng;
+                                    return NAME;
+                                }
+
+<strings>"="                    { PUSH_STATE(strval); return ASSIGN; }
+
+
+<strval>\"[^\"\\]+\"            {
+                                    POP_STATE;
+                                    yylval->sized_cstring.cstring = yytext + 1;
+                                    yylval->sized_cstring.len = yyleng - 2;
+                                    return PLAIN_STRING;
+                                }
+
+
+
+
+<strval>"\""                    {
+                                    POP_STATE;
+                                    // *built_pattern = g_bytes_pattern_new();
+                                    PUSH_STATE(strval_raw);
+                                }
+<strval>"{"                     {
+                                    POP_STATE;
+                                    // *built_pattern = g_bytes_pattern_new();
+                                    PUSH_STATE(strval_hex);
+                                }
+
+<strval_raw>"\""                { POP_STATE; /*yylval->pattern = *built_pattern*/; return MASKED_STRING; }
+
+<strval_raw>"\\\""              { }//g_bytes_pattern_append_data(*built_pattern, '"', 0xff); }
+<strval_raw>"\\t"               { }//g_bytes_pattern_append_data(*built_pattern, '\t', 0xff); }
+<strval_raw>"\\r"               { }//g_bytes_pattern_append_data(*built_pattern, '\r', 0xff); }
+<strval_raw>"\\n"               { }//g_bytes_pattern_append_data(*built_pattern, '\n', 0xff); }
+<strval_raw>"\\\\"              { }//g_bytes_pattern_append_data(*built_pattern, '\\', 0xff); }
+
+<strval_raw>\\x[0-9a-fA-F]{2}   {
+                                    uint8_t __ch;
+                                    __ch = strtol(yytext + 2, NULL, 16);
+                                    //g_bytes_pattern_append_data(*built_pattern, __ch, 0xff);
+                                }
+
+<strval_raw>.                   { }//g_bytes_pattern_append_data(*built_pattern, *yytext, 0xff); }
+
+<strval_hex>"}"                 { POP_STATE; /*yylval->pattern = *built_pattern;*/ return MASKED_STRING; }
+
+<strval_hex>[0-9a-fA-F]{2}      {
+                                    uint8_t __ch;
+                                    __ch = strtol(yytext, NULL, 16);
+                                    //g_bytes_pattern_append_data(*built_pattern, __ch, 0xff);
+                                }
+
+<strval_hex>"??"                { /*g_bytes_pattern_insert_space(*built_pattern, 1, 1);*/ }
+ 
+
+
+
+
+<wait_for_colon>":"             { POP_STATE; return COLON; }
+
+<raw_block,strings,condition>"}"                  { POP_STATE; return BRACE_OUT; }
+
+
+
+%{ /* Commentaires */ %}
+
+<*>"/*"                         { PUSH_STATE(comment); }
+<comment>"*/"                   { POP_STATE; }
+<comment>(.|\n)                 { }
+
+<*>"//"[^\n]*                   { }
+
+
+%{ /* Actions par défaut */ %}
+
+<*>[ \t\n]+                     { }
+
+<*>.                            {
+                                    char *msg;
+                                    int ret;
+                                    ret = asprintf(&msg, "Unhandled token in rule definition: '%s'", yytext);
+                                    if (ret == -1)
+                                        YY_FATAL_ERROR("Unhandled token in undisclosed rule definition");
+                                    else
+                                    {
+                                        YY_FATAL_ERROR(msg);
+                                        free(msg);
+                                    }
+ }
+
+
+%%
diff --git a/src/core/core.c b/src/core/core.c
index 62f6821..01ebbe1 100644
--- a/src/core/core.c
+++ b/src/core/core.c
@@ -40,6 +40,7 @@
 #include "params.h"
 #include "processors.h"
 #include "queue.h"
+#include "../analysis/scan/core.h"
 #include "../common/io.h"
 #include "../common/xdg.h"
 #include "../glibext/linesegment.h"
@@ -65,6 +66,7 @@ bool load_all_core_components(bool cs)
     char *cfgdir;                           /* Répertoire de configuration */
     GContentExplorer *explorer;             /* Explorateur de contenus     */
     GContentResolver *resolver;             /* Résolveur de contenus       */
+    GScanNamespace *root_ns;                /* Espace de noms ROST racine  */
 
     /**
      * On mémorise les passages réussis.
@@ -103,6 +105,11 @@ bool load_all_core_components(bool cs)
             resolver = g_content_resolver_new();
             set_current_content_resolver(resolver);
 
+            root_ns = g_scan_namespace_new();
+            set_rost_root_namespace(root_ns);
+
+            if (result) result = populate_main_scan_namespace(root_ns);
+
             if (result) result = init_segment_content_hash_table();
 
             register_arch_gtypes();
@@ -143,6 +150,8 @@ void unload_all_core_components(bool cs)
 
         unload_processors_definitions();
 
+        set_rost_root_namespace(NULL);
+
         set_current_content_resolver(NULL);
 
         set_current_content_explorer(NULL);
diff --git a/src/core/global.c b/src/core/global.c
index 4ebb9e0..c99d711 100644
--- a/src/core/global.c
+++ b/src/core/global.c
@@ -40,6 +40,9 @@ static GContentExplorer *_explorer = NULL;
 /* Résolveur de contenus */
 static GContentResolver *_resolver = NULL;
 
+/* Espace de noms racine pour ROST */
+static GScanNamespace *_rost_root_ns = NULL;
+
 /* Projet global actif */
 static GStudyProject *_project = NULL;
 
@@ -224,6 +227,54 @@ GContentResolver *get_current_content_resolver(void)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : ns = espace de noms racine de ROST.                          *
+*                                                                             *
+*  Description : Définit l'adresse de l'espace de noms principal pour ROST.   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void set_rost_root_namespace(GScanNamespace *ns)
+{
+    if (_rost_root_ns != NULL)
+        g_object_unref(G_OBJECT(_rost_root_ns));
+
+    _rost_root_ns = ns;
+
+    if (ns != NULL)
+        g_object_ref_sink(G_OBJECT(ns));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit l'adresse de l'espace de noms principal pour ROST.   *
+*                                                                             *
+*  Retour      : Espace de noms racine de ROST ou NULL si aucun (!).          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanNamespace *get_rost_root_namespace(void)
+{
+    assert(_rost_root_ns != NULL);
+
+    g_object_ref(G_OBJECT(_rost_root_ns));
+
+    return _rost_root_ns;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : project = éventuelle adresse du nouveau projet principal.    *
 *                                                                             *
 *  Description : Définit l'adresse du projet courant.                         *
diff --git a/src/core/global.h b/src/core/global.h
index 088a7c9..0a9172b 100644
--- a/src/core/global.h
+++ b/src/core/global.h
@@ -30,6 +30,7 @@
 
 #include "../analysis/loading.h"
 #include "../analysis/project.h"
+#include "../analysis/scan/space.h"
 #include "../glibext/delayed.h"
 
 
@@ -58,6 +59,12 @@ void set_current_content_resolver(GContentResolver *);
 /* Fournit l'adresse du résolveur de contenus courant. */
 GContentResolver *get_current_content_resolver(void);
 
+/* Définit l'adresse de l'espace de noms principal pour ROST. */
+void set_rost_root_namespace(GScanNamespace *);
+
+/* Fournit l'adresse de l'espace de noms principal pour ROST. */
+GScanNamespace *get_rost_root_namespace(void);
+
 /* Définit l'adresse du projet courant. */
 void set_current_project(GStudyProject *);
 
diff --git a/src/rost.c b/src/rost.c
new file mode 100644
index 0000000..37ca098
--- /dev/null
+++ b/src/rost.c
@@ -0,0 +1,316 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * rost.c - fichier d'entrée du centre de collecte
+ *
+ * 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 <getopt.h>
+#include <libgen.h>
+#include <locale.h>
+#include <stdlib.h>
+
+
+#include <config.h>
+#include <i18n.h>
+
+
+
+#include "gleak.h"
+#include "analysis/contents/file.h"
+#include "analysis/scan/options.h"
+#include "analysis/scan/scanner.h"
+#include "analysis/scan/patterns/backends/bitap.h"
+#include "analysis/scan/patterns/backends/acism.h"
+#include "core/core.h"
+#include "core/global.h"
+#include "core/logs.h"
+#include "core/paths.h"
+
+
+
+/* Affiche des indications quant à l'utilisation du programme. */
+static void show_rost_help(const char *);
+
+/* Affiche des indications sur la version courante du programme. */
+static void show_rost_version(void);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : name = nom du programme en question.                         *
+*                                                                             *
+*  Description : Affiche des indications quant à l'utilisation du programme.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void show_rost_help(const char *name)
+{
+    char *tmp;                              /* Conservation modifiable     */
+    char *base;                             /* Version courte du nom       */
+
+    tmp = strdup(name);
+
+    base = basename(tmp);
+
+    printf("\n");
+
+    printf("Usage: %s [--help] [--version] [--verbosity] [options] <rules file> <file | dir>\n", base);
+
+    printf("\n");
+
+    printf("\t-h --help\t\tShow this help message.\n");
+    printf("\t-v --version\t\tDisplay the program version.\n");
+
+    printf("\n");
+
+    printf("\t-A --algorithm=name\tSelect one of the available algorithms for data: bitmap, acism (default: acsim).\n");
+    printf("\t-S --print-stats\tPrint rules' statistics.\n");
+    printf("\t-V --verbosity=level\tSet the log level (0 for all messages, %u for none).\n", LMT_COUNT);
+
+    printf("\n");
+
+    free(tmp);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Affiche des indications sur la version courante du programme.*
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void show_rost_version(void)
+{
+    char *edir;                             /* Répertoire de base effectif */
+
+    printf("\n");
+
+    printf("-o-  Chrysalide ROST r%u  -o-\n", REVISION);
+    printf(_("Last compiled on %s at %s\n"), __DATE__, __TIME__);
+
+    printf("\n");
+
+    edir = get_effective_directory(PLUGINS_LIB_DIR);
+    printf(_("Plugins library directory: %s\n"), edir);
+    free(edir);
+
+    edir = get_effective_directory(PLUGINS_DATA_DIR);
+    printf(_("Plugins data directory: %s\n"), edir);
+    free(edir);
+
+    edir = get_effective_directory(LOCALE_DIR);
+    printf(_("Locale directory: %s\n"), edir);
+    free(edir);
+
+    printf("\n");
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : argc = nombre d'arguments dans la ligne de commande.         *
+*                argv = arguments de la ligne de commande.                    *
+*                                                                             *
+*  Description : Point d'entrée du programme.                                 *
+*                                                                             *
+*  Retour      : EXIT_SUCCESS si le prgm s'est déroulé sans encombres.        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int main(int argc, char **argv)
+{
+    int result;                             /* Bilan de l'exécution        */
+    bool show_help;                         /* Affichage de l'aide ?       */
+    bool show_version;                      /* Affichage de la version ?   */
+    LogMessageType verbosity;               /* Niveau de filtre de message */
+    GScanOptions *options;                  /* Options d'analyses          */
+    int index;                              /* Indice d'argument           */
+    int ret;                                /* Bilan d'un appel            */
+    char *rules;                            /* Définition de règles        */
+    char *target;                           /* Cible communiquée           */
+    char *edir;                             /* Répertoire de base effectif */
+    GContentScanner *scanner;               /* Encadrement d'une recherche */
+    GBinContent *content;                   /* Contenu à analyser          */
+    GScanContext *context;                  /* Contexte des trouvailles    */
+
+    static struct option long_options[] = {
+        { "help",           no_argument,        NULL,   'h' },
+        { "version",        no_argument,        NULL,   'v' },
+        { "algorithm",      required_argument,  NULL,   'A' },
+        { "print-stats",    no_argument,        NULL,   'S' },
+        { "verbosity",      required_argument,  NULL,   'V' },
+        { NULL,             0,                  NULL,   0 }
+    };
+
+    result = EXIT_FAILURE;
+
+    /* Décodage des options */
+
+    show_help = false;
+    show_version = false;
+
+    verbosity = LMT_INFO;
+
+    options = g_scan_options_new();
+
+    g_scan_options_set_backend_for_data(options, G_TYPE_ACISM_BACKEND);
+
+    while (true)
+    {
+        ret = getopt_long(argc, argv, "hvA:SV:", long_options, &index);
+        if (ret == -1) break;
+
+        switch (ret)
+        {
+            case 'h':
+                show_help = true;
+                break;
+
+            case 'v':
+                show_version = true;
+                break;
+
+            case 'A':
+                if (strcmp(optarg, "bitmap") == 0)
+                    g_scan_options_set_backend_for_data(options, G_TYPE_BITAP_BACKEND);
+                else if (strcmp(optarg, "acism") == 0)
+                    g_scan_options_set_backend_for_data(options, G_TYPE_ACISM_BACKEND);
+                else
+                    g_scan_options_set_backend_for_data(options, G_TYPE_INVALID);
+                break;
+
+            case 'S':
+                g_scan_options_set_print_stats(options, true);
+                break;
+
+            case 'V':
+                verbosity = strtoul(optarg, NULL, 10);
+                break;
+
+        }
+
+    }
+
+    if ((optind + 2) != argc)
+    {
+        show_rost_help(argv[0]);
+        result = EXIT_FAILURE;
+        goto done;
+    }
+
+    rules = argv[optind];
+    target = argv[optind + 1];
+
+    /* Actions de base */
+
+    if (show_help)
+    {
+        show_rost_help(argv[0]);
+        result = EXIT_SUCCESS;
+        goto done;
+    }
+
+    if (show_version)
+    {
+        show_rost_version();
+        result = EXIT_SUCCESS;
+        goto done;
+    }
+
+    if (g_scan_options_get_backend_for_data(options) == G_TYPE_INVALID)
+    {
+        show_rost_help(argv[0]);
+        result = EXIT_FAILURE;
+        goto done;
+    }
+
+    /* Lancement des choses sérieuses */
+
+    setlocale(LC_ALL, "");
+    edir = get_effective_directory(LOCALE_DIR);
+    bindtextdomain(PACKAGE, edir);
+    free(edir);
+    textdomain(PACKAGE);
+
+    /* Initialisation de GTK */
+    g_set_prgname("ROST");
+    //gtk_init(&argc, &argv);
+
+    /* Initialisation du programme */
+
+    set_batch_mode();
+
+    set_log_verbosity(verbosity);
+
+    /*
+    if (!load_all_core_components(false))
+        goto done;
+    */
+
+    /* Traitement des recherches */
+
+    scanner = g_content_scanner_new_from_file(rules);
+
+    content = g_file_content_new(target);
+
+    context = g_content_scanner_analyze(scanner, options, content);
+
+    g_scan_context_display(context);
+
+    g_object_unref(G_OBJECT(context));
+    g_object_unref(G_OBJECT(content));
+
+    g_object_unref(G_OBJECT(scanner));
+
+    g_object_unref(G_OBJECT(options));
+
+    /* Sortie */
+
+    //unload_all_core_components(false);
+
+#ifdef TRACK_GOBJECT_LEAKS
+    remember_gtypes_for_leaks();
+#endif
+
+#ifdef TRACK_GOBJECT_LEAKS
+    dump_remaining_gtypes();
+#endif
+
+ done:
+
+    return result;
+
+}
diff --git a/tests/analysis/scan/expr.py b/tests/analysis/scan/expr.py
new file mode 100644
index 0000000..dbe8c55
--- /dev/null
+++ b/tests/analysis/scan/expr.py
@@ -0,0 +1,169 @@
+
+
+from chrysacase import ChrysalideTestCase
+from pychrysalide.analysis.scan import ScanExpression
+from pychrysalide.glibext import ComparableItem
+
+
+class TestScanExpression(ChrysalideTestCase):
+    """TestCase for analysis.scan.ScanExpression."""
+
+
+    def testDirectInstances(self):
+        """Reject direct instances."""
+
+        with self.assertRaisesRegex(RuntimeError, 'pychrysalide.analysis.scan.ScanExpression is an abstract class'):
+
+            e = ScanExpression()
+
+
+    def testBooleanComparison(self):
+        """Compare custom scan expressions."""
+
+        class StrLenExpr(ScanExpression):
+
+            def __init__(self, value):
+                super().__init__(ScanExpression.ExprValueType.STRING)
+                self._value = value
+
+            def _cmp_rich(self, other, op):
+
+                if op == ComparableItem.RichCmpOperation.EQ:
+                    return len(self._value) == len(other._value)
+
+
+        e0 = StrLenExpr('00000000000')
+
+        e1 = StrLenExpr('00000000000')
+
+        e2 = StrLenExpr('000000000000000000000000000')
+
+        self.assertTrue(e0 == e1)
+
+        # !?
+        # Python teste e0 != e1 (non implémenté), puis e1 != e0 (pareil) et en déduit une différence !
+        # self.assertFalse(e0 != e1)
+
+        self.assertFalse(e0 == e2)
+
+        # TypeError: '<' not supported between instances of 'StrLenExpr' and 'StrLenExpr'
+        with self.assertRaisesRegex(TypeError, '\'<\' not supported between instances'):
+            self.assertTrue(e0 < e1)
+
+
+
+
+
+
+    # def testTypeSubclassing(self):
+    #     """Verify the data type subclassing is working."""
+
+    #     class MyType(DataType):
+
+    #         def __init__(self, num):
+    #             super(MyType, self).__init__()
+    #             self._num = num
+
+    #         def _to_string(self, include):
+    #             return '%x' % self._num
+
+    #         def _dup(self):
+    #             return MyType(self._num)
+
+    #     tp = MyType(0x123)
+
+    #     self.assertEqual(str(tp), '123')
+
+    #     tp2 = tp.dup()
+
+    #     self.assertEqual(str(tp), str(tp2))
+
+
+    # def testTypeDefaultProperties(self):
+    #     """Check for default values of some type properties."""
+
+    #     class MyPropType(DataType):
+    #         pass
+
+    #     tp = MyPropType()
+
+    #     self.assertTrue(tp.handle_namespaces)
+
+    #     self.assertFalse(tp.is_pointer)
+
+    #     self.assertFalse(tp.is_reference)
+
+    #     class MyPropType2(DataType):
+
+    #         def _handle_namespaces(self):
+    #             return True
+
+    #         def _is_pointer(self):
+    #             return 123 < 1234
+
+    #         def _is_reference(self):
+    #             return False
+
+    #     tp2 = MyPropType2()
+
+    #     self.assertTrue(tp.handle_namespaces)
+
+    #     self.assertTrue(tp2.is_pointer)
+
+    #     self.assertFalse(tp2.is_reference)
+
+
+    # def testTypeNamespaces(self):
+    #     """Test the type namespace property."""
+
+    #     class MyNSType(DataType):
+
+    #         def __init__(self, name):
+    #             super(MyNSType, self).__init__()
+    #             self._name = name
+
+    #         def _to_string(self, include):
+    #             return self._name
+
+    #     tp = MyNSType('TP')
+    #     ns = MyNSType('NS')
+
+    #     self.assertIsNone(tp.namespace)
+
+    #     tp.namespace = (ns, '.')
+
+    #     self.assertEqual(str(tp), 'NS.TP')
+
+    #     self.assertEqual(tp.namespace, (ns, '.'))
+
+
+    # def testTypeHash(self):
+    #     """Hash a user-defined type."""
+
+    #     class MyUserType(DataType):
+
+    #         def __init__(self, name):
+    #             super(MyUserType, self).__init__()
+    #             self._name = name
+
+    #         def _hash(self):
+    #             return hash(self._name)
+
+    #     tp = MyUserType('random')
+
+    #     self.assertEqual(tp.hash, hash('random') & ((1 << 32) - 1))
+
+    #     class MyOutOfRangeUserType(DataType):
+
+    #         hard_coded_hash = -8752470794866657507
+
+    #         def __init__(self, name):
+    #             super(MyOutOfRangeUserType, self).__init__()
+    #             self._name = name
+
+    #         def _hash(self):
+    #             return self.hard_coded_hash
+
+    #     tp = MyOutOfRangeUserType('out-of-range')
+
+    #     self.assertEqual(tp.hash, MyOutOfRangeUserType.hard_coded_hash & ((1 << 32) - 1))
diff --git a/tests/analysis/scan/exprs.py b/tests/analysis/scan/exprs.py
new file mode 100644
index 0000000..c89dc59
--- /dev/null
+++ b/tests/analysis/scan/exprs.py
@@ -0,0 +1,122 @@
+
+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
+
+
+class TestScanExpressions(ChrysalideTestCase):
+    """TestCase for analysis.scan.exprs.*."""
+
+    @classmethod
+    def setUpClass(cls):
+
+        super(TestScanExpressions, cls).setUpClass()
+
+        cls._options = ScanOptions()
+        cls._options.backend_for_data = AcismBackend
+
+
+    def testBasicStringOperations(self):
+        """Evaluate basic string operations."""
+
+        cnt = MemoryContent(b'empty')
+
+        rule = '''
+rule test {
+
+   condition:
+      "123abc456" contains "abc"
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertTrue(ctx.has_match_for_rule('test'))
+
+        rule = '''
+rule test {
+
+   condition:
+      "123\t456" contains "\t"
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertTrue(ctx.has_match_for_rule('test'))
+
+        rule = '''
+rule test {
+
+   condition:
+      "123-456" startswith "1"
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertTrue(ctx.has_match_for_rule('test'))
+
+        rule = '''
+rule test {
+
+   condition:
+      "123-456" startswith "1234"
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertFalse(ctx.has_match_for_rule('test'))
+
+        rule = '''
+rule test {
+
+   condition:
+      "123-456" endswith "6"
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertTrue(ctx.has_match_for_rule('test'))
+
+        rule = '''
+rule test {
+
+   condition:
+      "123-456" endswith "3456"
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertFalse(ctx.has_match_for_rule('test'))
+
+        rule = '''
+rule test {
+
+   condition:
+      "ABCD" iequals "AbCd"
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertTrue(ctx.has_match_for_rule('test'))
diff --git a/tests/analysis/scan/func.py b/tests/analysis/scan/func.py
new file mode 100644
index 0000000..bd7d0ce
--- /dev/null
+++ b/tests/analysis/scan/func.py
@@ -0,0 +1,16 @@
+
+
+from chrysacase import ChrysalideTestCase
+from pychrysalide.analysis.scan import ScanFunction
+
+
+class TestScanFunction(ChrysalideTestCase):
+    """TestCase for analysis.scan.ScanFunction."""
+
+
+    def testDirectInstances(self):
+        """Reject direct instances."""
+
+        with self.assertRaisesRegex(RuntimeError, 'pychrysalide.analysis.scan.ScanFunction is an abstract class'):
+
+            f = ScanFunction('name')
diff --git a/tests/analysis/scan/grammar.py b/tests/analysis/scan/grammar.py
new file mode 100644
index 0000000..5a2e1d5
--- /dev/null
+++ b/tests/analysis/scan/grammar.py
@@ -0,0 +1,286 @@
+
+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
+
+
+class TestRostGrammar(ChrysalideTestCase):
+    """TestCase for analysis.scan.ScanExpression."""
+
+    @classmethod
+    def setUpClass(cls):
+
+        super(TestRostGrammar, cls).setUpClass()
+
+        cls._options = ScanOptions()
+        cls._options.backend_for_data = AcismBackend
+
+
+    def testComments(self):
+        """Ensure comments do not bother rule definitions."""
+
+        cnt = MemoryContent(b'no_real_content')
+
+        rule = '''
+/*
+    Multi-line header...
+*/
+
+rule test {    // comment
+
+   /*
+    * Some context
+    */
+
+   condition:  /* List of condition(s) */
+      true     // Dummy condition
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertTrue(not(ctx is None) and ctx.has_match_for_rule('test'))
+
+
+    def testUintCast(self):
+        """Process nested integer values from binary content."""
+
+        cnt = MemoryContent(b'\x4d\x5a\x00\x00' + b'\x50\x45\x00\x00' + 52 * b'\x00' + b'\x04\x00\x00\x00')
+
+        rule = '''
+rule IsPE {
+
+    condition:
+
+        // MZ signature at offset 0 and ...
+
+        uint16(0) == 0x5a4d and
+
+        // ... PE signature at offset stored in the MZ header at offset 0x3c
+
+        uint32(uint32(0x3c)) == 0x00004550
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertTrue(not(ctx is None) and ctx.has_match_for_rule('IsPE'))
+
+
+    def testBasicBooleanConditions(self):
+        """Evaluate basic boolean conditions."""
+
+        cnt = MemoryContent(b'0123')
+
+        rule = '''
+rule test {
+
+   condition:
+      true and false
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertTrue(not(ctx is None))
+        self.assertFalse(ctx.has_match_for_rule('test'))
+
+        rule = '''
+rule test {
+
+   condition:
+      true or false
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertTrue(not(ctx is None) and ctx.has_match_for_rule('test'))
+
+
+    def testArithmeticOpeations(self):
+        """Compute some arithmetic operations."""
+
+        cnt = MemoryContent(b'0123')
+
+        rule = '''
+rule test {
+
+   condition:
+      1 + 4 * 3 + 2 == 15
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertTrue(not(ctx is None) and ctx.has_match_for_rule('test'))
+
+
+        rule = '''
+rule test {
+
+   condition:
+      (1 + 4) * 3 + 2 == 17
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertTrue(not(ctx is None) and ctx.has_match_for_rule('test'))
+
+
+        rule = '''
+rule test {
+
+   condition:
+      1 + 4 * (3 + 2) == 21
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertTrue(not(ctx is None) and ctx.has_match_for_rule('test'))
+
+
+        rule = '''
+rule test {
+
+   condition:
+      (1 + 4) * (3 + 2) == 25
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertTrue(not(ctx is None) and ctx.has_match_for_rule('test'))
+
+
+    def testSizeUnits(self):
+        """Evaluate size units."""
+
+        cnt = MemoryContent(b'0123')
+
+
+        rule = '''
+rule test {
+
+   condition:
+      1KB == 1024
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertTrue(not(ctx is None) and ctx.has_match_for_rule('test'))
+
+
+        rule = '''
+rule test {
+
+   condition:
+      2MB == 2 * 1024 * 1024
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertTrue(not(ctx is None) and ctx.has_match_for_rule('test'))
+
+
+        rule = '''
+rule test {
+
+   condition:
+      4Kb == (4 * 1024)
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertTrue(not(ctx is None) and ctx.has_match_for_rule('test'))
+
+
+        rule = '''
+rule test {
+
+   condition:
+      1KB <= 1024 and 1024 < 1MB
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertTrue(not(ctx is None) and ctx.has_match_for_rule('test'))
+
+
+    def testNamespace(self):
+        """Resolve main functions with the root scan namesapce."""
+
+        cnt = MemoryContent(b'\x01\x02\x03\x04')
+
+        rule = '''
+rule test {
+
+   condition:
+      datasize == 4
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertTrue(not(ctx is None) and ctx.has_match_for_rule('test'))
+
+
+        rule = '''
+rule test {
+
+   condition:
+      uint16(0) == 0x201 and uint16(datasize - 2) == 0x0403
+
+}
+'''
+
+        scanner = ContentScanner(rule)
+
+        ctx = scanner.analyze(self._options, cnt)
+
+        self.assertTrue(not(ctx is None) and ctx.has_match_for_rule('test'))
diff --git a/tests/analysis/scan/options.py b/tests/analysis/scan/options.py
new file mode 100644
index 0000000..7617b3a
--- /dev/null
+++ b/tests/analysis/scan/options.py
@@ -0,0 +1,16 @@
+
+
+from chrysacase import ChrysalideTestCase
+from gi._constants import TYPE_INVALID
+from pychrysalide.analysis.scan import ScanOptions
+
+
+class TestScanOptions(ChrysalideTestCase):
+    """TestCase for analysis.scan.ScanOptions."""
+
+    def testEmptyOptions(self):
+        """Check default scan options."""
+
+        ops = ScanOptions()
+
+        self.assertEqual(ops.backend_for_data, TYPE_INVALID)
-- 
cgit v0.11.2-87-g4458