summaryrefslogtreecommitdiff
path: root/src/analysis/scan
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2023-09-12 21:49:01 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2023-09-12 21:49:01 (GMT)
commit6f160d1b1e1bfdd06414d5b6c49a0c9d9fc8a830 (patch)
tree2b2cfc9d1641a6fcf4c2be5578d35fda2585fb1a /src/analysis/scan
parentfef46dc1537e3302ac7bab653d24495c570e1d5c (diff)
Complete the output of scan results (text or JSON).
Diffstat (limited to 'src/analysis/scan')
-rw-r--r--src/analysis/scan/matches/bytes.c55
-rw-r--r--src/analysis/scan/pattern.c128
-rw-r--r--src/analysis/scan/pattern.h4
-rw-r--r--src/analysis/scan/rule.c128
-rw-r--r--src/analysis/scan/rule.h4
-rw-r--r--src/analysis/scan/scanner.c128
-rw-r--r--src/analysis/scan/scanner.h4
7 files changed, 425 insertions, 26 deletions
diff --git a/src/analysis/scan/matches/bytes.c b/src/analysis/scan/matches/bytes.c
index 043170e..ccd73a1 100644
--- a/src/analysis/scan/matches/bytes.c
+++ b/src/analysis/scan/matches/bytes.c
@@ -449,7 +449,7 @@ static void g_scan_bytes_match_output_to_json(const GScanBytesMatch *match, cons
write(fd, ",\n", 2);
- /* Affichage du contenu */
+ /* Affichage du contenu brut */
for (i = 0; i < level; i++)
write(fd, padding->data, padding->len);
@@ -462,12 +462,61 @@ static void g_scan_bytes_match_output_to_json(const GScanBytesMatch *match, cons
for (k = 0; k < match->len; k++)
{
- if (isprint(data[k]))
+ if (data[k] == '\\')
+ write(fd, "\\\\", 2);
+
+ else if (isprint(data[k]))
write(fd, &data[k], 1);
else
{
- write(fd, "\\x", 2);
+ write(fd, "\\u", 2);
+
+ /**
+ * Cf. https://datatracker.ietf.org/doc/html/rfc8259#section-7
+ */
+ ret = snprintf(value, ULLONG_MAXLEN, "%04hhx", data[k]);
+
+ if (ret > 0)
+ {
+ assert(ret == 4);
+ write(fd, value, ret);
+ }
+
+ else
+ {
+ log_simple_message(LMT_EXT_ERROR, "Error while converting data!");
+ write(fd, "??", 2);
+ }
+
+ }
+
+ }
+
+ write(fd, "\",\n", 3);
+
+ /* Affichage du contenu en version humainement lisible */
+
+ for (i = 0; i < level; i++)
+ write(fd, padding->data, padding->len);
+
+ write(fd, "\"content_str\": \"", 16);
+
+ init_vmpa(&pos, match->start, VMPA_NO_VIRTUAL);
+
+ data = g_binary_content_get_raw_access(match->content, &pos, match->len);
+
+ for (k = 0; k < match->len; k++)
+ {
+ if (data[k] == '\\')
+ write(fd, "\\\\", 2);
+
+ else if (isprint(data[k]))
+ write(fd, &data[k], 1);
+
+ else
+ {
+ write(fd, "\\\\x", 3);
ret = snprintf(value, ULLONG_MAXLEN, "%02hhx", data[k]);
diff --git a/src/analysis/scan/pattern.c b/src/analysis/scan/pattern.c
index 5b966d2..797f4ac 100644
--- a/src/analysis/scan/pattern.c
+++ b/src/analysis/scan/pattern.c
@@ -25,10 +25,15 @@
#include <malloc.h>
+#include <stdio.h>
#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
#include "pattern-int.h"
+#include "../../core/logs.h"
@@ -216,14 +221,69 @@ void g_search_pattern_output_to_text(const GSearchPattern *pattern, GScanContext
* *
* Description : Convertit un motif de recherche en texte. *
* *
-* Retour : - *
+* Retour : Données textuelles ou NULL en cas d'erreur. *
* *
* Remarques : - *
* *
******************************************************************************/
-void g_search_pattern_convert_as_text(const GSearchPattern *pattern, GScanContext *context)
+char *g_search_pattern_convert_as_text(const GSearchPattern *pattern, GScanContext *context)
{
+ char *result; /* Données à retourner */
+ char *name; /* Nom "unique" pour le canal */
+ int ret; /* Bilan de création de nom */
+ int fd; /* Canal d'écriture */
+ struct stat info; /* Infos. incluant une taille */
+ ssize_t got; /* Données effectivement relues*/
+
+ static unsigned long long counter = 0;
+
+ result = NULL;
+
+ ret = asprintf(&name, "rost-pattern2text-%llu", counter++);
+ if (ret == -1) goto exit;
+
+ fd = memfd_create(name, MFD_CLOEXEC);
+ if (fd == -1)
+ {
+ LOG_ERROR_N("memfd_create");
+ goto exit_with_name;
+ }
+
+ g_search_pattern_output_to_text(pattern, context, fd);
+
+ ret = fstat(fd, &info);
+ if (ret != 0)
+ {
+ LOG_ERROR_N("fstat");
+ goto exit_with_name_and_fd;
+ }
+
+ result = malloc((info.st_size + 1) * sizeof(char));
+
+ lseek(fd, SEEK_SET, 0);
+
+ got = read(fd, result, info.st_size);
+ if (got != info.st_size)
+ {
+ LOG_ERROR_N("read");
+ free(result);
+ goto exit_with_name_and_fd;
+ }
+
+ result[info.st_size] = '\0';
+
+ exit_with_name_and_fd:
+
+ close(fd);
+
+ exit_with_name:
+
+ free(name);
+
+ exit:
+
+ return result;
}
@@ -294,14 +354,72 @@ void g_search_pattern_output_to_json(const GSearchPattern *pattern, GScanContext
* *
* Description : Convertit un motif de recherche en JSON. *
* *
-* Retour : - *
+* Retour : Données textuelles au format JSON ou NULL en cas d'erreur. *
* *
* Remarques : - *
* *
******************************************************************************/
-void g_search_pattern_convert_as_json(const GSearchPattern *pattern, GScanContext *context)
+char *g_search_pattern_convert_as_json(const GSearchPattern *pattern, GScanContext *context)
{
- /* TODO */
+ char *result; /* Données à retourner */
+ char *name; /* Nom "unique" pour le canal */
+ int ret; /* Bilan de création de nom */
+ int fd; /* Canal d'écriture */
+ sized_string_t padding; /* Bourrage pour le JSON */
+ struct stat info; /* Infos. incluant une taille */
+ ssize_t got; /* Données effectivement relues*/
+
+ static unsigned long long counter = 0;
+
+ result = NULL;
+
+ ret = asprintf(&name, "rost-pattern2json-%llu", counter++);
+ if (ret == -1) goto exit;
+
+ fd = memfd_create(name, MFD_CLOEXEC);
+ if (fd == -1)
+ {
+ LOG_ERROR_N("memfd_create");
+ goto exit_with_name;
+ }
+
+ padding.data = " ";
+ padding.len = 3;
+
+ g_search_pattern_output_to_json(pattern, context, &padding, 0, fd, false);
+
+ ret = fstat(fd, &info);
+ if (ret != 0)
+ {
+ LOG_ERROR_N("fstat");
+ goto exit_with_name_and_fd;
+ }
+
+ result = malloc((info.st_size + 1) * sizeof(char));
+
+ lseek(fd, SEEK_SET, 0);
+
+ got = read(fd, result, info.st_size);
+ if (got != info.st_size)
+ {
+ LOG_ERROR_N("read");
+ free(result);
+ goto exit_with_name_and_fd;
+ }
+
+ result[info.st_size] = '\0';
+
+ exit_with_name_and_fd:
+
+ close(fd);
+
+ exit_with_name:
+
+ free(name);
+
+ exit:
+
+ return result;
}
diff --git a/src/analysis/scan/pattern.h b/src/analysis/scan/pattern.h
index 0e4327d..72f87e4 100644
--- a/src/analysis/scan/pattern.h
+++ b/src/analysis/scan/pattern.h
@@ -66,13 +66,13 @@ void g_search_pattern_set_name(GSearchPattern *, const char *, size_t);
void g_search_pattern_output_to_text(const GSearchPattern *, GScanContext *, int);
/* Convertit un motif de recherche en texte. */
-void g_search_pattern_convert_as_text(const GSearchPattern *, GScanContext *);
+char *g_search_pattern_convert_as_text(const GSearchPattern *, GScanContext *);
/* Affiche un motif de recherche au format JSON. */
void g_search_pattern_output_to_json(const GSearchPattern *, GScanContext *, const sized_string_t *, unsigned int, int, bool);
/* Convertit un motif de recherche en JSON. */
-void g_search_pattern_convert_as_json(const GSearchPattern *, GScanContext *);
+char *g_search_pattern_convert_as_json(const GSearchPattern *, GScanContext *);
diff --git a/src/analysis/scan/rule.c b/src/analysis/scan/rule.c
index 4ef1e3c..a1fcfcb 100644
--- a/src/analysis/scan/rule.c
+++ b/src/analysis/scan/rule.c
@@ -26,7 +26,11 @@
#include <assert.h>
#include <regex.h>
+#include <stdio.h>
#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
#include "rule-int.h"
@@ -561,15 +565,69 @@ void g_scan_rule_output_to_text(const GScanRule *rule, GScanContext *context, bo
* *
* Description : Convertit une règle en texte. *
* *
-* Retour : - *
+* Retour : Données textuelles ou NULL en cas d'erreur. *
* *
* Remarques : - *
* *
******************************************************************************/
-void g_scan_rule_convert_as_text(const GScanRule *rule, GScanContext *context)
+char *g_scan_rule_convert_as_text(const GScanRule *rule, GScanContext *context)
{
- /* TODO */
+ char *result; /* Données à retourner */
+ char *name; /* Nom "unique" pour le canal */
+ int ret; /* Bilan de création de nom */
+ int fd; /* Canal d'écriture */
+ struct stat info; /* Infos. incluant une taille */
+ ssize_t got; /* Données effectivement relues*/
+
+ static unsigned long long counter = 0;
+
+ result = NULL;
+
+ ret = asprintf(&name, "rost-rule2text-%llu", counter++);
+ if (ret == -1) goto exit;
+
+ fd = memfd_create(name, MFD_CLOEXEC);
+ if (fd == -1)
+ {
+ LOG_ERROR_N("memfd_create");
+ goto exit_with_name;
+ }
+
+ g_scan_rule_output_to_text(rule, context, true, fd);
+
+ ret = fstat(fd, &info);
+ if (ret != 0)
+ {
+ LOG_ERROR_N("fstat");
+ goto exit_with_name_and_fd;
+ }
+
+ result = malloc((info.st_size + 1) * sizeof(char));
+
+ lseek(fd, SEEK_SET, 0);
+
+ got = read(fd, result, info.st_size);
+ if (got != info.st_size)
+ {
+ LOG_ERROR_N("read");
+ free(result);
+ goto exit_with_name_and_fd;
+ }
+
+ result[info.st_size] = '\0';
+
+ exit_with_name_and_fd:
+
+ close(fd);
+
+ exit_with_name:
+
+ free(name);
+
+ exit:
+
+ return result;
}
@@ -668,14 +726,72 @@ void g_scan_rule_output_to_json(const GScanRule *rule, GScanContext *context, co
* *
* Description : Convertit une règle en JSON. *
* *
-* Retour : - *
+* Retour : Données textuelles au format JSON ou NULL en cas d'erreur. *
* *
* Remarques : - *
* *
******************************************************************************/
-void g_scan_rule_convert_as_json(const GScanRule *rule, GScanContext *context)
+char *g_scan_rule_convert_as_json(const GScanRule *rule, GScanContext *context)
{
- /* TODO */
+ char *result; /* Données à retourner */
+ char *name; /* Nom "unique" pour le canal */
+ int ret; /* Bilan de création de nom */
+ int fd; /* Canal d'écriture */
+ sized_string_t padding; /* Bourrage pour le JSON */
+ struct stat info; /* Infos. incluant une taille */
+ ssize_t got; /* Données effectivement relues*/
+
+ static unsigned long long counter = 0;
+
+ result = NULL;
+
+ ret = asprintf(&name, "rost-rule2json-%llu", counter++);
+ if (ret == -1) goto exit;
+
+ fd = memfd_create(name, MFD_CLOEXEC);
+ if (fd == -1)
+ {
+ LOG_ERROR_N("memfd_create");
+ goto exit_with_name;
+ }
+
+ padding.data = " ";
+ padding.len = 3;
+
+ g_scan_rule_output_to_json(rule, context, &padding, 0, fd, false);
+
+ ret = fstat(fd, &info);
+ if (ret != 0)
+ {
+ LOG_ERROR_N("fstat");
+ goto exit_with_name_and_fd;
+ }
+
+ result = malloc((info.st_size + 1) * sizeof(char));
+
+ lseek(fd, SEEK_SET, 0);
+
+ got = read(fd, result, info.st_size);
+ if (got != info.st_size)
+ {
+ LOG_ERROR_N("read");
+ free(result);
+ goto exit_with_name_and_fd;
+ }
+
+ result[info.st_size] = '\0';
+
+ exit_with_name_and_fd:
+
+ close(fd);
+
+ exit_with_name:
+
+ free(name);
+
+ exit:
+
+ return result;
}
diff --git a/src/analysis/scan/rule.h b/src/analysis/scan/rule.h
index 7ade51b..6ab5105 100644
--- a/src/analysis/scan/rule.h
+++ b/src/analysis/scan/rule.h
@@ -84,13 +84,13 @@ void g_scan_rule_check(GScanRule *, GEngineBackend *, GScanContext *);
void g_scan_rule_output_to_text(const GScanRule *, GScanContext *, bool, int);
/* Convertit une règle en texte. */
-void g_scan_rule_convert_as_text(const GScanRule *, GScanContext *);
+char *g_scan_rule_convert_as_text(const GScanRule *, GScanContext *);
/* Affiche une règle au format JSON. */
void g_scan_rule_output_to_json(const GScanRule *, GScanContext *, const sized_string_t *, unsigned int, int, bool);
/* Convertit une règle en JSON. */
-void g_scan_rule_convert_as_json(const GScanRule *, GScanContext *);
+char *g_scan_rule_convert_as_json(const GScanRule *, GScanContext *);
diff --git a/src/analysis/scan/scanner.c b/src/analysis/scan/scanner.c
index 29f47eb..41fa0de 100644
--- a/src/analysis/scan/scanner.c
+++ b/src/analysis/scan/scanner.c
@@ -27,6 +27,10 @@
#include <assert.h>
#include <libgen.h>
#include <malloc.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
#include "decl.h"
@@ -556,15 +560,69 @@ void g_content_scanner_output_to_text(const GContentScanner *scanner, GScanConte
* *
* Description : Convertit un gestionnaire de recherches en texte. *
* *
-* Retour : - *
+* Retour : Données textuelles ou NULL en cas d'erreur. *
* *
* Remarques : - *
* *
******************************************************************************/
-void g_content_scanner_convert_as_text(const GContentScanner *scanner, GScanContext *context)
+char *g_content_scanner_convert_to_text(const GContentScanner *scanner, GScanContext *context)
{
- /* TODO */
+ char *result; /* Données à retourner */
+ char *name; /* Nom "unique" pour le canal */
+ int ret; /* Bilan de création de nom */
+ int fd; /* Canal d'écriture */
+ struct stat info; /* Infos. incluant une taille */
+ ssize_t got; /* Données effectivement relues*/
+
+ static unsigned long long counter = 0;
+
+ result = NULL;
+
+ ret = asprintf(&name, "rost-scanner2text-%llu", counter++);
+ if (ret == -1) goto exit;
+
+ fd = memfd_create(name, MFD_CLOEXEC);
+ if (fd == -1)
+ {
+ LOG_ERROR_N("memfd_create");
+ goto exit_with_name;
+ }
+
+ g_content_scanner_output_to_text(scanner, context, true, fd);
+
+ ret = fstat(fd, &info);
+ if (ret != 0)
+ {
+ LOG_ERROR_N("fstat");
+ goto exit_with_name_and_fd;
+ }
+
+ result = malloc((info.st_size + 1) * sizeof(char));
+
+ lseek(fd, SEEK_SET, 0);
+
+ got = read(fd, result, info.st_size);
+ if (got != info.st_size)
+ {
+ LOG_ERROR_N("read");
+ free(result);
+ goto exit_with_name_and_fd;
+ }
+
+ result[info.st_size] = '\0';
+
+ exit_with_name_and_fd:
+
+ close(fd);
+
+ exit_with_name:
+
+ free(name);
+
+ exit:
+
+ return result;
}
@@ -624,14 +682,72 @@ void g_content_scanner_output_to_json(const GContentScanner *scanner, GScanConte
* *
* Description : Convertit un gestionnaire de recherches en JSON. *
* *
-* Retour : - *
+* Retour : Données textuelles au format JSON ou NULL en cas d'erreur. *
* *
* Remarques : - *
* *
******************************************************************************/
-void g_content_scanner_convert_as_json(const GContentScanner *scanner, GScanContext *context)
+char *g_content_scanner_convert_to_json(const GContentScanner *scanner, GScanContext *context)
{
- /* TODO */
+ char *result; /* Données à retourner */
+ char *name; /* Nom "unique" pour le canal */
+ int ret; /* Bilan de création de nom */
+ int fd; /* Canal d'écriture */
+ sized_string_t padding; /* Bourrage pour le JSON */
+ struct stat info; /* Infos. incluant une taille */
+ ssize_t got; /* Données effectivement relues*/
+
+ static unsigned long long counter = 0;
+
+ result = NULL;
+
+ ret = asprintf(&name, "rost-scanner2json-%llu", counter++);
+ if (ret == -1) goto exit;
+
+ fd = memfd_create(name, MFD_CLOEXEC);
+ if (fd == -1)
+ {
+ LOG_ERROR_N("memfd_create");
+ goto exit_with_name;
+ }
+
+ padding.data = " ";
+ padding.len = 3;
+
+ g_content_scanner_output_to_json(scanner, context, &padding, 0, fd);
+
+ ret = fstat(fd, &info);
+ if (ret != 0)
+ {
+ LOG_ERROR_N("fstat");
+ goto exit_with_name_and_fd;
+ }
+
+ result = malloc((info.st_size + 1) * sizeof(char));
+
+ lseek(fd, SEEK_SET, 0);
+
+ got = read(fd, result, info.st_size);
+ if (got != info.st_size)
+ {
+ LOG_ERROR_N("read");
+ free(result);
+ goto exit_with_name_and_fd;
+ }
+
+ result[info.st_size] = '\0';
+
+ exit_with_name_and_fd:
+
+ close(fd);
+
+ exit_with_name:
+
+ free(name);
+
+ exit:
+
+ return result;
}
diff --git a/src/analysis/scan/scanner.h b/src/analysis/scan/scanner.h
index d2b5dc1..e03ecda 100644
--- a/src/analysis/scan/scanner.h
+++ b/src/analysis/scan/scanner.h
@@ -76,13 +76,13 @@ GScanContext *g_content_scanner_analyze(GContentScanner *, GScanOptions *, GBinC
void g_content_scanner_output_to_text(const GContentScanner *, GScanContext *, bool, int);
/* Convertit un gestionnaire de recherches en texte. */
-void g_content_scanner_convert_as_text(const GContentScanner *, GScanContext *);
+char *g_content_scanner_convert_to_text(const GContentScanner *, GScanContext *);
/* Affiche un gestionnaire de recherches au format JSON. */
void g_content_scanner_output_to_json(const GContentScanner *, GScanContext *, const sized_string_t *, unsigned int, int);
/* Convertit un gestionnaire de recherches en JSON. */
-void g_content_scanner_convert_as_json(const GContentScanner *, GScanContext *);
+char *g_content_scanner_convert_to_json(const GContentScanner *, GScanContext *);