diff options
Diffstat (limited to 'src/analysis/scan/scanner.c')
-rw-r--r-- | src/analysis/scan/scanner.c | 180 |
1 files changed, 178 insertions, 2 deletions
diff --git a/src/analysis/scan/scanner.c b/src/analysis/scan/scanner.c index d52c0fc..ce8d677 100644 --- a/src/analysis/scan/scanner.c +++ b/src/analysis/scan/scanner.c @@ -25,11 +25,15 @@ #include <assert.h> +#include <libgen.h> +#include <malloc.h> #include "decl.h" #include "scanner-int.h" #include "../contents/file.h" +#include "../../common/extstr.h" +#include "../../core/logs.h" @@ -45,6 +49,9 @@ static void g_content_scanner_dispose(GContentScanner *); /* Procède à la libération totale de la mémoire. */ static void g_content_scanner_finalize(GContentScanner *); +/* Intègre une nouvelle règle de détection. */ +static bool _g_content_scanner_add_rule(GContentScanner *, GScanRule *); + /* Indique le type défini pour une recherche dans du binaire. */ @@ -89,6 +96,8 @@ static void g_content_scanner_class_init(GContentScannerClass *klass) static void g_content_scanner_init(GContentScanner *scanner) { + scanner->filename = NULL; + scanner->rules = NULL; scanner->rule_count = 0; @@ -137,6 +146,9 @@ static void g_content_scanner_dispose(GContentScanner *scanner) static void g_content_scanner_finalize(GContentScanner *scanner) { + if (scanner->filename != NULL) + free(scanner->filename); + if (scanner->rules != NULL) free(scanner->rules); @@ -250,6 +262,8 @@ bool g_content_scanner_create_from_file(GContentScanner *scanner, const char *fi content = g_file_content_new(filename); if (content == NULL) goto no_content; + scanner->filename = strdup(filename); + size = g_binary_content_compute_size(content); g_binary_content_compute_start_pos(content, &start); @@ -268,25 +282,187 @@ bool g_content_scanner_create_from_file(GContentScanner *scanner, const char *fi /****************************************************************************** * * +* Paramètres : scanner = scanner de contenus à consulter. * +* * +* Description : Indique le chemin d'un éventuel fichier de source. * +* * +* Retour : Chemin d'un éventuel fichier de définitions ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *g_content_scanner_get_filename(const GContentScanner *scanner) +{ + const char *result; /* Chemin à retourner */ + + result = scanner->filename; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : scanner = gestionnaire de recherche à compléter. * +* path = chemin vers une définition de règles à intégrer. * +* * +* Description : Inclut les définitions d'un fichier de règles externe. * +* * +* Retour : Bilan de l'inclusion à retourner. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_content_scanner_include_resource(GContentScanner *scanner, const char *path) +{ + bool result; /* Bilan à retourner */ + GContentScanner *included; /* Définition à inclure */ + char *tmp; /* Copie de travail */ + char *filename; /* Chemin d'accès reconstruit */ + size_t i; /* Boucle de parcours */ + const char *inc_name; /* Nom de la nouvelle règle */ + + /* Cas le plus simple : un chemin absolu */ + if (path[0] == '/') + included = g_content_scanner_new_from_file(path); + + /* Chemin relatif à l'emplacement de la définition courante ? */ + else if (scanner->filename != NULL) + { + tmp = strdup(scanner->filename); + + filename = strdup(dirname(tmp)); + filename = stradd(filename, G_DIR_SEPARATOR_S); + filename = stradd(filename, path); + + included = g_content_scanner_new_from_file(filename); + + free(filename); + free(tmp); + + } + + else + included = NULL; + + /* Inclusion des règles chargées */ + + result = (included != NULL); + + if (result) + { + for (i = 0; i < included->rule_count && result; i++) + { + result = _g_content_scanner_add_rule(scanner, included->rules[i]); + + if (!result) + { + inc_name = g_scan_rule_get_name(included->rules[i], (fnv64_t []) { 0 }); + + log_variadic_message(LMT_ERROR, "Can not import from '%s': rule '%s' already exists!", + path, inc_name); + + } + + } + + g_object_unref(G_OBJECT(included)); + + } + + return result; + + + +} + + +/****************************************************************************** +* * * Paramètres : scanner = gestionnaire de recherche à compléter. * * rule = règle de détection à intégrer. * * * * Description : Intègre une nouvelle règle de détection. * * * -* Retour : - * +* Retour : Bilan de l'ajout à retourner. * * * * Remarques : - * * * ******************************************************************************/ -void g_content_scanner_add_rule(GContentScanner *scanner, GScanRule *rule) +static bool _g_content_scanner_add_rule(GContentScanner *scanner, GScanRule *rule) { + bool result; /* Bilan à retourner */ + const char *inc_name; /* Nom de la nouvelle règle */ + fnv64_t inc_hash; /* Empreinte de ce nom */ + size_t i; /* Boucle de parcours */ + const char *cur_name; /* Nom d'une règle en place */ + fnv64_t cur_hash; /* Empreinte de ce nom */ + + result = false; + + inc_name = g_scan_rule_get_name(rule, &inc_hash); + + for (i = 0; i < scanner->rule_count; i++) + { + cur_name = g_scan_rule_get_name(scanner->rules[i], &cur_hash); + + if (inc_hash != cur_hash) + continue; + + if (strcmp(inc_name, cur_name) == 0) + goto exit_add; + + } + + result = true; + scanner->rules = realloc(scanner->rules, ++scanner->rule_count * sizeof(GScanRule *)); scanner->rules[scanner->rule_count - 1] = rule; g_object_ref(G_OBJECT(rule)); + exit_add: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : scanner = gestionnaire de recherche à compléter. * +* rule = règle de détection à intégrer. * +* * +* Description : Intègre une nouvelle règle de détection. * +* * +* Retour : Bilan de l'ajout à retourner. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_content_scanner_add_rule(GContentScanner *scanner, GScanRule *rule) +{ + bool result; /* Bilan à retourner */ + const char *inc_name; /* Nom de la nouvelle règle */ + + result = _g_content_scanner_add_rule(scanner, rule); + + if (!result) + { + inc_name = g_scan_rule_get_name(rule, (fnv64_t []) { 0 }); + + log_variadic_message(LMT_ERROR, "Can not add rule: '%s' already exists!", inc_name); + + } + + return result; + } |