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.c441
1 files changed, 200 insertions, 241 deletions
diff --git a/src/analysis/scan/context.c b/src/analysis/scan/context.c
index 8a9b600..7929f9c 100644
--- a/src/analysis/scan/context.c
+++ b/src/analysis/scan/context.c
@@ -32,29 +32,12 @@
#include "context-int.h"
#include "exprs/literal.h"
+#include "matches/area.h"
+#include "matches/bytes.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 *);
-
-
-
/* --------------------- MEMORISATION DE PROGRESSIONS D'ANALYSE --------------------- */
@@ -70,120 +53,12 @@ static void g_scan_context_dispose(GScanContext *);
/* Procède à la libération totale de la mémoire. */
static void g_scan_context_finalize(GScanContext *);
+#ifndef __USE_TABLE_FOR_MATCHES
+/* Compare un lien entre motif et correspondances avec un autre. */
+static int compare_matched_pattern(const matched_pattern_t *, const matched_pattern_t *);
-/* ---------------------------------------------------------------------------------- */
-/* 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));
-
-}
+#endif
@@ -239,12 +114,17 @@ static void g_scan_context_init(GScanContext *context)
context->content = NULL;
context->scan_done = false;
- context->next_patid = 0;
-
- context->atom_trackers = NULL;
+ context->match_allocator = g_umem_slice_new(sizeof(match_area_t));
+ context->match_storages = NULL;
+ context->storages_count = 0;
+#ifdef __USE_TABLE_FOR_MATCHES
+ context->full_trackers = g_hash_table_new_full(NULL, NULL, NULL/*g_object_unref*/, g_object_unref);
+#else
context->full_trackers = NULL;
+ context->full_allocated = 0;
context->full_count = 0;
+#endif
context->global = true;
@@ -268,18 +148,39 @@ static void g_scan_context_init(GScanContext *context)
static void g_scan_context_dispose(GScanContext *context)
{
- size_t i; /* Boucle de parcours */
+#ifndef __USE_TABLE_FOR_MATCHES
+ matched_pattern_t *iter; /* Boucle de parcours #1 */
+ matched_pattern_t *max; /* Borne de fin de parcours */
+#endif
+ size_t i; /* Boucle de parcours #2 */
g_clear_object(&context->options);
g_clear_object(&context->content);
- 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;
- }
+ g_clear_object(&context->match_allocator);
+
+ if (context->full_trackers != NULL)
+ {
+#ifdef __USE_TABLE_FOR_MATCHES
+
+ g_hash_table_destroy(context->full_trackers);
+ context->full_trackers = NULL;
+
+#else
+
+ iter = context->full_trackers;
+ max = iter + context->full_count;
+
+ for (; iter < max; iter++)
+ g_object_unref(G_OBJECT(iter->matches));
+
+ free(context->full_trackers);
+ context->full_trackers = NULL;
+
+#endif
+
+ }
for (i = 0; i < context->cond_count; i++)
g_clear_object(&context->conditions[i].expr);
@@ -304,25 +205,9 @@ static void g_scan_context_dispose(GScanContext *context)
static void g_scan_context_finalize(GScanContext *context)
{
size_t i; /* Boucle de parcours */
- atom_match_tracker_t *atracker; /* Conservateur à manipuler #1 */
- if (context->atom_trackers != NULL)
- {
- for (i = 0; i < context->next_patid; i++)
- {
- atracker = context->atom_trackers + i;
-
- if (atracker->matches != NULL)
- free(atracker->matches);
-
- }
-
- free(context->atom_trackers);
-
- }
-
- if (context->full_trackers != NULL)
- free(context->full_trackers);
+ if (context->match_storages != NULL)
+ free(context->match_storages);
if (context->conditions != NULL)
{
@@ -391,31 +276,9 @@ GScanOptions *g_scan_context_get_options(const GScanContext *context)
/******************************************************************************
* *
-* Paramètres : context = instance à consulter. *
-* *
-* Description : Fournit un identifiant unique pour un motif recherché. *
-* *
-* Retour : Identifiant nouveau à utiliser. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-patid_t g_scan_context_get_new_pattern_id(GScanContext *context)
-{
- patid_t result; /* Identifiant à retourner */
-
- result = context->next_patid++;
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : context = instance à consulter. *
-* content = contenu binaire en cours d'analyse. *
+* Paramètres : context = instance à consulter. *
+* content = contenu binaire en cours d'analyse. *
+* ids_count = nombre d'identifiants enregistrés. *
* *
* Description : Définit le contenu principal à analyser. *
* *
@@ -425,7 +288,7 @@ patid_t g_scan_context_get_new_pattern_id(GScanContext *context)
* *
******************************************************************************/
-void g_scan_context_set_content(GScanContext *context, GBinContent *content)
+void g_scan_context_set_content(GScanContext *context, GBinContent *content, size_t ids_count)
{
g_clear_object(&context->content);
@@ -433,7 +296,8 @@ void g_scan_context_set_content(GScanContext *context, GBinContent *content)
g_object_ref(G_OBJECT(content));
- context->atom_trackers = calloc(context->next_patid, sizeof(atom_match_tracker_t));
+ context->match_storages = calloc(ids_count, sizeof(match_area_t *));
+ context->storages_count = ids_count;
}
@@ -509,29 +373,25 @@ void g_scan_context_mark_scan_as_done(GScanContext *context)
* *
* Paramètres : context = instance à mettre à jour. *
* id = identifiant du motif trouvé. *
-* offset = localisation du motif au sein d'un contenu. *
+* end = position finale d'une correspondance partielle. *
* *
-* Description : Enregistre une correspondance partielle dans un contenu. *
+* Description : Retourne tous les correspondances partielles notées. *
* *
-* Retour : - *
+* Retour : Liste interne des localisations conservées. *
* *
* Remarques : - *
* *
******************************************************************************/
-void g_scan_context_register_atom_match(GScanContext *context, patid_t id, phys_t offset)
+void g_scan_context_store_atom_match_end(GScanContext *context, patid_t id, phys_t end)
{
- atom_match_tracker_t *tracker; /* Gestionnaire concerné */
+ match_area_t *new; /* Nouvel enregistrement */
- tracker = &context->atom_trackers[id];
+ new = g_umem_slice_alloc(context->match_allocator);
- if (tracker->used == tracker->allocated)
- {
- tracker->allocated += ALLOCATION_STEP;
- tracker->matches = realloc(tracker->matches, tracker->allocated * sizeof(phys_t));
- }
+ new->end = end + 1;
- tracker->matches[tracker->used++] = offset;
+ add_tail_match_area(new, &context->match_storages[id]);
}
@@ -540,7 +400,6 @@ void g_scan_context_register_atom_match(GScanContext *context, patid_t id, phys_
* *
* Paramètres : context = instance à mettre à jour. *
* id = identifiant du motif trouvé. *
-* count = nombre de localisations renvoyées. [OUT] *
* *
* Description : Retourne tous les correspondances partielles notées. *
* *
@@ -550,27 +409,54 @@ void g_scan_context_register_atom_match(GScanContext *context, patid_t id, phys_
* *
******************************************************************************/
-const phys_t *g_scan_context_get_atom_matches(const GScanContext *context, patid_t id, size_t *count)
+match_area_t *g_scan_context_get_atom_matches(const GScanContext *context, patid_t id)
+{
+ match_area_t *result; /* Liste constituée à renvoyer */
+
+ result = context->match_storages[id];
+
+ return result;
+
+}
+
+
+#ifndef __USE_TABLE_FOR_MATCHES
+
+/******************************************************************************
+* *
+* Paramètres : a = premier lien motif/correspondances à comparer. *
+* b = second lien motif/correspondances à comparer. *
+* *
+* Description : Compare un lien entre motif et correspondances avec un autre.*
+* *
+* Retour : Bilan de la comparaison. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int compare_matched_pattern(const matched_pattern_t *a, const matched_pattern_t *b)
{
- const phys_t *result; /* Liste constituée à renvoyer */
- atom_match_tracker_t *tracker; /* Gestionnaire concerné */
+ int result; /* Bilan à renvoyer */
- tracker = &context->atom_trackers[id];
+ assert(sizeof(unsigned long) == sizeof(void *));
- result = tracker->matches;
- *count = tracker->used;
+ result = sort_unsigned_long((unsigned long)a->pattern, (unsigned long)b->pattern);
return result;
}
+#endif
+
/******************************************************************************
* *
* Paramètres : context = instance à mettre à jour. *
-* match = représentation d'une plein ecorrespondance. *
+* pattern = definition initiale d'un motif recherché. *
+* matches = mémorisation de correspondances établies. *
* *
-* Description : Enregistre une correspondance complète avec un contenu. *
+* Description : Enregistre toutes les correspondances établies pour un motif.*
* *
* Retour : - *
* *
@@ -578,35 +464,48 @@ const phys_t *g_scan_context_get_atom_matches(const GScanContext *context, patid
* *
******************************************************************************/
-void g_scan_context_register_full_match(GScanContext *context, GScanMatch *match)
+void g_scan_context_register_full_matches(GScanContext *context, GSearchPattern *pattern, GScanMatches *matches)
{
- 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 */
+#ifndef NDEBUG
+ GSearchPattern *matches_pattern; /* Clef d'un suivi */
+#endif
+#ifndef __USE_TABLE_FOR_MATCHES
+ matched_pattern_t new; /* Nouvel enregistrement */
+#endif
- pattern = g_scan_match_get_source(match);
+#ifndef NDEBUG
- key.pattern = pattern;
+ matches_pattern = g_scan_matches_get_source(matches);
- 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);
+ assert(matches_pattern == pattern);
- if (found == NULL)
- {
- tracker = create_full_match_tracker(pattern);
+ g_object_unref(G_OBJECT(matches_pattern));
- context->full_trackers = qinsert(context->full_trackers, &context->full_count,
- sizeof(full_match_tracker_t *),
- (__compar_fn_t)compare_full_match_trackers, &tracker);
+#endif
- }
- else
- tracker = *found;
+#ifdef __USE_TABLE_FOR_MATCHES
+
+ assert(!g_hash_table_contains(context->full_trackers, pattern));
+
+ //g_object_ref(G_OBJECT(pattern)); /* TODO : REMME */
+ g_object_ref(G_OBJECT(matches));
+
+ g_hash_table_insert(context->full_trackers, pattern, matches);
+
+#else
+
+ new.pattern = pattern;
+ new.matches = matches;
- add_match_to_full_match_tracker(tracker, match);
+ g_object_ref(G_OBJECT(matches));
- g_object_unref(G_OBJECT(pattern));
+ context->full_trackers = qinsert_managed(context->full_trackers, &context->full_count, &context->full_allocated,
+ sizeof(matched_pattern_t), (__compar_fn_t)compare_matched_pattern,
+ &new);
+
+#endif
+
+ g_scan_matches_attach(matches, context, pattern);
}
@@ -615,9 +514,8 @@ void g_scan_context_register_full_match(GScanContext *context, GScanMatch *match
* *
* 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. *
+* Description : Fournit la liste de toutes les correspondances pour un motif.*
* *
* Retour : Liste courante de correspondances établies. *
* *
@@ -625,29 +523,90 @@ void g_scan_context_register_full_match(GScanContext *context, GScanMatch *match
* *
******************************************************************************/
-const GScanMatch **g_scan_context_get_full_matches(const GScanContext *context, const GSearchPattern *pattern, size_t *count)
+GScanMatches *g_scan_context_get_full_matches(const GScanContext *context, const GSearchPattern *pattern)
{
- GScanMatch **result; /* Correspondance à renvoyer */
- full_match_tracker_t key; /* Modèle d'identification */
- full_match_tracker_t **found; /* Structure à actualiser */
+ GScanMatches *result; /* Correspondance à renvoyer */
+#ifndef __USE_TABLE_FOR_MATCHES
+ matched_pattern_t target; /* Lien ciblé */
+ matched_pattern_t *found; /* Lien trouvé */
+#endif
+
+#ifdef __USE_TABLE_FOR_MATCHES
+
+ result = g_hash_table_lookup(context->full_trackers, pattern);
- key.pattern = pattern;
+ if (result != NULL)
+ g_object_ref(G_OBJECT(result));
- 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);
+#else
+
+ target.pattern = pattern;
+
+ found = bsearch(&target, context->full_trackers, context->full_count,
+ sizeof(matched_pattern_t), (__compar_fn_t)compare_matched_pattern);
if (found == NULL)
- {
result = NULL;
- *count = 0;
- }
else
{
- result = (*found)->matches;
- *count = (*found)->used;
+ result = found->matches;
+ g_object_ref(G_OBJECT(result));
}
+#endif
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : context = instance à mettre à jour. *
+* pattern = motif dont des correspondances sont à retrouver. *
+* *
+* Description : Dénombre les correspondances associées à un motif. *
+* *
+* Retour : Quantité de correspondances établies pour un motif entier. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+size_t g_scan_context_count_full_matches(const GScanContext *context, const GSearchPattern *pattern)
+{
+ size_t result; /* Quantité à retourner */
+#ifdef __USE_TABLE_FOR_MATCHES
+ GScanMatches *matches; /* Ensemble de Correspondances */
+#else
+ matched_pattern_t target; /* Lien ciblé */
+ matched_pattern_t *found; /* Lien trouvé */
+#endif
+
+#ifdef __USE_TABLE_FOR_MATCHES
+
+ matches = g_hash_table_lookup(context->full_trackers, pattern);
+
+ if (matches != NULL)
+ result = g_scan_matches_count(matches);
+ else
+ result = 0;
+
+#else
+
+ target.pattern = pattern;
+
+ found = bsearch(&target, context->full_trackers, context->full_count,
+ sizeof(matched_pattern_t), (__compar_fn_t)compare_matched_pattern);
+
+ if (found == NULL)
+ result = 0;
+ else
+ result = g_scan_matches_count(found->matches);
+
+#endif
+
return result;
}