summaryrefslogtreecommitdiff
path: root/src/analysis/scan/exprs/strop.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/scan/exprs/strop.c')
-rw-r--r--src/analysis/scan/exprs/strop.c207
1 files changed, 95 insertions, 112 deletions
diff --git a/src/analysis/scan/exprs/strop.c b/src/analysis/scan/exprs/strop.c
index 145e8da..c7c2878 100644
--- a/src/analysis/scan/exprs/strop.c
+++ b/src/analysis/scan/exprs/strop.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* strop.c - gestion des opérations booléennes
*
- * Copyright (C) 2022 Cyrille Bagard
+ * Copyright (C) 2023 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -38,27 +38,24 @@
/* Initialise la classe des opérations visant des chaînes. */
-static void g_string_operation_class_init(GStringOperationClass *);
+static void g_scan_string_operation_class_init(GScanStringOperationClass *);
/* Initialise une instance d'opération visant une chaîne. */
-static void g_string_operation_init(GStringOperation *);
+static void g_scan_string_operation_init(GScanStringOperation *);
/* Supprime toutes les références externes. */
-static void g_string_operation_dispose(GStringOperation *);
+static void g_scan_string_operation_dispose(GScanStringOperation *);
/* Procède à la libération totale de la mémoire. */
-static void g_string_operation_finalize(GStringOperation *);
+static void g_scan_string_operation_finalize(GScanStringOperation *);
/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
-/* Reproduit une expression en place dans une nouvelle instance. */
-static void g_string_operation_copy(GStringOperation *, const GStringOperation *);
-
/* Réduit une expression à une forme plus simple. */
-static bool g_string_operation_reduce(GStringOperation *, GScanContext *, GScanScope *, GScanExpression **);
+static ScanReductionState g_scan_string_operation_reduce(GScanStringOperation *, GScanContext *, GScanScope *, GScanExpression **);
@@ -68,7 +65,7 @@ static bool g_string_operation_reduce(GStringOperation *, GScanContext *, GScanS
/* 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);
+G_DEFINE_TYPE(GScanStringOperation, g_scan_string_operation, G_TYPE_SCAN_EXPRESSION);
/******************************************************************************
@@ -83,21 +80,20 @@ G_DEFINE_TYPE(GStringOperation, g_string_operation, G_TYPE_SCAN_EXPRESSION);
* *
******************************************************************************/
-static void g_string_operation_class_init(GStringOperationClass *klass)
+static void g_scan_string_operation_class_init(GScanStringOperationClass *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;
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_string_operation_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_scan_string_operation_finalize;
expr = G_SCAN_EXPRESSION_CLASS(klass);
expr->cmp_rich = (compare_expr_rich_fc)NULL;
- expr->copy = (copy_expr_fc)g_string_operation_copy;
- expr->reduce = (reduce_expr_fc)g_string_operation_reduce;
+ expr->reduce = (reduce_expr_fc)g_scan_string_operation_reduce;
}
@@ -114,7 +110,7 @@ static void g_string_operation_class_init(GStringOperationClass *klass)
* *
******************************************************************************/
-static void g_string_operation_init(GStringOperation *op)
+static void g_scan_string_operation_init(GScanStringOperation *op)
{
op->left = NULL;
op->right = NULL;
@@ -134,12 +130,12 @@ static void g_string_operation_init(GStringOperation *op)
* *
******************************************************************************/
-static void g_string_operation_dispose(GStringOperation *op)
+static void g_scan_string_operation_dispose(GScanStringOperation *op)
{
g_clear_object(&op->left);
g_clear_object(&op->right);
- G_OBJECT_CLASS(g_string_operation_parent_class)->dispose(G_OBJECT(op));
+ G_OBJECT_CLASS(g_scan_string_operation_parent_class)->dispose(G_OBJECT(op));
}
@@ -156,9 +152,9 @@ static void g_string_operation_dispose(GStringOperation *op)
* *
******************************************************************************/
-static void g_string_operation_finalize(GStringOperation *op)
+static void g_scan_string_operation_finalize(GScanStringOperation *op)
{
- G_OBJECT_CLASS(g_string_operation_parent_class)->finalize(G_OBJECT(op));
+ G_OBJECT_CLASS(g_scan_string_operation_parent_class)->finalize(G_OBJECT(op));
}
@@ -178,13 +174,13 @@ static void g_string_operation_finalize(GStringOperation *op)
* *
******************************************************************************/
-GScanExpression *g_string_operation_new(StringOperationType type, GScanExpression *first, GScanExpression *second, bool sensitive)
+GScanExpression *g_scan_string_operation_new(StringOperationType type, GScanExpression *first, GScanExpression *second, bool sensitive)
{
GScanExpression *result; /* Structure à retourner */
- result = g_object_new(G_TYPE_STRING_OPERATION, NULL);
+ result = g_object_new(G_TYPE_SCAN_STRING_OPERATION, NULL);
- if (!g_string_operation_create(G_STRING_OPERATION(result), type, first, second, sensitive))
+ if (!g_scan_string_operation_create(G_SCAN_STRING_OPERATION(result), type, first, second, sensitive))
g_clear_object(&result);
return result;
@@ -198,7 +194,7 @@ GScanExpression *g_string_operation_new(StringOperationType type, GScanExpressio
* type = type d'opération booléenne à représenter. *
* left = premier opérande concerné. *
* right = éventuel second opérande impliqué ou NULL. *
-* sensitive = détermine la prise en compte de la casse. *
+* sensitive = détermine la prise en compte de la casse. *
* *
* Description : Met en place une expression d'opération traite une chaîne. *
* *
@@ -208,22 +204,11 @@ GScanExpression *g_string_operation_new(StringOperationType type, GScanExpressio
* *
******************************************************************************/
-bool g_string_operation_create(GStringOperation *op, StringOperationType type, GScanExpression *left, GScanExpression *right, bool sensitive)
+bool g_scan_string_operation_create(GScanStringOperation *op, StringOperationType type, GScanExpression *left, GScanExpression *right, bool sensitive)
{
bool result; /* Bilan à retourner */
- ExprValueType vtype; /* Type de valeur portée */
-
- result = false;
-
- vtype = g_scan_expression_get_value_type(left);
-
- if (vtype != EVT_STRING && vtype != EVT_PENDING)
- goto exit;
-
- vtype = g_scan_expression_get_value_type(right);
- if (vtype != EVT_STRING && vtype != EVT_REG_EXPR && vtype != EVT_PENDING)
- goto exit;
+ result = true;
op->type = type;
@@ -251,10 +236,6 @@ bool g_string_operation_create(GStringOperation *op, StringOperationType type, G
op->right = right;
g_object_ref(G_OBJECT(op->right));
- result = true;
-
- exit:
-
return result;
}
@@ -268,36 +249,6 @@ bool g_string_operation_create(GStringOperation *op, StringOperationType type, G
/******************************************************************************
* *
-* Paramètres : dest = emplacement d'enregistrement à constituer. [OUT] *
-* src = expression source à copier. *
-* *
-* Description : Reproduit une expression en place dans une nouvelle instance.*
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_string_operation_copy(GStringOperation *dest, const GStringOperation *src)
-{
- GScanExpressionClass *class; /* Classe parente à solliciter */
-
- class = G_SCAN_EXPRESSION_CLASS(g_string_operation_parent_class);
-
- class->copy(G_SCAN_EXPRESSION(dest), G_SCAN_EXPRESSION(src));
-
- dest->type = src->type;
- dest->case_sensitive = src->case_sensitive;
-
- dest->left = g_scan_expression_duplicate(src->left);
- dest->right = g_scan_expression_duplicate(src->right);
-
-}
-
-
-/******************************************************************************
-* *
* Paramètres : expr = expression à consulter. *
* ctx = contexte de suivi de l'analyse courante. *
* scope = portée courante des variables locales. *
@@ -311,47 +262,65 @@ static void g_string_operation_copy(GStringOperation *dest, const GStringOperati
* *
******************************************************************************/
-static bool g_string_operation_reduce(GStringOperation *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out)
+static ScanReductionState g_scan_string_operation_reduce(GScanStringOperation *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out)
{
- bool result; /* Bilan à retourner */
+ ScanReductionState result; /* Etat synthétisé à retourner */
GScanExpression *new_left; /* Expression réduite (gauche) */
GScanExpression *new_right; /* Expression réduite (droite) */
- GLiteralExpression *op_left; /* Opérande gauche final */
- GLiteralExpression *op_right; /* Opérande droite final */
+ ScanReductionState state_left; /* Etat synthétisé #1 */
+ ScanReductionState state_right; /* Etat synthétisé #2 */
+ GScanLiteralExpression *op_left; /* Opérande gauche final */
+ GScanLiteralExpression *op_right; /* Opérande droite final */
const sized_string_t *strings[2]; /* Chaînes en jeu */
const void *found; /* Présence d'une bribe ? */
bool status; /* Bilan de comparaison #1 */
+ int ret; /* Bilan de comparaison #2 */
size_t offset; /* Point de départ d'analyse */
const regex_t *preg; /* Expression rationnelle */
- int ret; /* Bilan de comparaison #2 */
/* Réduction des éléments considérés */
new_left = NULL;
new_right = NULL;
- result = g_scan_expression_reduce(expr->left, ctx, scope, &new_left);
- if (!result) goto exit;
+ state_left = g_scan_expression_reduce(expr->left, ctx, scope, &new_left);
+ if (state_left == SRS_UNRESOLVABLE)
+ {
+ result = SRS_UNRESOLVABLE;
+ goto exit;
+ }
- result = g_scan_expression_reduce(expr->right, ctx, scope, &new_right);
- if (!result) goto exit;
+ state_right = g_scan_expression_reduce(expr->right, ctx, scope, &new_right);
+ if (state_right == SRS_UNRESOLVABLE)
+ {
+ result = SRS_UNRESOLVABLE;
+ goto exit;
+ }
/* Construction d'une réduction locale ? */
- if (G_IS_LITERAL_EXPRESSION(new_left) && G_IS_LITERAL_EXPRESSION(new_right))
+ if (G_IS_SCAN_LITERAL_EXPRESSION(new_left) && G_IS_SCAN_LITERAL_EXPRESSION(new_right))
{
- op_left = G_LITERAL_EXPRESSION(new_left);
- op_right = G_LITERAL_EXPRESSION(new_right);
+ op_left = G_SCAN_LITERAL_EXPRESSION(new_left);
+ op_right = G_SCAN_LITERAL_EXPRESSION(new_right);
+
+ if (!g_scan_literal_expression_get_string_value(op_left, &strings[0]))
+ {
+ result = SRS_UNRESOLVABLE;
+ goto exit;
+ }
- result = g_literal_expression_get_string_value(op_left, &strings[0]);
- if (!result) goto exit;
+ result = SRS_REDUCED;
switch (expr->type)
{
case SOT_CONTAINS:
- result = g_literal_expression_get_string_value(op_right, &strings[1]);
- if (!result) goto exit;
+ if (!g_scan_literal_expression_get_string_value(op_right, &strings[1]))
+ {
+ result = SRS_UNRESOLVABLE;
+ goto exit;
+ }
if (expr->case_sensitive)
found = memmem(strings[0]->data, strings[0]->len, strings[1]->data, strings[1]->len);
@@ -359,13 +328,16 @@ static bool g_string_operation_reduce(GStringOperation *expr, GScanContext *ctx,
else
found = memcasemem(strings[0]->data, strings[0]->len, strings[1]->data, strings[1]->len);
- result = g_literal_expression_new(EVT_BOOLEAN, (bool []) { found != NULL });
+ *out = g_scan_literal_expression_new(LVT_BOOLEAN, (bool []) { found != NULL });
break;
case SOT_STARTSWITH:
- result = g_literal_expression_get_string_value(op_right, &strings[1]);
- if (!result) goto exit;
+ if (!g_scan_literal_expression_get_string_value(op_right, &strings[1]))
+ {
+ result = SRS_UNRESOLVABLE;
+ goto exit;
+ }
if (strings[0]->len < strings[1]->len)
status = false;
@@ -381,13 +353,16 @@ static bool g_string_operation_reduce(GStringOperation *expr, GScanContext *ctx,
}
- result = g_literal_expression_new(EVT_BOOLEAN, &status);
+ *out = g_scan_literal_expression_new(LVT_BOOLEAN, &status);
break;
case SOT_ENDSWITH:
- result = g_literal_expression_get_string_value(op_right, &strings[1]);
- if (!result) goto exit;
+ if (!g_scan_literal_expression_get_string_value(op_right, &strings[1]))
+ {
+ result = SRS_UNRESOLVABLE;
+ goto exit;
+ }
if (strings[0]->len < strings[1]->len)
status = false;
@@ -405,23 +380,29 @@ static bool g_string_operation_reduce(GStringOperation *expr, GScanContext *ctx,
}
- result = g_literal_expression_new(EVT_BOOLEAN, &status);
+ *out = g_scan_literal_expression_new(LVT_BOOLEAN, &status);
break;
case SOT_MATCHES:
- result = g_literal_expression_get_regex_value(op_right, &preg);
- if (!result) goto exit;
+ if (!g_scan_literal_expression_get_regex_value(op_right, &preg))
+ {
+ result = SRS_UNRESOLVABLE;
+ goto exit;
+ }
ret = regexec(preg, strings[0]->data, 0, NULL, 0);
- *out = g_literal_expression_new(EVT_BOOLEAN, (bool []) { ret != REG_NOMATCH });
+ *out = g_scan_literal_expression_new(LVT_BOOLEAN, (bool []) { ret != REG_NOMATCH });
break;
case SOT_IEQUALS:
- result = g_literal_expression_get_string_value(op_right, &strings[1]);
- if (!result) goto exit;
+ if (!g_scan_literal_expression_get_string_value(op_right, &strings[1]))
+ {
+ result = SRS_UNRESOLVABLE;
+ goto exit;
+ }
if (strings[0]->len != strings[1]->len)
status = false;
@@ -432,7 +413,7 @@ static bool g_string_operation_reduce(GStringOperation *expr, GScanContext *ctx,
status = (ret == 0);
}
- result = g_literal_expression_new(EVT_BOOLEAN, &status);
+ *out = g_scan_literal_expression_new(LVT_BOOLEAN, &status);
break;
}
@@ -441,24 +422,26 @@ static bool g_string_operation_reduce(GStringOperation *expr, GScanContext *ctx,
/* Mise à jour de la progression ? */
- else if ((new_left != NULL && new_left != expr->left) || (new_right != NULL && new_right != expr->right))
+ else if (state_left == SRS_WAIT_FOR_SCAN || state_right == SRS_WAIT_FOR_SCAN)
{
- if (new_left == NULL)
- {
- new_left = expr->left;
- g_object_ref(G_OBJECT(new_left));
- }
+ if (new_left != expr->left || new_right != expr->right)
+ *out = g_scan_string_operation_new(expr->type, new_left, new_right, expr->case_sensitive);
- if (new_right == NULL)
- {
- new_right = expr->right;
- g_object_ref(G_OBJECT(new_right));
- }
+ result = SRS_WAIT_FOR_SCAN;
- *out = g_string_operation_new(expr->type, new_left, new_right, expr->case_sensitive);
+ }
+
+ /* Cas des situations où les expressions ne sont pas exploitables (!) */
+ else
+ {
+ assert(state_left == SRS_REDUCED && state_right == SRS_REDUCED);
+
+ result = SRS_UNRESOLVABLE;
}
+ /* Sortie propre */
+
exit:
g_clear_object(&new_left);