diff options
Diffstat (limited to 'src/analysis/scan/context.c')
-rw-r--r-- | src/analysis/scan/context.c | 374 |
1 files changed, 74 insertions, 300 deletions
diff --git a/src/analysis/scan/context.c b/src/analysis/scan/context.c index 94ea519..55311c4 100644 --- a/src/analysis/scan/context.c +++ b/src/analysis/scan/context.c @@ -32,32 +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 **); - -/* Prépare l'intégration d'une série de correspondances. */ -static void prepare_full_match_tracker(full_match_tracker_t *, size_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 --------------------- */ @@ -76,145 +56,6 @@ 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. * -* expected = quantité totale de correspondances attendue. * -* * -* Description : Prépare l'intégration d'une série de correspondances. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void prepare_full_match_tracker(full_match_tracker_t *tracker, size_t expected) -{ - if ((tracker->used + expected) > tracker->allocated) - { - tracker->allocated += expected; - tracker->matches = realloc(tracker->matches, tracker->allocated * sizeof(GScanMatch *)); - } - -} - - -/****************************************************************************** -* * -* 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)); - -} - - - -/* ---------------------------------------------------------------------------------- */ /* MEMORISATION DE PROGRESSIONS D'ANALYSE */ /* ---------------------------------------------------------------------------------- */ @@ -266,13 +107,10 @@ 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_storages = NULL; + context->storages_count = 0; - context->full_trackers = NULL; - context->full_count = 0; - context->current_tracker = NULL; + context->full_trackers = g_hash_table_new_full(NULL, NULL, g_object_unref, g_object_unref); context->global = true; @@ -302,12 +140,14 @@ static void g_scan_context_dispose(GScanContext *context) 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; - } + for (i = 0; i < context->storages_count; i++) + g_clear_object(&context->match_storages[i]); + + if (context->full_trackers != NULL) + { + g_hash_table_destroy(context->full_trackers); + context->full_trackers = NULL; + } for (i = 0; i < context->cond_count; i++) g_clear_object(&context->conditions[i].expr); @@ -332,25 +172,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) { @@ -419,31 +243,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. * * * @@ -453,15 +255,21 @@ 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) { + size_t i; /* Boucle de parcours */ + g_clear_object(&context->content); context->content = 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(GUMemSlice *)); + context->storages_count = ids_count; + + for (i = 0; i < ids_count; i++) + context->match_storages[i] = g_umem_slice_new(sizeof(match_area_t)); } @@ -536,30 +344,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. * +* count = nombre d'allocateurs en place. [OUT] * * * -* Description : Enregistre une correspondance partielle dans un contenu. * +* Description : Fournit la liste des allocateurs mémorisant des emplacements.* * * -* Retour : - * +* Retour : Liste des allocateurs assurant un suivi des correspondances. * * * * Remarques : - * * * ******************************************************************************/ -void g_scan_context_register_atom_match(GScanContext *context, patid_t id, phys_t offset) +GUMemSlice **g_scan_context_get_match_storages(GScanContext *context, size_t *count) { - atom_match_tracker_t *tracker; /* Gestionnaire concerné */ + GUMemSlice **result; /* Allocateur à renvoyer */ - tracker = &context->atom_trackers[id]; + result = context->match_storages; - if (tracker->used == tracker->allocated) - { - tracker->allocated += ALLOCATION_STEP; - tracker->matches = realloc(tracker->matches, tracker->allocated * sizeof(phys_t)); - } + *count = context->storages_count; - tracker->matches[tracker->used++] = offset; + return result; } @@ -568,7 +371,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. * * * @@ -578,15 +380,13 @@ 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) +GUMemSlice *g_scan_context_get_atom_matches(const GScanContext *context, patid_t id) { - const phys_t *result; /* Liste constituée à renvoyer */ - atom_match_tracker_t *tracker; /* Gestionnaire concerné */ + GUMemSlice *result; /* Liste constituée à renvoyer */ - tracker = &context->atom_trackers[id]; + result = context->match_storages[id]; - result = tracker->matches; - *count = tracker->used; + g_object_ref(G_OBJECT(result)); return result; @@ -595,11 +395,11 @@ const phys_t *g_scan_context_get_atom_matches(const GScanContext *context, patid /****************************************************************************** * * -* Paramètres : context = instance à mettre à jour. * -* match = représentation d'une plein ecorrespondance. * -* expected = quantité totale de correspondances attendue. * +* Paramètres : context = instance à mettre à jour. * +* pattern = definition initiale d'un motif recherché. * +* matches = mémorisation de correspondances établies. * * * -* Description : Prépare les enregistrements de correspondances complètes. * +* Description : Enregistre toutes les correspondances établies pour un motif.* * * * Retour : - * * * @@ -607,32 +407,28 @@ const phys_t *g_scan_context_get_atom_matches(const GScanContext *context, patid * * ******************************************************************************/ -void g_scan_context_prepare_full_match_registration(GScanContext *context, GSearchPattern *pattern, size_t expected) +void g_scan_context_register_full_matches(GScanContext *context, GSearchPattern *pattern, GScanMatches *matches) { - 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 - key.pattern = pattern; + assert(!g_hash_table_contains(context->full_trackers, 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); +#ifndef NDEBUG - if (found == NULL) - { - tracker = create_full_match_tracker(pattern); + matches_pattern = g_scan_matches_get_source(matches); - context->full_trackers = qinsert(context->full_trackers, &context->full_count, - sizeof(full_match_tracker_t *), - (__compar_fn_t)compare_full_match_trackers, &tracker); + assert(matches_pattern == pattern); - } - else - tracker = *found; + g_object_unref(G_OBJECT(matches_pattern)); - prepare_full_match_tracker(tracker, expected); +#endif - context->current_tracker = tracker; + g_object_ref(G_OBJECT(pattern)); + g_object_ref(G_OBJECT(matches)); + + g_hash_table_insert(context->full_trackers, pattern, matches); } @@ -640,36 +436,26 @@ void g_scan_context_prepare_full_match_registration(GScanContext *context, GSear /****************************************************************************** * * * Paramètres : context = instance à mettre à jour. * -* match = représentation d'une plein ecorrespondance. * +* pattern = motif dont des correspondances sont à retrouver. * * * -* Description : Enregistre une correspondance complète avec un contenu. * +* Description : Fournit la liste de toutes les correspondances pour un motif.* * * -* Retour : - * +* Retour : Liste courante de correspondances établies. * * * * Remarques : - * * * ******************************************************************************/ -void g_scan_context_register_full_match(GScanContext *context, GScanMatch *match) +GScanMatches *g_scan_context_get_full_matches(const GScanContext *context, const GSearchPattern *pattern) { -#ifndef NDEBUG - GSearchPattern *pattern; /* Clef d'un suivi */ -#endif - - assert(context->current_tracker != NULL); - -#ifndef NDEBUG - - pattern = g_scan_match_get_source(match); + GScanMatches *result; /* Correspondance à renvoyer */ - assert(context->current_tracker->pattern == pattern); + result = g_hash_table_lookup(context->full_trackers, pattern); - g_object_unref(G_OBJECT(pattern)); + if (result != NULL) + g_object_ref(G_OBJECT(result)); - -#endif - - add_match_to_full_match_tracker(context->current_tracker, match); + return result; } @@ -678,38 +464,26 @@ 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 : Dénombre les correspondances associées à un motif. * * * -* Retour : Liste courante de correspondances établies. * +* Retour : Quantité de correspondances établies pour un motif entier. * * * * Remarques : - * * * ******************************************************************************/ -const GScanMatch **g_scan_context_get_full_matches(const GScanContext *context, const GSearchPattern *pattern, size_t *count) +size_t g_scan_context_count_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 */ - - key.pattern = pattern; + size_t result; /* Quantité à retourner */ + GScanMatches *matches; /* Ensemble de Correspondances */ - 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; - } + matches = g_hash_table_lookup(context->full_trackers, pattern); + if (matches != NULL) + result = g_scan_bytes_matches_count(matches); else - { - result = (*found)->matches; - *count = (*found)->used; - } + result = 0; return result; |