summaryrefslogtreecommitdiff
path: root/src/analysis/scan/scanner.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/scan/scanner.c')
-rw-r--r--src/analysis/scan/scanner.c180
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;
+
}