summaryrefslogtreecommitdiff
path: root/src/analysis/scan/exprs
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2023-01-30 06:59:35 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2023-01-30 06:59:35 (GMT)
commitdb3b204dd7a71b2f74a4e69b2159a96e3ab66614 (patch)
tree34174311b7ac504f03a10a889ada7f28db7a06c0 /src/analysis/scan/exprs
parent34ee1bfca78e8423cfa29329fdc756569d6b1960 (diff)
Save an initial version of rost.
Diffstat (limited to 'src/analysis/scan/exprs')
-rw-r--r--src/analysis/scan/exprs/Makefile.am24
-rw-r--r--src/analysis/scan/exprs/arithmop-int.h60
-rw-r--r--src/analysis/scan/exprs/arithmop.c414
-rw-r--r--src/analysis/scan/exprs/arithmop.h67
-rw-r--r--src/analysis/scan/exprs/boolop-int.h60
-rw-r--r--src/analysis/scan/exprs/boolop.c450
-rw-r--r--src/analysis/scan/exprs/boolop.h65
-rw-r--r--src/analysis/scan/exprs/call-int.h63
-rw-r--r--src/analysis/scan/exprs/call.c426
-rw-r--r--src/analysis/scan/exprs/call.h59
-rw-r--r--src/analysis/scan/exprs/literal-int.h73
-rw-r--r--src/analysis/scan/exprs/literal.c605
-rw-r--r--src/analysis/scan/exprs/literal.h70
-rw-r--r--src/analysis/scan/exprs/relop-int.h60
-rw-r--r--src/analysis/scan/exprs/relop.c374
-rw-r--r--src/analysis/scan/exprs/relop.h56
-rw-r--r--src/analysis/scan/exprs/str-int.h61
-rw-r--r--src/analysis/scan/exprs/str.c437
-rw-r--r--src/analysis/scan/exprs/str.h67
19 files changed, 3491 insertions, 0 deletions
diff --git a/src/analysis/scan/exprs/Makefile.am b/src/analysis/scan/exprs/Makefile.am
new file mode 100644
index 0000000..f164864
--- /dev/null
+++ b/src/analysis/scan/exprs/Makefile.am
@@ -0,0 +1,24 @@
+
+noinst_LTLIBRARIES = libanalysisscanexprs.la
+
+
+libanalysisscanexprs_la_SOURCES = \
+ arithmop-int.h \
+ arithmop.h arithmop.c \
+ boolop-int.h \
+ boolop.h boolop.c \
+ call-int.h \
+ call.h call.c \
+ literal-int.h \
+ literal.h literal.c \
+ relop-int.h \
+ relop.h relop.c \
+ str-int.h \
+ str.h str.c
+
+libanalysisscanexprs_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS)
+
+
+devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
+
+dev_HEADERS = $(libanalysisscanexprs_la_SOURCES:%c=)
diff --git a/src/analysis/scan/exprs/arithmop-int.h b/src/analysis/scan/exprs/arithmop-int.h
new file mode 100644
index 0000000..75f1dbb
--- /dev/null
+++ b/src/analysis/scan/exprs/arithmop-int.h
@@ -0,0 +1,60 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * arithmop-int.h - prototypes internes pour la gestion des opérations arithmétiques
+ *
+ * Copyright (C) 2022 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_SCAN_EXPRS_ARITHMOP_INT_H
+#define _ANALYSIS_SCAN_EXPRS_ARITHMOP_INT_H
+
+
+#include "arithmop.h"
+
+
+#include "../expr-int.h"
+
+
+
+/* Opération arithmétique impliquant deux opérandes (instance) */
+struct _GArithmOperation
+{
+ GScanExpression parent; /* A laisser en premier */
+
+ ArithmeticExpressionOperator operator; /* Type d'opération menée */
+
+ GScanExpression *first; /* Expression impactée #1 */
+ GScanExpression *second; /* Expression impactée #2 */
+
+};
+
+/* Opération arithmétique impliquant deux opérandes (classe) */
+struct _GArithmOperationClass
+{
+ GScanExpressionClass parent; /* A laisser en premier */
+
+};
+
+
+/* Met en place une opération arithmétique entre expressions. */
+bool g_arithmetic_operation_create(GArithmOperation *, ArithmeticExpressionOperator, GScanExpression *, GScanExpression *);
+
+
+
+#endif /* _ANALYSIS_SCAN_EXPRS_ARITHMOP_INT_H */
diff --git a/src/analysis/scan/exprs/arithmop.c b/src/analysis/scan/exprs/arithmop.c
new file mode 100644
index 0000000..f57e260
--- /dev/null
+++ b/src/analysis/scan/exprs/arithmop.c
@@ -0,0 +1,414 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * arithmop.c - gestion des opérations arithmétiques
+ *
+ * Copyright (C) 2022 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "arithmop.h"
+
+
+#include "arithmop-int.h"
+#include "literal.h"
+
+
+
+/* --------------------- INTRODUCTION D'UNE NOUVELLE EXPRESSION --------------------- */
+
+
+/* Initialise la classe des opérations arithmétiques. */
+static void g_arithmetic_operation_class_init(GArithmOperationClass *);
+
+/* Initialise une instance d'opération arithmétique. */
+static void g_arithmetic_operation_init(GArithmOperation *);
+
+/* Supprime toutes les références externes. */
+static void g_arithmetic_operation_dispose(GArithmOperation *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_arithmetic_operation_finalize(GArithmOperation *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Réalise une comparaison entre objets selon un critère précis. */
+static bool g_arithmetic_operation_compare_rich(const GArithmOperation *, const GArithmOperation *, RichCmpOperation, bool *);
+
+/* Initialise une instance d'opération de relation. */
+static GScanExpression *g_arithmetic_operation_duplicate(const GArithmOperation *);
+
+/* Réduit une expression à une forme plus simple. */
+GScanExpression *g_arithmetic_operation_reduce(GArithmOperation *, GScanContext *, bool);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* INTRODUCTION D'UNE NOUVELLE EXPRESSION */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une opération de relation entre expressions. */
+G_DEFINE_TYPE(GArithmOperation, g_arithmetic_operation, G_TYPE_SCAN_EXPRESSION);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des opérations arithmétiques. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_arithmetic_operation_class_init(GArithmOperationClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GScanExpressionClass *expr; /* Version de classe parente */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_arithmetic_operation_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_arithmetic_operation_finalize;
+
+ expr = G_SCAN_EXPRESSION_CLASS(klass);
+
+ expr->cmp_rich = (compare_expr_rich_fc)g_arithmetic_operation_compare_rich;
+ expr->dup = (dup_expr_fc)g_arithmetic_operation_duplicate;
+ expr->reduce = (reduce_expr_fc)g_arithmetic_operation_reduce;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : op = instance à initialiser. *
+* *
+* Description : Initialise une instance d'opération arithmétique. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_arithmetic_operation_init(GArithmOperation *op)
+{
+ op->first = NULL;
+ op->second = NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : op = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_arithmetic_operation_dispose(GArithmOperation *op)
+{
+ g_clear_object(&op->first);
+ g_clear_object(&op->second);
+
+ G_OBJECT_CLASS(g_arithmetic_operation_parent_class)->dispose(G_OBJECT(op));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : op = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_arithmetic_operation_finalize(GArithmOperation *op)
+{
+ G_OBJECT_CLASS(g_arithmetic_operation_parent_class)->finalize(G_OBJECT(op));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operator = type d'opération arithmétique à représenter. *
+* first = premier opérande concerné. *
+* second = éventuel second opérande impliqué ou NULL. *
+* *
+* Description : Organise une opération arithmétique entre expressions. *
+* *
+* Retour : Fonction mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GScanExpression *g_arithmetic_operation_new(ArithmeticExpressionOperator operator, GScanExpression *first, GScanExpression *second)
+{
+ GScanExpression *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_ARITHMETIC_OPERATION, NULL);
+
+ if (!g_arithmetic_operation_create(G_ARITHMETIC_OPERATION(result), operator, first, second))
+ g_clear_object(&result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : op = instance à initialiser pleinement. *
+* operator = type d'opération booléenne à représenter. *
+* first = premier opérande concerné. *
+* second = éventuel second opérande impliqué ou NULL. *
+* *
+* Description : Met en place une opération arithmétique entre expressions. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_arithmetic_operation_create(GArithmOperation *op, ArithmeticExpressionOperator operator, GScanExpression *first, GScanExpression *second)
+{
+ bool result; /* Bilan à retourner */
+ ExprValueType vtype; /* Type de valeur portée */
+
+ result = false;
+
+ vtype = g_scan_expression_get_value_type(first);
+
+ if (vtype != EVT_INTEGER && vtype != EVT_PENDING)
+ goto exit;
+
+ vtype = g_scan_expression_get_value_type(second);
+
+ if (vtype != EVT_INTEGER && vtype != EVT_PENDING)
+ goto exit;
+
+ if (!g_scan_expression_create(G_SCAN_EXPRESSION(op), EVT_INTEGER))
+ goto exit;
+
+ op->operator = operator;
+
+ op->first = first;
+ g_object_ref(G_OBJECT(op->first));
+
+ op->second = second;
+ g_object_ref(G_OBJECT(op->second));
+
+ result = true;
+
+ exit:
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : item = premier objet à consulter pour une comparaison. *
+* other = second objet à consulter pour une comparaison. *
+* op = opération de comparaison à réaliser. *
+* status = bilan des opérations de comparaison. [OUT] *
+* *
+* Description : Réalise une comparaison entre objets selon un critère précis.*
+* *
+* Retour : true si la comparaison a pu être effectuée, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_arithmetic_operation_compare_rich(const GArithmOperation *item, const GArithmOperation *other, RichCmpOperation op, bool *status)
+{
+ bool result; /* Etat à retourner */
+ bool equal; /* Bilan intermédiaire */
+
+ result = true; // TODO : cmp parent()->type
+
+ if (item->operator != other->operator)
+ {
+ result = compare_rich_integer_values(item->operator, other->operator, op);
+ goto done;
+ }
+
+ equal = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item), G_COMPARABLE_ITEM(other), RCO_EQ, status);
+
+ if (!equal)
+ {
+ result = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->first),
+ G_COMPARABLE_ITEM(other->first),
+ op, status);
+ goto done;
+ }
+
+ result = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->second),
+ G_COMPARABLE_ITEM(other->second),
+ op, status);
+
+ done:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = expression à copier. *
+* *
+* Description : Reproduit une expression en place dans une nouvelle instance.*
+* *
+* Retour : Nouvelle instance d'expression. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GScanExpression *g_arithmetic_operation_duplicate(const GArithmOperation *expr)
+{
+ GScanExpression *result; /* Instance copiée à retourner */
+
+ result = g_arithmetic_operation_new(expr->operator, expr->first, expr->second);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = expression à consulter. *
+* ctx = contexte de suivi de l'analyse courante. *
+* final = impose une conversion finale de dernier tour. *
+* *
+* Description : Réduit une expression à une forme plus simple. *
+* *
+* Retour : Réduction correspondante, expression déjà réduite, ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GScanExpression *g_arithmetic_operation_reduce(GArithmOperation *expr, GScanContext *ctx, bool final)
+{
+ GScanExpression *result; /* Instance à renvoyer */
+ GScanExpression *new; /* Nouvelle expression obtenue */
+ unsigned long long val_1; /* Première valeur à traiter */
+ unsigned long long val_2; /* Second valeur à traiter */
+ bool valid; /* Validité de ce bilan obtenu */
+ unsigned long long reduced; /* Valeur réduite finale */
+
+ result = NULL;
+
+ /* Réduction des éléments considérés */
+
+ new = g_scan_expression_reduce(expr->first, ctx, final);
+
+ if (new != NULL)
+ {
+ g_object_unref(G_OBJECT(expr->first));
+ expr->first = new;
+ }
+
+ if (expr->second != NULL)
+ {
+ new = g_scan_expression_reduce(expr->second, ctx, final);
+
+ if (new != NULL)
+ {
+ g_object_unref(G_OBJECT(expr->second));
+ expr->second = new;
+ }
+
+ }
+
+ /* Construction d'une réduction locale ? */
+
+ if (G_IS_LITERAL_EXPRESSION(expr->first) && G_IS_LITERAL_EXPRESSION(expr->second))
+ {
+ valid = g_literal_expression_get_integer_value(G_LITERAL_EXPRESSION(expr->first), &val_1);
+
+ if (valid)
+ valid = g_literal_expression_get_integer_value(G_LITERAL_EXPRESSION(expr->second), &val_2);
+
+ if (valid)
+ switch (expr->operator)
+ {
+ case AEO_PLUS:
+ reduced = val_1 + val_2;
+ break;
+
+ case AEO_MINUS:
+ reduced = val_1 - val_2;
+ break;
+
+ case AEO_MUL:
+ reduced = val_1 * val_2;
+ break;
+
+ case AEO_DIV:
+ valid = (val_2 != 0);
+ if (valid)
+ reduced = val_1 / val_2;
+ break;
+
+ case AEO_MOD:
+ valid = (val_2 != 0);
+ if (valid)
+ reduced = val_1 % val_2;
+ break;
+
+ }
+
+ if (valid)
+ result = g_literal_expression_new(EVT_INTEGER, &reduced);
+
+ }
+
+ return result;
+
+}
diff --git a/src/analysis/scan/exprs/arithmop.h b/src/analysis/scan/exprs/arithmop.h
new file mode 100644
index 0000000..dcc8bf8
--- /dev/null
+++ b/src/analysis/scan/exprs/arithmop.h
@@ -0,0 +1,67 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * arithmop.h - prototypes pour la gestion des opérations arithmétiques
+ *
+ * Copyright (C) 2022 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_SCAN_EXPRS_ARITHMOP_H
+#define _ANALYSIS_SCAN_EXPRS_ARITHMOP_H
+
+
+#include "../expr.h"
+
+
+
+#define G_TYPE_ARITHMETIC_OPERATION g_arithmetic_operation_get_type()
+#define G_ARITHMETIC_OPERATION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARITHMETIC_OPERATION, GArithmOperation))
+#define G_IS_ARITHMETIC_OPERATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARITHMETIC_OPERATION))
+#define G_ARITHMETIC_OPERATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARITHMETIC_OPERATION, GArithmOperationClass))
+#define G_IS_ARITHMETIC_OPERATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARITHMETIC_OPERATION))
+#define G_ARITHMETIC_OPERATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARITHMETIC_OPERATION, GArithmOperationClass))
+
+
+/* Opération arithmétique impliquant deux opérandes (instance) */
+typedef struct _GArithmOperation GArithmOperation;
+
+/* Opération arithmétique impliquant deux opérandes (classe) */
+typedef struct _GArithmOperationClass GArithmOperationClass;
+
+
+/* Type d'opération arithmétique */
+typedef enum _ArithmeticExpressionOperator
+{
+ AEO_PLUS, /* Opération binaire "+" */
+ AEO_MINUS, /* Opération binaire "-" */
+ AEO_MUL, /* Opération binaire "*" */
+ AEO_DIV, /* Opération binaire "\" */
+ AEO_MOD, /* Opération binaire "%" */
+
+} ArithmeticExpressionOperator;
+
+
+/* Indique le type défini pour une opération arithmétique entre expressions. */
+GType g_arithmetic_operation_get_type(void);
+
+/* Organise une opération arithmétique entre expressions. */
+GScanExpression *g_arithmetic_operation_new(ArithmeticExpressionOperator, GScanExpression *, GScanExpression *);
+
+
+
+#endif /* _ANALYSIS_SCAN_EXPRS_ARITHMOP_H */
diff --git a/src/analysis/scan/exprs/boolop-int.h b/src/analysis/scan/exprs/boolop-int.h
new file mode 100644
index 0000000..c381cfe
--- /dev/null
+++ b/src/analysis/scan/exprs/boolop-int.h
@@ -0,0 +1,60 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * boolop-int.h - prototypes internes pour la gestion des opérations booléennes
+ *
+ * Copyright (C) 2022 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_SCAN_EXPRS_BOOLOP_INT_H
+#define _ANALYSIS_SCAN_EXPRS_BOOLOP_INT_H
+
+
+#include "boolop.h"
+
+
+#include "../expr-int.h"
+
+
+
+/* Opération booléenne avec un ou deux opérandes (instance) */
+struct _GBoolOperation
+{
+ GScanExpression parent; /* A laisser en premier */
+
+ BooleanOperationType type; /* Type d'opération menée */
+
+ GScanExpression *first; /* Expression impactée #1 */
+ GScanExpression *second; /* Expression impactée #2 */
+
+};
+
+/* Opération booléenne avec un ou deux opérandes (classe) */
+struct _GBoolOperationClass
+{
+ GScanExpressionClass parent; /* A laisser en premier */
+
+};
+
+
+/* Met en place une expression d'opération booléenne. */
+bool g_boolean_operation_create(GBoolOperation *, BooleanOperationType, GScanExpression *, GScanExpression *);
+
+
+
+#endif /* _ANALYSIS_SCAN_EXPRS_BOOLOP_INT_H */
diff --git a/src/analysis/scan/exprs/boolop.c b/src/analysis/scan/exprs/boolop.c
new file mode 100644
index 0000000..2902fdd
--- /dev/null
+++ b/src/analysis/scan/exprs/boolop.c
@@ -0,0 +1,450 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * boolop.c - gestion des opérations booléennes
+ *
+ * Copyright (C) 2022 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "boolop.h"
+
+
+#include <assert.h>
+
+
+#include "boolop-int.h"
+#include "literal.h"
+
+
+
+/* --------------------- INTRODUCTION D'UNE NOUVELLE EXPRESSION --------------------- */
+
+
+/* Initialise la classe des opérations booléennes. */
+static void g_boolean_operation_class_init(GBoolOperationClass *);
+
+/* Initialise une instance d'opération booléenne. */
+static void g_boolean_operation_init(GBoolOperation *);
+
+/* Supprime toutes les références externes. */
+static void g_boolean_operation_dispose(GBoolOperation *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_boolean_operation_finalize(GBoolOperation *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Réalise une comparaison entre objets selon un critère précis. */
+static bool g_boolean_operation_compare_rich(const GBoolOperation *, const GBoolOperation *, RichCmpOperation, bool *);
+
+/* Reproduit une expression en place dans une nouvelle instance. */
+static GScanExpression *g_boolean_operation_duplicate(const GBoolOperation *);
+
+/* Réduit une expression à une forme plus simple. */
+GScanExpression *g_boolean_operation_reduce(GBoolOperation *, GScanContext *, bool);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* INTRODUCTION D'UNE NOUVELLE EXPRESSION */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une opération booléenne sur expression(s). */
+G_DEFINE_TYPE(GBoolOperation, g_boolean_operation, G_TYPE_SCAN_EXPRESSION);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des opérations booléennes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_boolean_operation_class_init(GBoolOperationClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GScanExpressionClass *expr; /* Version de classe parente */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_boolean_operation_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_boolean_operation_finalize;
+
+ expr = G_SCAN_EXPRESSION_CLASS(klass);
+
+ expr->cmp_rich = (compare_expr_rich_fc)g_boolean_operation_compare_rich;
+ expr->dup = (dup_expr_fc)g_boolean_operation_duplicate;
+ expr->reduce = (reduce_expr_fc)g_boolean_operation_reduce;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : op = instance à initialiser. *
+* *
+* Description : Initialise une instance d'opération booléenne. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_boolean_operation_init(GBoolOperation *op)
+{
+ op->first = NULL;
+ op->second = NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : op = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_boolean_operation_dispose(GBoolOperation *op)
+{
+ g_clear_object(&op->first);
+ g_clear_object(&op->second);
+
+ G_OBJECT_CLASS(g_boolean_operation_parent_class)->dispose(G_OBJECT(op));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : op = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_boolean_operation_finalize(GBoolOperation *op)
+{
+ G_OBJECT_CLASS(g_boolean_operation_parent_class)->finalize(G_OBJECT(op));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type d'opération booléenne à représenter. *
+* first = premier opérande concerné. *
+* second = éventuel second opérande impliqué ou NULL. *
+* *
+* Description : Organise un appel de fonction avec ses arguments. *
+* *
+* Retour : Fonction mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GScanExpression *g_boolean_operation_new(BooleanOperationType type, GScanExpression *first, GScanExpression *second)
+{
+ GScanExpression *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_BOOLEAN_OPERATION, NULL);
+
+ if (!g_boolean_operation_create(G_BOOLEAN_OPERATION(result), type, first, second))
+ g_clear_object(&result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = instance à initialiser pleinement. *
+* type = type d'opération booléenne à représenter. *
+* first = premier opérande concerné. *
+* second = éventuel second opérande impliqué ou NULL. *
+* *
+* Description : Met en place une expression d'opération booléenne. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_boolean_operation_create(GBoolOperation *op, BooleanOperationType type, GScanExpression *first, GScanExpression *second)
+{
+ bool result; /* Bilan à retourner */
+
+ result = false;
+
+ if (g_scan_expression_get_value_type(first) != EVT_BOOLEAN)
+ goto exit;
+
+ if (g_scan_expression_get_value_type(second) != EVT_BOOLEAN)
+ goto exit;
+
+ if (!g_scan_expression_create(G_SCAN_EXPRESSION(op), EVT_BOOLEAN))
+ goto exit;
+
+ op->type = type;
+
+ switch (type)
+ {
+ case BOT_AND:
+ case BOT_OR:
+ op->first = first;
+ g_object_ref(G_OBJECT(op->first));
+
+ op->second = second;
+ g_object_ref(G_OBJECT(op->second));
+
+ result = true;
+ break;
+
+ case BOT_NOT:
+ op->first = first;
+ g_object_ref(G_OBJECT(op->first));
+
+ result = (second == NULL);
+ assert(second != NULL);
+ break;
+
+ }
+
+ exit:
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : item = premier objet à consulter pour une comparaison. *
+* other = second objet à consulter pour une comparaison. *
+* op = opération de comparaison à réaliser. *
+* status = bilan des opérations de comparaison. [OUT] *
+* *
+* Description : Réalise une comparaison entre objets selon un critère précis.*
+* *
+* Retour : true si la comparaison a pu être effectuée, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_boolean_operation_compare_rich(const GBoolOperation *item, const GBoolOperation *other, RichCmpOperation op, bool *status)
+{
+ bool result; /* Etat à retourner */
+ bool equal; /* Bilan intermédiaire */
+
+ result = true;
+
+ if (item->type != other->type)
+ {
+ *status = compare_rich_integer_values(item->type, other->type, op);
+ goto done;
+ }
+
+ equal = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item), G_COMPARABLE_ITEM(other), RCO_EQ, status);
+
+ if (!equal)
+ {
+ *status = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->first),
+ G_COMPARABLE_ITEM(other->first),
+ op, status);
+ goto done;
+ }
+
+ if (item->second == NULL)
+ {
+ assert(other->second == NULL);
+
+ switch (op)
+ {
+ case RCO_LT:
+ case RCO_NE:
+ case RCO_GT:
+ *status = false;
+ break;
+
+ case RCO_LE:
+ case RCO_EQ:
+ case RCO_GE:
+ *status = true;
+ break;
+
+ }
+
+ }
+
+ else
+ *status = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->second),
+ G_COMPARABLE_ITEM(other->second),
+ op, status);
+
+ done:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = expression à copier. *
+* *
+* Description : Reproduit une expression en place dans une nouvelle instance.*
+* *
+* Retour : Nouvelle instance d'expression. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GScanExpression *g_boolean_operation_duplicate(const GBoolOperation *expr)
+{
+ GScanExpression *result; /* Instance copiée à retourner */
+
+ result = g_boolean_operation_new(expr->type, expr->first, expr->second);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = expression à consulter. *
+* ctx = contexte de suivi de l'analyse courante. *
+* final = impose une conversion finale de dernier tour. *
+* *
+* Description : Réduit une expression à une forme plus simple. *
+* *
+* Retour : Réduction correspondante, expression déjà réduite, ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GScanExpression *g_boolean_operation_reduce(GBoolOperation *expr, GScanContext *ctx, bool final)
+{
+ GScanExpression *result; /* Instance à renvoyer */
+ GScanExpression *new; /* Nouvelle expression obtenue */
+ bool values[2]; /* Valeurs des éléments portés */
+ bool valid[2]; /* Validité de ces valeurs */
+
+ result = NULL;
+
+ /* Réduction des éléments considérés */
+
+ new = g_scan_expression_reduce(expr->first, ctx, final);
+
+ if (new != NULL)
+ {
+ g_object_unref(G_OBJECT(expr->first));
+ expr->first = new;
+ }
+
+ if (expr->second != NULL)
+ {
+ new = g_scan_expression_reduce(expr->second, ctx, final);
+
+ if (new != NULL)
+ {
+ g_object_unref(G_OBJECT(expr->second));
+ expr->second = new;
+ }
+
+ }
+
+ /* Construction d'une réduction locale ? */
+
+ switch (expr->type)
+ {
+ case BOT_AND:
+ if (G_IS_LITERAL_EXPRESSION(expr->first) && G_IS_LITERAL_EXPRESSION(expr->second))
+ {
+ valid[0] = g_literal_expression_get_boolean_value(G_LITERAL_EXPRESSION(expr->first), &values[0]);
+ valid[1] = g_literal_expression_get_boolean_value(G_LITERAL_EXPRESSION(expr->second), &values[1]);
+
+ if (valid[0] && valid[1])
+ result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { values[0] && values[1] });
+
+ else
+ /* Etre malin si 0 && x => bilan (si ctx->quick) */
+ ;
+
+ }
+ break;
+
+ case BOT_OR:
+ if (G_IS_LITERAL_EXPRESSION(expr->first) && G_IS_LITERAL_EXPRESSION(expr->second))
+ {
+ valid[0] = g_literal_expression_get_boolean_value(G_LITERAL_EXPRESSION(expr->first), &values[0]);
+ valid[1] = g_literal_expression_get_boolean_value(G_LITERAL_EXPRESSION(expr->second), &values[1]);
+
+ if (valid[0] && valid[1])
+ result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { values[0] || values[1] });
+
+ }
+ break;
+
+ case BOT_NOT:
+ if (G_IS_LITERAL_EXPRESSION(expr->first))
+ {
+ valid[0] = g_literal_expression_get_boolean_value(G_LITERAL_EXPRESSION(expr->first), &values[0]);
+
+ if (valid[0])
+ result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { !values[1] });
+
+ }
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/src/analysis/scan/exprs/boolop.h b/src/analysis/scan/exprs/boolop.h
new file mode 100644
index 0000000..4add5a1
--- /dev/null
+++ b/src/analysis/scan/exprs/boolop.h
@@ -0,0 +1,65 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * boolop.h - prototypes pour la gestion des opérations booléennes
+ *
+ * Copyright (C) 2022 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_SCAN_EXPRS_BOOLOP_H
+#define _ANALYSIS_SCAN_EXPRS_BOOLOP_H
+
+
+#include "../expr.h"
+
+
+
+#define G_TYPE_BOOLEAN_OPERATION g_boolean_operation_get_type()
+#define G_BOOLEAN_OPERATION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_BOOLEAN_OPERATION, GBoolOperation))
+#define G_IS_BOOLEAN_OPERATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_BOOLEAN_OPERATION))
+#define G_BOOLEAN_OPERATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BOOLEAN_OPERATION, GBoolOperationClass))
+#define G_IS_BOOLEAN_OPERATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BOOLEAN_OPERATION))
+#define G_BOOLEAN_OPERATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BOOLEAN_OPERATION, GBoolOperationClass))
+
+
+/* Opération booléenne avec un ou deux opérandes (instance) */
+typedef struct _GBoolOperation GBoolOperation;
+
+/* Opération booléenne avec un ou deux opérandes (classe) */
+typedef struct _GBoolOperationClass GBoolOperationClass;
+
+
+/* Types d'opérations booléennes supportées */
+typedef enum _BooleanOperationType
+{
+ BOT_AND, /* Opérateur binaire "and" */
+ BOT_OR, /* Opérateur binaire "or" */
+ BOT_NOT, /* Opérateur unaire "not" */
+
+} BooleanOperationType;
+
+
+/* Indique le type défini pour une opération booléenne sur expression(s). */
+GType g_boolean_operation_get_type(void);
+
+/* Organise un appel de fonction avec ses arguments. */
+GScanExpression *g_boolean_operation_new(BooleanOperationType, GScanExpression *, GScanExpression *);
+
+
+
+#endif /* _ANALYSIS_SCAN_EXPRS_BOOLOP_H */
diff --git a/src/analysis/scan/exprs/call-int.h b/src/analysis/scan/exprs/call-int.h
new file mode 100644
index 0000000..d68977f
--- /dev/null
+++ b/src/analysis/scan/exprs/call-int.h
@@ -0,0 +1,63 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * call-int.h - prototypes internes pour l'organisation d'un appel à un élément de scan enregistré
+ *
+ * Copyright (C) 2022 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_SCAN_EXPRS_CALL_INT_H
+#define _ANALYSIS_SCAN_EXPRS_CALL_INT_H
+
+
+#include "call.h"
+
+
+#include "../expr-int.h"
+
+
+
+/* Exécution d'une fonction auxiliaire d'analyse (instance) */
+struct _GPendingCall
+{
+ GScanExpression parent; /* A laisser en premier */
+
+ GRegisteredItem *base; /* Base de recherche */
+ char *target; /* Cible dans l'espace */
+
+ GScanExpression **args; /* Arguments d'appel fournis */
+ size_t count; /* Quantité de ces arguments */
+
+ struct _GPendingCall *next; /* Evnetuel prochain élément */
+
+};
+
+/* Exécution d'une fonction auxiliaire d'analyse (classe) */
+struct _GPendingCallClass
+{
+ GScanExpressionClass parent; /* A laisser en premier */
+
+};
+
+
+/* Met en place une expression d'appel. */
+bool g_pending_call_create(GPendingCall *, const char *, size_t, GScanExpression **, size_t);
+
+
+
+#endif /* _ANALYSIS_SCAN_EXPRS_CALL_INT_H */
diff --git a/src/analysis/scan/exprs/call.c b/src/analysis/scan/exprs/call.c
new file mode 100644
index 0000000..76f5fc3
--- /dev/null
+++ b/src/analysis/scan/exprs/call.c
@@ -0,0 +1,426 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * call.c - organisation d'un appel à un élément de scan enregistré
+ *
+ * Copyright (C) 2022 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "call.h"
+
+
+#include <malloc.h>
+#include <string.h>
+
+
+#include "call-int.h"
+#include "../../../core/global.h"
+
+
+
+/* --------------------- INTRODUCTION D'UNE NOUVELLE EXPRESSION --------------------- */
+
+
+/* Initialise la classe des appels de fonction avec arguments. */
+static void g_pending_call_class_init(GPendingCallClass *);
+
+/* Initialise une instance d'appel de fonction avec arguments. */
+static void g_pending_call_init(GPendingCall *);
+
+/* Supprime toutes les références externes. */
+static void g_pending_call_dispose(GPendingCall *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_pending_call_finalize(GPendingCall *);
+
+/* Définit une base de recherche pour la cible d'appel. */
+static void g_pending_call_set_base(GPendingCall *, GRegisteredItem *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Reproduit une expression en place dans une nouvelle instance. */
+static GScanExpression *g_pending_call_duplicate(const GPendingCall *);
+
+/* Réduit une expression à une forme plus simple. */
+GScanExpression *g_pending_call_reduce(GPendingCall *, GScanContext *, bool);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* INTRODUCTION D'UNE NOUVELLE EXPRESSION */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un appel de fonction enregistrée. */
+G_DEFINE_TYPE(GPendingCall, g_pending_call, G_TYPE_SCAN_EXPRESSION);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des appels de fonction avec arguments. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_pending_call_class_init(GPendingCallClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GScanExpressionClass *expr; /* Version de classe parente */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_pending_call_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_pending_call_finalize;
+
+ expr = G_SCAN_EXPRESSION_CLASS(klass);
+
+ expr->cmp_rich = (compare_expr_rich_fc)NULL;
+ expr->dup = (dup_expr_fc)g_pending_call_duplicate;
+ expr->reduce = (reduce_expr_fc)g_pending_call_reduce;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : call = instance à initialiser. *
+* *
+* Description : Initialise une instance d'appel de fonction avec arguments. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_pending_call_init(GPendingCall *call)
+{
+ call->base = NULL;
+ call->target = NULL;
+
+ call->args = NULL;
+ call->count = 0;
+
+ call->next = NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : call = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_pending_call_dispose(GPendingCall *call)
+{
+ size_t i; /* Boucle de parcours */
+
+ g_clear_object(&call->base);
+
+ for (i = 0; i < call->count; i++)
+ g_clear_object(&call->args[i]);
+
+ g_clear_object(&call->next);
+
+ G_OBJECT_CLASS(g_pending_call_parent_class)->dispose(G_OBJECT(call));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : call = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_pending_call_finalize(GPendingCall *call)
+{
+ if (call->target != NULL)
+ free(call->target);
+
+ if (call->args != NULL)
+ free(call->args);
+
+ G_OBJECT_CLASS(g_pending_call_parent_class)->finalize(G_OBJECT(call));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : target = désignation de l'objet d'appel à identifier. *
+* len = taille de cette désignation. *
+* args = éventuelle liste d'arguments à actionner. *
+* count = quantité de ces arguments. *
+* *
+* Description : Organise un appel de fonction avec ses arguments. *
+* *
+* Retour : Fonction mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GScanExpression *g_pending_call_new(const char *target, size_t len, GScanExpression **args, size_t count)
+{
+ GScanExpression *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_PENDING_CALL, NULL);
+
+ if (!g_pending_call_create(G_PENDING_CALL(result), target, len, args, count))
+ g_clear_object(&result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : call = instance à initialiser pleinement. *
+* target = désignation de l'objet d'appel à identifier. *
+* len = taille de cette désignation. *
+* args = éventuelle liste d'arguments à actionner. *
+* count = quantité de ces arguments. *
+* *
+* Description : Met en place une expression d'appel. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_pending_call_create(GPendingCall *call, const char *target, size_t len, GScanExpression **args, size_t count)
+{
+ bool result; /* Bilan à retourner */
+ size_t i; /* Boucle de parcours */
+
+ result = g_scan_expression_create(G_SCAN_EXPRESSION(call), EVT_PENDING);
+ if (!result) goto exit;
+
+ call->target = strndup(target, len);
+
+ call->args = malloc(count * sizeof(GScanExpression *));
+ call->count = count;
+
+ for (i = 0; i < count; i++)
+ {
+ call->args[i] = args[i];
+ g_object_ref(G_OBJECT(args[i]));
+ }
+
+ exit:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : call = expression d'appel à actualiser. *
+* base = zone de recherche pour la résolution à venir. *
+* *
+* Description : Définit une base de recherche pour la cible d'appel. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_pending_call_set_base(GPendingCall *call, GRegisteredItem *base)
+{
+ call->base = base;
+ g_object_ref(G_OBJECT(base));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : call = expression d'appel à compléter. *
+* next = expression d'appel suivante dans la chaîne. *
+* *
+* Description : Complète la chaine d'expressions d'appel. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_pending_call_attach_next(GPendingCall *call, GPendingCall *next)
+{
+ call->next = next;
+ g_object_ref(G_OBJECT(next));
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = expression à copier. *
+* *
+* Description : Reproduit une expression en place dans une nouvelle instance.*
+* *
+* Retour : Nouvelle instance d'expression. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GScanExpression *g_pending_call_duplicate(const GPendingCall *expr)
+{
+ GScanExpression *result; /* Instance copiée à retourner */
+
+ result = g_pending_call_new(expr->target, strlen(expr->target), expr->args, expr->count);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = expression à consulter. *
+* ctx = contexte de suivi de l'analyse courante. *
+* final = indique une ultime conversion dans le cycle en cours.*
+* *
+* Description : Réduit une expression à une forme plus simple. *
+* *
+* Retour : Réduction correspondante, expression déjà réduite, ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GScanExpression *g_pending_call_reduce(GPendingCall *expr, GScanContext *ctx, bool final)
+{
+ GScanExpression *result; /* Instance à renvoyer */
+ size_t i; /* Boucle de parcours */
+ GScanExpression *new; /* Nouvelle expression obtenue */
+ bool last; /* Détection de fin de chaîne */
+ GRegisteredItem *base; /* Base de recherche courante */
+ GRegisteredItem *rebase; /* Nouvelle base résolue */
+ GScanExpression *new_next; /* Nouvelle version du suivant */
+
+ for (i = 0; i < expr->count; i++)
+ {
+ new = g_scan_expression_reduce(expr->args[i], ctx, final);
+
+ if (new != NULL)
+ {
+ g_object_unref(G_OBJECT(expr->args[i]));
+ expr->args[i] = new;
+ }
+
+ }
+
+ last = (expr->next == NULL);
+
+ if (!last)
+ new_next = g_scan_expression_duplicate(G_SCAN_EXPRESSION(expr->next));
+ else
+ new_next = NULL;
+
+ if (expr->target != NULL)
+ {
+ if (expr->base != NULL)
+ {
+ base = expr->base;
+ g_object_ref(G_OBJECT(base));
+ }
+ else
+ base = G_REGISTERED_ITEM(get_rost_root_namespace());
+
+ rebase = g_registered_item_resolve(base, expr->target, ctx,
+ last ? NULL : expr->args, last ? 0 : expr->count,
+ last, final);
+
+ g_object_unref(G_OBJECT(base));
+
+ if (rebase == NULL)
+ {
+ result = NULL;
+ goto done;
+ }
+
+ if (last)
+ {
+ g_pending_call_set_base(expr, rebase);
+
+ free(expr->target);
+ expr->target = NULL;
+
+ }
+ else
+ g_pending_call_set_base(G_PENDING_CALL(new_next), rebase);
+
+ }
+
+ if (last)
+ result = g_registered_item_reduce(expr->base, ctx, expr->args, expr->count, final);
+
+ else
+ {
+ result = g_scan_expression_reduce(new_next, ctx, final);
+
+ if (result == NULL)
+ {
+ g_object_ref(G_OBJECT(new_next));
+ result = new_next;
+ }
+
+ }
+
+ done:
+
+ g_clear_object(&new_next);
+
+ return result;
+
+}
diff --git a/src/analysis/scan/exprs/call.h b/src/analysis/scan/exprs/call.h
new file mode 100644
index 0000000..b69ca85
--- /dev/null
+++ b/src/analysis/scan/exprs/call.h
@@ -0,0 +1,59 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * call.h - prototypes pour l'organisation d'un appel à un élément de scan enregistré
+ *
+ * Copyright (C) 2022 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_SCAN_EXPRS_CALL_H
+#define _ANALYSIS_SCAN_EXPRS_CALL_H
+
+
+#include "../expr.h"
+#include "../item.h"
+
+
+
+#define G_TYPE_PENDING_CALL g_pending_call_get_type()
+#define G_PENDING_CALL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_PENDING_CALL, GPendingCall))
+#define G_IS_PENDING_CALL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_PENDING_CALL))
+#define G_PENDING_CALL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_PENDING_CALL, GPendingCallClass))
+#define G_IS_PENDING_CALL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_PENDING_CALL))
+#define G_PENDING_CALL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_PENDING_CALL, GPendingCallClass))
+
+
+/* Exécution d'une fonction auxiliaire d'analyse (instance) */
+typedef struct _GPendingCall GPendingCall;
+
+/* Exécution d'une fonction auxiliaire d'analyse (classe) */
+typedef struct _GPendingCallClass GPendingCallClass;
+
+
+/* Indique le type défini pour un appel de fonction enregistrée. */
+GType g_pending_call_get_type(void);
+
+/* Organise un appel de fonction avec ses arguments. */
+GScanExpression *g_pending_call_new(const char *, size_t, GScanExpression **, size_t);
+
+/* Complète la chaine d'expressions d'appel. */
+void g_pending_call_attach_next(GPendingCall *, GPendingCall *);
+
+
+
+#endif /* _ANALYSIS_SCAN_EXPRS_CALL_H */
diff --git a/src/analysis/scan/exprs/literal-int.h b/src/analysis/scan/exprs/literal-int.h
new file mode 100644
index 0000000..d803d30
--- /dev/null
+++ b/src/analysis/scan/exprs/literal-int.h
@@ -0,0 +1,73 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * literal-int.h - prototypes internes pour la représentation d'une valeur concrète
+ *
+ * Copyright (C) 2022 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_SCAN_EXPRS_LITERAL_INT_H
+#define _ANALYSIS_SCAN_EXPRS_LITERAL_INT_H
+
+
+#include "literal.h"
+
+
+#include <stdbool.h>
+
+
+#include "../expr-int.h"
+
+
+
+/* Expression portant une valeur concrète (instance) */
+struct _GLiteralExpression
+{
+ GScanExpression parent; /* A laisser en premier */
+
+ ExprValueType value_type; /* Type de valeur portée */
+
+ union
+ {
+ bool boolean; /* Valeur booléenne */
+ unsigned long long integer; /* Valeur entière 64 bits */
+ char *string; /* Chaîne de caractères */
+ struct
+ {
+ char *regex; /* Formulation d'origine */
+ regex_t preg; /* Expression rationnelle */
+ };
+
+ } value;
+
+};
+
+/* Expression portant une valeur concrète (classe) */
+struct _GLiteralExpressionClass
+{
+ GScanExpressionClass parent; /* A laisser en premier */
+
+};
+
+
+/* Met en place une expression de valeur concrête. */
+bool g_literal_expression_create(GLiteralExpression *, ExprValueType, ...);
+
+
+
+#endif /* _ANALYSIS_SCAN_EXPRS_LITERAL_INT_H */
diff --git a/src/analysis/scan/exprs/literal.c b/src/analysis/scan/exprs/literal.c
new file mode 100644
index 0000000..f40747d
--- /dev/null
+++ b/src/analysis/scan/exprs/literal.c
@@ -0,0 +1,605 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * literal.c - représentation d'une valeur concrète
+ *
+ * Copyright (C) 2022 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "literal.h"
+
+
+#include <assert.h>
+#include <stdarg.h>
+#include <string.h>
+
+
+#include "literal-int.h"
+
+
+
+/* --------------------- INTRODUCTION D'UNE NOUVELLE EXPRESSION --------------------- */
+
+
+/* Initialise la classe des expressions de valeur concrète. */
+static void g_literal_expression_class_init(GLiteralExpressionClass *);
+
+/* Initialise une instance d'expression de valeur concrète. */
+static void g_literal_expression_init(GLiteralExpression *);
+
+/* Supprime toutes les références externes. */
+static void g_literal_expression_dispose(GLiteralExpression *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_literal_expression_finalize(GLiteralExpression *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Réalise une comparaison entre objets selon un critère précis. */
+static bool g_literal_expression_compare_rich(const GLiteralExpression *, const GLiteralExpression *, RichCmpOperation, bool *);
+
+/* Reproduit une expression en place dans une nouvelle instance. */
+static GScanExpression *g_literal_expression_duplicate(const GLiteralExpression *);
+
+/* Réduit une expression à une forme plus simple. */
+GScanExpression *g_literal_expression_reduce(GLiteralExpression *, GScanContext *, bool);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* INTRODUCTION D'UNE NOUVELLE EXPRESSION */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un appel de fonction enregistrée. */
+G_DEFINE_TYPE(GLiteralExpression, g_literal_expression, G_TYPE_SCAN_EXPRESSION);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des expressions de valeur concrète. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_literal_expression_class_init(GLiteralExpressionClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GScanExpressionClass *expr; /* Version de classe parente */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_literal_expression_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_literal_expression_finalize;
+
+ expr = G_SCAN_EXPRESSION_CLASS(klass);
+
+ expr->cmp_rich = (compare_expr_rich_fc)g_literal_expression_compare_rich;
+ expr->dup = (dup_expr_fc)g_literal_expression_duplicate;
+ expr->reduce = (reduce_expr_fc)g_literal_expression_reduce;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = instance à initialiser. *
+* *
+* Description : Initialise une instance d'expression de valeur concrète. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_literal_expression_init(GLiteralExpression *expr)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_literal_expression_dispose(GLiteralExpression *expr)
+{
+ G_OBJECT_CLASS(g_literal_expression_parent_class)->dispose(G_OBJECT(expr));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_literal_expression_finalize(GLiteralExpression *expr)
+{
+ G_OBJECT_CLASS(g_literal_expression_parent_class)->finalize(G_OBJECT(expr));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : vtype = type de valeur associée par l'expression. *
+* ... = valeur concrête à intégrer. *
+* *
+* Description : Organise un appel de fonction avec ses arguments. *
+* *
+* Retour : Fonction mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GScanExpression *g_literal_expression_new(ExprValueType vtype, ...)
+{
+ GScanExpression *result; /* Structure à retourner */
+ va_list ap; /* Liste d'arguements */
+ void *ptr; /* Vision générique de valeur */
+
+ result = g_object_new(G_TYPE_LITERAL_EXPRESSION, NULL);
+
+ va_start(ap, vtype);
+
+ ptr = va_arg(ap, void *);
+
+ if (!g_literal_expression_create(G_LITERAL_EXPRESSION(result), vtype, ptr))
+ g_clear_object(&result);
+
+ va_end(ap);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = instance à initialiser pleinement. *
+* vtype = type de valeur associée par l'expression. *
+* ... = valeur concrête à intégrer. *
+* *
+* Description : Met en place une expression de valeur concrête. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_literal_expression_create(GLiteralExpression *expr, ExprValueType vtype, ...)
+{
+ bool result; /* Bilan à retourner */
+ va_list ap; /* Liste d'arguements */
+ const bool *boolean; /* Valeur booléenne */
+ const unsigned long long *integer; /* Valeur entière 64 bits */
+ const char *string; /* Chaîne de caractères */
+ size_t len; /* Taille de la chaîne */
+ int cflags; /* Détails de compilation */
+ unsigned int i; /* Boucle de parcours */
+ char *tmp; /* Zone de travail temporaire */
+ int ret; /* Bilan d'une opération */
+
+ result = g_scan_expression_create(G_SCAN_EXPRESSION(expr), vtype);
+
+ if (result)
+ {
+ va_start(ap, vtype);
+
+ switch (vtype)
+ {
+ case EVT_BOOLEAN:
+ boolean = va_arg(ap, const bool *);
+ expr->value.boolean = *boolean;
+ break;
+
+ case EVT_INTEGER:
+ integer = va_arg(ap, const unsigned long long *);
+ expr->value.integer = *integer;
+ break;
+
+ case EVT_STRING:
+ string = va_arg(ap, const char *);
+ expr->value.string = strdup(string);
+ break;
+
+ case EVT_REG_EXPR:
+ string = va_arg(ap, const char *);
+ len = strlen(string);
+
+ result = (len > 2 && string[0] == '/');
+
+ cflags = REG_EXTENDED | REG_NOSUB;
+
+ for (i = 0; i < 2 && result; i++)
+ {
+ result = (len > 2);
+
+ if (string[len - 1] == 'i')
+ {
+ cflags |= REG_ICASE;
+ len -= 1;
+ }
+
+ else if (string[len - 1] == 's')
+ {
+ cflags |= REG_NEWLINE;
+ len -= 1;
+ }
+
+ else if (string[len - 1] == '/')
+ break;
+
+ }
+
+ if (result)
+ result = (string[len - 1] == '/');
+
+ if (result)
+ {
+ assert(len > 2);
+
+ tmp = strndup(&string[1], len - 2);
+ ret = regcomp(&expr->value.preg, tmp, cflags);
+ free(tmp);
+
+ result = (ret == 0);
+
+ if (result)
+ expr->value.regex = strdup(string);
+
+ }
+
+ break;
+
+ default:
+ result = false;
+ break;
+
+ }
+
+ va_end(ap);
+
+ }
+
+ expr->value_type = vtype;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = premier objet à consulter pour une comparaison. *
+* value = valeur portée portée par l'expression. [OUT] *
+* *
+* Description : Indique la valeur portée par une expression booléenne. *
+* *
+* Retour : true si l'expression est de type booléen, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_literal_expression_get_boolean_value(const GLiteralExpression *item, bool *value)
+{
+ bool result; /* Etat à retourner */
+
+ result = (item->value_type == EVT_BOOLEAN);
+
+ if (result)
+ *value = item->value.boolean;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = premier objet à consulter pour une comparaison. *
+* value = valeur portée portée par l'expression. [OUT] *
+* *
+* Description : Indique la valeur portée par une expression d'entier. *
+* *
+* Retour : true si l'expression est de type entier, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_literal_expression_get_integer_value(const GLiteralExpression *item, unsigned long long *value)
+{
+ bool result; /* Etat à retourner */
+
+ result = (item->value_type == EVT_INTEGER);
+
+ if (result)
+ *value = item->value.integer;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = premier objet à consulter pour une comparaison. *
+* value = valeur portée portée par l'expression. [OUT] *
+* *
+* Description : Indique la valeur portée par une expression de chaîne. *
+* *
+* Retour : true si l'expression est de type entier, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_literal_expression_get_string_value(const GLiteralExpression *item, const char **value)
+{
+ bool result; /* Etat à retourner */
+
+ result = (item->value_type == EVT_STRING);
+
+ if (result)
+ *value = item->value.string;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = premier objet à consulter pour une comparaison. *
+* value = valeur portée portée par l'expression. [OUT] *
+* *
+* Description : Indique la valeur portée par une expression rationnelle. *
+* *
+* Retour : true si l'expression est de type entier, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_literal_expression_get_regex_value(const GLiteralExpression *item, const regex_t **value)
+{
+ bool result; /* Etat à retourner */
+
+ result = (item->value_type == EVT_REG_EXPR);
+
+ if (result)
+ *value = &item->value.preg;
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : item = premier objet à consulter pour une comparaison. *
+* other = second objet à consulter pour une comparaison. *
+* op = opération de comparaison à réaliser. *
+* status = bilan des opérations de comparaison. [OUT] *
+* *
+* Description : Réalise une comparaison entre objets selon un critère précis.*
+* *
+* Retour : true si la comparaison a pu être effectuée, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_literal_expression_compare_rich(const GLiteralExpression *item, const GLiteralExpression *other, RichCmpOperation op, bool *status)
+{
+ bool result; /* Etat à retourner */
+ int cmp; /* Bilan intermédiaire */
+
+ if (item->value_type != other->value_type)
+ {
+ *status = compare_rich_integer_values(item->value_type, other->value_type, op);
+ result = true;
+ goto done;
+ }
+
+ switch (item->value_type)
+ {
+ case EVT_BOOLEAN:
+ switch (op)
+ {
+ case RCO_EQ:
+ *status = (item->value.boolean == other->value.boolean);
+ result = true;
+ break;
+
+ case RCO_NE:
+ *status = (item->value.boolean != other->value.boolean);
+ result = true;
+ break;
+
+ default:
+ result = false;
+ break;
+
+ };
+ break;
+
+ case EVT_INTEGER:
+ *status = compare_rich_integer_values(item->value.integer, other->value.integer, op);
+ result = true;
+ break;
+
+ case EVT_STRING:
+ cmp = strcmp(item->value.string, other->value.string);
+ *status = compare_rich_integer_values(cmp, 0, op);
+ result = true;
+ break;
+
+ case EVT_REG_EXPR:
+ cmp = strcmp(item->value.regex, other->value.regex);
+ *status = compare_rich_integer_values(cmp, 0, op);
+ result = true;
+ break;
+
+ default:
+ result = false;
+ break;
+
+ }
+
+ done:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = expression à copier. *
+* *
+* Description : Reproduit une expression en place dans une nouvelle instance.*
+* *
+* Retour : Nouvelle instance d'expression. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GScanExpression *g_literal_expression_duplicate(const GLiteralExpression *expr)
+{
+ GScanExpression *result; /* Instance copiée à retourner */
+ const void *ptr; /* Pointeur vers des données */
+
+ switch (expr->value_type)
+ {
+ case EVT_BOOLEAN:
+ ptr = &expr->value.boolean;
+ break;
+
+ case EVT_INTEGER:
+ ptr = &expr->value.integer;
+ break;
+
+ case EVT_STRING:
+ ptr = &expr->value.string;
+ break;
+
+ case EVT_REG_EXPR:
+ ptr = &expr->value.regex;
+ break;
+
+ default:
+ ptr = NULL;
+ break;
+
+ }
+
+ assert(ptr != NULL);
+
+ result = g_literal_expression_new(expr->value_type, ptr);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = expression à consulter. *
+* ctx = contexte de suivi de l'analyse courante. *
+* force = impose une conversion en booléen si possible. *
+* *
+* Description : Réduit une expression à une forme plus simple. *
+* *
+* Retour : Réduction correspondante, expression déjà réduite, ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GScanExpression *g_literal_expression_reduce(GLiteralExpression *expr, GScanContext *ctx, bool force)
+{
+ GScanExpression *result; /* Instance à renvoyer */
+
+ if (!force)
+ result = NULL;
+
+ else
+ switch (expr->value_type)
+ {
+ case EVT_BOOLEAN:
+ result = NULL;
+ break;
+
+ case EVT_INTEGER:
+ result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { expr->value.integer > 0 });
+ break;
+
+ case EVT_STRING:
+ result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { strlen(expr->value.string) > 0 });
+ break;
+
+ case EVT_REG_EXPR:
+ result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { strlen(expr->value.regex) > 0 });
+ break;
+
+ default:
+ result = NULL;
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/src/analysis/scan/exprs/literal.h b/src/analysis/scan/exprs/literal.h
new file mode 100644
index 0000000..ac5724f
--- /dev/null
+++ b/src/analysis/scan/exprs/literal.h
@@ -0,0 +1,70 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * literal.h - prototypes pour la représentation d'une valeur concrète
+ *
+ * Copyright (C) 2022 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_SCAN_EXPRS_LITERAL_H
+#define _ANALYSIS_SCAN_EXPRS_LITERAL_H
+
+
+#include <regex.h>
+
+
+#include "../expr.h"
+
+
+
+#define G_TYPE_LITERAL_EXPRESSION g_literal_expression_get_type()
+#define G_LITERAL_EXPRESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_LITERAL_EXPRESSION, GLiteralExpression))
+#define G_IS_LITERAL_EXPRESSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_LITERAL_EXPRESSION))
+#define G_LITERAL_EXPRESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_LITERAL_EXPRESSION, GLiteralExpressionClass))
+#define G_IS_LITERAL_EXPRESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_LITERAL_EXPRESSION))
+#define G_LITERAL_EXPRESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_LITERAL_EXPRESSION, GLiteralExpressionClass))
+
+
+/* Expression portant une valeur concrète (instance) */
+typedef struct _GLiteralExpression GLiteralExpression;
+
+/* Expression portant une valeur concrète (classe) */
+typedef struct _GLiteralExpressionClass GLiteralExpressionClass;
+
+
+/* Indique le type défini pour un appel de fonction enregistrée. */
+GType g_literal_expression_get_type(void);
+
+/* Organise un appel de fonction avec ses arguments. */
+GScanExpression *g_literal_expression_new(ExprValueType, ...);
+
+/* Indique la valeur portée par une expression booléenne. */
+bool g_literal_expression_get_boolean_value(const GLiteralExpression *, bool *);
+
+/* Indique la valeur portée par une expression d'entier. */
+bool g_literal_expression_get_integer_value(const GLiteralExpression *, unsigned long long *);
+
+/* Indique la valeur portée par une expression de chaîne. */
+bool g_literal_expression_get_string_value(const GLiteralExpression *, const char **);
+
+/* Indique la valeur portée par une expression rationnelle. */
+bool g_literal_expression_get_regex_value(const GLiteralExpression *, const regex_t **);
+
+
+
+#endif /* _ANALYSIS_SCAN_EXPRS_LITERAL_H */
diff --git a/src/analysis/scan/exprs/relop-int.h b/src/analysis/scan/exprs/relop-int.h
new file mode 100644
index 0000000..273b543
--- /dev/null
+++ b/src/analysis/scan/exprs/relop-int.h
@@ -0,0 +1,60 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * relop-int.h - prototypes internes pour la gestion des opérations relationnelles
+ *
+ * Copyright (C) 2022 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_SCAN_EXPRS_RELOP_INT_H
+#define _ANALYSIS_SCAN_EXPRS_RELOP_INT_H
+
+
+#include "relop.h"
+
+
+#include "../expr-int.h"
+
+
+
+/* Opération relationnelle impliquant deux opérandes (instance) */
+struct _GRelOperation
+{
+ GScanExpression parent; /* A laisser en premier */
+
+ RichCmpOperation rel_type; /* Type de relation étudiée */
+
+ GScanExpression *first; /* Expression impactée #1 */
+ GScanExpression *second; /* Expression impactée #2 */
+
+};
+
+/* Opération relationnelle impliquant deux opérandes (classe) */
+struct _GRelOperationClass
+{
+ GScanExpressionClass parent; /* A laisser en premier */
+
+};
+
+
+/* Met en place une opération relationnelle entre expressions. */
+bool g_relational_operation_create(GRelOperation *, RichCmpOperation, GScanExpression *, GScanExpression *);
+
+
+
+#endif /* _ANALYSIS_SCAN_EXPRS_RELOP_INT_H */
diff --git a/src/analysis/scan/exprs/relop.c b/src/analysis/scan/exprs/relop.c
new file mode 100644
index 0000000..94ce77d
--- /dev/null
+++ b/src/analysis/scan/exprs/relop.c
@@ -0,0 +1,374 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * relop.c - gestion des opérations relationnelles
+ *
+ * Copyright (C) 2022 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "relop.h"
+
+
+#include "relop-int.h"
+#include "literal.h"
+
+
+
+/* --------------------- INTRODUCTION D'UNE NOUVELLE EXPRESSION --------------------- */
+
+
+/* Initialise la classe des opérations de relations. */
+static void g_relational_operation_class_init(GRelOperationClass *);
+
+/* Initialise une instance d'opération de relation. */
+static void g_relational_operation_init(GRelOperation *);
+
+/* Supprime toutes les références externes. */
+static void g_relational_operation_dispose(GRelOperation *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_relational_operation_finalize(GRelOperation *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Réalise une comparaison entre objets selon un critère précis. */
+static bool g_relational_operation_compare_rich(const GRelOperation *, const GRelOperation *, RichCmpOperation, bool *);
+
+/* Initialise une instance d'opération de relation. */
+static GScanExpression *g_relational_operation_duplicate(const GRelOperation *);
+
+/* Réduit une expression à une forme plus simple. */
+GScanExpression *g_relational_operation_reduce(GRelOperation *, GScanContext *, bool);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* INTRODUCTION D'UNE NOUVELLE EXPRESSION */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une opération de relation entre expressions. */
+G_DEFINE_TYPE(GRelOperation, g_relational_operation, G_TYPE_SCAN_EXPRESSION);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des opérations de relations. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_relational_operation_class_init(GRelOperationClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GScanExpressionClass *expr; /* Version de classe parente */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_relational_operation_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_relational_operation_finalize;
+
+ expr = G_SCAN_EXPRESSION_CLASS(klass);
+
+ expr->cmp_rich = (compare_expr_rich_fc)g_relational_operation_compare_rich;
+ expr->dup = (dup_expr_fc)g_relational_operation_duplicate;
+ expr->reduce = (reduce_expr_fc)g_relational_operation_reduce;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : op = instance à initialiser. *
+* *
+* Description : Initialise une instance d'opération de relation. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_relational_operation_init(GRelOperation *op)
+{
+ op->first = NULL;
+ op->second = NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : op = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_relational_operation_dispose(GRelOperation *op)
+{
+ g_clear_object(&op->first);
+ g_clear_object(&op->second);
+
+ G_OBJECT_CLASS(g_relational_operation_parent_class)->dispose(G_OBJECT(op));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : op = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_relational_operation_finalize(GRelOperation *op)
+{
+ G_OBJECT_CLASS(g_relational_operation_parent_class)->finalize(G_OBJECT(op));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type d'opération booléenne à représenter. *
+* first = premier opérande concerné. *
+* second = éventuel second opérande impliqué ou NULL. *
+* *
+* Description : Organise une opération relationnelle entre expressions. *
+* *
+* Retour : Fonction mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GScanExpression *g_relational_operation_new(RichCmpOperation type, GScanExpression *first, GScanExpression *second)
+{
+ GScanExpression *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_RELATIONAL_OPERATION, NULL);
+
+ if (!g_relational_operation_create(G_RELATIONAL_OPERATION(result), type, first, second))
+ g_clear_object(&result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : op = instance à initialiser pleinement. *
+* type = type d'opération booléenne à représenter. *
+* first = premier opérande concerné. *
+* second = éventuel second opérande impliqué ou NULL. *
+* *
+* Description : Met en place une opération relationnelle entre expressions. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_relational_operation_create(GRelOperation *op, RichCmpOperation type, GScanExpression *first, GScanExpression *second)
+{
+ bool result; /* Bilan à retourner */
+
+ result = false;
+
+ if (g_scan_expression_get_value_type(first) != g_scan_expression_get_value_type(first))
+ goto exit;
+
+ if (!g_scan_expression_create(G_SCAN_EXPRESSION(op), EVT_BOOLEAN))
+ goto exit;
+
+ op->rel_type = type;
+
+ op->first = first;
+ g_object_ref(G_OBJECT(op->first));
+
+ op->second = second;
+ g_object_ref(G_OBJECT(op->second));
+
+ result = true;
+
+ exit:
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : item = premier objet à consulter pour une comparaison. *
+* other = second objet à consulter pour une comparaison. *
+* op = opération de comparaison à réaliser. *
+* status = bilan des opérations de comparaison. [OUT] *
+* *
+* Description : Réalise une comparaison entre objets selon un critère précis.*
+* *
+* Retour : true si la comparaison a pu être effectuée, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_relational_operation_compare_rich(const GRelOperation *item, const GRelOperation *other, RichCmpOperation op, bool *status)
+{
+ bool result; /* Etat à retourner */
+ bool equal; /* Bilan intermédiaire */
+
+ result = true; // TODO : cmp parent()->type
+
+ if (item->rel_type != other->rel_type)
+ {
+ result = compare_rich_integer_values(item->rel_type, other->rel_type, op);
+ goto done;
+ }
+
+ equal = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item), G_COMPARABLE_ITEM(other), RCO_EQ, status);
+
+ if (!equal)
+ {
+ result = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->first),
+ G_COMPARABLE_ITEM(other->first),
+ op, status);
+ goto done;
+ }
+
+ result = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->second),
+ G_COMPARABLE_ITEM(other->second),
+ op, status);
+
+ done:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = expression à copier. *
+* *
+* Description : Reproduit une expression en place dans une nouvelle instance.*
+* *
+* Retour : Nouvelle instance d'expression. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GScanExpression *g_relational_operation_duplicate(const GRelOperation *expr)
+{
+ GScanExpression *result; /* Instance copiée à retourner */
+
+ result = g_relational_operation_new(expr->rel_type, expr->first, expr->second);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = expression à consulter. *
+* ctx = contexte de suivi de l'analyse courante. *
+* final = impose une conversion finale de dernier tour. *
+* *
+* Description : Réduit une expression à une forme plus simple. *
+* *
+* Retour : Réduction correspondante, expression déjà réduite, ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GScanExpression *g_relational_operation_reduce(GRelOperation *expr, GScanContext *ctx, bool final)
+{
+ GScanExpression *result; /* Instance à renvoyer */
+ GScanExpression *new; /* Nouvelle expression obtenue */
+ bool status; /* Bilan d'une comparaison */
+ bool valid; /* Validité de ce bilan obtenu */
+
+ result = NULL;
+
+ /* Réduction des éléments considérés */
+
+ new = g_scan_expression_reduce(expr->first, ctx, final);
+
+ if (new != NULL)
+ {
+ g_object_unref(G_OBJECT(expr->first));
+ expr->first = new;
+ }
+
+ if (expr->second != NULL)
+ {
+ new = g_scan_expression_reduce(expr->second, ctx, final);
+
+ if (new != NULL)
+ {
+ g_object_unref(G_OBJECT(expr->second));
+ expr->second = new;
+ }
+
+ }
+
+ /* Construction d'une réduction locale ? */
+
+ if (G_IS_LITERAL_EXPRESSION(expr->first) && G_IS_LITERAL_EXPRESSION(expr->second))
+ {
+ valid = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(expr->first),
+ G_COMPARABLE_ITEM(expr->second),
+ expr->rel_type, &status);
+
+ if (valid)
+ result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { status });
+
+ }
+
+ return result;
+
+}
diff --git a/src/analysis/scan/exprs/relop.h b/src/analysis/scan/exprs/relop.h
new file mode 100644
index 0000000..ecbc8ef
--- /dev/null
+++ b/src/analysis/scan/exprs/relop.h
@@ -0,0 +1,56 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * relop.h - prototypes pour la gestion des opérations relationnelles
+ *
+ * Copyright (C) 2022 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_SCAN_EXPRS_RELOP_H
+#define _ANALYSIS_SCAN_EXPRS_RELOP_H
+
+
+#include "../expr.h"
+#include "../../../glibext/comparison.h"
+
+
+
+#define G_TYPE_RELATIONAL_OPERATION g_relational_operation_get_type()
+#define G_RELATIONAL_OPERATION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_RELATIONAL_OPERATION, GRelOperation))
+#define G_IS_RELATIONAL_OPERATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_RELATIONAL_OPERATION))
+#define G_RELATIONAL_OPERATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_RELATIONAL_OPERATION, GRelOperationClass))
+#define G_IS_RELATIONAL_OPERATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_RELATIONAL_OPERATION))
+#define G_RELATIONAL_OPERATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_RELATIONAL_OPERATION, GRelOperationClass))
+
+
+/* Opération relationnelle impliquant deux opérandes (instance) */
+typedef struct _GRelOperation GRelOperation;
+
+/* Opération relationnelle impliquant deux opérandes (classe) */
+typedef struct _GRelOperationClass GRelOperationClass;
+
+
+/* Indique le type défini pour une opération de relation entre expressions. */
+GType g_relational_operation_get_type(void);
+
+/* Organise une opération relationnelle entre expressions. */
+GScanExpression *g_relational_operation_new(RichCmpOperation, GScanExpression *, GScanExpression *);
+
+
+
+#endif /* _ANALYSIS_SCAN_EXPRS_RELOP_H */
diff --git a/src/analysis/scan/exprs/str-int.h b/src/analysis/scan/exprs/str-int.h
new file mode 100644
index 0000000..9bed5cf
--- /dev/null
+++ b/src/analysis/scan/exprs/str-int.h
@@ -0,0 +1,61 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * str-int.h - prototypes internes pour la gestion des opérations booléennes
+ *
+ * Copyright (C) 2022 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_SCAN_EXPRS_STR_INT_H
+#define _ANALYSIS_SCAN_EXPRS_STR_INT_H
+
+
+#include "str.h"
+
+
+#include "../expr-int.h"
+
+
+
+/* Opération booléenne avec un ou deux opérandes (instance) */
+struct _GStringOperation
+{
+ GScanExpression parent; /* A laisser en premier */
+
+ StringOperationType type; /* Type d'opération menée */
+ bool case_sensitive; /* Respect de la casse ? */
+
+ GScanExpression *first; /* Expression impactée #1 */
+ GScanExpression *second; /* Expression impactée #2 */
+
+};
+
+/* Opération booléenne avec un ou deux opérandes (classe) */
+struct _GStringOperationClass
+{
+ GScanExpressionClass parent; /* A laisser en premier */
+
+};
+
+
+/* Met en place une expression d'opération traite une chaîne. */
+bool g_string_operation_create(GStringOperation *, StringOperationType, GScanExpression *, GScanExpression *, bool);
+
+
+
+#endif /* _ANALYSIS_SCAN_EXPRS_STR_INT_H */
diff --git a/src/analysis/scan/exprs/str.c b/src/analysis/scan/exprs/str.c
new file mode 100644
index 0000000..675b2f6
--- /dev/null
+++ b/src/analysis/scan/exprs/str.c
@@ -0,0 +1,437 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * str.c - gestion des opérations booléennes
+ *
+ * Copyright (C) 2022 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "str.h"
+
+
+#include <assert.h>
+#include <string.h>
+#include <strings.h>
+
+
+#include "str-int.h"
+#include "literal.h"
+
+
+
+/* --------------------- INTRODUCTION D'UNE NOUVELLE EXPRESSION --------------------- */
+
+
+/* Initialise la classe des opérations visant des chaînes. */
+static void g_string_operation_class_init(GStringOperationClass *);
+
+/* Initialise une instance d'opération visant une chaîne. */
+static void g_string_operation_init(GStringOperation *);
+
+/* Supprime toutes les références externes. */
+static void g_string_operation_dispose(GStringOperation *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_string_operation_finalize(GStringOperation *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Reproduit une expression en place dans une nouvelle instance. */
+static GScanExpression *g_string_operation_duplicate(const GStringOperation *);
+
+/* Réduit une expression à une forme plus simple. */
+GScanExpression *g_string_operation_reduce(GStringOperation *, GScanContext *, bool);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* INTRODUCTION D'UNE NOUVELLE EXPRESSION */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une opération traitant une chaîne de caractères. */
+G_DEFINE_TYPE(GStringOperation, g_string_operation, G_TYPE_SCAN_EXPRESSION);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des opérations visant des chaînes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_string_operation_class_init(GStringOperationClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GScanExpressionClass *expr; /* Version de classe parente */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_string_operation_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_string_operation_finalize;
+
+ expr = G_SCAN_EXPRESSION_CLASS(klass);
+
+ expr->cmp_rich = (compare_expr_rich_fc)NULL;
+ expr->dup = (dup_expr_fc)g_string_operation_duplicate;
+ expr->reduce = (reduce_expr_fc)g_string_operation_reduce;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : op = instance à initialiser. *
+* *
+* Description : Initialise une instance d'opération visant une chaîne. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_string_operation_init(GStringOperation *op)
+{
+ op->first = NULL;
+ op->second = NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : op = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_string_operation_dispose(GStringOperation *op)
+{
+ g_clear_object(&op->first);
+ g_clear_object(&op->second);
+
+ G_OBJECT_CLASS(g_string_operation_parent_class)->dispose(G_OBJECT(op));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : op = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_string_operation_finalize(GStringOperation *op)
+{
+ G_OBJECT_CLASS(g_string_operation_parent_class)->finalize(G_OBJECT(op));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type d'opération booléenne à représenter. *
+* first = premier opérande concerné. *
+* second = éventuel second opérande impliqué ou NULL. *
+* sensitive = détermine la prise en compte de la casse. *
+* *
+* Description : Organise un appel de fonction avec ses arguments. *
+* *
+* Retour : Fonction mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GScanExpression *g_string_operation_new(StringOperationType type, GScanExpression *first, GScanExpression *second, bool sensitive)
+{
+ GScanExpression *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_STRING_OPERATION, NULL);
+
+ if (!g_string_operation_create(G_STRING_OPERATION(result), type, first, second, sensitive))
+ g_clear_object(&result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : op = instance à initialiser pleinement. *
+* type = type d'opération booléenne à représenter. *
+* first = premier opérande concerné. *
+* second = éventuel second opérande impliqué ou NULL. *
+* sensitive = détermine la prise en compte de la casse. *
+* *
+* Description : Met en place une expression d'opération traite une chaîne. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_string_operation_create(GStringOperation *op, StringOperationType type, GScanExpression *first, GScanExpression *second, bool sensitive)
+{
+ bool result; /* Bilan à retourner */
+ ExprValueType vtype; /* Type de valeur portée */
+
+ result = false;
+
+ vtype = g_scan_expression_get_value_type(first);
+
+ if (vtype != EVT_STRING && vtype != EVT_PENDING)
+ goto exit;
+
+ vtype = g_scan_expression_get_value_type(second);
+
+ if (vtype != EVT_STRING && vtype != EVT_REG_EXPR && vtype != EVT_PENDING)
+ goto exit;
+
+ op->type = type;
+
+ switch (type)
+ {
+ case SOT_CONTAINS:
+ case SOT_STARTSWITH:
+ case SOT_ENDSWITH:
+ op->case_sensitive = sensitive;
+ break;
+
+ case SOT_MATCHES:
+ break;
+
+ case SOT_IEQUALS:
+ assert(!sensitive);
+ op->case_sensitive = false;
+ break;
+
+ }
+
+ op->first = first;
+ g_object_ref(G_OBJECT(op->first));
+
+ op->second = second;
+ g_object_ref(G_OBJECT(op->second));
+
+ result = true;
+
+ exit:
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : op = expression à copier. *
+* *
+* Description : Reproduit une expression en place dans une nouvelle instance.*
+* *
+* Retour : Nouvelle instance d'expression. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GScanExpression *g_string_operation_duplicate(const GStringOperation *op)
+{
+ GScanExpression *result; /* Instance copiée à retourner */
+
+ result = g_string_operation_new(op->type, op->first, op->second, op->case_sensitive);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : op = expression à consulter. *
+* ctx = contexte de suivi de l'analyse courante. *
+* final = impose une conversion finale de dernier tour. *
+* *
+* Description : Réduit une expression à une forme plus simple. *
+* *
+* Retour : Réduction correspondante, expression déjà réduite, ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GScanExpression *g_string_operation_reduce(GStringOperation *op, GScanContext *ctx, bool final)
+{
+ GScanExpression *result; /* Instance à renvoyer */
+ GScanExpression *new; /* Nouvelle expression obtenue */
+ const char *strings[2]; /* Chaînes en jeu */
+ bool status; /* Bilan intermédiaire */
+ char *found; /* Eventuelle portion trouvée */
+ size_t len[2]; /* Tailles max. de comparaison */
+ int ret; /* Bilan de comparaison */
+ const regex_t *preg; /* Expression rationnelle */
+
+ result = NULL;
+
+ /* Réduction des éléments considérés */
+
+ new = g_scan_expression_reduce(op->first, ctx, final);
+
+ if (new != NULL)
+ {
+ g_object_unref(G_OBJECT(op->first));
+ op->first = new;
+ }
+
+ new = g_scan_expression_reduce(op->second, ctx, final);
+
+ if (new != NULL)
+ {
+ g_object_unref(G_OBJECT(op->second));
+ op->second = new;
+ }
+
+ /* Construction d'une réduction locale ? */
+
+ if (!G_IS_LITERAL_EXPRESSION(op->first))
+ goto exit;
+
+ if (!G_IS_LITERAL_EXPRESSION(op->second))
+ goto exit;
+
+ status = g_literal_expression_get_string_value(G_LITERAL_EXPRESSION(op->first), &strings[0]);
+ if (!status) goto exit;
+
+ switch (op->type)
+ {
+ case SOT_CONTAINS:
+
+ status = g_literal_expression_get_string_value(G_LITERAL_EXPRESSION(op->second), &strings[1]);
+ if (!status) goto exit;
+
+ if (op->case_sensitive)
+ found = strstr(strings[0], strings[1]);
+ else
+ found = strcasestr(strings[0], strings[1]);
+
+ result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { found != NULL });
+ break;
+
+ case SOT_STARTSWITH:
+
+ status = g_literal_expression_get_string_value(G_LITERAL_EXPRESSION(op->second), &strings[1]);
+ if (!status) goto exit;
+
+ len[1] = strlen(strings[1]);
+
+ if (op->case_sensitive)
+ ret = strncmp(strings[0], strings[1], len[1]);
+ else
+ ret = strncasecmp(strings[0], strings[1], len[1]);
+
+ result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { ret == 0 });
+ break;
+
+ case SOT_ENDSWITH:
+
+ len[0] = strlen(strings[0]);
+
+ status = g_literal_expression_get_string_value(G_LITERAL_EXPRESSION(op->second), &strings[1]);
+ if (!status) goto exit;
+
+ len[1] = strlen(strings[1]);
+
+ if (len[0] < len[1])
+ result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { false });
+
+ else
+ {
+ if (op->case_sensitive)
+ ret = strncmp(strings[0] + (len[0] - len[1]), strings[1], len[1]);
+ else
+ ret = strncasecmp(strings[0] + (len[0] - len[1]), strings[1], len[1]);
+
+ result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { ret == 0 });
+
+ }
+ break;
+
+ case SOT_MATCHES:
+
+ status = g_literal_expression_get_regex_value(G_LITERAL_EXPRESSION(op->second), &preg);
+ if (!status) goto exit;
+
+ ret = regexec(preg, strings[0], 0, NULL, 0);
+
+ result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { ret != REG_NOMATCH });
+ break;
+
+ case SOT_IEQUALS:
+
+ len[0] = strlen(strings[0]);
+
+ status = g_literal_expression_get_string_value(G_LITERAL_EXPRESSION(op->second), &strings[1]);
+ if (!status) goto exit;
+
+ len[1] = strlen(strings[1]);
+
+ if (len[0] != len[1])
+ result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { false });
+
+ else
+ {
+ ret = strcasecmp(strings[0], strings[1]);
+ result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { ret == 0 });
+ }
+ break;
+
+ }
+
+ exit:
+
+ return result;
+
+}
diff --git a/src/analysis/scan/exprs/str.h b/src/analysis/scan/exprs/str.h
new file mode 100644
index 0000000..195f941
--- /dev/null
+++ b/src/analysis/scan/exprs/str.h
@@ -0,0 +1,67 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * str.h - prototypes pour la gestion des opérations booléennes
+ *
+ * Copyright (C) 2022 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_SCAN_EXPRS_STR_H
+#define _ANALYSIS_SCAN_EXPRS_STR_H
+
+
+#include "../expr.h"
+
+
+
+#define G_TYPE_STRING_OPERATION g_string_operation_get_type()
+#define G_STRING_OPERATION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_STRING_OPERATION, GStringOperation))
+#define G_IS_STRING_OPERATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_STRING_OPERATION))
+#define G_STRING_OPERATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_STRING_OPERATION, GStringOperationClass))
+#define G_IS_STRING_OPERATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_STRING_OPERATION))
+#define G_STRING_OPERATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_STRING_OPERATION, GStringOperationClass))
+
+
+/* Opération booléenne avec un ou deux opérandes (instance) */
+typedef struct _GStringOperation GStringOperation;
+
+/* Opération booléenne avec un ou deux opérandes (classe) */
+typedef struct _GStringOperationClass GStringOperationClass;
+
+
+/* Types d'opérations booléennes supportées */
+typedef enum _StringOperationType
+{
+ SOT_CONTAINS, /* Opérateurs "[i]contains" */
+ SOT_STARTSWITH, /* Opérateurs "[i]startswith" */
+ SOT_ENDSWITH, /* Opérateurs "[i]endswith" */
+ SOT_MATCHES, /* Opérateur "matches" */
+ SOT_IEQUALS, /* Opérateur "iequals" */
+
+} StringOperationType;
+
+
+/* Indique le type défini pour une opération traitant une chaîne de caractères. */
+GType g_string_operation_get_type(void);
+
+/* Organise un appel de fonction avec ses arguments. */
+GScanExpression *g_string_operation_new(StringOperationType, GScanExpression *, GScanExpression *, bool);
+
+
+
+#endif /* _ANALYSIS_SCAN_EXPRS_STR_H */