diff options
Diffstat (limited to 'src/analysis/scan')
| -rw-r--r-- | src/analysis/scan/Makefile.am | 2 | ||||
| -rw-r--r-- | src/analysis/scan/context.c | 16 | ||||
| -rw-r--r-- | src/analysis/scan/exprs/access.c | 17 | ||||
| -rw-r--r-- | src/analysis/scan/scope-int.h | 54 | ||||
| -rw-r--r-- | src/analysis/scan/scope.c | 209 | ||||
| -rw-r--r-- | src/analysis/scan/scope.h | 24 | 
6 files changed, 314 insertions, 8 deletions
| diff --git a/src/analysis/scan/Makefile.am b/src/analysis/scan/Makefile.am index d4d7aa4..d24f4a8 100644 --- a/src/analysis/scan/Makefile.am +++ b/src/analysis/scan/Makefile.am @@ -36,6 +36,8 @@ libanalysisscan_la_SOURCES =				\  	rule.h rule.c							\  	scanner-int.h							\  	scanner.h scanner.c						\ +	scope-int.h								\ +	scope.h scope.c							\  	space-int.h								\  	space.h space.c							\  	tokens.l								\ diff --git a/src/analysis/scan/context.c b/src/analysis/scan/context.c index 1f9c38e..f108e93 100644 --- a/src/analysis/scan/context.c +++ b/src/analysis/scan/context.c @@ -763,7 +763,9 @@ bool g_scan_context_has_match_for_rule(GScanContext *context, const char *name)      bool result;                            /* Bilan à retourner           */      size_t i;                               /* Boucle de parcours          */      rule_condition_t *cond;                 /* Condition à considérer      */ +    GScanScope *scope;                      /* Définition de portées       */      GScanExpression *new;                   /* Nouvelle expression réduite */ +    ScanReductionState state;               /* Statut d'une réduction      */      bool valid;                             /* Validité d'une récupération */      result = false; @@ -786,20 +788,26 @@ bool g_scan_context_has_match_for_rule(GScanContext *context, const char *name)      if (!cond->final_reduced)      { -        valid = g_scan_expression_reduce(cond->expr, context, NULL, &new); -        if (!valid || new == NULL) goto exit; +        scope = g_scan_scope_new(name); + +        state = g_scan_expression_reduce(cond->expr, context, scope, &new); +        if (state == SRS_UNRESOLVABLE) goto exit_reduction;          g_object_unref(G_OBJECT(cond->expr));          cond->expr = new; -        valid = g_scan_expression_reduce_to_boolean(cond->expr, context, NULL, &new); -        if (!valid || new == NULL) goto exit; +        valid = g_scan_expression_reduce_to_boolean(cond->expr, context, scope, &new); +        if (!valid || new == NULL) goto exit_reduction;          g_object_unref(G_OBJECT(cond->expr));          cond->expr = new;          cond->final_reduced = true; + exit_reduction: + +        g_object_unref(G_OBJECT(scope)); +      }      /* Tentative de récupération d'un bilan final */ diff --git a/src/analysis/scan/exprs/access.c b/src/analysis/scan/exprs/access.c index 1c3a880..a8f0dc9 100644 --- a/src/analysis/scan/exprs/access.c +++ b/src/analysis/scan/exprs/access.c @@ -428,6 +428,7 @@ static ScanReductionState g_scan_named_access_reduce(GScanNamedAccess *expr, GSc      ScanReductionState result;              /* Etat synthétisé à retourner */      GRegisteredItem *resolved;              /* Cible concrète obtenue      */      GScanExpression *new_next;              /* Nouvelle version du suivant */ +    const char *current_rule;               /* Nom de la règle courante    */      bool status;                            /* Bilan d'une autre règle     */      resolved = _g_scan_named_access_prepare_reduction(expr, ctx, scope); @@ -478,10 +479,20 @@ static ScanReductionState g_scan_named_access_reduce(GScanNamedAccess *expr, GSc          if (g_scan_context_has_rule_for_name(ctx, expr->target))          { -            status = g_scan_context_has_match_for_rule(ctx, expr->target); +            current_rule = g_scan_scope_get_rule_name(scope); -            *out = g_scan_literal_expression_new(LVT_BOOLEAN, &status); -            result = SRS_REDUCED; +            /* Si référence circulaire il y a... */ +            if (strcmp(current_rule, expr->target) == 0) +                result = SRS_UNRESOLVABLE; + +            else +            { +                status = g_scan_context_has_match_for_rule(ctx, expr->target); + +                *out = g_scan_literal_expression_new(LVT_BOOLEAN, &status); +                result = SRS_REDUCED; + +            }          } diff --git a/src/analysis/scan/scope-int.h b/src/analysis/scan/scope-int.h new file mode 100644 index 0000000..2d70532 --- /dev/null +++ b/src/analysis/scan/scope-int.h @@ -0,0 +1,54 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * scope-int.h - prototypes internes pour la définition d'une portée locale de variables + * + * Copyright (C) 2023 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  Chrysalide is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ANALYSIS_SCAN_SCOPE_INT_H +#define _ANALYSIS_SCAN_SCOPE_INT_H + + +#include "scope.h" + + + +/* Portée locale de variables et règle d'appartenance (instance) */ +struct _GScanScope +{ +    GObject parent;                         /* A laisser en premier        */ + +    char *rule;                             /* Règle d'appartenance        */ + +}; + +/* Portée locale de variables et règle d'appartenance (classe) */ +struct _GScanScopeClass +{ +    GObjectClass parent;                    /* A laisser en premier        */ + +}; + + +/* Met en place une définition de portée pour variables. */ +bool g_scan_scope_create(GScanScope *, const char *); + + + +#endif  /* _ANALYSIS_SCAN_SCOPE_INT_H */ diff --git a/src/analysis/scan/scope.c b/src/analysis/scan/scope.c new file mode 100644 index 0000000..852b1d3 --- /dev/null +++ b/src/analysis/scan/scope.c @@ -0,0 +1,209 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * scope.c - définition d'une portée locale de variables + * + * Copyright (C) 2023 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  Chrysalide is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "scope.h" + + +#include <malloc.h> +#include <string.h> + + +#include "scope-int.h" + + + +/* Initialise la classe des définitions de portée locale. */ +static void g_scan_scope_class_init(GScanScopeClass *); + +/* Initialise une instance de définition de portée locale. */ +static void g_scan_scope_init(GScanScope *); + +/* Supprime toutes les références externes. */ +static void g_scan_scope_dispose(GScanScope *); + +/* Procède à la libération totale de la mémoire. */ +static void g_scan_scope_finalize(GScanScope *); + + + +/* Indique le type défini pour la définition de portée de variables. */ +G_DEFINE_TYPE(GScanScope, g_scan_scope, G_TYPE_OBJECT); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des définitions de portée locale.       * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_scan_scope_class_init(GScanScopeClass *klass) +{ +    GObjectClass *object;                   /* Autre version de la classe  */ + +    object = G_OBJECT_CLASS(klass); + +    object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_scope_dispose; +    object->finalize = (GObjectFinalizeFunc)g_scan_scope_finalize; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : scope = instance à initialiser.                              * +*                                                                             * +*  Description : Initialise une instance de définition de portée locale.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_scan_scope_init(GScanScope *scope) +{ +    scope->rule = NULL; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : scope = instance d'objet GLib à traiter.                     * +*                                                                             * +*  Description : Supprime toutes les références externes.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_scan_scope_dispose(GScanScope *scope) +{ +    G_OBJECT_CLASS(g_scan_scope_parent_class)->dispose(G_OBJECT(scope)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : scope = instance d'objet GLib à traiter.                     * +*                                                                             * +*  Description : Procède à la libération totale de la mémoire.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_scan_scope_finalize(GScanScope *scope) +{ +    if (scope->rule != NULL) +        free(scope->rule); + +    G_OBJECT_CLASS(g_scan_scope_parent_class)->finalize(G_OBJECT(scope)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : rule = désignation de la règle courante dans l'analyse.      * +*                                                                             * +*  Description : Prépare une définition de portée pour variables.             * +*                                                                             * +*  Retour      : Définition mise en place.                                    * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GScanScope *g_scan_scope_new(const char *rule) +{ +    GScanScope *result;                /* Structure à retourner       */ + +    result = g_object_new(G_TYPE_SCAN_SCOPE, NULL); + +    if (!g_scan_scope_create(result, rule)) +        g_clear_object(&result); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : scope = définition de portée à à initialiser pleinement.     * +*                rule  = désignation de la règle courante dans l'analyse.     * +*                                                                             * +*  Description : Met en place une définition de portée pour variables.        * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_scan_scope_create(GScanScope *scope, const char *rule) +{ +    bool result;                            /* Bilan à retourner           */ + +    result = true; + +    scope->rule = strdup(rule); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : scope = définition de portée à consulter.                    * +*                                                                             * +*  Description : Fournit le nom de la règle d'appartenance.                   * +*                                                                             * +*  Retour      : Nom de la règle courante pour une analyse.                   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +const char *g_scan_scope_get_rule_name(const GScanScope *scope) +{ +    const char *result;                     /* Chemin à retourner          */ + +    result = scope->rule; + +    return result; + +} diff --git a/src/analysis/scan/scope.h b/src/analysis/scan/scope.h index 1e5de2c..26b8757 100644 --- a/src/analysis/scan/scope.h +++ b/src/analysis/scan/scope.h @@ -25,12 +25,34 @@  #define _ANALYSIS_SCAN_SCOPE_H +#include <glib-object.h> +#include <stdbool.h> -typedef void *GScanScope; +#define G_TYPE_SCAN_SCOPE            g_scan_scope_get_type() +#define G_SCAN_SCOPE(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_SCOPE, GScanScope)) +#define G_IS_SCAN_SCOPE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_SCOPE)) +#define G_SCAN_SCOPE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_SCOPE, GScanScopeClass)) +#define G_IS_SCAN_SCOPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_SCOPE)) +#define G_SCAN_SCOPE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_SCOPE, GScanScopeClass)) +/* Portée locale de variables et règle d'appartenance (instance) */ +typedef struct _GScanScope GScanScope; + +/* Portée locale de variables et règle d'appartenance (classe) */ +typedef struct _GScanScopeClass GScanScopeClass; + + +/* Indique le type défini pour la définition de portée de variables. */ +GType g_scan_scope_get_type(void); + +/* Prépare une définition de portée pour variables. */ +GScanScope *g_scan_scope_new(const char *); + +/* Fournit le nom de la règle d'appartenance. */ +const char *g_scan_scope_get_rule_name(const GScanScope *); | 
