diff options
Diffstat (limited to 'src/analysis')
| -rw-r--r-- | src/analysis/scan/context-int.h | 2 | ||||
| -rw-r--r-- | src/analysis/scan/context.c | 48 | ||||
| -rw-r--r-- | src/analysis/scan/context.h | 6 | ||||
| -rw-r--r-- | src/analysis/scan/grammar.y | 34 | ||||
| -rw-r--r-- | src/analysis/scan/pattern.c | 10 | ||||
| -rw-r--r-- | src/analysis/scan/rule-int.h | 6 | ||||
| -rw-r--r-- | src/analysis/scan/rule.c | 83 | ||||
| -rw-r--r-- | src/analysis/scan/rule.h | 15 | ||||
| -rw-r--r-- | src/analysis/scan/scanner.c | 58 | ||||
| -rw-r--r-- | src/analysis/scan/tokens.l | 3 | 
10 files changed, 233 insertions, 32 deletions
| diff --git a/src/analysis/scan/context-int.h b/src/analysis/scan/context-int.h index 8a5fbaf..654ecca 100644 --- a/src/analysis/scan/context-int.h +++ b/src/analysis/scan/context-int.h @@ -83,6 +83,8 @@ struct _GScanContext      full_match_tracker_t **full_trackers;   /* Correspondances confirmées  */      size_t full_count;                      /* Quantité de correspondances */ +    bool global;                            /* Validation globale          */ +      rule_condition_t *conditions;           /* Ensemble de règles suivies  */      size_t cond_count;                      /* Quantité de ces conditions  */ diff --git a/src/analysis/scan/context.c b/src/analysis/scan/context.c index c016f7e..8a9b600 100644 --- a/src/analysis/scan/context.c +++ b/src/analysis/scan/context.c @@ -246,6 +246,8 @@ static void g_scan_context_init(GScanContext *context)      context->full_trackers = NULL;      context->full_count = 0; +    context->global = true; +      context->conditions = NULL;      context->cond_count = 0; @@ -751,6 +753,49 @@ bool g_scan_context_has_rule_for_name(const GScanContext *context, const char *n  /******************************************************************************  *                                                                             *  *  Paramètres  : context = mémoire de résultats d'analyse à consulter.        * +*                                                                             * +*  Description : Indique le bilan des règles globales.                        * +*                                                                             * +*  Retour      : Bilan global des analyses menées.                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_scan_context_has_global_match(const GScanContext *context) +{ +    bool result;                            /* Bilan global à retourner    */ + +    result = context->global; + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : context = mémoire de résultats d'analyse à actualiser.       * +*                global  = bilan global des analyses menées.                  * +*                                                                             * +*  Description : Définit le bilan des règles globales.                        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_scan_context_set_global_match(GScanContext *context, bool global) +{ +    context->global = global; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : context = mémoire de résultats d'analyse à consulter.        *  *                name    = désignation de la règle ciblée.                    *  *                                                                             *  *  Description : Indique si une correspondance globale a pu être établie.     * @@ -773,6 +818,9 @@ bool g_scan_context_has_match_for_rule(GScanContext *context, const char *name)      result = false; +    if (!context->global) +        goto exit; +      /* Recherche de la règle visée */      cond = NULL; diff --git a/src/analysis/scan/context.h b/src/analysis/scan/context.h index de8a213..7fb3dd4 100644 --- a/src/analysis/scan/context.h +++ b/src/analysis/scan/context.h @@ -101,6 +101,12 @@ bool g_scan_context_set_rule_condition(GScanContext *, const char *, GScanExpres  /* Indique si un nom donné correspond à une règle. */  bool g_scan_context_has_rule_for_name(const GScanContext *, const char *); +/* Indique le bilan des règles globales. */ +bool g_scan_context_has_global_match(const GScanContext *); + +/* Définit le bilan des règles globales. */ +void g_scan_context_set_global_match(GScanContext *, bool); +  /* Indique si une correspondance globale a pu être établie. */  bool g_scan_context_has_match_for_rule(GScanContext *, const char *); diff --git a/src/analysis/scan/grammar.y b/src/analysis/scan/grammar.y index 25bb536..e1f0e9e 100644 --- a/src/analysis/scan/grammar.y +++ b/src/analysis/scan/grammar.y @@ -73,11 +73,9 @@ typedef void *yyscan_t;          sized_string_t *tmp_masks;          /* Masques associés            */      } masked; - +    ScanRuleFlags rule_flags;               /* Fanions pour règle          */      GScanRule *rule;                        /* Nouvelle règle à intégrer   */ - -      GScanTokenNode *node;                   /* Bribe de motif à intégrer   */      GSearchPattern *pattern;                /* Nouveau motif à considérer  */ @@ -140,6 +138,7 @@ YY_DECL;  %token NOCASE "nocase"  %token FULLWORD "fullword"  %token PRIVATE "private" +%token GLOBAL "global"  %token HEX_BYTES @@ -234,6 +233,8 @@ YY_DECL;  %type <unsigned_integer> UNSIGNED_INTEGER  %type <sized_cstring> STRING +%type <rule_flags> rule_flags +%type <rule_flags> rule_flag  %type <rule> rule  %type <sized_cstring> PLAIN_TEXT @@ -345,14 +346,35 @@ YY_DECL;   * Définition de règle.   */ -              rule : RAW_RULE RULE_NAME +              rule : rule_flags RAW_RULE RULE_NAME                     { -                       *built_rule = g_scan_rule_new($2.data); +                       *built_rule = g_scan_rule_new($1, $3.data);                         $<rule>$ = *built_rule;                     }                     BRACE_IN meta bytes condition BRACE_OUT                     { -                       $$ = $<rule>3; +                       $$ = $<rule>4; +                   } +                   ; + + +        rule_flags : /* empty */ +                   { +                       $$ = SRF_NONE; +                   } +                   | rule_flags rule_flag +                   { +                       $$ = $1 | $2; +                   } +                   ; + +         rule_flag : "private" +                   { +                       $$ = SRF_PRIVATE; +                   } +                   | "global" +                   { +                       $$ = SRF_GLOBAL;                     }                     ; diff --git a/src/analysis/scan/pattern.c b/src/analysis/scan/pattern.c index 797f4ac..fe3babc 100644 --- a/src/analysis/scan/pattern.c +++ b/src/analysis/scan/pattern.c @@ -295,7 +295,7 @@ char *g_search_pattern_convert_as_text(const GSearchPattern *pattern, GScanConte  *                padding  = éventuel bourrage initial à placer ou NULL.       *  *                level    = profondeur actuelle.                              *  *                fd       = canal d'écriture.                                 * -*                trailing = impose une virgule finale ?                       * +*                tail     = décline la pose d'une virgule finale ?            *  *                                                                             *  *  Description : Affiche un motif de recherche au format JSON.                *  *                                                                             * @@ -305,7 +305,7 @@ char *g_search_pattern_convert_as_text(const GSearchPattern *pattern, GScanConte  *                                                                             *  ******************************************************************************/ -void g_search_pattern_output_to_json(const GSearchPattern *pattern, GScanContext *context, const sized_string_t *padding, unsigned int level, int fd, bool trailing) +void g_search_pattern_output_to_json(const GSearchPattern *pattern, GScanContext *context, const sized_string_t *padding, unsigned int level, int fd, bool tail)  {      unsigned int i;                         /* Boucle de parcours          */      GSearchPatternClass *class;             /* Classe à activer            */ @@ -339,10 +339,10 @@ void g_search_pattern_output_to_json(const GSearchPattern *pattern, GScanContext      for (i = 0; i < level; i++)          write(fd, padding->data, padding->len); -    if (trailing) -        write(fd, "},\n", 3); -    else +    if (tail)          write(fd, "}\n", 2); +    else +        write(fd, "},\n", 3);  } diff --git a/src/analysis/scan/rule-int.h b/src/analysis/scan/rule-int.h index b43cba9..1ca2b7f 100644 --- a/src/analysis/scan/rule-int.h +++ b/src/analysis/scan/rule-int.h @@ -37,6 +37,8 @@ struct _GScanRule  {      GObject parent;                         /* A laisser en premier        */ +    ScanRuleFlags flags;                    /* Propriétés de la règle      */ +      char *name;                             /* Désignation de la règle     */      fnv64_t name_hash;                      /* Empreinte de la désignation */ @@ -56,5 +58,9 @@ struct _GScanRuleClass  }; +/* Met en place une règle de détection statique avec motifs. */ +bool g_scan_rule_create(GScanRule *, ScanRuleFlags, const char *); + +  #endif  /* _ANALYSIS_SCAN_RULE_INT_H */ diff --git a/src/analysis/scan/rule.c b/src/analysis/scan/rule.c index a7d7765..68222dd 100644 --- a/src/analysis/scan/rule.c +++ b/src/analysis/scan/rule.c @@ -97,6 +97,8 @@ static void g_scan_rule_class_init(GScanRuleClass *klass)  static void g_scan_rule_init(GScanRule *rule)  { +    rule->flags = SRF_NONE; +      rule->name = NULL;      rule->name_hash = 0; @@ -159,7 +161,8 @@ static void g_scan_rule_finalize(GScanRule *rule)  /******************************************************************************  *                                                                             * -*  Paramètres  : name = désignation à associer à la future règle.             * +*  Paramètres  : flags = propriétés particulières à conférer à la règle.      * +*                name  = désignation à associer à la future règle.            *  *                                                                             *  *  Description : Crée une règle de détection statique à l'aide de motifs.     *  *                                                                             * @@ -169,12 +172,14 @@ static void g_scan_rule_finalize(GScanRule *rule)  *                                                                             *  ******************************************************************************/ -GScanRule *g_scan_rule_new(const char *name) +GScanRule *g_scan_rule_new(ScanRuleFlags flags, const char *name)  {      GScanRule *result;                /* Structure à retourner       */      result = g_object_new(G_TYPE_SCAN_RULE, NULL); +    result->flags = flags; +      result->name = strdup(name);      result->name_hash = fnv_64a_hash(name); @@ -185,7 +190,60 @@ GScanRule *g_scan_rule_new(const char *name)  /******************************************************************************  *                                                                             * -*  Paramètres  : rule = règle de détection à compléter.                       * +*  Paramètres  : rule  = règle de détection à initialiser pleinement.         * +*                flags = propriétés particulières à conférer à la règle.      * +*                name  = désignation à associer à la future règle.            * +*                                                                             * +*  Description : Met en place une règle de détection statique avec motifs.    * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_scan_rule_create(GScanRule *rule, ScanRuleFlags flags, const char *name) +{ +    GScanRule *result;                /* Structure à retourner       */ + +    result = g_object_new(G_TYPE_SCAN_RULE, NULL); + +    result->flags = flags; + +    result->name = strdup(name); +    result->name_hash = fnv_64a_hash(name); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : rule = règle de détection à consulter.                       * +*                                                                             * +*  Description : Indique les particularités liées à une règle de détection.   * +*                                                                             * +*  Retour      : Propriétés particulières attachées à la règle.               * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +ScanRuleFlags g_scan_rule_get_flags(const GScanRule *rule) +{ +    ScanRuleFlags result;                   /* Fanions à retourner         */ + +    result = rule->flags; + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : rule = règle de détection à consulter.                       *  *                hash = empreinte précalculée associée au nom. [OUT]          *  *                                                                             *  *  Description : Indique le nom associé à une règle de détection.             * @@ -202,7 +260,8 @@ const char *g_scan_rule_get_name(const GScanRule *rule, fnv64_t *hash)      result = rule->name; -    *hash = rule->name_hash; +    if (hash != NULL) +        *hash = rule->name_hash;      return result; @@ -635,7 +694,7 @@ char *g_scan_rule_convert_as_text(const GScanRule *rule, GScanContext *context)  *                padding  = éventuel bourrage initial à placer ou NULL.       *  *                level    = profondeur actuelle.                              *  *                fd       = canal d'écriture.                                 * -*                trailing = impose une virgule finale ?                       * +*                tail     = décline la pose d'une virgule finale ?            *  *                                                                             *  *  Description : Affiche une règle au format JSON.                            *  *                                                                             * @@ -645,10 +704,10 @@ char *g_scan_rule_convert_as_text(const GScanRule *rule, GScanContext *context)  *                                                                             *  ******************************************************************************/ -void g_scan_rule_output_to_json(const GScanRule *rule, GScanContext *context, const sized_string_t *padding, unsigned int level, int fd, bool trailing) +void g_scan_rule_output_to_json(const GScanRule *rule, GScanContext *context, const sized_string_t *padding, unsigned int level, int fd, bool tail)  {      size_t i;                               /* Boucle de parcours          */ -    bool sub_trailing;                      /* Virgule finale              */ +    bool sub_tail;                          /* Saut de la virgule finale ? */      /* Introduction */ @@ -677,9 +736,9 @@ void g_scan_rule_output_to_json(const GScanRule *rule, GScanContext *context, co      for (i = 0; i < rule->bytes_used; i++)      { -        sub_trailing = ((i + 1) < rule->bytes_used); +        sub_tail = ((i + 1) == rule->bytes_used); -        g_search_pattern_output_to_json(rule->bytes_locals[i], context, padding, level + 2, fd, sub_trailing); +        g_search_pattern_output_to_json(rule->bytes_locals[i], context, padding, level + 2, fd, sub_tail);      } @@ -707,10 +766,10 @@ void g_scan_rule_output_to_json(const GScanRule *rule, GScanContext *context, co      for (i = 0; i < level; i++)          write(fd, padding->data, padding->len); -    if (trailing) -        write(fd, "},\n", 3); -    else +    if (tail)          write(fd, "}\n", 2); +    else +        write(fd, "},\n", 3);  } diff --git a/src/analysis/scan/rule.h b/src/analysis/scan/rule.h index 6ab5105..3e6fe9d 100644 --- a/src/analysis/scan/rule.h +++ b/src/analysis/scan/rule.h @@ -53,11 +53,24 @@ typedef struct _GScanRule GScanRule;  typedef struct _GScanRuleClass GScanRuleClass; +/* Particularités de règle à faire valoir */ +typedef enum _ScanRuleFlags +{ +    SRF_NONE    = (0 << 0),                 /* Absence de particularité    */ +    SRF_PRIVATE = (1 << 0),                 /* Règle silencieuse           */ +    SRF_GLOBAL  = (1 << 1)                  /* Règle de base implicite     */ + +} ScanRuleFlags; + +  /* Indique le type défini pour une règle de détection par motifs. */  GType g_scan_rule_get_type(void);  /* Crée une règle de détection statique à l'aide de motifs. */ -GScanRule *g_scan_rule_new(const char *); +GScanRule *g_scan_rule_new(ScanRuleFlags, const char *); + +/* Indique les particularités liées à une règle de détection.   */ +ScanRuleFlags g_scan_rule_get_flags(const GScanRule *);  /* Indique le nom associé à une règle de détection. */  const char *g_scan_rule_get_name(const GScanRule *, fnv64_t *); diff --git a/src/analysis/scan/scanner.c b/src/analysis/scan/scanner.c index 41fa0de..7b553e6 100644 --- a/src/analysis/scan/scanner.c +++ b/src/analysis/scan/scanner.c @@ -364,7 +364,7 @@ bool g_content_scanner_include_resource(GContentScanner *scanner, const char *pa              if (!result)              { -                inc_name = g_scan_rule_get_name(included->rules[i], (fnv64_t []) { 0 }); +                inc_name = g_scan_rule_get_name(included->rules[i], NULL);                  log_variadic_message(LMT_ERROR, "Can not import from '%s': rule '%s' already exists!",                                       path, inc_name); @@ -459,7 +459,7 @@ bool g_content_scanner_add_rule(GContentScanner *scanner, GScanRule *rule)      if (!result)      { -        inc_name = g_scan_rule_get_name(rule, (fnv64_t []) { 0 }); +        inc_name = g_scan_rule_get_name(rule, NULL);          log_variadic_message(LMT_ERROR, "Can not add rule: '%s' already exists!", inc_name); @@ -489,6 +489,11 @@ GScanContext *g_content_scanner_analyze(GContentScanner *scanner, GScanOptions *      GScanContext *result;                   /* Bilan global à retourner    */      bool status;                            /* Bilan d'opération locale    */      size_t i;                               /* Boucle de parcours          */ +    bool global;                            /* Bilan des règles globales   */ +    GScanRule *rule;                        /* Règle à consulter           */ +    const char *name;                       /* Désignation de la règle     */ + +    /* Préparations... */      result = g_scan_context_new(options); @@ -510,6 +515,8 @@ GScanContext *g_content_scanner_analyze(GContentScanner *scanner, GScanOptions *      } +    /* Phase d'analyse */ +      g_scan_context_set_content(result, content);      g_engine_backend_run_scan(scanner->data_backend, result); @@ -519,6 +526,25 @@ GScanContext *g_content_scanner_analyze(GContentScanner *scanner, GScanOptions *      for (i = 0; i < scanner->rule_count; i++)          g_scan_rule_check(scanner->rules[i], scanner->data_backend, result); +    /* Etablissement d'un bilan global */ + +    global = true; + +    for (i = 0; i < scanner->rule_count; i++) +    { +        rule = scanner->rules[i]; + +        if ((g_scan_rule_get_flags(rule) & SRF_GLOBAL) == 0) +            continue; + +        name = g_scan_rule_get_name(rule, NULL); + +        global = g_scan_context_has_match_for_rule(result, name); + +    } + +    g_scan_context_set_global_match(result, global); +   exit:      return result; @@ -645,29 +671,45 @@ char *g_content_scanner_convert_to_text(const GContentScanner *scanner, GScanCon  void g_content_scanner_output_to_json(const GContentScanner *scanner, GScanContext *context, const sized_string_t *padding, unsigned int level, int fd)  { -    size_t i;                               /* Boucle de parcours          */ -    bool trailing;                          /* Virgule finale              */ +    size_t k;                               /* Boucle de parcours #1       */ +    size_t i;                               /* Boucle de parcours #2       */ +    size_t last_displayed;                  /* Dernier indice affiché      */ +    bool tail;                              /* Saut de la virgule finale ? */      /* Introduction */ -    for (i = 0; i < level; i++) +    for (k = 0; k < level; k++)          write(fd, padding->data, padding->len);      write(fd, "[\n", 2);      /* Sous-traitance aux règles */ +    for (i = scanner->rule_count; i > 0; i--) +        if ((g_scan_rule_get_flags(scanner->rules[i - 1]) & SRF_PRIVATE) == 0) +            break; + +    if (i == 0) +        goto nothing_to_display; +    else +        last_displayed = i - 1; +      for (i = 0; i < scanner->rule_count; i++)      { -        trailing = ((i + 1) < scanner->rule_count); +        if ((g_scan_rule_get_flags(scanner->rules[i]) & SRF_PRIVATE) == SRF_PRIVATE) +            continue; -        g_scan_rule_output_to_json(scanner->rules[i], context, padding, level + 1, fd, trailing); +        tail = (i == last_displayed); + +        g_scan_rule_output_to_json(scanner->rules[i], context, padding, level + 1, fd, tail);      }      /* Conclusion */ -    for (i = 0; i < level; i++) + nothing_to_display: + +    for (k = 0; k < level; k++)          write(fd, padding->data, padding->len);      write(fd, "]\n", 2); diff --git a/src/analysis/scan/tokens.l b/src/analysis/scan/tokens.l index 241c973..1a17344 100644 --- a/src/analysis/scan/tokens.l +++ b/src/analysis/scan/tokens.l @@ -403,6 +403,9 @@ bytes_fuzzy_id [\*A-Za-z_][\*A-Za-z0-9_]*  %{ /* Définition locale d'une règle */ %} +                           "global" { return GLOBAL; } +                          "private" { return PRIVATE; } +                               "rule" {                                          PUSH_STATE(rule_intro);                                          return RAW_RULE; | 
