diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2023-08-18 00:07:39 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2023-08-18 00:07:39 (GMT) |
commit | 2424c52c4f3bc44ce5f36348442cfa103e0989c2 (patch) | |
tree | f68aea488f403b234d4fcc6fd6e0f7b88a628ac8 /src/analysis/scan/matches/bytes.c | |
parent | 1c5a0e67186def152536d9c506e2e6c3a3a265c5 (diff) |
Create some modifiers and handle match properties inside ROST.
Diffstat (limited to 'src/analysis/scan/matches/bytes.c')
-rw-r--r-- | src/analysis/scan/matches/bytes.c | 270 |
1 files changed, 238 insertions, 32 deletions
diff --git a/src/analysis/scan/matches/bytes.c b/src/analysis/scan/matches/bytes.c index 90fa27d..043170e 100644 --- a/src/analysis/scan/matches/bytes.c +++ b/src/analysis/scan/matches/bytes.c @@ -24,10 +24,14 @@ #include "bytes.h" +#include <assert.h> #include <ctype.h> +#include <stdio.h> #include "bytes-int.h" +#include "../../../common/cpp.h" +#include "../../../core/logs.h" @@ -35,24 +39,27 @@ /* Initialise la classe des correspondances de chaînes. */ -static void g_bytes_match_class_init(GBytesMatchClass *); +static void g_scan_bytes_match_class_init(GScanBytesMatchClass *); /* Initialise une instance de correspondance de chaîne trouvée. */ -static void g_bytes_match_init(GBytesMatch *); +static void g_scan_bytes_match_init(GScanBytesMatch *); /* Supprime toutes les références externes. */ -static void g_bytes_match_dispose(GBytesMatch *); +static void g_scan_bytes_match_dispose(GScanBytesMatch *); /* Procède à la libération totale de la mémoire. */ -static void g_bytes_match_finalize(GBytesMatch *); +static void g_scan_bytes_match_finalize(GScanBytesMatch *); /* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ -/* Affiche une correspondance sur la sortie standard. */ -static void g_bytes_match_display(const GBytesMatch *); +/* Affiche une correspondance au format texte. */ +static void g_scan_bytes_match_output_to_text(const GScanBytesMatch *, int); + +/* Affiche une correspondance au format JSON. */ +static void g_scan_bytes_match_output_to_json(const GScanBytesMatch *, const sized_string_t *, unsigned int, int); @@ -62,7 +69,7 @@ static void g_bytes_match_display(const GBytesMatch *); /* Indique le type défini pour un correspondance de chaîne identifiée. */ -G_DEFINE_TYPE(GBytesMatch, g_bytes_match, G_TYPE_SCAN_MATCH); +G_DEFINE_TYPE(GScanBytesMatch, g_scan_bytes_match, G_TYPE_SCAN_MATCH); /****************************************************************************** @@ -77,19 +84,20 @@ G_DEFINE_TYPE(GBytesMatch, g_bytes_match, G_TYPE_SCAN_MATCH); * * ******************************************************************************/ -static void g_bytes_match_class_init(GBytesMatchClass *klass) +static void g_scan_bytes_match_class_init(GScanBytesMatchClass *klass) { GObjectClass *object; /* Autre version de la classe */ GScanMatchClass *match; /* Version parente de la classe*/ object = G_OBJECT_CLASS(klass); - object->dispose = (GObjectFinalizeFunc/* ! */)g_bytes_match_dispose; - object->finalize = (GObjectFinalizeFunc)g_bytes_match_finalize; + object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_bytes_match_dispose; + object->finalize = (GObjectFinalizeFunc)g_scan_bytes_match_finalize; match = G_SCAN_MATCH_CLASS(klass); - match->display = (display_scan_match_fc)g_bytes_match_display; + match->to_text = (output_scan_match_to_text_fc)g_scan_bytes_match_output_to_text; + match->to_json = (output_scan_match_to_json_fc)g_scan_bytes_match_output_to_json; } @@ -106,7 +114,7 @@ static void g_bytes_match_class_init(GBytesMatchClass *klass) * * ******************************************************************************/ -static void g_bytes_match_init(GBytesMatch *match) +static void g_scan_bytes_match_init(GScanBytesMatch *match) { match->content = NULL; @@ -128,11 +136,11 @@ static void g_bytes_match_init(GBytesMatch *match) * * ******************************************************************************/ -static void g_bytes_match_dispose(GBytesMatch *match) +static void g_scan_bytes_match_dispose(GScanBytesMatch *match) { g_clear_object(&match->content); - G_OBJECT_CLASS(g_bytes_match_parent_class)->dispose(G_OBJECT(match)); + G_OBJECT_CLASS(g_scan_bytes_match_parent_class)->dispose(G_OBJECT(match)); } @@ -149,9 +157,9 @@ static void g_bytes_match_dispose(GBytesMatch *match) * * ******************************************************************************/ -static void g_bytes_match_finalize(GBytesMatch *match) +static void g_scan_bytes_match_finalize(GScanBytesMatch *match) { - G_OBJECT_CLASS(g_bytes_match_parent_class)->finalize(G_OBJECT(match)); + G_OBJECT_CLASS(g_scan_bytes_match_parent_class)->finalize(G_OBJECT(match)); } @@ -171,13 +179,13 @@ static void g_bytes_match_finalize(GBytesMatch *match) * * ******************************************************************************/ -GScanMatch *g_bytes_match_new(GSearchPattern *source, GBinContent *content, phys_t start, phys_t len) +GScanMatch *g_scan_bytes_match_new(GSearchPattern *source, GBinContent *content, phys_t start, phys_t len) { GScanMatch *result; /* Structure à retourner */ - result = g_object_new(G_TYPE_BYTES_MATCH, NULL); + result = g_object_new(G_TYPE_SCAN_BYTES_MATCH, NULL); - if (!g_bytes_match_create(G_BYTES_MATCH(result), source, content, start, len)) + if (!g_scan_bytes_match_create(G_SCAN_BYTES_MATCH(result), source, content, start, len)) g_clear_object(&result); return result; @@ -201,7 +209,7 @@ GScanMatch *g_bytes_match_new(GSearchPattern *source, GBinContent *content, phys * * ******************************************************************************/ -bool g_bytes_match_create(GBytesMatch *match, GSearchPattern *source, GBinContent *content, phys_t start, phys_t len) +bool g_scan_bytes_match_create(GScanBytesMatch *match, GSearchPattern *source, GBinContent *content, phys_t start, phys_t len) { bool result; /* Bilan à retourner */ GScanMatch *base; /* Lien vers les infos de base */ @@ -224,6 +232,58 @@ bool g_bytes_match_create(GBytesMatch *match, GSearchPattern *source, GBinConten } +/****************************************************************************** +* * +* Paramètres : match = informations de correspondance à consulter. * +* * +* Description : Fournit une référence au contenu lié à la correspondance. * +* * +* Retour : Content binaire associé au context. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinContent *g_scan_bytes_match_get_content(const GScanBytesMatch *match) +{ + GBinContent *result; /* Instance à retourner */ + + result = match->content; + + g_object_ref(G_OBJECT(result)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : match = informations de correspondance à consulter. * +* start = position de départ d'un motif détecté. [OUT] * +* end = position d'arrivée d'un motif détecté. [OUT] * +* * +* Description : Indique la localisation d'une correspondance établie. * +* * +* Retour : Taille mesurée de la correspondance. * +* * +* Remarques : - * +* * +******************************************************************************/ + +phys_t g_scan_bytes_match_get_location(const GScanBytesMatch *match, phys_t *start, phys_t *end) +{ + phys_t result; /* Taille à retourner */ + + result = match->len; + + *start = match->start; + *end = match->start + result; + + return result; + +} + /* ---------------------------------------------------------------------------------- */ /* IMPLEMENTATION DES FONCTIONS DE CLASSE */ @@ -233,8 +293,9 @@ bool g_bytes_match_create(GBytesMatch *match, GSearchPattern *source, GBinConten /****************************************************************************** * * * Paramètres : match = définition de correspondance à manipuler. * +* fd = canal d'écriture. * * * -* Description : Affiche une correspondance sur la sortie standard. * +* Description : Affiche une correspondance au format texte. * * * * Retour : - * * * @@ -242,15 +303,34 @@ bool g_bytes_match_create(GBytesMatch *match, GSearchPattern *source, GBinConten * * ******************************************************************************/ -static void g_bytes_match_display(const GBytesMatch *match) +static void g_scan_bytes_match_output_to_text(const GScanBytesMatch *match, int fd) { + char value[2 + ULLONG_MAXLEN]; /* Impression de la position */ + int ret; /* Bilan d'une conversion */ GScanMatch *base; /* Lien vers les infos de base */ const char *name; /* Désignation du motif ciblé */ vmpa2t pos; /* Tête de lecture */ const bin_t *data; /* Accès aux données brutes */ - phys_t i; /* Boucle de parcours */ + phys_t k; /* Boucle de parcours #2 */ + + /* Position dans le binaire (hexadécimal) */ + + ret = snprintf(value, ULLONG_MAXLEN, "0x%llx", (unsigned long long)match->start); + + if (ret > 0) + write(fd, value, ret); - /* Affichage d'un repère */ + else + { + log_simple_message(LMT_EXT_ERROR, "Error while converting offset to hex!"); + write(fd, "\"<error>\"", 9); + } + + write(fd, ":", 1); + + /* Affichage de la désignation */ + + write(fd, "$", 1); base = G_SCAN_MATCH(match); @@ -262,25 +342,151 @@ static void g_bytes_match_display(const GBytesMatch *match) * Cette absence de nom est supportée ici. */ - if (name == NULL) - name = ""; + if (name != NULL) + write(fd, name, strlen(name)); + + write(fd, ": ", 2); + + /* Affichage du contenu */ + + 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 (isprint(data[k])) + write(fd, &data[k], 1); + + else + { + write(fd, "\\x", 2); + + ret = snprintf(value, ULLONG_MAXLEN, "%02hhx", data[k]); + + if (ret > 0) + { + assert(ret == 2); + write(fd, value, ret); + } + + else + { + log_simple_message(LMT_EXT_ERROR, "Error while converting data!"); + write(fd, "??", 2); + } + + } + + } + + write(fd, "\n", 1); + +} + + +/****************************************************************************** +* * +* Paramètres : match = définition de correspondance à manipuler. * +* padding = éventuel bourrage initial à placer ou NULL. * +* level = profondeur actuelle. * +* fd = canal d'écriture. * +* * +* Description : Affiche une correspondance au format JSON. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_scan_bytes_match_output_to_json(const GScanBytesMatch *match, const sized_string_t *padding, unsigned int level, int fd) +{ + unsigned int i; /* Boucle de parcours #1 */ + vmpa2t pos; /* Tête de lecture */ + char value[4 + ULLONG_MAXLEN]; /* Impression de la position */ + int ret; /* Bilan d'une conversion */ + const bin_t *data; /* Accès aux données brutes */ + phys_t k; /* Boucle de parcours #2 */ + + /* Position dans le binaire (décimal) */ + + for (i = 0; i < level; i++) + write(fd, padding->data, padding->len); + + write(fd, "\"offset\": ", 10); + + ret = snprintf(value, ULLONG_MAXLEN, "%llu", (unsigned long long)match->start); + + if (ret > 0) + write(fd, value, ret); + + else + { + log_simple_message(LMT_EXT_ERROR, "Error while converting offset!"); + write(fd, "null", 4); + } + + write(fd, ",\n", 2); + + /* Position dans le binaire (hexadécimal) */ + + for (i = 0; i < level; i++) + write(fd, padding->data, padding->len); + + write(fd, "\"offset_hex\": ", 14); - printf("0x%llx:$%s: ", (unsigned long long)match->start, name); + ret = snprintf(value, ULLONG_MAXLEN, "\"0x%llx\"", (unsigned long long)match->start); + + if (ret > 0) + write(fd, value, ret); + + else + { + log_simple_message(LMT_EXT_ERROR, "Error while converting offset to hex!"); + write(fd, "null", 4); + } + + write(fd, ",\n", 2); /* Affichage du contenu */ + for (i = 0; i < level; i++) + write(fd, padding->data, padding->len); + + write(fd, "\"content\": \"", 12); + init_vmpa(&pos, match->start, VMPA_NO_VIRTUAL); data = g_binary_content_get_raw_access(match->content, &pos, match->len); - for (i = 0; i < match->len; i++) + for (k = 0; k < match->len; k++) { - if (isprint(data[i])) - printf("%c", data[i]); + if (isprint(data[k])) + write(fd, &data[k], 1); + else - printf("\\x%02hhx", data[i]); + { + write(fd, "\\x", 2); + + ret = snprintf(value, ULLONG_MAXLEN, "%02hhx", data[k]); + + if (ret > 0) + { + assert(ret == 2); + write(fd, value, ret); + } + + else + { + log_simple_message(LMT_EXT_ERROR, "Error while converting data!"); + write(fd, "??", 2); + } + + } + } - printf("\n"); + write(fd, "\"\n", 2); } |