diff options
Diffstat (limited to 'src/analysis/scan/context.c')
| -rw-r--r-- | src/analysis/scan/context.c | 441 |
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; } |
