From 26f93f593542cc550107744e92f95e9516e7435e Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Tue, 20 Feb 2024 09:11:17 +0100 Subject: Share GObject instances between scan contexts and matches. --- src/analysis/scan/context.c | 2 + src/analysis/scan/matches-int.h | 8 ++- src/analysis/scan/matches.c | 55 +++++++++++++++++++- src/analysis/scan/matches.h | 6 +++ src/analysis/scan/matches/bytes-int.h | 10 ---- src/analysis/scan/matches/bytes.c | 98 ++++------------------------------- src/analysis/scan/matches/bytes.h | 5 +- src/analysis/scan/patterns/token.c | 66 +++++++++-------------- src/analysis/scan/patterns/token.h | 2 +- src/analysis/scan/rule.c | 26 ++++++++-- 10 files changed, 127 insertions(+), 151 deletions(-) diff --git a/src/analysis/scan/context.c b/src/analysis/scan/context.c index 55311c4..fc4194b 100644 --- a/src/analysis/scan/context.c +++ b/src/analysis/scan/context.c @@ -430,6 +430,8 @@ void g_scan_context_register_full_matches(GScanContext *context, GSearchPattern g_hash_table_insert(context->full_trackers, pattern, matches); + g_scan_matches_attach(matches, context, pattern); + } diff --git a/src/analysis/scan/matches-int.h b/src/analysis/scan/matches-int.h index 674fe03..4e6a244 100644 --- a/src/analysis/scan/matches-int.h +++ b/src/analysis/scan/matches-int.h @@ -44,7 +44,13 @@ struct _GScanMatches { GObject parent; /* A laisser en premier */ - GSearchPattern *source; /* Motif d'origine recherché */ + /** + * L'aspect constant des instances marque seulement le fait que les + * pointeurs sont partagés avec un contexte, qui est le réel propriétaire + * de ces instances. + */ + const GScanContext *context; /* Contexte de rattachement */ + const GSearchPattern *source; /* Motif d'origine recherché */ }; diff --git a/src/analysis/scan/matches.c b/src/analysis/scan/matches.c index 3dc15f9..d83114c 100644 --- a/src/analysis/scan/matches.c +++ b/src/analysis/scan/matches.c @@ -84,6 +84,7 @@ static void g_scan_matches_class_init(GScanMatchesClass *klass) static void g_scan_matches_init(GScanMatches *matches) { + matches->context = NULL; matches->source = NULL; } @@ -103,7 +104,10 @@ static void g_scan_matches_init(GScanMatches *matches) static void g_scan_matches_dispose(GScanMatches *matches) { - g_clear_object(&matches->source); + /** + * Contexte et source sont des instances partagées. Leur propriété n'est + * donc pas à modifier avec un appel à g_clear_object() ici. + */ G_OBJECT_CLASS(g_scan_matches_parent_class)->dispose(G_OBJECT(matches)); @@ -131,6 +135,53 @@ static void g_scan_matches_finalize(GScanMatches *matches) /****************************************************************************** * * +* Paramètres : matches = instance dont l'initialisation est à compléter. * +* context = contexte associé au scan courant. * +* source = lien vers le motif recherché d'origine. * +* * +* Description : Associe des éléments de contexte à des correspondances. * +* * +* Retour : - * +* * +* Remarques : Aucun transfert de propriété n'a lieu ici ! * +* * +******************************************************************************/ + +void g_scan_matches_attach(GScanMatches *matches, const GScanContext *context, const GSearchPattern *source) +{ + matches->context = context; + matches->source = source; + +} + + +/****************************************************************************** +* * +* Paramètres : matches = informations de correspondances à consulter. * +* * +* Description : Fournit le contexte du scan associé aux correspondances. * +* * +* Retour : Contexte de scan courant. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GScanContext *g_scan_bytes_matches_get_context(const GScanMatches *matches) +{ + GScanContext *result; /* Instance à retourner */ + + result = (GScanContext *)matches->context; + + g_object_ref(G_OBJECT(result)); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : matches = définition de correspondance à consulter. * * * * Description : Indique la source du motif d'origine recherché. * @@ -145,7 +196,7 @@ GSearchPattern *g_scan_matches_get_source(const GScanMatches *matches) { GSearchPattern *result; /* Source à retourner */ - result = matches->source; + result = (GSearchPattern *)matches->source; g_object_ref(G_OBJECT(result)); diff --git a/src/analysis/scan/matches.h b/src/analysis/scan/matches.h index 345db96..26e54ed 100644 --- a/src/analysis/scan/matches.h +++ b/src/analysis/scan/matches.h @@ -51,6 +51,12 @@ typedef struct _GScanMatchesClass GScanMatchesClass; /* Indique le type défini pour une série de correspondances identifiées. */ GType g_scan_matches_get_type(void); +/* Associe des éléments de contexte à des correspondances. */ +void g_scan_matches_attach(GScanMatches *, const GScanContext *, const GSearchPattern *); + +/* Fournit le contexte du scan associé aux correspondances. */ +GScanContext *g_scan_bytes_matches_get_context(const GScanMatches *); + /* Indique la source du motif d'origine recherché. */ GSearchPattern *g_scan_matches_get_source(const GScanMatches *); diff --git a/src/analysis/scan/matches/bytes-int.h b/src/analysis/scan/matches/bytes-int.h index d356208..f6239e3 100644 --- a/src/analysis/scan/matches/bytes-int.h +++ b/src/analysis/scan/matches/bytes-int.h @@ -37,12 +37,6 @@ struct _GScanBytesMatches { GScanMatches parent; /* A laisser en premier */ - GScanContext *context; /* Contexte de rattachement */ - - // TODO : if NDEBUG ? - phys_t content_start; /* Point de début du contenu */ - phys_t content_end; /* Point de fin du contenu */ - match_area_t *areas; /* Zones couvertes */ size_t count; /* Nombre de zones */ @@ -56,9 +50,5 @@ struct _GScanBytesMatchesClass }; -/* Met en place une série de correspondances avec des octets. */ -bool g_scan_bytes_matches_create(GScanBytesMatches *, GSearchPattern *, GScanContext *); - - #endif /* _ANALYSIS_SCAN_MATCHES_BYTES_INT_H */ diff --git a/src/analysis/scan/matches/bytes.c b/src/analysis/scan/matches/bytes.c index c4c43bc..218121d 100644 --- a/src/analysis/scan/matches/bytes.c +++ b/src/analysis/scan/matches/bytes.c @@ -117,11 +117,6 @@ static void g_scan_bytes_matches_class_init(GScanBytesMatchesClass *klass) static void g_scan_bytes_matches_init(GScanBytesMatches *matches) { - matches->context = NULL; - - matches->content_start = VMPA_NO_PHYSICAL; - matches->content_end = VMPA_NO_PHYSICAL; - matches->areas = NULL; matches->count = 0; @@ -142,8 +137,6 @@ static void g_scan_bytes_matches_init(GScanBytesMatches *matches) static void g_scan_bytes_matches_dispose(GScanBytesMatches *matches) { - //g_clear_object(&matches->context); - G_OBJECT_CLASS(g_scan_bytes_matches_parent_class)->dispose(G_OBJECT(matches)); } @@ -170,8 +163,7 @@ static void g_scan_bytes_matches_finalize(GScanBytesMatches *matches) /****************************************************************************** * * -* Paramètres : source = lien vers le motif recherché d'origine. * -* context = contexte associé au scan courant. * +* Paramètres : - * * * * Description : Crée un suivi pour série de correspondances avec des octets. * * * @@ -181,87 +173,12 @@ static void g_scan_bytes_matches_finalize(GScanBytesMatches *matches) * * ******************************************************************************/ -GScanMatches *g_scan_bytes_matches_new(GSearchPattern *source, GScanContext *context) +GScanMatches *g_scan_bytes_matches_new(void) { GScanMatches *result; /* Structure à retourner */ result = g_object_new(G_TYPE_SCAN_BYTES_MATCHES, NULL); - if (!g_scan_bytes_matches_create(G_SCAN_BYTES_MATCHES(result), source, context)) - g_clear_object(&result); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : matches = instance à initialiser pleinement. * -* source = lien vers le motif recherché d'origine. * -* context = contexte associé au scan courant. * -* * -* Description : Met en place une série de correspondances avec des octets. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_scan_bytes_matches_create(GScanBytesMatches *matches, GSearchPattern *source, GScanContext *context) -{ - bool result; /* Bilan à retourner */ - GScanMatches *base; /* Lien vers les infos de base */ - GBinContent *content; /* Contenu à manipuler */ - vmpa2t start; /* Point de début du contenu */ - vmpa2t end; /* Point de fin du contenu */ - - result = true; - - base = G_SCAN_MATCHES(matches); - - base->source = source; - g_object_ref(G_OBJECT(source)); - - matches->context = context; - //g_object_ref(G_OBJECT(context)); - - content = g_scan_context_get_content(context); - - g_binary_content_compute_start_pos(content, &start); - g_binary_content_compute_end_pos(content, &end); - - matches->content_start = start.physical; - matches->content_end = end.physical; - - g_object_unref(G_OBJECT(content)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : matches = informations de correspondances à consulter. * -* * -* Description : Fournit le contexte du scan associé aux correspondances. * -* * -* Retour : Contexte de scan courant. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GScanContext *g_scan_bytes_matches_get_context(const GScanBytesMatches *matches) -{ - GScanContext *result; /* Instance à retourner */ - - result = matches->context; - - g_object_ref(G_OBJECT(result)); - return result; } @@ -433,8 +350,8 @@ char *g_scan_bytes_matches_get_modifier_path(const GScanBytesMatches *matches) static void g_scan_bytes_matches_output_to_text(const GScanBytesMatches *matches, int fd) { - GBinContent *content; /* Contenu binaire analysé */ GScanMatches *base; /* Lien vers les infos de base */ + GBinContent *content; /* Contenu binaire analysé */ const char *name; /* Désignation du motif ciblé */ match_area_t *iter; /* Boucle de parcours #1 */ char value[2 + ULLONG_MAXLEN]; /* Impression de la position */ @@ -444,10 +361,10 @@ static void g_scan_bytes_matches_output_to_text(const GScanBytesMatches *matches const bin_t *data; /* Accès aux données brutes */ phys_t k; /* Boucle de parcours #2 */ - content = g_scan_context_get_content(matches->context); - base = G_SCAN_MATCHES(matches); + content = g_scan_context_get_content(base->context); + name = g_search_pattern_get_name(base->source); for_each_match_area(iter, matches->areas) @@ -547,6 +464,7 @@ static void g_scan_bytes_matches_output_to_json(const GScanBytesMatches *matches unsigned int i; /* Boucle de parcours #1 */ char value[4 + ULLONG_MAXLEN]; /* Impression de la position */ int ret; /* Bilan d'une conversion */ + GScanMatches *base; /* Lien vers les infos de base */ GBinContent *content; /* Contenu binaire analysé */ match_area_t *iter; /* Boucle de parcours #1 */ vmpa2t pos; /* Tête de lecture */ @@ -581,7 +499,9 @@ static void g_scan_bytes_matches_output_to_json(const GScanBytesMatches *matches write(fd, "\"matches\": [\n", 13); - content = g_scan_context_get_content(matches->context); + base = G_SCAN_MATCHES(matches); + + content = g_scan_context_get_content(base->context); for_each_match_area(iter, matches->areas) { diff --git a/src/analysis/scan/matches/bytes.h b/src/analysis/scan/matches/bytes.h index 9e046aa..50f60a4 100644 --- a/src/analysis/scan/matches/bytes.h +++ b/src/analysis/scan/matches/bytes.h @@ -56,10 +56,7 @@ typedef struct _GScanBytesMatchesClass GScanBytesMatchesClass; GType g_scan_bytes_matches_get_type(void); /* Crée un suivi pour série de correspondances avec des octets. */ -GScanMatches *g_scan_bytes_matches_new(GSearchPattern *, GScanContext *); - -/* Fournit le contexte du scan associé aux correspondances. */ -GScanContext *g_scan_bytes_matches_get_context(const GScanBytesMatches *); +GScanMatches *g_scan_bytes_matches_new(void); /* Intègre une liste de correspondances vérifiées. */ void g_scan_bytes_matches_set_list(GScanBytesMatches *, match_area_t *, size_t); diff --git a/src/analysis/scan/patterns/token.c b/src/analysis/scan/patterns/token.c index 76a5e66..b3c6d53 100644 --- a/src/analysis/scan/patterns/token.c +++ b/src/analysis/scan/patterns/token.c @@ -300,6 +300,7 @@ bool g_bytes_token_build_id(GBytesToken *token, GEngineBackend *backend) * * * Paramètres : token = définition de la bribe à manipuler. * * matches = suivi des correspondances à consolider. * +* params = paramètres des opérations de validation. * * * * Description : Transforme les correspondances locales en trouvailles. * * * @@ -309,83 +310,70 @@ bool g_bytes_token_build_id(GBytesToken *token, GEngineBackend *backend) * * ******************************************************************************/ -void g_bytes_token_check(const GBytesToken *token, GScanBytesMatches *matches) +void g_bytes_token_check(const GBytesToken *token, GScanBytesMatches *matches, scan_node_check_params_t *params) { - scan_node_check_params_t params; /* Rassemblement de paramètres */ - vmpa2t start; /* Point de début du contenu */ - vmpa2t end; /* Point de fin du contenu */ match_area_t *area; /* Correspondance à valider */ match_area_t *next; /* Correspondance suivante */ vmpa2t pos; /* Tête de lecture */ const bin_t *byte; /* Octet à valider */ - /* Définition d'un contexte */ + /* Réinitialisation */ - params.context = g_scan_bytes_matches_get_context(matches); - params.content = g_scan_context_get_content(params.context); - params.allocator = g_umem_slice_new(sizeof(match_area_t)); + // TODO: offset - g_binary_content_compute_start_pos(params.content, &start); - g_binary_content_compute_end_pos(params.content, &end); + params->initialized = false; - params.content_start = start.physical; - params.content_end = end.physical; + params->main_areas = NULL; + params->main_count = 0; - // offset + params->created_areas = NULL; + params->created_count = 0; - params.initialized = false; - - params.main_areas = NULL; - params.main_count = 0; - - params.created_areas = NULL; - params.created_count = 0; - - params.kept_areas = NULL; - params.kept_count = 0; + params->kept_areas = NULL; + params->kept_count = 0; /* Lancement des analyses */ - g_scan_token_node_check_forward(token->root, ¶ms); + g_scan_token_node_check_forward(token->root, params); if (token->need_backward) - g_scan_token_node_check_backward(token->root, ¶ms); + g_scan_token_node_check_backward(token->root, params); // REMME ? sort_and_filter_pending_matches(matches); if (token->fullword) { - for_each_match_area_safe(area, ¶ms.main_areas, next) + for_each_match_area_safe(area, ¶ms->main_areas, next) { /* Validation de l'octet précédent, s'il existe */ - if (area->start > params.content_start) + if (area->start > params->content_start) { init_vmpa(&pos, area->start - 1, VMPA_NO_VIRTUAL); - byte = g_binary_content_get_raw_access(params.content, &pos, 1); + byte = g_binary_content_get_raw_access(params->content, &pos, 1); if (isalnum(*byte)) { - del_match_area(area, ¶ms.main_areas); - assert(¶ms.main_count > 0); - params.main_count--; + del_match_area(area, ¶ms->main_areas); + assert(¶ms->main_count > 0); + params->main_count--; continue; } } /* Validation de l'octet suivant, s'il existe */ - if (area->end < params.content_end) + if (area->end < params->content_end) { init_vmpa(&pos, area->end, VMPA_NO_VIRTUAL); - byte = g_binary_content_get_raw_access(params.content, &pos, 1); + byte = g_binary_content_get_raw_access(params->content, &pos, 1); if (isalnum(*byte)) { - del_match_area(area, ¶ms.main_areas); - assert(¶ms.main_count > 0); - params.main_count--; + del_match_area(area, ¶ms->main_areas); + assert(¶ms->main_count > 0); + params->main_count--; continue; } @@ -395,11 +383,7 @@ void g_bytes_token_check(const GBytesToken *token, GScanBytesMatches *matches) } - g_scan_bytes_matches_set_list(matches, params.main_areas, params.main_count); - - g_object_unref(G_OBJECT(params.context)); - g_object_unref(G_OBJECT(params.content)); - //g_object_unref(G_OBJECT(params.allocator)); + g_scan_bytes_matches_set_list(matches, params->main_areas, params->main_count); } diff --git a/src/analysis/scan/patterns/token.h b/src/analysis/scan/patterns/token.h index 3bc5cb7..f5b78f6 100644 --- a/src/analysis/scan/patterns/token.h +++ b/src/analysis/scan/patterns/token.h @@ -65,7 +65,7 @@ bool g_bytes_token_enroll(GBytesToken *, GEngineBackend *, size_t); bool g_bytes_token_build_id(GBytesToken *, GEngineBackend *); /* Transforme les correspondances locales en trouvailles. */ -void g_bytes_token_check(const GBytesToken *, GScanBytesMatches *); +void g_bytes_token_check(const GBytesToken *, GScanBytesMatches *, scan_node_check_params_t *); /* Retrouve l'origine d'une correspondance à partir d'un indice. */ char *g_bytes_token_get_modifier_path(const GBytesToken *, size_t); diff --git a/src/analysis/scan/rule.c b/src/analysis/scan/rule.c index 14a6d38..05fc657 100644 --- a/src/analysis/scan/rule.c +++ b/src/analysis/scan/rule.c @@ -613,17 +613,34 @@ bool g_scan_rule_define_pattern_ids(GScanRule *rule, GEngineBackend *backend) void g_scan_rule_check(GScanRule *rule, GEngineBackend *backend, GScanContext *context) { + scan_node_check_params_t params; /* Rassemblement de paramètres */ + vmpa2t start; /* Point de début du contenu */ + vmpa2t end; /* Point de fin du contenu */ size_t i; /* Boucle de parcours */ GSearchPattern *pattern; /* Motif à intégrer */ - GScanBytesMatches *matches; /* Correspondances établies */ + GScanMatches *matches; /* Correspondances établies */ + + /* Définition d'un contexte */ + + params.context = context; + params.content = g_scan_context_get_content(context); + params.allocator = g_umem_slice_new(sizeof(match_area_t)); + + g_binary_content_compute_start_pos(params.content, &start); + g_binary_content_compute_end_pos(params.content, &end); + + params.content_start = start.physical; + params.content_end = end.physical; + + /* Vérifications */ for (i = 0; i < rule->bytes_used; i++) { pattern = rule->bytes_locals[i]; - matches = g_scan_bytes_matches_new(pattern, context); + matches = g_scan_bytes_matches_new(); - g_bytes_token_check(G_BYTES_TOKEN(pattern), matches); + g_bytes_token_check(G_BYTES_TOKEN(pattern), G_SCAN_BYTES_MATCHES(matches), ¶ms); g_scan_context_register_full_matches(context, pattern, matches); @@ -631,6 +648,9 @@ void g_scan_rule_check(GScanRule *rule, GEngineBackend *backend, GScanContext *c } + g_object_unref(G_OBJECT(params.content)); + //g_object_unref(G_OBJECT(params.allocator)); + } -- cgit v0.11.2-87-g4458