summaryrefslogtreecommitdiff
path: root/src/analysis/scan/patterns/tokens/plain.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/scan/patterns/tokens/plain.c')
-rw-r--r--src/analysis/scan/patterns/tokens/plain.c365
1 files changed, 242 insertions, 123 deletions
diff --git a/src/analysis/scan/patterns/tokens/plain.c b/src/analysis/scan/patterns/tokens/plain.c
index 9eb731e..26e7dfa 100644
--- a/src/analysis/scan/patterns/tokens/plain.c
+++ b/src/analysis/scan/patterns/tokens/plain.c
@@ -28,59 +28,41 @@
#include <string.h>
-#include "../token-int.h"
+#include "plain-int.h"
/* ----------------------- RECHERCHE D'UN MOTIF DE TEXTE BRUT ----------------------- */
-/* Encadrement d'une recherche de texte brut (instance) */
-struct _GPlainBytes
-{
- GStringToken parent; /* A laisser en premier */
-
- uint8_t *raw; /* Octets recherchés */
- size_t allocated; /* Taille allouée */
- size_t used; /* Quantité d'octets utilisée */
-
- phys_t atom_pos; /* Début de sélection atomique */
- phys_t atom_len; /* Taille de ladite sélection */
- phys_t atom_rem; /* Reste après l'atome */
- patid_t pid; /* Identifiant de la bribe */
-
-};
-
-/* Encadrement d'une recherche de texte brut (classe) */
-struct _GPlainBytesClass
-{
- GStringTokenClass parent; /* A laisser en premier */
-
-};
-
-
/* Initialise la classe des recherches de texte brut. */
-static void g_plain_bytes_class_init(GPlainBytesClass *klass);
+static void g_scan_plain_bytes_class_init(GScanPlainBytesClass *klass);
/* Initialise une instance de recherche de texte brut. */
-static void g_plain_bytes_init(GPlainBytes *);
+static void g_scan_plain_bytes_init(GScanPlainBytes *);
/* Supprime toutes les références externes. */
-static void g_plain_bytes_dispose(GPlainBytes *);
+static void g_scan_plain_bytes_dispose(GScanPlainBytes *);
/* Procède à la libération totale de la mémoire. */
-static void g_plain_bytes_finalize(GPlainBytes *);
+static void g_scan_plain_bytes_finalize(GScanPlainBytes *);
/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+/* Affiche un motif de recherche au format texte. */
+static void g_scan_plain_bytes_output_to_text(const GScanPlainBytes *, GScanContext *, int);
+
+/* Affiche un motif de recherche au format JSON. */
+static void g_scan_plain_bytes_output_to_json(const GScanPlainBytes *, GScanContext *, const sized_string_t *, unsigned int, int);
+
/* Inscrit la définition d'un motif dans un moteur de recherche. */
-static bool g_plain_bytes_enroll(GPlainBytes *, GScanContext *, GEngineBackend *, size_t);
+static bool g_scan_plain_bytes_enroll(GScanPlainBytes *, GScanContext *, GEngineBackend *, size_t);
/* Transforme les correspondances locales en trouvailles. */
-static void g_plain_bytes_check(const GPlainBytes *, GScanContext *, GBinContent *, pending_matches_t *);
+static void g_scan_plain_bytes_check(const GScanPlainBytes *, GScanContext *, GBinContent *, pending_matches_t *);
@@ -90,7 +72,7 @@ static void g_plain_bytes_check(const GPlainBytes *, GScanContext *, GBinContent
/* Indique le type défini pour une suite d'octets à retrouver dans un binaire. */
-G_DEFINE_TYPE(GPlainBytes, g_plain_bytes, G_TYPE_STRING_TOKEN);
+G_DEFINE_TYPE(GScanPlainBytes, g_scan_plain_bytes, G_TYPE_STRING_TOKEN);
/******************************************************************************
@@ -105,7 +87,7 @@ G_DEFINE_TYPE(GPlainBytes, g_plain_bytes, G_TYPE_STRING_TOKEN);
* *
******************************************************************************/
-static void g_plain_bytes_class_init(GPlainBytesClass *klass)
+static void g_scan_plain_bytes_class_init(GScanPlainBytesClass *klass)
{
GObjectClass *object; /* Autre version de la classe */
GSearchPatternClass *pattern; /* Version de classe ancêtre */
@@ -113,26 +95,25 @@ static void g_plain_bytes_class_init(GPlainBytesClass *klass)
object = G_OBJECT_CLASS(klass);
- object->dispose = (GObjectFinalizeFunc/* ! */)g_plain_bytes_dispose;
- object->finalize = (GObjectFinalizeFunc)g_plain_bytes_finalize;
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_plain_bytes_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_scan_plain_bytes_finalize;
pattern = G_SEARCH_PATTERN_CLASS(klass);
- //pattern->prepare = (prepare_pattern_fc)g_plain_bytes_prepare;
- //pattern->analyze = (analyze_pattern_fc)g_plain_bytes_analyze;
- //pattern->count = (count_pattern_matchs_fc);
+ pattern->to_text = (output_pattern_to_text_fc)g_scan_plain_bytes_output_to_text;
+ pattern->to_json = (output_pattern_to_json_fc)g_scan_plain_bytes_output_to_json;
token = G_STRING_TOKEN_CLASS(klass);
- token->enroll = (enroll_token_fc)g_plain_bytes_enroll;
- token->check = (check_token_fc)g_plain_bytes_check;
+ token->enroll = (enroll_token_fc)g_scan_plain_bytes_enroll;
+ token->check = (check_token_fc)g_scan_plain_bytes_check;
}
/******************************************************************************
* *
-* Paramètres : pattern = instance à initialiser. *
+* Paramètres : bytes = instance à initialiser. *
* *
* Description : Initialise une instance de recherche de texte brut. *
* *
@@ -142,16 +123,15 @@ static void g_plain_bytes_class_init(GPlainBytesClass *klass)
* *
******************************************************************************/
-static void g_plain_bytes_init(GPlainBytes *bytes)
+static void g_scan_plain_bytes_init(GScanPlainBytes *bytes)
{
- bytes->raw = NULL;
- bytes->allocated = 0;
- bytes->used = 0;
+ init_szstr(&bytes->orig);
+ bytes->modifier = NULL;
+ bytes->flags = SPBF_NONE;
- bytes->atom_pos = 0;
- bytes->atom_len = 0;
- bytes->atom_rem = 0;
- bytes->pid = INVALID_PATTERN_ID;
+ bytes->raw = NULL;
+ bytes->atoms = NULL;
+ bytes->count = 0;
}
@@ -168,9 +148,11 @@ static void g_plain_bytes_init(GPlainBytes *bytes)
* *
******************************************************************************/
-static void g_plain_bytes_dispose(GPlainBytes *bytes)
+static void g_scan_plain_bytes_dispose(GScanPlainBytes *bytes)
{
- G_OBJECT_CLASS(g_plain_bytes_parent_class)->dispose(G_OBJECT(bytes));
+ g_clear_object(&bytes->modifier);
+
+ G_OBJECT_CLASS(g_scan_plain_bytes_parent_class)->dispose(G_OBJECT(bytes));
}
@@ -187,20 +169,31 @@ static void g_plain_bytes_dispose(GPlainBytes *bytes)
* *
******************************************************************************/
-static void g_plain_bytes_finalize(GPlainBytes *bytes)
+static void g_scan_plain_bytes_finalize(GScanPlainBytes *bytes)
{
+ size_t i; /* Boucle de parcours */
+
+ exit_szstr(&bytes->orig);
+
+ for (i = 0; i < bytes->count; i++)
+ exit_szstr(&bytes->raw[i]);
+
if (bytes->raw != NULL)
free(bytes->raw);
- G_OBJECT_CLASS(g_plain_bytes_parent_class)->finalize(G_OBJECT(bytes));
+ if (bytes->atoms != NULL)
+ free(bytes->atoms);
+
+ G_OBJECT_CLASS(g_scan_plain_bytes_parent_class)->finalize(G_OBJECT(bytes));
}
/******************************************************************************
* *
-* Paramètres : text = texte brut à rechercher. *
-* len = longueur de ce texte. *
+* Paramètres : text = texte brut à rechercher. *
+* modifier = transformateur éventuel à solliciter. *
+* flags = particularités à prendre en considération. *
* *
* Description : Construit un gestionnaire de recherche de texte brut. *
* *
@@ -210,19 +203,51 @@ static void g_plain_bytes_finalize(GPlainBytes *bytes)
* *
******************************************************************************/
-GSearchPattern *g_plain_bytes_new(const uint8_t *raw, size_t len)
+GSearchPattern *g_scan_plain_bytes_new(const sized_binary_t *text, GScanTokenModifier *modifier, ScanPlainBytesFlags flags)
{
- GPlainBytes *result; /* Structure à retourner */
+ GSearchPattern *result; /* Structure à retourner */
- result = g_object_new(G_TYPE_PLAIN_BYTES, NULL);
+ result = g_object_new(G_TYPE_SCAN_PLAIN_BYTES, NULL);
- result->raw = malloc(len);
- result->allocated = len;
- result->used = len;
+ if (!g_scan_plain_bytes_create(G_SCAN_PLAIN_BYTES(result), text, modifier, flags))
+ g_clear_object(&result);
- memcpy(result->raw, raw, len);
+ return result;
+
+}
- return G_SEARCH_PATTERN(result);
+/******************************************************************************
+* *
+* Paramètres : bytes = encadrement de motif à initialiser pleinement. *
+* text = texte brut à rechercher. *
+* modifier = transformateur éventuel à solliciter. *
+* flags = particularités à prendre en considération. *
+* *
+* Description : Met en place un gestionnaire de recherche de texte brut. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_scan_plain_bytes_create(GScanPlainBytes *bytes, const sized_binary_t *text, GScanTokenModifier *modifier, ScanPlainBytesFlags flags)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+ szstrdup(&bytes->orig, text);
+
+ if (modifier != NULL)
+ {
+ bytes->modifier = modifier;
+ g_object_ref(G_OBJECT(modifier));
+ }
+
+ bytes->flags = flags;
+
+ return result;
}
@@ -235,6 +260,52 @@ GSearchPattern *g_plain_bytes_new(const uint8_t *raw, size_t len)
/******************************************************************************
* *
+* Paramètres : pattern = définition de motif à considérer. *
+* context = contexte de l'analyse à mener. *
+* fd = canal d'écriture. *
+* *
+* Description : Affiche un motif de recherche au format texte. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_plain_bytes_output_to_text(const GScanPlainBytes *pattern, GScanContext *context, int fd)
+{
+ G_SEARCH_PATTERN_CLASS(g_scan_plain_bytes_parent_class)->to_text(G_SEARCH_PATTERN(pattern), context, fd);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : pattern = définition de motif à considérer. *
+* context = contexte de l'analyse à mener. *
+* padding = éventuel bourrage initial à placer ou NULL. *
+* level = profondeur actuelle. *
+* fd = canal d'écriture. *
+* *
+* Description : Affiche un motif de recherche au format JSON. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_plain_bytes_output_to_json(const GScanPlainBytes *pattern, GScanContext *context, const sized_string_t *padding, unsigned int level, int fd)
+{
+ G_SEARCH_PATTERN_CLASS(g_scan_plain_bytes_parent_class)->to_json(G_SEARCH_PATTERN(pattern), context, padding, level, fd);
+
+ /* TODO */
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : bytes = définition de la bribe à enregistrer. *
* context = contexte de l'analyse à mener. *
* backend = moteur de recherche à préchauffer. *
@@ -248,39 +319,99 @@ GSearchPattern *g_plain_bytes_new(const uint8_t *raw, size_t len)
* *
******************************************************************************/
-static bool g_plain_bytes_enroll(GPlainBytes *bytes, GScanContext *context, GEngineBackend *backend, size_t maxsize)
+static bool g_scan_plain_bytes_enroll(GScanPlainBytes *bytes, GScanContext *context, GEngineBackend *backend, size_t maxsize)
{
+ return false;
+#if 0
bool result; /* Statut à retourner */
+ size_t i; /* Boucle de parcours #1 */
+ tracked_scan_atom_t atom; /* Atome identifié */
+ size_t letters; /* Nombre de lettres présentes */
+ size_t k; /* Boucle de parcours #2 */
+ size_t extra_count; /* Quantité pour l'exhaustivité*/
+ sized_binary_t *extra; /* Couverture supplémntaire */
+ size_t remaining; /* Quantité restant à traiter */
+ /* Génération d'une base de chaînes à couvrir */
- result = true;
-
+ if (bytes->modifier == NULL)
+ {
+ bytes->raw = malloc(sizeof(sized_binary_t));
+ bytes->count = 1;
+ szstrdup(&bytes[0].raw[0], &bytes->orig);
- bytes->atom_pos = 0;
+ result = true;
- if (bytes->used > maxsize) // Attention à la position de départ (à retrancher) !
- {
- bytes->atom_len = maxsize;
- bytes->atom_rem = bytes->used - maxsize;
}
else
+ result = g_scan_token_modifier_transform(bytes->modifier, &bytes->orig, &bytes->raw, &bytes->count);
+
+ if (!result)
+ goto exit;
+
+ /* Préparation pour la mémorisation des atomes */
+
+ bytes->atoms = malloc(bytes->count * sizeof(tracked_scan_atom_t));
+
+ /* Recherche des atomes */
+
+ for (i = 0; i < bytes->count; i++)
{
- bytes->atom_len = bytes->used;
- bytes->atom_rem = 0;
- }
+ if (bytes->flags & SPBF_CASE_INSENSITIVE)
+ {
+ find_best_atom(&bytes->raw[i], maxsize, &atom, &letters);
+ if (letters == 0)
+ bytes->atoms[i] = atom;
- bytes->pid = g_engine_backend_enroll_plain_pattern(backend, context, bytes->raw, bytes->atom_len);
+ /* Insertion des combinaisons pour couvrir toutes les casses */
+ else
+ {
+ for (k = 0, extra_count = 1; k < letters; k++, extra_count *= 2)
+ ;
+ extra = make_atoms_case_insensitive(&bytes->raw[i], extra_count);
+ remaining = bytes->count - i - 1;
- result = (bytes->pid != INVALID_PATTERN_ID);
+ bytes->count += (extra_count - 1);
+ bytes->raw = realloc(bytes->raw, bytes->count * sizeof(sized_binary_t));
+ memmove(&bytes->raw[i + extra_count], &bytes->raw[i + 1], remaining * sizeof(sized_binary_t));
- return result;
+ for (k = 0; k < extra_count; k++)
+ bytes->raw[i + k] = extra[k];
+
+ free(extra);
+
+ bytes->atoms = realloc(bytes->raw, bytes->count * sizeof(tracked_scan_atom_t));
+
+ for (k = 0; k < extra_count; k++)
+ bytes->atoms[i + k] = atom;
+ i += extra_count - 1;
+
+ }
+
+ }
+
+ else
+ find_best_atom(&bytes->raw[i], maxsize, &bytes->atoms[i], &letters);
+
+ }
+
+ /* Enregistrements en masse */
+
+
+ for (i = 0; i < bytes->count && result; i++)
+ result = enroll_prepared_atom(&bytes->raw[i], context, backend, &bytes->atoms[i]);
+
+ exit:
+
+ return result;
+#endif
}
@@ -299,76 +430,64 @@ static bool g_plain_bytes_enroll(GPlainBytes *bytes, GScanContext *context, GEng
* *
******************************************************************************/
-static void g_plain_bytes_check(const GPlainBytes *bytes, GScanContext *context, GBinContent *content, pending_matches_t *matches)
+static void g_scan_plain_bytes_check(const GScanPlainBytes *bytes, GScanContext *context, GBinContent *content, pending_matches_t *matches)
{
- bool initialized; /* Initialisation du suivi ? */
+#if 0
+
+ size_t i; /* Boucle de parcours #1 */
+ const sized_binary_t *raw; /* Données brutes d'origine */
+ const tracked_scan_atom_t *atom; /* Atome correspondant */
size_t count; /* Quantité de bribes trouvées */
const phys_t *found; /* Localisations des bribes */
- size_t mindex; /* Indice d'élément à compléter*/
- size_t i; /* Boucle de parcours */
+ size_t k; /* Boucle de parcours #2 */
phys_t start; /* Point de départ */
vmpa2t pos; /* Position dans les données */
const bin_t *ptr; /* Accès aux données brutes */
int ret; /* Bilan d'une comparaison */
- initialized = are_pending_matches_initialized(matches);
-
- found = g_scan_context_get_atom_matches(context, bytes->pid, &count);
-
- mindex = 0;
-
- for (i = 0; i < count; i++)
+ for (i = 0; i < bytes->count; i++)
{
- start = found[i] - bytes->atom_pos;
-
- /* Recherche d'un point de départ attendu et conforme ? */
+ raw = &bytes->raw[i];
+ atom = &bytes->atoms[i];
- if (initialized)
- if (!find_target_in_pending_matches(matches, start, &mindex))
- continue;
+ found = g_scan_context_get_atom_matches(context, atom->pid, &count);
- init_vmpa(&pos, start, VMPA_NO_VIRTUAL);
-
- /* Validation du contenu avant l'atome */
-
- if (bytes->atom_pos > 0)
+ for (k = 0; k < count; k++)
{
- ptr = g_binary_content_get_raw_access(content, &pos, bytes->atom_len);
-
- ret = memcmp(bytes->raw + bytes->atom_pos, ptr, bytes->atom_len);
- if (ret != 0) goto exclude_false_positive;
+ start = found[k] - atom->pos;
- }
+ init_vmpa(&pos, start, VMPA_NO_VIRTUAL);
- /* Validation du contenu après l'atome */
+ /* Validation du contenu avant l'atome */
- if (bytes->atom_rem > 0)
- {
- advance_vmpa(&pos, bytes->atom_len);
+ if (atom->pos > 0)
+ {
+ ptr = g_binary_content_get_raw_access(content, &pos, atom->pos);
- ptr = g_binary_content_get_raw_access(content, &pos, bytes->atom_rem);
+ ret = memcmp(raw->data, ptr, atom->pos);
+ if (ret != 0) continue;
- ret = memcmp(bytes->raw + bytes->atom_pos + bytes->atom_len, ptr, bytes->atom_rem);
- if (ret != 0) goto exclude_false_positive;
+ }
- }
+ /* Validation du contenu après l'atome */
- /* Mémorisation de la correspondance */
+ if (atom->rem > 0)
+ {
+ advance_vmpa(&pos, atom->len);
- if (initialized)
- extend_pending_matches(matches, mindex, bytes->used);
- else
- add_pending_matches(matches, start, bytes->used);
+ ptr = g_binary_content_get_raw_access(content, &pos, atom->rem);
- continue;
+ ret = memcmp(raw->data + atom->pos + atom->len, ptr, atom->rem);
+ if (ret != 0) continue;
- exclude_false_positive:
+ }
- if (initialized)
- remove_pending_matches(matches, mindex);
+ /* Mémorisation de la correspondance */
- }
+ add_pending_matches(matches, start, raw->len);
- set_pending_matches_initialized(matches);
+ }
+ }
+#endif
}