summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/Makefile.am2
-rw-r--r--plugins/apihashing/Makefile.am65
-rw-r--r--plugins/apihashing/apihash.c134
-rw-r--r--plugins/apihashing/apihash.h55
-rw-r--r--plugins/apihashing/classics/Makefile.am14
-rw-r--r--plugins/apihashing/classics/crc32.c332
-rw-r--r--plugins/apihashing/classics/crc32.h58
-rw-r--r--plugins/apihashing/classics/djb2.c323
-rw-r--r--plugins/apihashing/classics/djb2.h58
-rw-r--r--plugins/apihashing/classics/ror13.c323
-rw-r--r--plugins/apihashing/classics/ror13.h58
-rw-r--r--plugins/apihashing/core.c110
-rw-r--r--plugins/apihashing/core.h38
-rw-r--r--plugins/apihashing/custom/Makefile.am18
-rw-r--r--plugins/apihashing/custom/add1505-shl5.c325
-rw-r--r--plugins/apihashing/custom/add1505-shl5.h58
-rw-r--r--plugins/apihashing/custom/enigma-murmur.c377
-rw-r--r--plugins/apihashing/custom/enigma-murmur.h58
-rw-r--r--plugins/apihashing/custom/imul21-add.c326
-rw-r--r--plugins/apihashing/custom/imul21-add.h58
-rw-r--r--plugins/apihashing/custom/imul83-add.c326
-rw-r--r--plugins/apihashing/custom/imul83-add.h58
-rw-r--r--plugins/apihashing/custom/sll1-add-hash32.c326
-rw-r--r--plugins/apihashing/custom/sll1-add-hash32.h58
-rw-r--r--plugins/apihashing/custom/sub-index1.c291
-rw-r--r--plugins/apihashing/custom/sub-index1.h58
-rw-r--r--plugins/apihashing/custom/sub42.c291
-rw-r--r--plugins/apihashing/custom/sub42.h58
-rw-r--r--plugins/apihashing/python/Makefile.am20
-rw-r--r--plugins/apihashing/python/apihash.c212
-rw-r--r--plugins/apihashing/python/apihash.h45
-rw-r--r--plugins/apihashing/python/classics/Makefile.am16
-rw-r--r--plugins/apihashing/python/classics/crc32.c211
-rw-r--r--plugins/apihashing/python/classics/crc32.h45
-rw-r--r--plugins/apihashing/python/classics/djb2.c211
-rw-r--r--plugins/apihashing/python/classics/djb2.h45
-rw-r--r--plugins/apihashing/python/classics/module.c68
-rw-r--r--plugins/apihashing/python/classics/module.h38
-rw-r--r--plugins/apihashing/python/classics/ror13.c211
-rw-r--r--plugins/apihashing/python/classics/ror13.h45
-rw-r--r--plugins/apihashing/python/custom/Makefile.am20
-rw-r--r--plugins/apihashing/python/custom/add1505-shl5.c211
-rw-r--r--plugins/apihashing/python/custom/add1505-shl5.h45
-rw-r--r--plugins/apihashing/python/custom/enigma-murmur.c211
-rw-r--r--plugins/apihashing/python/custom/enigma-murmur.h45
-rw-r--r--plugins/apihashing/python/custom/imul21-add.c211
-rw-r--r--plugins/apihashing/python/custom/imul21-add.h45
-rw-r--r--plugins/apihashing/python/custom/imul83-add.c211
-rw-r--r--plugins/apihashing/python/custom/imul83-add.h45
-rw-r--r--plugins/apihashing/python/custom/module.c76
-rw-r--r--plugins/apihashing/python/custom/module.h38
-rw-r--r--plugins/apihashing/python/custom/sll1-add-hash32.c211
-rw-r--r--plugins/apihashing/python/custom/sll1-add-hash32.h45
-rw-r--r--plugins/apihashing/python/custom/sub-index1.c213
-rw-r--r--plugins/apihashing/python/custom/sub-index1.h45
-rw-r--r--plugins/apihashing/python/custom/sub42.c212
-rw-r--r--plugins/apihashing/python/custom/sub42.h45
-rw-r--r--plugins/apihashing/python/module.c87
-rw-r--r--plugins/apihashing/python/module.h38
-rw-r--r--plugins/dalvik/context.c4
-rw-r--r--plugins/dalvik/context.h2
-rw-r--r--plugins/encodings/Makefile.am64
-rw-r--r--plugins/encodings/base64.c139
-rw-r--r--plugins/encodings/base64.h43
-rw-r--r--plugins/encodings/core.c89
-rw-r--r--plugins/encodings/core.h38
-rw-r--r--plugins/encodings/python/Makefile.am21
-rw-r--r--plugins/encodings/python/base64.c139
-rw-r--r--plugins/encodings/python/base64.h39
-rw-r--r--plugins/encodings/python/module.c87
-rw-r--r--plugins/encodings/python/module.h38
-rw-r--r--plugins/encodings/python/rost/Makefile.am15
-rw-r--r--plugins/encodings/python/rost/base64.c211
-rw-r--r--plugins/encodings/python/rost/base64.h45
-rw-r--r--plugins/encodings/python/rost/module.c64
-rw-r--r--plugins/encodings/python/rost/module.h38
-rw-r--r--plugins/encodings/rost/Makefile.am12
-rw-r--r--plugins/encodings/rost/base64.c555
-rw-r--r--plugins/encodings/rost/base64.h58
-rw-r--r--plugins/kaitai/Makefile.am5
-rw-r--r--plugins/kaitai/core.c4
-rw-r--r--plugins/kaitai/grammar.y73
-rw-r--r--plugins/kaitai/import.c300
-rw-r--r--plugins/kaitai/import.h41
-rw-r--r--plugins/kaitai/parser-int.h2
-rw-r--r--plugins/kaitai/parser.c15
-rw-r--r--plugins/kaitai/parser.h2
-rw-r--r--plugins/kaitai/parsers/attribute-int.h3
-rw-r--r--plugins/kaitai/parsers/attribute.c197
-rw-r--r--plugins/kaitai/parsers/attribute.h20
-rw-r--r--plugins/kaitai/parsers/instance.c149
-rw-r--r--plugins/kaitai/parsers/instance.h3
-rw-r--r--plugins/kaitai/parsers/meta-int.h3
-rw-r--r--plugins/kaitai/parsers/meta.c81
-rw-r--r--plugins/kaitai/parsers/meta.h3
-rw-r--r--plugins/kaitai/parsers/struct-int.h2
-rw-r--r--plugins/kaitai/parsers/struct.c114
-rw-r--r--plugins/kaitai/parsers/switch.c112
-rw-r--r--plugins/kaitai/parsers/type-int.h3
-rw-r--r--plugins/kaitai/parsers/type.c58
-rw-r--r--plugins/kaitai/parsers/type.h3
-rw-r--r--plugins/kaitai/python/Makefile.am5
-rw-r--r--plugins/kaitai/python/module.c3
-rw-r--r--plugins/kaitai/python/parsers/attribute.c11
-rw-r--r--plugins/kaitai/python/parsers/meta.c52
-rw-r--r--plugins/kaitai/python/records/Makefile.am5
-rw-r--r--plugins/kaitai/python/records/bits.c318
-rw-r--r--plugins/kaitai/python/records/bits.h45
-rw-r--r--plugins/kaitai/python/records/delayed.c (renamed from plugins/kaitai/python/records/value.c)94
-rw-r--r--plugins/kaitai/python/records/delayed.h (renamed from plugins/kaitai/python/records/value.h)16
-rw-r--r--plugins/kaitai/python/records/module.c6
-rw-r--r--plugins/kaitai/python/rost/Makefile.am14
-rw-r--r--plugins/kaitai/python/rost/module.c115
-rw-r--r--plugins/kaitai/python/rost/module.h41
-rw-r--r--plugins/kaitai/python/rost/trigger.c236
-rw-r--r--plugins/kaitai/python/rost/trigger.h45
-rw-r--r--plugins/kaitai/record.c18
-rw-r--r--plugins/kaitai/records/Makefile.am8
-rw-r--r--plugins/kaitai/records/bits-int.h59
-rw-r--r--plugins/kaitai/records/bits.c283
-rw-r--r--plugins/kaitai/records/bits.h62
-rw-r--r--plugins/kaitai/records/delayed-int.h (renamed from plugins/kaitai/records/value-int.h)19
-rw-r--r--plugins/kaitai/records/delayed.c (renamed from plugins/kaitai/records/value.c)128
-rw-r--r--plugins/kaitai/records/delayed.h (renamed from plugins/kaitai/records/value.h)32
-rw-r--r--plugins/kaitai/rost/Makefile.am18
-rw-r--r--plugins/kaitai/rost/browser-int.h58
-rw-r--r--plugins/kaitai/rost/browser.c478
-rw-r--r--plugins/kaitai/rost/browser.h58
-rw-r--r--plugins/kaitai/rost/core.c66
-rw-r--r--plugins/kaitai/rost/core.h37
-rw-r--r--plugins/kaitai/rost/space-int.h55
-rw-r--r--plugins/kaitai/rost/space.c254
-rw-r--r--plugins/kaitai/rost/space.h59
-rw-r--r--plugins/kaitai/rost/trigger-int.h59
-rw-r--r--plugins/kaitai/rost/trigger.c320
-rw-r--r--plugins/kaitai/rost/trigger.h61
-rw-r--r--plugins/kaitai/scope.c2
-rw-r--r--plugins/kaitai/tokens.l2
-rw-r--r--plugins/pychrysalide/analysis/content.c87
-rw-r--r--plugins/pychrysalide/analysis/contents/encapsulated.c50
-rw-r--r--plugins/pychrysalide/analysis/contents/file.c50
-rw-r--r--plugins/pychrysalide/analysis/contents/memory.c50
-rw-r--r--plugins/pychrysalide/analysis/contents/restricted.c53
-rw-r--r--plugins/pychrysalide/analysis/scan/Makefile.am5
-rw-r--r--plugins/pychrysalide/analysis/scan/constants.c2
-rw-r--r--plugins/pychrysalide/analysis/scan/context.c89
-rw-r--r--plugins/pychrysalide/analysis/scan/core.c21
-rw-r--r--plugins/pychrysalide/analysis/scan/expr.c2
-rw-r--r--plugins/pychrysalide/analysis/scan/expr.h2
-rw-r--r--plugins/pychrysalide/analysis/scan/exprs/Makefile.am15
-rw-r--r--plugins/pychrysalide/analysis/scan/exprs/constants.c128
-rw-r--r--plugins/pychrysalide/analysis/scan/exprs/constants.h42
-rw-r--r--plugins/pychrysalide/analysis/scan/exprs/literal.c281
-rw-r--r--plugins/pychrysalide/analysis/scan/exprs/literal.h45
-rw-r--r--plugins/pychrysalide/analysis/scan/exprs/module.c103
-rw-r--r--plugins/pychrysalide/analysis/scan/exprs/module.h42
-rw-r--r--plugins/pychrysalide/analysis/scan/item.c487
-rw-r--r--plugins/pychrysalide/analysis/scan/item.h8
-rw-r--r--plugins/pychrysalide/analysis/scan/module.c5
-rw-r--r--plugins/pychrysalide/analysis/scan/patterns/modifier.c116
-rw-r--r--plugins/pychrysalide/analysis/scan/patterns/modifiers/Makefile.am3
-rw-r--r--plugins/pychrysalide/analysis/scan/patterns/modifiers/hex.c4
-rw-r--r--plugins/pychrysalide/analysis/scan/patterns/modifiers/module.c2
-rw-r--r--plugins/pychrysalide/analysis/scan/patterns/modifiers/rev.c2
-rw-r--r--plugins/pychrysalide/analysis/scan/patterns/modifiers/xor.c210
-rw-r--r--plugins/pychrysalide/analysis/scan/patterns/modifiers/xor.h45
-rw-r--r--plugins/pychrysalide/analysis/scan/scanner.c6
-rw-r--r--plugins/pychrysalide/analysis/scan/space.c6
-rw-r--r--plugins/pychrysalide/common/bits.c56
-rw-r--r--plugins/pychrysalide/core.c27
-rw-r--r--plugins/pychrysalide/plugins/plugin.c2
-rw-r--r--plugins/python/scripting/core.py3
172 files changed, 14974 insertions, 588 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 7ce4229..1cda6e0 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -28,8 +28,10 @@ SUBDIRS = \
mobicore \
pe \
yaml \
+ apihashing \
bhash \
dalvik \
+ encodings \
libcsem \
lnxsyscalls \
readdex \
diff --git a/plugins/apihashing/Makefile.am b/plugins/apihashing/Makefile.am
new file mode 100644
index 0000000..d73f8b0
--- /dev/null
+++ b/plugins/apihashing/Makefile.am
@@ -0,0 +1,65 @@
+
+lib_LTLIBRARIES = libapihashing.la
+
+libdir = $(pluginslibdir)
+
+
+if BUILD_PYTHON_PACKAGE
+
+RUN_PATH = -Wl,-rpath,'$$ORIGIN/../chrysalide-libs:$$ORIGIN'
+
+else
+
+RUN_PATH = -Wl,-rpath,'$$ORIGIN'
+
+endif
+
+if BUILD_PYTHON3_BINDINGS
+
+PYTHON3_LIBADD = python/libapihashingpython.la
+
+if BUILD_DISCARD_LOCAL
+
+if BUILD_PYTHON_PACKAGE
+PYTHON3_RUN_PATH = -Wl,-rpath,'$$ORIGIN/..'
+else
+PYTHON3_RUN_PATH = -Wl,-rpath,'$$ORIGIN'
+endif
+
+else
+
+PYTHON3_RUN_PATH = -Wl,-rpath,$(abs_top_srcdir)/plugins/pychrysalide/.libs
+
+endif
+
+PYTHON3_LDFLAGS = $(PYTHON3_RUN_PATH) -L$(top_srcdir)/plugins/pychrysalide/.libs -l:pychrysalide.so
+
+PYTHON3_SUBDIRS = python
+
+endif
+
+
+libapihashing_la_SOURCES = \
+ apihash.h apihash.c \
+ core.h core.c
+
+libapihashing_la_LIBADD = \
+ $(PYTHON3_LIBADD) \
+ classics/libapihashingclassics.la \
+ custom/libapihashingcustom.la
+
+libapihashing_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) -I$(top_srcdir)/src
+
+libapihashing_la_LDFLAGS = \
+ -avoid-version \
+ -L$(top_srcdir)/src/.libs -lchrysacore \
+ -L$(top_srcdir)/plugins/pe/.libs -lpe \
+ $(RUN_PATH) $(PYTHON3_LDFLAGS)
+
+
+devdir = $(includedir)/chrysalide/$(subdir)
+
+dev_HEADERS = $(libapihashing_la_SOURCES:%c=)
+
+
+SUBDIRS = $(PYTHON3_SUBDIRS) classics custom
diff --git a/plugins/apihashing/apihash.c b/plugins/apihashing/apihash.c
new file mode 100644
index 0000000..3313073
--- /dev/null
+++ b/plugins/apihashing/apihash.c
@@ -0,0 +1,134 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * apihash.c - détermination d'API par empreinte de fonction
+ *
+ * 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 "apihash.h"
+
+
+#include <analysis/scan/patterns/modifier-int.h>
+
+
+
+/* ----------------------- RECHERCHE D'UN MOTIF DE TEXTE BRUT ----------------------- */
+
+
+/* Initialise la classe des transmissions en empreintes d'API. */
+static void g_api_hash_modifier_class_init(GApiHashModifierClass *klass);
+
+/* Initialise une instance de transmission en empreinte d'API. */
+static void g_api_hash_modifier_init(GApiHashModifier *);
+
+/* Supprime toutes les références externes. */
+static void g_api_hash_modifier_dispose(GApiHashModifier *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_api_hash_modifier_finalize(GApiHashModifier *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* RECHERCHE D'UN MOTIF DE TEXTE BRUT */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une transormation en empreinte d'API. */
+G_DEFINE_TYPE(GApiHashModifier, g_api_hash_modifier, G_TYPE_SCAN_TOKEN_MODIFIER);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des transmissions en empreintes d'API. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_api_hash_modifier_class_init(GApiHashModifierClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_api_hash_modifier_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_api_hash_modifier_finalize;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : modifier = instance à initialiser. *
+* *
+* Description : Initialise une instance de transmission en empreinte d'API. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_api_hash_modifier_init(GApiHashModifier *modifier)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : modifier = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_api_hash_modifier_dispose(GApiHashModifier *modifier)
+{
+ G_OBJECT_CLASS(g_api_hash_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_api_hash_modifier_finalize(GApiHashModifier *modifier)
+{
+ G_OBJECT_CLASS(g_api_hash_modifier_parent_class)->finalize(G_OBJECT(modifier));
+
+}
diff --git a/plugins/apihashing/apihash.h b/plugins/apihashing/apihash.h
new file mode 100644
index 0000000..cfc3365
--- /dev/null
+++ b/plugins/apihashing/apihash.h
@@ -0,0 +1,55 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * apihash.h - prototypes pour la détermination d'API par empreinte de fonction
+ *
+ * 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_APIHASH_H
+#define _PLUGINS_APIHASHING_APIHASH_H
+
+
+#include <glib-object.h>
+
+
+#include <analysis/scan/patterns/modifier.h>
+
+
+
+#define G_TYPE_API_HASH_MODIFIER g_api_hash_modifier_get_type()
+#define G_API_HASH_MODIFIER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_API_HASH_MODIFIER, GApiHashModifier))
+#define G_IS_API_HASH_MODIFIER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_API_HASH_MODIFIER))
+#define G_API_HASH_MODIFIER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_API_HASH_MODIFIER, GApiHashModifierClass))
+#define G_IS_API_HASH_MODIFIER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_API_HASH_MODIFIER))
+#define G_API_HASH_MODIFIER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_API_HASH_MODIFIER, GApiHashModifierClass))
+
+
+/* Transormation en empreinte d'API (instance) */
+typedef GScanTokenModifier GApiHashModifier;
+
+/* Transormation en empreinte d'API (classe) */
+typedef GScanTokenModifierClass GApiHashModifierClass;
+
+
+/* Indique le type défini pour une transormation en empreinte d'API. */
+GType g_api_hash_modifier_get_type(void);
+
+
+
+#endif /* _PLUGINS_APIHASHING_APIHASH_H */
diff --git a/plugins/apihashing/classics/Makefile.am b/plugins/apihashing/classics/Makefile.am
new file mode 100644
index 0000000..9f97b47
--- /dev/null
+++ b/plugins/apihashing/classics/Makefile.am
@@ -0,0 +1,14 @@
+
+noinst_LTLIBRARIES = libapihashingclassics.la
+
+libapihashingclassics_la_SOURCES = \
+ crc32.h crc32.c \
+ djb2.h djb2.c \
+ ror13.h ror13.c
+
+libapihashingclassics_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) -I$(top_srcdir)/src
+
+
+devdir = $(includedir)/chrysalide-$(subdir)
+
+dev_HEADERS = $(libapihashingclassics_la_SOURCES:%c=)
diff --git a/plugins/apihashing/classics/crc32.c b/plugins/apihashing/classics/crc32.c
new file mode 100644
index 0000000..98f9a6b
--- /dev/null
+++ b/plugins/apihashing/classics/crc32.c
@@ -0,0 +1,332 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * crc32.c - transormation en empreinte d'API crc32
+ *
+ * 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 "crc32.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 empreintes crc32. */
+static void g_scan_crc32_modifier_class_init(GScanCrc32ModifierClass *klass);
+
+/* Initialise une instance de transmission en empreinte crc32. */
+static void g_scan_crc32_modifier_init(GScanCrc32Modifier *);
+
+/* Supprime toutes les références externes. */
+static void g_scan_crc32_modifier_dispose(GScanCrc32Modifier *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_scan_crc32_modifier_finalize(GScanCrc32Modifier *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Fournit le nom d'appel d'un modificateur pour motif. */
+static char *g_scan_crc32_modifier_get_name(const GScanCrc32Modifier *);
+
+/* Calcule l'empreinte crc32 d'un motif de recherche. */
+static uint32_t compute_crc32(const sized_binary_t *);
+
+/* Transforme une séquence d'octets pour motif de recherche. */
+static bool g_scan_crc32_modifier_transform(const GScanCrc32Modifier *, 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_crc32_modifier_get_path(const GScanCrc32Modifier *, size_t *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* RECHERCHE D'UN MOTIF DE TEXTE BRUT */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une transormation en encodage Crc32. */
+G_DEFINE_TYPE(GScanCrc32Modifier, g_scan_crc32_modifier, G_TYPE_API_HASH_MODIFIER);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des transmissions en empreintes crc32. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_crc32_modifier_class_init(GScanCrc32ModifierClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GScanTokenModifierClass *modifier; /* Version de classe parente */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_crc32_modifier_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_scan_crc32_modifier_finalize;
+
+ modifier = G_SCAN_TOKEN_MODIFIER_CLASS(klass);
+
+ modifier->get_name = (get_scan_modifier_name_fc)g_scan_crc32_modifier_get_name;
+
+ modifier->transform = (transform_scan_token_fc)g_scan_crc32_modifier_transform;
+ modifier->get_path = (get_modifier_path)g_scan_crc32_modifier_get_path;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : modifier = instance à initialiser. *
+* *
+* Description : Initialise une instance de transmission en empreinte crc32. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_crc32_modifier_init(GScanCrc32Modifier *modifier)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : modifier = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_crc32_modifier_dispose(GScanCrc32Modifier *modifier)
+{
+ G_OBJECT_CLASS(g_scan_crc32_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_crc32_modifier_finalize(GScanCrc32Modifier *modifier)
+{
+ G_OBJECT_CLASS(g_scan_crc32_modifier_parent_class)->finalize(G_OBJECT(modifier));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Construit un modificateur livrant des empreintes crc32. *
+* *
+* Retour : Mécanisme mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GScanTokenModifier *g_scan_crc32_modifier_new(void)
+{
+ GScanTokenModifier *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_SCAN_CRC32_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_crc32_modifier_get_name(const GScanCrc32Modifier *modifier)
+{
+ char *result; /* Désignation à retourner */
+
+ result = strdup("crc32");
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : src = séquence d'octets à traiter. *
+* *
+* Description : Calcule l'empreinte crc32 d'un motif de recherche. *
+* *
+* Retour : Valeur entière de l'empreinte déterminée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static uint32_t compute_crc32(const sized_binary_t *src)
+{
+ uint32_t result; /* Valeur à retourner */
+ size_t i; /* Boucle de parcours #1 */
+ size_t k; /* Boucle de parcours #2 */
+
+ result = 0xffffffff;
+
+ for (i = 0; i < src->len; i++)
+ {
+ result ^= src->data[i];
+
+ for (k = 0; k < 8; k++)
+ result = result & 1 ? (result >> 1) ^ 0xedb88320 : result >> 1;
+
+ }
+
+ result = ~result;
+
+ 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_crc32_modifier_transform(const GScanCrc32Modifier *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_crc32(_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_crc32_modifier_get_path(const GScanCrc32Modifier *modifier, size_t *index)
+{
+ char *result; /* Combinaison à retourner */
+
+ if (*index > 0)
+ {
+ result = NULL;
+ (*index)--;
+ }
+
+ else
+ result = strdup("crc32");
+
+ return result;
+
+}
diff --git a/plugins/apihashing/classics/crc32.h b/plugins/apihashing/classics/crc32.h
new file mode 100644
index 0000000..0198c5d
--- /dev/null
+++ b/plugins/apihashing/classics/crc32.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * crc32.h - prototypes pour la transormation en empreinte d'API crc32
+ *
+ * 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_CLASSICS_CRC32_H
+#define _PLUGINS_APIHASHING_CLASSICS_CRC32_H
+
+
+#include <glib-object.h>
+
+
+#include "../apihash.h"
+
+
+
+#define G_TYPE_SCAN_CRC32_MODIFIER g_scan_crc32_modifier_get_type()
+#define G_SCAN_CRC32_MODIFIER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_CRC32_MODIFIER, GScanCrc32Modifier))
+#define G_IS_SCAN_CRC32_MODIFIER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_CRC32_MODIFIER))
+#define G_SCAN_CRC32_MODIFIER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_CRC32_MODIFIER, GScanCrc32ModifierClass))
+#define G_IS_SCAN_CRC32_MODIFIER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_CRC32_MODIFIER))
+#define G_SCAN_CRC32_MODIFIER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_CRC32_MODIFIER, GScanCrc32ModifierClass))
+
+
+/* Transormation en empreinte d'API crc32 (instance) */
+typedef GApiHashModifier GScanCrc32Modifier;
+
+/* Transormation en empreinte d'API crc32 (classe) */
+typedef GApiHashModifierClass GScanCrc32ModifierClass;
+
+
+/* Indique le type défini pour une transormation en empreinte crc32. */
+GType g_scan_crc32_modifier_get_type(void);
+
+/* Construit un modificateur livrant des empreintes crc32. */
+GScanTokenModifier *g_scan_crc32_modifier_new(void);
+
+
+
+#endif /* _PLUGINS_APIHASHING_CLASSICS_CRC32_H */
diff --git a/plugins/apihashing/classics/djb2.c b/plugins/apihashing/classics/djb2.c
new file mode 100644
index 0000000..524218f
--- /dev/null
+++ b/plugins/apihashing/classics/djb2.c
@@ -0,0 +1,323 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * djb2.c - transormation en empreinte d'API djb2
+ *
+ * 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 "djb2.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 empreintes djb2. */
+static void g_scan_djb2_modifier_class_init(GScanDjb2ModifierClass *klass);
+
+/* Initialise une instance de transmission en empreinte djb2. */
+static void g_scan_djb2_modifier_init(GScanDjb2Modifier *);
+
+/* Supprime toutes les références externes. */
+static void g_scan_djb2_modifier_dispose(GScanDjb2Modifier *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_scan_djb2_modifier_finalize(GScanDjb2Modifier *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Fournit le nom d'appel d'un modificateur pour motif. */
+static char *g_scan_djb2_modifier_get_name(const GScanDjb2Modifier *);
+
+/* Calcule l'empreinte djb2 d'un motif de recherche. */
+static uint32_t compute_djb2(const sized_binary_t *);
+
+/* Transforme une séquence d'octets pour motif de recherche. */
+static bool g_scan_djb2_modifier_transform(const GScanDjb2Modifier *, 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_djb2_modifier_get_path(const GScanDjb2Modifier *, size_t *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* RECHERCHE D'UN MOTIF DE TEXTE BRUT */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une transormation en encodage Djb2. */
+G_DEFINE_TYPE(GScanDjb2Modifier, g_scan_djb2_modifier, G_TYPE_API_HASH_MODIFIER);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des transmissions en empreintes djb2. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_djb2_modifier_class_init(GScanDjb2ModifierClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GScanTokenModifierClass *modifier; /* Version de classe parente */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_djb2_modifier_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_scan_djb2_modifier_finalize;
+
+ modifier = G_SCAN_TOKEN_MODIFIER_CLASS(klass);
+
+ modifier->get_name = (get_scan_modifier_name_fc)g_scan_djb2_modifier_get_name;
+
+ modifier->transform = (transform_scan_token_fc)g_scan_djb2_modifier_transform;
+ modifier->get_path = (get_modifier_path)g_scan_djb2_modifier_get_path;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : modifier = instance à initialiser. *
+* *
+* Description : Initialise une instance de transmission en empreinte djb2. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_djb2_modifier_init(GScanDjb2Modifier *modifier)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : modifier = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_djb2_modifier_dispose(GScanDjb2Modifier *modifier)
+{
+ G_OBJECT_CLASS(g_scan_djb2_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_djb2_modifier_finalize(GScanDjb2Modifier *modifier)
+{
+ G_OBJECT_CLASS(g_scan_djb2_modifier_parent_class)->finalize(G_OBJECT(modifier));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Construit un modificateur livrant des empreintes djb2. *
+* *
+* Retour : Mécanisme mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GScanTokenModifier *g_scan_djb2_modifier_new(void)
+{
+ GScanTokenModifier *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_SCAN_DJB2_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_djb2_modifier_get_name(const GScanDjb2Modifier *modifier)
+{
+ char *result; /* Désignation à retourner */
+
+ result = strdup("djb2");
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : src = séquence d'octets à traiter. *
+* *
+* Description : Calcule l'empreinte djb2 d'un motif de recherche. *
+* *
+* Retour : Valeur entière de l'empreinte déterminée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static uint32_t compute_djb2(const sized_binary_t *src)
+{
+ uint32_t result; /* Valeur à retourner */
+ size_t i; /* Boucle de parcours */
+
+ result = 0x1505; /* 5381 */
+
+ for (i = 0; i < src->len; i++)
+ result = ((result << 5) + result) + src->data[i]; /* hash * 33 + c */
+
+ 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_djb2_modifier_transform(const GScanDjb2Modifier *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_djb2(_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_djb2_modifier_get_path(const GScanDjb2Modifier *modifier, size_t *index)
+{
+ char *result; /* Combinaison à retourner */
+
+ if (*index > 0)
+ {
+ result = NULL;
+ (*index)--;
+ }
+
+ else
+ result = strdup("djb2");
+
+ return result;
+
+}
diff --git a/plugins/apihashing/classics/djb2.h b/plugins/apihashing/classics/djb2.h
new file mode 100644
index 0000000..04df1df
--- /dev/null
+++ b/plugins/apihashing/classics/djb2.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * djb2.h - prototypes pour la transormation en empreinte d'API djb2
+ *
+ * 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_CLASSICS_DJB2_H
+#define _PLUGINS_APIHASHING_CLASSICS_DJB2_H
+
+
+#include <glib-object.h>
+
+
+#include "../apihash.h"
+
+
+
+#define G_TYPE_SCAN_DJB2_MODIFIER g_scan_djb2_modifier_get_type()
+#define G_SCAN_DJB2_MODIFIER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_DJB2_MODIFIER, GScanDjb2Modifier))
+#define G_IS_SCAN_DJB2_MODIFIER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_DJB2_MODIFIER))
+#define G_SCAN_DJB2_MODIFIER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_DJB2_MODIFIER, GScanDjb2ModifierClass))
+#define G_IS_SCAN_DJB2_MODIFIER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_DJB2_MODIFIER))
+#define G_SCAN_DJB2_MODIFIER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_DJB2_MODIFIER, GScanDjb2ModifierClass))
+
+
+/* Transormation en empreinte d'API DJB2 (instance) */
+typedef GApiHashModifier GScanDjb2Modifier;
+
+/* Transormation en empreinte d'API DJB2 (classe) */
+typedef GApiHashModifierClass GScanDjb2ModifierClass;
+
+
+/* Indique le type défini pour une transormation en empreinte djb2. */
+GType g_scan_djb2_modifier_get_type(void);
+
+/* Construit un modificateur livrant des empreintes djb2. */
+GScanTokenModifier *g_scan_djb2_modifier_new(void);
+
+
+
+#endif /* _PLUGINS_APIHASHING_CLASSICS_DJB2_H */
diff --git a/plugins/apihashing/classics/ror13.c b/plugins/apihashing/classics/ror13.c
new file mode 100644
index 0000000..e557804
--- /dev/null
+++ b/plugins/apihashing/classics/ror13.c
@@ -0,0 +1,323 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * ror13.c - transormation en empreinte d'API ror13
+ *
+ * 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 "ror13.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 empreintes ror13. */
+static void g_scan_ror13_modifier_class_init(GScanRor13ModifierClass *klass);
+
+/* Initialise une instance de transmission en empreinte ror13. */
+static void g_scan_ror13_modifier_init(GScanRor13Modifier *);
+
+/* Supprime toutes les références externes. */
+static void g_scan_ror13_modifier_dispose(GScanRor13Modifier *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_scan_ror13_modifier_finalize(GScanRor13Modifier *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Fournit le nom d'appel d'un modificateur pour motif. */
+static char *g_scan_ror13_modifier_get_name(const GScanRor13Modifier *);
+
+/* Calcule l'empreinte ror13 d'un motif de recherche. */
+static uint32_t compute_ror13(const sized_binary_t *);
+
+/* Transforme une séquence d'octets pour motif de recherche. */
+static bool g_scan_ror13_modifier_transform(const GScanRor13Modifier *, 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_ror13_modifier_get_path(const GScanRor13Modifier *, size_t *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* RECHERCHE D'UN MOTIF DE TEXTE BRUT */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une transormation en empreinte ror13. */
+G_DEFINE_TYPE(GScanRor13Modifier, g_scan_ror13_modifier, G_TYPE_API_HASH_MODIFIER);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des transmissions en empreintes ror13. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_ror13_modifier_class_init(GScanRor13ModifierClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GScanTokenModifierClass *modifier; /* Version de classe parente */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_ror13_modifier_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_scan_ror13_modifier_finalize;
+
+ modifier = G_SCAN_TOKEN_MODIFIER_CLASS(klass);
+
+ modifier->get_name = (get_scan_modifier_name_fc)g_scan_ror13_modifier_get_name;
+
+ modifier->transform = (transform_scan_token_fc)g_scan_ror13_modifier_transform;
+ modifier->get_path = (get_modifier_path)g_scan_ror13_modifier_get_path;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : modifier = instance à initialiser. *
+* *
+* Description : Initialise une instance de transmission en empreinte ror13. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_ror13_modifier_init(GScanRor13Modifier *modifier)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : modifier = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_ror13_modifier_dispose(GScanRor13Modifier *modifier)
+{
+ G_OBJECT_CLASS(g_scan_ror13_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_ror13_modifier_finalize(GScanRor13Modifier *modifier)
+{
+ G_OBJECT_CLASS(g_scan_ror13_modifier_parent_class)->finalize(G_OBJECT(modifier));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Construit un modificateur livrant des empreintes ror13. *
+* *
+* Retour : Mécanisme mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GScanTokenModifier *g_scan_ror13_modifier_new(void)
+{
+ GScanTokenModifier *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_SCAN_ROR13_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_ror13_modifier_get_name(const GScanRor13Modifier *modifier)
+{
+ char *result; /* Désignation à retourner */
+
+ result = strdup("ror13");
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : src = séquence d'octets à traiter. *
+* *
+* Description : Calcule l'empreinte ror13 d'un motif de recherche. *
+* *
+* Retour : Valeur entière de l'empreinte déterminée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static uint32_t compute_ror13(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 = src->data[i] + ((result << 19) | (result >> 13));
+
+ 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_ror13_modifier_transform(const GScanRor13Modifier *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_ror13(_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_ror13_modifier_get_path(const GScanRor13Modifier *modifier, size_t *index)
+{
+ char *result; /* Combinaison à retourner */
+
+ if (*index > 0)
+ {
+ result = NULL;
+ (*index)--;
+ }
+
+ else
+ result = strdup("ror13");
+
+ return result;
+
+}
diff --git a/plugins/apihashing/classics/ror13.h b/plugins/apihashing/classics/ror13.h
new file mode 100644
index 0000000..43480bd
--- /dev/null
+++ b/plugins/apihashing/classics/ror13.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * ror13.h - prototypes pour la transormation en empreinte d'API ror13
+ *
+ * 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_CLASSICS_ROR13_H
+#define _PLUGINS_APIHASHING_CLASSICS_ROR13_H
+
+
+#include <glib-object.h>
+
+
+#include "../apihash.h"
+
+
+
+#define G_TYPE_SCAN_ROR13_MODIFIER g_scan_ror13_modifier_get_type()
+#define G_SCAN_ROR13_MODIFIER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_ROR13_MODIFIER, GScanRor13Modifier))
+#define G_IS_SCAN_ROR13_MODIFIER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_ROR13_MODIFIER))
+#define G_SCAN_ROR13_MODIFIER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_ROR13_MODIFIER, GScanRor13ModifierClass))
+#define G_IS_SCAN_ROR13_MODIFIER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_ROR13_MODIFIER))
+#define G_SCAN_ROR13_MODIFIER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_ROR13_MODIFIER, GScanRor13ModifierClass))
+
+
+/* Transormation en empreinte d'API ror13 (instance) */
+typedef GApiHashModifier GScanRor13Modifier;
+
+/* Transormation en empreinte d'API ror13 (classe) */
+typedef GApiHashModifierClass GScanRor13ModifierClass;
+
+
+/* Indique le type défini pour une transormation en empreinte ror13. */
+GType g_scan_ror13_modifier_get_type(void);
+
+/* Construit un modificateur livrant des empreintes ror13. */
+GScanTokenModifier *g_scan_ror13_modifier_new(void);
+
+
+
+#endif /* _PLUGINS_APIHASHING_CLASSICS_ROR13_H */
diff --git a/plugins/apihashing/core.c b/plugins/apihashing/core.c
new file mode 100644
index 0000000..a74a637
--- /dev/null
+++ b/plugins/apihashing/core.c
@@ -0,0 +1,110 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * core.c - prototypes pour le calcul d'encodages
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "core.h"
+
+
+#include <analysis/scan/core.h>
+#include <plugins/self.h>
+
+
+#ifdef INCLUDE_PYTHON3_BINDINGS
+# include "python/module.h"
+# include "python/classics/module.h"
+#endif
+#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_
+# define PG_REQ RL("PyChrysalide")
+#else
+# define PG_REQ NO_REQ
+#endif
+
+
+
+DEFINE_CHRYSALIDE_PLUGIN("ApiHashing", "API hash computing as ROST modifiers",
+ PACKAGE_VERSION, CHRYSALIDE_WEBSITE("doc/formats"),
+ PG_REQ, AL(PGA_PLUGIN_INIT));
+
+
+
+/******************************************************************************
+* *
+* Paramètres : plugin = greffon à manipuler. *
+* *
+* Description : Prend acte du chargement du greffon. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+#define REGISTER_SCAN_MODIFIER(m) \
+ ({ \
+ GScanTokenModifier *__mod; \
+ bool __status; \
+ __mod = m; \
+ __status = register_scan_token_modifier(__mod); \
+ g_object_unref(G_OBJECT(__mod)); \
+ __status; \
+ })
+
+ if (result) result = REGISTER_SCAN_MODIFIER(g_scan_crc32_modifier_new());
+ 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
+
+ if (result) result = add_apihashing_module_to_python_module();
+ if (result) result = register_apihashing_classics_modifiers();
+
+#endif
+
+ return result;
+
+}
diff --git a/plugins/apihashing/core.h b/plugins/apihashing/core.h
new file mode 100644
index 0000000..75a6e73
--- /dev/null
+++ b/plugins/apihashing/core.h
@@ -0,0 +1,38 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * core.h - prototypes pour le calcul d'encodages
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _PLUGINS_ENCODINGS_CORE_H
+#define _PLUGINS_ENCODINGS_CORE_H
+
+
+#include <plugins/plugin.h>
+#include <plugins/plugin-int.h>
+
+
+
+/* Prend acte du chargement du greffon. */
+G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *);
+
+
+
+#endif /* _PLUGINS_ENCODINGS_CORE_H */
diff --git a/plugins/apihashing/custom/Makefile.am b/plugins/apihashing/custom/Makefile.am
new file mode 100644
index 0000000..026addc
--- /dev/null
+++ b/plugins/apihashing/custom/Makefile.am
@@ -0,0 +1,18 @@
+
+noinst_LTLIBRARIES = libapihashingcustom.la
+
+libapihashingcustom_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 \
+ 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
+
+
+devdir = $(includedir)/chrysalide-$(subdir)
+
+dev_HEADERS = $(libapihashingcustom_la_SOURCES:%c=)
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/sll1-add-hash32.c b/plugins/apihashing/custom/sll1-add-hash32.c
new file mode 100644
index 0000000..de00f81
--- /dev/null
+++ b/plugins/apihashing/custom/sll1-add-hash32.c
@@ -0,0 +1,326 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * sll1-add-hash32.c - transormation en empreinte d'API sll1-add-hash32
+ *
+ * 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 "sll1-add-hash32.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 sll1-add-hash32. */
+static void g_scan_sll1_add_hash32_modifier_class_init(GScanSll1AddHash32ModifierClass *klass);
+
+/* Initialise une instance de transmission en sll1-add-hash32. */
+static void g_scan_sll1_add_hash32_modifier_init(GScanSll1AddHash32Modifier *);
+
+/* Supprime toutes les références externes. */
+static void g_scan_sll1_add_hash32_modifier_dispose(GScanSll1AddHash32Modifier *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_scan_sll1_add_hash32_modifier_finalize(GScanSll1AddHash32Modifier *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Fournit le nom d'appel d'un modificateur pour motif. */
+static char *g_scan_sll1_add_hash32_modifier_get_name(const GScanSll1AddHash32Modifier *);
+
+/* Calcule l'empreinte sll1-add-hash32 d'un motif de recherche. */
+static uint32_t compute_sll1_add_hash32(const sized_binary_t *);
+
+/* Transforme une séquence d'octets pour motif de recherche. */
+static bool g_scan_sll1_add_hash32_modifier_transform(const GScanSll1AddHash32Modifier *, 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_sll1_add_hash32_modifier_get_path(const GScanSll1AddHash32Modifier *, size_t *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* RECHERCHE D'UN MOTIF DE TEXTE BRUT */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une transormation en empreinte sll1-add-hash32. */
+G_DEFINE_TYPE(GScanSll1AddHash32Modifier, g_scan_sll1_add_hash32_modifier, G_TYPE_API_HASH_MODIFIER);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des transmissions en sll1-add-hash32. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_sll1_add_hash32_modifier_class_init(GScanSll1AddHash32ModifierClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GScanTokenModifierClass *modifier; /* Version de classe parente */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_sll1_add_hash32_modifier_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_scan_sll1_add_hash32_modifier_finalize;
+
+ modifier = G_SCAN_TOKEN_MODIFIER_CLASS(klass);
+
+ modifier->get_name = (get_scan_modifier_name_fc)g_scan_sll1_add_hash32_modifier_get_name;
+
+ modifier->transform = (transform_scan_token_fc)g_scan_sll1_add_hash32_modifier_transform;
+ modifier->get_path = (get_modifier_path)g_scan_sll1_add_hash32_modifier_get_path;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : modifier = instance à initialiser. *
+* *
+* Description : Initialise une instance de transmission en sll1-add-hash32. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_sll1_add_hash32_modifier_init(GScanSll1AddHash32Modifier *modifier)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : modifier = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_sll1_add_hash32_modifier_dispose(GScanSll1AddHash32Modifier *modifier)
+{
+ G_OBJECT_CLASS(g_scan_sll1_add_hash32_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_sll1_add_hash32_modifier_finalize(GScanSll1AddHash32Modifier *modifier)
+{
+ G_OBJECT_CLASS(g_scan_sll1_add_hash32_modifier_parent_class)->finalize(G_OBJECT(modifier));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Construit un modificateur vers empreintes sll1-add-hash32. *
+* *
+* Retour : Mécanisme mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GScanTokenModifier *g_scan_sll1_add_hash32_modifier_new(void)
+{
+ GScanTokenModifier *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_SCAN_SLL1_ADD_HASH32_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_sll1_add_hash32_modifier_get_name(const GScanSll1AddHash32Modifier *modifier)
+{
+ char *result; /* Désignation à retourner */
+
+ result = strdup("sll1-add-hash32");
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : src = séquence d'octets à traiter. *
+* *
+* Description : Calcule l'empreinte sll1-add-hash32 d'un motif de recherche. *
+* *
+* Retour : Valeur entière de l'empreinte déterminée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static uint32_t compute_sll1_add_hash32(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 += (src->data[i] | 0x60);
+ result <<= 1;
+ }
+
+ 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_sll1_add_hash32_modifier_transform(const GScanSll1AddHash32Modifier *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_sll1_add_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_sll1_add_hash32_modifier_get_path(const GScanSll1AddHash32Modifier *modifier, size_t *index)
+{
+ char *result; /* Combinaison à retourner */
+
+ if (*index > 0)
+ {
+ result = NULL;
+ (*index)--;
+ }
+
+ else
+ result = strdup("sll1-add-hash32");
+
+ return result;
+
+}
diff --git a/plugins/apihashing/custom/sll1-add-hash32.h b/plugins/apihashing/custom/sll1-add-hash32.h
new file mode 100644
index 0000000..39abee2
--- /dev/null
+++ b/plugins/apihashing/custom/sll1-add-hash32.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * sll1-add-hash32.h - prototypes pour la transormation en empreinte d'API sll1-add-hash32
+ *
+ * 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_SLL1_ADD_HASH32_H
+#define _PLUGINS_APIHASHING_CUSTOM_SLL1_ADD_HASH32_H
+
+
+#include <glib-object.h>
+
+
+#include "../apihash.h"
+
+
+
+#define G_TYPE_SCAN_SLL1_ADD_HASH32_MODIFIER g_scan_sll1_add_hash32_modifier_get_type()
+#define G_SCAN_SLL1_ADD_HASH32_MODIFIER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_SLL1_ADD_HASH32_MODIFIER, GScanSll1AddHash32Modifier))
+#define G_IS_SCAN_SLL1_ADD_HASH32_MODIFIER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_SLL1_ADD_HASH32_MODIFIER))
+#define G_SCAN_SLL1_ADD_HASH32_MODIFIER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_SLL1_ADD_HASH32_MODIFIER, GScanSll1AddHash32ModifierClass))
+#define G_IS_SCAN_SLL1_ADD_HASH32_MODIFIER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_SLL1_ADD_HASH32_MODIFIER))
+#define G_SCAN_SLL1_ADD_HASH32_MODIFIER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_SLL1_ADD_HASH32_MODIFIER, GScanSll1AddHash32ModifierClass))
+
+
+/* Transormation en empreinte d'API sll1_add_hash32 (instance) */
+typedef GApiHashModifier GScanSll1AddHash32Modifier;
+
+/* Transormation en empreinte d'API sll1_add_hash32 (classe) */
+typedef GApiHashModifierClass GScanSll1AddHash32ModifierClass;
+
+
+/* Indique le type défini pour une transormation en empreinte sll1-add-hash32. */
+GType g_scan_sll1_add_hash32_modifier_get_type(void);
+
+/* Construit un modificateur vers empreintes sll1-add-hash32. */
+GScanTokenModifier *g_scan_sll1_add_hash32_modifier_new(void);
+
+
+
+#endif /* _PLUGINS_APIHASHING_CUSTOM_SLL1_ADD_HASH32_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/Makefile.am b/plugins/apihashing/python/Makefile.am
new file mode 100644
index 0000000..d94218d
--- /dev/null
+++ b/plugins/apihashing/python/Makefile.am
@@ -0,0 +1,20 @@
+
+noinst_LTLIBRARIES = libapihashingpython.la
+
+libapihashingpython_la_SOURCES = \
+ apihash.h apihash.c \
+ module.h module.c
+
+libapihashingpython_la_LIBADD = \
+ classics/libapihashingpythonclassics.la
+
+libapihashingpython_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+ -I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
+
+
+devdir = $(includedir)/chrysalide/$(subdir)
+
+dev_HEADERS = $(libapihashingpython_la_SOURCES:%c=)
+
+
+SUBDIRS = classics
diff --git a/plugins/apihashing/python/apihash.c b/plugins/apihashing/python/apihash.c
new file mode 100644
index 0000000..a3ae519
--- /dev/null
+++ b/plugins/apihashing/python/apihash.c
@@ -0,0 +1,212 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * base64.c - équivalent Python du fichier "plugins/encodings/rost/base64.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 "apihash.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+#include <plugins/pychrysalide/analysis/scan/patterns/modifier.h>
+
+
+#include "../apihash.h"
+
+
+
+CREATE_DYN_CONSTRUCTOR(api_hash_modifier, G_TYPE_API_HASH_MODIFIER);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_api_hash_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_api_hash_modifier_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ int ret; /* Bilan de lecture des args. */
+
+#define API_HASH_MODIFIER_DOC \
+ "The *ApiHashModifier* class is the base object for all algorithms" \
+ " involed in malwares and revolving API functions to call from" \
+ " a hash value.\n" \
+ "\n" \
+ "Instances can be created using the following constructor:\n" \
+ "\n" \
+ " ApiHashModifier()"
+
+ /* 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_api_hash_modifier_type(void)
+{
+ static PyMethodDef py_api_hash_modifier_methods[] = {
+ { NULL }
+ };
+
+ static PyGetSetDef py_api_hash_modifier_getseters[] = {
+ { NULL }
+ };
+
+ static PyTypeObject py_api_hash_modifier_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.plugins.apihashing.ApiHashModifier",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+ .tp_doc = API_HASH_MODIFIER_DOC,
+
+ .tp_methods = py_api_hash_modifier_methods,
+ .tp_getset = py_api_hash_modifier_getseters,
+
+ .tp_init = py_api_hash_modifier_init,
+ .tp_new = py_api_hash_modifier_new,
+
+ };
+
+ return &py_api_hash_modifier_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Prend en charge l'objet 'pychrysalide.....ApiHashModifier'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool ensure_python_api_hash_modifier_is_registered(void)
+{
+ PyTypeObject *type; /* Type Python Base64Modifier */
+ PyObject *module; /* Module à recompléter */
+ PyObject *dict; /* Dictionnaire du module */
+
+ type = get_python_api_hash_modifier_type();
+
+ if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+ {
+ module = get_access_to_python_module("pychrysalide.plugins.apihashing");
+
+ dict = PyModule_GetDict(module);
+
+ if (!ensure_python_scan_token_modifier_is_registered())
+ return false;
+
+ if (!register_class_for_pygobject(dict, G_TYPE_API_HASH_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 par empreinte d'API. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_api_hash_modifier(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_api_hash_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 API hash modifier");
+ break;
+
+ case 1:
+ *((GApiHashModifier **)dst) = G_API_HASH_MODIFIER(pygobject_get(arg));
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/apihashing/python/apihash.h b/plugins/apihashing/python/apihash.h
new file mode 100644
index 0000000..5474d49
--- /dev/null
+++ b/plugins/apihashing/python/apihash.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * base64.h - équivalent Python du fichier "plugins/encodings/rost/base64.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_ENCODINGS_PYTHON_ROST_BASE64_H
+#define _PLUGINS_ENCODINGS_PYTHON_ROST_BASE64_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_api_hash_modifier_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.plugins.apihashing.ApiHashModifier'. */
+bool ensure_python_api_hash_modifier_is_registered(void);
+
+/* Tente de convertir en transformation par empreinte d'API. */
+int convert_to_api_hash_modifier(PyObject *, void *);
+
+
+
+#endif /* _PLUGINS_ENCODINGS_PYTHON_ROST_BASE64_H */
diff --git a/plugins/apihashing/python/classics/Makefile.am b/plugins/apihashing/python/classics/Makefile.am
new file mode 100644
index 0000000..316e13f
--- /dev/null
+++ b/plugins/apihashing/python/classics/Makefile.am
@@ -0,0 +1,16 @@
+
+noinst_LTLIBRARIES = libapihashingpythonclassics.la
+
+libapihashingpythonclassics_la_SOURCES = \
+ crc32.h crc32.c \
+ djb2.h djb2.c \
+ module.h module.c \
+ ror13.h ror13.c
+
+libapihashingpythonclassics_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+ -I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
+
+
+devdir = $(includedir)/chrysalide-$(subdir)
+
+dev_HEADERS = $(libapihashingpythonclassics_la_SOURCES:%c=)
diff --git a/plugins/apihashing/python/classics/crc32.c b/plugins/apihashing/python/classics/crc32.c
new file mode 100644
index 0000000..d7c6f7c
--- /dev/null
+++ b/plugins/apihashing/python/classics/crc32.c
@@ -0,0 +1,211 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * crc32.c - équivalent Python du fichier "plugins/apihashing/classics/crc32.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 "crc32.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+
+
+#include "../apihash.h"
+#include "../../classics/crc32.h"
+
+
+
+CREATE_DYN_CONSTRUCTOR(scan_crc32_modifier, G_TYPE_SCAN_CRC32_MODIFIER);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_scan_crc32_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_crc32_modifier_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ int ret; /* Bilan de lecture des args. */
+
+#define SCAN_CRC32_MODIFIER_DOC \
+ "The *Crc32Modifier* class transforms a byte pattern into its" \
+ " crc32 encoded form.\n" \
+ "\n" \
+ "Instances can be created using the following constructor:\n" \
+ "\n" \
+ " Crc32Modifier()"
+
+ /* 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_crc32_modifier_type(void)
+{
+ static PyMethodDef py_scan_crc32_modifier_methods[] = {
+ { NULL }
+ };
+
+ static PyGetSetDef py_scan_crc32_modifier_getseters[] = {
+ { NULL }
+ };
+
+ static PyTypeObject py_scan_crc32_modifier_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.analysis.scan.patterns.modifiers.Crc32Modifier",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+ .tp_doc = SCAN_CRC32_MODIFIER_DOC,
+
+ .tp_methods = py_scan_crc32_modifier_methods,
+ .tp_getset = py_scan_crc32_modifier_getseters,
+
+ .tp_init = py_scan_crc32_modifier_init,
+ .tp_new = py_scan_crc32_modifier_new,
+
+ };
+
+ return &py_scan_crc32_modifier_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Prend en charge l'objet 'pychrysalide....Crc32Modifier'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool ensure_python_scan_crc32_modifier_is_registered(void)
+{
+ PyTypeObject *type; /* Type Python Crc32Modifier */
+ PyObject *module; /* Module à recompléter */
+ PyObject *dict; /* Dictionnaire du module */
+
+ type = get_python_scan_crc32_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_CRC32_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 crc32. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_scan_crc32_modifier(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_scan_crc32_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 crc32 modifier");
+ break;
+
+ case 1:
+ *((GScanCrc32Modifier **)dst) = G_SCAN_CRC32_MODIFIER(pygobject_get(arg));
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/apihashing/python/classics/crc32.h b/plugins/apihashing/python/classics/crc32.h
new file mode 100644
index 0000000..118a916
--- /dev/null
+++ b/plugins/apihashing/python/classics/crc32.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * crc32.h - équivalent Python du fichier "plugins/apihashing/classics/crc32.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_CLASSICS_CRC32_H
+#define _PLUGINS_APIHASHING_PYTHON_CLASSICS_CRC32_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_scan_crc32_modifier_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.scan.patterns.modifiers.Crc32Modifier'. */
+bool ensure_python_scan_crc32_modifier_is_registered(void);
+
+/* Tente de convertir en transformation en empreinte crc32. */
+int convert_to_scan_crc32_modifier(PyObject *, void *);
+
+
+
+#endif /* _PLUGINS_APIHASHING_PYTHON_CLASSICS_CRC32_H */
diff --git a/plugins/apihashing/python/classics/djb2.c b/plugins/apihashing/python/classics/djb2.c
new file mode 100644
index 0000000..f3d0844
--- /dev/null
+++ b/plugins/apihashing/python/classics/djb2.c
@@ -0,0 +1,211 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * djb2.c - équivalent Python du fichier "plugins/apihashing/classics/djb2.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 "djb2.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+
+
+#include "../apihash.h"
+#include "../../classics/djb2.h"
+
+
+
+CREATE_DYN_CONSTRUCTOR(scan_djb2_modifier, G_TYPE_SCAN_DJB2_MODIFIER);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_scan_djb2_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_djb2_modifier_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ int ret; /* Bilan de lecture des args. */
+
+#define SCAN_DJB2_MODIFIER_DOC \
+ "The *Djb2Modifier* class transforms a byte pattern into its" \
+ " djb2 encoded form.\n" \
+ "\n" \
+ "Instances can be created using the following constructor:\n" \
+ "\n" \
+ " Djb2Modifier()"
+
+ /* 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_djb2_modifier_type(void)
+{
+ static PyMethodDef py_scan_djb2_modifier_methods[] = {
+ { NULL }
+ };
+
+ static PyGetSetDef py_scan_djb2_modifier_getseters[] = {
+ { NULL }
+ };
+
+ static PyTypeObject py_scan_djb2_modifier_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.analysis.scan.patterns.modifiers.Djb2Modifier",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+ .tp_doc = SCAN_DJB2_MODIFIER_DOC,
+
+ .tp_methods = py_scan_djb2_modifier_methods,
+ .tp_getset = py_scan_djb2_modifier_getseters,
+
+ .tp_init = py_scan_djb2_modifier_init,
+ .tp_new = py_scan_djb2_modifier_new,
+
+ };
+
+ return &py_scan_djb2_modifier_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Prend en charge l'objet 'pychrysalide....Djb2Modifier'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool ensure_python_scan_djb2_modifier_is_registered(void)
+{
+ PyTypeObject *type; /* Type Python Djb2Modifier */
+ PyObject *module; /* Module à recompléter */
+ PyObject *dict; /* Dictionnaire du module */
+
+ type = get_python_scan_djb2_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_DJB2_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 djb2. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_scan_djb2_modifier(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_scan_djb2_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 djb2 modifier");
+ break;
+
+ case 1:
+ *((GScanDjb2Modifier **)dst) = G_SCAN_DJB2_MODIFIER(pygobject_get(arg));
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/apihashing/python/classics/djb2.h b/plugins/apihashing/python/classics/djb2.h
new file mode 100644
index 0000000..b4086f8
--- /dev/null
+++ b/plugins/apihashing/python/classics/djb2.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * djb2.h - équivalent Python du fichier "plugins/apihashing/classics/djb2.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_CLASSICS_DJB2_H
+#define _PLUGINS_APIHASHING_PYTHON_CLASSICS_DJB2_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_scan_djb2_modifier_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.scan.patterns.modifiers.Djb2Modifier'. */
+bool ensure_python_scan_djb2_modifier_is_registered(void);
+
+/* Tente de convertir en transformation en empreinte djb2. */
+int convert_to_scan_djb2_modifier(PyObject *, void *);
+
+
+
+#endif /* _PLUGINS_APIHASHING_PYTHON_CLASSICS_DJB2_H */
diff --git a/plugins/apihashing/python/classics/module.c b/plugins/apihashing/python/classics/module.c
new file mode 100644
index 0000000..b00757a
--- /dev/null
+++ b/plugins/apihashing/python/classics/module.c
@@ -0,0 +1,68 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire classics en tant que module
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "module.h"
+
+
+#include <assert.h>
+#include <Python.h>
+
+
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+
+
+#include "crc32.h"
+#include "djb2.h"
+#include "ror13.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Intègre les modificateurs d'empreintes classiques pour ROST. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool register_apihashing_classics_modifiers(void)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+ if (result) result = ensure_python_scan_crc32_modifier_is_registered();
+ if (result) result = ensure_python_scan_djb2_modifier_is_registered();
+ if (result) result = ensure_python_scan_ror13_modifier_is_registered();
+
+ assert(result);
+
+ return result;
+
+}
diff --git a/plugins/apihashing/python/classics/module.h b/plugins/apihashing/python/classics/module.h
new file mode 100644
index 0000000..10c817d
--- /dev/null
+++ b/plugins/apihashing/python/classics/module.h
@@ -0,0 +1,38 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire classics en tant que module
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef _PLUGINS_APIHASHING_PYTHON_CLASSICS_MODULE_H
+#define _PLUGINS_APIHASHING_PYTHON_CLASSICS_MODULE_H
+
+
+#include <stdbool.h>
+
+
+
+/* Intègre les modificateurs d'empreintes classiques pour ROST. */
+bool register_apihashing_classics_modifiers(void);
+
+
+
+#endif /* _PLUGINS_APIHASHING_PYTHON_CLASSICS_MODULE_H */
diff --git a/plugins/apihashing/python/classics/ror13.c b/plugins/apihashing/python/classics/ror13.c
new file mode 100644
index 0000000..429f7da
--- /dev/null
+++ b/plugins/apihashing/python/classics/ror13.c
@@ -0,0 +1,211 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * ror13.c - équivalent Python du fichier "plugins/apihashing/classics/ror13.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 "ror13.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+
+
+#include "../apihash.h"
+#include "../../classics/ror13.h"
+
+
+
+CREATE_DYN_CONSTRUCTOR(scan_ror13_modifier, G_TYPE_SCAN_ROR13_MODIFIER);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_scan_ror13_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_ror13_modifier_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ int ret; /* Bilan de lecture des args. */
+
+#define SCAN_ROR13_MODIFIER_DOC \
+ "The *Ror13Modifier* class transforms a byte pattern into its" \
+ " ror13 encoded form.\n" \
+ "\n" \
+ "Instances can be created using the following constructor:\n" \
+ "\n" \
+ " Ror13Modifier()"
+
+ /* 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_ror13_modifier_type(void)
+{
+ static PyMethodDef py_scan_ror13_modifier_methods[] = {
+ { NULL }
+ };
+
+ static PyGetSetDef py_scan_ror13_modifier_getseters[] = {
+ { NULL }
+ };
+
+ static PyTypeObject py_scan_ror13_modifier_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.analysis.scan.patterns.modifiers.Ror13Modifier",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+ .tp_doc = SCAN_ROR13_MODIFIER_DOC,
+
+ .tp_methods = py_scan_ror13_modifier_methods,
+ .tp_getset = py_scan_ror13_modifier_getseters,
+
+ .tp_init = py_scan_ror13_modifier_init,
+ .tp_new = py_scan_ror13_modifier_new,
+
+ };
+
+ return &py_scan_ror13_modifier_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Prend en charge l'objet 'pychrysalide....Ror13Modifier'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool ensure_python_scan_ror13_modifier_is_registered(void)
+{
+ PyTypeObject *type; /* Type Python Ror13Modifier */
+ PyObject *module; /* Module à recompléter */
+ PyObject *dict; /* Dictionnaire du module */
+
+ type = get_python_scan_ror13_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_ROR13_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 ror13. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_scan_ror13_modifier(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_scan_ror13_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 ror13 modifier");
+ break;
+
+ case 1:
+ *((GScanRor13Modifier **)dst) = G_SCAN_ROR13_MODIFIER(pygobject_get(arg));
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/apihashing/python/classics/ror13.h b/plugins/apihashing/python/classics/ror13.h
new file mode 100644
index 0000000..021a516
--- /dev/null
+++ b/plugins/apihashing/python/classics/ror13.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * ror13.h - équivalent Python du fichier "plugins/apihashing/classics/ror13.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_CLASSICS_ROR13_H
+#define _PLUGINS_APIHASHING_PYTHON_CLASSICS_ROR13_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_scan_ror13_modifier_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.scan.patterns.modifiers.Ror13Modifier'. */
+bool ensure_python_scan_ror13_modifier_is_registered(void);
+
+/* Tente de convertir en transformation en empreinte ror13. */
+int convert_to_scan_ror13_modifier(PyObject *, void *);
+
+
+
+#endif /* _PLUGINS_APIHASHING_PYTHON_CLASSICS_ROR13_H */
diff --git a/plugins/apihashing/python/custom/Makefile.am b/plugins/apihashing/python/custom/Makefile.am
new file mode 100644
index 0000000..5fbb11f
--- /dev/null
+++ b/plugins/apihashing/python/custom/Makefile.am
@@ -0,0 +1,20 @@
+
+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 \
+ 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
+
+
+devdir = $(includedir)/chrysalide-$(subdir)
+
+dev_HEADERS = $(libapihashingpythoncustom_la_SOURCES:%c=)
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
new file mode 100644
index 0000000..07107dd
--- /dev/null
+++ b/plugins/apihashing/python/custom/module.c
@@ -0,0 +1,76 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire custom en tant que module
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "module.h"
+
+
+#include <assert.h>
+#include <Python.h>
+
+
+#include <plugins/pychrysalide/access.h>
+#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"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Intègre les modificateurs d'empreintes particulières à ROST. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool register_apihashing_custom_modifiers(void)
+{
+ bool result; /* Bilan à retourner */
+
+ 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);
+
+ return result;
+
+}
diff --git a/plugins/apihashing/python/custom/module.h b/plugins/apihashing/python/custom/module.h
new file mode 100644
index 0000000..9073651
--- /dev/null
+++ b/plugins/apihashing/python/custom/module.h
@@ -0,0 +1,38 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire custom en tant que module
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef _PLUGINS_APIHASHING_PYTHON_CUSTOM_MODULE_H
+#define _PLUGINS_APIHASHING_PYTHON_CUSTOM_MODULE_H
+
+
+#include <stdbool.h>
+
+
+
+/* Intègre les modificateurs d'empreintes particulières à ROST. */
+bool register_apihashing_custom_modifiers(void);
+
+
+
+#endif /* _PLUGINS_APIHASHING_PYTHON_CUSTOM_MODULE_H */
diff --git a/plugins/apihashing/python/custom/sll1-add-hash32.c b/plugins/apihashing/python/custom/sll1-add-hash32.c
new file mode 100644
index 0000000..c63fcf3
--- /dev/null
+++ b/plugins/apihashing/python/custom/sll1-add-hash32.c
@@ -0,0 +1,211 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * sll1-add-hash32.c - équivalent Python du fichier "plugins/apihashing/custom/sll1-add-hash32.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 "sll1-add-hash32.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+
+
+#include "../apihash.h"
+#include "../../custom/sll1-add-hash32.h"
+
+
+
+CREATE_DYN_CONSTRUCTOR(scan_sll1_add_hash32_modifier, G_TYPE_SCAN_SLL1_ADD_HASH32_MODIFIER);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_scan_sll1_add_hash32_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_sll1_add_hash32_modifier_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ int ret; /* Bilan de lecture des args. */
+
+#define SCAN_SLL1_ADD_HASH32_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_sll1_add_hash32_modifier_type(void)
+{
+ static PyMethodDef py_scan_sll1_add_hash32_modifier_methods[] = {
+ { NULL }
+ };
+
+ static PyGetSetDef py_scan_sll1_add_hash32_modifier_getseters[] = {
+ { NULL }
+ };
+
+ static PyTypeObject py_scan_sll1_add_hash32_modifier_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.analysis.scan.patterns.modifiers.Sll1AddHash32Modifier",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+ .tp_doc = SCAN_SLL1_ADD_HASH32_MODIFIER_DOC,
+
+ .tp_methods = py_scan_sll1_add_hash32_modifier_methods,
+ .tp_getset = py_scan_sll1_add_hash32_modifier_getseters,
+
+ .tp_init = py_scan_sll1_add_hash32_modifier_init,
+ .tp_new = py_scan_sll1_add_hash32_modifier_new,
+
+ };
+
+ return &py_scan_sll1_add_hash32_modifier_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Prend en charge l'objet '...Sll1AddHash32Modifier'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool ensure_python_scan_sll1_add_hash32_modifier_is_registered(void)
+{
+ PyTypeObject *type; /* Type Sll1AddHash32Modifier */
+ PyObject *module; /* Module à recompléter */
+ PyObject *dict; /* Dictionnaire du module */
+
+ type = get_python_scan_sll1_add_hash32_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_SLL1_ADD_HASH32_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 sll1-add-hash32. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_scan_sll1_add_hash32_modifier(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_scan_sll1_add_hash32_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 sll1-add-hash32 modifier");
+ break;
+
+ case 1:
+ *((GScanSll1AddHash32Modifier **)dst) = G_SCAN_SLL1_ADD_HASH32_MODIFIER(pygobject_get(arg));
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/apihashing/python/custom/sll1-add-hash32.h b/plugins/apihashing/python/custom/sll1-add-hash32.h
new file mode 100644
index 0000000..bf11c34
--- /dev/null
+++ b/plugins/apihashing/python/custom/sll1-add-hash32.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * sll1-add-hash32.h - équivalent Python du fichier "plugins/apihashing/custom/sll1-add-hash32.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_SLL1_ADD_HASH32_H
+#define _PLUGINS_APIHASHING_PYTHON_CUSTOM_SLL1_ADD_HASH32_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_scan_sll1_add_hash32_modifier_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.scan.patterns.modifiers.Sll1AddHash32Modifier'. */
+bool ensure_python_scan_sll1_add_hash32_modifier_is_registered(void);
+
+/* Tente de convertir en empreinte sll1-add-hash32. */
+int convert_to_scan_sll1_add_hash32_modifier(PyObject *, void *);
+
+
+
+#endif /* _PLUGINS_APIHASHING_PYTHON_CUSTOM_SLL1_ADD_HASH32_H */
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/plugins/apihashing/python/module.c b/plugins/apihashing/python/module.c
new file mode 100644
index 0000000..588a0d8
--- /dev/null
+++ b/plugins/apihashing/python/module.c
@@ -0,0 +1,87 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire apihashing en tant que module
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "module.h"
+
+
+#include <assert.h>
+#include <Python.h>
+
+
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+
+
+#include "apihash.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Ajoute le module 'plugins.apihashing' au module Python. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool add_apihashing_module_to_python_module(void)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *super; /* Module à compléter */
+ PyObject *module; /* Sous-module mis en place */
+
+#define PYCHRYSALIDE_PLUGINS_APIHASHING_DOC \
+ "apihashing is a module providing a few implementations" \
+ " of algorithms used to resolve API functions by hash."
+
+ static PyModuleDef py_chrysalide_apihashing_module = {
+
+ .m_base = PyModuleDef_HEAD_INIT,
+
+ .m_name = "pychrysalide.plugins.apihashing",
+ .m_doc = PYCHRYSALIDE_PLUGINS_APIHASHING_DOC,
+
+ .m_size = -1,
+
+ };
+
+ result = false;
+
+ super = get_access_to_python_module("pychrysalide.plugins");
+
+ module = build_python_module(super, &py_chrysalide_apihashing_module);
+
+ result = (module != NULL);
+
+ if (result) result = ensure_python_api_hash_modifier_is_registered();
+
+ assert(result);
+
+ return result;
+
+}
diff --git a/plugins/apihashing/python/module.h b/plugins/apihashing/python/module.h
new file mode 100644
index 0000000..fe628b9
--- /dev/null
+++ b/plugins/apihashing/python/module.h
@@ -0,0 +1,38 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire apihashing en tant que module
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef _PLUGINS_APIHASHING_PYTHON_MODULE_H
+#define _PLUGINS_APIHASHING_PYTHON_MODULE_H
+
+
+#include <stdbool.h>
+
+
+
+/* Ajoute le module 'plugins.apihashing' au module Python. */
+bool add_apihashing_module_to_python_module(void);
+
+
+
+#endif /* _PLUGINS_APIHASHING_PYTHON_MODULE_H */
diff --git a/plugins/dalvik/context.c b/plugins/dalvik/context.c
index b08678c..9cf878b 100644
--- a/plugins/dalvik/context.c
+++ b/plugins/dalvik/context.c
@@ -373,7 +373,7 @@ bool g_dalvik_context_register_array_data_padding(GDalvikContext *ctx, const vmp
* *
******************************************************************************/
-GArchInstruction *g_dalvik_context_get_raw_data(GDalvikContext *ctx, const GBinContent *content, vmpa2t *pos)
+GArchInstruction *g_dalvik_context_get_raw_data(GDalvikContext *ctx, GBinContent *content, vmpa2t *pos)
{
GArchInstruction *result; /* Instruction à retourner */
raw_data_area *found; /* Zone de couverture trouvée */
@@ -390,7 +390,7 @@ GArchInstruction *g_dalvik_context_get_raw_data(GDalvikContext *ctx, const GBinC
if (found)
{
- restricted = g_restricted_content_new_ro(content, &found->range);
+ restricted = g_restricted_content_new(content, &found->range);
length = get_mrange_length(&found->range);
count = length / found->item_len;
diff --git a/plugins/dalvik/context.h b/plugins/dalvik/context.h
index bfa2757..f09cfa6 100644
--- a/plugins/dalvik/context.h
+++ b/plugins/dalvik/context.h
@@ -67,7 +67,7 @@ bool g_dalvik_context_register_array_data(GDalvikContext *, const vmpa2t *, uint
bool g_dalvik_context_register_array_data_padding(GDalvikContext *, const vmpa2t *);
/* Place une donnée en tant qu'instruction si besoin est. */
-GArchInstruction *g_dalvik_context_get_raw_data(GDalvikContext *, const GBinContent *, vmpa2t *);
+GArchInstruction *g_dalvik_context_get_raw_data(GDalvikContext *, GBinContent *, vmpa2t *);
diff --git a/plugins/encodings/Makefile.am b/plugins/encodings/Makefile.am
new file mode 100644
index 0000000..6dd71fb
--- /dev/null
+++ b/plugins/encodings/Makefile.am
@@ -0,0 +1,64 @@
+
+lib_LTLIBRARIES = libencodings.la
+
+libdir = $(pluginslibdir)
+
+
+if BUILD_PYTHON_PACKAGE
+
+RUN_PATH = -Wl,-rpath,'$$ORIGIN/../chrysalide-libs:$$ORIGIN'
+
+else
+
+RUN_PATH = -Wl,-rpath,'$$ORIGIN'
+
+endif
+
+if BUILD_PYTHON3_BINDINGS
+
+PYTHON3_LIBADD = python/libencodingspython.la
+
+if BUILD_DISCARD_LOCAL
+
+if BUILD_PYTHON_PACKAGE
+PYTHON3_RUN_PATH = -Wl,-rpath,'$$ORIGIN/..'
+else
+PYTHON3_RUN_PATH = -Wl,-rpath,'$$ORIGIN'
+endif
+
+else
+
+PYTHON3_RUN_PATH = -Wl,-rpath,$(abs_top_srcdir)/plugins/pychrysalide/.libs
+
+endif
+
+PYTHON3_LDFLAGS = $(PYTHON3_RUN_PATH) -L$(top_srcdir)/plugins/pychrysalide/.libs -l:pychrysalide.so
+
+PYTHON3_SUBDIRS = python
+
+endif
+
+
+libencodings_la_SOURCES = \
+ base64.h base64.c \
+ core.h core.c
+
+libencodings_la_LIBADD = \
+ $(PYTHON3_LIBADD) \
+ rost/libencodingsrost.la
+
+libencodings_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) -I$(top_srcdir)/src
+
+libencodings_la_LDFLAGS = \
+ -avoid-version \
+ -L$(top_srcdir)/src/.libs -lchrysacore \
+ -L$(top_srcdir)/plugins/pe/.libs -lpe \
+ $(RUN_PATH) $(PYTHON3_LDFLAGS)
+
+
+devdir = $(includedir)/chrysalide/$(subdir)
+
+dev_HEADERS = $(libencodings_la_SOURCES:%c=)
+
+
+SUBDIRS = $(PYTHON3_SUBDIRS) rost
diff --git a/plugins/encodings/base64.c b/plugins/encodings/base64.c
new file mode 100644
index 0000000..c749a87
--- /dev/null
+++ b/plugins/encodings/base64.c
@@ -0,0 +1,139 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * base64.c - calculs d'encodages en base 64
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "base64.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : input = données d'entrée à traiter. *
+* output = données sortantes constituées. [OUT] *
+* alphabet = alphabet d'encodage mis à disposition. *
+* *
+* Description : Procède à l'encodage d'un contenu en base 64. *
+* *
+* Retour : Bilan de l'opération : true en cas de réussite, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool _base64_encode(const sized_binary_t *input, sized_string_t *output, const sized_string_t *alphabet)
+{
+ bool result; /* Bilan à retourner */
+ const bin_t *src; /* Tête de lecture #1 */
+ const bin_t *alpha; /* Tête de lecture #2 */
+ bin_t *iter; /* Tête d'écriture */
+ size_t i; /* Boucle de parcours */
+
+ result = (alphabet->len == 64);
+ if (!result) goto exit;
+
+ /* Création du réceptacle */
+
+ output->len = input->len * 4 / 3;
+
+ if (output->len % 4 != 0)
+ output->len += (4 - output->len % 4);
+
+ output->data = malloc((output->len + 1) * sizeof(bin_t));
+
+ /* Encodage du corps du message */
+
+ src = input->static_bin_data;
+ alpha = alphabet->static_bin_data;
+
+ iter = output->bin_data;
+
+ if (input->len > 2)
+ for (i = 0; i < (input->len - 2); i += 3)
+ {
+ *iter++ = alpha[(src[i] >> 2) & 0x3f];
+
+ *iter++ = alpha[((src[i] & 0x03) << 4) | ((src[i + 1] & 0xf0) >> 4)];
+
+ *iter++ = alpha[((src[i + 1] & 0x0f) << 2) | ((src[i + 2] & 0xc0) >> 6)];
+
+ *iter++ = alpha[src[i + 2] & 0x3f];
+
+ }
+ else
+ i = 0;
+
+ /* Bourrage final ? */
+
+ if (i < input->len)
+ {
+ *iter++ = alpha[(src[i] >> 2) & 0x3f];
+
+ if (i == (input->len - 1))
+ {
+ *iter++ = alpha[((src[i] & 0x03) << 4)];
+ *iter++ = '=';
+ }
+ else
+ {
+ *iter++ = alpha[((src[i] & 0x03) << 4) | ((src[i + 1] & 0xf0) >> 4)];
+ *iter++ = alpha[((src[i + 1] & 0x0f) << 2)];
+ }
+
+ *iter++ = '=';
+ }
+
+ *iter = 0x00;
+
+ exit:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : input = données d'entrée à traiter. *
+* output = données sortantes constituées. [OUT] *
+* *
+* Description : Procède à l'encodage par défaut d'un contenu en base 64. *
+* *
+* Retour : Bilan de l'opération : true en cas de réussite, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool base64_encode(const sized_binary_t *input, sized_string_t *output)
+{
+ bool result; /* Bilan à retourner */
+
+ const sized_string_t alphabet = {
+ .static_data = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
+ .len = 64
+ };
+
+ result = _base64_encode(input, output, &alphabet);
+
+ return result;
+
+}
diff --git a/plugins/encodings/base64.h b/plugins/encodings/base64.h
new file mode 100644
index 0000000..64ddccd
--- /dev/null
+++ b/plugins/encodings/base64.h
@@ -0,0 +1,43 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * base64.h - prototypes pour les calculs d'encodages en base 64
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _PLUGINS_ENCODINGS_BASE64_H
+#define _PLUGINS_ENCODINGS_BASE64_H
+
+
+#include <stdbool.h>
+
+
+#include <common/szstr.h>
+
+
+
+/* Procède à l'encodage d'un contenu en base 64. */
+bool _base64_encode(const sized_binary_t *, sized_string_t *, const sized_string_t *);
+
+/* Procède à l'encodage par défaut d'un contenu en base 64. */
+bool base64_encode(const sized_binary_t *, sized_string_t *);
+
+
+
+#endif /* _PLUGINS_ENCODINGS_BASE64_H */
diff --git a/plugins/encodings/core.c b/plugins/encodings/core.c
new file mode 100644
index 0000000..2ece208
--- /dev/null
+++ b/plugins/encodings/core.c
@@ -0,0 +1,89 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * core.c - prototypes pour le calcul d'encodages
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "core.h"
+
+
+#include <analysis/scan/core.h>
+#include <plugins/self.h>
+
+
+#ifdef INCLUDE_PYTHON3_BINDINGS
+# include "python/module.h"
+# include "python/rost/module.h"
+#endif
+#include "rost/base64.h"
+
+
+#ifdef INCLUDE_PYTHON3_BINDINGS_
+# define PG_REQ RL("PyChrysalide")
+#else
+# define PG_REQ NO_REQ
+#endif
+
+
+
+DEFINE_CHRYSALIDE_PLUGIN("Encodings", "Special encoding methods for binaries",
+ PACKAGE_VERSION, CHRYSALIDE_WEBSITE("doc/formats"),
+ PG_REQ, AL(PGA_PLUGIN_INIT));
+
+
+
+/******************************************************************************
+* *
+* Paramètres : plugin = greffon à manipuler. *
+* *
+* Description : Prend acte du chargement du greffon. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin)
+{
+ bool result; /* Bilan à retourner */
+ GScanTokenModifier *modifier; /* Modificateur à enregistrer */
+
+ modifier = g_scan_base64_modifier_new();
+
+ result = register_scan_token_modifier(modifier);
+
+ g_object_unref(G_OBJECT(modifier));
+
+ if (!result) goto exit;
+
+#ifdef INCLUDE_PYTHON3_BINDINGS
+
+ result = add_encodings_module_to_python_module();
+
+ if (result)
+ result = register_encodings_rost_modifiers();
+#endif
+
+ exit:
+
+ return result;
+
+}
diff --git a/plugins/encodings/core.h b/plugins/encodings/core.h
new file mode 100644
index 0000000..75a6e73
--- /dev/null
+++ b/plugins/encodings/core.h
@@ -0,0 +1,38 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * core.h - prototypes pour le calcul d'encodages
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _PLUGINS_ENCODINGS_CORE_H
+#define _PLUGINS_ENCODINGS_CORE_H
+
+
+#include <plugins/plugin.h>
+#include <plugins/plugin-int.h>
+
+
+
+/* Prend acte du chargement du greffon. */
+G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *);
+
+
+
+#endif /* _PLUGINS_ENCODINGS_CORE_H */
diff --git a/plugins/encodings/python/Makefile.am b/plugins/encodings/python/Makefile.am
new file mode 100644
index 0000000..523a6f4
--- /dev/null
+++ b/plugins/encodings/python/Makefile.am
@@ -0,0 +1,21 @@
+
+noinst_LTLIBRARIES = libencodingspython.la
+
+libencodingspython_la_SOURCES = \
+ base64.h base64.c \
+ module.h module.c
+
+libencodingspython_la_LIBADD = \
+ rost/libencodingspythonrost.la
+
+libencodingspython_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) \
+ $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+ -I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
+
+
+devdir = $(includedir)/chrysalide/$(subdir)
+
+dev_HEADERS = $(libencodingspython_la_SOURCES:%c=)
+
+
+SUBDIRS = rost
diff --git a/plugins/encodings/python/base64.c b/plugins/encodings/python/base64.c
new file mode 100644
index 0000000..3bc84a2
--- /dev/null
+++ b/plugins/encodings/python/base64.c
@@ -0,0 +1,139 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * base64.c - équivalent Python du fichier "plugins/encodings/base64.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 "base64.h"
+
+
+#include <pygobject.h>
+
+
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+
+
+#include "../base64.h"
+
+
+
+/* Procède à l'encodage d'un contenu en base 64. */
+static PyObject *py_encodings_base64_encode(PyObject *, PyObject *);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* args = paramètre à récupérer pour le traitement. *
+* *
+* Description : Procède à l'encodage d'un contenu en base 64. *
+* *
+* Retour : None ou données sortantes constituées. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_encodings_base64_encode(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Valeur à retourner */
+ sized_string_t alphabet; /* Alphabet de traitement ? */
+ Py_ssize_t alen; /* Taille de cet alphabet */
+ sized_binary_t input; /* Données à traiter */
+ Py_ssize_t ilen; /* Quantité de ces données */
+ int ret; /* Bilan de lecture des args. */
+ sized_string_t output; /* Données encodées à exporter */
+ bool status; /* Bilan de l'opération */
+
+#define ENCODINGS_BASE64_ENCODE_METHOD PYTHON_METHOD_DEF \
+( \
+ base64_encode, "input, /, alphabet=None", \
+ METH_VARARGS, py_encodings, \
+ "Encode a given content using Base64.\n" \
+ "\n" \
+ "The *input* argument has to be provided as bytes. The optional" \
+ " *alphabet* is expected to be a 64-byte array if defined.\n" \
+ "\n" \
+ "The returned value is bytes or *None* in case of error." \
+)
+
+ result = NULL;
+
+ alphabet.data = NULL;
+ alen = 0;
+
+ ret = PyArg_ParseTuple(args, "s#|s#", &input.static_data, &ilen, &alphabet.static_data, &alen);
+ if (!ret) goto exit;
+
+ alphabet.len = alen;
+ input.len = ilen;
+
+ if (alphabet.len > 0)
+ status = _base64_encode(&input, &output, &alphabet);
+ else
+ status = base64_encode(&input, &output);
+
+ if (status)
+ {
+ result = PyBytes_FromStringAndSize(output.data, output.len);
+ exit_szstr(&output);
+ }
+ else
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+
+ exit:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : super = module dont la définition est à compléter. *
+* *
+* Description : Définit une extension du module 'encodings' à compléter. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool populate_encodings_module_with_base64(PyObject *super)
+{
+ bool result; /* Bilan à retourner */
+
+ static PyMethodDef py_base64_methods[] = {
+ ENCODINGS_BASE64_ENCODE_METHOD,
+ { NULL }
+ };
+
+ result = register_python_module_methods(super, py_base64_methods);
+
+ return result;
+
+}
diff --git a/plugins/encodings/python/base64.h b/plugins/encodings/python/base64.h
new file mode 100644
index 0000000..1e08cf6
--- /dev/null
+++ b/plugins/encodings/python/base64.h
@@ -0,0 +1,39 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * base64.h - équivalent Python du fichier "plugins/encodings/base64.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_ENCODINGS_PYTHON_BASE64_H
+#define _PLUGINS_ENCODINGS_PYTHON_BASE64_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Définit une extension du module 'encodings' à compléter. */
+bool populate_encodings_module_with_base64(PyObject *);
+
+
+
+#endif /* _PLUGINS_ENCODINGS_PYTHON_BASE64_H */
diff --git a/plugins/encodings/python/module.c b/plugins/encodings/python/module.c
new file mode 100644
index 0000000..454159b
--- /dev/null
+++ b/plugins/encodings/python/module.c
@@ -0,0 +1,87 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire encodings en tant que module
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "module.h"
+
+
+#include <assert.h>
+#include <Python.h>
+
+
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+
+
+#include "base64.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Ajoute le module 'plugins.encodings' au module Python. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool add_encodings_module_to_python_module(void)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *super; /* Module à compléter */
+ PyObject *module; /* Sous-module mis en place */
+
+#define PYCHRYSALIDE_PLUGINS_ENCODINGS_DOC \
+ "encodings is a module providing a few implementations" \
+ " of algorithms used to encode data."
+
+ static PyModuleDef py_chrysalide_encodings_module = {
+
+ .m_base = PyModuleDef_HEAD_INIT,
+
+ .m_name = "pychrysalide.plugins.encodings",
+ .m_doc = PYCHRYSALIDE_PLUGINS_ENCODINGS_DOC,
+
+ .m_size = -1,
+
+ };
+
+ result = false;
+
+ super = get_access_to_python_module("pychrysalide.plugins");
+
+ module = build_python_module(super, &py_chrysalide_encodings_module);
+
+ result = (module != NULL);
+
+ if (result) result = populate_encodings_module_with_base64(module);
+
+ assert(result);
+
+ return result;
+
+}
diff --git a/plugins/encodings/python/module.h b/plugins/encodings/python/module.h
new file mode 100644
index 0000000..e7dd812
--- /dev/null
+++ b/plugins/encodings/python/module.h
@@ -0,0 +1,38 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire encodings en tant que module
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef _PLUGINS_ENCODINGS_PYTHON_MODULE_H
+#define _PLUGINS_ENCODINGS_PYTHON_MODULE_H
+
+
+#include <stdbool.h>
+
+
+
+/* Ajoute le module 'plugins.encodings' au module Python. */
+bool add_encodings_module_to_python_module(void);
+
+
+
+#endif /* _PLUGINS_ENCODINGS_PYTHON_MODULE_H */
diff --git a/plugins/encodings/python/rost/Makefile.am b/plugins/encodings/python/rost/Makefile.am
new file mode 100644
index 0000000..531fb26
--- /dev/null
+++ b/plugins/encodings/python/rost/Makefile.am
@@ -0,0 +1,15 @@
+
+noinst_LTLIBRARIES = libencodingspythonrost.la
+
+libencodingspythonrost_la_SOURCES = \
+ base64.h base64.c \
+ module.h module.c
+
+libencodingspythonrost_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) \
+ $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+ -I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
+
+
+devdir = $(includedir)/chrysalide-$(subdir)
+
+dev_HEADERS = $(libencodingspythonrost_la_SOURCES:%c=)
diff --git a/plugins/encodings/python/rost/base64.c b/plugins/encodings/python/rost/base64.c
new file mode 100644
index 0000000..57bba76
--- /dev/null
+++ b/plugins/encodings/python/rost/base64.c
@@ -0,0 +1,211 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * base64.c - équivalent Python du fichier "plugins/encodings/rost/base64.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 "base64.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+#include <plugins/pychrysalide/analysis/scan/patterns/modifier.h>
+
+
+#include "../../rost/base64.h"
+
+
+
+CREATE_DYN_CONSTRUCTOR(scan_base64_modifier, G_TYPE_SCAN_BASE64_MODIFIER);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_scan_base64_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_base64_modifier_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ int ret; /* Bilan de lecture des args. */
+
+#define SCAN_BASE64_MODIFIER_DOC \
+ "The *Base64Modifier* class transforms a byte pattern into its" \
+ " base64 encoded form.\n" \
+ "\n" \
+ "Instances can be created using the following constructor:\n" \
+ "\n" \
+ " Base64Modifier()"
+
+ /* 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_base64_modifier_type(void)
+{
+ static PyMethodDef py_scan_base64_modifier_methods[] = {
+ { NULL }
+ };
+
+ static PyGetSetDef py_scan_base64_modifier_getseters[] = {
+ { NULL }
+ };
+
+ static PyTypeObject py_scan_base64_modifier_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.analysis.scan.patterns.modifiers.Base64Modifier",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+ .tp_doc = SCAN_BASE64_MODIFIER_DOC,
+
+ .tp_methods = py_scan_base64_modifier_methods,
+ .tp_getset = py_scan_base64_modifier_getseters,
+
+ .tp_init = py_scan_base64_modifier_init,
+ .tp_new = py_scan_base64_modifier_new,
+
+ };
+
+ return &py_scan_base64_modifier_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Prend en charge l'objet 'pychrysalide....Base64Modifier'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool ensure_python_scan_base64_modifier_is_registered(void)
+{
+ PyTypeObject *type; /* Type Python Base64Modifier */
+ PyObject *module; /* Module à recompléter */
+ PyObject *dict; /* Dictionnaire du module */
+
+ type = get_python_scan_base64_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_scan_token_modifier_is_registered())
+ return false;
+
+ if (!register_class_for_pygobject(dict, G_TYPE_SCAN_BASE64_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 par encodage en Base64. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_scan_base64_modifier(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_scan_base64_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 Base64 modifier");
+ break;
+
+ case 1:
+ *((GScanBase64Modifier **)dst) = G_SCAN_BASE64_MODIFIER(pygobject_get(arg));
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/encodings/python/rost/base64.h b/plugins/encodings/python/rost/base64.h
new file mode 100644
index 0000000..0ef0834
--- /dev/null
+++ b/plugins/encodings/python/rost/base64.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * base64.h - équivalent Python du fichier "plugins/encodings/rost/base64.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_ENCODINGS_PYTHON_ROST_BASE64_H
+#define _PLUGINS_ENCODINGS_PYTHON_ROST_BASE64_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_scan_base64_modifier_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.scan.patterns.modifiers.Base64Modifier'. */
+bool ensure_python_scan_base64_modifier_is_registered(void);
+
+/* Tente de convertir en transformation par encodage en Base64. */
+int convert_to_scan_base64_modifier(PyObject *, void *);
+
+
+
+#endif /* _PLUGINS_ENCODINGS_PYTHON_ROST_BASE64_H */
diff --git a/plugins/encodings/python/rost/module.c b/plugins/encodings/python/rost/module.c
new file mode 100644
index 0000000..4812bb5
--- /dev/null
+++ b/plugins/encodings/python/rost/module.c
@@ -0,0 +1,64 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire rost en tant que module
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "module.h"
+
+
+#include <assert.h>
+#include <Python.h>
+
+
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+
+
+#include "base64.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Intègre les modificateurs pour ROST. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool register_encodings_rost_modifiers(void)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+ if (result) result = ensure_python_scan_base64_modifier_is_registered();
+
+ assert(result);
+
+ return result;
+
+}
diff --git a/plugins/encodings/python/rost/module.h b/plugins/encodings/python/rost/module.h
new file mode 100644
index 0000000..ba021cb
--- /dev/null
+++ b/plugins/encodings/python/rost/module.h
@@ -0,0 +1,38 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire rost en tant que module
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef _PLUGINS_ENCODINGS_PYTHON_ROST_MODULE_H
+#define _PLUGINS_ENCODINGS_PYTHON_ROST_MODULE_H
+
+
+#include <stdbool.h>
+
+
+
+/* Intègre les modificateurs pour ROST. */
+bool register_encodings_rost_modifiers(void);
+
+
+
+#endif /* _PLUGINS_ENCODINGS_PYTHON_ROST_MODULE_H */
diff --git a/plugins/encodings/rost/Makefile.am b/plugins/encodings/rost/Makefile.am
new file mode 100644
index 0000000..efca690
--- /dev/null
+++ b/plugins/encodings/rost/Makefile.am
@@ -0,0 +1,12 @@
+
+noinst_LTLIBRARIES = libencodingsrost.la
+
+libencodingsrost_la_SOURCES = \
+ base64.h base64.c
+
+libencodingsrost_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) -I$(top_srcdir)/src
+
+
+devdir = $(includedir)/chrysalide-$(subdir)
+
+dev_HEADERS = $(libencodingsrost_la_SOURCES:%c=)
diff --git a/plugins/encodings/rost/base64.c b/plugins/encodings/rost/base64.c
new file mode 100644
index 0000000..adbb2fb
--- /dev/null
+++ b/plugins/encodings/rost/base64.c
@@ -0,0 +1,555 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * base64.c - transormation en encodage Base64
+ *
+ * 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 "base64.h"
+
+
+#include <assert.h>
+#include <malloc.h>
+#include <stdint.h>
+#include <string.h>
+
+
+#include <analysis/scan/patterns/modifier-int.h>
+
+
+#include "../base64.h"
+
+
+
+/* ----------------------- RECHERCHE D'UN MOTIF DE TEXTE BRUT ----------------------- */
+
+
+/* Initialise la classe des transmissions en encodage Base64. */
+static void g_scan_base64_modifier_class_init(GScanBase64ModifierClass *klass);
+
+/* Initialise une instance de transmission en encodage Base64. */
+static void g_scan_base64_modifier_init(GScanBase64Modifier *);
+
+/* Supprime toutes les références externes. */
+static void g_scan_base64_modifier_dispose(GScanBase64Modifier *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_scan_base64_modifier_finalize(GScanBase64Modifier *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Fournit le nom d'appel d'un modificateur pour motif. */
+static char *g_scan_base64_modifier_get_name(const GScanBase64Modifier *);
+
+/* Finalise l'encoddage en Base64 d'un motif transformé. */
+static void strip_base64_modifier_output(const sized_binary_t *, const sized_binary_t *, size_t, sized_binary_t *);
+
+/* Transforme une séquence d'octets pour motif de recherche. */
+static bool g_scan_base64_modifier_transform(const GScanBase64Modifier *, const sized_binary_t *, size_t, sized_binary_t **, size_t *);
+
+/* Détermine si un argument est bien toléré par un modificateur. */
+static bool g_scan_base64_modifier_can_handle_arg(const GScanBase64Modifier *, const modifier_arg_t *);
+
+/* Transforme une séquence d'octets pour motif de recherche. */
+static bool g_scan_base64_modifier_transform_with_arg(const GScanBase64Modifier *, const sized_binary_t *, size_t, const modifier_arg_t *, sized_binary_t **, size_t *);
+
+/* Retrouve l'origine d'une correspondance à partir d'un indice. */
+static char *g_scan_base64_modifier_get_path(const GScanBase64Modifier *, size_t *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* RECHERCHE D'UN MOTIF DE TEXTE BRUT */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une transormation en encodage Base64. */
+G_DEFINE_TYPE(GScanBase64Modifier, g_scan_base64_modifier, G_TYPE_SCAN_TOKEN_MODIFIER);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des transmissions en encodage Base64. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_base64_modifier_class_init(GScanBase64ModifierClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GScanTokenModifierClass *modifier; /* Version de classe parente */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_base64_modifier_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_scan_base64_modifier_finalize;
+
+ modifier = G_SCAN_TOKEN_MODIFIER_CLASS(klass);
+
+ modifier->get_name = (get_scan_modifier_name_fc)g_scan_base64_modifier_get_name;
+
+ modifier->transform = (transform_scan_token_fc)g_scan_base64_modifier_transform;
+ modifier->can_handle = (can_token_modifier_handle_arg)g_scan_base64_modifier_can_handle_arg;
+ modifier->transform_with = (transform_scan_token_with_fc)g_scan_base64_modifier_transform_with_arg;
+ modifier->get_path = (get_modifier_path)g_scan_base64_modifier_get_path;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : modifier = instance à initialiser. *
+* *
+* Description : Initialise une instance de transmission en encodage Base64. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_base64_modifier_init(GScanBase64Modifier *modifier)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : modifier = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_base64_modifier_dispose(GScanBase64Modifier *modifier)
+{
+ G_OBJECT_CLASS(g_scan_base64_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_base64_modifier_finalize(GScanBase64Modifier *modifier)
+{
+ G_OBJECT_CLASS(g_scan_base64_modifier_parent_class)->finalize(G_OBJECT(modifier));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Construit un modificateur livrant des encodages en Base64. *
+* *
+* Retour : Mécanisme mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GScanTokenModifier *g_scan_base64_modifier_new(void)
+{
+ GScanTokenModifier *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_SCAN_BASE64_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_base64_modifier_get_name(const GScanBase64Modifier *modifier)
+{
+ char *result; /* Désignation à retourner */
+
+ result = strdup("base64");
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : input = contenu brut d'origine. *
+* tmpput = encodage en Base64 intermédiaire obtenu. *
+* skip = nombre de caractères initiaux à sauter. *
+* output = encodage en Base64 final à conserver. *
+* *
+* Description : Finalise l'encoddage en Base64 d'un motif transformé. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void strip_base64_modifier_output(const sized_binary_t *input, const sized_binary_t *tmpput, size_t skip, sized_binary_t *output)
+{
+ size_t keep; /* Nombre d'octets immuables */
+
+ keep = (input->len * 8) / 6;
+
+ assert(keep >= skip);
+
+ if (skip > 0)
+ skip++;
+
+ keep -= skip;
+
+ output->len = keep;
+ output->bin_data = malloc(keep * sizeof(bin_t));
+
+ memcpy(output->bin_data, tmpput->static_bin_data + skip, keep);
+
+}
+
+
+/******************************************************************************
+* *
+* 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_base64_modifier_transform(const GScanBase64Modifier *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 */
+ sized_binary_t tmp_in; /* Manipulation des variations */
+ sized_binary_t tmp_out; /* Manipulation des variations */
+
+ result = true;
+
+ *dcount = scount * 3;
+ *dest = calloc(*dcount, sizeof(sized_binary_t));
+
+ binary = &(*dest)[0];
+
+ for (i = 0; i < scount && result; i++)
+ {
+ _src = src + i;
+
+ tmp_in.data = malloc((_src->len + 2) * sizeof(bin_t));
+
+ /**
+ * Explications sur la définition des modifications sur les
+ * encodages produits : https://www.leeholmes.com/searching-for-content-in-base-64-strings/
+ */
+
+ /* Encodage premier */
+
+ result = base64_encode(_src, &tmp_out);
+ if (!result) goto exit;
+
+ strip_base64_modifier_output(_src, &tmp_out, 0, binary++);
+
+ exit_szstr(&tmp_out);
+
+ /* Variante 1 */
+
+ tmp_in.data[0] = ' ';
+ memcpy(&tmp_in.data[1], _src->static_bin_data, _src->len);
+
+ tmp_in.len = _src->len + 1;
+
+ result = base64_encode(&tmp_in, &tmp_out);
+ if (!result) goto exit;
+
+ strip_base64_modifier_output(&tmp_in, &tmp_out, 1, binary);
+
+ /**
+ * Lors qu'un unique octet est encodé, cet octet ne produit aucun
+ * caractère que ne dépend que de lui :
+ *
+ * | X |
+ * 1 2 3 4 5 6 | 7 8 1 2 3 4 | 5 6 7 8 1 2 | 3 4 5 6 7 8
+ *
+ * Les compteurs sont alors diminués.
+ */
+
+ if (binary->len == 0)
+ (*dcount)--;
+ else
+ binary++;
+
+ exit_szstr(&tmp_out);
+
+ /* Variante 2 */
+
+ tmp_in.data[0] = ' ';
+ tmp_in.data[2] = ' ';
+ memcpy(&tmp_in.data[2], _src->static_bin_data, _src->len);
+
+ tmp_in.len = _src->len + 2;
+
+ result = base64_encode(&tmp_in, &tmp_out);
+ if (!result) goto exit;
+
+ strip_base64_modifier_output(&tmp_in, &tmp_out, 2, binary++);
+
+ exit_szstr(&tmp_out);
+
+ exit:
+
+ exit_szstr(&tmp_in);
+
+ }
+
+ if (!result)
+ {
+ for (i = 0; i < *dcount; i++)
+ exit_szstr(&(*dest)[i]);
+
+ free(*dest);
+
+ *dcount = 0;
+ *dest = NULL;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : modifier = modificateur à solliciter. *
+* arg = argument de personnalisation. *
+* *
+* Description : Détermine si un argument est bien toléré par un modificateur.*
+* *
+* Retour : Bilan de la consultation : support ou non. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_scan_base64_modifier_can_handle_arg(const GScanBase64Modifier *modifier, const modifier_arg_t *arg)
+{
+ bool result; /* Bilan d'opération à renvoyer*/
+
+ switch (arg->type)
+ {
+ case MAT_STRING:
+ result = (arg->value.string.len == 64);
+ break;
+
+ default:
+ result = false;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : modifier = modificateur à solliciter. *
+* src = séquences d'octets à traiter. *
+* scount = quantité de ces séquences. *
+* arg = argument de personnalisation. *
+* 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_base64_modifier_transform_with_arg(const GScanBase64Modifier *modifier, const sized_binary_t *src, size_t scount, const modifier_arg_t *arg, 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 */
+ sized_binary_t tmp_in; /* Manipulation des variations */
+ sized_binary_t tmp_out; /* Manipulation des variations */
+
+ result = (arg->type == MAT_STRING);
+ if (!result) goto bad_arg;
+
+ *dcount = scount * 3;
+ *dest = calloc(*dcount, sizeof(sized_binary_t));
+
+ binary = &(*dest)[0];
+
+ for (i = 0; i < scount && result; i++)
+ {
+ _src = src + i;
+
+ tmp_in.data = malloc((_src->len + 2) * sizeof(bin_t));
+
+ /**
+ * Explications sur la définition des modifications sur les
+ * encodages produits : https://www.leeholmes.com/searching-for-content-in-base-64-strings/
+ */
+
+ /* Encodage premier */
+
+ result = _base64_encode(_src, &tmp_out, &arg->value.string);
+ if (!result) goto exit;
+
+ strip_base64_modifier_output(_src, &tmp_out, 0, binary++);
+
+ exit_szstr(&tmp_out);
+
+ /* Variante 1 */
+
+ tmp_in.data[0] = ' ';
+ memcpy(&tmp_in.data[1], _src->static_bin_data, _src->len);
+
+ tmp_in.len = _src->len + 1;
+
+ result = _base64_encode(&tmp_in, &tmp_out, &arg->value.string);
+ if (!result) goto exit;
+
+ strip_base64_modifier_output(&tmp_in, &tmp_out, 1, binary++);
+
+ exit_szstr(&tmp_out);
+
+ /* Variante 2 */
+
+ tmp_in.data[0] = ' ';
+ tmp_in.data[2] = ' ';
+ memcpy(&tmp_in.data[2], _src->static_bin_data, _src->len);
+
+ tmp_in.len = _src->len + 2;
+
+ result = _base64_encode(&tmp_in, &tmp_out, &arg->value.string);
+ if (!result) goto exit;
+
+ strip_base64_modifier_output(&tmp_in, &tmp_out, 2, binary++);
+
+ exit_szstr(&tmp_out);
+
+ exit:
+
+ exit_szstr(&tmp_in);
+
+ }
+
+ if (!result)
+ {
+ for (i = 0; i < *dcount; i++)
+ exit_szstr(&(*dest)[i]);
+
+ free(*dest);
+
+ *dcount = 0;
+ *dest = NULL;
+
+ }
+
+ bad_arg:
+
+ 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_base64_modifier_get_path(const GScanBase64Modifier *modifier, size_t *index)
+{
+ char *result; /* Combinaison à retourner */
+
+ if (*index > 3)
+ {
+ result = NULL;
+ (*index) -= 3;
+ }
+
+ else
+ result = strdup("base64");
+
+ return result;
+
+}
diff --git a/plugins/encodings/rost/base64.h b/plugins/encodings/rost/base64.h
new file mode 100644
index 0000000..646b945
--- /dev/null
+++ b/plugins/encodings/rost/base64.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * base64.h - prototypes pour la transormation en encodage Base64
+ *
+ * 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_ENCODINGS_ROST_BASE64_H
+#define _PLUGINS_ENCODINGS_ROST_BASE64_H
+
+
+#include <glib-object.h>
+
+
+#include <analysis/scan/patterns/modifier.h>
+
+
+
+#define G_TYPE_SCAN_BASE64_MODIFIER g_scan_base64_modifier_get_type()
+#define G_SCAN_BASE64_MODIFIER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_BASE64_MODIFIER, GScanBase64Modifier))
+#define G_IS_SCAN_BASE64_MODIFIER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_BASE64_MODIFIER))
+#define G_SCAN_BASE64_MODIFIER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_BASE64_MODIFIER, GScanBase64ModifierClass))
+#define G_IS_SCAN_BASE64_MODIFIER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_BASE64_MODIFIER))
+#define G_SCAN_BASE64_MODIFIER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_BASE64_MODIFIER, GScanBase64ModifierClass))
+
+
+/* Transormation en encodage Base64 (instance) */
+typedef GScanTokenModifier GScanBase64Modifier;
+
+/* Transormation en encodage Base64 (classe) */
+typedef GScanTokenModifierClass GScanBase64ModifierClass;
+
+
+/* Indique le type défini pour une transormation en encodage Base64. */
+GType g_scan_base64_modifier_get_type(void);
+
+/* Construit un modificateur livrant des encodages en Base64. */
+GScanTokenModifier *g_scan_base64_modifier_new(void);
+
+
+
+#endif /* _PLUGINS_ENCODINGS_ROST_BASE64_H */
diff --git a/plugins/kaitai/Makefile.am b/plugins/kaitai/Makefile.am
index cbc0f25..9a4e112 100644
--- a/plugins/kaitai/Makefile.am
+++ b/plugins/kaitai/Makefile.am
@@ -54,6 +54,7 @@ libkaitai_la_SOURCES = \
array.h array.c \
core.h core.c \
expression.h \
+ import.h import.c \
parser-int.h \
parser.h parser.c \
record-int.h \
@@ -67,6 +68,7 @@ libkaitai_la_SOURCES = \
libkaitai_la_LIBADD = \
parsers/libkaitaiparsers.la \
records/libkaitairecords.la \
+ rost/libkaitairost.la \
$(PYTHON3_LIBADD)
libkaitai_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) -I$(top_srcdir)/src
@@ -88,5 +90,4 @@ CLEANFILES = grammar.h grammar.c grammar.output tokens.c tokens.h
EXTRA_DIST = tokens.h
-# misc
-SUBDIRS = parsers records $(PYTHON3_SUBDIRS)
+SUBDIRS = parsers records rost $(PYTHON3_SUBDIRS)
diff --git a/plugins/kaitai/core.c b/plugins/kaitai/core.c
index 7483fbc..c41d96d 100644
--- a/plugins/kaitai/core.c
+++ b/plugins/kaitai/core.c
@@ -30,6 +30,8 @@
#ifdef INCLUDE_PYTHON3_BINDINGS
# include "python/module.h"
#endif
+#include "rost/core.h"
+
#ifdef INCLUDE_PYTHON3_BINDINGS
@@ -62,7 +64,7 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin)
{
bool result; /* Bilan à retourner */
- result = true;
+ result = add_kaitai_support_to_rost();
#ifdef INCLUDE_PYTHON3_BINDINGS
diff --git a/plugins/kaitai/grammar.y b/plugins/kaitai/grammar.y
index 9e31113..9745dc8 100644
--- a/plugins/kaitai/grammar.y
+++ b/plugins/kaitai/grammar.y
@@ -31,9 +31,10 @@ typedef void *yyscan_t;
#include "expression.h"
#include "record.h"
+#include "records/bits.h"
+#include "records/delayed.h"
#include "records/item.h"
#include "records/list.h"
-#include "records/value.h"
}
@@ -580,7 +581,9 @@ YY_DECL;
%token ROOT "_root"
%token PARENT "_parent"
%token LAST "_"
+%token IO "_io"
%token METH_IO "._io"
+%token IO_EOF ".eof"
%token TRUE_CONST "true"
%token FALSE_CONST "false"
@@ -622,6 +625,7 @@ YY_DECL;
%type <value> field
%type <value> enumeration
%type <value> stream
+%type <value> stream_meths
@@ -714,6 +718,7 @@ YY_DECL;
| field { $$ = $1; }
| enumeration { $$ = $1; }
| stream { $$ = $1; }
+ | stream_meths { $$ = $1; }
| arithmetic_expr { $$ = $1; }
| relational_expr { $$ = $1; }
| logical_expr { $$ = $1; }
@@ -1487,7 +1492,35 @@ YY_DECL;
}
- stream : any_expr "._io"
+ stream : "_io"
+ {
+ GBinContent *__content;
+ mrange_t __range;
+ vmpa2t __next;
+
+ if (locals->last == NULL)
+ {
+ __content = g_match_record_get_content(locals->root);
+
+ g_binary_content_compute_start_pos(__content, &__next);
+
+ }
+ else
+ {
+ __content = g_match_record_get_content(locals->last);
+
+ g_match_record_get_range(locals->last, &__range);
+ compute_mrange_end_addr(&__range, &__next);
+
+ }
+
+ $$.stream = g_kaitai_stream_new(__content, &__next);
+ $$.type = GVT_STREAM;
+
+ g_object_unref(G_OBJECT(__content));
+
+ }
+ | any_expr "._io"
{
GBinContent *__content;
mrange_t __range;
@@ -1508,6 +1541,15 @@ YY_DECL;
}
;
+ stream_meths : stream ".eof"
+ {
+ $$.status = g_kaitai_stream_has_reached_eof($1.stream);;
+ $$.type = GVT_BOOLEAN;
+
+ EXIT_RESOLVED_VALUE($1);
+
+ }
+ ;
%%
@@ -1656,8 +1698,11 @@ static bool reduce_resolved_kaitai_expression(resolved_value_t *in_out)
while (result && in_out->type == GVT_RECORD)
{
- if (G_IS_RECORD_VALUE(in_out->record))
- result = g_record_value_compute_value(G_RECORD_VALUE(in_out->record), &deeper);
+ if (G_IS_RECORD_BIT_FIELD(in_out->record))
+ result = g_record_bit_field_get_value(G_RECORD_BIT_FIELD(in_out->record), &deeper);
+
+ else if (G_IS_RECORD_DELAYED(in_out->record))
+ result = g_record_delayed_compute_value(G_RECORD_DELAYED(in_out->record), &deeper);
else if (G_IS_RECORD_ITEM(in_out->record))
result = g_record_item_get_value(G_RECORD_ITEM(in_out->record), &deeper);
@@ -1734,6 +1779,26 @@ bool resolve_kaitai_expression_as_boolean(const kaitai_scope_t *locals, const ch
if (result)
result = reduce_resolved_kaitai_expression(out);
+ if (result)
+ {
+ if (out->type == GVT_UNSIGNED_INTEGER)
+ {
+ out->status = (out->unsigned_integer != 0);
+ out->type = GVT_BOOLEAN;
+ }
+ else if (out->type == GVT_SIGNED_INTEGER)
+ {
+ out->status = (out->signed_integer != 0);
+ out->type = GVT_BOOLEAN;
+ }
+ else if (out->type == GVT_FLOAT)
+ {
+ out->status = (out->floating_number != 0);
+ out->type = GVT_BOOLEAN;
+ }
+
+ }
+
if (result && out->type != GVT_BOOLEAN)
{
EXIT_RESOLVED_VALUE(*out);
diff --git a/plugins/kaitai/import.c b/plugins/kaitai/import.c
new file mode 100644
index 0000000..0412ff7
--- /dev/null
+++ b/plugins/kaitai/import.c
@@ -0,0 +1,300 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * import.c - localisation de fichiers de définitions externes
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "import.h"
+
+
+#include <libgen.h>
+#include <malloc.h>
+#include <string.h>
+
+
+#include <common/environment.h>
+#include <core/logs.h>
+
+
+
+/* Charge un type Kaitai à partir d'une définition voisine. */
+static GKaitaiType *import_relative_kaitai_definition(const char *, const char *);
+
+/* Charge un type Kaitai depuis un emplacement de $KSPATH. */
+static GKaitaiType *import_kaitai_definition_from_env(const char *);
+
+/* Charge un interpréteur pour une définition voisine. */
+static GKaitaiStruct *load_relative_kaitai_definition(const char *, const char *);
+
+/* Charge un interpréteur depuis un emplacement de $KSPATH. */
+static GKaitaiStruct *load_kaitai_definition_from_env(const char *);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : target = désignation de la définition à retrouver. *
+* reference = éventuel fichier pour les positions relatives. *
+* *
+* Description : Charge un type Kaitai à partir d'une définition voisine. *
+* *
+* Retour : Type valide en place ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GKaitaiType *import_relative_kaitai_definition(const char *target, const char *reference)
+{
+ GKaitaiType *result; /* Structure chargée à renvoyer*/
+ char *tmp; /* Zone de travail temporaire */
+ char *base; /* Base de recherche */
+ char *filename; /* Nom de fichier à tester */
+ int ret; /* Bilan d'une construction */
+
+ result = NULL;
+
+ tmp = strdup(reference);
+ base = dirname(tmp);
+
+ ret = asprintf(&filename, "%s%c%s.ksy", base, G_DIR_SEPARATOR, target);
+ if (ret == -1) goto build_error;
+
+ result = g_kaitai_type_new_as_import(target, filename);
+
+ free(filename);
+
+ build_error:
+
+ free(tmp);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : target = désignation de la définition à retrouver. *
+* *
+* Description : Charge un type Kaitai depuis un emplacement de $KSPATH. *
+* *
+* Retour : Type valide en place ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GKaitaiType *import_kaitai_definition_from_env(const char *target)
+{
+ GKaitaiType *result; /* Structure chargée à renvoyer*/
+ char *paths; /* Emplacements de greffons */
+ char *save; /* Sauvegarde pour ré-entrance */
+ char *path; /* Chemin à fouiller */
+ char *filename; /* Nom de fichier à tester */
+ int ret; /* Bilan d'une construction */
+
+ result = NULL;
+
+ paths = get_env_var("KSPATH");
+
+ save = NULL; /* gcc... */
+
+ for (path = strtok_r(paths, ":", &save);
+ path != NULL;
+ path = strtok_r(NULL, ":", &save))
+ {
+ ret = asprintf(&filename, "%s%c%s.ksy", path, G_DIR_SEPARATOR, target);
+ if (ret == -1)
+ {
+ LOG_ERROR_N("asprintf");
+ continue;
+ }
+
+ result = g_kaitai_type_new_as_import(target, filename);
+
+ if (result != NULL)
+ log_variadic_message(LMT_PROCESS, _("Found a required Kaitai definition to import: %s"), filename);
+
+ free(filename);
+
+ }
+
+ free(paths);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : target = désignation de la définition à retrouver. *
+* reference = éventuel fichier pour les positions relatives. *
+* *
+* Description : Met en place un type Kaitai pour une définition désignée. *
+* *
+* Retour : Type valide en place ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GKaitaiType *import_kaitai_definition(const char *target, const char *reference)
+{
+ GKaitaiType *result; /* Structure chargée à renvoyer*/
+
+ result = NULL;
+
+ if (reference != NULL)
+ result = import_relative_kaitai_definition(target, reference);
+
+ if (result == NULL)
+ result = import_kaitai_definition_from_env(target);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : target = désignation de la définition à retrouver. *
+* reference = éventuel fichier pour les positions relatives. *
+* *
+* Description : Charge un interpréteur pour une définition voisine. *
+* *
+* Retour : Interprétateur valide en place ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GKaitaiStruct *load_relative_kaitai_definition(const char *target, const char *reference)
+{
+ GKaitaiStruct *result; /* Structure chargée à renvoyer*/
+ char *tmp; /* Zone de travail temporaire */
+ char *base; /* Base de recherche */
+ char *filename; /* Nom de fichier à tester */
+ int ret; /* Bilan d'une construction */
+
+ result = NULL;
+
+ tmp = strdup(reference);
+ base = dirname(tmp);
+
+ ret = asprintf(&filename, "%s%c%s.ksy", base, G_DIR_SEPARATOR, target);
+ if (ret == -1) goto build_error;
+
+ result = g_kaitai_structure_new_from_file(filename);
+
+ free(filename);
+
+ build_error:
+
+ free(tmp);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : target = désignation de la définition à retrouver. *
+* *
+* Description : Charge un interpréteur depuis un emplacement de $KSPATH. *
+* *
+* Retour : Interprétateur valide en place ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GKaitaiStruct *load_kaitai_definition_from_env(const char *target)
+{
+ GKaitaiStruct *result; /* Structure chargée à renvoyer*/
+ char *paths; /* Emplacements de greffons */
+ char *save; /* Sauvegarde pour ré-entrance */
+ char *path; /* Chemin à fouiller */
+ char *filename; /* Nom de fichier à tester */
+ int ret; /* Bilan d'une construction */
+
+ result = NULL;
+
+ paths = get_env_var("KSPATH");
+
+ save = NULL; /* gcc... */
+
+ for (path = strtok_r(paths, ":", &save);
+ path != NULL;
+ path = strtok_r(NULL, ":", &save))
+ {
+ ret = asprintf(&filename, "%s%c%s.ksy", path, G_DIR_SEPARATOR, target);
+ if (ret == -1)
+ {
+ LOG_ERROR_N("asprintf");
+ continue;
+ }
+
+ result = g_kaitai_structure_new_from_file(filename);
+
+ if (result != NULL)
+ log_variadic_message(LMT_PROCESS, _("Found a required Kaitai definition: %s"), filename);
+
+ free(filename);
+
+ }
+
+ free(paths);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : target = désignation de la définition à retrouver. *
+* reference = éventuel fichier pour les positions relatives. *
+* *
+* Description : Met en place un interpréteur pour une définition désignée. *
+* *
+* Retour : Interprétateur valide en place ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GKaitaiStruct *load_kaitai_definition(const char *target, const char *reference)
+{
+ GKaitaiStruct *result; /* Structure chargée à renvoyer*/
+
+ result = NULL;
+
+ if (reference != NULL)
+ result = load_relative_kaitai_definition(target, reference);
+
+ if (result == NULL)
+ result = load_kaitai_definition_from_env(target);
+
+ return result;
+
+}
diff --git a/plugins/kaitai/import.h b/plugins/kaitai/import.h
new file mode 100644
index 0000000..66a0f5a
--- /dev/null
+++ b/plugins/kaitai/import.h
@@ -0,0 +1,41 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * import.h - prototypes pour la localisation de fichiers de définitions externes
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _PLUGINS_KAITAI_IMPORT_H
+#define _PLUGINS_KAITAI_IMPORT_H
+
+
+#include "parsers/struct.h"
+#include "parsers/type.h"
+
+
+
+/* Met en place un type Kaitai pour une définition désignée. */
+GKaitaiType *import_kaitai_definition(const char *, const char *);
+
+/* Met en place un interpréteur pour une définition désignée. */
+GKaitaiStruct *load_kaitai_definition(const char *, const char *);
+
+
+
+#endif /* _PLUGINS_KAITAI_IMPORT_H */
diff --git a/plugins/kaitai/parser-int.h b/plugins/kaitai/parser-int.h
index 4ddb0f9..8bac523 100644
--- a/plugins/kaitai/parser-int.h
+++ b/plugins/kaitai/parser-int.h
@@ -30,7 +30,7 @@
/* Parcourt un contenu binaire selon des spécifications Kaitai. */
-typedef bool (* parse_kaitai_fc) (GKaitaiParser *, kaitai_scope_t *, GBinContent *, vmpa2t *, GMatchRecord **);
+typedef bool (* parse_kaitai_fc) (GKaitaiParser *, kaitai_scope_t *, GBinContent *, ext_vmpa_t *, GMatchRecord **);
diff --git a/plugins/kaitai/parser.c b/plugins/kaitai/parser.c
index 77c15b3..cfe1aa1 100644
--- a/plugins/kaitai/parser.c
+++ b/plugins/kaitai/parser.c
@@ -24,6 +24,9 @@
#include "parser.h"
+#include <assert.h>
+
+
#include "parser-int.h"
@@ -131,7 +134,7 @@ static void g_kaitai_parser_finalize(GKaitaiParser *parser)
* Paramètres : parser = structure Kaitai en cours de parcours. *
* locals = variables locales pour les résolutions de types. *
* content = données binaires à analyser et traduire. *
-* pos = tête de lecture courante. [OUT] *
+* epos = tête de lecture courante. [OUT] *
* record = noeud d'arborescence d'éléments rencontrés. [OUT] *
* *
* Description : Parcourt un contenu binaire selon des spécifications Kaitai. *
@@ -142,18 +145,22 @@ static void g_kaitai_parser_finalize(GKaitaiParser *parser)
* *
******************************************************************************/
-bool g_kaitai_parser_parse_content(GKaitaiParser *parser, kaitai_scope_t *locals, GBinContent *content, vmpa2t *pos, GMatchRecord **record)
+bool g_kaitai_parser_parse_content(GKaitaiParser *parser, kaitai_scope_t *locals, GBinContent *content, ext_vmpa_t *epos, GMatchRecord **record)
{
bool result; /* Bilan à retourner */
GKaitaiParserClass *class; /* Classe de l'instance */
+ *record = NULL;
+
class = G_KAITAI_PARSER_GET_CLASS(parser);
- result = class->parse(parser, locals, content, pos, record);
+ result = class->parse(parser, locals, content, epos, record);
- if (result)
+ if (result && *record != NULL)
remember_last_record(locals, *record);
+ assert((!result && *record == NULL) || result);
+
return result;
}
diff --git a/plugins/kaitai/parser.h b/plugins/kaitai/parser.h
index 4c17087..64d759d 100644
--- a/plugins/kaitai/parser.h
+++ b/plugins/kaitai/parser.h
@@ -56,7 +56,7 @@ typedef struct _GKaitaiParserClass GKaitaiParserClass;
GType g_kaitai_parser_get_type(void);
/* Parcourt un contenu binaire selon des spécifications Kaitai. */
-bool g_kaitai_parser_parse_content(GKaitaiParser *, kaitai_scope_t *, GBinContent *, vmpa2t *, GMatchRecord **);
+bool g_kaitai_parser_parse_content(GKaitaiParser *, kaitai_scope_t *, GBinContent *, ext_vmpa_t *, GMatchRecord **);
diff --git a/plugins/kaitai/parsers/attribute-int.h b/plugins/kaitai/parsers/attribute-int.h
index ef64089..7d37af3 100644
--- a/plugins/kaitai/parsers/attribute-int.h
+++ b/plugins/kaitai/parsers/attribute-int.h
@@ -51,6 +51,9 @@ struct _GKaitaiAttribute
/* KAP_FIXED_CONTENT */
sized_string_t fixed_content; /* Données brutes attendues */
+ /* KAP_BIT_FIELD_TYPE */
+ uint8_t bf_size; /* Nombre de bits visés */
+
/* KAP_BASIC_TYPE */
struct
{
diff --git a/plugins/kaitai/parsers/attribute.c b/plugins/kaitai/parsers/attribute.c
index c61fe99..6050bb1 100644
--- a/plugins/kaitai/parsers/attribute.c
+++ b/plugins/kaitai/parsers/attribute.c
@@ -25,6 +25,7 @@
#include <assert.h>
+#include <stdlib.h>
#include <string.h>
@@ -35,6 +36,7 @@
#include "attribute-int.h"
#include "../expression.h"
#include "../scope.h"
+#include "../records/bits.h"
#include "../records/empty.h"
#include "../records/item.h"
#include "../records/list.h"
@@ -56,6 +58,9 @@ static void g_kaitai_attribute_dispose(GKaitaiAttribute *);
/* Procède à la libération totale de la mémoire. */
static void g_kaitai_attribute_finalize(GKaitaiAttribute *);
+/* Traduit en champ de bits une chaîne de caractères. */
+static bool g_kaitai_attribute_resolve_bit_field(GKaitaiAttribute *, const char *);
+
/* Traduit en type concret une chaîne de caractères. */
static bool g_kaitai_attribute_resolve_type(GKaitaiAttribute *, const char *);
@@ -71,7 +76,7 @@ static GKaitaiAttribute *g_kaitai_attribute_dup_for(const GKaitaiAttribute *);
/* Parcourt un contenu binaire selon des spécifications Kaitai. */
-static bool _g_kaitai_attribute_parse_content(GKaitaiAttribute *, kaitai_scope_t *, GBinContent *, vmpa2t *, GMatchRecord **);
+static bool _g_kaitai_attribute_parse_content(GKaitaiAttribute *, kaitai_scope_t *, GBinContent *, ext_vmpa_t *, GMatchRecord **);
/* Extrait d'un contenu une série d'octets avec terminaison. */
static bool g_kaitai_attribute_parse_terminated_bytes(GKaitaiAttribute *, const kaitai_scope_t *, GBinContent *, vmpa2t *, GMatchRecord **);
@@ -80,7 +85,7 @@ static bool g_kaitai_attribute_parse_terminated_bytes(GKaitaiAttribute *, const
static bool g_kaitai_attribute_compute_maybe_terminated_range(const GKaitaiAttribute *, const kaitai_scope_t *, const GBinContent *, const vmpa2t *, phys_t *, mrange_t *);
/* Parcourt un contenu binaire selon des spécifications Kaitai. */
-static bool g_kaitai_attribute_parse_content(GKaitaiAttribute *, kaitai_scope_t *, GBinContent *, vmpa2t *, GMatchRecord **);
+static bool g_kaitai_attribute_parse_content(GKaitaiAttribute *, kaitai_scope_t *, GBinContent *, ext_vmpa_t *, GMatchRecord **);
@@ -243,7 +248,7 @@ GKaitaiAttribute *g_kaitai_attribute_new(GYamlNode *parent)
result = g_object_new(G_TYPE_KAITAI_ATTRIBUTE, NULL);
- if (!g_kaitai_attribute_create(result, parent, true))
+ if (!g_kaitai_attribute_create(result, parent, false /* TODO : REMME ? */))
g_clear_object(&result);
return result;
@@ -399,7 +404,10 @@ bool g_kaitai_attribute_create(GKaitaiAttribute *attrib, GYamlNode *parent, bool
if (value != NULL)
{
- if (g_kaitai_attribute_resolve_type(attrib, value))
+ if (g_kaitai_attribute_resolve_bit_field(attrib, value))
+ attrib->payload |= KAP_BIT_FIELD_TYPE;
+
+ else if (g_kaitai_attribute_resolve_type(attrib, value))
attrib->payload |= KAP_BASIC_TYPE;
else
@@ -701,6 +709,54 @@ bool g_kaitai_attribute_create(GKaitaiAttribute *attrib, GYamlNode *parent, bool
* Paramètres : attrib = attribut Kaitai en cours de constitution. *
* desc = chaîne de caractère à interpréter en type. *
* *
+* Description : Traduit en champ de bits une chaîne de caractères. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_kaitai_attribute_resolve_bit_field(GKaitaiAttribute *attrib, const char *desc)
+{
+ bool result; /* Bilan à retourner */
+ size_t len; /* Taille de la chaîne à lire */
+ char *end; /* Prochain caractère à lire */
+ unsigned long size; /* Taille du champ de bits */
+
+ result = false;
+
+ if (desc[0] == 'b')
+ {
+ len = strlen(desc);
+
+ size = strtoul(&desc[1], &end, 10);
+
+ if (size > 64)
+ {
+ printf("Unsupported size for bit field: %lu\n", size);
+ goto exit;
+ }
+
+ result = ((desc + len) == end);
+
+ if (result)
+ attrib->bf_size = size;
+
+ }
+
+ exit:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : attrib = attribut Kaitai en cours de constitution. *
+* desc = chaîne de caractère à interpréter en type. *
+* *
* Description : Traduit en type concret une chaîne de caractères. *
* *
* Retour : Bilan de l'opération. *
@@ -930,7 +986,7 @@ static bool g_kaitai_attribute_check(const GKaitaiAttribute *attrib)
}
/**
- * Si une séquence d'octets finaux est spécifiées, alors l'attribut
+ * Si une séquence d'octets finaux est spécifiée, alors l'attribut
* doit correspondre à un type str[z] (lecture) ou de taille fixée
* (validation post-lecture).
*/
@@ -1018,7 +1074,8 @@ static GKaitaiAttribute *g_kaitai_attribute_dup_for(const GKaitaiAttribute *attr
* Les travaux de copie ne portent ainsi que sur le présent attribut.
*/
- result->raw_id = strdup(attrib->raw_id);
+ if (attrib->raw_id != NULL)
+ result->raw_id = strdup(attrib->raw_id);
if (attrib->orig_id != NULL)
result->orig_id = strdup(attrib->orig_id);
@@ -1428,6 +1485,50 @@ bool g_kaitai_attribute_read_value(const GKaitaiAttribute *attrib, const GBinCon
}
+/******************************************************************************
+* *
+* Paramètres : attrib = lecteur d'attribut Kaitai à consulter. *
+* content = contenu binaire à venir lire. *
+* epos = tête de lecture avec granularité en bits. *
+* size = quantité de bits à prendre en compte. *
+* endian = boustime des données à respecter. *
+* out = valeur à sauvegarder sous une forme générique.[OUT]*
+* *
+* Description : Lit la valeur d'un champ de bits Kaitai représenté. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_kaitai_attribute_read_bit_field_value(const GKaitaiAttribute *attrib, const GBinContent *content, const ext_vmpa_t *epos, uint8_t size, SourceEndian endian, resolved_value_t *out)
+{
+ bool result; /* Bilan à retourner */
+ ext_vmpa_t tmpepos; /* Localisation modifiable */
+ uint64_t tmp64; /* Valeur de 64 bits lue */
+
+ result = false;
+
+ if (attrib->payload & KAP_BIT_FIELD_TYPE)
+ {
+ copy_evmpa(&tmpepos, epos);
+
+ result = g_binary_content_read_bits(content, &tmpepos, size, endian, &tmp64);
+
+ if (result)
+ {
+ out->type = GVT_UNSIGNED_INTEGER;
+ out->unsigned_integer = tmp64;
+ }
+
+ }
+
+ return result;
+
+}
+
+
/* ---------------------------------------------------------------------------------- */
/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
@@ -1439,7 +1540,7 @@ bool g_kaitai_attribute_read_value(const GKaitaiAttribute *attrib, const GBinCon
* Paramètres : attrib = structure Kaitai en cours de parcours. *
* locals = variables locales pour les résolutions de types. *
* content = données binaires à analyser et traduire. *
-* pos = tête de lecture courante. [OUT] *
+* epos = tête de lecture courante. [OUT] *
* record = noeud d'arborescence d'éléments rencontrés. [OUT] *
* *
* Description : Parcourt un contenu binaire selon des spécifications Kaitai. *
@@ -1450,7 +1551,7 @@ bool g_kaitai_attribute_read_value(const GKaitaiAttribute *attrib, const GBinCon
* *
******************************************************************************/
-static bool _g_kaitai_attribute_parse_content(GKaitaiAttribute *attrib, kaitai_scope_t *locals, GBinContent *content, vmpa2t *pos, GMatchRecord **record)
+static bool _g_kaitai_attribute_parse_content(GKaitaiAttribute *attrib, kaitai_scope_t *locals, GBinContent *content, ext_vmpa_t *epos, GMatchRecord **record)
{
bool result; /* Bilan à retourner */
resolved_value_t authorized; /* Validation des traitements */
@@ -1499,7 +1600,10 @@ static bool _g_kaitai_attribute_parse_content(GKaitaiAttribute *attrib, kaitai_s
/* Zone de travail restreinte */
g_binary_content_compute_end_pos(content, &tmp);
- diff = compute_vmpa_diff(pos, &tmp);
+ diff = compute_vmpa_diff(&epos->base, &tmp);
+
+ if (epos->consumed_extra_bits > 0 && diff > 0)
+ diff--;
if (attrib->payload & KAP_SIZED)
{
@@ -1537,8 +1641,10 @@ static bool _g_kaitai_attribute_parse_content(GKaitaiAttribute *attrib, kaitai_s
if (!result)
goto exit;
- init_mrange(&work_range, pos, diff);
- work_area = g_restricted_content_new_ro(content, &work_range);
+ align_evmpa_on_byte(epos);
+
+ init_mrange(&work_range, &epos->base, diff);
+ work_area = g_restricted_content_new(content, &work_range);
has_empty_size = (diff == 0);
@@ -1555,13 +1661,18 @@ static bool _g_kaitai_attribute_parse_content(GKaitaiAttribute *attrib, kaitai_s
assert(false);
else if (attrib->payload & KAP_SIZED_EOS)
+ {
+ align_evmpa_on_byte(epos);
result = true;
+ }
else if (attrib->payload & KAP_FIXED_CONTENT)
{
if (diff >= attrib->fixed_content.len)
{
- copy_vmpa(&tmp, pos);
+ align_evmpa_on_byte(epos);
+
+ copy_vmpa(&tmp, &epos->base);
data = g_binary_content_get_raw_access(work_area, &tmp, attrib->fixed_content.len);
assert(data != NULL);
@@ -1575,8 +1686,26 @@ static bool _g_kaitai_attribute_parse_content(GKaitaiAttribute *attrib, kaitai_s
}
+ else if (attrib->payload & KAP_BIT_FIELD_TYPE)
+ {
+ if (attrib->has_endian)
+ endian = attrib->endian;
+ else
+ endian = g_kaitai_meta_get_endian(locals->meta);
+
+ *record = g_record_bit_field_new(attrib, work_area, epos, attrib->bf_size, endian);
+
+ result = (*record != NULL);
+
+ if (result)
+ advance_evmpa_bits(epos, attrib->bf_size);
+
+ }
+
else if (attrib->payload & KAP_BASIC_TYPE)
{
+ align_evmpa_on_byte(epos);
+
switch (attrib->basic)
{
case BTP_CHAR:
@@ -1584,7 +1713,8 @@ static bool _g_kaitai_attribute_parse_content(GKaitaiAttribute *attrib, kaitai_s
if (attrib->is_string)
{
if ((attrib->payload & KAP_SIZED) == 0)
- result = g_kaitai_attribute_parse_terminated_bytes(attrib, locals, work_area, pos, record);
+ result = g_kaitai_attribute_parse_terminated_bytes(attrib, locals,
+ work_area, &epos->base, record);
}
else
{
@@ -1627,7 +1757,7 @@ static bool _g_kaitai_attribute_parse_content(GKaitaiAttribute *attrib, kaitai_s
if (user_type != NULL)
{
result = g_kaitai_parser_parse_content(G_KAITAI_PARSER(user_type),
- locals, work_area, pos, record);
+ locals, work_area, epos, record);
if (result)
/**
@@ -1647,7 +1777,7 @@ static bool _g_kaitai_attribute_parse_content(GKaitaiAttribute *attrib, kaitai_s
}
else if (attrib->payload & KAP_DYNAMIC_TYPE)
- result = g_kaitai_parser_parse_content(G_KAITAI_PARSER(attrib->switchon), locals, work_area, pos, record);
+ result = g_kaitai_parser_parse_content(G_KAITAI_PARSER(attrib->switchon), locals, work_area, epos, record);
else if (attrib->payload & KAP_SIZED)
{
@@ -1660,6 +1790,11 @@ static bool _g_kaitai_attribute_parse_content(GKaitaiAttribute *attrib, kaitai_s
if (result && *record == NULL)
{
/**
+ * A ce stade, la granularité des travaux est l'octet.
+ */
+ assert(epos->consumed_extra_bits == 0);
+
+ /**
* On choisit de laisser la création de correspondances nulles.
*
* Cela permet de disposer de la présence de champs valides, même vides
@@ -1668,12 +1803,13 @@ static bool _g_kaitai_attribute_parse_content(GKaitaiAttribute *attrib, kaitai_s
/* if (diff > 0) */
{
- result = g_kaitai_attribute_compute_maybe_terminated_range(attrib, locals, content, pos, &diff, &range);
+ result = g_kaitai_attribute_compute_maybe_terminated_range(attrib, locals, content,
+ &epos->base, &diff, &range);
if (result)
{
if (has_empty_size)
- *record = G_MATCH_RECORD(g_record_empty_new(G_KAITAI_PARSER(attrib), content, pos));
+ *record = G_MATCH_RECORD(g_record_empty_new(G_KAITAI_PARSER(attrib), content, &epos->base));
else
{
@@ -1685,7 +1821,7 @@ static bool _g_kaitai_attribute_parse_content(GKaitaiAttribute *attrib, kaitai_s
*record = G_MATCH_RECORD(g_record_item_new(attrib, work_area, &range, endian));
if (*record != NULL)
- advance_vmpa(pos, diff);
+ advance_vmpa(&epos->base, diff);
else
result = false;
@@ -1701,13 +1837,16 @@ static bool _g_kaitai_attribute_parse_content(GKaitaiAttribute *attrib, kaitai_s
if (attrib->payload & KAP_SIZED)
{
- cur_diff = compute_vmpa_diff(get_mrange_addr(&work_range), pos);
+ /* Réalignement éventuel suite aux lectures dans la zone périmétrée... */
+ align_evmpa_on_byte(epos);
+
+ cur_diff = compute_vmpa_diff(get_mrange_addr(&work_range), &epos->base);
/* Pour GCC... */
max_size = get_mrange_length(&work_range);
if (cur_diff < max_size)
- advance_vmpa(pos, max_size - cur_diff);
+ advance_vmpa(&epos->base, max_size - cur_diff);
assert(work_area != content);
g_object_unref(G_OBJECT(work_area));
@@ -1932,7 +2071,7 @@ static bool g_kaitai_attribute_compute_maybe_terminated_range(const GKaitaiAttri
* Paramètres : attrib = structure Kaitai en cours de parcours. *
* locals = variables locales pour les résolutions de types. *
* content = données binaires à analyser et traduire. *
-* pos = tête de lecture courante. [OUT] *
+* epos = tête de lecture courante. [OUT] *
* record = noeud d'arborescence d'éléments rencontrés. [OUT] *
* *
* Description : Parcourt un contenu binaire selon des spécifications Kaitai. *
@@ -1943,7 +2082,7 @@ static bool g_kaitai_attribute_compute_maybe_terminated_range(const GKaitaiAttri
* *
******************************************************************************/
-static bool g_kaitai_attribute_parse_content(GKaitaiAttribute *attrib, kaitai_scope_t *locals, GBinContent *content, vmpa2t *pos, GMatchRecord **record)
+static bool g_kaitai_attribute_parse_content(GKaitaiAttribute *attrib, kaitai_scope_t *locals, GBinContent *content, ext_vmpa_t *epos, GMatchRecord **record)
{
bool result; /* Bilan à retourner */
resolved_value_t authorized; /* Validation des traitements */
@@ -1957,7 +2096,7 @@ static bool g_kaitai_attribute_parse_content(GKaitaiAttribute *attrib, kaitai_sc
resolved_value_t loop; /* Poursuite des lectures ? */
if (attrib->repetition == KAR_NO_REPETITION)
- result = _g_kaitai_attribute_parse_content(attrib, locals, content, pos, record);
+ result = _g_kaitai_attribute_parse_content(attrib, locals, content, epos, record);
else
{
@@ -1975,7 +2114,7 @@ static bool g_kaitai_attribute_parse_content(GKaitaiAttribute *attrib, kaitai_sc
}
- list = g_record_list_new(attrib, content, pos);
+ list = g_record_list_new(attrib, content, &epos->base);
switch (attrib->repetition)
{
@@ -1984,17 +2123,17 @@ static bool g_kaitai_attribute_parse_content(GKaitaiAttribute *attrib, kaitai_sc
result = true;
g_binary_content_compute_end_pos(content, &end);
- diff = compute_vmpa_diff(pos, &end);
+ diff = compute_vmpa_diff(&epos->base, &end);
while (diff > 0)
{
- result = _g_kaitai_attribute_parse_content(attrib, locals, content, pos, &child);
+ result = _g_kaitai_attribute_parse_content(attrib, locals, content, epos, &child);
if (!result) break;
g_record_list_add_record(list, child);
remember_last_record(locals, child);
- diff = compute_vmpa_diff(pos, &end);
+ diff = compute_vmpa_diff(&epos->base, &end);
}
@@ -2025,7 +2164,7 @@ static bool g_kaitai_attribute_parse_content(GKaitaiAttribute *attrib, kaitai_sc
for (i = 0; i < count; i++)
{
- result = _g_kaitai_attribute_parse_content(attrib, locals, content, pos, &child);
+ result = _g_kaitai_attribute_parse_content(attrib, locals, content, epos, &child);
if (!result) break;
g_record_list_add_record(list, child);
@@ -2039,7 +2178,7 @@ static bool g_kaitai_attribute_parse_content(GKaitaiAttribute *attrib, kaitai_sc
do
{
- result = _g_kaitai_attribute_parse_content(attrib, locals, content, pos, &child);
+ result = _g_kaitai_attribute_parse_content(attrib, locals, content, epos, &child);
if (!result) break;
g_record_list_add_record(list, child);
diff --git a/plugins/kaitai/parsers/attribute.h b/plugins/kaitai/parsers/attribute.h
index 38b78d7..9b43936 100644
--- a/plugins/kaitai/parsers/attribute.h
+++ b/plugins/kaitai/parsers/attribute.h
@@ -56,18 +56,19 @@ typedef struct _GKaitaiAttributeClass GKaitaiAttributeClass;
/* Type de charge associée à un attribut */
typedef enum _KaitaiAttributePayload
{
- KAP_UNINITIALIZED = (0 << 0), /* Type non initialisé */
+ KAP_UNINITIALIZED = (0 << 0), /* Type non initialisé */
- KAP_FIXED_CONTENT = (1 << 0), /* Contenu brut attendu */
- KAP_BASIC_TYPE = (1 << 1), /* Type prédéfini */
- KAP_USER_TYPE = (1 << 2), /* Type personnalisé */
- KAP_DYNAMIC_TYPE = (1 << 3), /* Type dynmatique */
- KAP_SIZED = (1 << 4), /* Bourrage dimensionné */
- KAP_SIZED_EOS = (1 << 5), /* Bourrage final */
+ KAP_FIXED_CONTENT = (1 << 0), /* Contenu brut attendu */
+ KAP_BIT_FIELD_TYPE = (1 << 1), /* Champ d'un ou plusieurs bits*/
+ KAP_BASIC_TYPE = (1 << 2), /* Type prédéfini */
+ KAP_USER_TYPE = (1 << 3), /* Type personnalisé */
+ KAP_DYNAMIC_TYPE = (1 << 4), /* Type dynmatique */
+ KAP_SIZED = (1 << 5), /* Bourrage dimensionné */
+ KAP_SIZED_EOS = (1 << 6), /* Bourrage final */
} KaitaiAttributePayload;
-/* Types de base reconnus par Kaitai */
+/* Types de base reconnus par Kaitai */ /* TODO : REMME ? (car non utilisé) */
typedef enum _KaitaiBasicType
{
KBT_U1, /* Octet non signé */
@@ -149,6 +150,9 @@ bool g_kaitai_attribute_handle_signed_integer(const GKaitaiAttribute *);
/* Lit la valeur d'un élément Kaitai entier représenté. */
bool g_kaitai_attribute_read_value(const GKaitaiAttribute *, const GBinContent *, const mrange_t *, SourceEndian, resolved_value_t *);
+/* Lit la valeur d'un champ de bits Kaitai représenté. */
+bool g_kaitai_attribute_read_bit_field_value(const GKaitaiAttribute *, const GBinContent *, const ext_vmpa_t *, uint8_t, SourceEndian, resolved_value_t *);
+
#endif /* _PLUGINS_KAITAI_PARSERS_ATTRIBUTE_H */
diff --git a/plugins/kaitai/parsers/instance.c b/plugins/kaitai/parsers/instance.c
index 63db224..d62c1f6 100644
--- a/plugins/kaitai/parsers/instance.c
+++ b/plugins/kaitai/parsers/instance.c
@@ -34,7 +34,7 @@
#include "instance-int.h"
#include "../expression.h"
-#include "../records/value.h"
+#include "../records/delayed.h"
@@ -59,7 +59,7 @@ static void g_kaitai_instance_finalize(GKaitaiInstance *);
/* Parcourt un contenu binaire selon des spécifications Kaitai. */
-static bool g_kaitai_instance_parse_content(GKaitaiInstance *, kaitai_scope_t *, GBinContent *, vmpa2t *, GMatchRecord **);
+static bool g_kaitai_instance_parse_content(GKaitaiInstance *, kaitai_scope_t *, GBinContent *, ext_vmpa_t *, GMatchRecord **);
@@ -349,74 +349,30 @@ const char *g_kaitai_instance_get_name(const GKaitaiInstance *inst)
* *
* Paramètres : inst = lecteur d'instance Kaitai à consulter. *
* locals = variables locales pour les résolutions de types. *
-* value = valeur à sauvegarder sous une forme générique. [OUT]*
+* content = contenu binaire lié à la correspondance. *
* *
-* Description : Détermine la valeur d'un élément Kaitai entier calculé. *
+* Description : Détermine la valeur effective d'un élément Kaitai dynamique. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : valeur à sauvegarder sous une forme générique. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool g_kaitai_instance_compute_value(const GKaitaiInstance *inst, const kaitai_scope_t *locals, resolved_value_t *value)
+GMatchRecord *g_kaitai_instance_compute_real_record(const GKaitaiInstance *inst, const kaitai_scope_t *locals, GBinContent *content)
{
- bool result; /* Bilan à retourner */
-
- if (inst->value == NULL)
- result = false;
-
- else
- result = resolve_kaitai_expression_as_any(locals,
- inst->value,
- strlen(inst->value),
- value);
-
- return result;
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-* *
-* Paramètres : inst = structure Kaitai en cours de parcours. *
-* locals = variables locales pour les résolutions de types. *
-* content = données binaires à analyser et traduire. *
-* pos = tête de lecture courante. [OUT] *
-* record = noeud d'arborescence d'éléments rencontrés. [OUT] *
-* *
-* Description : Parcourt un contenu binaire selon des spécifications Kaitai. *
-* *
-* Retour : Bilan de l'opératon : true pour continuer, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool g_kaitai_instance_parse_content(GKaitaiInstance *inst, kaitai_scope_t *locals, GBinContent *content, vmpa2t *pos, GMatchRecord **record)
-{
- bool result; /* Bilan à retourner */
+ GMatchRecord *result; /* Enregistrement à retourner */
GBinContent *work_area; /* Aire de travail */
GKaitaiStream *stream; /* Flux de données pour Kaitai */
- resolved_value_t offset; /* Position à adopter */
+ bool status; /* Bilan intermédiaire */
vmpa2t forced_pos; /* Tete de lecture constituée */
+ resolved_value_t offset; /* Position à adopter */
GKaitaiParserClass *class; /* Classe parente à solliciter */
+ ext_vmpa_t epos; /* Tête de lecture complète */
- if (inst->value != NULL)
- {
- *record = G_MATCH_RECORD(g_record_value_new(inst, locals));
+ result = NULL;
- result = (*record != NULL);
-
- }
-
- else
+ if (inst->value == NULL)
{
/* Contenu particulier */
@@ -425,8 +381,8 @@ static bool g_kaitai_instance_parse_content(GKaitaiInstance *inst, kaitai_scope_
else
{
- result = resolve_kaitai_expression_as_stream(locals, inst->io, strlen(inst->io), &stream);
- if (!result) goto exit;
+ status = resolve_kaitai_expression_as_stream(locals, inst->io, strlen(inst->io), &stream);
+ if (!status) goto exit;
work_area = g_kaitai_stream_get_content(stream);
@@ -438,8 +394,8 @@ static bool g_kaitai_instance_parse_content(GKaitaiInstance *inst, kaitai_scope_
g_binary_content_compute_start_pos(work_area, &forced_pos);
- result = resolve_kaitai_expression_as_integer(locals, inst->pos, strlen(inst->pos), &offset);
- if (!result) goto exit_with_content;
+ status = resolve_kaitai_expression_as_integer(locals, inst->pos, strlen(inst->pos), &offset);
+ if (!status) goto exit_with_content;
if (offset.type == GVT_UNSIGNED_INTEGER)
advance_vmpa(&forced_pos, offset.unsigned_integer);
@@ -450,7 +406,7 @@ static bool g_kaitai_instance_parse_content(GKaitaiInstance *inst, kaitai_scope_
if (offset.signed_integer < 0)
{
- result = false;
+ status = false;
goto exit_with_content;
}
@@ -462,7 +418,9 @@ static bool g_kaitai_instance_parse_content(GKaitaiInstance *inst, kaitai_scope_
class = G_KAITAI_PARSER_CLASS(g_kaitai_instance_parent_class);
- result = class->parse(G_KAITAI_PARSER(inst), locals, work_area, &forced_pos, record);
+ init_evmpa_from_vmpa(&epos, &forced_pos);
+
+ class->parse(G_KAITAI_PARSER(inst), locals, work_area, &epos, &result);
exit_with_content:
@@ -476,3 +434,70 @@ static bool g_kaitai_instance_parse_content(GKaitaiInstance *inst, kaitai_scope_
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : inst = lecteur d'instance Kaitai à consulter. *
+* locals = variables locales pour les résolutions de types. *
+* value = valeur à sauvegarder sous une forme générique. [OUT]*
+* *
+* Description : Détermine la valeur d'un élément Kaitai entier calculé. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_kaitai_instance_compute_value(const GKaitaiInstance *inst, const kaitai_scope_t *locals, resolved_value_t *value)
+{
+ bool result; /* Bilan à retourner */
+
+ if (inst->value == NULL)
+ result = false;
+
+ else
+ result = resolve_kaitai_expression_as_any(locals,
+ inst->value,
+ strlen(inst->value),
+ value);
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : inst = structure Kaitai en cours de parcours. *
+* locals = variables locales pour les résolutions de types. *
+* content = données binaires à analyser et traduire. *
+* epos = tête de lecture courante. [OUT] *
+* record = noeud d'arborescence d'éléments rencontrés. [OUT] *
+* *
+* Description : Parcourt un contenu binaire selon des spécifications Kaitai. *
+* *
+* Retour : Bilan de l'opératon : true pour continuer, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_kaitai_instance_parse_content(GKaitaiInstance *inst, kaitai_scope_t *locals, GBinContent *content, ext_vmpa_t *epos, GMatchRecord **record)
+{
+ bool result; /* Bilan à retourner */
+
+ *record = G_MATCH_RECORD(g_record_delayed_new(inst, locals, inst->value == NULL ? content : NULL));
+
+ result = (*record != NULL);
+
+ return result;
+
+}
diff --git a/plugins/kaitai/parsers/instance.h b/plugins/kaitai/parsers/instance.h
index a9aee9a..4594137 100644
--- a/plugins/kaitai/parsers/instance.h
+++ b/plugins/kaitai/parsers/instance.h
@@ -60,6 +60,9 @@ GKaitaiInstance *g_kaitai_instance_new(GYamlNode *);
/* Indique le nom attribué à une instance Kaitai. */
const char *g_kaitai_instance_get_name(const GKaitaiInstance *);
+/* Détermine la valeur effective d'un élément Kaitai dynamique. */
+GMatchRecord *g_kaitai_instance_compute_real_record(const GKaitaiInstance *, const kaitai_scope_t *, GBinContent *);
+
/* Détermine la valeur d'un élément Kaitai entier calculé. */
bool g_kaitai_instance_compute_value(const GKaitaiInstance *, const kaitai_scope_t *, resolved_value_t *);
diff --git a/plugins/kaitai/parsers/meta-int.h b/plugins/kaitai/parsers/meta-int.h
index 7d847ef..5fe9174 100644
--- a/plugins/kaitai/parsers/meta-int.h
+++ b/plugins/kaitai/parsers/meta-int.h
@@ -39,6 +39,9 @@ struct _GKaitaiMeta
SourceEndian endian; /* Boutisme par défaut */
+ char **dependencies; /* Définitions à importer */
+ size_t dep_count; /* Nombre de ces définitions */
+
};
/* Description globale d'une définition Kaitai (classe) */
diff --git a/plugins/kaitai/parsers/meta.c b/plugins/kaitai/parsers/meta.c
index dc30c73..132eefd 100644
--- a/plugins/kaitai/parsers/meta.c
+++ b/plugins/kaitai/parsers/meta.c
@@ -97,6 +97,9 @@ static void g_kaitai_meta_init(GKaitaiMeta *meta)
meta->endian = SRE_LITTLE;
+ meta->dependencies = NULL;
+ meta->dep_count = 0;
+
}
@@ -133,12 +136,20 @@ static void g_kaitai_meta_dispose(GKaitaiMeta *meta)
static void g_kaitai_meta_finalize(GKaitaiMeta *meta)
{
+ size_t i; /* Boucle de parcours */
+
if (meta->id != NULL)
free(meta->id);
if (meta->title != NULL)
free(meta->title);
+ for (i = 0; i < meta->dep_count; i++)
+ free(meta->dependencies[i]);
+
+ if (meta->dependencies != NULL)
+ free(meta->dependencies);
+
G_OBJECT_CLASS(g_kaitai_meta_parent_class)->finalize(G_OBJECT(meta));
}
@@ -188,6 +199,9 @@ bool g_kaitai_meta_create(GKaitaiMeta *meta, GYamlNode *parent)
bool result; /* Bilan à retourner */
GYamlNode *node; /* Noeud particulier présent */
const char *value; /* Valeur Yaml particulière */
+ GYamlNode **nodes; /* Eventuels noeuds trouvés */
+ size_t count; /* Quantité de ces noeuds */
+ size_t i; /* Boucle de parcours */
result = true;
@@ -245,6 +259,45 @@ bool g_kaitai_meta_create(GKaitaiMeta *meta, GYamlNode *parent)
}
+ /* Imports */
+
+ node = g_yaml_node_find_first_by_path(parent, "/meta/imports/");
+
+ if (node != NULL)
+ {
+ result = G_IS_YAML_COLLEC(node);
+
+ if (result)
+ {
+ nodes = g_yaml_collection_get_nodes(G_YAML_COLLEC(node), &count);
+
+ for (i = 0; i < count; i++)
+ {
+ if (!G_IS_YAML_PAIR(nodes[i]))
+ break;
+
+ value = g_yaml_pair_get_key(G_YAML_PAIR(nodes[i]));
+
+ meta->dependencies = realloc(meta->dependencies, ++meta->dep_count * sizeof(char *));
+
+ meta->dependencies[meta->dep_count - 1] = strdup(value);
+
+ g_object_unref(G_OBJECT(nodes[i]));
+
+ }
+
+ result = (i == count);
+
+ for (; i < count; i++)
+ g_object_unref(G_OBJECT(nodes[i]));
+
+ if (nodes != NULL)
+ free(nodes);
+
+ }
+
+ }
+
return result;
}
@@ -279,7 +332,7 @@ const char *g_kaitai_meta_get_id(const GKaitaiMeta *meta)
* *
* Description : Fournit la désignation humaine d'une définiton Kaitai. *
* *
-* Retour : Intitulé de définition OU NULL. *
+* Retour : Intitulé de définition ou NULL. *
* *
* Remarques : - *
* *
@@ -317,3 +370,29 @@ SourceEndian g_kaitai_meta_get_endian(const GKaitaiMeta *meta)
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : meta = description globale à consulter. *
+* count = quantité de définitions à importer. [OUT] *
+* *
+* Description : Indique la liste des définitions à importer. *
+* *
+* Retour : Liste de désignations de définitions ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const char * const *g_kaitai_meta_get_dependencies(const GKaitaiMeta *meta, size_t *count)
+{
+ const char * const *result; /* Liste à retourner */
+
+ result = (const char * const *)meta->dependencies;
+
+ *count = meta->dep_count;
+
+ return result;
+
+}
diff --git a/plugins/kaitai/parsers/meta.h b/plugins/kaitai/parsers/meta.h
index 3797823..b8b685d 100644
--- a/plugins/kaitai/parsers/meta.h
+++ b/plugins/kaitai/parsers/meta.h
@@ -63,6 +63,9 @@ const char *g_kaitai_meta_get_title(const GKaitaiMeta *);
/* Indique le boustime observé par défaut par une définiton. */
SourceEndian g_kaitai_meta_get_endian(const GKaitaiMeta *);
+/* Indique la liste des définitions à importer. */
+const char * const *g_kaitai_meta_get_dependencies(const GKaitaiMeta *, size_t *);
+
#endif /* _PLUGINS_KAITAI_PARSERS_META_H */
diff --git a/plugins/kaitai/parsers/struct-int.h b/plugins/kaitai/parsers/struct-int.h
index f34be32..6eb6e53 100644
--- a/plugins/kaitai/parsers/struct-int.h
+++ b/plugins/kaitai/parsers/struct-int.h
@@ -37,6 +37,8 @@ struct _GKaitaiStruct
{
GKaitaiParser parent; /* A laisser en premier */
+ char *filename; /* Eventuelle source de données*/
+
GKaitaiMeta *meta; /* Description globale */
GKaitaiAttribute **seq_items; /* Sous-attributs présents */
diff --git a/plugins/kaitai/parsers/struct.c b/plugins/kaitai/parsers/struct.c
index 128a788..d447cf3 100644
--- a/plugins/kaitai/parsers/struct.c
+++ b/plugins/kaitai/parsers/struct.c
@@ -33,6 +33,7 @@
#include "struct-int.h"
+#include "../import.h"
#include "../parser.h"
#include "../records/empty.h"
#include "../records/group.h"
@@ -54,13 +55,16 @@ static void g_kaitai_structure_dispose(GKaitaiStruct *);
/* Procède à la libération totale de la mémoire. */
static void g_kaitai_structure_finalize(GKaitaiStruct *);
+/* Charge les éventuelles dépendances de la définition. */
+static bool g_kaitai_structure_load_imports(GKaitaiStruct *);
+
/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
/* Parcourt un contenu binaire selon des spécifications Kaitai. */
-static bool g_kaitai_structure_parse_content(GKaitaiStruct *, kaitai_scope_t *, GBinContent *, vmpa2t *, GMatchRecord **);
+static bool g_kaitai_structure_parse_content(GKaitaiStruct *, kaitai_scope_t *, GBinContent *, ext_vmpa_t *, GMatchRecord **);
@@ -116,6 +120,8 @@ static void g_kaitai_structure_class_init(GKaitaiStructClass *klass)
static void g_kaitai_structure_init(GKaitaiStruct *kstruct)
{
+ kstruct->filename = NULL;
+
kstruct->meta = NULL;
kstruct->seq_items = NULL;
@@ -182,6 +188,9 @@ static void g_kaitai_structure_dispose(GKaitaiStruct *kstruct)
static void g_kaitai_structure_finalize(GKaitaiStruct *kstruct)
{
+ if (kstruct->filename != NULL)
+ free(kstruct->filename);
+
if (kstruct->seq_items != NULL)
free(kstruct->seq_items);
@@ -305,6 +314,8 @@ bool g_kaitai_structure_create_from_file(GKaitaiStruct *kstruct, const char *fil
bool result; /* Bilan à retourner */
GYamlNode *root; /* Noeud racine YAML */
+ kstruct->filename = strdup(filename);
+
root = parse_yaml_from_file(filename);
if (root != NULL)
@@ -343,6 +354,7 @@ bool g_kaitai_structure_create(GKaitaiStruct *kstruct, GYamlNode *parent)
GYamlNode **nodes; /* Eventuels noeuds trouvés */
size_t count; /* Quantité de ces noeuds */
size_t i; /* Boucle de parcours */
+ size_t first; /* Premier emplacement dispo. */
bool failed; /* Détection d'un échec */
result = false;
@@ -352,6 +364,9 @@ bool g_kaitai_structure_create(GKaitaiStruct *kstruct, GYamlNode *parent)
kstruct->meta = g_kaitai_meta_new(parent);
assert(kstruct->meta != NULL);
+ result = g_kaitai_structure_load_imports(kstruct);
+ if (!result) goto bad_loading;
+
/* Séquence */
collec = g_yaml_node_find_first_by_path(parent, "/seq/");
@@ -406,13 +421,15 @@ bool g_kaitai_structure_create(GKaitaiStruct *kstruct, GYamlNode *parent)
if (count > 0)
{
- kstruct->types = calloc(count, sizeof(GKaitaiType *));
- kstruct->types_count = count;
+ first = kstruct->types_count;
+
+ kstruct->types_count += count;
+ kstruct->types = realloc(kstruct->types, kstruct->types_count * sizeof(GKaitaiType *));
for (i = 0; i < count; i++)
{
- kstruct->types[i] = g_kaitai_type_new(nodes[i]);
- if (kstruct->types[i] == NULL) break;
+ kstruct->types[first + i] = g_kaitai_type_new(nodes[i]);
+ if (kstruct->types[first + i] == NULL) break;
g_object_unref(G_OBJECT(nodes[i]));
@@ -529,6 +546,49 @@ bool g_kaitai_structure_create(GKaitaiStruct *kstruct, GYamlNode *parent)
/******************************************************************************
* *
+* Paramètres : kstruct = lecteur de définition à initialiser pleinement. *
+* *
+* Description : Charge les éventuelles dépendances de la définition. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_kaitai_structure_load_imports(GKaitaiStruct *kstruct)
+{
+ bool result; /* Bilan d'opération à renvoyer*/
+ const char * const *dependencies; /* Liste d'imports requis */
+ size_t count; /* Quantité de ces imports */
+ size_t i; /* Boucle de parcours */
+ GKaitaiType *imported; /* Structure importée */
+
+ result = true;
+
+ dependencies = g_kaitai_meta_get_dependencies(kstruct->meta, &count);
+
+ for (i = 0; i < count; i++)
+ {
+ imported = import_kaitai_definition(dependencies[i], kstruct->filename);
+ if (imported == NULL) break;
+
+ kstruct->types_count++;
+ kstruct->types = realloc(kstruct->types, kstruct->types_count * sizeof(GKaitaiType *));
+
+ kstruct->types[kstruct->types_count - 1] = imported;
+
+ }
+
+ result = (i == count);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : kstruct = structure Kaitai à consulter. *
* *
* Description : Fournit la description globale d'une définition Kaitai. *
@@ -624,6 +684,9 @@ GKaitaiType *g_kaitai_structure_find_sub_type(const GKaitaiStruct *kstruct, cons
break;
}
+ result = g_kaitai_structure_find_sub_type(G_KAITAI_STRUCT(kstruct->types[i]), name);
+ if (result != NULL) break;
+
}
return result;
@@ -649,13 +712,15 @@ GMatchRecord *g_kaitai_structure_parse(GKaitaiStruct *kstruct, GBinContent *cont
GMatchRecord *result; /* Arborescence à retourner */
vmpa2t pos; /* Tête de lecture */
kaitai_scope_t locals; /* Variables locales */
- bool status; /* Bilan de l'analyse */
+ ext_vmpa_t epos; /* Tête de lecture complète */
g_binary_content_compute_start_pos(content, &pos);
init_record_scope(&locals, kstruct->meta);
- status = g_kaitai_parser_parse_content(G_KAITAI_PARSER(kstruct), &locals, content, &pos, &result);
+ init_evmpa_from_vmpa(&epos, &pos);
+
+ g_kaitai_parser_parse_content(G_KAITAI_PARSER(kstruct), &locals, content, &epos, &result);
return result;
@@ -673,7 +738,7 @@ GMatchRecord *g_kaitai_structure_parse(GKaitaiStruct *kstruct, GBinContent *cont
* Paramètres : kstruct = structure Kaitai en cours de parcours. *
* locals = variables locales pour les résolutions de types. *
* content = données binaires à analyser et traduire. *
-* pos = tête de lecture courante. [OUT] *
+* epos = tête de lecture courante. [OUT] *
* record = noeud d'arborescence d'éléments rencontrés. [OUT] *
* *
* Description : Parcourt un contenu binaire selon des spécifications Kaitai. *
@@ -684,7 +749,7 @@ GMatchRecord *g_kaitai_structure_parse(GKaitaiStruct *kstruct, GBinContent *cont
* *
******************************************************************************/
-static bool g_kaitai_structure_parse_content(GKaitaiStruct *kstruct, kaitai_scope_t *locals, GBinContent *content, vmpa2t *pos, GMatchRecord **record)
+static bool g_kaitai_structure_parse_content(GKaitaiStruct *kstruct, kaitai_scope_t *locals, GBinContent *content, ext_vmpa_t *epos, GMatchRecord **record)
{
bool result; /* Bilan à retourner */
GRecordGroup *group; /* Ensemble à constituer */
@@ -697,7 +762,7 @@ static bool g_kaitai_structure_parse_content(GKaitaiStruct *kstruct, kaitai_scop
/* Si le groupe est vide */
if ((kstruct->seq_items_count + kstruct->instances_count) == 0)
{
- *record = G_MATCH_RECORD(g_record_empty_new(G_KAITAI_PARSER(kstruct), content, pos));
+ *record = G_MATCH_RECORD(g_record_empty_new(G_KAITAI_PARSER(kstruct), content, &epos->base));
if (locals->root == NULL)
locals->root = *record;
@@ -716,10 +781,18 @@ static bool g_kaitai_structure_parse_content(GKaitaiStruct *kstruct, kaitai_scop
old = locals->parent;
locals->parent = *record;
- for (i = 0; i < kstruct->seq_items_count; i++)
+ /**
+ * Les instances sont à charger avant les éléments fixes car
+ * des références au premières peuvent être attendues dans ces derniers.
+ *
+ * Les évolutions de la tête de lecture n'ont en revanche normalement
+ * pas d'incidence sur le chargement des éléments fixes.
+ */
+
+ for (i = 0; i < kstruct->instances_count; i++)
{
- result = g_kaitai_parser_parse_content(G_KAITAI_PARSER(kstruct->seq_items[i]),
- locals, content, pos, &child);
+ result = g_kaitai_parser_parse_content(G_KAITAI_PARSER(kstruct->instances[i]),
+ locals, content, epos, &child);
if (!result) goto exit;
if (child != NULL)
@@ -730,10 +803,16 @@ static bool g_kaitai_structure_parse_content(GKaitaiStruct *kstruct, kaitai_scop
}
- for (i = 0; i < kstruct->instances_count; i++)
+ /**
+ * Seconde phase.
+ */
+
+ locals->parent = *record;
+
+ for (i = 0; i < kstruct->seq_items_count; i++)
{
- result = g_kaitai_parser_parse_content(G_KAITAI_PARSER(kstruct->instances[i]),
- locals, content, pos, &child);
+ result = g_kaitai_parser_parse_content(G_KAITAI_PARSER(kstruct->seq_items[i]),
+ locals, content, epos, &child);
if (!result) goto exit;
if (child != NULL)
@@ -748,6 +827,9 @@ static bool g_kaitai_structure_parse_content(GKaitaiStruct *kstruct, kaitai_scop
locals->parent = old;
+ if (!result)
+ g_clear_object(record);
+
}
return result;
diff --git a/plugins/kaitai/parsers/switch.c b/plugins/kaitai/parsers/switch.c
index c823f27..6cfc96b 100644
--- a/plugins/kaitai/parsers/switch.c
+++ b/plugins/kaitai/parsers/switch.c
@@ -83,7 +83,7 @@ static void g_kaitai_switch_finalize(GKaitaiSwitch *);
/* Parcourt un contenu binaire selon des spécifications Kaitai. */
-static bool g_kaitai_switch_parse_content(GKaitaiSwitch *, kaitai_scope_t *, GBinContent *, vmpa2t *, GMatchRecord **);
+static bool g_kaitai_switch_parse_content(GKaitaiSwitch *, kaitai_scope_t *, GBinContent *, ext_vmpa_t *, GMatchRecord **);
@@ -285,7 +285,7 @@ static const char *is_suitable_switch_case_for_integer(const switch_case_t *swca
{
if (value->type == GVT_UNSIGNED_INTEGER)
{
- unsigned_conv = strtoull(swcase->value, NULL, 10);
+ unsigned_conv = strtoull(swcase->value, NULL, 0);
valid = (errno != ERANGE && errno != EINVAL);
@@ -295,7 +295,7 @@ static const char *is_suitable_switch_case_for_integer(const switch_case_t *swca
}
else
{
- signed_conv = strtoll(swcase->value, NULL, 10);
+ signed_conv = strtoll(swcase->value, NULL, 0);
valid = (errno != ERANGE && errno != EINVAL);
@@ -569,7 +569,7 @@ bool g_kaitai_switch_create(GKaitaiSwitch *kswitch, GYamlNode *parent, GKaitaiAt
* Paramètres : kswitch = structure Kaitai en cours de parcours. *
* locals = variables locales pour les résolutions de types. *
* content = données binaires à analyser et traduire. *
-* pos = tête de lecture courante. [OUT] *
+* epos = tête de lecture courante. [OUT] *
* record = noeud d'arborescence d'éléments rencontrés. [OUT] *
* *
* Description : Parcourt un contenu binaire selon des spécifications Kaitai. *
@@ -580,127 +580,65 @@ bool g_kaitai_switch_create(GKaitaiSwitch *kswitch, GYamlNode *parent, GKaitaiAt
* *
******************************************************************************/
-static bool g_kaitai_switch_parse_content(GKaitaiSwitch *kswitch, kaitai_scope_t *locals, GBinContent *content, vmpa2t *pos, GMatchRecord **record)
+static bool g_kaitai_switch_parse_content(GKaitaiSwitch *kswitch, kaitai_scope_t *locals, GBinContent *content, ext_vmpa_t *epos, GMatchRecord **record)
{
bool result; /* Bilan à retourner */
- GMatchRecord *reference; /* Correspondance à utiliser */
- GKaitaiParser *creator; /* Lecteur d'origine */
- KaitaiAttributePayload payload; /* Type de charge supportée */
- BaseType basic; /* Type de base reconnu */
- bool is_string; /* Type lié à une chaîne ? */
-#ifndef NDEBUG
- bool status; /* Bilan d'une consultation */
-#endif
const char *final_type; /* Type à utiliser au final */
resolved_value_t value; /* Valeur de cible entière */
+ bool status; /* Bilan intermédiaire */
size_t i; /* Boucle de parcours */
GKaitaiAttribute *attrib; /* Lecteur approprié */
- result = false;
-
- /* Détermination de la forme de comparaison */
-
- reference = g_match_record_find_by_name(locals->parent,
- kswitch->target, strlen(kswitch->target),
- DIRECT_SEARCH_DEEP_LEVEL);
-
- if (reference == NULL)
- goto exit;
-
- creator = g_match_record_get_creator(reference);
-
- if (creator == NULL)
- goto exit_with_ref;
-
- if (!G_IS_KAITAI_ATTRIBUTE(creator))
- goto exit_with_creator;
-
- payload = g_kaitai_attribute_get_payload(G_KAITAI_ATTRIBUTE(creator));
-
- if ((payload & KAP_BASIC_TYPE) == 0)
- goto exit_with_creator;
-
-#ifndef NDEBUG
- status = g_kaitai_attribute_get_basic_type(G_KAITAI_ATTRIBUTE(creator), &basic, &is_string);
- assert(status);
-#else
- g_kaitai_attribute_get_basic_type(G_KAITAI_ATTRIBUTE(creator), &basic, &is_string);
-#endif
-
- /* Détermination du type visé */
+ result = true;
final_type = NULL;
- if (is_string)
- {
- result = resolve_kaitai_expression_as_bytes(locals,
- kswitch->target,
- strlen(kswitch->target),
- &value);
- if (!result) goto exit_with_creator;
+ /* Tenative n°1 : version "entier" */
+
+ status = resolve_kaitai_expression_as_integer(locals, kswitch->target, strlen(kswitch->target), &value);
+ if (status)
for (i = 0; i < kswitch->count; i++)
{
- final_type = is_suitable_switch_case_for_bytes(kswitch->cases[i], &value);
+ final_type = is_suitable_switch_case_for_integer(kswitch->cases[i], locals, &value);
if (final_type != NULL)
- break;
+ goto next_step;
}
- }
-
- else
- {
- if (basic == BTP_UCHAR || basic == BTP_USHORT || basic == BTP_UINT || basic == BTP_ULONG_LONG)
- {
- result = resolve_kaitai_expression_as_integer(locals,
- kswitch->target,
- strlen(kswitch->target),
- &value);
- if (!result) goto exit_with_creator;
+ status = resolve_kaitai_expression_as_bytes(locals, kswitch->target, strlen(kswitch->target), &value);
- for (i = 0; i < kswitch->count; i++)
- {
- final_type = is_suitable_switch_case_for_integer(kswitch->cases[i], locals, &value);
+ /* Tenative n°1 : version "chaîne" */
- if (final_type != NULL)
- break;
+ if (status)
+ for (i = 0; i < kswitch->count; i++)
+ {
+ final_type = is_suitable_switch_case_for_bytes(kswitch->cases[i], &value);
- }
+ if (final_type != NULL)
+ goto next_step;
}
- else
- printf("other type: %u\n", basic);
-
- }
-
if (final_type == NULL && kswitch->defcase != NULL)
final_type = kswitch->defcase->type;
+ next_step:
+
/* Mise en place d'un attribut et analyse */
if (final_type != NULL)
{
attrib = g_kaitai_attribute_dup_for_user_type(kswitch->generic, final_type);
- result = g_kaitai_parser_parse_content(G_KAITAI_PARSER(attrib), locals, content, pos, record);
+ result = g_kaitai_parser_parse_content(G_KAITAI_PARSER(attrib), locals, content, epos, record);
g_object_unref(G_OBJECT(attrib));
}
- exit_with_creator:
-
- g_object_unref(G_OBJECT(creator));
-
- exit_with_ref:
-
- g_object_unref(G_OBJECT(reference));
-
- exit:
-
+ return true;
return result;
}
diff --git a/plugins/kaitai/parsers/type-int.h b/plugins/kaitai/parsers/type-int.h
index 4a4d939..535ce57 100644
--- a/plugins/kaitai/parsers/type-int.h
+++ b/plugins/kaitai/parsers/type-int.h
@@ -50,6 +50,9 @@ struct _GKaitaiTypeClass
/* Met en place un lecteur de type pour Kaitai. */
bool g_kaitai_type_create(GKaitaiType *, GYamlNode *);
+/* Met en place un lecteur de type externe pour Kaitai. */
+bool g_kaitai_type_create_as_import(GKaitaiType *, const char *, const char *);
+
#endif /* PLUGINS_KAITAI_PARSERS_TYPE_INT_H */
diff --git a/plugins/kaitai/parsers/type.c b/plugins/kaitai/parsers/type.c
index 30d0373..81efbeb 100644
--- a/plugins/kaitai/parsers/type.c
+++ b/plugins/kaitai/parsers/type.c
@@ -215,6 +215,64 @@ bool g_kaitai_type_create(GKaitaiType *type, GYamlNode *parent)
/******************************************************************************
* *
+* Paramètres : name = nom à attribuer au futur type. *
+* filename = chemin vers une définition Kaitai à charger. *
+* *
+* Description : Construit un lecteur de type externe pour Kaitai. *
+* *
+* Retour : Instance mise en place ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GKaitaiType *g_kaitai_type_new_as_import(const char *name, const char *filename)
+{
+ GKaitaiType *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_KAITAI_TYPE, NULL);
+
+ if (!g_kaitai_type_create_as_import(result, name, filename))
+ g_clear_object(&result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = lecteur de type Kaitai à initialiser pleinement. *
+* name = nom à attribuer au futur type. *
+* filename = chemin vers une définition Kaitai à charger. *
+* *
+* Description : Met en place un lecteur de type externe pour Kaitai. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_kaitai_type_create_as_import(GKaitaiType *type, const char *name, const char *filename)
+{
+ bool result; /* Bilan à retourner */
+
+ /* Extraction du nom */
+
+ type->name = strdup(name);
+
+ /* Extraction des bases du type */
+
+ result = g_kaitai_structure_create_from_file(G_KAITAI_STRUCT(type), filename);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : type = définition de type particulier à consulter. *
* *
* Description : Indique le nom de scène du type représenté. *
diff --git a/plugins/kaitai/parsers/type.h b/plugins/kaitai/parsers/type.h
index 0656c64..d19ab90 100644
--- a/plugins/kaitai/parsers/type.h
+++ b/plugins/kaitai/parsers/type.h
@@ -54,6 +54,9 @@ GType g_kaitai_type_get_type(void);
/* Construit un lecteur de type pour Kaitai. */
GKaitaiType *g_kaitai_type_new(GYamlNode *);
+/* Construit un lecteur de type externe pour Kaitai. */
+GKaitaiType *g_kaitai_type_new_as_import(const char *, const char *);
+
/* Indique le nom de scène du type représenté. */
const char *g_kaitai_type_get_name(const GKaitaiType *);
diff --git a/plugins/kaitai/python/Makefile.am b/plugins/kaitai/python/Makefile.am
index ab40744..f222a66 100644
--- a/plugins/kaitai/python/Makefile.am
+++ b/plugins/kaitai/python/Makefile.am
@@ -11,7 +11,8 @@ libkaitaipython_la_SOURCES = \
libkaitaipython_la_LIBADD = \
parsers/libkaitaipythonparsers.la \
- records/libkaitaipythonrecords.la
+ records/libkaitaipythonrecords.la \
+ rost/libkaitaipythonrost.la
libkaitaipython_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
-I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
@@ -22,4 +23,4 @@ devdir = $(includedir)/chrysalide-$(subdir)
dev_HEADERS = $(libkaitaipython_la_SOURCES:%c=)
-SUBDIRS = parsers records
+SUBDIRS = parsers records rost
diff --git a/plugins/kaitai/python/module.c b/plugins/kaitai/python/module.c
index fa1f9c2..07fb962 100644
--- a/plugins/kaitai/python/module.c
+++ b/plugins/kaitai/python/module.c
@@ -39,6 +39,7 @@
#include "stream.h"
#include "parsers/module.h"
#include "records/module.h"
+#include "rost/module.h"
@@ -89,6 +90,7 @@ bool add_kaitai_module_to_python_module(void)
if (result) result = add_kaitai_parsers_module();
if (result) result = add_kaitai_records_module();
+ if (result) result = add_kaitai_rost_module();
if (!result)
Py_XDECREF(module);
@@ -124,6 +126,7 @@ bool populate_kaitai_module(void)
if (result) result = populate_kaitai_parsers_module();
if (result) result = populate_kaitai_records_module();
+ if (result) result = populate_kaitai_rost_module();
assert(result);
diff --git a/plugins/kaitai/python/parsers/attribute.c b/plugins/kaitai/python/parsers/attribute.c
index c8ea314..c2f3db6 100644
--- a/plugins/kaitai/python/parsers/attribute.c
+++ b/plugins/kaitai/python/parsers/attribute.c
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * attribute.h - équivalent Python du fichier "plugins/kaitai/parsers/attribute.h"
+ * attribute.c - équivalent Python du fichier "plugins/kaitai/parsers/attribute.c"
*
* Copyright (C) 2019 Cyrille Bagard
*
@@ -149,9 +149,14 @@ static PyObject *py_kaitai_attribute_get_raw_id(PyObject *self, void *closure)
attrib = G_KAITAI_ATTRIBUTE(pygobject_get(self));
value = g_kaitai_attribute_get_raw_id(attrib);
- assert(value != NULL);
- result = PyUnicode_FromString(value);
+ if (value == NULL)
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+ else
+ result = PyUnicode_FromString(value);
return result;
diff --git a/plugins/kaitai/python/parsers/meta.c b/plugins/kaitai/python/parsers/meta.c
index 3432640..0bd7bf9 100644
--- a/plugins/kaitai/python/parsers/meta.c
+++ b/plugins/kaitai/python/parsers/meta.c
@@ -50,6 +50,9 @@ static PyObject *py_kaitai_meta_get_id(PyObject *, void *);
/* Fournit la désignation humaine d'une définiton Kaitai. */
static PyObject *py_kaitai_meta_get_title(PyObject *, void *);
+/* Indique la liste des définitions à importer. */
+static PyObject *py_kaitai_meta_get_dependencies(PyObject *, void *);
+
/******************************************************************************
@@ -162,7 +165,7 @@ static PyObject *py_kaitai_meta_get_id(PyObject *self, void *closure)
* *
* Description : Fournit la désignation humaine d'une définiton Kaitai. *
* *
-* Retour : Intitulé de définition OU None. *
+* Retour : Intitulé de définition ou None. *
* *
* Remarques : - *
* *
@@ -206,7 +209,7 @@ static PyObject *py_kaitai_meta_get_title(PyObject *self, void *closure)
* *
* Description : Fournit la désignation humaine d'une définiton Kaitai. *
* *
-* Retour : Intitulé de définition OU None. *
+* Retour : Intitulé de définition ou None. *
* *
* Remarques : - *
* *
@@ -238,6 +241,50 @@ static PyObject *py_kaitai_meta_get_endian(PyObject *self, void *closure)
/******************************************************************************
* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Indique la liste des définitions à importer. *
+* *
+* Retour : Liste de désignations de définitions, vide ou non. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_kaitai_meta_get_dependencies(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GKaitaiMeta *meta; /* Version native de l'objet */
+ const char * const *dependencies; /* Liste d'imports requis */
+ size_t count; /* Quantité de ces imports */
+ size_t i; /* Boucle de parcours */
+
+#define KAITAI_META_DEPENDENCIES_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ dependencies, py_kaitai_meta, \
+ "Tuple of all definitions to import for the current" \
+ " definition.\n" \
+ "\n" \
+ "The result may be an empty string list." \
+)
+
+ meta = G_KAITAI_META(pygobject_get(self));
+
+ dependencies = g_kaitai_meta_get_dependencies(meta, &count);
+
+ result = PyTuple_New(count);
+
+ for (i = 0; i < count; i++)
+ PyTuple_SetItem(result, i, PyUnicode_FromString(dependencies[i]));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : - *
* *
* Description : Fournit un accès à une définition de type à diffuser. *
@@ -258,6 +305,7 @@ PyTypeObject *get_python_kaitai_meta_type(void)
KAITAI_META_ID_ATTRIB,
KAITAI_META_TITLE_ATTRIB,
KAITAI_META_ENDIAN_ATTRIB,
+ KAITAI_META_DEPENDENCIES_ATTRIB,
{ NULL }
};
diff --git a/plugins/kaitai/python/records/Makefile.am b/plugins/kaitai/python/records/Makefile.am
index 1413228..3a3c672 100644
--- a/plugins/kaitai/python/records/Makefile.am
+++ b/plugins/kaitai/python/records/Makefile.am
@@ -2,12 +2,13 @@
noinst_LTLIBRARIES = libkaitaipythonrecords.la
libkaitaipythonrecords_la_SOURCES = \
+ bits.h bits.c \
+ delayed.h delayed.c \
empty.h empty.c \
group.h group.c \
item.h item.c \
list.h list.c \
- module.h module.c \
- value.h value.c
+ module.h module.c
libkaitaipythonrecords_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
-I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
diff --git a/plugins/kaitai/python/records/bits.c b/plugins/kaitai/python/records/bits.c
new file mode 100644
index 0000000..f94148b
--- /dev/null
+++ b/plugins/kaitai/python/records/bits.c
@@ -0,0 +1,318 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * bits.h - équivalent Python du fichier "plugins/kaitai/parsers/bits.h"
+ *
+ * Copyright (C) 2019 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "bits.h"
+
+
+#include <assert.h>
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+#include <plugins/pychrysalide/analysis/content.h>
+#include <plugins/pychrysalide/arch/vmpa.h>
+
+
+#include "../record.h"
+#include "../parsers/attribute.h"
+#include "../../records/bits-int.h"
+
+
+
+CREATE_DYN_CONSTRUCTOR(record_bit_field, G_TYPE_RECORD_BIT_FIELD);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_record_bit_field_init(PyObject *, PyObject *, PyObject *);
+
+/* Lit la valeur d'un élément Kaitai entier représenté. */
+static PyObject *py_record_bit_field_get_value(PyObject *, void *);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet à initialiser (théoriquement). *
+* args = arguments fournis à l'appel. *
+* kwds = arguments de type key=val fournis. *
+* *
+* Description : Initialise une instance sur la base du dérivé de GObject. *
+* *
+* Retour : 0. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int py_record_bit_field_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+#if 0
+ GKaitaiAttribute *attrib; /* Attribut défini créateur */
+ GBinContent *content; /* Contenu binaire analysé */
+ mrange_t range; /* Espace couvert */
+ SourceEndian endian; /* Boutisme à observer */
+ int ret; /* Bilan de lecture des args. */
+ GRecordBitField *field; /* Création GLib à transmettre */
+#endif
+
+#define RECORD_BIT_FIELD_DOC \
+ "The RecordItem class remembers a match between a described attribute and" \
+ " its concret value read from parsed binary data." \
+ "\n" \
+ "Instances can be created using the following constructor:\n" \
+ "\n" \
+ " RecordItem(content, range, endian, attrib)" \
+ "\n" \
+ "Where the *attrib* arguments refers to a" \
+ " pychrysalide.plugins.kaitai.parsers.KaitaiAttribute instance as the" \
+ " creator of the newly created object, *content* points to a" \
+ " pychrysalide.analysis.BinContent instance, *range* is a" \
+ " pychrysalide.arch.mrange object, *endian* states with a" \
+ " pychrysalide.analysis.BinContent.SourceEndian hint the endianness used" \
+ " to read integer values."
+
+ /* Récupération des paramètres */
+
+#if 0 /* FIXME */
+
+ ret = PyArg_ParseTuple(args, "O&O&O&",
+ convert_to_kaitai_attribute, &attrib,
+ convert_to_binary_content, &content,
+ convert_any_to_mrange, &range,
+ convert_to_binary_content, &endian);
+ if (!ret) return -1;
+
+ /* Initialisation d'un objet GLib */
+
+ ret = forward_pygobjet_init(self);
+ if (ret == -1) return -1;
+
+ /* Eléments de base */
+
+ field = G_RECORD_BIT_FIELD(pygobject_get(self));
+
+ if (!g_record_bit_field_create(field, attrib, content, &range, endian))
+ {
+ PyErr_SetString(PyExc_ValueError, _("Unable to create record bit field."));
+ return -1;
+ }
+
+ return 0;
+
+#endif
+
+ PyErr_SetString(PyExc_ValueError, _("Unable to create record bit field at the moment."));
+ return -1;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Lit la valeur d'un élément Kaitai entier représenté. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_record_bit_field_get_value(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GRecordBitField *field; /* Version native de l'élément */
+ resolved_value_t resolved; /* Valeur sous forme générique */
+ bool status; /* Bilan d'opération */
+
+#define RECORD_BIT_FIELD_VALUE_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ value, py_record_bit_field, \
+ "Carried value (as integer), or None in case of error." \
+)
+
+ result = NULL;
+
+ field = G_RECORD_BIT_FIELD(pygobject_get(self));
+
+ status = g_record_bit_field_get_value(field, &resolved);
+
+ if (status)
+ switch (resolved.type)
+ {
+ case GVT_UNSIGNED_INTEGER:
+ result = PyLong_FromUnsignedLongLong(resolved.unsigned_integer);
+ break;
+
+ default:
+ assert(false);
+ result = Py_None;
+ Py_INCREF(result);
+ break;
+
+ }
+
+ else
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Fournit un accès à une définition de type à diffuser. *
+* *
+* Retour : Définition d'objet pour Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyTypeObject *get_python_record_bit_field_type(void)
+{
+ static PyMethodDef py_record_bit_field_methods[] = {
+ { NULL }
+ };
+
+ static PyGetSetDef py_record_bit_field_getseters[] = {
+ RECORD_BIT_FIELD_VALUE_ATTRIB,
+ { NULL }
+ };
+
+ static PyTypeObject py_record_bit_field_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.plugins.kaitai.records.RecordBitField",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+ .tp_doc = RECORD_BIT_FIELD_DOC,
+
+ .tp_methods = py_record_bit_field_methods,
+ .tp_getset = py_record_bit_field_getseters,
+
+ .tp_init = py_record_bit_field_init,
+ .tp_new = py_record_bit_field_new,
+
+ };
+
+ return &py_record_bit_field_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Prend en charge l'objet 'pychrysalide.....RecordBitField. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool ensure_python_record_bit_field_is_registered(void)
+{
+ PyTypeObject *type; /* Type Python 'RecordItem' */
+ PyObject *module; /* Module à recompléter */
+ PyObject *dict; /* Dictionnaire du module */
+
+ type = get_python_record_bit_field_type();
+
+ if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+ {
+ module = get_access_to_python_module("pychrysalide.plugins.kaitai.records");
+
+ dict = PyModule_GetDict(module);
+
+ if (!ensure_python_match_record_is_registered())
+ return false;
+
+ if (!register_class_for_pygobject(dict, G_TYPE_RECORD_BIT_FIELD, 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 correspondance attribut/binaire. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_record_bit_field(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_record_bit_field_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 record bit field");
+ break;
+
+ case 1:
+ *((GRecordBitField **)dst) = G_RECORD_BIT_FIELD(pygobject_get(arg));
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/kaitai/python/records/bits.h b/plugins/kaitai/python/records/bits.h
new file mode 100644
index 0000000..6c833bb
--- /dev/null
+++ b/plugins/kaitai/python/records/bits.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * bits.h - prototypes pour l'équivalent Python du fichier "plugins/kaitai/records/bits.h"
+ *
+ * Copyright (C) 2019 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef _PLUGINS_KAITAI_PYTHON_RECORDS_BITS_H
+#define _PLUGINS_KAITAI_PYTHON_RECORDS_BITS_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_record_bit_field_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.plugins.kaitai.records.RecordBitField'. */
+bool ensure_python_record_bit_field_is_registered(void);
+
+/* Tente de convertir en correspondance attribut/binaire. */
+int convert_to_record_bit_field(PyObject *, void *);
+
+
+
+#endif /* _PLUGINS_KAITAI_PYTHON_RECORDS_BITS_H */
diff --git a/plugins/kaitai/python/records/value.c b/plugins/kaitai/python/records/delayed.c
index bd4ad74..32e3db1 100644
--- a/plugins/kaitai/python/records/value.c
+++ b/plugins/kaitai/python/records/delayed.c
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * value.c - équivalent Python du fichier "plugins/kaitai/parsers/value.c"
+ * delayed.c - équivalent Python du fichier "plugins/kaitai/parsers/delayed.c"
*
* Copyright (C) 2019 Cyrille Bagard
*
@@ -22,7 +22,7 @@
*/
-#include "value.h"
+#include "delayed.h"
#include <assert.h>
@@ -40,17 +40,17 @@
#include "../record.h"
#include "../scope.h"
#include "../parsers/instance.h"
-#include "../../records/value-int.h"
+#include "../../records/delayed-int.h"
-CREATE_DYN_CONSTRUCTOR(record_value, G_TYPE_RECORD_VALUE);
+CREATE_DYN_CONSTRUCTOR(record_delayed, G_TYPE_RECORD_DELAYED);
/* Initialise une instance sur la base du dérivé de GObject. */
-static int py_record_value_init(PyObject *, PyObject *, PyObject *);
+static int py_record_delayed_init(PyObject *, PyObject *, PyObject *);
/* Lit la valeur d'un élément Kaitai entier représenté. */
-static PyObject *py_record_value_get_value(PyObject *, void *);
+static PyObject *py_record_delayed_get_value(PyObject *, void *);
@@ -68,31 +68,37 @@ static PyObject *py_record_value_get_value(PyObject *, void *);
* *
******************************************************************************/
-static int py_record_value_init(PyObject *self, PyObject *args, PyObject *kwds)
+static int py_record_delayed_init(PyObject *self, PyObject *args, PyObject *kwds)
{
GKaitaiInstance *inst; /* Instance définie créatrice */
kaitai_scope_t *locals; /* Environnement local */
+ GBinContent *content; /* Contenu binaire analysé */
int ret; /* Bilan de lecture des args. */
- GRecordValue *value; /* Création GLib à transmettre */
+ GRecordDelayed *delayed; /* Création GLib à transmettre */
-#define RECORD_VALUE_DOC \
- "The RecordValue class stores a link to an instance used to compute a" \
+#define RECORD_DELAYED_DOC \
+ "The RecordDelayed class stores a link to an instance used to compute a" \
" given value." \
"\n" \
"Instances can be created using the following constructor:\n" \
"\n" \
- " RecordValue(inst, locals)" \
+ " RecordDelayed(inst, locals, content)" \
"\n" \
"Where the *inst* arguments refers to a" \
" pychrysalide.plugins.kaitai.parsers.KaitaiInstance instance as the" \
" creator of the newly created object, *locals* points to a" \
- " pychrysalide.plugins.kaitai.KaitaiScope structure used as current scope."
+ " pychrysalide.plugins.kaitai.KaitaiScope structure used as current scope." \
+ " The *content* argument is a pychrysalide.analysis.BinContent instance if" \
+ " the delayed instance does not define a direct value."
/* Récupération des paramètres */
- ret = PyArg_ParseTuple(args, "O&O&",
+ content = NULL;
+
+ ret = PyArg_ParseTuple(args, "O&O&|O&",
convert_to_kaitai_instance, &inst,
- convert_to_kaitai_scope, &locals);
+ convert_to_kaitai_scope, &locals,
+ convert_to_binary_content_or_none, &content);
if (!ret) return -1;
/* Initialisation d'un objet GLib */
@@ -102,11 +108,11 @@ static int py_record_value_init(PyObject *self, PyObject *args, PyObject *kwds)
/* Eléments de base */
- value = G_RECORD_VALUE(pygobject_get(self));
+ delayed = G_RECORD_DELAYED(pygobject_get(self));
- if (!g_record_value_create(value, inst, locals))
+ if (!g_record_delayed_create(delayed, inst, locals, content))
{
- PyErr_SetString(PyExc_ValueError, _("Unable to create record value."));
+ PyErr_SetString(PyExc_ValueError, _("Unable to create record delayed."));
return -1;
}
@@ -128,24 +134,24 @@ static int py_record_value_init(PyObject *self, PyObject *args, PyObject *kwds)
* *
******************************************************************************/
-static PyObject *py_record_value_get_value(PyObject *self, void *closure)
+static PyObject *py_record_delayed_get_value(PyObject *self, void *closure)
{
PyObject *result; /* Valeur à retourner */
- GRecordValue *value; /* Version native de l'élément */
+ GRecordDelayed *delayed; /* Version native de l'élément */
resolved_value_t resolved; /* Valeur sous forme générique */
bool status; /* Bilan d'opération */
-#define RECORD_VALUE_VALUE_ATTRIB PYTHON_GET_DEF_FULL \
+#define RECORD_DELAYED_VALUE_ATTRIB PYTHON_GET_DEF_FULL \
( \
- value, py_record_value, \
+ value, py_record_delayed, \
"Carried value (as integer, bytes), or None in case of error." \
)
result = NULL;
- value = G_RECORD_VALUE(pygobject_get(self));
+ delayed = G_RECORD_DELAYED(pygobject_get(self));
- status = g_record_value_compute_and_aggregate_value(value, &resolved);
+ status = g_record_delayed_compute_and_aggregate_value(delayed, &resolved);
if (status)
switch (resolved.type)
@@ -216,37 +222,37 @@ static PyObject *py_record_value_get_value(PyObject *self, void *closure)
* *
******************************************************************************/
-PyTypeObject *get_python_record_value_type(void)
+PyTypeObject *get_python_record_delayed_type(void)
{
- static PyMethodDef py_record_value_methods[] = {
+ static PyMethodDef py_record_delayed_methods[] = {
{ NULL }
};
- static PyGetSetDef py_record_value_getseters[] = {
- RECORD_VALUE_VALUE_ATTRIB,
+ static PyGetSetDef py_record_delayed_getseters[] = {
+ RECORD_DELAYED_VALUE_ATTRIB,
{ NULL }
};
- static PyTypeObject py_record_value_type = {
+ static PyTypeObject py_record_delayed_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "pychrysalide.plugins.kaitai.records.RecordValue",
+ .tp_name = "pychrysalide.plugins.kaitai.records.RecordDelayed",
.tp_basicsize = sizeof(PyGObject),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- .tp_doc = RECORD_VALUE_DOC,
+ .tp_doc = RECORD_DELAYED_DOC,
- .tp_methods = py_record_value_methods,
- .tp_getset = py_record_value_getseters,
+ .tp_methods = py_record_delayed_methods,
+ .tp_getset = py_record_delayed_getseters,
- .tp_init = py_record_value_init,
- .tp_new = py_record_value_new,
+ .tp_init = py_record_delayed_init,
+ .tp_new = py_record_delayed_new,
};
- return &py_record_value_type;
+ return &py_record_delayed_type;
}
@@ -255,7 +261,7 @@ PyTypeObject *get_python_record_value_type(void)
* *
* Paramètres : - *
* *
-* Description : Prend en charge l'objet 'pychrysalide...records.RecordValue. *
+* Description : Prend en charge l'objet 'pychrysalide..records.RecordDelayed.*
* *
* Retour : Bilan de l'opération. *
* *
@@ -263,13 +269,13 @@ PyTypeObject *get_python_record_value_type(void)
* *
******************************************************************************/
-bool ensure_python_record_value_is_registered(void)
+bool ensure_python_record_delayed_is_registered(void)
{
- PyTypeObject *type; /* Type Python 'RecordValue' */
+ PyTypeObject *type; /* Type Python 'RecordDelayed' */
PyObject *module; /* Module à recompléter */
PyObject *dict; /* Dictionnaire du module */
- type = get_python_record_value_type();
+ type = get_python_record_delayed_type();
if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
{
@@ -280,7 +286,7 @@ bool ensure_python_record_value_is_registered(void)
if (!ensure_python_match_record_is_registered())
return false;
- if (!register_class_for_pygobject(dict, G_TYPE_RECORD_VALUE, type))
+ if (!register_class_for_pygobject(dict, G_TYPE_RECORD_DELAYED, type))
return false;
}
@@ -303,11 +309,11 @@ bool ensure_python_record_value_is_registered(void)
* *
******************************************************************************/
-int convert_to_record_value(PyObject *arg, void *dst)
+int convert_to_record_delayed(PyObject *arg, void *dst)
{
int result; /* Bilan à retourner */
- result = PyObject_IsInstance(arg, (PyObject *)get_python_record_value_type());
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_record_delayed_type());
switch (result)
{
@@ -317,11 +323,11 @@ int convert_to_record_value(PyObject *arg, void *dst)
break;
case 0:
- PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to record value");
+ PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to record delayed");
break;
case 1:
- *((GRecordValue **)dst) = G_RECORD_VALUE(pygobject_get(arg));
+ *((GRecordDelayed **)dst) = G_RECORD_DELAYED(pygobject_get(arg));
break;
default:
diff --git a/plugins/kaitai/python/records/value.h b/plugins/kaitai/python/records/delayed.h
index 16cadcb..ba2d23a 100644
--- a/plugins/kaitai/python/records/value.h
+++ b/plugins/kaitai/python/records/delayed.h
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * value.h - prototypes pour l'équivalent Python du fichier "plugins/kaitai/records/value.h"
+ * delayed.h - prototypes pour l'équivalent Python du fichier "plugins/kaitai/records/delayed.h"
*
* Copyright (C) 2019 Cyrille Bagard
*
@@ -22,8 +22,8 @@
*/
-#ifndef _PLUGINS_KAITAI_PYTHON_RECORDS_VALUE_H
-#define _PLUGINS_KAITAI_PYTHON_RECORDS_VALUE_H
+#ifndef _PLUGINS_KAITAI_PYTHON_RECORDS_DELAYED_H
+#define _PLUGINS_KAITAI_PYTHON_RECORDS_DELAYED_H
#include <Python.h>
@@ -32,14 +32,14 @@
/* Fournit un accès à une définition de type à diffuser. */
-PyTypeObject *get_python_record_value_type(void);
+PyTypeObject *get_python_record_delayed_type(void);
-/* Prend en charge l'objet 'pychrysalide.plugins.kaitai.records.RecordValue'. */
-bool ensure_python_record_value_is_registered(void);
+/* Prend en charge l'objet 'pychrysalide.plugins.kaitai.records.RecordDelayed'. */
+bool ensure_python_record_delayed_is_registered(void);
/* Tente de convertir en valeur calculée. */
-int convert_to_record_value(PyObject *, void *);
+int convert_to_record_delayed(PyObject *, void *);
-#endif /* _PLUGINS_KAITAI_PYTHON_RECORDS_VALUE_H */
+#endif /* _PLUGINS_KAITAI_PYTHON_RECORDS_DELAYED_H */
diff --git a/plugins/kaitai/python/records/module.c b/plugins/kaitai/python/records/module.c
index ea33c31..af97434 100644
--- a/plugins/kaitai/python/records/module.c
+++ b/plugins/kaitai/python/records/module.c
@@ -32,11 +32,12 @@
#include <plugins/pychrysalide/helpers.h>
+#include "bits.h"
+#include "delayed.h"
#include "empty.h"
#include "group.h"
#include "item.h"
#include "list.h"
-#include "value.h"
@@ -109,11 +110,12 @@ bool populate_kaitai_records_module(void)
result = true;
+ if (result) result = ensure_python_record_bit_field_is_registered();
+ if (result) result = ensure_python_record_delayed_is_registered();
if (result) result = ensure_python_record_empty_is_registered();
if (result) result = ensure_python_record_group_is_registered();
if (result) result = ensure_python_record_item_is_registered();
if (result) result = ensure_python_record_list_is_registered();
- if (result) result = ensure_python_record_value_is_registered();
assert(result);
diff --git a/plugins/kaitai/python/rost/Makefile.am b/plugins/kaitai/python/rost/Makefile.am
new file mode 100644
index 0000000..cae0419
--- /dev/null
+++ b/plugins/kaitai/python/rost/Makefile.am
@@ -0,0 +1,14 @@
+
+noinst_LTLIBRARIES = libkaitaipythonrost.la
+
+libkaitaipythonrost_la_SOURCES = \
+ module.h module.c \
+ trigger.h trigger.c
+
+libkaitaipythonrost_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+ -I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
+
+
+devdir = $(includedir)/chrysalide-$(subdir)
+
+dev_HEADERS = $(libkaitaipythonrost_la_SOURCES:%c=)
diff --git a/plugins/kaitai/python/rost/module.c b/plugins/kaitai/python/rost/module.c
new file mode 100644
index 0000000..66a5a82
--- /dev/null
+++ b/plugins/kaitai/python/rost/module.c
@@ -0,0 +1,115 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire rost en tant que module
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "module.h"
+
+
+#include <Python.h>
+
+
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+
+
+#include "trigger.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Ajoute le module 'plugins.kaitai.rost' au module Python. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool add_kaitai_rost_module(void)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *super; /* Module à compléter */
+ PyObject *module; /* Sous-module mis en place */
+
+#define PYCHRYSALIDE_PLUGINS_KAITAI_ROST_DOC \
+ "This module creates some glue to extend the ROST features" \
+ " using Kaitai definitions for analyzing and filtering" \
+ " contents."
+
+ static PyModuleDef py_chrysalide_kaitai_rost_module = {
+
+ .m_base = PyModuleDef_HEAD_INIT,
+
+ .m_name = "pychrysalide.plugins.kaitai.rost",
+ .m_doc = PYCHRYSALIDE_PLUGINS_KAITAI_ROST_DOC,
+
+ .m_size = -1,
+
+ };
+
+ result = false;
+
+ super = get_access_to_python_module("pychrysalide.plugins.kaitai");
+
+ module = build_python_module(super, &py_chrysalide_kaitai_rost_module);
+
+ result = (module != NULL);
+
+ assert(result);
+
+ if (!result)
+ Py_XDECREF(module);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Intègre les objets du module 'plugins.kaitai.rost'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool populate_kaitai_rost_module(void)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+ if (result) result = ensure_python_kaitai_trigger_is_registered();
+
+ assert(result);
+
+ return result;
+
+}
diff --git a/plugins/kaitai/python/rost/module.h b/plugins/kaitai/python/rost/module.h
new file mode 100644
index 0000000..8415c2e
--- /dev/null
+++ b/plugins/kaitai/python/rost/module.h
@@ -0,0 +1,41 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire rost en tant que module
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef _PLUGINS_KAITAI_PYTHON_ROST_MODULE_H
+#define _PLUGINS_KAITAI_PYTHON_ROST_MODULE_H
+
+
+#include <stdbool.h>
+
+
+
+/* Ajoute le module 'plugins.kaitai.rost' au module Python. */
+bool add_kaitai_rost_module(void);
+
+/* Intègre les objets du module 'plugins.kaitai.rost'. */
+bool populate_kaitai_rost_module(void);
+
+
+
+#endif /* _PLUGINS_KAITAI_PYTHON_ROST_MODULE_H */
diff --git a/plugins/kaitai/python/rost/trigger.c b/plugins/kaitai/python/rost/trigger.c
new file mode 100644
index 0000000..180ef6e
--- /dev/null
+++ b/plugins/kaitai/python/rost/trigger.c
@@ -0,0 +1,236 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * trigger.c - équivalent Python du fichier "plugins/kaitai/rost/trigger.c"
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "trigger.h"
+
+
+#include <assert.h>
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+#include <plugins/pychrysalide/analysis/scan/item.h>
+
+
+#include "../parsers/struct.h"
+#include "../../parsers/struct.h"
+#include "../../rost/trigger-int.h"
+
+
+
+CREATE_DYN_CONSTRUCTOR(kaitai_trigger, G_TYPE_KAITAI_TRIGGER);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_kaitai_trigger_init(PyObject *, PyObject *, PyObject *);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet à initialiser (théoriquement). *
+* args = arguments fournis à l'appel. *
+* kwds = arguments de type key=val fournis. *
+* *
+* Description : Initialise une instance sur la base du dérivé de GObject. *
+* *
+* Retour : 0. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int py_kaitai_trigger_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ GKaitaiStruct *kstruct; /* Définition Kaitai en place */
+ int ret; /* Bilan de lecture des args. */
+ GKaitaiTrigger *trigger; /* Création GLib à transmettre */
+
+#define KAITAI_TRIGGER_DOC \
+ "The KaitaiTrigger object store an access to a loaded Kaitai definition" \
+ " creates as many as required instances from it when ROST filters contents" \
+ " with the help of the Kaitai module.\n" \
+ "\n" \
+ "Instances can be created using following constructor:\n" \
+ "\n" \
+ " KaitaiTrigger(kstruct)" \
+ "\n" \
+ "Where *kstruct* is a pychrysalide.plugins.kaitai.parsers.KaitaiStruct" \
+ " instance loaded with a valid Kaitai definition."
+
+ /* Récupération des paramètres */
+
+ ret = PyArg_ParseTuple(args, "O&", convert_to_kaitai_structure, &kstruct);
+ if (!ret) return -1;
+
+ /* Initialisation d'un objet GLib */
+
+ ret = forward_pygobjet_init(self);
+ if (ret == -1) return -1;
+
+ /* Eléments de base */
+
+ trigger = G_KAITAI_TRIGGER(pygobject_get(self));
+
+ if (!g_kaitai_trigger_create(trigger, kstruct))
+ {
+ PyErr_SetString(PyExc_ValueError, _("Unable to create Kaitai stream."));
+ return -1;
+
+ }
+
+ return 0;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Fournit un accès à une définition de type à diffuser. *
+* *
+* Retour : Définition d'objet pour Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyTypeObject *get_python_kaitai_trigger_type(void)
+{
+ static PyMethodDef py_kaitai_trigger_methods[] = {
+ { NULL }
+ };
+
+ static PyGetSetDef py_kaitai_trigger_getseters[] = {
+ { NULL }
+ };
+
+ static PyTypeObject py_kaitai_trigger_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.plugins.kaitai.rost.KaitaiTrigger",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+ .tp_doc = KAITAI_TRIGGER_DOC,
+
+ .tp_methods = py_kaitai_trigger_methods,
+ .tp_getset = py_kaitai_trigger_getseters,
+
+ .tp_init = py_kaitai_trigger_init,
+ .tp_new = py_kaitai_trigger_new,
+
+ };
+
+ return &py_kaitai_trigger_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Prend en charge l'objet 'pychrysalide....rost.KaitaiTrigger. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool ensure_python_kaitai_trigger_is_registered(void)
+{
+ PyTypeObject *type; /* Type Python 'RecordEmpty' */
+ PyObject *module; /* Module à recompléter */
+ PyObject *dict; /* Dictionnaire du module */
+
+ type = get_python_kaitai_trigger_type();
+
+ if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+ {
+ module = get_access_to_python_module("pychrysalide.plugins.kaitai.rost");
+
+ dict = PyModule_GetDict(module);
+
+ if (!ensure_python_scan_registered_item_is_registered())
+ return false;
+
+ if (!register_class_for_pygobject(dict, G_TYPE_KAITAI_TRIGGER, type))
+ return false;
+
+ }
+
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : arg = argument quelconque à tenter de convertir. *
+* dst = destination des valeurs récupérées en cas de succès. *
+* *
+* Description : Tente de convertir en accès à une définition Kaitai. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_kaitai_trigger(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_kaitai_trigger_type());
+
+ switch (result)
+ {
+ case -1:
+ /* L'exception est déjà fixée par Python */
+ result = 0;
+ break;
+
+ case 0:
+ PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to Kaitai trigger");
+ break;
+
+ case 1:
+ *((GKaitaiTrigger **)dst) = G_KAITAI_TRIGGER(pygobject_get(arg));
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/kaitai/python/rost/trigger.h b/plugins/kaitai/python/rost/trigger.h
new file mode 100644
index 0000000..44776f7
--- /dev/null
+++ b/plugins/kaitai/python/rost/trigger.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * trigger.h - prototypes pour l'équivalent Python du fichier "plugins/kaitai/rost/trigger.h"
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef _PLUGINS_KAITAI_PYTHON_ROST_TRIGGER_H
+#define _PLUGINS_KAITAI_PYTHON_ROST_TRIGGER_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_kaitai_trigger_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.plugins.kaitai.rost.KaitaiTrigger'. */
+bool ensure_python_kaitai_trigger_is_registered(void);
+
+/* Tente de convertir en accès à une définition Kaitai. */
+int convert_to_kaitai_trigger(PyObject *, void *);
+
+
+
+#endif /* _PLUGINS_KAITAI_PYTHON_ROST_TRIGGER_H */
diff --git a/plugins/kaitai/record.c b/plugins/kaitai/record.c
index 5717b17..de1e80d 100644
--- a/plugins/kaitai/record.c
+++ b/plugins/kaitai/record.c
@@ -115,6 +115,10 @@ static void g_match_record_init(GMatchRecord *record)
static void g_match_record_dispose(GMatchRecord *record)
{
+ g_clear_object(&record->creator);
+
+ g_clear_object(&record->content);
+
G_OBJECT_CLASS(g_match_record_parent_class)->dispose(G_OBJECT(record));
}
@@ -331,12 +335,16 @@ static GMatchRecord *_g_match_record_find_by_name(GMatchRecord *record, const ch
{
label = g_kaitai_attribute_get_label(G_KAITAI_ATTRIBUTE(record->creator));
- label_len = strlen(label);
-
- if (label_len == len && strncmp(label, name, len) == 0)
+ if (label != NULL)
{
- result = record;
- g_object_ref(G_OBJECT(result));
+ label_len = strlen(label);
+
+ if (label_len == len && strncmp(label, name, len) == 0)
+ {
+ result = record;
+ g_object_ref(G_OBJECT(result));
+ }
+
}
}
diff --git a/plugins/kaitai/records/Makefile.am b/plugins/kaitai/records/Makefile.am
index c11e823..3884bfb 100644
--- a/plugins/kaitai/records/Makefile.am
+++ b/plugins/kaitai/records/Makefile.am
@@ -2,6 +2,10 @@
noinst_LTLIBRARIES = libkaitairecords.la
libkaitairecords_la_SOURCES = \
+ bits-int.h \
+ bits.h bits.c \
+ delayed-int.h \
+ delayed.h delayed.c \
empty-int.h \
empty.h empty.c \
group-int.h \
@@ -9,9 +13,7 @@ libkaitairecords_la_SOURCES = \
item-int.h \
item.h item.c \
list-int.h \
- list.h list.c \
- value-int.h \
- value.h value.c
+ list.h list.c
libkaitairecords_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) -I$(top_srcdir)/src
diff --git a/plugins/kaitai/records/bits-int.h b/plugins/kaitai/records/bits-int.h
new file mode 100644
index 0000000..7b03911
--- /dev/null
+++ b/plugins/kaitai/records/bits-int.h
@@ -0,0 +1,59 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * bits-int.h - prototypes internes pour la conservation d'un champ de bits entre attribut et binaire
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _PLUGINS_KAITAI_RECORDS_BITS_INT_H
+#define _PLUGINS_KAITAI_RECORDS_BITS_INT_H
+
+
+#include "bits.h"
+
+
+#include "../record-int.h"
+
+
+
+/* Correspondance de bits établie entre un attribut et du binaire (instance) */
+struct _GRecordBitField
+{
+ GMatchRecord parent; /* A laisser en premier */
+
+ ext_vmpa_t epos; /* Point de départ */
+ uint8_t size; /* Quantité de bits concernés */
+ SourceEndian endian; /* Boutisme des données imposé */
+
+};
+
+/* Correspondance de bits établie entre un attribut et du binaire (classe) */
+struct _GRecordBitFieldClass
+{
+ GMatchRecordClass parent; /* A laisser en premier */
+
+};
+
+
+/* Met en place une correspondance entre attribut et binaire. */
+bool g_record_bit_field_create(GRecordBitField *, GKaitaiAttribute *, GBinContent *, const ext_vmpa_t *, uint8_t, SourceEndian);
+
+
+
+#endif /* _PLUGINS_KAITAI_RECORDS_BITS_INT_H */
diff --git a/plugins/kaitai/records/bits.c b/plugins/kaitai/records/bits.c
new file mode 100644
index 0000000..d224112
--- /dev/null
+++ b/plugins/kaitai/records/bits.c
@@ -0,0 +1,283 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * bits.c - conservation d'un champ de bits entre attribut et binaire
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "bits.h"
+
+
+#include <assert.h>
+#include <string.h>
+
+
+#include "bits-int.h"
+
+
+
+/* -------------------- DEFINITION D'UNE CORRESPONDANCE UNITAIRE -------------------- */
+
+
+/* Initialise la classe des correspondances attribut/binaire. */
+static void g_record_bit_field_class_init(GRecordBitFieldClass *);
+
+/* Initialise une correspondance entre attribut et binaire. */
+static void g_record_bit_field_init(GRecordBitField *);
+
+/* Supprime toutes les références externes. */
+static void g_record_bit_field_dispose(GRecordBitField *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_record_bit_field_finalize(GRecordBitField *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Calcule ou fournit la zone couverte par une correspondance. */
+static void g_record_bit_field_get_range(const GRecordBitField *, mrange_t *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* DEFINITION D'UNE CORRESPONDANCE UNITAIRE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une correspondance entre un attribut et du binaire. */
+G_DEFINE_TYPE(GRecordBitField, g_record_bit_field, G_TYPE_MATCH_RECORD);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des correspondances attribut/binaire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_record_bit_field_class_init(GRecordBitFieldClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GMatchRecordClass *record; /* Version parente de la classe*/
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_record_bit_field_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_record_bit_field_finalize;
+
+ record = G_MATCH_RECORD_CLASS(klass);
+
+ record->get_range = (get_record_range_fc)g_record_bit_field_get_range;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : field = instance à initialiser. *
+* *
+* Description : Initialise une correspondance entre attribut et binaire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_record_bit_field_init(GRecordBitField *field)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : field = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_record_bit_field_dispose(GRecordBitField *field)
+{
+ G_OBJECT_CLASS(g_record_bit_field_parent_class)->dispose(G_OBJECT(field));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : field = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_record_bit_field_finalize(GRecordBitField *field)
+{
+ G_OBJECT_CLASS(g_record_bit_field_parent_class)->finalize(G_OBJECT(field));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : attrib = analyseur à l'origine de la correspondance. *
+* content = contenu binaire lié à la correspondance. *
+* epos = tête de lecture avec granularité en bits. *
+* size = quantité de bits à prendre en compte. *
+* endian = boustime des données à respecter. *
+* *
+* Description : Crée une nouvelle correspondance entre attribut et binaire. *
+* *
+* Retour : Instance mise en place ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GMatchRecord *g_record_bit_field_new(GKaitaiAttribute *attrib, GBinContent *content, const ext_vmpa_t *epos, uint8_t size, SourceEndian endian)
+{
+ GMatchRecord *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_RECORD_BIT_FIELD, NULL);
+
+ if (!g_record_bit_field_create(G_RECORD_BIT_FIELD(result), attrib, content, epos, size, endian))
+ g_clear_object(&result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : field = correspondance à initialiser pleinement. *
+* attrib = analyseur à l'origine de la correspondance. *
+* content = contenu binaire lié à la correspondance. *
+* epos = tête de lecture avec granularité en bits. *
+* size = quantité de bits à prendre en compte. *
+* endian = boustime des données à respecter. *
+* *
+* Description : Met en place une correspondance entre attribut et binaire. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_record_bit_field_create(GRecordBitField *field, GKaitaiAttribute *attrib, GBinContent *content, const ext_vmpa_t *epos, uint8_t size, SourceEndian endian)
+{
+ bool result; /* Bilan à retourner */
+
+ result = g_match_record_create(G_MATCH_RECORD(field), G_KAITAI_PARSER(attrib), content);
+
+ if (result)
+ {
+ copy_evmpa(&field->epos, epos);
+ field->size = size;
+ field->endian = endian;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : field = correspondance à consulter. *
+* out = valeur à sauvegarder sous une forme générique. [OUT] *
+* *
+* Description : Lit la valeur d'un élément Kaitai entier représenté. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_record_bit_field_get_value(const GRecordBitField *field, resolved_value_t *out)
+{
+ bool result; /* Bilan à retourner */
+ GKaitaiParser *parser; /* Attribut associé à l'élément*/
+
+ parser = g_match_record_get_creator(G_MATCH_RECORD(field));
+ assert(G_IS_KAITAI_ATTRIBUTE(parser));
+
+ result = g_kaitai_attribute_read_bit_field_value(G_KAITAI_ATTRIBUTE(parser),
+ G_MATCH_RECORD(field)->content,
+ &field->epos, field->size,
+ field->endian, out);
+
+ g_object_unref(G_OBJECT(parser));
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : record = correspondance à consulter. *
+* range = zone de couverture déterminée. [OUT] *
+* *
+* Description : Calcule ou fournit la zone couverte par une correspondance. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_record_bit_field_get_range(const GRecordBitField *record, mrange_t *range)
+{
+ phys_t len; /* Taille en octets */
+
+ len = record->size / 8;
+
+ if (record->size % 8 > 0)
+ len ++;
+
+ init_mrange(range, &record->epos.base, len);
+
+}
diff --git a/plugins/kaitai/records/bits.h b/plugins/kaitai/records/bits.h
new file mode 100644
index 0000000..923e8e3
--- /dev/null
+++ b/plugins/kaitai/records/bits.h
@@ -0,0 +1,62 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * bits.h - prototypes pour la conservation d'un champ de bits entre attribut et binaire
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _PLUGINS_KAITAI_RECORDS_BITS_H
+#define _PLUGINS_KAITAI_RECORDS_BITS_H
+
+
+#include <glib-object.h>
+
+
+#include "../record.h"
+#include "../parsers/attribute.h"
+
+
+
+#define G_TYPE_RECORD_BIT_FIELD g_record_bit_field_get_type()
+#define G_RECORD_BIT_FIELD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_RECORD_BIT_FIELD, GRecordBitField))
+#define G_IS_RECORD_BIT_FIELD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_RECORD_BIT_FIELD))
+#define G_RECORD_BIT_FIELD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_RECORD_BIT_FIELD, GRecordBitFieldClass))
+#define G_IS_RECORD_BIT_FIELD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_RECORD_BIT_FIELD))
+#define G_RECORD_BIT_FIELD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_RECORD_BIT_FIELD, GRecordBitFieldClass))
+
+
+/* Correspondance de bits établie entre un attribut et du binaire (instance) */
+typedef struct _GRecordBitField GRecordBitField;
+
+/* Correspondance de bits établie entre un attribut et du binaire (classe) */
+typedef struct _GRecordBitFieldClass GRecordBitFieldClass;
+
+
+/* Indique le type défini pour une correspondance entre un attribut et du binaire. */
+GType g_record_bit_field_get_type(void);
+
+/* Crée une nouvelle correspondance entre attribut et binaire. */
+GMatchRecord *g_record_bit_field_new(GKaitaiAttribute *, GBinContent *, const ext_vmpa_t *, uint8_t, SourceEndian);
+
+/* Lit la valeur d'un élément Kaitai entier représenté. */
+bool g_record_bit_field_get_value(const GRecordBitField *, resolved_value_t *);
+
+
+
+#endif /* _PLUGINS_KAITAI_RECORDS_BITS_H */
diff --git a/plugins/kaitai/records/value-int.h b/plugins/kaitai/records/delayed-int.h
index 6a84a7f..9275500 100644
--- a/plugins/kaitai/records/value-int.h
+++ b/plugins/kaitai/records/delayed-int.h
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * value-int.h - prototypes internes pour la conservation d'une instance virtuelle
+ * delayed-int.h - prototypes internes pour la conservation d'une instance virtuelle
*
* Copyright (C) 2019 Cyrille Bagard
*
@@ -21,11 +21,11 @@
*/
-#ifndef _PLUGINS_KAITAI_RECORDS_VALUE_INT_H
-#define _PLUGINS_KAITAI_RECORDS_VALUE_INT_H
+#ifndef _PLUGINS_KAITAI_RECORDS_DELAYED_INT_H
+#define _PLUGINS_KAITAI_RECORDS_DELAYED_INT_H
-#include "value.h"
+#include "delayed.h"
#include "../record-int.h"
@@ -33,16 +33,19 @@
/* Valeur calculée selon des correspondances parallèles (instance) */
-struct _GRecordValue
+struct _GRecordDelayed
{
GMatchRecord parent; /* A laisser en premier */
kaitai_scope_t locals; /* Sauvegarde de contexte */
+ bool has_value; /* Port d'une valeur directe ? */
+ GMatchRecord *real_record; /* Enregistrement effectif */
+
};
/* Valeur calculée selon des correspondances parallèles (classe) */
-struct _GRecordValueClass
+struct _GRecordDelayedClass
{
GMatchRecordClass parent; /* A laisser en premier */
@@ -50,8 +53,8 @@ struct _GRecordValueClass
/* Met en place une valeur calculée selon des correspondances. */
-bool g_record_value_create(GRecordValue *, GKaitaiInstance *, const kaitai_scope_t *);
+bool g_record_delayed_create(GRecordDelayed *, GKaitaiInstance *, const kaitai_scope_t *, GBinContent *);
-#endif /* _PLUGINS_KAITAI_RECORDS_VALUE_INT_H */
+#endif /* _PLUGINS_KAITAI_RECORDS_DELAYED_INT_H */
diff --git a/plugins/kaitai/records/value.c b/plugins/kaitai/records/delayed.c
index cafe5c3..8c1395c 100644
--- a/plugins/kaitai/records/value.c
+++ b/plugins/kaitai/records/delayed.c
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * value.c - conservation d'une correspondance entre attribut et binaire
+ * delayed.c - conservation d'une correspondance entre attribut et binaire
*
* Copyright (C) 2019 Cyrille Bagard
*
@@ -21,7 +21,7 @@
*/
-#include "value.h"
+#include "delayed.h"
#include <assert.h>
@@ -29,7 +29,8 @@
#include <string.h>
-#include "value-int.h"
+#include "delayed-int.h"
+#include "item.h"
#include "../parsers/attribute.h"
@@ -38,16 +39,16 @@
/* Initialise la classe des valeurs purement calculées. */
-static void g_record_value_class_init(GRecordValueClass *);
+static void g_record_delayed_class_init(GRecordDelayedClass *);
/* Initialise une correspondance entre attribut et binaire. */
-static void g_record_value_init(GRecordValue *);
+static void g_record_delayed_init(GRecordDelayed *);
/* Supprime toutes les références externes. */
-static void g_record_value_dispose(GRecordValue *);
+static void g_record_delayed_dispose(GRecordDelayed *);
/* Procède à la libération totale de la mémoire. */
-static void g_record_value_finalize(GRecordValue *);
+static void g_record_delayed_finalize(GRecordDelayed *);
@@ -55,7 +56,7 @@ static void g_record_value_finalize(GRecordValue *);
/* Calcule ou fournit la zone couverte par une correspondance. */
-static void g_record_value_get_range(const GRecordValue *, mrange_t *);
+static void g_record_delayed_get_range(const GRecordDelayed *, mrange_t *);
@@ -65,7 +66,7 @@ static void g_record_value_get_range(const GRecordValue *, mrange_t *);
/* Indique le type défini pour une valeur calculée selon des correspondances établies. */
-G_DEFINE_TYPE(GRecordValue, g_record_value, G_TYPE_MATCH_RECORD);
+G_DEFINE_TYPE(GRecordDelayed, g_record_delayed, G_TYPE_MATCH_RECORD);
/******************************************************************************
@@ -80,26 +81,26 @@ G_DEFINE_TYPE(GRecordValue, g_record_value, G_TYPE_MATCH_RECORD);
* *
******************************************************************************/
-static void g_record_value_class_init(GRecordValueClass *klass)
+static void g_record_delayed_class_init(GRecordDelayedClass *klass)
{
GObjectClass *object; /* Autre version de la classe */
GMatchRecordClass *record; /* Version parente de la classe*/
object = G_OBJECT_CLASS(klass);
- object->dispose = (GObjectFinalizeFunc/* ! */)g_record_value_dispose;
- object->finalize = (GObjectFinalizeFunc)g_record_value_finalize;
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_record_delayed_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_record_delayed_finalize;
record = G_MATCH_RECORD_CLASS(klass);
- record->get_range = (get_record_range_fc)g_record_value_get_range;
+ record->get_range = (get_record_range_fc)g_record_delayed_get_range;
}
/******************************************************************************
* *
-* Paramètres : value = instance à initialiser. *
+* Paramètres : delayed = instance à initialiser. *
* *
* Description : Initialise une correspondance entre attribut et binaire. *
* *
@@ -109,16 +110,18 @@ static void g_record_value_class_init(GRecordValueClass *klass)
* *
******************************************************************************/
-static void g_record_value_init(GRecordValue *value)
+static void g_record_delayed_init(GRecordDelayed *delayed)
{
- init_record_scope(&value->locals, NULL);
+ init_record_scope(&delayed->locals, NULL);
+
+ delayed->real_record = NULL;
}
/******************************************************************************
* *
-* Paramètres : value = instance d'objet GLib à traiter. *
+* Paramètres : delayed = instance d'objet GLib à traiter. *
* *
* Description : Supprime toutes les références externes. *
* *
@@ -128,18 +131,18 @@ static void g_record_value_init(GRecordValue *value)
* *
******************************************************************************/
-static void g_record_value_dispose(GRecordValue *value)
+static void g_record_delayed_dispose(GRecordDelayed *delayed)
{
- reset_record_scope(&value->locals);
+ reset_record_scope(&delayed->locals);
- G_OBJECT_CLASS(g_record_value_parent_class)->dispose(G_OBJECT(value));
+ G_OBJECT_CLASS(g_record_delayed_parent_class)->dispose(G_OBJECT(delayed));
}
/******************************************************************************
* *
-* Paramètres : value = instance d'objet GLib à traiter. *
+* Paramètres : delayed = instance d'objet GLib à traiter. *
* *
* Description : Procède à la libération totale de la mémoire. *
* *
@@ -149,17 +152,18 @@ static void g_record_value_dispose(GRecordValue *value)
* *
******************************************************************************/
-static void g_record_value_finalize(GRecordValue *value)
+static void g_record_delayed_finalize(GRecordDelayed *delayed)
{
- G_OBJECT_CLASS(g_record_value_parent_class)->finalize(G_OBJECT(value));
+ G_OBJECT_CLASS(g_record_delayed_parent_class)->finalize(G_OBJECT(delayed));
}
/******************************************************************************
* *
-* Paramètres : inst = analyseur à l'origine de la correspondance. *
-* locals = correspondances courantes pour résolutions. *
+* Paramètres : inst = analyseur à l'origine de la correspondance. *
+* locals = correspondances courantes pour résolutions. *
+* content = contenu binaire lié à la correspondance. *
* *
* Description : Crée une nouvelle valeur calculée à partir d'une instance. *
* *
@@ -169,13 +173,13 @@ static void g_record_value_finalize(GRecordValue *value)
* *
******************************************************************************/
-GRecordValue *g_record_value_new(GKaitaiInstance *inst, const kaitai_scope_t *locals)
+GRecordDelayed *g_record_delayed_new(GKaitaiInstance *inst, const kaitai_scope_t *locals, GBinContent *content)
{
- GRecordValue *result; /* Structure à retourner */
+ GRecordDelayed *result; /* Structure à retourner */
- result = g_object_new(G_TYPE_RECORD_VALUE, NULL);
+ result = g_object_new(G_TYPE_RECORD_DELAYED, NULL);
- if (!g_record_value_create(result, inst, locals))
+ if (!g_record_delayed_create(result, inst, locals, content))
g_clear_object(&result);
return result;
@@ -185,9 +189,10 @@ GRecordValue *g_record_value_new(GKaitaiInstance *inst, const kaitai_scope_t *lo
/******************************************************************************
* *
-* Paramètres : value = correspondance à initialiser pleinement. *
-* inst = analyseur à l'origine de la correspondance. *
-* locals = correspondances courantes pour résolutions. *
+* Paramètres : delayed = correspondance à initialiser pleinement. *
+* inst = analyseur à l'origine de la correspondance. *
+* locals = correspondances courantes pour résolutions. *
+* content = contenu binaire lié à la correspondance. *
* *
* Description : Met en place une valeur calculée à partir d'une instance. *
* *
@@ -197,14 +202,14 @@ GRecordValue *g_record_value_new(GKaitaiInstance *inst, const kaitai_scope_t *lo
* *
******************************************************************************/
-bool g_record_value_create(GRecordValue *value, GKaitaiInstance *inst, const kaitai_scope_t *locals)
+bool g_record_delayed_create(GRecordDelayed *delayed, GKaitaiInstance *inst, const kaitai_scope_t *locals, GBinContent *content)
{
bool result; /* Bilan à retourner */
- result = g_match_record_create(G_MATCH_RECORD(value), G_KAITAI_PARSER(inst), NULL);
+ result = g_match_record_create(G_MATCH_RECORD(delayed), G_KAITAI_PARSER(inst), content);
if (result)
- copy_record_scope(&value->locals, locals);
+ copy_record_scope(&delayed->locals, locals);
return result;
@@ -213,8 +218,8 @@ bool g_record_value_create(GRecordValue *value, GKaitaiInstance *inst, const kai
/******************************************************************************
* *
-* Paramètres : value = correspondance à consulter. *
-* value = valeur à sauvegarder sous une forme générique. [OUT] *
+* Paramètres : delayed = correspondance à consulter. *
+* out = valeur à sauvegarder sous forme générique. [OUT] *
* *
* Description : Détermine la valeur d'un élément Kaitai calculé. *
* *
@@ -224,17 +229,36 @@ bool g_record_value_create(GRecordValue *value, GKaitaiInstance *inst, const kai
* *
******************************************************************************/
-bool g_record_value_compute_value(const GRecordValue *value, resolved_value_t *out)
+bool g_record_delayed_compute_value(GRecordDelayed *delayed, resolved_value_t *out)
{
bool result; /* Bilan à retourner */
GKaitaiParser *parser; /* Instance liée à l'élément */
- parser = g_match_record_get_creator(G_MATCH_RECORD(value));
+ parser = g_match_record_get_creator(G_MATCH_RECORD(delayed));
assert(G_IS_KAITAI_ATTRIBUTE(parser));
- result = g_kaitai_instance_compute_value(G_KAITAI_INSTANCE(parser),
- &value->locals,
- out);
+ if (G_MATCH_RECORD(delayed)->content == NULL)
+ result = g_kaitai_instance_compute_value(G_KAITAI_INSTANCE(parser),
+ &delayed->locals,
+ out);
+
+ else
+ {
+ if (delayed->real_record == NULL)
+ delayed->real_record = g_kaitai_instance_compute_real_record(G_KAITAI_INSTANCE(parser),
+ &delayed->locals,
+ G_MATCH_RECORD(delayed)->content);
+
+ if (delayed->real_record == NULL)
+ result = false;
+
+ else
+ {
+ assert(G_IS_RECORD_ITEM(delayed->real_record));
+ result = g_record_item_get_value(G_RECORD_ITEM(delayed->real_record), out);
+ }
+
+ }
g_object_unref(G_OBJECT(parser));
@@ -245,8 +269,8 @@ bool g_record_value_compute_value(const GRecordValue *value, resolved_value_t *o
/******************************************************************************
* *
-* Paramètres : value = correspondance à consulter. *
-* value = valeur à sauvegarder sous une forme générique. [OUT] *
+* Paramètres : delayed = correspondance à consulter. *
+* out = valeur à sauvegarder sous forme générique. [OUT] *
* *
* Description : Détermine et ajuste la valeur d'un élément Kaitai calculé. *
* *
@@ -256,20 +280,12 @@ bool g_record_value_compute_value(const GRecordValue *value, resolved_value_t *o
* *
******************************************************************************/
-bool g_record_value_compute_and_aggregate_value(const GRecordValue *value, resolved_value_t *out)
+bool g_record_delayed_compute_and_aggregate_value(GRecordDelayed *delayed, resolved_value_t *out)
{
bool result; /* Bilan à retourner */
- GKaitaiParser *parser; /* Instance liée à l'élément */
sized_string_t converted; /* Conversion finale ? */
- parser = g_match_record_get_creator(G_MATCH_RECORD(value));
- assert(G_IS_KAITAI_ATTRIBUTE(parser));
-
- result = g_kaitai_instance_compute_value(G_KAITAI_INSTANCE(parser),
- &value->locals,
- out);
-
- g_object_unref(G_OBJECT(parser));
+ result = g_record_delayed_compute_value(delayed, out);
if (result)
{
@@ -318,7 +334,7 @@ bool g_record_value_compute_and_aggregate_value(const GRecordValue *value, resol
/******************************************************************************
* *
-* Paramètres : value = correspondance à consulter. *
+* Paramètres : delayed = correspondance à consulter. *
* range = zone de couverture déterminée. [OUT] *
* *
* Description : Calcule ou fournit la zone couverte par une correspondance. *
@@ -329,7 +345,7 @@ bool g_record_value_compute_and_aggregate_value(const GRecordValue *value, resol
* *
******************************************************************************/
-static void g_record_value_get_range(const GRecordValue *value, mrange_t *range)
+static void g_record_delayed_get_range(const GRecordDelayed *delayed, mrange_t *range)
{
copy_mrange(range, UNUSED_MRANGE_PTR);
diff --git a/plugins/kaitai/records/value.h b/plugins/kaitai/records/delayed.h
index 8ee9cdd..e88bb6c 100644
--- a/plugins/kaitai/records/value.h
+++ b/plugins/kaitai/records/delayed.h
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * value.h - prototypes pour la conservation d'une correspondance entre attribut et binaire
+ * delayed.h - prototypes pour la conservation d'une correspondance entre attribut et binaire
*
* Copyright (C) 2019 Cyrille Bagard
*
@@ -21,8 +21,8 @@
*/
-#ifndef _PLUGINS_KAITAI_RECORDS_VALUE_H
-#define _PLUGINS_KAITAI_RECORDS_VALUE_H
+#ifndef _PLUGINS_KAITAI_RECORDS_DELAYED_H
+#define _PLUGINS_KAITAI_RECORDS_DELAYED_H
#include <glib-object.h>
@@ -33,33 +33,33 @@
-#define G_TYPE_RECORD_VALUE g_record_value_get_type()
-#define G_RECORD_VALUE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_RECORD_VALUE, GRecordValue))
-#define G_IS_RECORD_VALUE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_RECORD_VALUE))
-#define G_RECORD_VALUE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_RECORD_VALUE, GRecordValueClass))
-#define G_IS_RECORD_VALUE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_RECORD_VALUE))
-#define G_RECORD_VALUE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_RECORD_VALUE, GRecordValueClass))
+#define G_TYPE_RECORD_DELAYED g_record_delayed_get_type()
+#define G_RECORD_DELAYED(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_RECORD_DELAYED, GRecordDelayed))
+#define G_IS_RECORD_DELAYED(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_RECORD_DELAYED))
+#define G_RECORD_DELAYED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_RECORD_DELAYED, GRecordDelayedClass))
+#define G_IS_RECORD_DELAYED_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_RECORD_DELAYED))
+#define G_RECORD_DELAYED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_RECORD_DELAYED, GRecordDelayedClass))
/* Valeur calculée selon des correspondances parallèles (instance) */
-typedef struct _GRecordValue GRecordValue;
+typedef struct _GRecordDelayed GRecordDelayed;
/* Valeur calculée selon des correspondances parallèles (classe) */
-typedef struct _GRecordValueClass GRecordValueClass;
+typedef struct _GRecordDelayedClass GRecordDelayedClass;
/* Indique le type défini pour une valeur calculée selon des correspondances établies. */
-GType g_record_value_get_type(void);
+GType g_record_delayed_get_type(void);
/* Crée une nouvelle valeur calculée à partir d'une instance. */
-GRecordValue *g_record_value_new(GKaitaiInstance *, const kaitai_scope_t *);
+GRecordDelayed *g_record_delayed_new(GKaitaiInstance *, const kaitai_scope_t *, GBinContent *);
/* Détermine la valeur d'un élément Kaitai entier calculé. */
-bool g_record_value_compute_value(const GRecordValue *, resolved_value_t *);
+bool g_record_delayed_compute_value(GRecordDelayed *, resolved_value_t *);
/* Détermine et ajuste la valeur d'un élément Kaitai calculé. */
-bool g_record_value_compute_and_aggregate_value(const GRecordValue *, resolved_value_t *);
+bool g_record_delayed_compute_and_aggregate_value(GRecordDelayed *, resolved_value_t *);
-#endif /* _PLUGINS_KAITAI_RECORDS_VALUE_H */
+#endif /* _PLUGINS_KAITAI_RECORDS_DELAYED_H */
diff --git a/plugins/kaitai/rost/Makefile.am b/plugins/kaitai/rost/Makefile.am
new file mode 100644
index 0000000..c7ea84a
--- /dev/null
+++ b/plugins/kaitai/rost/Makefile.am
@@ -0,0 +1,18 @@
+
+noinst_LTLIBRARIES = libkaitairost.la
+
+libkaitairost_la_SOURCES = \
+ browser-int.h \
+ browser.h browser.c \
+ core.h core.c \
+ space-int.h \
+ space.h space.c \
+ trigger-int.h \
+ trigger.h trigger.c
+
+libkaitairost_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) -I$(top_srcdir)/src
+
+
+devdir = $(includedir)/chrysalide-$(subdir)
+
+dev_HEADERS = $(libkaitairost_la_SOURCES:%c=)
diff --git a/plugins/kaitai/rost/browser-int.h b/plugins/kaitai/rost/browser-int.h
new file mode 100644
index 0000000..4b49680
--- /dev/null
+++ b/plugins/kaitai/rost/browser-int.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * browser-int.h - prototypes internes pour le parcours des résultats d'analyse Kaitai pour ROST
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef PLUGINS_KAITAI_ROST_BROWSER_INT_H
+#define PLUGINS_KAITAI_ROST_BROWSER_INT_H
+
+
+#include <analysis/scan/item-int.h>
+
+
+#include "browser.h"
+
+
+
+/* Parcours des résultats d'une analyse Kaitai pour ROST (instance) */
+struct _GKaitaiBrowser
+{
+ GScanRegisteredItem parent; /* A laisser en premier */
+
+ char *path; /* Chamin vers l'enregistrement*/
+ GMatchRecord *record; /* Correspondance à parcourir */
+
+};
+
+/* Parcours des résultats d'une analyse Kaitai pour ROST (classe) */
+struct _GKaitaiBrowserClass
+{
+ GScanRegisteredItemClass parent; /* A laisser en premier */
+
+};
+
+
+/* Met en place un nouveau parcours de correspondances Kaitai. */
+bool g_kaitai_browser_create(GKaitaiBrowser *, const char *, GMatchRecord *);
+
+
+
+#endif /* PLUGINS_KAITAI_ROST_BROWSER_INT_H */
diff --git a/plugins/kaitai/rost/browser.c b/plugins/kaitai/rost/browser.c
new file mode 100644
index 0000000..159915b
--- /dev/null
+++ b/plugins/kaitai/rost/browser.c
@@ -0,0 +1,478 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * browser.c - accès à des définitions Kaitai depuis ROST
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "browser.h"
+
+
+#include <assert.h>
+#include <string.h>
+
+
+#include <analysis/scan/exprs/literal.h>
+
+
+#include "browser-int.h"
+#include "../records/bits.h"
+#include "../records/delayed.h"
+#include "../records/item.h"
+#include "../records/list.h"
+
+
+
+/* ---------------------- PARCOURS DE CORRESPONDANCES ETABLIES ---------------------- */
+
+
+/* Initialise la classe des parcours de correspondances Kaitai. */
+static void g_kaitai_browser_class_init(GKaitaiBrowserClass *);
+
+/* Initialise un parcours de correspondances Kaitai. */
+static void g_kaitai_browser_init(GKaitaiBrowser *);
+
+/* Supprime toutes les références externes. */
+static void g_kaitai_browser_dispose(GKaitaiBrowser *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_kaitai_browser_finalize(GKaitaiBrowser *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Indique le nom associé à une expression d'évaluation. */
+static char *g_kaitai_browser_get_name(const GKaitaiBrowser *);
+
+/* Lance une résolution d'élément à solliciter. */
+static bool g_kaitai_browser_resolve(GKaitaiBrowser *, const char *, GScanContext *, GScanScope *, GScanRegisteredItem **);
+
+/* Réduit une expression à une forme plus simple. */
+static bool g_kaitai_browser_reduce(GKaitaiBrowser *, GScanContext *, GScanScope *, GScanExpression **);
+
+/* Effectue une extraction d'élément à partir d'une série. */
+static GObject *g_kaitai_browser_extract_at(GKaitaiBrowser *, const GScanExpression *, GScanContext *, GScanScope *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* PARCOURS DE CORRESPONDANCES ETABLIES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un parcours de correspondances Kaitai pour ROST. */
+G_DEFINE_TYPE(GKaitaiBrowser, g_kaitai_browser, G_TYPE_SCAN_REGISTERED_ITEM);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des parcours de correspondances Kaitai. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_kaitai_browser_class_init(GKaitaiBrowserClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GScanRegisteredItemClass *registered; /* Version de classe parente */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_kaitai_browser_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_kaitai_browser_finalize;
+
+ registered = G_SCAN_REGISTERED_ITEM_CLASS(klass);
+
+ registered->get_name = (get_registered_item_name_fc)g_kaitai_browser_get_name;
+ registered->resolve = (resolve_registered_item_fc)g_kaitai_browser_resolve;
+ registered->reduce = (reduce_registered_item_fc)g_kaitai_browser_reduce;
+ registered->extract = (extract_registered_item_at)g_kaitai_browser_extract_at;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : browser = instance à initialiser. *
+* *
+* Description : Initialise un parcours de correspondances Kaitai. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_kaitai_browser_init(GKaitaiBrowser *browser)
+{
+ browser->path = NULL;
+ browser->record = NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : browser = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_kaitai_browser_dispose(GKaitaiBrowser *browser)
+{
+ g_clear_object(&browser->record);
+
+ G_OBJECT_CLASS(g_kaitai_browser_parent_class)->dispose(G_OBJECT(browser));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : browser = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_kaitai_browser_finalize(GKaitaiBrowser *browser)
+{
+ if (browser->path != NULL)
+ free(browser->path);
+
+ G_OBJECT_CLASS(g_kaitai_browser_parent_class)->finalize(G_OBJECT(browser));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : path = chemin vers l'enregistrement fourni. *
+* record = correspondance racine à considérer. *
+* *
+* Description : Crée un nouveau parcours de correspondances Kaitai. *
+* *
+* Retour : Instance mise en place ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GKaitaiBrowser *g_kaitai_browser_new(const char *path, GMatchRecord *record)
+{
+ GKaitaiBrowser *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_KAITAI_BROWSER, NULL);
+
+ if (!g_kaitai_browser_create(result, path, record))
+ g_clear_object(&result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : browser = encadrement d'un parcours de correspondances. *
+* path = chemin vers l'enregistrement fourni. *
+* record = correspondance racine à considérer. *
+* *
+* Description : Met en place un nouveau parcours de correspondances Kaitai. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_kaitai_browser_create(GKaitaiBrowser *browser, const char *path, GMatchRecord *record)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+ if (path != NULL)
+ browser->path = strdup(path);
+
+ browser->record = record;
+ g_object_ref(G_OBJECT(browser->record));
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : item = élément d'appel à consulter. *
+* *
+* Description : Indique le nom associé à une expression d'évaluation. *
+* *
+* Retour : Désignation humaine de l'expression d'évaluation. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *g_kaitai_browser_get_name(const GKaitaiBrowser *item)
+{
+ char *result; /* Désignation à retourner */
+ int ret; /* Statut de construction */
+
+ if (item->path == NULL)
+ result = strdup("kaitai://");
+
+ else
+ {
+ ret = asprintf(&result, "kaitai://%s", item->path);
+ assert(ret > 0);
+
+ if (ret <= 0)
+ result = strdup("kaitai://???");
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = élément d'appel à consulter. *
+* target = désignation de l'objet d'appel à identifier. *
+* ctx = contexte de suivi de l'analyse courante. *
+* scope = portée courante des variables locales. *
+* out = zone d'enregistrement de la résolution opérée. [OUT]*
+* *
+* Description : Lance une résolution d'élément à solliciter. *
+* *
+* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_kaitai_browser_resolve(GKaitaiBrowser *item, const char *target, GScanContext *ctx, GScanScope *scope, GScanRegisteredItem **out)
+{
+ bool result; /* Bilan à retourner */
+ GMatchRecord *found; /* Correspondance trouvée */
+ char *path;
+ int ret; /* Statut de construction */
+
+ found = g_match_record_find_by_name(item->record, target, strlen(target), 1);
+ result = (found != NULL);
+
+ if (result)
+ {
+ ret = asprintf(&path, "%s.%s", item->path, target);
+ assert(ret > 0);
+
+ if (ret <= 0)
+ path = strdup("!?");
+
+ *out = G_SCAN_REGISTERED_ITEM(g_kaitai_browser_new(path, found));
+
+ free(path);
+ g_object_unref(G_OBJECT(found));
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = élément d'appel à consulter. *
+* ctx = contexte de suivi de l'analyse courante. *
+* scope = portée courante des variables locales. *
+* out = zone d'enregistrement de la réduction opérée. [OUT] *
+* *
+* Description : Réduit une expression à une forme plus simple. *
+* *
+* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_kaitai_browser_reduce(GKaitaiBrowser *item, GScanContext *ctx, GScanScope *scope, GScanExpression **out)
+{
+ bool result; /* Bilan à retourner */
+ size_t count; /* Décompte total à considérer */
+ resolved_value_t value; /* Valeur brute à transformer */
+
+ if (G_IS_RECORD_LIST(item->record))
+ {
+ count = g_record_list_count_records(G_RECORD_LIST(item->record));
+
+ *out = g_scan_literal_expression_new(LVT_BOOLEAN, (bool []){ count > 0 });
+
+ result = true;
+
+ }
+
+ else
+ {
+ if (G_IS_RECORD_BIT_FIELD(item->record))
+ result = g_record_bit_field_get_value(G_RECORD_BIT_FIELD(item->record), &value);
+
+ else if (G_IS_RECORD_DELAYED(item->record))
+ result = g_record_delayed_compute_and_aggregate_value(G_RECORD_DELAYED(item->record), &value);
+
+ else if (G_IS_RECORD_ITEM(item->record))
+ result = g_record_item_get_value(G_RECORD_ITEM(item->record), &value);
+
+ else
+ result = false;
+
+ if (result)
+ {
+ switch (value.type)
+ {
+ case GVT_UNSIGNED_INTEGER:
+ *out = g_scan_literal_expression_new(LVT_UNSIGNED_INTEGER, &value.unsigned_integer);
+ break;
+
+ case GVT_SIGNED_INTEGER:
+ *out = g_scan_literal_expression_new(LVT_SIGNED_INTEGER, &value.signed_integer);
+ break;
+
+ case GVT_FLOAT:
+ /* TODO */
+ break;
+
+ case GVT_BOOLEAN:
+ *out = g_scan_literal_expression_new(LVT_BOOLEAN, &value.status);
+ break;
+
+ case GVT_BYTES:
+ *out = g_scan_literal_expression_new(LVT_STRING, &value.bytes);
+ break;
+
+ default:
+ break;
+
+ }
+
+ EXIT_RESOLVED_VALUE(value);
+
+ }
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = élément d'appel à consulter. *
+* index = indice de l'élément à cibler. *
+* ctx = contexte de suivi de l'analyse courante. *
+* scope = portée courante des variables locales. *
+* *
+* Description : Effectue une extraction d'élément à partir d'une série. *
+* *
+* Retour : Elément de série obtenu ou NULL si erreur irrécupérable. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GObject *g_kaitai_browser_extract_at(GKaitaiBrowser *item, const GScanExpression *index, GScanContext *ctx, GScanScope *scope)
+{
+ GObject *result; /* Elément récupéré à renvoyer */
+ GScanLiteralExpression *literal; /* Accès direct à l'indice */
+ LiteralValueType vtype; /* Type de valeur portée */
+ unsigned long long at; /* Valeur concrète du point */
+ bool status; /* Bilan d'obtention d'indice */
+ GRecordList *list; /* Accès direct à la liste */
+ size_t count; /* Décompte total à considérer */
+ GMatchRecord *found; /* Correspondance trouvée */
+ char *path;
+ int ret; /* Statut de construction */
+
+ result = NULL;
+
+ /* Validations préliminaires */
+
+ if (!G_IS_RECORD_LIST(item->record)) goto exit;
+ if (!G_IS_SCAN_LITERAL_EXPRESSION(index)) goto exit;
+
+ literal = G_SCAN_LITERAL_EXPRESSION(index);
+
+ vtype = g_scan_literal_expression_get_value_type(literal);
+ if (vtype != LVT_UNSIGNED_INTEGER) goto exit;
+
+ status = g_scan_literal_expression_get_unsigned_integer_value(literal, &at);
+ if (!status) goto exit;
+
+ list = G_RECORD_LIST(item->record);
+
+ count = g_record_list_count_records(list);
+ if (at >= count) goto exit;
+
+ /* Récupération de l'élément visé */
+
+ found = g_record_list_get_record(list, at);
+ if (found == NULL) goto exit;
+
+ ret = asprintf(&path, "%s[%llu]", item->path, at);
+ assert(ret > 0);
+
+ if (ret <= 0)
+ path = strdup("!?");
+
+ result = G_OBJECT(g_kaitai_browser_new(path, found));
+
+ free(path);
+ g_object_unref(G_OBJECT(found));
+
+ exit:
+
+ return result;
+
+}
diff --git a/plugins/kaitai/rost/browser.h b/plugins/kaitai/rost/browser.h
new file mode 100644
index 0000000..89b9f6f
--- /dev/null
+++ b/plugins/kaitai/rost/browser.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * browser.h - prototypes pour le parcours des résultats d'analyse Kaitai pour ROST
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef PLUGINS_KAITAI_ROST_BROWSER_H
+#define PLUGINS_KAITAI_ROST_BROWSER_H
+
+
+#include <glib-object.h>
+
+
+#include "../record.h"
+
+
+
+#define G_TYPE_KAITAI_BROWSER g_kaitai_browser_get_type()
+#define G_KAITAI_BROWSER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_KAITAI_BROWSER, GKaitaiBrowser))
+#define G_IS_KAITAI_BROWSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_KAITAI_BROWSER))
+#define G_KAITAI_BROWSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_KAITAI_BROWSER, GKaitaiBrowserClass))
+#define G_IS_KAITAI_BROWSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_KAITAI_BROWSER))
+#define G_KAITAI_BROWSER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_KAITAI_BROWSER, GKaitaiBrowserClass))
+
+
+/* Parcours des résultats d'une analyse Kaitai pour ROST (instance) */
+typedef struct _GKaitaiBrowser GKaitaiBrowser;
+
+/* Parcours des résultats d'une analyse Kaitai pour ROST (classe) */
+typedef struct _GKaitaiBrowserClass GKaitaiBrowserClass;
+
+
+/* Indique le type défini pour un parcours de correspondances Kaitai pour ROST. */
+GType g_kaitai_browser_get_type(void);
+
+/* Crée un nouveau parcours de correspondances Kaitai. */
+GKaitaiBrowser *g_kaitai_browser_new(const char *, GMatchRecord *);
+
+
+
+#endif /* PLUGINS_KAITAI_ROST_BROWSER_H */
diff --git a/plugins/kaitai/rost/core.c b/plugins/kaitai/rost/core.c
new file mode 100644
index 0000000..8271389
--- /dev/null
+++ b/plugins/kaitai/rost/core.c
@@ -0,0 +1,66 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * core.c - mise à disposition d'un support Kaitai pour ROST
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "core.h"
+
+
+#include <core/global.h>
+
+
+#include "space.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Intègre un support de Kaitai pour ROST. *
+* *
+* Retour : Bilan du chargement mené. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool add_kaitai_support_to_rost(void)
+{
+ bool result; /* Bilan à retourner */
+ GScanNamespace *root_ns; /* Espace de noms ROST racine */
+ GScanNamespace *kaitai_ns; /* Espace de noms pour Kaitai */
+
+ result = true;
+
+ root_ns = get_rost_root_namespace();
+
+ kaitai_ns = g_kaitai_namespace_new();
+
+ result = g_scan_namespace_register_item(root_ns, G_SCAN_REGISTERED_ITEM(kaitai_ns));
+
+ g_object_unref(G_OBJECT(kaitai_ns));
+
+ g_object_unref(G_OBJECT(root_ns));
+
+ return result;
+
+}
diff --git a/plugins/kaitai/rost/core.h b/plugins/kaitai/rost/core.h
new file mode 100644
index 0000000..6f810eb
--- /dev/null
+++ b/plugins/kaitai/rost/core.h
@@ -0,0 +1,37 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * core.h - prototypes pour la mise à disposition d'un support Kaitai pour ROST
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _PLUGINS_KAITAI_ROST_CORE_H
+#define _PLUGINS_KAITAI_ROST_CORE_H
+
+
+#include <stdbool.h>
+
+
+
+/* Intègre un support de Kaitai pour ROST. */
+bool add_kaitai_support_to_rost(void);
+
+
+
+#endif /* _PLUGINS_KAITAI_ROST_CORE_H */
diff --git a/plugins/kaitai/rost/space-int.h b/plugins/kaitai/rost/space-int.h
new file mode 100644
index 0000000..47ec707
--- /dev/null
+++ b/plugins/kaitai/rost/space-int.h
@@ -0,0 +1,55 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * space-int.h - prototypes internes pour la définition d'un espace de noms pour les fonctions de scan
+ *
+ * Copyright (C) 2022 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _PLUGINS_KAITAI_ROST_SPACE_INT_H
+#define _PLUGINS_KAITAI_ROST_SPACE_INT_H
+
+
+#include "space.h"
+
+
+#include <analysis/scan/space-int.h>
+
+
+
+/* Espace de noms avec chargement dynamique de définitions Kaitai (instance) */
+struct _GKaitaiNamespace
+{
+ GScanNamespace parent; /* A laisser en premier */
+
+};
+
+/* Espace de noms avec chargement dynamique de définitions Kaitai (classe) */
+struct _GKaitaiNamespaceClass
+{
+ GScanNamespaceClass parent; /* A laisser en premier */
+
+};
+
+
+/* Met en place un nouvel espace de noms pour scan. */
+bool g_kaitai_namespace_create(GKaitaiNamespace *);
+
+
+
+#endif /* _PLUGINS_KAITAI_ROST_SPACE_INT_H */
diff --git a/plugins/kaitai/rost/space.c b/plugins/kaitai/rost/space.c
new file mode 100644
index 0000000..ee922d2
--- /dev/null
+++ b/plugins/kaitai/rost/space.c
@@ -0,0 +1,254 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * space.c - définition d'un espace de noms pour les fonctions de scan
+ *
+ * Copyright (C) 2022 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "space.h"
+
+
+#include <string.h>
+
+
+#include "trigger.h"
+#include "space-int.h"
+#include "../import.h"
+
+
+
+/* ------------------------- SOCLE POUR LES ESPACES DE NOMS ------------------------- */
+
+
+/* Initialise la classe des espaces de noms dynamiques Kaitai. */
+static void g_kaitai_namespace_class_init(GKaitaiNamespaceClass *);
+
+/* Initialise une instance d'espace de noms dynamiques Kaitai. */
+static void g_kaitai_namespace_init(GKaitaiNamespace *);
+
+/* Supprime toutes les références externes. */
+static void g_kaitai_namespace_dispose(GKaitaiNamespace *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_kaitai_namespace_finalize(GKaitaiNamespace *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Lance une résolution d'élément à solliciter. */
+static bool g_kaitai_namespace_resolve(GKaitaiNamespace *, const char *, GScanContext *, GScanScope *, GScanRegisteredItem **);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* SOCLE POUR LES ESPACES DE NOMS */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une définition d'espace de noms dynamique Kaitai. */
+G_DEFINE_TYPE(GKaitaiNamespace, g_kaitai_namespace, G_TYPE_SCAN_NAMESPACE);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des espaces de noms dynamiques Kaitai. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_kaitai_namespace_class_init(GKaitaiNamespaceClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GScanRegisteredItemClass *registered; /* Version de classe parente */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_kaitai_namespace_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_kaitai_namespace_finalize;
+
+ registered = G_SCAN_REGISTERED_ITEM_CLASS(klass);
+
+ registered->resolve = (resolve_registered_item_fc)g_kaitai_namespace_resolve;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : space = instance à initialiser. *
+* *
+* Description : Initialise une instance d'espace de noms dynamiques Kaitai. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_kaitai_namespace_init(GKaitaiNamespace *space)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : space = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_kaitai_namespace_dispose(GKaitaiNamespace *space)
+{
+ G_OBJECT_CLASS(g_kaitai_namespace_parent_class)->dispose(G_OBJECT(space));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : space = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_kaitai_namespace_finalize(GKaitaiNamespace *space)
+{
+ G_OBJECT_CLASS(g_kaitai_namespace_parent_class)->finalize(G_OBJECT(space));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Construit un nouvel espace de noms dynamique pour Kaitai. *
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GScanNamespace *g_kaitai_namespace_new(void)
+{
+ GScanNamespace *result; /* Instance à retourner */
+
+ result = g_object_new(G_TYPE_KAITAI_NAMESPACE, NULL);
+
+ if (!g_kaitai_namespace_create(G_KAITAI_NAMESPACE(result)))
+ g_clear_object(&result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : space = instance d'espace de noms à initialiser. *
+* name = désignation du futur espace de noms. *
+* *
+* Description : Met en place un nouvel espace de noms pour scan. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_kaitai_namespace_create(GKaitaiNamespace *space)
+{
+ bool result; /* Bilan à retourner */
+
+ result = g_scan_namespace_create(G_SCAN_NAMESPACE(space), "kaitai");
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : item = élément d'appel à consulter. *
+* target = désignation de l'objet d'appel à identifier. *
+* ctx = contexte de suivi de l'analyse courante. *
+* scope = portée courante des variables locales. *
+* out = zone d'enregistrement de la résolution opérée. [OUT]*
+* *
+* Description : Lance une résolution d'élément à solliciter. *
+* *
+* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_kaitai_namespace_resolve(GKaitaiNamespace *item, const char *target, GScanContext *ctx, GScanScope *scope, GScanRegisteredItem **out)
+{
+ bool result; /* Bilan à retourner */
+ GScanRegisteredItemClass *parent; /* Version de classe parente */
+ GKaitaiStruct *kstruct; /* Lecteur de définition */
+
+ parent = G_SCAN_REGISTERED_ITEM_CLASS(g_kaitai_namespace_parent_class);
+
+ result = parent->resolve(G_SCAN_REGISTERED_ITEM(item), target, ctx, scope, out);
+
+ if (!result)
+ {
+ kstruct = load_kaitai_definition(target, NULL);
+
+ if (kstruct != NULL)
+ {
+ *out = g_kaitai_trigger_new(kstruct);
+ result = true;
+
+ g_object_unref(G_OBJECT(kstruct));
+
+ }
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/kaitai/rost/space.h b/plugins/kaitai/rost/space.h
new file mode 100644
index 0000000..5dcea5e
--- /dev/null
+++ b/plugins/kaitai/rost/space.h
@@ -0,0 +1,59 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * space.h - prototypes pour la définition d'un espace de noms pour les fonctions de scan
+ *
+ * Copyright (C) 2022 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _PLUGINS_KAITAI_ROST_SPACE_H
+#define _PLUGINS_KAITAI_ROST_SPACE_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+
+
+#include <analysis/scan/space.h>
+
+
+
+#define G_TYPE_KAITAI_NAMESPACE g_kaitai_namespace_get_type()
+#define G_KAITAI_NAMESPACE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_KAITAI_NAMESPACE, GKaitaiNamespace))
+#define G_IS_KAITAI_NAMESPACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_KAITAI_NAMESPACE))
+#define G_KAITAI_NAMESPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_KAITAI_NAMESPACE, GKaitaiNamespaceClass))
+#define G_IS_KAITAI_NAMESPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_KAITAI_NAMESPACE))
+#define G_KAITAI_NAMESPACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_KAITAI_NAMESPACE, GKaitaiNamespaceClass))
+
+
+/* Espace de noms avec chargement dynamique de définitions Kaitai (instance) */
+typedef struct _GKaitaiNamespace GKaitaiNamespace;
+
+/* Espace de noms avec chargement dynamique de définitions Kaitai (classe) */
+typedef struct _GKaitaiNamespaceClass GKaitaiNamespaceClass;
+
+
+/* Indique le type défini pour une définition d'espace de noms dynamique Kaitai. */
+GType g_kaitai_namespace_get_type(void);
+
+/* Construit un nouvel espace de noms dynamique pour Kaitai. */
+GScanNamespace *g_kaitai_namespace_new(void);
+
+
+
+#endif /* _PLUGINS_KAITAI_ROST_SPACE_H */
diff --git a/plugins/kaitai/rost/trigger-int.h b/plugins/kaitai/rost/trigger-int.h
new file mode 100644
index 0000000..6830cd7
--- /dev/null
+++ b/plugins/kaitai/rost/trigger-int.h
@@ -0,0 +1,59 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * trigger-int.h - prototypes internes pour l'accès à des définitions Kaitai depuis ROST
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _PLUGINS_KAITAI_ROST_TRIGGER_INT_H
+#define _PLUGINS_KAITAI_ROST_TRIGGER_INT_H
+
+
+#include <analysis/scan/item-int.h>
+
+
+#include "trigger.h"
+
+
+
+/* Accès à une définition et déclenchement d'une analyse Kaitai depuis ROST (instance) */
+struct _GKaitaiTrigger
+{
+ GScanRegisteredItem parent; /* A laisser en premier */
+
+ char *name; /* Désignation arbitraire */
+
+ GKaitaiStruct *kstruct; /* Définition à décliner */
+
+};
+
+/* Accès à une définition et déclenchement d'une analyse Kaitai depuis ROST (classe) */
+struct _GKaitaiTriggerClass
+{
+ GScanRegisteredItemClass parent; /* A laisser en premier */
+
+};
+
+
+/* Met en place un accès à une définition Kaitai pour ROST. */
+bool g_kaitai_trigger_create(GKaitaiTrigger *, GKaitaiStruct *);
+
+
+
+#endif /* _PLUGINS_KAITAI_ROST_TRIGGER_INT_H */
diff --git a/plugins/kaitai/rost/trigger.c b/plugins/kaitai/rost/trigger.c
new file mode 100644
index 0000000..6bb6e5d
--- /dev/null
+++ b/plugins/kaitai/rost/trigger.c
@@ -0,0 +1,320 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * trigger.c - accès à des définitions Kaitai depuis ROST
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "trigger.h"
+
+
+#include <string.h>
+
+
+#include "browser.h"
+#include "trigger-int.h"
+
+
+
+/* ---------------------- ACCES ET DECLENCHEMENT D'UNE ANALYSE ---------------------- */
+
+
+/* Initialise la classe des accès aux définitions Kaitai. */
+static void g_kaitai_trigger_class_init(GKaitaiTriggerClass *);
+
+/* Initialise un accès à une définition Kaitai. */
+static void g_kaitai_trigger_init(GKaitaiTrigger *);
+
+/* Supprime toutes les références externes. */
+static void g_kaitai_trigger_dispose(GKaitaiTrigger *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_kaitai_trigger_finalize(GKaitaiTrigger *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Indique le nom associé à une expression d'évaluation. */
+static char *g_kaitai_trigger_get_name(const GKaitaiTrigger *);
+
+/* Lance une résolution d'élément à solliciter. */
+static bool g_kaitai_trigger_resolve(GKaitaiTrigger *, const char *, GScanContext *, GScanScope *, GScanRegisteredItem **);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* ACCES ET DECLENCHEMENT D'UNE ANALYSE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un accès à une définition Kaitai pour ROST. */
+G_DEFINE_TYPE(GKaitaiTrigger, g_kaitai_trigger, G_TYPE_SCAN_REGISTERED_ITEM);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des accès aux définitions Kaitai. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_kaitai_trigger_class_init(GKaitaiTriggerClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GScanRegisteredItemClass *registered; /* Version de classe parente */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_kaitai_trigger_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_kaitai_trigger_finalize;
+
+ registered = G_SCAN_REGISTERED_ITEM_CLASS(klass);
+
+ registered->get_name = (get_registered_item_name_fc)g_kaitai_trigger_get_name;
+ registered->resolve = (resolve_registered_item_fc)g_kaitai_trigger_resolve;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : trigger = instance à initialiser. *
+* *
+* Description : Initialise un accès à une définition Kaitai. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_kaitai_trigger_init(GKaitaiTrigger *trigger)
+{
+ trigger->name = NULL;
+
+ trigger->kstruct = NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : trigger = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_kaitai_trigger_dispose(GKaitaiTrigger *trigger)
+{
+ g_clear_object(&trigger->kstruct);
+
+ G_OBJECT_CLASS(g_kaitai_trigger_parent_class)->dispose(G_OBJECT(trigger));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : trigger = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_kaitai_trigger_finalize(GKaitaiTrigger *trigger)
+{
+ if (trigger->name != NULL)
+ free(trigger->name);
+
+ G_OBJECT_CLASS(g_kaitai_trigger_parent_class)->finalize(G_OBJECT(trigger));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : kstruct = définition Kaitai à manipuler avec du contenu. *
+* *
+* Description : Crée un nouvel accès à une définition Kaitai à instancier. *
+* *
+* Retour : Instance mise en place ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GScanRegisteredItem *g_kaitai_trigger_new(GKaitaiStruct *kstruct)
+{
+ GScanRegisteredItem *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_KAITAI_TRIGGER, NULL);
+
+ if (!g_kaitai_trigger_create(G_KAITAI_TRIGGER(result), kstruct))
+ g_clear_object(&result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : trigger = lien vers une définition Kaitai à instancier. *
+* kstruct = définition Kaitai à manipuler avec du contenu. *
+* *
+* Description : Met en place un accès à une définition Kaitai pour ROST. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_kaitai_trigger_create(GKaitaiTrigger *trigger, GKaitaiStruct *kstruct)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+ trigger->kstruct = kstruct;
+ g_object_ref(G_OBJECT(trigger->kstruct));
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : trigger = élément d'appel à consulter. *
+* *
+* Description : Indique le nom associé à une expression d'évaluation. *
+* *
+* Retour : Désignation humaine de l'expression d'évaluation. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *g_kaitai_trigger_get_name(const GKaitaiTrigger *trigger)
+{
+ char *result; /* Désignation à retourner */
+ GKaitaiMeta *meta; /* Eventuelles métadonnées */
+ const char *id; /* Identifiant de définition */
+
+ if (trigger->name != NULL)
+ result = strdup(trigger->name);
+
+ else
+ {
+ result = NULL;
+
+ meta = g_kaitai_structure_get_meta(trigger->kstruct);
+ if (meta == NULL) goto done;
+
+ id = g_kaitai_meta_get_id(meta);
+ if (id == NULL) goto done;
+
+ result = strdup(id);
+
+ g_object_unref(G_OBJECT(meta));
+
+ done:
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = élément d'appel à consulter. *
+* target = désignation de l'objet d'appel à identifier. *
+* ctx = contexte de suivi de l'analyse courante. *
+* scope = portée courante des variables locales. *
+* out = zone d'enregistrement de la résolution opérée. [OUT]*
+* *
+* Description : Lance une résolution d'élément à solliciter. *
+* *
+* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_kaitai_trigger_resolve(GKaitaiTrigger *item, const char *target, GScanContext *ctx, GScanScope *scope, GScanRegisteredItem **out)
+{
+ bool result; /* Bilan à retourner */
+ GKaitaiBrowser *browser; /* Navigateur pour résultats */
+ GBinContent *content; /* Contenu binaire à analyser */
+ GMatchRecord *record; /* Premier niveau de résultats */
+
+ browser = g_object_get_data(G_OBJECT(item), "kaitai_browser");
+
+ if (browser == NULL)
+ {
+ content = g_scan_context_get_content(ctx);
+
+ record = g_kaitai_structure_parse(item->kstruct, content);
+
+ g_object_unref(G_OBJECT(content));
+
+ if (record != NULL)
+ {
+ browser = g_kaitai_browser_new(NULL, record);
+
+ g_object_set_data_full(G_OBJECT(item), "kaitai_browser", browser, g_object_unref);
+
+ }
+
+ }
+
+ if (browser == NULL)
+ result = false;
+
+ else
+ result = g_scan_registered_item_resolve(G_SCAN_REGISTERED_ITEM(browser), target, ctx, scope, out);
+
+ return result;
+
+}
diff --git a/plugins/kaitai/rost/trigger.h b/plugins/kaitai/rost/trigger.h
new file mode 100644
index 0000000..f55e998
--- /dev/null
+++ b/plugins/kaitai/rost/trigger.h
@@ -0,0 +1,61 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * trigger.h - prototypes pour l'accès à des définitions Kaitai depuis ROST
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef PLUGINS_KAITAI_ROST_TRIGGER_H
+#define PLUGINS_KAITAI_ROST_TRIGGER_H
+
+
+#include <glib-object.h>
+
+
+#include <analysis/scan/item.h>
+
+
+#include "../parsers/struct.h"
+
+
+
+#define G_TYPE_KAITAI_TRIGGER g_kaitai_trigger_get_type()
+#define G_KAITAI_TRIGGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_KAITAI_TRIGGER, GKaitaiTrigger))
+#define G_IS_KAITAI_TRIGGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_KAITAI_TRIGGER))
+#define G_KAITAI_TRIGGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_KAITAI_TRIGGER, GKaitaiTriggerClass))
+#define G_IS_KAITAI_TRIGGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_KAITAI_TRIGGER))
+#define G_KAITAI_TRIGGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_KAITAI_TRIGGER, GKaitaiTriggerClass))
+
+
+/* Accès à une définition et déclenchement d'une analyse Kaitai depuis ROST (instance) */
+typedef struct _GKaitaiTrigger GKaitaiTrigger;
+
+/* Accès à une définition et déclenchement d'une analyse Kaitai depuis ROST (classe) */
+typedef struct _GKaitaiTriggerClass GKaitaiTriggerClass;
+
+
+/* Indique le type défini pour un accès à une définition Kaitai pour ROST. */
+GType g_kaitai_trigger_get_type(void);
+
+/* Crée un nouvel accès à une définition Kaitai à instancier. */
+GScanRegisteredItem *g_kaitai_trigger_new(GKaitaiStruct *);
+
+
+
+#endif /* PLUGINS_KAITAI_ROST_TRIGGER_H */
diff --git a/plugins/kaitai/scope.c b/plugins/kaitai/scope.c
index 6d1d47a..fad8890 100644
--- a/plugins/kaitai/scope.c
+++ b/plugins/kaitai/scope.c
@@ -231,7 +231,7 @@ GKaitaiType *find_sub_type(const kaitai_scope_t *locals, const char *name)
size_t i; /* Boucle de parcours */
GKaitaiParser *parser; /* Lecteur d'origine */
- GMatchRecord *list[] = { locals->root, locals->parent, locals->last };
+ GMatchRecord *list[] = { locals->last, locals->parent, locals->root };
result = NULL;
diff --git a/plugins/kaitai/tokens.l b/plugins/kaitai/tokens.l
index 3ddf40d..8c93299 100644
--- a/plugins/kaitai/tokens.l
+++ b/plugins/kaitai/tokens.l
@@ -91,7 +91,9 @@
"_root" { return ROOT; }
"_parent" { return PARENT; }
"_" { return LAST; }
+"_io" { return IO; }
"._io" { return METH_IO; }
+".eof" { return IO_EOF; }
"true" { return TRUE_CONST; }
"false" { return FALSE_CONST; }
diff --git a/plugins/pychrysalide/analysis/content.c b/plugins/pychrysalide/analysis/content.c
index f94e3f7..c30cdd8 100644
--- a/plugins/pychrysalide/analysis/content.c
+++ b/plugins/pychrysalide/analysis/content.c
@@ -40,6 +40,7 @@
#include "cattribs.h"
#include "constants.h"
+#include "storage/serialize.h"
#include "../access.h"
#include "../helpers.h"
#include "../arch/vmpa.h"
@@ -49,8 +50,13 @@
/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
-/* Procède à l'initialisation de l'interface de génération. */
-static void py_binary_content_interface_init(GBinContentIface *, gpointer *);
+/* Initialise la classe générique des contenus de binaire. */
+static void py_binary_content_init_gclass(GBinContentClass *, gpointer);
+
+CREATE_DYN_ABSTRACT_CONSTRUCTOR(binary_content, G_TYPE_BIN_CONTENT, py_binary_content_init_gclass);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_binary_content_init(PyObject *, PyObject *, PyObject *);
/* Fournit le nom associé au contenu binaire. */
static char *py_binary_content_describe_wrapper(const GBinContent *, bool);
@@ -126,10 +132,10 @@ static PyObject *py_binary_content_get_data(PyObject *, void *);
/******************************************************************************
* *
-* Paramètres : iface = interface GLib à initialiser. *
-* unused = adresse non utilisée ici. *
+* Paramètres : class = classe à initialiser. *
+* unused = données non utilisées ici. *
* *
-* Description : Procède à l'initialisation de l'interface de génération. *
+* Description : Initialise la classe générique des contenus de binaire. *
* *
* Retour : - *
* *
@@ -137,21 +143,45 @@ static PyObject *py_binary_content_get_data(PyObject *, void *);
* *
******************************************************************************/
-static void py_binary_content_interface_init(GBinContentIface *iface, gpointer *unused)
+static void py_binary_content_init_gclass(GBinContentClass *class, gpointer unused)
{
+ class->describe = py_binary_content_describe_wrapper;
+
+ class->read_raw = py_binary_content_read_raw_wrapper;
+ class->read_u8 = py_binary_content_read_u8_wrapper;
+ class->read_u16 = py_binary_content_read_u16_wrapper;
+ class->read_u32 = py_binary_content_read_u32_wrapper;
+ class->read_u64 = py_binary_content_read_u64_wrapper;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet à initialiser (théoriquement). *
+* args = arguments fournis à l'appel. *
+* kwds = arguments de type key=val fournis. *
+* *
+* Description : Initialise une instance sur la base du dérivé de GObject. *
+* *
+* Retour : 0. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int py_binary_content_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ int ret; /* Bilan de lecture des args. */
+
#define BINARY_CONTENT_DOC \
- "The BinContent is an interface which handles access to a given binary" \
- " content.\n" \
+ "A BinContent is an abstract object which handles access to a given" \
+ " binary content.\n" \
"\n" \
"All of its implementations are located in the" \
" pychrysalide.analysis.contents module. The main implemantation is" \
" the pychrysalide.analysis.contents.FileContent class.\n" \
"\n" \
- "A typical class declaration for a new implementation looks like:\n" \
- "\n" \
- " class NewImplem(GObject.Object, BinContent):\n" \
- " ...\n" \
- "\n" \
"The following methods have to be defined for new implementations:\n" \
"* pychrysalide.analysis.BinContent._describe();\n" \
"* pychrysalide.analysis.BinContent._read_raw();\n" \
@@ -161,13 +191,12 @@ static void py_binary_content_interface_init(GBinContentIface *iface, gpointer *
"* pychrysalide.analysis.BinContent._read_u32();\n" \
"* pychrysalide.analysis.BinContent._read_u64();\n"
- iface->describe = py_binary_content_describe_wrapper;
+ /* Initialisation d'un objet GLib */
+
+ ret = forward_pygobjet_init(self);
+ if (ret == -1) return -1;
- iface->read_raw = py_binary_content_read_raw_wrapper;
- iface->read_u8 = py_binary_content_read_u8_wrapper;
- iface->read_u16 = py_binary_content_read_u16_wrapper;
- iface->read_u32 = py_binary_content_read_u32_wrapper;
- iface->read_u64 = py_binary_content_read_u64_wrapper;
+ return 0;
}
@@ -1406,14 +1435,17 @@ PyTypeObject *get_python_binary_content_type(void)
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "pychrysalide.analysis.BinContent",
- .tp_basicsize = sizeof(PyObject),
+ .tp_basicsize = sizeof(PyGObject),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
.tp_doc = BINARY_CONTENT_DOC,
.tp_methods = py_binary_content_methods,
- .tp_getset = py_binary_content_getseters
+ .tp_getset = py_binary_content_getseters,
+
+ .tp_init = py_binary_content_init,
+ .tp_new = py_binary_content_new,
};
@@ -1440,23 +1472,18 @@ bool ensure_python_binary_content_is_registered(void)
PyObject *module; /* Module à recompléter */
PyObject *dict; /* Dictionnaire du module */
- static GInterfaceInfo info = { /* Paramètres d'inscription */
-
- .interface_init = (GInterfaceInitFunc)py_binary_content_interface_init,
- .interface_finalize = NULL,
- .interface_data = NULL,
-
- };
-
type = get_python_binary_content_type();
if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
{
+ if (!ensure_python_serializable_object_is_registered())
+ return false;
+
module = get_access_to_python_module("pychrysalide.analysis");
dict = PyModule_GetDict(module);
- if (!register_interface_for_pygobject(dict, G_TYPE_BIN_CONTENT, type, &info))
+ if (!register_class_for_pygobject(dict, G_TYPE_BIN_CONTENT, type))
return false;
if (!define_analysis_content_constants(type))
diff --git a/plugins/pychrysalide/analysis/contents/encapsulated.c b/plugins/pychrysalide/analysis/contents/encapsulated.c
index a818bab..e9583e6 100644
--- a/plugins/pychrysalide/analysis/contents/encapsulated.c
+++ b/plugins/pychrysalide/analysis/contents/encapsulated.c
@@ -28,18 +28,20 @@
#include <pygobject.h>
-#include <analysis/contents/encapsulated.h>
+#include <i18n.h>
+#include <analysis/contents/encapsulated-int.h>
#include "../content.h"
-#include "../storage/serialize.h"
#include "../../access.h"
#include "../../helpers.h"
-/* Crée un nouvel objet Python de type 'BinContent'. */
-static PyObject *py_encaps_content_new(PyTypeObject *, PyObject *, PyObject *);
+CREATE_DYN_CONSTRUCTOR(encaps_content, G_TYPE_ENCAPS_CONTENT);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_encaps_content_init(PyObject *, PyObject *, PyObject *);
/* Indique la base d'un contenu binaire encapsulé. */
static PyObject *py_encaps_content_get_base(PyObject *, void *);
@@ -54,26 +56,25 @@ static PyObject *py_encaps_content_get_endpoint(PyObject *, void *);
/******************************************************************************
* *
-* Paramètres : type = type de l'objet à instancier. *
+* Paramètres : self = objet à initialiser (théoriquement). *
* args = arguments fournis à l'appel. *
* kwds = arguments de type key=val fournis. *
* *
-* Description : Crée un nouvel objet Python de type 'BinContent'. *
+* Description : Initialise une instance sur la base du dérivé de GObject. *
* *
-* Retour : Instance Python mise en place. *
+* Retour : 0. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_encaps_content_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+static int py_encaps_content_init(PyObject *self, PyObject *args, PyObject *kwds)
{
- PyObject *result; /* Instance à retourner */
GBinContent *base; /* Base de l'extraction */
const char *path; /* Chemin vers le contenu final*/
GBinContent *endpoint; /* Contenu accessible au final */
int ret; /* Bilan de lecture des args. */
- GBinContent *content; /* Version GLib du contenu */
+ GEncapsContent *content; /* Version GLib du contenu */
#define ENCAPS_CONTENT_DOC \
"EncapsulatedContent gathers items relative to a binary encapsulated" \
@@ -94,20 +95,30 @@ static PyObject *py_encaps_content_new(PyTypeObject *type, PyObject *args, PyObj
" pychrysalide.analysis.BinContent instances and the access path must" \
" be provided as a string."
+ /* Récupération des paramètres */
+
ret = PyArg_ParseTuple(args, "O&sO&",
convert_to_binary_content, &base,
&path,
convert_to_binary_content, &endpoint);
- if (!ret) return NULL;
+ if (!ret) return -1;
- content = g_encaps_content_new(base, path, endpoint);
+ /* Initialisation d'un objet GLib */
- result = pygobject_new(G_OBJECT(content));
+ ret = forward_pygobjet_init(self);
+ if (ret == -1) return -1;
- if (content != NULL)
- g_object_unref(content);
+ /* Eléments de base */
- return result;
+ content = G_ENCAPS_CONTENT(pygobject_get(self));
+
+ if (!g_encaps_content_create(content, base, path, endpoint))
+ {
+ PyErr_SetString(PyExc_ValueError, _("Unable to create encapsulated content."));
+ return -1;
+ }
+
+ return 0;
}
@@ -276,7 +287,9 @@ PyTypeObject *get_python_encaps_content_type(void)
.tp_methods = py_encaps_content_methods,
.tp_getset = py_encaps_content_getseters,
- .tp_new = py_encaps_content_new
+
+ .tp_init = py_encaps_content_init,
+ .tp_new = py_encaps_content_new,
};
@@ -311,9 +324,6 @@ bool ensure_python_encaps_content_is_registered(void)
dict = PyModule_GetDict(module);
- if (!ensure_python_serializable_object_is_registered())
- return false;
-
if (!ensure_python_binary_content_is_registered())
return false;
diff --git a/plugins/pychrysalide/analysis/contents/file.c b/plugins/pychrysalide/analysis/contents/file.c
index 9552b6c..5bef069 100644
--- a/plugins/pychrysalide/analysis/contents/file.c
+++ b/plugins/pychrysalide/analysis/contents/file.c
@@ -28,18 +28,20 @@
#include <pygobject.h>
-#include <analysis/contents/file.h>
+#include <i18n.h>
+#include <analysis/contents/file-int.h>
#include "memory.h"
-#include "../storage/serialize.h"
#include "../../access.h"
#include "../../helpers.h"
-/* Crée un nouvel objet Python de type 'BinContent'. */
-static PyObject *py_file_content_new(PyTypeObject *, PyObject *, PyObject *);
+CREATE_DYN_CONSTRUCTOR(file_content, G_TYPE_FILE_CONTENT);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_file_content_init(PyObject *, PyObject *, PyObject *);
/* Fournit le nom de fichier associé au contenu binaire. */
static PyObject *py_file_content_get_filename(PyObject *, void *);
@@ -48,24 +50,23 @@ static PyObject *py_file_content_get_filename(PyObject *, void *);
/******************************************************************************
* *
-* Paramètres : type = type de l'objet à instancier. *
+* Paramètres : self = objet à initialiser (théoriquement). *
* args = arguments fournis à l'appel. *
* kwds = arguments de type key=val fournis. *
* *
-* Description : Crée un nouvel objet Python de type 'BinContent'. *
+* Description : Initialise une instance sur la base du dérivé de GObject. *
* *
-* Retour : Instance Python mise en place. *
+* Retour : 0. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_file_content_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+static int py_file_content_init(PyObject *self, PyObject *args, PyObject *kwds)
{
- PyObject *result; /* Instance à retourner */
const char *filename; /* Nom du fichier à charger */
int ret; /* Bilan de lecture des args. */
- GBinContent *content; /* Version GLib du contenu */
+ GFileContent *content; /* Version GLib du contenu */
#define FILE_CONTENT_DOC \
"FileContent handles binary content loaded from a file.\n" \
@@ -76,17 +77,27 @@ static PyObject *py_file_content_new(PyTypeObject *type, PyObject *args, PyObjec
"\n" \
"Where filename is a path to an existing file."
+ /* Récupération des paramètres */
+
ret = PyArg_ParseTuple(args, "s", &filename);
- if (!ret) return NULL;
+ if (!ret) return -1;
- content = g_file_content_new(filename);
+ /* Initialisation d'un objet GLib */
- result = pygobject_new(G_OBJECT(content));
+ ret = forward_pygobjet_init(self);
+ if (ret == -1) return -1;
- if (content != NULL)
- g_object_unref(content);
+ /* Eléments de base */
- return result;
+ content = G_FILE_CONTENT(pygobject_get(self));
+
+ if (!g_file_content_create(content, filename))
+ {
+ PyErr_SetString(PyExc_ValueError, _("Unable to create file content."));
+ return -1;
+ }
+
+ return 0;
}
@@ -163,7 +174,9 @@ PyTypeObject *get_python_file_content_type(void)
.tp_methods = py_file_content_methods,
.tp_getset = py_file_content_getseters,
- .tp_new = py_file_content_new
+
+ .tp_init = py_file_content_init,
+ .tp_new = py_file_content_new,
};
@@ -201,9 +214,6 @@ bool ensure_python_file_content_is_registered(void)
if (!ensure_python_memory_content_is_registered())
return false;
- if (!ensure_python_serializable_object_is_registered())
- return false;
-
if (!register_class_for_pygobject(dict, G_TYPE_FILE_CONTENT, type))
return false;
diff --git a/plugins/pychrysalide/analysis/contents/memory.c b/plugins/pychrysalide/analysis/contents/memory.c
index b5448f0..7464779 100644
--- a/plugins/pychrysalide/analysis/contents/memory.c
+++ b/plugins/pychrysalide/analysis/contents/memory.c
@@ -28,42 +28,43 @@
#include <pygobject.h>
-#include <analysis/contents/memory.h>
+#include <i18n.h>
+#include <analysis/contents/memory-int.h>
#include "../content.h"
-#include "../storage/serialize.h"
#include "../../access.h"
#include "../../helpers.h"
-/* Crée un nouvel objet Python de type 'BinContent'. */
-static PyObject *py_memory_content_new(PyTypeObject *, PyObject *, PyObject *);
+CREATE_DYN_CONSTRUCTOR(memory_content, G_TYPE_MEMORY_CONTENT);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_memory_content_init(PyObject *, PyObject *, PyObject *);
/******************************************************************************
* *
-* Paramètres : type = type de l'objet à instancier. *
+* Paramètres : self = objet à initialiser (théoriquement). *
* args = arguments fournis à l'appel. *
* kwds = arguments de type key=val fournis. *
* *
-* Description : Crée un nouvel objet Python de type 'BinContent'. *
+* Description : Initialise une instance sur la base du dérivé de GObject. *
* *
-* Retour : Instance Python mise en place. *
+* Retour : 0. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_memory_content_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+static int py_memory_content_init(PyObject *self, PyObject *args, PyObject *kwds)
{
- PyObject *result; /* Instance à retourner */
const char *data; /* Tampon interne de Python */
Py_ssize_t length; /* Taille utilisé de ce tampon */
int ret; /* Bilan de lecture des args. */
- GBinContent *content; /* Version GLib du contenu */
+ GMemoryContent *content; /* Version GLib du contenu */
#define MEMORY_CONTENT_DOC \
"MemoryContent builds a binary content from memory data only." \
@@ -76,22 +77,32 @@ static PyObject *py_memory_content_new(PyTypeObject *type, PyObject *args, PyObj
"Where data is provided as string or read-only bytes-like object." \
" The string may contain embedded null bytes."
+ /* Récupération des paramètres */
+
/**
* La taille doit être de type 'int' et non 'Py_ssize_t', sinon les 32 bits
* de poids fort ne sont pas initialisés !
*/
ret = PyArg_ParseTuple(args, "s#", &data, &length);
- if (!ret) return NULL;
+ if (!ret) return -1;
+
+ /* Initialisation d'un objet GLib */
- content = g_memory_content_new((const bin_t *)data, length);
+ ret = forward_pygobjet_init(self);
+ if (ret == -1) return -1;
- result = pygobject_new(G_OBJECT(content));
+ /* Eléments de base */
- if (content != NULL)
- g_object_unref(content);
+ content = G_MEMORY_CONTENT(pygobject_get(self));
- return result;
+ if (!g_memory_content_create(content, (const bin_t *)data, length))
+ {
+ PyErr_SetString(PyExc_ValueError, _("Unable to create memory content."));
+ return -1;
+ }
+
+ return 0;
}
@@ -131,7 +142,9 @@ PyTypeObject *get_python_memory_content_type(void)
.tp_methods = py_memory_content_methods,
.tp_getset = py_memory_content_getseters,
- .tp_new = py_memory_content_new
+
+ .tp_init = py_memory_content_init,
+ .tp_new = py_memory_content_new,
};
@@ -166,9 +179,6 @@ bool ensure_python_memory_content_is_registered(void)
dict = PyModule_GetDict(module);
- if (!ensure_python_serializable_object_is_registered())
- return false;
-
if (!ensure_python_binary_content_is_registered())
return false;
diff --git a/plugins/pychrysalide/analysis/contents/restricted.c b/plugins/pychrysalide/analysis/contents/restricted.c
index 2609bb4..4521578 100644
--- a/plugins/pychrysalide/analysis/contents/restricted.c
+++ b/plugins/pychrysalide/analysis/contents/restricted.c
@@ -31,19 +31,21 @@
#include <i18n.h>
-#include <analysis/contents/restricted.h>
+#include <i18n.h>
+#include <analysis/contents/restricted-int.h>
#include "../content.h"
-#include "../storage/serialize.h"
#include "../../access.h"
#include "../../helpers.h"
#include "../../arch/vmpa.h"
-/* Crée un nouvel objet Python de type 'BinContent'. */
-static PyObject *py_restricted_content_new(PyTypeObject *, PyObject *, PyObject *);
+CREATE_DYN_CONSTRUCTOR(restricted_content, G_TYPE_RESTRICTED_CONTENT);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_restricted_content_init(PyObject *, PyObject *, PyObject *);
/* Indique l'espace de restriction appliqué à un contenu. */
static PyObject *py_restricted_content_get_range(PyObject *, void *);
@@ -52,25 +54,24 @@ static PyObject *py_restricted_content_get_range(PyObject *, void *);
/******************************************************************************
* *
-* Paramètres : type = type de l'objet à instancier. *
+* Paramètres : self = objet à initialiser (théoriquement). *
* args = arguments fournis à l'appel. *
* kwds = arguments de type key=val fournis. *
* *
-* Description : Crée un nouvel objet Python de type 'BinContent'. *
+* Description : Initialise une instance sur la base du dérivé de GObject. *
* *
-* Retour : Instance Python mise en place. *
+* Retour : 0. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_restricted_content_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+static int py_restricted_content_init(PyObject *self, PyObject *args, PyObject *kwds)
{
- PyObject *result; /* Instance à retourner */
- GBinContent *content; /* Instance GLib correspondante*/
+ GBinContent *internal; /* Instance GLib correspondante*/
mrange_t range; /* Restriction à appliquer */
int ret; /* Bilan de lecture des args. */
- GBinContent *restricted; /* Création GLib à transmettre */
+ GRestrictedContent *content; /* Version GLib du contenu */
#define RESTRICTED_CONTENT_DOC \
"RestrictedContent restricts access to a given area for a binary content." \
@@ -82,14 +83,27 @@ static PyObject *py_restricted_content_new(PyTypeObject *type, PyObject *args, P
"Where content is a pychrysalide.analysis.BinContent instance and range" \
" a Python object which can be converted into pychrysalide.arch.mrange."
- ret = PyArg_ParseTuple(args, "O&O&", convert_to_binary_content, &content, convert_any_to_mrange, &range);
- if (!ret) return NULL;
+ /* Récupération des paramètres */
- restricted = g_restricted_content_new(content, &range);
+ ret = PyArg_ParseTuple(args, "O&O&", convert_to_binary_content, &internal, convert_any_to_mrange, &range);
+ if (!ret) return -1;
- result = pygobject_new(G_OBJECT(restricted));
+ /* Initialisation d'un objet GLib */
- return result;
+ ret = forward_pygobjet_init(self);
+ if (ret == -1) return -1;
+
+ /* Eléments de base */
+
+ content = G_RESTRICTED_CONTENT(pygobject_get(self));
+
+ if (!g_restricted_content_create(content, internal, &range))
+ {
+ PyErr_SetString(PyExc_ValueError, _("Unable to create restricted content."));
+ return -1;
+ }
+
+ return 0;
}
@@ -166,7 +180,9 @@ PyTypeObject *get_python_restricted_content_type(void)
.tp_methods = py_restricted_content_methods,
.tp_getset = py_restricted_content_getseters,
- .tp_new = py_restricted_content_new
+
+ .tp_init = py_restricted_content_init,
+ .tp_new = py_restricted_content_new,
};
@@ -201,9 +217,6 @@ bool ensure_python_restricted_content_is_registered(void)
dict = PyModule_GetDict(module);
- if (!ensure_python_serializable_object_is_registered())
- return false;
-
if (!ensure_python_binary_content_is_registered())
return false;
diff --git a/plugins/pychrysalide/analysis/scan/Makefile.am b/plugins/pychrysalide/analysis/scan/Makefile.am
index 32bf1e3..8c9fb77 100644
--- a/plugins/pychrysalide/analysis/scan/Makefile.am
+++ b/plugins/pychrysalide/analysis/scan/Makefile.am
@@ -13,9 +13,10 @@ libpychrysaanalysisscan_la_SOURCES = \
space.h space.c
libpychrysaanalysisscan_la_LIBADD = \
+ exprs/libpychrysaanalysisscanexprs.la \
patterns/libpychrysaanalysisscanpatterns.la
-libpychrysaanalysisscan_la_CFLAGS = $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) $(TOOLKIT_CFLAGS) \
+libpychrysaanalysisscan_la_CFLAGS = $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) $(TOOLKIT_CFLAGS) \
-I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
@@ -24,4 +25,4 @@ devdir = $(includedir)/chrysalide/$(subdir)
dev_HEADERS = $(libpychrysaanalysisscan_la_SOURCES:%c=)
-SUBDIRS = patterns
+SUBDIRS = exprs patterns
diff --git a/plugins/pychrysalide/analysis/scan/constants.c b/plugins/pychrysalide/analysis/scan/constants.c
index 7ada8d3..d030df2 100644
--- a/plugins/pychrysalide/analysis/scan/constants.c
+++ b/plugins/pychrysalide/analysis/scan/constants.c
@@ -51,7 +51,7 @@ bool define_expression_value_type_constants(PyTypeObject *type)
values = PyDict_New();
- result = add_const_to_group(values, "SRS_PENDING", SRS_PENDING);
+ result = add_const_to_group(values, "PENDING", SRS_PENDING);
if (result) result = add_const_to_group(values, "REDUCED", SRS_REDUCED);
if (result) result = add_const_to_group(values, "WAIT_FOR_SCAN", SRS_WAIT_FOR_SCAN);
if (result) result = add_const_to_group(values, "UNRESOLVABLE", SRS_UNRESOLVABLE);
diff --git a/plugins/pychrysalide/analysis/scan/context.c b/plugins/pychrysalide/analysis/scan/context.c
index 8f29457..9becaf7 100644
--- a/plugins/pychrysalide/analysis/scan/context.c
+++ b/plugins/pychrysalide/analysis/scan/context.c
@@ -32,10 +32,11 @@
#include <analysis/content.h>
#include <analysis/scan/context-int.h>
#include <analysis/scan/expr.h>
-#include <plugins/pychrysalide/access.h>
-#include <plugins/pychrysalide/helpers.h>
-#include <plugins/pychrysalide/analysis/content.h>
-#include <plugins/pychrysalide/analysis/scan/expr.h>
+
+#include "expr.h"
+#include "../content.h"
+#include "../../access.h"
+#include "../../helpers.h"
@@ -50,6 +51,12 @@ static PyObject *py_scan_context_mark_scan_as_done(PyObject *, PyObject *);
/* Indique si une correspondance globale a pu être établie. */
static PyObject *py_scan_context_has_match_for_rule(PyObject *, PyObject *);
+/* Fournit une référence au contenu principal analysé. */
+static PyObject *py_scan_context_get_content(PyObject *, void *);
+
+/* Définit le contenu principal à analyser. */
+static int py_scan_context_set_content(PyObject *, PyObject *, void *);
+
/* Indique si la phase d'analyse de contenu est terminée. */
static PyObject *py_scan_context_is_scan_done(PyObject *, void *);
@@ -183,6 +190,79 @@ static PyObject *py_scan_context_has_match_for_rule(PyObject *self, PyObject *ar
/******************************************************************************
* *
+* Paramètres : self = classe représentant une routine binaire. *
+* closure = adresse non utilisée ici. *
+* *
+* Description : Fournit une référence au contenu principal analysé. *
+* *
+* Retour : Content binaire associé au context. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_scan_context_get_content(PyObject *self, void *closure)
+{
+ PyObject *result; /* Eléments à retourner */
+ GScanContext *context; /* Version native */
+ GBinContent *content; /* Contenu binaire à référencer*/
+
+#define SCAN_CONTEXT_CONTENT_ATTRIB PYTHON_GETSET_DEF_FULL \
+( \
+ content, py_scan_context, \
+ "Link to the scanned binary content.\n" \
+ "\n" \
+ "The result is a pychrysalide.analysis.BinContent for" \
+ " fully initialized context." \
+)
+
+ context = G_SCAN_CONTEXT(pygobject_get(self));
+ content = g_scan_context_get_content(context);
+
+ result = pygobject_new(G_OBJECT(content));
+
+ g_object_unref(G_OBJECT(content));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* value = valeur fournie à intégrer ou prendre en compte. *
+* closure = non utilisé ici. *
+* *
+* Description : Définit le contenu principal à analyser. *
+* *
+* Retour : Content binaire associé au context. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int py_scan_context_set_content(PyObject *self, PyObject *value, void *closure)
+{
+ GScanContext *context; /* Elément à consulter */
+ int ret; /* Bilan de lecture des args. */
+ GBinContent *content; /* Contenu binaire à référencer*/
+
+ ret = PyObject_IsInstance(value, (PyObject *)get_python_binary_content_type());
+ if (!ret) return -1;
+
+ context = G_SCAN_CONTEXT(pygobject_get(self));
+ content = G_BIN_CONTENT(pygobject_get(value));
+
+ // FIXME g_scan_context_set_content(context, content);
+
+ return 0;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : self = objet Python concerné par l'appel. *
* closure = non utilisé ici. *
* *
@@ -242,6 +322,7 @@ PyTypeObject *get_python_scan_context_type(void)
};
static PyGetSetDef py_scan_context_getseters[] = {
+ SCAN_CONTEXT_CONTENT_ATTRIB,
SCAN_CONTEXT_IS_SCAN_DONE_ATTRIB,
{ NULL }
};
diff --git a/plugins/pychrysalide/analysis/scan/core.c b/plugins/pychrysalide/analysis/scan/core.c
index f609f7d..16df9a9 100644
--- a/plugins/pychrysalide/analysis/scan/core.c
+++ b/plugins/pychrysalide/analysis/scan/core.c
@@ -37,18 +37,6 @@
-/* #include <malloc.h> */
-
-/* #include <i18n.h> */
-/* #include <arch/processor.h> */
-/* #include <core/processors.h> */
-
-/* #include "../core.h" */
-
-/* #include "../arch/processor.h" */
-
-
-
/* Inscrit un modificateur dans la liste des disponibles. */
static PyObject *py_scan_register_token_modifier(PyObject *, PyObject *);
@@ -119,7 +107,8 @@ static PyObject *py_scan_register_token_modifier(PyObject *self, PyObject *args)
static PyObject *py_scan_find_token_modifiers_for_name(PyObject *self, PyObject *args)
{
PyObject *result; /* Bilan à retourner */
- const char *name; /* Nom d'appel à rechercher */
+ sized_string_t name; /* Nom d'appel à rechercher */
+ Py_ssize_t len; /* Taille de ce nom */
int ret; /* Bilan de lecture des args. */
GScanTokenModifier *modifier; /* Instance mise en place */
@@ -135,10 +124,12 @@ static PyObject *py_scan_find_token_modifiers_for_name(PyObject *self, PyObject
" if no instance was found for the provided name." \
)
- ret = PyArg_ParseTuple(args, "s", &name);
+ ret = PyArg_ParseTuple(args, "s#", &name.static_data, &len);
if (!ret) return NULL;
- modifier = find_scan_token_modifiers_for_name(name);
+ name.len = len;
+
+ modifier = find_scan_token_modifiers_for_name(&name);
if (modifier != NULL)
{
diff --git a/plugins/pychrysalide/analysis/scan/expr.c b/plugins/pychrysalide/analysis/scan/expr.c
index 3622e9b..2d8245a 100644
--- a/plugins/pychrysalide/analysis/scan/expr.c
+++ b/plugins/pychrysalide/analysis/scan/expr.c
@@ -107,7 +107,7 @@ static int py_scan_expression_init(PyObject *self, PyObject *args, PyObject *kwd
" the following arguments as keyword parameters:\n" \
"* *state*: initial state of reduction for the expression, as a" \
" pychrysalide.analysis.scan.ScanExpression.ScanReductionState" \
- " value." \
+ " value." \
"\n" \
"The following methods have to be defined for new classes:\n" \
"* pychrysalide.analysis.scan.ScanExpression._cmp_rich().\n"
diff --git a/plugins/pychrysalide/analysis/scan/expr.h b/plugins/pychrysalide/analysis/scan/expr.h
index 00ab28d..42f5350 100644
--- a/plugins/pychrysalide/analysis/scan/expr.h
+++ b/plugins/pychrysalide/analysis/scan/expr.h
@@ -37,7 +37,7 @@ PyTypeObject *get_python_scan_expression_type(void);
/* Prend en charge l'objet 'pychrysalide.analysis.scan.ScanExpression'. */
bool ensure_python_scan_expression_is_registered(void);
-/* Tente de convertir en fonction d'analyse pour scan. */
+/* Tente de convertir en expression d'évaluation généraliste. */
int convert_to_scan_expression(PyObject *, void *);
diff --git a/plugins/pychrysalide/analysis/scan/exprs/Makefile.am b/plugins/pychrysalide/analysis/scan/exprs/Makefile.am
new file mode 100644
index 0000000..e40d4de
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/exprs/Makefile.am
@@ -0,0 +1,15 @@
+
+noinst_LTLIBRARIES = libpychrysaanalysisscanexprs.la
+
+libpychrysaanalysisscanexprs_la_SOURCES = \
+ constants.h constants.c \
+ literal.h literal.c \
+ module.h module.c
+
+libpychrysaanalysisscanexprs_la_CFLAGS = $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+ $(TOOLKIT_CFLAGS) -I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
+
+
+devdir = $(includedir)/chrysalide/$(subdir)
+
+dev_HEADERS = $(libpychrysaanalysisscanexprs_la_SOURCES:%c=)
diff --git a/plugins/pychrysalide/analysis/scan/exprs/constants.c b/plugins/pychrysalide/analysis/scan/exprs/constants.c
new file mode 100644
index 0000000..b11ac4c
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/exprs/constants.c
@@ -0,0 +1,128 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants.c - ajout des constantes de base pour les expressions
+ *
+ * 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 "constants.h"
+
+
+#include <analysis/scan/exprs/literal.h>
+
+
+#include "../../../helpers.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type dont le dictionnaire est à compléter. *
+* *
+* Description : Définit les constantes relatives aux expressions de scan. *
+* *
+* Retour : true en cas de succès de l'opération, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool define_literal_expression_value_type_constants(PyTypeObject *type)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *values; /* Groupe de valeurs à établir */
+
+ values = PyDict_New();
+
+ result = add_const_to_group(values, "LVT_BOOLEAN", LVT_BOOLEAN);
+ if (result) result = add_const_to_group(values, "SIGNED_INTEGER", LVT_SIGNED_INTEGER);
+ if (result) result = add_const_to_group(values, "UNSIGNED_INTEGER", LVT_UNSIGNED_INTEGER);
+ if (result) result = add_const_to_group(values, "STRING", LVT_STRING);
+
+ if (!result)
+ {
+ Py_DECREF(values);
+ goto exit;
+ }
+
+ result = attach_constants_group_to_type(type, false, "LiteralValueType", values,
+ "Type of value carried by a literal scan expression.");
+
+ exit:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : arg = argument quelconque à tenter de convertir. *
+* dst = destination des valeurs récupérées en cas de succès. *
+* *
+* Description : Tente de convertir en constante LiteralValueType. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_literal_expression_value_type(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+ unsigned long value; /* Valeur transcrite */
+
+ result = PyObject_IsInstance(arg, (PyObject *)&PyLong_Type);
+
+ switch (result)
+ {
+ case -1:
+ /* L'exception est déjà fixée par Python */
+ result = 0;
+ break;
+
+ case 0:
+ PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to LiteralValueType");
+ break;
+
+ case 1:
+ value = PyLong_AsUnsignedLong(arg);
+
+ if (value > LVT_REG_EXPR)
+ {
+ PyErr_SetString(PyExc_TypeError, "invalid value for LiteralValueType");
+ result = 0;
+ }
+
+ else
+ *((LiteralValueType *)dst) = value;
+
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/scan/exprs/constants.h b/plugins/pychrysalide/analysis/scan/exprs/constants.h
new file mode 100644
index 0000000..e5b8e8c
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/exprs/constants.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants.h - prototypes pour l'ajout des constantes de base pour les expressions
+ *
+ * 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_PYCHRYSALIDE_ANALYSIS_SCAN_EXPRS_CONSTANTS_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_EXPRS_CONSTANTS_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Définit les constantes relatives aux expressions litérales. */
+bool define_literal_expression_value_type_constants(PyTypeObject *);
+
+/* Tente de convertir en constante LiteralValueType. */
+int convert_to_literal_expression_value_type(PyObject *, void *);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_EXPRS_CONSTANTS_H */
diff --git a/plugins/pychrysalide/analysis/scan/exprs/literal.c b/plugins/pychrysalide/analysis/scan/exprs/literal.c
new file mode 100644
index 0000000..d7ae002
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/exprs/literal.c
@@ -0,0 +1,281 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * literal.c - équivalent Python du fichier "analysis/scan/exprs/literal.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 "literal.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <analysis/scan/exprs/literal-int.h>
+
+
+#include "constants.h"
+#include "../expr.h"
+#include "../../../access.h"
+#include "../../../helpers.h"
+
+
+
+CREATE_DYN_CONSTRUCTOR(scan_literal_expression, G_TYPE_SCAN_LITERAL_EXPRESSION);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_scan_literal_expression_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_literal_expression_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ PyObject *py_value; /* Valeur en version Python */
+ int ret; /* Bilan de lecture des args. */
+ LiteralValueType vtype; /* Valeur à porter */
+ bool arg_boolean; /* Argument natif booléen */
+ unsigned long long arg_uinteger; /* Argument natif entier */
+ sized_string_t arg_string; /* Argument natif textuel */
+ Py_ssize_t arg_str_length; /* Taille de ce texte */
+ void *arg_ptr; /* Pointeur vers un argument */
+ GScanLiteralExpression *expr; /* Création GLib à transmettre */
+
+#define SCAN_LITERAL_EXPRESSION_DOC \
+ "A ScanLiteralExpression object defines expression carrying" \
+ " literal values available for scan match conditions.\n" \
+ "\n" \
+ "Instances can be created using one of the following" \
+ " constructors:\n" \
+ "\n" \
+ " ScanLiteralExpression(value)" \
+ "\n" \
+ "\n" \
+ "Where *value* is either a boolean, an integer or bytes."
+
+ /* Récupération des paramètres */
+
+ ret = PyArg_ParseTuple(args, "O", &py_value);
+ if (!ret) return -1;
+
+ if (PyBool_Check(py_value))
+ {
+ vtype = LVT_BOOLEAN;
+
+ arg_boolean = (py_value == Py_True);
+ arg_ptr = &arg_boolean;
+
+ }
+
+ else if (PyLong_Check(py_value))
+ {
+ if (1 /* sign - TODO */)
+ ;
+
+ vtype = LVT_UNSIGNED_INTEGER;
+
+ arg_uinteger = PyLong_AsUnsignedLongLong(py_value);
+ arg_ptr = &arg_uinteger;
+
+ }
+
+ else if (PyBytes_Check(py_value))
+ {
+ vtype = LVT_STRING;
+
+ ret = PyBytes_AsStringAndSize(py_value, &arg_string.data, &arg_str_length);
+ if (ret == -1) return -1;
+
+ arg_string.len = arg_str_length;
+ arg_ptr = &arg_string;
+
+ }
+
+ else
+ {
+ PyErr_SetString(PyExc_ValueError, _("Unsupported Python value for a literal scan expression."));
+ return -1;
+ }
+
+ /* Initialisation d'un objet GLib */
+
+ ret = forward_pygobjet_init(self);
+ if (ret == -1) return -1;
+
+ /* Eléments de base */
+
+ expr = G_SCAN_LITERAL_EXPRESSION(pygobject_get(self));
+
+ if (!g_scan_literal_expression_create(expr, vtype, arg_ptr))
+ {
+ PyErr_SetString(PyExc_ValueError, _("Unable to create literal expression."));
+ 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_literal_expression_type(void)
+{
+ static PyMethodDef py_scan_literal_expression_methods[] = {
+ { NULL }
+ };
+
+ static PyGetSetDef py_scan_literal_expression_getseters[] = {
+ { NULL }
+ };
+
+ static PyTypeObject py_scan_literal_expression_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.analysis.scan.exprs.ScanLiteralExpression",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+ .tp_doc = SCAN_LITERAL_EXPRESSION_DOC,
+
+ .tp_methods = py_scan_literal_expression_methods,
+ .tp_getset = py_scan_literal_expression_getseters,
+
+ .tp_init = py_scan_literal_expression_init,
+ .tp_new = py_scan_literal_expression_new,
+
+ };
+
+ return &py_scan_literal_expression_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Prend en charge l'objet 'pychrysalide....PlainModifier'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool ensure_python_scan_literal_expression_is_registered(void)
+{
+ PyTypeObject *type; /* Type Python 'PlainModifier' */
+ PyObject *module; /* Module à recompléter */
+ PyObject *dict; /* Dictionnaire du module */
+
+ type = get_python_scan_literal_expression_type();
+
+ if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+ {
+ module = get_access_to_python_module("pychrysalide.analysis.scan.exprs");
+
+ dict = PyModule_GetDict(module);
+
+ if (!ensure_python_scan_expression_is_registered())
+ return false;
+
+ if (!register_class_for_pygobject(dict, G_TYPE_SCAN_LITERAL_EXPRESSION, type))
+ return false;
+
+ if (!define_literal_expression_value_type_constants(type))
+ return false;
+
+ }
+
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : arg = argument quelconque à tenter de convertir. *
+* dst = destination des valeurs récupérées en cas de succès. *
+* *
+* Description : Tente de convertir en transmission d'octets à l'identique. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_scan_literal_expression(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_scan_literal_expression_type());
+
+ switch (result)
+ {
+ case -1:
+ /* L'exception est déjà fixée par Python */
+ result = 0;
+ break;
+
+ case 0:
+ PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to scan literal expression");
+ break;
+
+ case 1:
+ *((GScanLiteralExpression **)dst) = G_SCAN_LITERAL_EXPRESSION(pygobject_get(arg));
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/scan/exprs/literal.h b/plugins/pychrysalide/analysis/scan/exprs/literal.h
new file mode 100644
index 0000000..8e7ea70
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/exprs/literal.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * literal.h - équivalent Python du fichier "analysis/scan/exprs/literal.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_PYCHRYSALIDE_ANALYSIS_SCAN_EXPRS_LITERAL_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_EXPRS_LITERAL_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_scan_literal_expression_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.scan.exprs.ScanLiteralExpression'. */
+bool ensure_python_scan_literal_expression_is_registered(void);
+
+/* Tente de convertir en transmission d'octets à l'identique. */
+int convert_to_scan_literal_expression(PyObject *, void *);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_EXPRS_LITERAL_H */
diff --git a/plugins/pychrysalide/analysis/scan/exprs/module.c b/plugins/pychrysalide/analysis/scan/exprs/module.c
new file mode 100644
index 0000000..4f38430
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/exprs/module.c
@@ -0,0 +1,103 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire exprs en tant que module
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "module.h"
+
+
+#include <assert.h>
+
+
+#include "literal.h"
+#include "../../../helpers.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : super = module dont la définition est à compléter. *
+* *
+* Description : Ajoute le module 'analysis....modifiers' à un module Python. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool add_analysis_scan_exprs_module(PyObject *super)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *module; /* Sous-module mis en place */
+
+#define PYCHRYSALIDE_ANALYSIS_SCAN_EXPRS_MODULE_DOC \
+ "This module provide expressions used to build a match condition."
+
+ static PyModuleDef py_chrysalide_analysis_scan_exprs_module = {
+
+ .m_base = PyModuleDef_HEAD_INIT,
+
+ .m_name = "pychrysalide.analysis.scan.exprs",
+ .m_doc = PYCHRYSALIDE_ANALYSIS_SCAN_EXPRS_MODULE_DOC,
+
+ .m_size = -1,
+
+ };
+
+ module = build_python_module(super, &py_chrysalide_analysis_scan_exprs_module);
+
+ result = (module != NULL);
+
+ if (!result)
+ Py_XDECREF(module);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Intègre les objets du module 'analysis...patterns.modifiers'.*
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool populate_analysis_scan_exprs_module(void)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+ if (result) result = ensure_python_scan_literal_expression_is_registered();
+
+ assert(result);
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/scan/exprs/module.h b/plugins/pychrysalide/analysis/scan/exprs/module.h
new file mode 100644
index 0000000..ee4b8ab
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/exprs/module.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire exprs en tant que module
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_EXPRS_MODULE_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_EXPRS_MODULE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Ajoute le module 'analysis.scan.exprs' à un module Python. */
+bool add_analysis_scan_exprs_module(PyObject *);
+
+/* Intègre les objets du module 'analysis.scan.exprs'. */
+bool populate_analysis_scan_exprs_module(void);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_EXPRS_MODULE_H */
diff --git a/plugins/pychrysalide/analysis/scan/item.c b/plugins/pychrysalide/analysis/scan/item.c
index 959694e..014ae24 100644
--- a/plugins/pychrysalide/analysis/scan/item.c
+++ b/plugins/pychrysalide/analysis/scan/item.c
@@ -38,14 +38,68 @@
-CREATE_DYN_CONSTRUCTOR(registered_item, G_TYPE_REGISTERED_ITEM);
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+
+/* Initialise la classe des éléments appelables enregistrés. */
+static void py_scan_registered_item_init_gclass(GScanRegisteredItemClass *, gpointer);
+
+CREATE_DYN_ABSTRACT_CONSTRUCTOR(scan_registered_item, G_TYPE_SCAN_REGISTERED_ITEM, py_scan_registered_item_init_gclass);
/* Initialise une instance sur la base du dérivé de GObject. */
-static int py_registered_item_init(PyObject *, PyObject *, PyObject *);
+static int py_scan_registered_item_init(PyObject *, PyObject *, PyObject *);
+
+/* Indique le nom associé à une expression d'évaluation. */
+static char *py_scan_registered_item_get_name_wrapper(const GScanRegisteredItem *);
+
+/* Lance une résolution d'élément à solliciter. */
+static bool py_scan_registered_item_resolve_wrapper(GScanRegisteredItem *, const char *, GScanContext *, GScanScope *, GScanRegisteredItem **);
+
+/* Réduit une expression à une forme plus simple. */
+static bool py_scan_registered_item_reduce_wrapper(GScanRegisteredItem *, GScanContext *, GScanScope *, GScanExpression **);
+
+/* Effectue un appel à une fonction enregistrée. */
+static bool py_scan_registered_item_run_call_wrapper(GScanRegisteredItem *, GScanExpression **, size_t, GScanContext *, GScanScope *, GObject **);
+
+
+
+/* ------------------------- CONNEXION AVEC L'API DE PYTHON ------------------------- */
+
/* Lance une résolution d'élément à appeler. */
-static PyObject *py_registered_item_resolve(PyObject *, PyObject *);
+static PyObject *py_scan_registered_item_resolve(PyObject *, PyObject *);
+
+/* Fournit le désignation associée à un composant nommé. */
+static PyObject *py_scan_registered_item_get_name(PyObject *, void *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* GLUE POUR CREATION DEPUIS PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : class = classe à initialiser. *
+* unused = données non utilisées ici. *
+* *
+* Description : Initialise la classe des éléments appelables enregistrés. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+static void py_scan_registered_item_init_gclass(GScanRegisteredItemClass *class, gpointer unused)
+{
+ class->get_name = py_scan_registered_item_get_name_wrapper;
+ class->resolve = py_scan_registered_item_resolve_wrapper;
+ class->reduce = py_scan_registered_item_reduce_wrapper;
+ class->run_call = py_scan_registered_item_run_call_wrapper;
+
+}
/******************************************************************************
@@ -62,17 +116,26 @@ static PyObject *py_registered_item_resolve(PyObject *, PyObject *);
* *
******************************************************************************/
-static int py_registered_item_init(PyObject *self, PyObject *args, PyObject *kwds)
+static int py_scan_registered_item_init(PyObject *self, PyObject *args, PyObject *kwds)
{
int ret; /* Bilan de lecture des args. */
-#define REGISTERED_ITEM_DOC \
- "The *RegisteredItem* class defines the basics for evaluation" \
- " items involved into content scanning.\n" \
+#define SCAN_REGISTERED_ITEM_DOC \
+ "The *RegisteredItem* class is an abstract definition which is" \
+ " the base for all keywords involved in a match condition" \
+ " expression.\n" \
"\n" \
- "Instances can be created using the following constructor:\n" \
+ "Calls to the *__init__* constructor of this abstract object" \
+ " expect no particular argument.\n" \
"\n" \
- " RegisteredItem()"
+ "The following methods have to be defined for new classes:\n" \
+ "* pychrysalide.analysis.scan.RegisteredItem._resolve();\n" \
+ "* pychrysalide.analysis.scan.RegisteredItem._reduce();\n" \
+ "* pychrysalide.analysis.scan.RegisteredItem._call().\n" \
+ "\n" \
+ "One item has to be defined as class attributes in the final" \
+ " class:\n" \
+ "* pychrysalide.analysis.scan.RegisteredItem._name.\n"
/* Initialisation d'un objet GLib */
@@ -86,6 +149,338 @@ static int py_registered_item_init(PyObject *self, PyObject *args, PyObject *kwd
/******************************************************************************
* *
+* Paramètres : item = élément d'appel à consulter. *
+* *
+* Description : Indique le nom associé à une expression d'évaluation. *
+* *
+* Retour : Désignation humaine de l'expression d'évaluation. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *py_scan_registered_item_get_name_wrapper(const GScanRegisteredItem *item)
+{
+ char *result; /* Désignation à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyname; /* Nom en objet Python */
+ int ret; /* Bilan d'une conversion */
+
+#define SCAN_REGISTERED_ITEM_NAME_ATTRIB_WRAPPER PYTHON_GETTER_WRAPPER_DEF \
+( \
+ _name, \
+ "Provide the keyword of the expression item to be evaluated.\n" \
+ "\n" \
+ "The result has to be a string." \
+)
+
+ result = NULL;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(item));
+
+ if (PyObject_HasAttrString(pyobj, "_name"))
+ {
+ pyname = PyObject_GetAttrString(pyobj, "_name");
+
+ if (pyname != NULL)
+ {
+ ret = PyUnicode_Check(pyname);
+
+ if (ret)
+ result = strdup(PyUnicode_AsUTF8(pyname));
+
+ Py_DECREF(pyname);
+
+ }
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = élément d'appel à consulter. *
+* target = désignation de l'objet d'appel à identifier. *
+* ctx = contexte de suivi de l'analyse courante. *
+* scope = portée courante des variables locales. *
+* out = zone d'enregistrement de la résolution opérée. [OUT]*
+* *
+* Description : Lance une résolution d'élément à solliciter. *
+* *
+* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_scan_registered_item_resolve_wrapper(GScanRegisteredItem *item, const char *target, GScanContext *ctx, GScanScope *scope, GScanRegisteredItem **out)
+{
+ bool result; /* Bilan à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *pyret; /* Bilan de consultation */
+ GObject *gobj_ret; /* Bilan natif de consultation */
+
+#define SCAN_REGISTERED_ITEM_RESOLVE_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _cmp_rich, "$self, target, ctx, scope, /", \
+ METH_VARARGS, \
+ "Abstract method used to resolve an item by name.\n" \
+ "\n" \
+ "The *target* argument provide the name of the searched item;" \
+ " *ctx* is a pychrysalide.analysis.scan.ScanContext instance" \
+ " providing information about the current state; *scope* is a" \
+ " pychrysalide.analysis.scan.ScanScope offering a view on the" \
+ " current namespace for variables.\n" \
+ "\n" \
+ "The result has to be a pychrysalide.analysis.scan.RegisteredItem" \
+ " instance on success, or *None* in case of failure." \
+)
+
+ result = false;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(item));
+
+ if (has_python_method(pyobj, "_resolve"))
+ {
+ args = PyTuple_New(3);
+ PyTuple_SetItem(args, 0, PyUnicode_FromString(target));
+ PyTuple_SetItem(args, 1, pygobject_new(G_OBJECT(ctx)));
+ PyTuple_SetItem(args, 2, pygobject_new(G_OBJECT(scope)));
+
+ pyret = run_python_method(pyobj, "_resolve", args);
+
+ if (pyret != NULL)
+ {
+ gobj_ret = pygobject_get(pyret);
+
+ if (G_IS_SCAN_REGISTERED_ITEM(gobj_ret))
+ {
+ *out = G_SCAN_REGISTERED_ITEM(gobj_ret);
+
+ g_object_ref(G_OBJECT(*out));
+ result = true;
+
+ }
+
+ Py_DECREF(pyret);
+
+ }
+
+ Py_DECREF(args);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = élément d'appel à consulter. *
+* ctx = contexte de suivi de l'analyse courante. *
+* scope = portée courante des variables locales. *
+* out = zone d'enregistrement de la réduction opérée. [OUT] *
+* *
+* Description : Réduit une expression à une forme plus simple. *
+* *
+* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_scan_registered_item_reduce_wrapper(GScanRegisteredItem *item, GScanContext *ctx, GScanScope *scope, GScanExpression **out)
+{
+ bool result; /* Bilan à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *pyret; /* Bilan de consultation */
+ GObject *gobj_ret; /* Bilan natif de consultation */
+
+#define SCAN_REGISTERED_ITEM_REDUCE_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _cmp_rich, "$self, ctx, scope, /", \
+ METH_VARARGS, \
+ "Abstract method used to replace the item by an equivalent reduced" \
+ " value.\n" \
+ "\n" \
+ "The *ctx* argument is a pychrysalide.analysis.scan.ScanContext" \
+ " instance providing information about the current state; *scope*" \
+ " is a pychrysalide.analysis.scan.ScanScope offering a view on the" \
+ " current namespace for variables.\n" \
+ "\n" \
+ "The result has to be a pychrysalide.analysis.scan.ScanExpression" \
+ " instance on success, or *None* in case of failure." \
+)
+
+ result = false;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(item));
+
+ if (has_python_method(pyobj, "_reduce"))
+ {
+ args = PyTuple_New(2);
+ PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(ctx)));
+ PyTuple_SetItem(args, 1, pygobject_new(G_OBJECT(scope)));
+
+ pyret = run_python_method(pyobj, "_reduce", args);
+
+ if (pyret != NULL)
+ {
+ gobj_ret = pygobject_get(pyret);
+
+ if (G_IS_SCAN_EXPRESSION(gobj_ret))
+ {
+ *out = G_SCAN_EXPRESSION(gobj_ret);
+
+ g_object_ref(G_OBJECT(*out));
+ result = true;
+
+ }
+
+ Py_DECREF(pyret);
+
+ }
+
+ Py_DECREF(args);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = élément d'appel à consulter. *
+* args = liste d'éventuels arguments fournis. *
+* count = taille de cette liste. *
+* ctx = contexte de suivi de l'analyse courante. *
+* scope = portée courante des variables locales. *
+* out = zone d'enregistrement de la résolution opérée. [OUT] *
+* *
+* Description : Effectue un appel à une fonction enregistrée. *
+* *
+* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_scan_registered_item_run_call_wrapper(GScanRegisteredItem *item, GScanExpression **args, size_t count, GScanContext *ctx, GScanScope *scope, GObject **out)
+{
+ bool result; /* Bilan à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *sub_args; /* Sous-arguments pour l'appel */
+ size_t i; /* Boucle de parcours */
+ PyObject *py_args; /* Arguments pour l'appel */
+ PyObject *pyret; /* Bilan de consultation */
+ GObject *gobj_ret; /* Bilan natif de consultation */
+
+#define SCAN_REGISTERED_ITEM_CALL_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _cmp_rich, "$self, args, ctx, scope, /", \
+ METH_VARARGS, \
+ "Abstract method used to replace the item and its arguments by an" \
+ " equivalent reduced value.\n" \
+ "\n" \
+ "The *args* argument is a tuple of already reduced" \
+ " pychrysalide.analysis.scan.ScanExpression objects; ctx* argument" \
+ " is a pychrysalide.analysis.scan.ScanContext instance providing" \
+ " information about the current state; *scope* is a" \
+ " pychrysalide.analysis.scan.ScanScope offering a view on the" \
+ " current namespace for variables.\n" \
+ "\n" \
+ "The result has to be a pychrysalide.analysis.scan.ScanExpression" \
+ " instance on success, or *None* in case of failure." \
+)
+
+ result = false;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(item));
+
+ if (has_python_method(pyobj, "_call"))
+ {
+ sub_args = PyTuple_New(count);
+
+ for (i = 0; i < count; i++)
+ PyTuple_SetItem(sub_args, 1, pygobject_new(G_OBJECT(args[i])));
+
+ py_args = PyTuple_New(3);
+ PyTuple_SetItem(py_args, 0, sub_args);
+ PyTuple_SetItem(py_args, 1, pygobject_new(G_OBJECT(ctx)));
+ PyTuple_SetItem(py_args, 2, pygobject_new(G_OBJECT(scope)));
+
+ pyret = run_python_method(pyobj, "_call", py_args);
+
+ if (pyret != NULL)
+ {
+ gobj_ret = pygobject_get(pyret);
+
+ if (G_IS_OBJECT(gobj_ret))
+ {
+ *out = gobj_ret;
+
+ g_object_ref(G_OBJECT(*out));
+ result = true;
+
+ }
+
+ Py_DECREF(pyret);
+
+ }
+
+ Py_DECREF(py_args);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* CONNEXION AVEC L'API DE PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
* Paramètres : self = élément d'appel à consulter. *
* args = arguments fournis pour l'opération. *
* *
@@ -99,21 +494,21 @@ static int py_registered_item_init(PyObject *self, PyObject *args, PyObject *kwd
* *
******************************************************************************/
-static PyObject *py_registered_item_resolve(PyObject *self, PyObject *args)
+static PyObject *py_scan_registered_item_resolve(PyObject *self, PyObject *args)
{
PyObject *result; /* Bilan à retourner */
const char *target; /* Désignation de la cible */
GScanContext *ctx; /* Contexte d'analyse */
GScanScope *scope; /* Portée de variables locales */
int ret; /* Bilan de lecture des args. */
- GRegisteredItem *item; /* Version native */
+ GScanRegisteredItem *item; /* Version native */
bool status; /* Bilan d'exécution */
- GRegisteredItem *resolved; /* Elément trouvé */
+ GScanRegisteredItem *resolved; /* Elément trouvé */
-#define REGISTERED_ITEM_RESOLVE_METHOD PYTHON_METHOD_DEF \
+#define SCAN_REGISTERED_ITEM_RESOLVE_METHOD PYTHON_METHOD_DEF \
( \
resolve, "$self, target, /, ctx=None, scope=None", \
- METH_VARARGS, py_registered_item, \
+ METH_VARARGS, py_scan_registered_item, \
"Resolve a name into a scan item." \
"\n" \
"The *target* name is the only mandatory parameter and has to point"\
@@ -137,9 +532,9 @@ static PyObject *py_registered_item_resolve(PyObject *self, PyObject *args)
convert_to_scan_context, &ctx);
if (!ret) return NULL;
- item = G_REGISTERED_ITEM(pygobject_get(self));
+ item = G_SCAN_REGISTERED_ITEM(pygobject_get(self));
- status = g_registered_item_resolve(item, target, ctx, scope, &resolved);
+ status = g_scan_registered_item_resolve(item, target, ctx, scope, &resolved);
if (!status)
{
@@ -178,23 +573,23 @@ static PyObject *py_registered_item_resolve(PyObject *self, PyObject *args)
* *
******************************************************************************/
-static PyObject *py_registered_item_get_name(PyObject *self, void *closure)
+static PyObject *py_scan_registered_item_get_name(PyObject *self, void *closure)
{
PyObject *result; /* Décompte à retourner */
- GRegisteredItem *item; /* Version native */
+ GScanRegisteredItem *item; /* Version native */
char *name; /* Désignation à convertir */
-#define REGISTERED_ITEM_NAME_ATTRIB PYTHON_GET_DEF_FULL \
+#define SCAN_REGISTERED_ITEM_NAME_ATTRIB PYTHON_GET_DEF_FULL \
( \
- name, py_registered_item, \
+ name, py_scan_registered_item, \
"Name linked to the registered item.\n" \
"\n" \
"The result should be a string, or *None* for the root namespace." \
)
- item = G_REGISTERED_ITEM(pygobject_get(self));
+ item = G_SCAN_REGISTERED_ITEM(pygobject_get(self));
- name = g_registered_item_get_name(item);
+ name = g_scan_registered_item_get_name(item);
if (name == NULL)
{
@@ -224,38 +619,42 @@ static PyObject *py_registered_item_get_name(PyObject *self, void *closure)
* *
******************************************************************************/
-PyTypeObject *get_python_registered_item_type(void)
+PyTypeObject *get_python_scan_registered_item_type(void)
{
- static PyMethodDef py_registered_item_methods[] = {
- REGISTERED_ITEM_RESOLVE_METHOD,
+ static PyMethodDef py_scan_registered_item_methods[] = {
+ SCAN_REGISTERED_ITEM_RESOLVE_WRAPPER,
+ SCAN_REGISTERED_ITEM_REDUCE_WRAPPER,
+ SCAN_REGISTERED_ITEM_CALL_WRAPPER,
+ SCAN_REGISTERED_ITEM_RESOLVE_METHOD,
{ NULL }
};
- static PyGetSetDef py_registered_item_getseters[] = {
- REGISTERED_ITEM_NAME_ATTRIB,
+ static PyGetSetDef py_scan_registered_item_getseters[] = {
+ SCAN_REGISTERED_ITEM_NAME_ATTRIB_WRAPPER,
+ SCAN_REGISTERED_ITEM_NAME_ATTRIB,
{ NULL }
};
- static PyTypeObject py_registered_item_type = {
+ static PyTypeObject py_scan_registered_item_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "pychrysalide.analysis.scan.RegisteredItem",
+ .tp_name = "pychrysalide.analysis.scan.ScanRegisteredItem",
.tp_basicsize = sizeof(PyGObject),
- .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_BASETYPE,
- .tp_doc = REGISTERED_ITEM_DOC,
+ .tp_doc = SCAN_REGISTERED_ITEM_DOC,
- .tp_methods = py_registered_item_methods,
- .tp_getset = py_registered_item_getseters,
+ .tp_methods = py_scan_registered_item_methods,
+ .tp_getset = py_scan_registered_item_getseters,
- .tp_init = py_registered_item_init,
- .tp_new = py_registered_item_new,
+ .tp_init = py_scan_registered_item_init,
+ .tp_new = py_scan_registered_item_new,
};
- return &py_registered_item_type;
+ return &py_scan_registered_item_type;
}
@@ -264,7 +663,7 @@ PyTypeObject *get_python_registered_item_type(void)
* *
* Paramètres : - *
* *
-* Description : Prend en charge l'objet 'pychrysalide...scan.RegisteredItem'.*
+* Description : Prend en charge l'objet 'pychrysalide...ScanRegisteredItem'. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -272,13 +671,13 @@ PyTypeObject *get_python_registered_item_type(void)
* *
******************************************************************************/
-bool ensure_python_registered_item_is_registered(void)
+bool ensure_python_scan_registered_item_is_registered(void)
{
- PyTypeObject *type; /* Type Python 'RegisteredItem' */
+ PyTypeObject *type; /* Type 'ScanRegisteredItem' */
PyObject *module; /* Module à recompléter */
PyObject *dict; /* Dictionnaire du module */
- type = get_python_registered_item_type();
+ type = get_python_scan_registered_item_type();
if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
{
@@ -286,7 +685,7 @@ bool ensure_python_registered_item_is_registered(void)
dict = PyModule_GetDict(module);
- if (!register_class_for_pygobject(dict, G_TYPE_REGISTERED_ITEM, type))
+ if (!register_class_for_pygobject(dict, G_TYPE_SCAN_REGISTERED_ITEM, type))
return false;
}
@@ -309,11 +708,11 @@ bool ensure_python_registered_item_is_registered(void)
* *
******************************************************************************/
-int convert_to_registered_item(PyObject *arg, void *dst)
+int convert_to_scan_registered_item(PyObject *arg, void *dst)
{
int result; /* Bilan à retourner */
- result = PyObject_IsInstance(arg, (PyObject *)get_python_registered_item_type());
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_scan_registered_item_type());
switch (result)
{
@@ -327,7 +726,7 @@ int convert_to_registered_item(PyObject *arg, void *dst)
break;
case 1:
- *((GRegisteredItem **)dst) = G_REGISTERED_ITEM(pygobject_get(arg));
+ *((GScanRegisteredItem **)dst) = G_SCAN_REGISTERED_ITEM(pygobject_get(arg));
break;
default:
diff --git a/plugins/pychrysalide/analysis/scan/item.h b/plugins/pychrysalide/analysis/scan/item.h
index b3f1661..773908c 100644
--- a/plugins/pychrysalide/analysis/scan/item.h
+++ b/plugins/pychrysalide/analysis/scan/item.h
@@ -32,13 +32,13 @@
/* Fournit un accès à une définition de type à diffuser. */
-PyTypeObject *get_python_registered_item_type(void);
+PyTypeObject *get_python_scan_registered_item_type(void);
-/* Prend en charge l'objet 'pychrysalide.analysis.scan.RegisteredItem'. */
-bool ensure_python_registered_item_is_registered(void);
+/* Prend en charge l'objet 'pychrysalide.analysis.scan.ScanRegisteredItem'. */
+bool ensure_python_scan_registered_item_is_registered(void);
/* Tente de convertir en expression d'évaluation généraliste. */
-int convert_to_registered_item(PyObject *, void *);
+int convert_to_scan_registered_item(PyObject *, void *);
diff --git a/plugins/pychrysalide/analysis/scan/module.c b/plugins/pychrysalide/analysis/scan/module.c
index ff19d92..9ae0e52 100644
--- a/plugins/pychrysalide/analysis/scan/module.c
+++ b/plugins/pychrysalide/analysis/scan/module.c
@@ -35,6 +35,7 @@
#include "options.h"
#include "scanner.h"
#include "space.h"
+#include "exprs/module.h"
#include "patterns/module.h"
#include "../../helpers.h"
@@ -76,6 +77,7 @@ bool add_analysis_scan_module(PyObject *super)
result = (module != NULL);
+ if (result) result = add_analysis_scan_exprs_module(module);
if (result) result = add_analysis_scan_patterns_module(module);
if (!result)
@@ -107,12 +109,13 @@ bool populate_analysis_scan_module(void)
if (result) result = ensure_python_content_scanner_is_registered();
if (result) result = ensure_python_scan_context_is_registered();
if (result) result = ensure_python_scan_expression_is_registered();
- if (result) result = ensure_python_registered_item_is_registered();
+ if (result) result = ensure_python_scan_registered_item_is_registered();
if (result) result = ensure_python_scan_options_is_registered();
if (result) result = ensure_python_scan_namespace_is_registered();
if (result) result = populate_scan_module_with_core_methods();
+ if (result) result = populate_analysis_scan_exprs_module();
if (result) result = populate_analysis_scan_patterns_module();
assert(result);
diff --git a/plugins/pychrysalide/analysis/scan/patterns/modifier.c b/plugins/pychrysalide/analysis/scan/patterns/modifier.c
index 4cae011..6547d91 100644
--- a/plugins/pychrysalide/analysis/scan/patterns/modifier.c
+++ b/plugins/pychrysalide/analysis/scan/patterns/modifier.c
@@ -91,19 +91,27 @@ static int py_scan_token_modifier_init(PyObject *self, PyObject *args, PyObject
static PyObject *py_scan_token_modifier_transform(PyObject *self, PyObject *args)
{
PyObject *result; /* Bilan à faire remonter */
- const char *data; /* Séquence d'octets à traiter */
+ PyObject *py_src; /* Motifs Python en entrée */
+ PyObject *py_arg; /* Eventuel paramètre de config*/
+ sized_binary_t src; /* Entrée au format adapté */
Py_ssize_t len; /* Quantité de ces données */
int ret; /* Bilan de lecture des args. */
- sized_binary_t src; /* Entrée au format adapté */
+ sized_binary_t *src_list; /* Entrées au format adapté */
+ size_t scount; /* Taille de cette liste */
+ bool dyn_src; /* Allocation dynamique ? */
+ Py_ssize_t size; /* Taille d'une séquence */
+ Py_ssize_t k; /* Boucle de parcours #1 */
+ PyObject *item; /* Elément de liste de motifs */
+ modifier_arg_t arg; /* Eventuelle précision */
GScanTokenModifier *modifier; /* Version native de l'instance*/
sized_binary_t *dest; /* Liste des nouvelles chaînes */
- size_t count; /* Taille de cette liste */
+ size_t dcount; /* Taille de cette liste */
bool status; /* Bilan de l'opération */
- size_t i; /* Boucle de parcours */
+ size_t i; /* Boucle de parcours #2 */
#define SCAN_TOKEN_MODIFIER_TRANSFORM_METHOD PYTHON_METHOD_DEF \
( \
- transform, "$self, data", \
+ transform, "$self, data, /, arg", \
METH_VARARGS, py_scan_token_modifier, \
"Transform data from a byte pattern for an incoming scan.\n" \
"\n" \
@@ -113,21 +121,105 @@ static PyObject *py_scan_token_modifier_transform(PyObject *self, PyObject *args
" *None* in case of error." \
)
- ret = PyArg_ParseTuple(args, "s#", &data, &len);
+ py_arg = NULL;
+
+ ret = PyArg_ParseTuple(args, "O|O", &py_src, &py_arg);
if (!ret) return NULL;
- src.data = (char *)data;
- src.len = len;
+ /* Constitution des motifs d'entrée */
+
+ if (PyBytes_Check(py_src))
+ {
+ ret = PyBytes_AsStringAndSize(py_src, &src.data, &len);
+ if (ret == -1) return NULL;
+
+ src.len = len;
+
+ src_list = &src;
+ scount = 1;
+
+ dyn_src = false;
+
+ }
+
+ else if (PySequence_Check(py_src))
+ {
+ size = PySequence_Size(py_src);
+
+ src_list = malloc(size * sizeof(sized_binary_t));
+ scount = size;
+
+ dyn_src = true;
+
+ for (k = 0; k < size; k++)
+ {
+ item = PySequence_ITEM(py_src, k);
+
+ if (PyBytes_Check(item))
+ {
+ ret = PyBytes_AsStringAndSize(item, &src_list[k].data, &len);
+ if (ret == -1) return NULL;
+
+ src_list[k].len = len;
+
+ }
+ else
+ {
+ free(src_list);
+
+ PyErr_SetString(PyExc_TypeError, "lists of items other than bytes are not supported");
+ return NULL;
+ }
+
+ }
+
+ }
+
+ else
+ {
+ PyErr_SetString(PyExc_TypeError, "only bytes and lists of bytes are expected as input for modifiers");
+ return NULL;
+ }
+
+ /* Récupération d'une éventuelle précision opérationnelle */
+
+ if (py_arg != NULL)
+ {
+ if (PyLong_Check(py_arg))
+ {
+ arg.type = MAT_UNSIGNED_INTEGER;
+ arg.value.u_integer = PyLong_AsUnsignedLongLong(py_arg);
+ }
+
+ else
+ {
+ if (dyn_src)
+ free(src_list);
+
+ PyErr_SetString(PyExc_TypeError, "unable to handle the argument type for calling a modifier");
+ return NULL;
+
+ }
+
+ }
+
+ /* Création des nouveaux motifs */
modifier = G_SCAN_TOKEN_MODIFIER(pygobject_get(self));
- status = g_scan_token_modifier_transform(modifier, &src, &dest, &count);
+ if (py_arg == NULL)
+ status = g_scan_token_modifier_transform(modifier, src_list, scount, &dest, &dcount);
+ else
+ status = g_scan_token_modifier_transform_with_arg(modifier, src_list, scount, &arg, &dest, &dcount);
+
+ if (dyn_src)
+ free(src_list);
if (status)
{
- result = PyTuple_New(count);
+ result = PyTuple_New(dcount);
- for (i = 0; i < count; i++)
+ for (i = 0; i < dcount; i++)
{
PyTuple_SetItem(result, i, PyBytes_FromStringAndSize(dest[i].data, dest[i].len));
exit_szstr(&dest[i]);
@@ -226,7 +318,7 @@ PyTypeObject *get_python_scan_token_modifier_type(void)
.tp_name = "pychrysalide.analysis.scan.patterns.TokenModifier",
.tp_basicsize = sizeof(PyGObject),
- .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
.tp_doc = SCAN_TOKEN_MODIFIER_DOC,
diff --git a/plugins/pychrysalide/analysis/scan/patterns/modifiers/Makefile.am b/plugins/pychrysalide/analysis/scan/patterns/modifiers/Makefile.am
index baf7ed5..ae53e45 100644
--- a/plugins/pychrysalide/analysis/scan/patterns/modifiers/Makefile.am
+++ b/plugins/pychrysalide/analysis/scan/patterns/modifiers/Makefile.am
@@ -6,7 +6,8 @@ libpychrysaanalysisscanpatternsmodifiers_la_SOURCES = \
list.h list.c \
module.h module.c \
plain.h plain.c \
- rev.h rev.c
+ rev.h rev.c \
+ xor.h xor.c
libpychrysaanalysisscanpatternsmodifiers_la_CFLAGS = $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) $(TOOLKIT_CFLAGS) \
-I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
diff --git a/plugins/pychrysalide/analysis/scan/patterns/modifiers/hex.c b/plugins/pychrysalide/analysis/scan/patterns/modifiers/hex.c
index d0d1e1f..503580d 100644
--- a/plugins/pychrysalide/analysis/scan/patterns/modifiers/hex.c
+++ b/plugins/pychrysalide/analysis/scan/patterns/modifiers/hex.c
@@ -131,7 +131,7 @@ PyTypeObject *get_python_scan_hex_modifier_type(void)
* *
* Paramètres : - *
* *
-* Description : Prend en charge l'objet 'pychrysalide....HexModifier'. *
+* Description : Prend en charge l'objet 'pychrysalide....HexModifier'. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -141,7 +141,7 @@ PyTypeObject *get_python_scan_hex_modifier_type(void)
bool ensure_python_scan_hex_modifier_is_registered(void)
{
- PyTypeObject *type; /* Type Python 'HexModifier' */
+ PyTypeObject *type; /* Type Python 'HexModifier' */
PyObject *module; /* Module à recompléter */
PyObject *dict; /* Dictionnaire du module */
diff --git a/plugins/pychrysalide/analysis/scan/patterns/modifiers/module.c b/plugins/pychrysalide/analysis/scan/patterns/modifiers/module.c
index 1e9bda7..ae450dc 100644
--- a/plugins/pychrysalide/analysis/scan/patterns/modifiers/module.c
+++ b/plugins/pychrysalide/analysis/scan/patterns/modifiers/module.c
@@ -32,6 +32,7 @@
#include "list.h"
#include "plain.h"
#include "rev.h"
+#include "xor.h"
#include "../../../../helpers.h"
@@ -102,6 +103,7 @@ bool populate_analysis_scan_patterns_modifiers_module(void)
if (result) result = ensure_python_scan_modifier_list_is_registered();
if (result) result = ensure_python_scan_plain_modifier_is_registered();
if (result) result = ensure_python_scan_reverse_modifier_is_registered();
+ if (result) result = ensure_python_scan_xor_modifier_is_registered();
assert(result);
diff --git a/plugins/pychrysalide/analysis/scan/patterns/modifiers/rev.c b/plugins/pychrysalide/analysis/scan/patterns/modifiers/rev.c
index 6ee350c..841e929 100644
--- a/plugins/pychrysalide/analysis/scan/patterns/modifiers/rev.c
+++ b/plugins/pychrysalide/analysis/scan/patterns/modifiers/rev.c
@@ -141,7 +141,7 @@ PyTypeObject *get_python_scan_reverse_modifier_type(void)
bool ensure_python_scan_reverse_modifier_is_registered(void)
{
- PyTypeObject *type; /* Type Python 'HexModifier' */
+ PyTypeObject *type; /* Type Python ReverseModifier */
PyObject *module; /* Module à recompléter */
PyObject *dict; /* Dictionnaire du module */
diff --git a/plugins/pychrysalide/analysis/scan/patterns/modifiers/xor.c b/plugins/pychrysalide/analysis/scan/patterns/modifiers/xor.c
new file mode 100644
index 0000000..17a32f4
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/patterns/modifiers/xor.c
@@ -0,0 +1,210 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * xor.c - équivalent Python du fichier "analysis/scan/patterns/modifiers/xor.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 "xor.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <analysis/scan/patterns/modifiers/xor.h>
+
+
+#include "../modifier.h"
+#include "../../../../access.h"
+#include "../../../../helpers.h"
+
+
+
+CREATE_DYN_CONSTRUCTOR(scan_xor_modifier, G_TYPE_SCAN_XOR_MODIFIER);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_scan_xor_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_xor_modifier_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ int ret; /* Bilan de lecture des args. */
+
+#define SCAN_XOR_MODIFIER_DOC \
+ "The *XorModifier* class transforms a byte pattern by XORing bytes.\n" \
+ "\n" \
+ "Instances can be created using the following constructor:\n" \
+ "\n" \
+ " XorModifier()"
+
+ /* 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_xor_modifier_type(void)
+{
+ static PyMethodDef py_scan_xor_modifier_methods[] = {
+ { NULL }
+ };
+
+ static PyGetSetDef py_scan_xor_modifier_getseters[] = {
+ { NULL }
+ };
+
+ static PyTypeObject py_scan_xor_modifier_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.analysis.scan.patterns.modifiers.XorModifier",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+ .tp_doc = SCAN_XOR_MODIFIER_DOC,
+
+ .tp_methods = py_scan_xor_modifier_methods,
+ .tp_getset = py_scan_xor_modifier_getseters,
+
+ .tp_init = py_scan_xor_modifier_init,
+ .tp_new = py_scan_xor_modifier_new,
+
+ };
+
+ return &py_scan_xor_modifier_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Prend en charge l'objet 'pychrysalide....XorModifier'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool ensure_python_scan_xor_modifier_is_registered(void)
+{
+ PyTypeObject *type; /* Type Python XorModifier */
+ PyObject *module; /* Module à recompléter */
+ PyObject *dict; /* Dictionnaire du module */
+
+ type = get_python_scan_xor_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_scan_token_modifier_is_registered())
+ return false;
+
+ if (!register_class_for_pygobject(dict, G_TYPE_SCAN_XOR_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 d'octets par inverse. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_scan_xor_modifier(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_scan_xor_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 XOR modifier");
+ break;
+
+ case 1:
+ *((GScanXorModifier **)dst) = G_SCAN_XOR_MODIFIER(pygobject_get(arg));
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/scan/patterns/modifiers/xor.h b/plugins/pychrysalide/analysis/scan/patterns/modifiers/xor.h
new file mode 100644
index 0000000..7b9bb69
--- /dev/null
+++ b/plugins/pychrysalide/analysis/scan/patterns/modifiers/xor.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * xor.h - équivalent Python du fichier "analysis/scan/patterns/modifiers/xor.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_PYCHRYSALIDE_ANALYSIS_SCAN_PATTERNS_MODIFIERS_XOR_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_PATTERNS_MODIFIERS_XOR_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_scan_xor_modifier_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.scan.patterns.modifiers.XorModifier'. */
+bool ensure_python_scan_xor_modifier_is_registered(void);
+
+/* Tente de convertir en transformation d'octets par inverse. */
+int convert_to_scan_xor_modifier(PyObject *, void *);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_SCAN_PATTERNS_MODIFIERS_XOR_H */
diff --git a/plugins/pychrysalide/analysis/scan/scanner.c b/plugins/pychrysalide/analysis/scan/scanner.c
index e2d5a18..bc58c9a 100644
--- a/plugins/pychrysalide/analysis/scan/scanner.c
+++ b/plugins/pychrysalide/analysis/scan/scanner.c
@@ -76,6 +76,7 @@ static PyObject *py_content_scanner_get_filename(PyObject *, void *);
static int py_content_scanner_init(PyObject *self, PyObject *args, PyObject *kwds)
{
const char *text; /* Contenu de règles à traiter */
+ Py_ssize_t len; /* Taille de ce nom */
const char *filename; /* Fichier de définitions */
int ret; /* Bilan de lecture des args. */
GContentScanner *scanner; /* Création GLib à transmettre */
@@ -100,9 +101,10 @@ static int py_content_scanner_init(PyObject *self, PyObject *args, PyObject *kwd
/* Récupération des paramètres */
text = NULL;
+ len = 0;
filename = NULL;
- ret = PyArg_ParseTupleAndKeywords(args, kwds, "|ss", kwlist, &text, &filename);
+ ret = PyArg_ParseTupleAndKeywords(args, kwds, "|s#s", kwlist, &text, &len, &filename);
if (!ret) return -1;
/* Initialisation d'un objet GLib */
@@ -116,7 +118,7 @@ static int py_content_scanner_init(PyObject *self, PyObject *args, PyObject *kwd
if (text != NULL)
{
- if (!g_content_scanner_create_from_text(scanner, text))
+ if (!g_content_scanner_create_from_text(scanner, text, len))
{
PyErr_SetString(PyExc_ValueError, _("Unable to create content scanner."));
return -1;
diff --git a/plugins/pychrysalide/analysis/scan/space.c b/plugins/pychrysalide/analysis/scan/space.c
index 79e0c28..6ea87b8 100644
--- a/plugins/pychrysalide/analysis/scan/space.c
+++ b/plugins/pychrysalide/analysis/scan/space.c
@@ -122,7 +122,7 @@ static int py_scan_namespace_init(PyObject *self, PyObject *args, PyObject *kwds
static PyObject *py_scan_namespace_register_item(PyObject *self, PyObject *args)
{
PyObject *result; /* Bilan à retourner */
- GRegisteredItem *item; /* Elément d'évaluation à lier */
+ GScanRegisteredItem *item; /* Elément d'évaluation à lier */
int ret; /* Bilan de lecture des args. */
GScanNamespace *space; /* Version native */
bool status; /* Bilan de l'opération */
@@ -140,7 +140,7 @@ static PyObject *py_scan_namespace_register_item(PyObject *self, PyObject *args)
" *True* in case of success, *False* for a failure.\n" \
)
- ret = PyArg_ParseTuple(args, "O&", convert_to_registered_item, &item);
+ ret = PyArg_ParseTuple(args, "O&", convert_to_scan_registered_item, &item);
if (!ret) return NULL;
space = G_SCAN_NAMESPACE(pygobject_get(self));
@@ -185,7 +185,7 @@ PyTypeObject *get_python_scan_namespace_type(void)
.tp_name = "pychrysalide.analysis.scan.ScanNamespace",
.tp_basicsize = sizeof(PyGObject),
- .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
.tp_doc = SCAN_NAMESPACE_DOC,
diff --git a/plugins/pychrysalide/common/bits.c b/plugins/pychrysalide/common/bits.c
index 9275996..a127251 100644
--- a/plugins/pychrysalide/common/bits.c
+++ b/plugins/pychrysalide/common/bits.c
@@ -98,6 +98,9 @@ static PyObject *py_bitfield_test_zeros_with(PyObject *, PyObject *);
/* Teste l'état à 1 de bits selon un masque de bits. */
static PyObject *py_bitfield_test_ones_with(PyObject *, PyObject *);
+/* Recherche un prochain bit défini dans un champ de bits. */
+static PyObject *py_bitfield_find_next_set(PyObject *, PyObject *);
+
/* Indique la taille d'un champ de bits donné. */
static PyObject *py_bitfield_get_size(PyObject *, void *);
@@ -891,6 +894,58 @@ static PyObject *py_bitfield_test_ones_with(PyObject *self, PyObject *args)
/******************************************************************************
* *
+* Paramètres : self = champ de bits à consulter. *
+* args = arguments fournis pour la conduite de l'opération. *
+* *
+* Description : Recherche un prochain bit défini dans un champ de bits. *
+* *
+* Retour : Position d'un bit à 1 ou taille du champ si plus aucun. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_bitfield_find_next_set(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Bilan à faire remonter */
+ unsigned long prev; /* Indice d'un bit à écarter */
+ int ret; /* Bilan de lecture des args. */
+ py_bitfield_t *bf; /* Instance à manipuler */
+ size_t found; /* Indice de bit trouvé */
+
+#define BITFIELD_FIND_NEXT_SET_METHOD PYTHON_METHOD_DEF \
+( \
+ find_next_set, "$self, /, prev=None", \
+ METH_VARARGS, py_bitfield, \
+ "Find the index of the next set bit in the bit field.\n"\
+ "\n" \
+ "If provided, the *prev* argument is the position of" \
+ " a previously found bit, which gets discarded for the" \
+ " current call.\n" \
+ "\n" \
+ "The result is a integer value: a valid index inside" \
+ " the bit field, or the bit field size if no set bit" \
+ " is found." \
+)
+
+ prev = (unsigned long)-1;
+
+ ret = PyArg_ParseTuple(args, "|k", &prev);
+ if (!ret) return NULL;
+
+ bf = (py_bitfield_t *)self;
+
+ found = find_next_set_in_bit_field(bf->native, prev == (unsigned long)-1 ? NULL : (size_t []) { prev });
+
+ result = PyLong_FromSize_t(found);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : self = classe représentant une instruction. *
* closure = adresse non utilisée ici. *
* *
@@ -998,6 +1053,7 @@ PyTypeObject *get_python_bitfield_type(void)
BITFIELD_TEST_ALL_METHOD,
BITFIELD_TEST_ZEROS_WITH_METHOD,
BITFIELD_TEST_ONES_WITH_METHOD,
+ BITFIELD_FIND_NEXT_SET_METHOD,
{ NULL }
};
diff --git a/plugins/pychrysalide/core.c b/plugins/pychrysalide/core.c
index 771d129..08f570f 100644
--- a/plugins/pychrysalide/core.c
+++ b/plugins/pychrysalide/core.c
@@ -64,8 +64,10 @@
#include "debug/module.h"
#include "format/module.h"
#include "glibext/module.h"
-#include "gtkext/module.h"
-#include "gui/module.h"
+#ifdef INCLUDE_GTK_SUPPORT
+# include "gtkext/module.h"
+# include "gui/module.h"
+#endif
#include "mangling/module.h"
#include "plugins/module.h"
#include "plugins/plugin.h"
@@ -101,7 +103,9 @@ static bool is_current_abi_suitable(void);
static bool install_metaclass_for_python_gobjects(void);
/* Définit la version attendue de GTK à charger dans Python. */
+#ifdef INCLUDE_GTK_SUPPORT
static bool set_version_for_gtk_namespace(const char *);
+#endif
/* Point de sortie pour l'initialisation de Python. */
static void PyExit_pychrysalide(void);
@@ -423,7 +427,7 @@ static bool install_metaclass_for_python_gobjects(void)
* Remarques : - *
* *
******************************************************************************/
-
+#ifdef INCLUDE_GTK_SUPPORT
static bool set_version_for_gtk_namespace(const char *version)
{
bool result; /* Bilan à retourner */
@@ -459,6 +463,7 @@ static bool set_version_for_gtk_namespace(const char *version)
return result;
}
+#endif
/******************************************************************************
@@ -584,8 +589,10 @@ PyMODINIT_FUNC PyInit_pychrysalide(void)
if (!install_metaclass_for_python_gobjects())
goto exit;
+#ifdef INCLUDE_GTK_SUPPORT
if (!set_version_for_gtk_namespace("3.0"))
goto exit;
+#endif
if (!load_all_core_components(true))
{
@@ -800,11 +807,11 @@ static void load_python_plugins(GPluginModule *plugin)
if (dir != NULL)
{
- closedir(dir);
+ closedir(dir);
- edir = get_effective_directory(PLUGINS_DATA_DIR G_DIR_SEPARATOR_S "python");
- extend_python_path(edir);
- free(edir);
+ edir = get_effective_directory(PLUGINS_DATA_DIR G_DIR_SEPARATOR_S "python");
+ extend_python_path(edir);
+ free(edir);
}
@@ -821,7 +828,7 @@ static void load_python_plugins(GPluginModule *plugin)
save = NULL; /* gcc... */
for (path = strtok_r(paths, ":", &save);
- path != NULL;
+ path != NULL;
path = strtok_r(NULL, ":", &save))
{
dir = opendir(path);
@@ -900,7 +907,7 @@ static void load_python_plugins(GPluginModule *plugin)
}
- closedir(dir);
+ closedir(dir);
}
@@ -944,8 +951,6 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin)
gstate = PyGILState_Ensure();
- PySys_SetArgv(0, (wchar_t *[]) { NULL });
-
_chrysalide_module = PyImport_ImportModule("pychrysalide");
/**
diff --git a/plugins/pychrysalide/plugins/plugin.c b/plugins/pychrysalide/plugins/plugin.c
index 340c617..b013345 100644
--- a/plugins/pychrysalide/plugins/plugin.c
+++ b/plugins/pychrysalide/plugins/plugin.c
@@ -1796,8 +1796,6 @@ GPluginModule *create_python_plugin(const char *modname, const char *filename)
if (class == NULL) goto no_class;
if (!PyType_Check(class->ob_type)) goto no_class;
- Py_INCREF(class);
-
instance = PyObject_CallFunction(class, NULL);
if (instance == NULL) goto no_instance;
diff --git a/plugins/python/scripting/core.py b/plugins/python/scripting/core.py
index ff912ed..135edb4 100644
--- a/plugins/python/scripting/core.py
+++ b/plugins/python/scripting/core.py
@@ -1,4 +1,7 @@
+import gi
+gi.require_version('Gtk', '3.0')
+
from gi.repository import GLib, Gtk
import os