summaryrefslogtreecommitdiff
path: root/src/analysis/scan/context.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/scan/context.c')
-rw-r--r--src/analysis/scan/context.c325
1 files changed, 302 insertions, 23 deletions
diff --git a/src/analysis/scan/context.c b/src/analysis/scan/context.c
index c19b76c..1f9c38e 100644
--- a/src/analysis/scan/context.c
+++ b/src/analysis/scan/context.c
@@ -25,11 +25,36 @@
#include <assert.h>
+#include <malloc.h>
+#include <stdlib.h>
#include <string.h>
#include "context-int.h"
#include "exprs/literal.h"
+#include "../../common/sort.h"
+
+
+
+
+
+/* ------------------- ADMINISTRATION DES CORRESPONDANCES TOTALES ------------------- */
+
+
+/* Initialise un suivi de trouvailles pour un premier motif. */
+static full_match_tracker_t *create_full_match_tracker(GSearchPattern *);
+
+/* Termine le suivi de trouvailles pour un motif. */
+static void delete_full_match_tracker(full_match_tracker_t *);
+
+/* Etablit la comparaison entre deux structures de suivi. */
+static int compare_full_match_trackers(const full_match_tracker_t **, const full_match_tracker_t **);
+
+/* Note l'existence d'une nouvelle correspondance pour un motif. */
+static void add_match_to_full_match_tracker(full_match_tracker_t *, GScanMatch *);
+
+
+
@@ -47,6 +72,131 @@ static void g_scan_context_finalize(GScanContext *);
+
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* ADMINISTRATION DES CORRESPONDANCES TOTALES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : pattern = motif de recherche trouvé. *
+* *
+* Description : Initialise un suivi de trouvailles pour un premier motif. *
+* *
+* Retour : Structure de suivi mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static full_match_tracker_t *create_full_match_tracker(GSearchPattern *pattern)
+{
+ full_match_tracker_t *result; /* Structure à retourner */
+
+ result = malloc(sizeof(full_match_tracker_t));
+
+ result->pattern = pattern;
+ g_object_ref(G_OBJECT(pattern));
+
+ result->matches = malloc(ALLOCATION_STEP * sizeof(GScanMatch *));
+ result->allocated = ALLOCATION_STEP;
+ result->used = 0;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : tracker = structure de gestion à manipuler. *
+* *
+* Description : Termine le suivi de trouvailles pour un motif. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void delete_full_match_tracker(full_match_tracker_t *tracker)
+{
+ size_t i; /* Boucle de parcours */
+
+ g_object_unref(G_OBJECT(tracker->pattern));
+
+ for (i = 0; i < tracker->used; i++)
+ g_object_unref(G_OBJECT(tracker->matches[i]));
+
+ free(tracker->matches);
+
+ free(tracker);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : a = première structure de suivi à consulter. *
+* b = seconde structure de suivi à consulter. *
+* *
+* Description : Etablit la comparaison entre deux structures de suivi. *
+* *
+* Retour : Bilan : -1 (a < b), 0 (a == b) ou 1 (a > b). *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int compare_full_match_trackers(const full_match_tracker_t **a, const full_match_tracker_t **b)
+{
+ int result; /* Bilan à renvoyer */
+
+ result = sort_unsigned_long((unsigned long)(*a)->pattern, (unsigned long)(*b)->pattern);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : tracker = structure de gestion à manipuler. *
+* match = correspondance complète établie. *
+* *
+* Description : Note l'existence d'une nouvelle correspondance pour un motif.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void add_match_to_full_match_tracker(full_match_tracker_t *tracker, GScanMatch *match)
+{
+ if (tracker->used == tracker->allocated)
+ {
+ tracker->allocated += ALLOCATION_STEP;
+ tracker->matches = realloc(tracker->matches, tracker->allocated * sizeof(GScanMatch *));
+ }
+
+ tracker->matches[tracker->used++] = match;
+ g_object_ref(G_OBJECT(match));
+
+}
+
+
+
+
+
+
+
+
+
/* Indique le type défini pour un contexte de suivi d'analyse. */
G_DEFINE_TYPE(GScanContext, g_scan_context, G_TYPE_OBJECT);
@@ -97,9 +247,8 @@ static void g_scan_context_init(GScanContext *context)
context->atom_trackers = NULL;
- context->full_matches = NULL;
- context->full_allocated = 0;
- context->full_used = 0;
+ context->full_trackers = NULL;
+ context->full_count = 0;
context->conditions = NULL;
context->cond_count = 0;
@@ -127,8 +276,12 @@ static void g_scan_context_dispose(GScanContext *context)
g_clear_object(&context->content);
- for (i = 0; i < context->full_used; i++)
- g_clear_object(&context->full_matches[i]);
+ for (i = 0; i < context->full_count; i++)
+ if (context->full_trackers[i] != NULL)
+ {
+ delete_full_match_tracker(context->full_trackers[i]);
+ context->full_trackers[i] = NULL;
+ }
for (i = 0; i < context->cond_count; i++)
g_clear_object(&context->conditions[i].expr);
@@ -170,8 +323,8 @@ static void g_scan_context_finalize(GScanContext *context)
}
- if (context->full_matches != NULL)
- free(context->full_matches);
+ if (context->full_trackers != NULL)
+ free(context->full_trackers);
if (context->conditions != NULL)
{
@@ -387,14 +540,75 @@ const phys_t *g_scan_context_get_atom_matches(const GScanContext *context, patid
void g_scan_context_register_full_match(GScanContext *context, GScanMatch *match)
{
- if (context->full_used == context->full_allocated)
+ GSearchPattern *pattern; /* Clef d'un suivi */
+ full_match_tracker_t key; /* Modèle d'identification */
+ full_match_tracker_t **found; /* Structure à actualiser */
+ full_match_tracker_t *tracker; /* Nouveau suivi à intégrer */
+
+ pattern = g_scan_match_get_source(match);
+
+ key.pattern = pattern;
+
+ found = bsearch((full_match_tracker_t *[]) { &key }, context->full_trackers, context->full_count,
+ sizeof(full_match_tracker_t *), (__compar_fn_t)compare_full_match_trackers);
+
+ if (found == NULL)
{
- context->full_allocated += ALLOCATION_STEP;
- context->full_matches = realloc(context->full_matches, context->full_allocated * sizeof(GScanMatch *));
+ tracker = create_full_match_tracker(pattern);
+
+ context->full_trackers = qinsert(context->full_trackers, &context->full_count,
+ sizeof(full_match_tracker_t *),
+ (__compar_fn_t)compare_full_match_trackers, &tracker);
+
}
+ else
+ tracker = *found;
- context->full_matches[context->full_used++] = match;
- g_object_ref(G_OBJECT(match));
+ add_match_to_full_match_tracker(tracker, match);
+
+ g_object_unref(G_OBJECT(pattern));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : context = instance à mettre à jour. *
+* pattern = motif dont des correspondances sont à retrouver. *
+* count = quantité de correspondances enregistrées. [OUT] *
+* *
+* Description : Fournit la liste de toutes les correspondances d'un motif. *
+* *
+* Retour : Liste courante de correspondances établies. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const GScanMatch **g_scan_context_get_full_matches(const GScanContext *context, const GSearchPattern *pattern, size_t *count)
+{
+ GScanMatch **result; /* Correspondance à renvoyer */
+ full_match_tracker_t key; /* Modèle d'identification */
+ full_match_tracker_t **found; /* Structure à actualiser */
+
+ key.pattern = pattern;
+
+ found = bsearch((full_match_tracker_t *[]) { &key }, context->full_trackers, context->full_count,
+ sizeof(full_match_tracker_t *), (__compar_fn_t)compare_full_match_trackers);
+
+ if (found == NULL)
+ {
+ result = NULL;
+ count = 0;
+ }
+
+ else
+ {
+ result = (*found)->matches;
+ *count = (*found)->used;
+ }
+
+ return result;
}
@@ -411,12 +625,25 @@ void g_scan_context_register_full_match(GScanContext *context, GScanMatch *match
* *
******************************************************************************/
-void g_scan_context_display(const GScanContext *context)
+void g_scan_context_display(GScanContext *context)
{
size_t i; /* Boucle de parcours */
+ const rule_condition_t *cond; /* Conditions de orrespondance */
+ /*
+ FIXME : ordre
for (i = 0; i < context->full_used; i++)
g_scan_match_display(context->full_matches[i]);
+ */
+
+ for (i = 0; i < context->cond_count; i++)
+ {
+ cond = &context->conditions[i];
+
+ if (g_scan_context_has_match_for_rule(context, cond->name))
+ fprintf(stderr, "Rule '%s' has matched!\n", cond->name);
+
+ }
}
@@ -445,7 +672,7 @@ bool g_scan_context_set_rule_condition(GScanContext *context, const char *name,
/* Recherche d'antécédent */
- for (i = 0; context->cond_count; i++)
+ for (i = 0; i < context->cond_count; i++)
if (strcmp(name, context->conditions[i].name) == 0)
{
result = false;
@@ -461,8 +688,10 @@ bool g_scan_context_set_rule_condition(GScanContext *context, const char *name,
new = &context->conditions[context->cond_count - 1];
new->name = strdup(name);
+ new->name_hash = fnv_64a_hash(name);
- new->expr = g_scan_expression_duplicate(expr);
+ new->expr = expr;//g_scan_expression_duplicate(expr);
+ g_object_ref(G_OBJECT(expr)); // FIXME => REMME dup()
new->final_reduced = false;
}
@@ -477,6 +706,50 @@ bool g_scan_context_set_rule_condition(GScanContext *context, const char *name,
* Paramètres : context = mémoire de résultats d'analyse à consulter. *
* name = désignation de la règle ciblée. *
* *
+* Description : Indique si un nom donné correspond à une règle. *
+* *
+* Retour : Bilan de la présence d'une règle désignée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_scan_context_has_rule_for_name(const GScanContext *context, const char *name)
+{
+ bool result; /* Bilan à retourner */
+ fnv64_t hash; /* Empreinte du nom à retrouver*/
+ size_t i; /* Boucle de parcours */
+ const rule_condition_t *cond; /* Condition connue du contexte*/
+
+ result = false;
+
+ hash = fnv_64a_hash(name);
+
+ for (i = 0; i < context->cond_count; i++)
+ {
+ cond = context->conditions + i;
+
+ if (cond->name_hash != hash)
+ continue;
+
+ if (strcmp(cond->name, name) == 0)
+ {
+ result = true;
+ break;
+ }
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* 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. *
* *
* Retour : Bilan final d'une analyse (false par défaut). *
@@ -513,21 +786,27 @@ bool g_scan_context_has_match_for_rule(GScanContext *context, const char *name)
if (!cond->final_reduced)
{
- cond->final_reduced = g_scan_expression_reduce(cond->expr, context, NULL, &new);
+ valid = g_scan_expression_reduce(cond->expr, context, NULL, &new);
+ if (!valid || new == NULL) goto exit;
- if (cond->final_reduced && new != NULL)
- {
- g_object_unref(G_OBJECT(cond->expr));
- cond->expr = new;
- }
+ 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;
+
+ g_object_unref(G_OBJECT(cond->expr));
+ cond->expr = new;
+
+ cond->final_reduced = true;
}
/* Tentative de récupération d'un bilan final */
- if (G_IS_LITERAL_EXPRESSION(cond->expr))
+ if (cond->final_reduced)
{
- valid = g_literal_expression_get_boolean_value(G_LITERAL_EXPRESSION(cond->expr), &result);
+ valid = g_scan_literal_expression_get_boolean_value(G_SCAN_LITERAL_EXPRESSION(cond->expr), &result);
if (!valid)
{