From c370bb014b20654a2b7351b2a9d7e1e5a3ce92cc Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sat, 21 Oct 2023 23:51:20 +0200
Subject: Implement a few extra customized Windows API hashings.

---
 plugins/apihashing/core.c                        |  12 +
 plugins/apihashing/custom/Makefile.am            |   8 +-
 plugins/apihashing/custom/add1505-shl5.c         | 325 +++++++++++++++++++
 plugins/apihashing/custom/add1505-shl5.h         |  58 ++++
 plugins/apihashing/custom/enigma-murmur.c        | 377 +++++++++++++++++++++++
 plugins/apihashing/custom/enigma-murmur.h        |  58 ++++
 plugins/apihashing/custom/imul21-add.c           | 326 ++++++++++++++++++++
 plugins/apihashing/custom/imul21-add.h           |  58 ++++
 plugins/apihashing/custom/imul83-add.c           | 326 ++++++++++++++++++++
 plugins/apihashing/custom/imul83-add.h           |  58 ++++
 plugins/apihashing/custom/sub-index1.c           | 291 +++++++++++++++++
 plugins/apihashing/custom/sub-index1.h           |  58 ++++
 plugins/apihashing/custom/sub42.c                | 291 +++++++++++++++++
 plugins/apihashing/custom/sub42.h                |  58 ++++
 plugins/apihashing/python/custom/Makefile.am     |   8 +-
 plugins/apihashing/python/custom/add1505-shl5.c  | 211 +++++++++++++
 plugins/apihashing/python/custom/add1505-shl5.h  |  45 +++
 plugins/apihashing/python/custom/enigma-murmur.c | 211 +++++++++++++
 plugins/apihashing/python/custom/enigma-murmur.h |  45 +++
 plugins/apihashing/python/custom/imul21-add.c    | 211 +++++++++++++
 plugins/apihashing/python/custom/imul21-add.h    |  45 +++
 plugins/apihashing/python/custom/imul83-add.c    | 211 +++++++++++++
 plugins/apihashing/python/custom/imul83-add.h    |  45 +++
 plugins/apihashing/python/custom/module.c        |  12 +
 plugins/apihashing/python/custom/sub-index1.c    | 213 +++++++++++++
 plugins/apihashing/python/custom/sub-index1.h    |  45 +++
 plugins/apihashing/python/custom/sub42.c         | 212 +++++++++++++
 plugins/apihashing/python/custom/sub42.h         |  45 +++
 tests/analysis/scan/pyapi.py                     |  89 +++++-
 29 files changed, 3946 insertions(+), 6 deletions(-)
 create mode 100644 plugins/apihashing/custom/add1505-shl5.c
 create mode 100644 plugins/apihashing/custom/add1505-shl5.h
 create mode 100644 plugins/apihashing/custom/enigma-murmur.c
 create mode 100644 plugins/apihashing/custom/enigma-murmur.h
 create mode 100644 plugins/apihashing/custom/imul21-add.c
 create mode 100644 plugins/apihashing/custom/imul21-add.h
 create mode 100644 plugins/apihashing/custom/imul83-add.c
 create mode 100644 plugins/apihashing/custom/imul83-add.h
 create mode 100644 plugins/apihashing/custom/sub-index1.c
 create mode 100644 plugins/apihashing/custom/sub-index1.h
 create mode 100644 plugins/apihashing/custom/sub42.c
 create mode 100644 plugins/apihashing/custom/sub42.h
 create mode 100644 plugins/apihashing/python/custom/add1505-shl5.c
 create mode 100644 plugins/apihashing/python/custom/add1505-shl5.h
 create mode 100644 plugins/apihashing/python/custom/enigma-murmur.c
 create mode 100644 plugins/apihashing/python/custom/enigma-murmur.h
 create mode 100644 plugins/apihashing/python/custom/imul21-add.c
 create mode 100644 plugins/apihashing/python/custom/imul21-add.h
 create mode 100644 plugins/apihashing/python/custom/imul83-add.c
 create mode 100644 plugins/apihashing/python/custom/imul83-add.h
 create mode 100644 plugins/apihashing/python/custom/sub-index1.c
 create mode 100644 plugins/apihashing/python/custom/sub-index1.h
 create mode 100644 plugins/apihashing/python/custom/sub42.c
 create mode 100644 plugins/apihashing/python/custom/sub42.h

diff --git a/plugins/apihashing/core.c b/plugins/apihashing/core.c
index dd480a8..a74a637 100644
--- a/plugins/apihashing/core.c
+++ b/plugins/apihashing/core.c
@@ -35,7 +35,13 @@
 #include "classics/crc32.h"
 #include "classics/djb2.h"
 #include "classics/ror13.h"
+#include "custom/add1505-shl5.h"
+#include "custom/enigma-murmur.h"
+#include "custom/imul21-add.h"
+#include "custom/imul83-add.h"
 #include "custom/sll1-add-hash32.h"
+#include "custom/sub-index1.h"
+#include "custom/sub42.h"
 
 
 #ifdef INCLUDE_PYTHON3_BINDINGS_
@@ -84,7 +90,13 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin)
     if (result) result = REGISTER_SCAN_MODIFIER(g_scan_djb2_modifier_new());
     if (result) result = REGISTER_SCAN_MODIFIER(g_scan_ror13_modifier_new());
 
+    if (result) result = REGISTER_SCAN_MODIFIER(g_scan_add1505_shl5_modifier_new());
+    if (result) result = REGISTER_SCAN_MODIFIER(g_scan_enigma_murmur_modifier_new());
+    if (result) result = REGISTER_SCAN_MODIFIER(g_scan_imul21_add_modifier_new());
+    if (result) result = REGISTER_SCAN_MODIFIER(g_scan_imul83_add_modifier_new());
     if (result) result = REGISTER_SCAN_MODIFIER(g_scan_sll1_add_hash32_modifier_new());
+    if (result) result = REGISTER_SCAN_MODIFIER(g_scan_sub42_modifier_new());
+    if (result) result = REGISTER_SCAN_MODIFIER(g_scan_sub_index1_modifier_new());
 
 #ifdef INCLUDE_PYTHON3_BINDINGS
 
diff --git a/plugins/apihashing/custom/Makefile.am b/plugins/apihashing/custom/Makefile.am
index 4c0359b..026addc 100644
--- a/plugins/apihashing/custom/Makefile.am
+++ b/plugins/apihashing/custom/Makefile.am
@@ -2,7 +2,13 @@
 noinst_LTLIBRARIES = libapihashingcustom.la
 
 libapihashingcustom_la_SOURCES =			\
-	sll1-add-hash32.h sll1-add-hash32.c
+	add1505-shl5.h add1505-shl5.c			\
+	enigma-murmur.h enigma-murmur.c			\
+	imul21-add.h imul21-add.c				\
+	imul83-add.h imul83-add.c				\
+	sll1-add-hash32.h sll1-add-hash32.c		\
+	sub-index1.h sub-index1.c				\
+	sub42.h sub42.c
 
 libapihashingcustom_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) -I$(top_srcdir)/src
 
diff --git a/plugins/apihashing/custom/add1505-shl5.c b/plugins/apihashing/custom/add1505-shl5.c
new file mode 100644
index 0000000..db96cf1
--- /dev/null
+++ b/plugins/apihashing/custom/add1505-shl5.c
@@ -0,0 +1,325 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * add1505-shl5.c - transormation en empreinte d'API add1505-shl5
+ *
+ * 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 "add1505-shl5.h"
+
+
+#include <malloc.h>
+
+
+#include <analysis/scan/patterns/modifier-int.h>
+
+
+
+
+/* ----------------------- RECHERCHE D'UN MOTIF DE TEXTE BRUT ----------------------- */
+
+
+/* Initialise la classe des transmissions en empreintes add1505-shl5. */
+static void g_scan_add1505_shl5_modifier_class_init(GScanAdd1505Shl5ModifierClass *);
+
+/* Initialise une instance de transmission en empreinte add1505-shl5. */
+static void g_scan_add1505_shl5_modifier_init(GScanAdd1505Shl5Modifier *);
+
+/* Supprime toutes les références externes. */
+static void g_scan_add1505_shl5_modifier_dispose(GScanAdd1505Shl5Modifier *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_scan_add1505_shl5_modifier_finalize(GScanAdd1505Shl5Modifier *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Fournit le nom d'appel d'un modificateur pour motif. */
+static char *g_scan_add1505_shl5_modifier_get_name(const GScanAdd1505Shl5Modifier *);
+
+/* Calcule l'empreinte add1505-shl5 d'un motif de recherche. */
+static uint32_t compute_add1505_shl5_hash32(const sized_binary_t *);
+
+/* Transforme une séquence d'octets pour motif de recherche. */
+static bool g_scan_add1505_shl5_modifier_transform(const GScanAdd1505Shl5Modifier *, const sized_binary_t *, size_t, sized_binary_t **, size_t *);
+
+/* Retrouve l'origine d'une correspondance à partir d'un indice. */
+static char *g_scan_add1505_shl5_modifier_get_path(const GScanAdd1505Shl5Modifier *, size_t *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                         RECHERCHE D'UN MOTIF DE TEXTE BRUT                         */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une transormation en empreinte add1505-shl5. */
+G_DEFINE_TYPE(GScanAdd1505Shl5Modifier, g_scan_add1505_shl5_modifier, G_TYPE_API_HASH_MODIFIER);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des transmissions en empreintes add1505-shl5.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_add1505_shl5_modifier_class_init(GScanAdd1505Shl5ModifierClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GScanTokenModifierClass *modifier;      /* Version de classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_add1505_shl5_modifier_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_scan_add1505_shl5_modifier_finalize;
+
+    modifier = G_SCAN_TOKEN_MODIFIER_CLASS(klass);
+
+    modifier->get_name = (get_scan_modifier_name_fc)g_scan_add1505_shl5_modifier_get_name;
+
+    modifier->transform = (transform_scan_token_fc)g_scan_add1505_shl5_modifier_transform;
+    modifier->get_path = (get_modifier_path)g_scan_add1505_shl5_modifier_get_path;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = instance à initialiser.                           *
+*                                                                             *
+*  Description : Initialise une instance de transmission en empreinte add1505-shl5.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_add1505_shl5_modifier_init(GScanAdd1505Shl5Modifier *modifier)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = instance d'objet GLib à traiter.                  *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_add1505_shl5_modifier_dispose(GScanAdd1505Shl5Modifier *modifier)
+{
+    G_OBJECT_CLASS(g_scan_add1505_shl5_modifier_parent_class)->dispose(G_OBJECT(modifier));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = instance d'objet GLib à traiter.                  *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_add1505_shl5_modifier_finalize(GScanAdd1505Shl5Modifier *modifier)
+{
+    G_OBJECT_CLASS(g_scan_add1505_shl5_modifier_parent_class)->finalize(G_OBJECT(modifier));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Construit un modificateur livrant des empreintes add1505-shl5.      *
+*                                                                             *
+*  Retour      : Mécanisme mis en place.                                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanTokenModifier *g_scan_add1505_shl5_modifier_new(void)
+{
+    GScanTokenModifier *result;                    /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_SCAN_ADD1505_SHL5_MODIFIER, NULL);
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = modificateur à consulter.                         *
+*                                                                             *
+*  Description : Fournit le nom d'appel d'un modificateur pour motif.         *
+*                                                                             *
+*  Retour      : Désignation humaine.                                         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *g_scan_add1505_shl5_modifier_get_name(const GScanAdd1505Shl5Modifier *modifier)
+{
+    char *result;                           /* Désignation à retourner     */
+
+    result = strdup("add1505-shl5");
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : src = séquence d'octets à traiter.                           *
+*                                                                             *
+*  Description : Calcule l'empreinte add1505-shl5 d'un motif de recherche.    *
+*                                                                             *
+*  Retour      : Valeur entière de l'empreinte déterminée.                    *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static uint32_t compute_add1505_shl5_hash32(const sized_binary_t *src)
+{
+    uint32_t result;                        /* Valeur à retourner          */
+    size_t i;                               /* Boucle de parcours          */
+
+    result = 0x1505;
+
+    for (i = 0; i < src->len; i++)
+    {
+        result += (result << 5);
+        result += src->data[i];
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = modificateur à solliciter.                        *
+*                src      = séquences d'octets à traiter.                     *
+*                scount   = quantité de ces séquences.                        *
+*                dest     = nouvelle(s) séquence(s) d'octets obtenue(s) [OUT] *
+*                dcount   = quantité de ces séquences.                        *
+*                                                                             *
+*  Description : Transforme une séquence d'octets pour motif de recherche.    *
+*                                                                             *
+*  Retour      : Bilan de l'opération : succès ou échec.                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_scan_add1505_shl5_modifier_transform(const GScanAdd1505Shl5Modifier *modifier, const sized_binary_t *src, size_t scount, sized_binary_t **dest, size_t *dcount)
+{
+    bool result;                            /* Bilan d'opération à renvoyer*/
+    sized_binary_t *binary;                 /* Raccourci vers le stockage  */
+    size_t i;                               /* Boucle de parcours #1       */
+    const sized_binary_t *_src;             /* Source courante             */
+    uint32_t hash;                          /* Valeur d'empreinte calculée */
+
+    result = true;
+
+    *dcount = scount;
+    *dest = calloc(*dcount, sizeof(sized_binary_t));
+
+    binary = &(*dest)[0];
+
+    for (i = 0; i < scount; i++, binary++)
+    {
+        _src = src + i;
+
+        hash = compute_add1505_shl5_hash32(_src);
+
+        binary->data = malloc(sizeof(hash) * sizeof(bin_t));
+        binary->len = sizeof(hash);
+
+        memcpy(binary->data, &hash, sizeof(hash));
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = modificateur à consulter.                         *
+*                index    = indice de la combinaison ciblée. [OUT]            *
+*                                                                             *
+*  Description : Retrouve l'origine d'une correspondance à partir d'un indice.*
+*                                                                             *
+*  Retour      : Version humainement lisible de la combinaison.               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *g_scan_add1505_shl5_modifier_get_path(const GScanAdd1505Shl5Modifier *modifier, size_t *index)
+{
+    char *result;                           /* Combinaison à retourner     */
+
+    if (*index > 0)
+    {
+        result = NULL;
+        (*index)--;
+    }
+
+    else
+        result = strdup("add1505-shl5");
+
+    return result;
+
+}
diff --git a/plugins/apihashing/custom/add1505-shl5.h b/plugins/apihashing/custom/add1505-shl5.h
new file mode 100644
index 0000000..5e71987
--- /dev/null
+++ b/plugins/apihashing/custom/add1505-shl5.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * add1505-shl5.h - prototypes pour la transormation en empreinte d'API add1505-shl5
+ *
+ * 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 _PLUGINS_APIHASHING_CUSTOM_ADD1505_SHL5_H
+#define _PLUGINS_APIHASHING_CUSTOM_ADD1505_SHL5_H
+
+
+#include <glib-object.h>
+
+
+#include "../apihash.h"
+
+
+
+#define G_TYPE_SCAN_ADD1505_SHL5_MODIFIER            g_scan_add1505_shl5_modifier_get_type()
+#define G_SCAN_ADD1505_SHL5_MODIFIER(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_ADD1505_SHL5_MODIFIER, GScanAdd1505Shl5Modifier))
+#define G_IS_SCAN_ADD1505_SHL5_MODIFIER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_ADD1505_SHL5_MODIFIER))
+#define G_SCAN_ADD1505_SHL5_MODIFIER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_ADD1505_SHL5_MODIFIER, GScanAdd1505Shl5ModifierClass))
+#define G_IS_SCAN_ADD1505_SHL5_MODIFIER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_ADD1505_SHL5_MODIFIER))
+#define G_SCAN_ADD1505_SHL5_MODIFIER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_ADD1505_SHL5_MODIFIER, GScanAdd1505Shl5ModifierClass))
+
+
+/* Transormation en empreinte d'API add1505-shl5 (instance) */
+typedef GApiHashModifier GScanAdd1505Shl5Modifier;
+
+/* Transormation en empreinte d'API add1505-shl5 (classe) */
+typedef GApiHashModifierClass GScanAdd1505Shl5ModifierClass;
+
+
+/* Indique le type défini pour une transormation en empreinte add1505-shl5. */
+GType g_scan_add1505_shl5_modifier_get_type(void);
+
+/* Construit un modificateur livrant des empreintes add1505-shl5. */
+GScanTokenModifier *g_scan_add1505_shl5_modifier_new(void);
+
+
+
+#endif  /* _PLUGINS_APIHASHING_CUSTOM_ADD1505_SHL5_H */
diff --git a/plugins/apihashing/custom/enigma-murmur.c b/plugins/apihashing/custom/enigma-murmur.c
new file mode 100644
index 0000000..cdc35b0
--- /dev/null
+++ b/plugins/apihashing/custom/enigma-murmur.c
@@ -0,0 +1,377 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * enigma-murmur.c - transormation en empreinte d'API enigma-murmur
+ *
+ * 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 "enigma-murmur.h"
+
+
+#include <malloc.h>
+
+
+#include <analysis/scan/patterns/modifier-int.h>
+
+
+
+
+/* ----------------------- RECHERCHE D'UN MOTIF DE TEXTE BRUT ----------------------- */
+
+
+/* Initialise la classe des empreintes enigma-murmur. */
+static void g_scan_enigma_murmur_modifier_class_init(GScanEnigmaMurmurModifierClass *);
+
+/* Initialise une instance d'empreinte enigma-murmur. */
+static void g_scan_enigma_murmur_modifier_init(GScanEnigmaMurmurModifier *);
+
+/* Supprime toutes les références externes. */
+static void g_scan_enigma_murmur_modifier_dispose(GScanEnigmaMurmurModifier *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_scan_enigma_murmur_modifier_finalize(GScanEnigmaMurmurModifier *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Fournit le nom d'appel d'un modificateur pour motif. */
+static char *g_scan_enigma_murmur_modifier_get_name(const GScanEnigmaMurmurModifier *);
+
+/* Calcule l'empreinte enigma-murmur d'un motif de recherche. */
+static uint32_t compute_enigma_murmur_hash32(const sized_binary_t *);
+
+/* Transforme une séquence d'octets pour motif de recherche. */
+static bool g_scan_enigma_murmur_modifier_transform(const GScanEnigmaMurmurModifier *, const sized_binary_t *, size_t, sized_binary_t **, size_t *);
+
+/* Retrouve l'origine d'une correspondance à partir d'un indice. */
+static char *g_scan_enigma_murmur_modifier_get_path(const GScanEnigmaMurmurModifier *, size_t *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                         RECHERCHE D'UN MOTIF DE TEXTE BRUT                         */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une transormation en empreinte enigma-murmur. */
+G_DEFINE_TYPE(GScanEnigmaMurmurModifier, g_scan_enigma_murmur_modifier, G_TYPE_API_HASH_MODIFIER);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des empreintes enigma-murmur.           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_enigma_murmur_modifier_class_init(GScanEnigmaMurmurModifierClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GScanTokenModifierClass *modifier;      /* Version de classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_enigma_murmur_modifier_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_scan_enigma_murmur_modifier_finalize;
+
+    modifier = G_SCAN_TOKEN_MODIFIER_CLASS(klass);
+
+    modifier->get_name = (get_scan_modifier_name_fc)g_scan_enigma_murmur_modifier_get_name;
+
+    modifier->transform = (transform_scan_token_fc)g_scan_enigma_murmur_modifier_transform;
+    modifier->get_path = (get_modifier_path)g_scan_enigma_murmur_modifier_get_path;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = instance à initialiser.                           *
+*                                                                             *
+*  Description : Initialise une instance d'empreinte enigma-murmur.           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_enigma_murmur_modifier_init(GScanEnigmaMurmurModifier *modifier)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = instance d'objet GLib à traiter.                  *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_enigma_murmur_modifier_dispose(GScanEnigmaMurmurModifier *modifier)
+{
+    G_OBJECT_CLASS(g_scan_enigma_murmur_modifier_parent_class)->dispose(G_OBJECT(modifier));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = instance d'objet GLib à traiter.                  *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_enigma_murmur_modifier_finalize(GScanEnigmaMurmurModifier *modifier)
+{
+    G_OBJECT_CLASS(g_scan_enigma_murmur_modifier_parent_class)->finalize(G_OBJECT(modifier));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Construit un modificateur pour des empreintes enigma-murmur. *
+*                                                                             *
+*  Retour      : Mécanisme mis en place.                                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanTokenModifier *g_scan_enigma_murmur_modifier_new(void)
+{
+    GScanTokenModifier *result;                    /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_SCAN_ENIGMA_MURMUR_MODIFIER, NULL);
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = modificateur à consulter.                         *
+*                                                                             *
+*  Description : Fournit le nom d'appel d'un modificateur pour motif.         *
+*                                                                             *
+*  Retour      : Désignation humaine.                                         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *g_scan_enigma_murmur_modifier_get_name(const GScanEnigmaMurmurModifier *modifier)
+{
+    char *result;                           /* Désignation à retourner     */
+
+    result = strdup("enigma-murmur");
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : src = séquence d'octets à traiter.                           *
+*                                                                             *
+*  Description : Calcule l'empreinte enigma-murmur d'un motif de recherche.   *
+*                                                                             *
+*  Retour      : Valeur entière de l'empreinte déterminée.                    *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static uint32_t compute_enigma_murmur_hash32(const sized_binary_t *src)
+{
+    uint32_t result;                        /* Valeur à retourner          */
+    size_t blk_count;                       /* Nombre de blocs présents    */
+    size_t i;                               /* Boucle de parcours          */
+    uint32_t k;                             /* Valeur pour un bloc         */
+    const bin_t *tail;                      /* Fragement de bloc final     */
+
+    result = 0x4a03bdfa;
+
+    /* Traitement par blocs de 4 octets */
+
+    blk_count = src->len / 4;
+
+    for (i = 0; i < blk_count; i++)
+    {
+        k = ((uint32_t *)src->data)[i];
+
+        k *= 0xcc9e2d51;
+        k = (k << 15) | (k >> 17);
+        k *= 0x1b873593;
+
+        result ^= k;
+        result = (result << 13) | (result >> 19);
+        result = result * 5 + 0xe6546b64;
+
+    }
+
+    /* Traitement du reste */
+
+    tail = src->static_bin_data + 4 * blk_count;
+
+    k = 0;
+
+    switch (src->len & 3)
+    {
+        case 3:
+            k ^= (tail[2] << 16);
+
+        case 2:
+            k ^= (tail[1] << 8);
+
+        case 1:
+            k ^= tail[0];
+            k *= 0xcc9e2d51;
+            k = (k << 15) | (k >> (17));
+            k *= 0x1b873593;
+            result ^= k;
+            break;
+
+        case 0:
+            break;
+
+    }
+
+    /* Conclusion */
+
+    result ^= src->len;
+
+    result ^= (result >> 16);
+    result *= 0x85ebca6b;
+    result ^= (result >> 13);
+    result *= 0xc2b2ae35;
+    result ^= (result >> 16);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = modificateur à solliciter.                        *
+*                src      = séquences d'octets à traiter.                     *
+*                scount   = quantité de ces séquences.                        *
+*                dest     = nouvelle(s) séquence(s) d'octets obtenue(s) [OUT] *
+*                dcount   = quantité de ces séquences.                        *
+*                                                                             *
+*  Description : Transforme une séquence d'octets pour motif de recherche.    *
+*                                                                             *
+*  Retour      : Bilan de l'opération : succès ou échec.                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_scan_enigma_murmur_modifier_transform(const GScanEnigmaMurmurModifier *modifier, const sized_binary_t *src, size_t scount, sized_binary_t **dest, size_t *dcount)
+{
+    bool result;                            /* Bilan d'opération à renvoyer*/
+    sized_binary_t *binary;                 /* Raccourci vers le stockage  */
+    size_t i;                               /* Boucle de parcours #1       */
+    const sized_binary_t *_src;             /* Source courante             */
+    uint32_t hash;                          /* Valeur d'empreinte calculée */
+
+    result = true;
+
+    *dcount = scount;
+    *dest = calloc(*dcount, sizeof(sized_binary_t));
+
+    binary = &(*dest)[0];
+
+    for (i = 0; i < scount; i++, binary++)
+    {
+        _src = src + i;
+
+        hash = compute_enigma_murmur_hash32(_src);
+
+        binary->data = malloc(sizeof(hash) * sizeof(bin_t));
+        binary->len = sizeof(hash);
+
+        memcpy(binary->data, &hash, sizeof(hash));
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = modificateur à consulter.                         *
+*                index    = indice de la combinaison ciblée. [OUT]            *
+*                                                                             *
+*  Description : Retrouve l'origine d'une correspondance à partir d'un indice.*
+*                                                                             *
+*  Retour      : Version humainement lisible de la combinaison.               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *g_scan_enigma_murmur_modifier_get_path(const GScanEnigmaMurmurModifier *modifier, size_t *index)
+{
+    char *result;                           /* Combinaison à retourner     */
+
+    if (*index > 0)
+    {
+        result = NULL;
+        (*index)--;
+    }
+
+    else
+        result = strdup("enigma-murmur");
+
+    return result;
+
+}
diff --git a/plugins/apihashing/custom/enigma-murmur.h b/plugins/apihashing/custom/enigma-murmur.h
new file mode 100644
index 0000000..29ae803
--- /dev/null
+++ b/plugins/apihashing/custom/enigma-murmur.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * enigma-murmur.h - prototypes pour la transormation en empreinte d'API enigma-murmur
+ *
+ * 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 _PLUGINS_APIHASHING_CUSTOM_ENIGMA_MURMUR_H
+#define _PLUGINS_APIHASHING_CUSTOM_ENIGMA_MURMUR_H
+
+
+#include <glib-object.h>
+
+
+#include "../apihash.h"
+
+
+
+#define G_TYPE_SCAN_ENIGMA_MURMUR_MODIFIER            g_scan_enigma_murmur_modifier_get_type()
+#define G_SCAN_ENIGMA_MURMUR_MODIFIER(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_ENIGMA_MURMUR_MODIFIER, GScanEnigmaMurmurModifier))
+#define G_IS_SCAN_ENIGMA_MURMUR_MODIFIER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_ENIGMA_MURMUR_MODIFIER))
+#define G_SCAN_ENIGMA_MURMUR_MODIFIER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_ENIGMA_MURMUR_MODIFIER, GScanEnigmaMurmurModifierClass))
+#define G_IS_SCAN_ENIGMA_MURMUR_MODIFIER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_ENIGMA_MURMUR_MODIFIER))
+#define G_SCAN_ENIGMA_MURMUR_MODIFIER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_ENIGMA_MURMUR_MODIFIER, GScanEnigmaMurmurModifierClass))
+
+
+/* Transormation en empreinte d'API enigma-murmur (instance) */
+typedef GApiHashModifier GScanEnigmaMurmurModifier;
+
+/* Transormation en empreinte d'API enigma-murmur (classe) */
+typedef GApiHashModifierClass GScanEnigmaMurmurModifierClass;
+
+
+/* Indique le type défini pour une transormation en empreinte enigma-murmur. */
+GType g_scan_enigma_murmur_modifier_get_type(void);
+
+/* Construit un modificateur pour des empreintes enigma-murmur. */
+GScanTokenModifier *g_scan_enigma_murmur_modifier_new(void);
+
+
+
+#endif  /* _PLUGINS_APIHASHING_CUSTOM_ENIGMA_MURMUR_H */
diff --git a/plugins/apihashing/custom/imul21-add.c b/plugins/apihashing/custom/imul21-add.c
new file mode 100644
index 0000000..2f71910
--- /dev/null
+++ b/plugins/apihashing/custom/imul21-add.c
@@ -0,0 +1,326 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * imul21-add.c - transormation en empreinte d'API imul21-add
+ *
+ * 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 "imul21-add.h"
+
+
+#include <malloc.h>
+#include <string.h>
+
+
+#include <analysis/scan/patterns/modifier-int.h>
+
+
+
+
+/* ----------------------- RECHERCHE D'UN MOTIF DE TEXTE BRUT ----------------------- */
+
+
+/* Initialise la classe des transmissions en imul21-add. */
+static void g_scan_imul21_add_modifier_class_init(GScanImul21AddModifierClass *);
+
+/* Initialise une instance de transmission en imul21-add. */
+static void g_scan_imul21_add_modifier_init(GScanImul21AddModifier *);
+
+/* Supprime toutes les références externes. */
+static void g_scan_imul21_add_modifier_dispose(GScanImul21AddModifier *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_scan_imul21_add_modifier_finalize(GScanImul21AddModifier *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Fournit le nom d'appel d'un modificateur pour motif. */
+static char *g_scan_imul21_add_modifier_get_name(const GScanImul21AddModifier *);
+
+/* Calcule l'empreinte imul21-add d'un motif de recherche. */
+static uint32_t compute_imul21_add(const sized_binary_t *);
+
+/* Transforme une séquence d'octets pour motif de recherche. */
+static bool g_scan_imul21_add_modifier_transform(const GScanImul21AddModifier *, const sized_binary_t *, size_t, sized_binary_t **, size_t *);
+
+/* Retrouve l'origine d'une correspondance à partir d'un indice. */
+static char *g_scan_imul21_add_modifier_get_path(const GScanImul21AddModifier *, size_t *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                         RECHERCHE D'UN MOTIF DE TEXTE BRUT                         */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une transormation en empreinte imul21-add. */
+G_DEFINE_TYPE(GScanImul21AddModifier, g_scan_imul21_add_modifier, G_TYPE_API_HASH_MODIFIER);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des transmissions en imul21-add.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_imul21_add_modifier_class_init(GScanImul21AddModifierClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GScanTokenModifierClass *modifier;      /* Version de classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_imul21_add_modifier_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_scan_imul21_add_modifier_finalize;
+
+    modifier = G_SCAN_TOKEN_MODIFIER_CLASS(klass);
+
+    modifier->get_name = (get_scan_modifier_name_fc)g_scan_imul21_add_modifier_get_name;
+
+    modifier->transform = (transform_scan_token_fc)g_scan_imul21_add_modifier_transform;
+    modifier->get_path = (get_modifier_path)g_scan_imul21_add_modifier_get_path;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = instance à initialiser.                           *
+*                                                                             *
+*  Description : Initialise une instance de transmission en imul21-add.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_imul21_add_modifier_init(GScanImul21AddModifier *modifier)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = instance d'objet GLib à traiter.                  *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_imul21_add_modifier_dispose(GScanImul21AddModifier *modifier)
+{
+    G_OBJECT_CLASS(g_scan_imul21_add_modifier_parent_class)->dispose(G_OBJECT(modifier));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = instance d'objet GLib à traiter.                  *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_imul21_add_modifier_finalize(GScanImul21AddModifier *modifier)
+{
+    G_OBJECT_CLASS(g_scan_imul21_add_modifier_parent_class)->finalize(G_OBJECT(modifier));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Construit un modificateur vers empreintes imul21-add.        *
+*                                                                             *
+*  Retour      : Mécanisme mis en place.                                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanTokenModifier *g_scan_imul21_add_modifier_new(void)
+{
+    GScanTokenModifier *result;                    /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_SCAN_IMUL21_ADD_MODIFIER, NULL);
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = modificateur à consulter.                         *
+*                                                                             *
+*  Description : Fournit le nom d'appel d'un modificateur pour motif.         *
+*                                                                             *
+*  Retour      : Désignation humaine.                                         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *g_scan_imul21_add_modifier_get_name(const GScanImul21AddModifier *modifier)
+{
+    char *result;                           /* Désignation à retourner     */
+
+    result = strdup("imul21-add");
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : src = séquence d'octets à traiter.                           *
+*                                                                             *
+*  Description : Calcule l'empreinte imul21-add d'un motif de recherche.      *
+*                                                                             *
+*  Retour      : Valeur entière de l'empreinte déterminée.                    *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static uint32_t compute_imul21_add(const sized_binary_t *src)
+{
+    uint32_t result;                        /* Valeur à retourner          */
+    size_t i;                               /* Boucle de parcours          */
+
+    result = 0;
+
+    for (i = 0; i < src->len; i++)
+    {
+        result *= 0x21;
+        result += src->data[i];
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = modificateur à solliciter.                        *
+*                src      = séquences d'octets à traiter.                     *
+*                scount   = quantité de ces séquences.                        *
+*                dest     = nouvelle(s) séquence(s) d'octets obtenue(s) [OUT] *
+*                dcount   = quantité de ces séquences.                        *
+*                                                                             *
+*  Description : Transforme une séquence d'octets pour motif de recherche.    *
+*                                                                             *
+*  Retour      : Bilan de l'opération : succès ou échec.                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_scan_imul21_add_modifier_transform(const GScanImul21AddModifier *modifier, const sized_binary_t *src, size_t scount, sized_binary_t **dest, size_t *dcount)
+{
+    bool result;                            /* Bilan d'opération à renvoyer*/
+    sized_binary_t *binary;                 /* Raccourci vers le stockage  */
+    size_t i;                               /* Boucle de parcours #1       */
+    const sized_binary_t *_src;             /* Source courante             */
+    uint32_t hash;                          /* Valeur d'empreinte calculée */
+
+    result = true;
+
+    *dcount = scount;
+    *dest = calloc(*dcount, sizeof(sized_binary_t));
+
+    binary = &(*dest)[0];
+
+    for (i = 0; i < scount; i++, binary++)
+    {
+        _src = src + i;
+
+        hash = compute_imul21_add(_src);
+
+        binary->data = malloc(sizeof(hash) * sizeof(bin_t));
+        binary->len = sizeof(hash);
+
+        memcpy(binary->data, &hash, sizeof(hash));
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = modificateur à consulter.                         *
+*                index    = indice de la combinaison ciblée. [OUT]            *
+*                                                                             *
+*  Description : Retrouve l'origine d'une correspondance à partir d'un indice.*
+*                                                                             *
+*  Retour      : Version humainement lisible de la combinaison.               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *g_scan_imul21_add_modifier_get_path(const GScanImul21AddModifier *modifier, size_t *index)
+{
+    char *result;                           /* Combinaison à retourner     */
+
+    if (*index > 0)
+    {
+        result = NULL;
+        (*index)--;
+    }
+
+    else
+        result = strdup("imul21-add");
+
+    return result;
+
+}
diff --git a/plugins/apihashing/custom/imul21-add.h b/plugins/apihashing/custom/imul21-add.h
new file mode 100644
index 0000000..fcaa140
--- /dev/null
+++ b/plugins/apihashing/custom/imul21-add.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * imul21-add.h - prototypes pour la transormation en empreinte d'API imul21-add
+ *
+ * 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 _PLUGINS_APIHASHING_CUSTOM_IMUL21_ADD_H
+#define _PLUGINS_APIHASHING_CUSTOM_IMUL21_ADD_H
+
+
+#include <glib-object.h>
+
+
+#include "../apihash.h"
+
+
+
+#define G_TYPE_SCAN_IMUL21_ADD_MODIFIER            g_scan_imul21_add_modifier_get_type()
+#define G_SCAN_IMUL21_ADD_MODIFIER(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_IMUL21_ADD_MODIFIER, GScanImul21AddModifier))
+#define G_IS_SCAN_IMUL21_ADD_MODIFIER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_IMUL21_ADD_MODIFIER))
+#define G_SCAN_IMUL21_ADD_MODIFIER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_IMUL21_ADD_MODIFIER, GScanImul21AddModifierClass))
+#define G_IS_SCAN_IMUL21_ADD_MODIFIER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_IMUL21_ADD_MODIFIER))
+#define G_SCAN_IMUL21_ADD_MODIFIER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_IMUL21_ADD_MODIFIER, GScanImul21AddModifierClass))
+
+
+/* Transformation en empreinte d'API imul21-add (instance) */
+typedef GApiHashModifier GScanImul21AddModifier;
+
+/* Transformation en empreinte d'API imul21-add (classe) */
+typedef GApiHashModifierClass GScanImul21AddModifierClass;
+
+
+/* Indique le type défini pour une transormation en empreinte imul21-add. */
+GType g_scan_imul21_add_modifier_get_type(void);
+
+/* Construit un modificateur vers empreintes imul21-add. */
+GScanTokenModifier *g_scan_imul21_add_modifier_new(void);
+
+
+
+#endif  /* _PLUGINS_APIHASHING_CUSTOM_IMUL21_ADD_H */
diff --git a/plugins/apihashing/custom/imul83-add.c b/plugins/apihashing/custom/imul83-add.c
new file mode 100644
index 0000000..29f8cf5
--- /dev/null
+++ b/plugins/apihashing/custom/imul83-add.c
@@ -0,0 +1,326 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * imul83-add.c - transormation en empreinte d'API imul83-add
+ *
+ * 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 "imul83-add.h"
+
+
+#include <malloc.h>
+#include <string.h>
+
+
+#include <analysis/scan/patterns/modifier-int.h>
+
+
+
+
+/* ----------------------- RECHERCHE D'UN MOTIF DE TEXTE BRUT ----------------------- */
+
+
+/* Initialise la classe des transmissions en imul83-add. */
+static void g_scan_imul83_add_modifier_class_init(GScanImul83AddModifierClass *);
+
+/* Initialise une instance de transmission en imul83-add. */
+static void g_scan_imul83_add_modifier_init(GScanImul83AddModifier *);
+
+/* Supprime toutes les références externes. */
+static void g_scan_imul83_add_modifier_dispose(GScanImul83AddModifier *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_scan_imul83_add_modifier_finalize(GScanImul83AddModifier *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Fournit le nom d'appel d'un modificateur pour motif. */
+static char *g_scan_imul83_add_modifier_get_name(const GScanImul83AddModifier *);
+
+/* Calcule l'empreinte imul83-add d'un motif de recherche. */
+static uint32_t compute_imul83_add(const sized_binary_t *);
+
+/* Transforme une séquence d'octets pour motif de recherche. */
+static bool g_scan_imul83_add_modifier_transform(const GScanImul83AddModifier *, const sized_binary_t *, size_t, sized_binary_t **, size_t *);
+
+/* Retrouve l'origine d'une correspondance à partir d'un indice. */
+static char *g_scan_imul83_add_modifier_get_path(const GScanImul83AddModifier *, size_t *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                         RECHERCHE D'UN MOTIF DE TEXTE BRUT                         */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une transormation en empreinte imul83-add. */
+G_DEFINE_TYPE(GScanImul83AddModifier, g_scan_imul83_add_modifier, G_TYPE_API_HASH_MODIFIER);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des transmissions en imul83-add.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_imul83_add_modifier_class_init(GScanImul83AddModifierClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GScanTokenModifierClass *modifier;      /* Version de classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_imul83_add_modifier_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_scan_imul83_add_modifier_finalize;
+
+    modifier = G_SCAN_TOKEN_MODIFIER_CLASS(klass);
+
+    modifier->get_name = (get_scan_modifier_name_fc)g_scan_imul83_add_modifier_get_name;
+
+    modifier->transform = (transform_scan_token_fc)g_scan_imul83_add_modifier_transform;
+    modifier->get_path = (get_modifier_path)g_scan_imul83_add_modifier_get_path;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = instance à initialiser.                           *
+*                                                                             *
+*  Description : Initialise une instance de transmission en imul83-add.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_imul83_add_modifier_init(GScanImul83AddModifier *modifier)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = instance d'objet GLib à traiter.                  *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_imul83_add_modifier_dispose(GScanImul83AddModifier *modifier)
+{
+    G_OBJECT_CLASS(g_scan_imul83_add_modifier_parent_class)->dispose(G_OBJECT(modifier));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = instance d'objet GLib à traiter.                  *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_imul83_add_modifier_finalize(GScanImul83AddModifier *modifier)
+{
+    G_OBJECT_CLASS(g_scan_imul83_add_modifier_parent_class)->finalize(G_OBJECT(modifier));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Construit un modificateur vers empreintes imul83-add.        *
+*                                                                             *
+*  Retour      : Mécanisme mis en place.                                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanTokenModifier *g_scan_imul83_add_modifier_new(void)
+{
+    GScanTokenModifier *result;                    /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_SCAN_IMUL83_ADD_MODIFIER, NULL);
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = modificateur à consulter.                         *
+*                                                                             *
+*  Description : Fournit le nom d'appel d'un modificateur pour motif.         *
+*                                                                             *
+*  Retour      : Désignation humaine.                                         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *g_scan_imul83_add_modifier_get_name(const GScanImul83AddModifier *modifier)
+{
+    char *result;                           /* Désignation à retourner     */
+
+    result = strdup("imul83-add");
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : src = séquence d'octets à traiter.                           *
+*                                                                             *
+*  Description : Calcule l'empreinte imul83-add d'un motif de recherche.      *
+*                                                                             *
+*  Retour      : Valeur entière de l'empreinte déterminée.                    *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static uint32_t compute_imul83_add(const sized_binary_t *src)
+{
+    uint32_t result;                        /* Valeur à retourner          */
+    size_t i;                               /* Boucle de parcours          */
+
+    result = 0;
+
+    for (i = 0; i < src->len; i++)
+    {
+        result *= 0x83;
+        result += src->data[i];
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = modificateur à solliciter.                        *
+*                src      = séquences d'octets à traiter.                     *
+*                scount   = quantité de ces séquences.                        *
+*                dest     = nouvelle(s) séquence(s) d'octets obtenue(s) [OUT] *
+*                dcount   = quantité de ces séquences.                        *
+*                                                                             *
+*  Description : Transforme une séquence d'octets pour motif de recherche.    *
+*                                                                             *
+*  Retour      : Bilan de l'opération : succès ou échec.                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_scan_imul83_add_modifier_transform(const GScanImul83AddModifier *modifier, const sized_binary_t *src, size_t scount, sized_binary_t **dest, size_t *dcount)
+{
+    bool result;                            /* Bilan d'opération à renvoyer*/
+    sized_binary_t *binary;                 /* Raccourci vers le stockage  */
+    size_t i;                               /* Boucle de parcours #1       */
+    const sized_binary_t *_src;             /* Source courante             */
+    uint32_t hash;                          /* Valeur d'empreinte calculée */
+
+    result = true;
+
+    *dcount = scount;
+    *dest = calloc(*dcount, sizeof(sized_binary_t));
+
+    binary = &(*dest)[0];
+
+    for (i = 0; i < scount; i++, binary++)
+    {
+        _src = src + i;
+
+        hash = compute_imul83_add(_src);
+
+        binary->data = malloc(sizeof(hash) * sizeof(bin_t));
+        binary->len = sizeof(hash);
+
+        memcpy(binary->data, &hash, sizeof(hash));
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = modificateur à consulter.                         *
+*                index    = indice de la combinaison ciblée. [OUT]            *
+*                                                                             *
+*  Description : Retrouve l'origine d'une correspondance à partir d'un indice.*
+*                                                                             *
+*  Retour      : Version humainement lisible de la combinaison.               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *g_scan_imul83_add_modifier_get_path(const GScanImul83AddModifier *modifier, size_t *index)
+{
+    char *result;                           /* Combinaison à retourner     */
+
+    if (*index > 0)
+    {
+        result = NULL;
+        (*index)--;
+    }
+
+    else
+        result = strdup("imul83-add");
+
+    return result;
+
+}
diff --git a/plugins/apihashing/custom/imul83-add.h b/plugins/apihashing/custom/imul83-add.h
new file mode 100644
index 0000000..7e376ee
--- /dev/null
+++ b/plugins/apihashing/custom/imul83-add.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * imul83-add.h - prototypes pour la transormation en empreinte d'API imul83-add
+ *
+ * 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 _PLUGINS_APIHASHING_CUSTOM_IMUL83_ADD_H
+#define _PLUGINS_APIHASHING_CUSTOM_IMUL83_ADD_H
+
+
+#include <glib-object.h>
+
+
+#include "../apihash.h"
+
+
+
+#define G_TYPE_SCAN_IMUL83_ADD_MODIFIER            g_scan_imul83_add_modifier_get_type()
+#define G_SCAN_IMUL83_ADD_MODIFIER(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_IMUL83_ADD_MODIFIER, GScanImul83AddModifier))
+#define G_IS_SCAN_IMUL83_ADD_MODIFIER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_IMUL83_ADD_MODIFIER))
+#define G_SCAN_IMUL83_ADD_MODIFIER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_IMUL83_ADD_MODIFIER, GScanImul83AddModifierClass))
+#define G_IS_SCAN_IMUL83_ADD_MODIFIER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_IMUL83_ADD_MODIFIER))
+#define G_SCAN_IMUL83_ADD_MODIFIER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_IMUL83_ADD_MODIFIER, GScanImul83AddModifierClass))
+
+
+/* Transformation en empreinte d'API imul83-add (instance) */
+typedef GApiHashModifier GScanImul83AddModifier;
+
+/* Transformation en empreinte d'API imul83-add (classe) */
+typedef GApiHashModifierClass GScanImul83AddModifierClass;
+
+
+/* Indique le type défini pour une transormation en empreinte imul83-add. */
+GType g_scan_imul83_add_modifier_get_type(void);
+
+/* Construit un modificateur vers empreintes imul83-add. */
+GScanTokenModifier *g_scan_imul83_add_modifier_new(void);
+
+
+
+#endif  /* _PLUGINS_APIHASHING_CUSTOM_IMUL83_ADD_H */
diff --git a/plugins/apihashing/custom/sub-index1.c b/plugins/apihashing/custom/sub-index1.c
new file mode 100644
index 0000000..79eafd8
--- /dev/null
+++ b/plugins/apihashing/custom/sub-index1.c
@@ -0,0 +1,291 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * sub-index1.c - transormation en empreinte d'API sub-index1
+ *
+ * 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 "sub-index1.h"
+
+
+#include <malloc.h>
+
+
+#include <analysis/scan/patterns/modifier-int.h>
+
+
+
+
+/* ----------------------- RECHERCHE D'UN MOTIF DE TEXTE BRUT ----------------------- */
+
+
+/* Initialise la classe des transmissions en sub-index1. */
+static void g_scan_sub_index1_modifier_class_init(GScanSubIndex1ModifierClass *);
+
+/* Initialise une instance de transmission en sub-index1. */
+static void g_scan_sub_index1_modifier_init(GScanSubIndex1Modifier *);
+
+/* Supprime toutes les références externes. */
+static void g_scan_sub_index1_modifier_dispose(GScanSubIndex1Modifier *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_scan_sub_index1_modifier_finalize(GScanSubIndex1Modifier *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Fournit le nom d'appel d'un modificateur pour motif. */
+static char *g_scan_sub_index1_modifier_get_name(const GScanSubIndex1Modifier *);
+
+/* Transforme une séquence d'octets pour motif de recherche. */
+static bool g_scan_sub_index1_modifier_transform(const GScanSubIndex1Modifier *, const sized_binary_t *, size_t, sized_binary_t **, size_t *);
+
+/* Retrouve l'origine d'une correspondance à partir d'un indice. */
+static char *g_scan_sub_index1_modifier_get_path(const GScanSubIndex1Modifier *, size_t *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                         RECHERCHE D'UN MOTIF DE TEXTE BRUT                         */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une transormation en empreinte sub-index1. */
+G_DEFINE_TYPE(GScanSubIndex1Modifier, g_scan_sub_index1_modifier, G_TYPE_API_HASH_MODIFIER);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des transmissions en sub-index1.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_sub_index1_modifier_class_init(GScanSubIndex1ModifierClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GScanTokenModifierClass *modifier;      /* Version de classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_sub_index1_modifier_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_scan_sub_index1_modifier_finalize;
+
+    modifier = G_SCAN_TOKEN_MODIFIER_CLASS(klass);
+
+    modifier->get_name = (get_scan_modifier_name_fc)g_scan_sub_index1_modifier_get_name;
+
+    modifier->transform = (transform_scan_token_fc)g_scan_sub_index1_modifier_transform;
+    modifier->get_path = (get_modifier_path)g_scan_sub_index1_modifier_get_path;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = instance à initialiser.                           *
+*                                                                             *
+*  Description : Initialise une instance de transmission en sub-index1.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_sub_index1_modifier_init(GScanSubIndex1Modifier *modifier)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = instance d'objet GLib à traiter.                  *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_sub_index1_modifier_dispose(GScanSubIndex1Modifier *modifier)
+{
+    G_OBJECT_CLASS(g_scan_sub_index1_modifier_parent_class)->dispose(G_OBJECT(modifier));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = instance d'objet GLib à traiter.                  *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_sub_index1_modifier_finalize(GScanSubIndex1Modifier *modifier)
+{
+    G_OBJECT_CLASS(g_scan_sub_index1_modifier_parent_class)->finalize(G_OBJECT(modifier));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Construit un modificateur livrant des empreintes sub-index1. *
+*                                                                             *
+*  Retour      : Mécanisme mis en place.                                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanTokenModifier *g_scan_sub_index1_modifier_new(void)
+{
+    GScanTokenModifier *result;                    /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_SCAN_SUB_INDEX1_MODIFIER, NULL);
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = modificateur à consulter.                         *
+*                                                                             *
+*  Description : Fournit le nom d'appel d'un modificateur pour motif.         *
+*                                                                             *
+*  Retour      : Désignation humaine.                                         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *g_scan_sub_index1_modifier_get_name(const GScanSubIndex1Modifier *modifier)
+{
+    char *result;                           /* Désignation à retourner     */
+
+    result = strdup("sub-index1");
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = modificateur à solliciter.                        *
+*                src      = séquences d'octets à traiter.                     *
+*                scount   = quantité de ces séquences.                        *
+*                dest     = nouvelle(s) séquence(s) d'octets obtenue(s) [OUT] *
+*                dcount   = quantité de ces séquences.                        *
+*                                                                             *
+*  Description : Transforme une séquence d'octets pour motif de recherche.    *
+*                                                                             *
+*  Retour      : Bilan de l'opération : succès ou échec.                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_scan_sub_index1_modifier_transform(const GScanSubIndex1Modifier *modifier, const sized_binary_t *src, size_t scount, sized_binary_t **dest, size_t *dcount)
+{
+    bool result;                            /* Bilan d'opération à renvoyer*/
+    sized_binary_t *binary;                 /* Raccourci vers le stockage  */
+    size_t i;                               /* Boucle de parcours #1       */
+    const sized_binary_t *_src;             /* Source courante             */
+    size_t k;                               /* Boucle de parcours #2       */
+
+    result = true;
+
+    *dcount = scount;
+    *dest = calloc(*dcount, sizeof(sized_binary_t));
+
+    binary = &(*dest)[0];
+
+    for (i = 0; i < scount; i++, binary++)
+    {
+        _src = src + i;
+
+        binary->len = _src->len;
+        binary->data = malloc(binary->len);
+
+        for (k = 0; k < _src->len; k++)
+            binary->data[k] = _src->data[k] + k + 1;
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = modificateur à consulter.                         *
+*                index    = indice de la combinaison ciblée. [OUT]            *
+*                                                                             *
+*  Description : Retrouve l'origine d'une correspondance à partir d'un indice.*
+*                                                                             *
+*  Retour      : Version humainement lisible de la combinaison.               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *g_scan_sub_index1_modifier_get_path(const GScanSubIndex1Modifier *modifier, size_t *index)
+{
+    char *result;                           /* Combinaison à retourner     */
+
+    if (*index > 0)
+    {
+        result = NULL;
+        (*index)--;
+    }
+
+    else
+        result = strdup("sub-index1");
+
+    return result;
+
+}
diff --git a/plugins/apihashing/custom/sub-index1.h b/plugins/apihashing/custom/sub-index1.h
new file mode 100644
index 0000000..b2acc06
--- /dev/null
+++ b/plugins/apihashing/custom/sub-index1.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * sub-index1.h - prototypes pour la transormation en empreinte d'API sub-index1
+ *
+ * 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 _PLUGINS_APIHASHING_CUSTOM_SUB_INDEX1_H
+#define _PLUGINS_APIHASHING_CUSTOM_SUB_INDEX1_H
+
+
+#include <glib-object.h>
+
+
+#include "../apihash.h"
+
+
+
+#define G_TYPE_SCAN_SUB_INDEX1_MODIFIER            g_scan_sub_index1_modifier_get_type()
+#define G_SCAN_SUB_INDEX1_MODIFIER(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_SUB_INDEX1_MODIFIER, GScanSubIndex1Modifier))
+#define G_IS_SCAN_SUB_INDEX1_MODIFIER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_SUB_INDEX1_MODIFIER))
+#define G_SCAN_SUB_INDEX1_MODIFIER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_SUB_INDEX1_MODIFIER, GScanSubIndex1ModifierClass))
+#define G_IS_SCAN_SUB_INDEX1_MODIFIER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_SUB_INDEX1_MODIFIER))
+#define G_SCAN_SUB_INDEX1_MODIFIER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_SUB_INDEX1_MODIFIER, GScanSubIndex1ModifierClass))
+
+
+/* Transormation en empreinte d'API sub-index1 (instance) */
+typedef GApiHashModifier GScanSubIndex1Modifier;
+
+/* Transormation en empreinte d'API sub-index1 (classe) */
+typedef GApiHashModifierClass GScanSubIndex1ModifierClass;
+
+
+/* Indique le type défini pour une transormation en empreinte sub-index1. */
+GType g_scan_sub_index1_modifier_get_type(void);
+
+/* Construit un modificateur livrant des empreintes sub-index1. */
+GScanTokenModifier *g_scan_sub_index1_modifier_new(void);
+
+
+
+#endif  /* _PLUGINS_APIHASHING_CUSTOM_SUB_INDEX1_H */
diff --git a/plugins/apihashing/custom/sub42.c b/plugins/apihashing/custom/sub42.c
new file mode 100644
index 0000000..95bd49d
--- /dev/null
+++ b/plugins/apihashing/custom/sub42.c
@@ -0,0 +1,291 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * sub42.c - transormation en empreinte d'API sub42
+ *
+ * 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 "sub42.h"
+
+
+#include <malloc.h>
+
+
+#include <analysis/scan/patterns/modifier-int.h>
+
+
+
+
+/* ----------------------- RECHERCHE D'UN MOTIF DE TEXTE BRUT ----------------------- */
+
+
+/* Initialise la classe des transmissions en empreintes sub42. */
+static void g_scan_sub42_modifier_class_init(GScanSub42ModifierClass *);
+
+/* Initialise une instance de transmission en empreinte sub42. */
+static void g_scan_sub42_modifier_init(GScanSub42Modifier *);
+
+/* Supprime toutes les références externes. */
+static void g_scan_sub42_modifier_dispose(GScanSub42Modifier *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_scan_sub42_modifier_finalize(GScanSub42Modifier *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Fournit le nom d'appel d'un modificateur pour motif. */
+static char *g_scan_sub42_modifier_get_name(const GScanSub42Modifier *);
+
+/* Transforme une séquence d'octets pour motif de recherche. */
+static bool g_scan_sub42_modifier_transform(const GScanSub42Modifier *, const sized_binary_t *, size_t, sized_binary_t **, size_t *);
+
+/* Retrouve l'origine d'une correspondance à partir d'un indice. */
+static char *g_scan_sub42_modifier_get_path(const GScanSub42Modifier *, size_t *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                         RECHERCHE D'UN MOTIF DE TEXTE BRUT                         */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une transormation en empreinte sub42. */
+G_DEFINE_TYPE(GScanSub42Modifier, g_scan_sub42_modifier, G_TYPE_API_HASH_MODIFIER);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des transmissions en empreintes sub42.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_sub42_modifier_class_init(GScanSub42ModifierClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GScanTokenModifierClass *modifier;      /* Version de classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_sub42_modifier_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_scan_sub42_modifier_finalize;
+
+    modifier = G_SCAN_TOKEN_MODIFIER_CLASS(klass);
+
+    modifier->get_name = (get_scan_modifier_name_fc)g_scan_sub42_modifier_get_name;
+
+    modifier->transform = (transform_scan_token_fc)g_scan_sub42_modifier_transform;
+    modifier->get_path = (get_modifier_path)g_scan_sub42_modifier_get_path;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = instance à initialiser.                           *
+*                                                                             *
+*  Description : Initialise une instance de transmission en empreinte sub42.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_sub42_modifier_init(GScanSub42Modifier *modifier)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = instance d'objet GLib à traiter.                  *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_sub42_modifier_dispose(GScanSub42Modifier *modifier)
+{
+    G_OBJECT_CLASS(g_scan_sub42_modifier_parent_class)->dispose(G_OBJECT(modifier));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = instance d'objet GLib à traiter.                  *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_scan_sub42_modifier_finalize(GScanSub42Modifier *modifier)
+{
+    G_OBJECT_CLASS(g_scan_sub42_modifier_parent_class)->finalize(G_OBJECT(modifier));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Construit un modificateur livrant des empreintes sub42.      *
+*                                                                             *
+*  Retour      : Mécanisme mis en place.                                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GScanTokenModifier *g_scan_sub42_modifier_new(void)
+{
+    GScanTokenModifier *result;                    /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_SCAN_SUB42_MODIFIER, NULL);
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = modificateur à consulter.                         *
+*                                                                             *
+*  Description : Fournit le nom d'appel d'un modificateur pour motif.         *
+*                                                                             *
+*  Retour      : Désignation humaine.                                         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *g_scan_sub42_modifier_get_name(const GScanSub42Modifier *modifier)
+{
+    char *result;                           /* Désignation à retourner     */
+
+    result = strdup("sub42");
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = modificateur à solliciter.                        *
+*                src      = séquences d'octets à traiter.                     *
+*                scount   = quantité de ces séquences.                        *
+*                dest     = nouvelle(s) séquence(s) d'octets obtenue(s) [OUT] *
+*                dcount   = quantité de ces séquences.                        *
+*                                                                             *
+*  Description : Transforme une séquence d'octets pour motif de recherche.    *
+*                                                                             *
+*  Retour      : Bilan de l'opération : succès ou échec.                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_scan_sub42_modifier_transform(const GScanSub42Modifier *modifier, const sized_binary_t *src, size_t scount, sized_binary_t **dest, size_t *dcount)
+{
+    bool result;                            /* Bilan d'opération à renvoyer*/
+    sized_binary_t *binary;                 /* Raccourci vers le stockage  */
+    size_t i;                               /* Boucle de parcours #1       */
+    const sized_binary_t *_src;             /* Source courante             */
+    size_t k;                               /* Boucle de parcours #2       */
+
+    result = true;
+
+    *dcount = scount;
+    *dest = calloc(*dcount, sizeof(sized_binary_t));
+
+    binary = &(*dest)[0];
+
+    for (i = 0; i < scount; i++, binary++)
+    {
+        _src = src + i;
+
+        binary->len = _src->len;
+        binary->data = malloc(binary->len);
+
+        for (k = 0; k < _src->len; k++)
+            binary->data[k] = _src->data[k] + 0x42;
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : modifier = modificateur à consulter.                         *
+*                index    = indice de la combinaison ciblée. [OUT]            *
+*                                                                             *
+*  Description : Retrouve l'origine d'une correspondance à partir d'un indice.*
+*                                                                             *
+*  Retour      : Version humainement lisible de la combinaison.               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *g_scan_sub42_modifier_get_path(const GScanSub42Modifier *modifier, size_t *index)
+{
+    char *result;                           /* Combinaison à retourner     */
+
+    if (*index > 0)
+    {
+        result = NULL;
+        (*index)--;
+    }
+
+    else
+        result = strdup("sub42");
+
+    return result;
+
+}
diff --git a/plugins/apihashing/custom/sub42.h b/plugins/apihashing/custom/sub42.h
new file mode 100644
index 0000000..8a11741
--- /dev/null
+++ b/plugins/apihashing/custom/sub42.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * sub42.h - prototypes pour la transormation en empreinte d'API sub42
+ *
+ * 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 _PLUGINS_APIHASHING_CUSTOM_SUB42_H
+#define _PLUGINS_APIHASHING_CUSTOM_SUB42_H
+
+
+#include <glib-object.h>
+
+
+#include "../apihash.h"
+
+
+
+#define G_TYPE_SCAN_SUB42_MODIFIER            g_scan_sub42_modifier_get_type()
+#define G_SCAN_SUB42_MODIFIER(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_SUB42_MODIFIER, GScanSub42Modifier))
+#define G_IS_SCAN_SUB42_MODIFIER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_SUB42_MODIFIER))
+#define G_SCAN_SUB42_MODIFIER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_SUB42_MODIFIER, GScanSub42ModifierClass))
+#define G_IS_SCAN_SUB42_MODIFIER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_SUB42_MODIFIER))
+#define G_SCAN_SUB42_MODIFIER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_SUB42_MODIFIER, GScanSub42ModifierClass))
+
+
+/* Transormation en empreinte d'API sub42 (instance) */
+typedef GApiHashModifier GScanSub42Modifier;
+
+/* Transormation en empreinte d'API sub42 (classe) */
+typedef GApiHashModifierClass GScanSub42ModifierClass;
+
+
+/* Indique le type défini pour une transormation en empreinte sub42. */
+GType g_scan_sub42_modifier_get_type(void);
+
+/* Construit un modificateur livrant des empreintes sub42. */
+GScanTokenModifier *g_scan_sub42_modifier_new(void);
+
+
+
+#endif  /* _PLUGINS_APIHASHING_CUSTOM_SUB42_H */
diff --git a/plugins/apihashing/python/custom/Makefile.am b/plugins/apihashing/python/custom/Makefile.am
index 04b0f81..5fbb11f 100644
--- a/plugins/apihashing/python/custom/Makefile.am
+++ b/plugins/apihashing/python/custom/Makefile.am
@@ -2,8 +2,14 @@
 noinst_LTLIBRARIES = libapihashingpythoncustom.la
 
 libapihashingpythoncustom_la_SOURCES = 		\
+	add1505-shl5.h add1505-shl5.c			\
+	enigma-murmur.h enigma-murmur.c			\
+	imul21-add.h imul21-add.c				\
+	imul83-add.h imul83-add.c				\
 	module.h module.c						\
-	sll1-add-hash32.h sll1-add-hash32.c
+	sll1-add-hash32.h sll1-add-hash32.c		\
+	sub-index1.h sub-index1.c				\
+	sub42.h sub42.c
 
 libapihashingpythoncustom_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
 	-I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
diff --git a/plugins/apihashing/python/custom/add1505-shl5.c b/plugins/apihashing/python/custom/add1505-shl5.c
new file mode 100644
index 0000000..f70323c
--- /dev/null
+++ b/plugins/apihashing/python/custom/add1505-shl5.c
@@ -0,0 +1,211 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * add1505-shl5.c - équivalent Python du fichier "plugins/apihashing/custom/add1505-shl5.c"
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "add1505-shl5.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+
+
+#include "../apihash.h"
+#include "../../custom/add1505-shl5.h"
+
+
+
+CREATE_DYN_CONSTRUCTOR(scan_add1505_shl5_modifier, G_TYPE_SCAN_ADD1505_SHL5_MODIFIER);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_scan_add1505_shl5_modifier_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_add1505_shl5_modifier_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    int ret;                                /* Bilan de lecture des args.  */
+
+#define SCAN_ADD1505_SHL5_MODIFIER_DOC                              \
+    "The *Add1505Shl5Modifier* class transforms a byte pattern"     \
+    " using a add1505-shl5 hash.\n"                                 \
+    "\n"                                                            \
+    "Instances can be created using the following constructor:\n"   \
+    "\n"                                                            \
+    "    Add1505Shl5Modifier()"
+
+    /* 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_add1505_shl5_modifier_type(void)
+{
+    static PyMethodDef py_scan_add1505_shl5_modifier_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_scan_add1505_shl5_modifier_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_scan_add1505_shl5_modifier_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.scan.patterns.modifiers.Add1505Shl5Modifier",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = SCAN_ADD1505_SHL5_MODIFIER_DOC,
+
+        .tp_methods     = py_scan_add1505_shl5_modifier_methods,
+        .tp_getset      = py_scan_add1505_shl5_modifier_getseters,
+
+        .tp_init        = py_scan_add1505_shl5_modifier_init,
+        .tp_new         = py_scan_add1505_shl5_modifier_new,
+
+    };
+
+    return &py_scan_add1505_shl5_modifier_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Prend en charge l'objet '...Add1505Shl5Modifier'.            *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_python_scan_add1505_shl5_modifier_is_registered(void)
+{
+    PyTypeObject *type;                     /* Type Add1505Shl5Modifier    */
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_scan_add1505_shl5_modifier_type();
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.analysis.scan.patterns.modifiers");
+
+        dict = PyModule_GetDict(module);
+
+        if (!ensure_python_api_hash_modifier_is_registered())
+            return false;
+
+        if (!register_class_for_pygobject(dict, G_TYPE_SCAN_ADD1505_SHL5_MODIFIER, 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 empreinte add1505-shl5.                *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_scan_add1505_shl5_modifier(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_scan_add1505_shl5_modifier_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 add1505-shl5 modifier");
+            break;
+
+        case 1:
+            *((GScanAdd1505Shl5Modifier **)dst) = G_SCAN_ADD1505_SHL5_MODIFIER(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/apihashing/python/custom/add1505-shl5.h b/plugins/apihashing/python/custom/add1505-shl5.h
new file mode 100644
index 0000000..941d6ce
--- /dev/null
+++ b/plugins/apihashing/python/custom/add1505-shl5.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * add1505-shl5.h - équivalent Python du fichier "plugins/apihashing/custom/add1505-shl5.h"
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_APIHASHING_PYTHON_CUSTOM_ADD1505_SHL5_H
+#define _PLUGINS_APIHASHING_PYTHON_CUSTOM_ADD1505_SHL5_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_scan_add1505_shl5_modifier_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.scan.patterns.modifiers.Add1505Shl5Modifier'. */
+bool ensure_python_scan_add1505_shl5_modifier_is_registered(void);
+
+/* Tente de convertir en empreinte add1505-shl5. */
+int convert_to_scan_add1505_shl5_modifier(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_APIHASHING_PYTHON_CUSTOM_ADD1505_SHL5_H */
diff --git a/plugins/apihashing/python/custom/enigma-murmur.c b/plugins/apihashing/python/custom/enigma-murmur.c
new file mode 100644
index 0000000..f544f1a
--- /dev/null
+++ b/plugins/apihashing/python/custom/enigma-murmur.c
@@ -0,0 +1,211 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * enigma-murmur.c - équivalent Python du fichier "plugins/apihashing/custom/enigma-murmur.c"
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "enigma-murmur.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+
+
+#include "../apihash.h"
+#include "../../custom/enigma-murmur.h"
+
+
+
+CREATE_DYN_CONSTRUCTOR(scan_enigma_murmur_modifier, G_TYPE_SCAN_ENIGMA_MURMUR_MODIFIER);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_scan_enigma_murmur_modifier_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_enigma_murmur_modifier_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    int ret;                                /* Bilan de lecture des args.  */
+
+#define SCAN_ENIGMA_MURMUR_MODIFIER_DOC                             \
+    "The *EnigmaMurmurModifier* class transforms a byte pattern"    \
+    " using a enigma-murmur hash.\n"                                \
+    "\n"                                                            \
+    "Instances can be created using the following constructor:\n"   \
+    "\n"                                                            \
+    "    EnigmaMurmurModifier()"
+
+    /* 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_enigma_murmur_modifier_type(void)
+{
+    static PyMethodDef py_scan_enigma_murmur_modifier_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_scan_enigma_murmur_modifier_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_scan_enigma_murmur_modifier_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.scan.patterns.modifiers.EnigmaMurmurModifier",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = SCAN_ENIGMA_MURMUR_MODIFIER_DOC,
+
+        .tp_methods     = py_scan_enigma_murmur_modifier_methods,
+        .tp_getset      = py_scan_enigma_murmur_modifier_getseters,
+
+        .tp_init        = py_scan_enigma_murmur_modifier_init,
+        .tp_new         = py_scan_enigma_murmur_modifier_new,
+
+    };
+
+    return &py_scan_enigma_murmur_modifier_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Prend en charge l'objet '...EnigmaMurmurModifier'.           *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_python_scan_enigma_murmur_modifier_is_registered(void)
+{
+    PyTypeObject *type;                     /* Type EnigmaMurmurModifier   */
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_scan_enigma_murmur_modifier_type();
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.analysis.scan.patterns.modifiers");
+
+        dict = PyModule_GetDict(module);
+
+        if (!ensure_python_api_hash_modifier_is_registered())
+            return false;
+
+        if (!register_class_for_pygobject(dict, G_TYPE_SCAN_ENIGMA_MURMUR_MODIFIER, 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 empreinte enigma-murmur.               *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_scan_enigma_murmur_modifier(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_scan_enigma_murmur_modifier_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 enigma-murmur modifier");
+            break;
+
+        case 1:
+            *((GScanEnigmaMurmurModifier **)dst) = G_SCAN_ENIGMA_MURMUR_MODIFIER(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/apihashing/python/custom/enigma-murmur.h b/plugins/apihashing/python/custom/enigma-murmur.h
new file mode 100644
index 0000000..8435dae
--- /dev/null
+++ b/plugins/apihashing/python/custom/enigma-murmur.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * enigma-murmur.h - équivalent Python du fichier "plugins/apihashing/custom/enigma-murmur.h"
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_APIHASHING_PYTHON_CUSTOM_ENIGMA_MURMUR_H
+#define _PLUGINS_APIHASHING_PYTHON_CUSTOM_ENIGMA_MURMUR_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_scan_enigma_murmur_modifier_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.scan.patterns.modifiers.EnigmaMurmurModifier'. */
+bool ensure_python_scan_enigma_murmur_modifier_is_registered(void);
+
+/* Tente de convertir en empreinte enigma-murmur. */
+int convert_to_scan_enigma_murmur_modifier(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_APIHASHING_PYTHON_CUSTOM_ENIGMA_MURMUR_H */
diff --git a/plugins/apihashing/python/custom/imul21-add.c b/plugins/apihashing/python/custom/imul21-add.c
new file mode 100644
index 0000000..aadc6cc
--- /dev/null
+++ b/plugins/apihashing/python/custom/imul21-add.c
@@ -0,0 +1,211 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * imul21-add.c - équivalent Python du fichier "plugins/apihashing/custom/imul21-add.c"
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "imul21-add.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+
+
+#include "../apihash.h"
+#include "../../custom/imul21-add.h"
+
+
+
+CREATE_DYN_CONSTRUCTOR(scan_imul21_add_modifier, G_TYPE_SCAN_IMUL21_ADD_MODIFIER);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_scan_imul21_add_modifier_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_imul21_add_modifier_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    int ret;                                /* Bilan de lecture des args.  */
+
+#define SCAN_IMUL21_ADD_MODIFIER_DOC                                \
+    "The *Sll1AddHash32Modifier* class transforms a byte pattern"   \
+    " using a variation of the sll1 algorithm.\n"                   \
+    "\n"                                                            \
+    "Instances can be created using the following constructor:\n"   \
+    "\n"                                                            \
+    "    Sll1AddHash32Modifier()"
+
+    /* 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_imul21_add_modifier_type(void)
+{
+    static PyMethodDef py_scan_imul21_add_modifier_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_scan_imul21_add_modifier_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_scan_imul21_add_modifier_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.scan.patterns.modifiers.Imul21AddModifier",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = SCAN_IMUL21_ADD_MODIFIER_DOC,
+
+        .tp_methods     = py_scan_imul21_add_modifier_methods,
+        .tp_getset      = py_scan_imul21_add_modifier_getseters,
+
+        .tp_init        = py_scan_imul21_add_modifier_init,
+        .tp_new         = py_scan_imul21_add_modifier_new,
+
+    };
+
+    return &py_scan_imul21_add_modifier_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Prend en charge l'objet '...Imul21AddModifier'.              *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_python_scan_imul21_add_modifier_is_registered(void)
+{
+    PyTypeObject *type;                     /* Type Sll1AddHash32Modifier  */
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_scan_imul21_add_modifier_type();
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.analysis.scan.patterns.modifiers");
+
+        dict = PyModule_GetDict(module);
+
+        if (!ensure_python_api_hash_modifier_is_registered())
+            return false;
+
+        if (!register_class_for_pygobject(dict, G_TYPE_SCAN_IMUL21_ADD_MODIFIER, 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 empreinte imul21-add.             *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_scan_imul21_add_modifier(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_scan_imul21_add_modifier_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 imul21-add modifier");
+            break;
+
+        case 1:
+            *((GScanImul21AddModifier **)dst) = G_SCAN_IMUL21_ADD_MODIFIER(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/apihashing/python/custom/imul21-add.h b/plugins/apihashing/python/custom/imul21-add.h
new file mode 100644
index 0000000..3fcc053
--- /dev/null
+++ b/plugins/apihashing/python/custom/imul21-add.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * imul21-add.h - équivalent Python du fichier "plugins/apihashing/custom/imul21-add.h"
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_APIHASHING_PYTHON_CUSTOM_IMUL21_ADD_H
+#define _PLUGINS_APIHASHING_PYTHON_CUSTOM_IMUL21_ADD_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_scan_imul21_add_modifier_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.scan.patterns.modifiers.Imul21AddModifier'. */
+bool ensure_python_scan_imul21_add_modifier_is_registered(void);
+
+/* Tente de convertir en empreinte imul21-add. */
+int convert_to_scan_imul21_add_modifier(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_APIHASHING_PYTHON_CUSTOM_IMUL21_ADD_H */
diff --git a/plugins/apihashing/python/custom/imul83-add.c b/plugins/apihashing/python/custom/imul83-add.c
new file mode 100644
index 0000000..5e2d929
--- /dev/null
+++ b/plugins/apihashing/python/custom/imul83-add.c
@@ -0,0 +1,211 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * imul83-add.c - équivalent Python du fichier "plugins/apihashing/custom/imul83-add.c"
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "imul83-add.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+
+
+#include "../apihash.h"
+#include "../../custom/imul83-add.h"
+
+
+
+CREATE_DYN_CONSTRUCTOR(scan_imul83_add_modifier, G_TYPE_SCAN_IMUL83_ADD_MODIFIER);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_scan_imul83_add_modifier_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_imul83_add_modifier_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    int ret;                                /* Bilan de lecture des args.  */
+
+#define SCAN_IMUL83_ADD_MODIFIER_DOC                                \
+    "The *Sll1AddHash32Modifier* class transforms a byte pattern"   \
+    " using a variation of the sll1 algorithm.\n"                   \
+    "\n"                                                            \
+    "Instances can be created using the following constructor:\n"   \
+    "\n"                                                            \
+    "    Sll1AddHash32Modifier()"
+
+    /* 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_imul83_add_modifier_type(void)
+{
+    static PyMethodDef py_scan_imul83_add_modifier_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_scan_imul83_add_modifier_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_scan_imul83_add_modifier_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.scan.patterns.modifiers.Imul83AddModifier",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = SCAN_IMUL83_ADD_MODIFIER_DOC,
+
+        .tp_methods     = py_scan_imul83_add_modifier_methods,
+        .tp_getset      = py_scan_imul83_add_modifier_getseters,
+
+        .tp_init        = py_scan_imul83_add_modifier_init,
+        .tp_new         = py_scan_imul83_add_modifier_new,
+
+    };
+
+    return &py_scan_imul83_add_modifier_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Prend en charge l'objet '...Imul83AddModifier'.              *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_python_scan_imul83_add_modifier_is_registered(void)
+{
+    PyTypeObject *type;                     /* Type Sll1AddHash32Modifier  */
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_scan_imul83_add_modifier_type();
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.analysis.scan.patterns.modifiers");
+
+        dict = PyModule_GetDict(module);
+
+        if (!ensure_python_api_hash_modifier_is_registered())
+            return false;
+
+        if (!register_class_for_pygobject(dict, G_TYPE_SCAN_IMUL83_ADD_MODIFIER, 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 empreinte imul83-add.             *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_scan_imul83_add_modifier(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_scan_imul83_add_modifier_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 imul83-add modifier");
+            break;
+
+        case 1:
+            *((GScanImul83AddModifier **)dst) = G_SCAN_IMUL83_ADD_MODIFIER(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/apihashing/python/custom/imul83-add.h b/plugins/apihashing/python/custom/imul83-add.h
new file mode 100644
index 0000000..fd05136
--- /dev/null
+++ b/plugins/apihashing/python/custom/imul83-add.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * imul83-add.h - équivalent Python du fichier "plugins/apihashing/custom/imul83-add.h"
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_APIHASHING_PYTHON_CUSTOM_IMUL83_ADD_H
+#define _PLUGINS_APIHASHING_PYTHON_CUSTOM_IMUL83_ADD_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_scan_imul83_add_modifier_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.scan.patterns.modifiers.Imul83AddModifier'. */
+bool ensure_python_scan_imul83_add_modifier_is_registered(void);
+
+/* Tente de convertir en empreinte imul83-add. */
+int convert_to_scan_imul83_add_modifier(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_APIHASHING_PYTHON_CUSTOM_IMUL83_ADD_H */
diff --git a/plugins/apihashing/python/custom/module.c b/plugins/apihashing/python/custom/module.c
index cc0afff..07107dd 100644
--- a/plugins/apihashing/python/custom/module.c
+++ b/plugins/apihashing/python/custom/module.c
@@ -33,7 +33,13 @@
 #include <plugins/pychrysalide/helpers.h>
 
 
+#include "add1505-shl5.h"
+#include "enigma-murmur.h"
+#include "imul21-add.h"
+#include "imul83-add.h"
 #include "sll1-add-hash32.h"
+#include "sub-index1.h"
+#include "sub42.h"
 
 
 
@@ -55,7 +61,13 @@ bool register_apihashing_custom_modifiers(void)
 
     result = true;
 
+    if (result) result = ensure_python_scan_add1505_shl5_modifier_is_registered();
+    if (result) result = ensure_python_scan_enigma_murmur_modifier_is_registered();
+    if (result) result = ensure_python_scan_imul21_add_modifier_is_registered();
+    if (result) result = ensure_python_scan_imul83_add_modifier_is_registered();
     if (result) result = ensure_python_scan_sll1_add_hash32_modifier_is_registered();
+    if (result) result = ensure_python_scan_sub42_modifier_is_registered();
+    if (result) result = ensure_python_scan_sub_index1_modifier_is_registered();
 
     assert(result);
 
diff --git a/plugins/apihashing/python/custom/sub-index1.c b/plugins/apihashing/python/custom/sub-index1.c
new file mode 100644
index 0000000..e5c1487
--- /dev/null
+++ b/plugins/apihashing/python/custom/sub-index1.c
@@ -0,0 +1,213 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * sub-index1.c - équivalent Python du fichier "plugins/apihashing/custom/sub-index1.c"
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "sub-index1.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+
+
+#include "../apihash.h"
+#include "../../custom/sub-index1.h"
+
+
+
+CREATE_DYN_CONSTRUCTOR(scan_sub_index1_modifier, G_TYPE_SCAN_SUB_INDEX1_MODIFIER);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_scan_sub_index1_modifier_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_sub_index1_modifier_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    int ret;                                /* Bilan de lecture des args.  */
+
+#define SCAN_SUB_INDEX1_MODIFIER_DOC                                \
+    "The *SubIndex1Modifier* class produces the encrypted version"  \
+    " of a byte pattern where the index of a byte is added to its"  \
+    " value.\n"                                                     \
+    "\n"                                                            \
+    "Instances can be created using the following constructor:\n"   \
+    "\n"                                                            \
+    "    Sub-Index1Modifier()"
+
+    /* 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_sub_index1_modifier_type(void)
+{
+    static PyMethodDef py_scan_sub_index1_modifier_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_scan_sub_index1_modifier_getseters[] = {
+
+        { NULL }
+    };
+
+    static PyTypeObject py_scan_sub_index1_modifier_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.scan.patterns.modifiers.SubIndex1Modifier",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = SCAN_SUB_INDEX1_MODIFIER_DOC,
+
+        .tp_methods     = py_scan_sub_index1_modifier_methods,
+        .tp_getset      = py_scan_sub_index1_modifier_getseters,
+
+        .tp_init        = py_scan_sub_index1_modifier_init,
+        .tp_new         = py_scan_sub_index1_modifier_new,
+
+    };
+
+    return &py_scan_sub_index1_modifier_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide....SubIndex1Modifier'. *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_python_scan_sub_index1_modifier_is_registered(void)
+{
+    PyTypeObject *type;                     /* Type Python Sub-Index1Modifier */
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_scan_sub_index1_modifier_type();
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.analysis.scan.patterns.modifiers");
+
+        dict = PyModule_GetDict(module);
+
+        if (!ensure_python_api_hash_modifier_is_registered())
+            return false;
+
+        if (!register_class_for_pygobject(dict, G_TYPE_SCAN_SUB_INDEX1_MODIFIER, 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 transformation en empreinte sub-index1.*
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_scan_sub_index1_modifier(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_scan_sub_index1_modifier_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 sub-index1 modifier");
+            break;
+
+        case 1:
+            *((GScanSubIndex1Modifier **)dst) = G_SCAN_SUB_INDEX1_MODIFIER(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/apihashing/python/custom/sub-index1.h b/plugins/apihashing/python/custom/sub-index1.h
new file mode 100644
index 0000000..65186f3
--- /dev/null
+++ b/plugins/apihashing/python/custom/sub-index1.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * sub-index1.h - équivalent Python du fichier "plugins/apihashing/custom/sub-index1.h"
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_APIHASHING_PYTHON_CUSTOM_SUB_INDEX1_H
+#define _PLUGINS_APIHASHING_PYTHON_CUSTOM_SUB_INDEX1_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_scan_sub_index1_modifier_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.scan.patterns.modifiers.SubIndex1Modifier'. */
+bool ensure_python_scan_sub_index1_modifier_is_registered(void);
+
+/* Tente de convertir en transformation en empreinte sub-index1. */
+int convert_to_scan_sub_index1_modifier(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_APIHASHING_PYTHON_CUSTOM_SUB_INDEX1_H */
diff --git a/plugins/apihashing/python/custom/sub42.c b/plugins/apihashing/python/custom/sub42.c
new file mode 100644
index 0000000..238496d
--- /dev/null
+++ b/plugins/apihashing/python/custom/sub42.c
@@ -0,0 +1,212 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * sub42.c - équivalent Python du fichier "plugins/apihashing/custom/sub42.c"
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "sub42.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+
+
+#include "../apihash.h"
+#include "../../custom/sub42.h"
+
+
+
+CREATE_DYN_CONSTRUCTOR(scan_sub42_modifier, G_TYPE_SCAN_SUB42_MODIFIER);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_scan_sub42_modifier_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_sub42_modifier_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    int ret;                                /* Bilan de lecture des args.  */
+
+#define SCAN_SUB42_MODIFIER_DOC                                     \
+    "The *Sub42Modifier* class produces the encrypted version of a" \
+    " byte pattern where 0x42 is added to each byte.\n"             \
+    "\n"                                                            \
+    "Instances can be created using the following constructor:\n"   \
+    "\n"                                                            \
+    "    Sub42Modifier()"
+
+    /* 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_sub42_modifier_type(void)
+{
+    static PyMethodDef py_scan_sub42_modifier_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_scan_sub42_modifier_getseters[] = {
+
+        { NULL }
+    };
+
+    static PyTypeObject py_scan_sub42_modifier_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.scan.patterns.modifiers.Sub42Modifier",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = SCAN_SUB42_MODIFIER_DOC,
+
+        .tp_methods     = py_scan_sub42_modifier_methods,
+        .tp_getset      = py_scan_sub42_modifier_getseters,
+
+        .tp_init        = py_scan_sub42_modifier_init,
+        .tp_new         = py_scan_sub42_modifier_new,
+
+    };
+
+    return &py_scan_sub42_modifier_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide....Sub42Modifier'.     *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_python_scan_sub42_modifier_is_registered(void)
+{
+    PyTypeObject *type;                     /* Type Python Sub42Modifier */
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_scan_sub42_modifier_type();
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.analysis.scan.patterns.modifiers");
+
+        dict = PyModule_GetDict(module);
+
+        if (!ensure_python_api_hash_modifier_is_registered())
+            return false;
+
+        if (!register_class_for_pygobject(dict, G_TYPE_SCAN_SUB42_MODIFIER, 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 transformation en empreinte sub42.     *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_scan_sub42_modifier(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_scan_sub42_modifier_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 sub42 modifier");
+            break;
+
+        case 1:
+            *((GScanSub42Modifier **)dst) = G_SCAN_SUB42_MODIFIER(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/apihashing/python/custom/sub42.h b/plugins/apihashing/python/custom/sub42.h
new file mode 100644
index 0000000..ce3660a
--- /dev/null
+++ b/plugins/apihashing/python/custom/sub42.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * sub42.h - équivalent Python du fichier "plugins/apihashing/custom/sub42.h"
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_APIHASHING_PYTHON_CUSTOM_SUB42_H
+#define _PLUGINS_APIHASHING_PYTHON_CUSTOM_SUB42_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_scan_sub42_modifier_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.scan.patterns.modifiers.Sub42Modifier'. */
+bool ensure_python_scan_sub42_modifier_is_registered(void);
+
+/* Tente de convertir en transformation en empreinte sub42. */
+int convert_to_scan_sub42_modifier(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_APIHASHING_PYTHON_CUSTOM_SUB42_H */
diff --git a/tests/analysis/scan/pyapi.py b/tests/analysis/scan/pyapi.py
index cfd12b3..7a697b3 100644
--- a/tests/analysis/scan/pyapi.py
+++ b/tests/analysis/scan/pyapi.py
@@ -139,7 +139,7 @@ class TestRostPythonAPI(ChrysalideTestCase):
             return struct.unpack('<I', t)[0]
 
 
-        # Example :
+        # Example:
         #  - PlugX (2020) - https://vms.drweb.fr/virus/?i=21512304
 
         mod = find_token_modifiers_for_name('crc32')
@@ -151,7 +151,7 @@ class TestRostPythonAPI(ChrysalideTestCase):
         self.assertEqual(b2i(transformed[0]), 0x3690e66)
 
 
-        # Example :
+        # Example:
         #  - GuLoader (2020) - https://www.crowdstrike.com/blog/guloader-malware-analysis/
 
         mod = find_token_modifiers_for_name('djb2')
@@ -163,7 +163,64 @@ class TestRostPythonAPI(ChrysalideTestCase):
         self.assertEqual(b2i(transformed[0]), 0xcf31bb1f)
 
 
-        # Example :
+    def testCustomAPIHashing(self):
+        """Reproduce custom API Hashing results."""
+
+        def b2i(t):
+            return struct.unpack('<I', t)[0]
+
+
+        # Example:
+        # Underminer Exploit Kit (2019) - https://jsac.jpcert.or.jp/archive/2019/pdf/JSAC2019_1_koike-nakajima_jp.pdf
+
+        mod = find_token_modifiers_for_name('add1505-shl5')
+        self.assertIsNotNone(mod)
+
+        source = b'LoadLibraryA'
+        transformed = mod.transform(source)
+
+        self.assertEqual(b2i(transformed[0]), 0x5fbff0fb)
+
+
+        # Example:
+        # Enigma Stealer (2023) https://www.trendmicro.com/es_mx/research/23/b/enigma-stealer-targets-cryptocurrency-industry-with-fake-jobs.html
+
+        mod = find_token_modifiers_for_name('enigma-murmur')
+        self.assertIsNotNone(mod)
+
+        source = b'CreateMutexW'
+        transformed = mod.transform(source)
+
+        self.assertEqual(b2i(transformed[0]), 0xfd43765a)
+
+
+        # Examples:
+        #  - ShadowHammer (2019) - https://blog.f-secure.com/analysis-shadowhammer-asus-attack-first-stage-payload/
+        #  - ShadowHammer (2019) - https://securelist.com/operation-shadowhammer-a-high-profile-supply-chain-attack/90380/
+
+        mod = find_token_modifiers_for_name('imul21-add')
+        self.assertIsNotNone(mod)
+
+        source = b'VirtualAlloc'
+        transformed = mod.transform(source)
+
+        self.assertEqual(b2i(transformed[0]), 0xdf894b12)
+
+
+        # Examples:
+        #  - Bottle Exploit Kit (2019) - https://nao-sec.org/2019/12/say-hello-to-bottle-exploit-kit.html
+        #  - ShadowHammer (2019) - https://securelist.com/operation-shadowhammer-a-high-profile-supply-chain-attack/90380/
+
+        mod = find_token_modifiers_for_name('imul83-add')
+        self.assertIsNotNone(mod)
+
+        source = b'GetProcAddress'
+        transformed = mod.transform(source)
+
+        self.assertEqual(b2i(transformed[0]), 0x9ab9b854)
+
+
+        # Examples:
         #  - ?? (2021) - https://www.threatspike.com/blogs/reflective-dll-injection
         #  - Mustang Panda (2022) - https://blog.talosintelligence.com/mustang-panda-targets-europe/
 
@@ -181,7 +238,7 @@ class TestRostPythonAPI(ChrysalideTestCase):
         self.assertEqual(b2i(transformed[0]), 0x91afca54)
 
 
-        # Example
+        # Example:
         #  - Energetic Bear (2019) - https://insights.sei.cmu.edu/blog/api-hashing-tool-imagine-that/
 
         mod = find_token_modifiers_for_name('sll1-add-hash32')
@@ -193,6 +250,30 @@ class TestRostPythonAPI(ChrysalideTestCase):
         self.assertEqual(b2i(transformed[0]), 0x000d5786)
 
 
+        # Example:
+        #  - SideWinder/WarHawk (2022) - https://www.zscaler.com/blogs/security-research/warhawk-new-backdoor-arsenal-sidewinder-apt-group
+
+        mod = find_token_modifiers_for_name('sub42')
+        self.assertIsNotNone(mod)
+
+        source = b'LoadLibraryA'
+        transformed = mod.transform(source)
+
+        self.assertEqual(transformed[0], b'\x8e\xb1\xa3\xa6\x8e\xab\xa4\xb4\xa3\xb4\xbb\x83')
+
+
+        # Example:
+        #  - TrickBot (2021) - https://medium.com/walmartglobaltech/trickbot-crews-new-cobaltstrike-loader-32c72b78e81c
+
+        mod = find_token_modifiers_for_name('sub-index1')
+        self.assertIsNotNone(mod)
+
+        source = b'raw.githubusercontent.com'
+        transformed = mod.transform(source)
+
+        self.assertEqual(transformed[0], b'\x73\x63\x7a\x32\x6c\x6f\x7b\x70\x7e\x6c\x80\x7f\x72\x80\x72\x7f\x7f\x86\x78\x82\x89\x44\x7a\x87\x86')
+
+
     def testBytePatternModifiersAPI(self):
         """Validate the API for pattern modifiers."""
 
-- 
cgit v0.11.2-87-g4458