From a32ea5bc193d8ea2f3349742cf816f8233354c8d Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Thu, 8 Feb 2024 23:08:58 +0100 Subject: Discard bit fields to find the bast atoms. --- src/analysis/scan/patterns/tokens/atom.c | 120 +++++++++++++++++++++++-------- src/analysis/scan/patterns/tokens/atom.h | 8 ++- 2 files changed, 95 insertions(+), 33 deletions(-) diff --git a/src/analysis/scan/patterns/tokens/atom.c b/src/analysis/scan/patterns/tokens/atom.c index 580ad30..f59c81c 100644 --- a/src/analysis/scan/patterns/tokens/atom.c +++ b/src/analysis/scan/patterns/tokens/atom.c @@ -44,7 +44,8 @@ /****************************************************************************** * * * Paramètres : ch = octet dont la valeur est à analyser. * -* seen = suivi des octets déjà rencontrés. [OUT] * +* seen = suivi des octets déjà rencontrés. [OUT] * +* uniq = volume d'octets originaux à actualiser. [OUT] * * letters = nombre de lettres rencontrées. [OUT] * * * * Description : Note l'intêret de rechercher un octet particulier. * @@ -55,7 +56,7 @@ * * ******************************************************************************/ -int rate_byte_quality(bin_t ch, bitfield_t *seen, size_t *letters) +int rate_byte_quality(bin_t ch, uint8_t *seen, size_t *uniq, size_t *letters) { int result; /* Note à retourner */ @@ -86,7 +87,8 @@ int rate_byte_quality(bin_t ch, bitfield_t *seen, size_t *letters) } - set_in_bit_field(seen, ch, 1); + if (seen[ch]++ == 0) + (*uniq)++; return result; @@ -95,8 +97,67 @@ int rate_byte_quality(bin_t ch, bitfield_t *seen, size_t *letters) /****************************************************************************** * * -* Paramètres : seen = suivi des octets déjà rencontrés. * -* max = nombre d'octets considérés à la base. * +* Paramètres : ch = octet dont la valeur est à analyser. * +* seen = suivi des octets déjà rencontrés. [OUT] * +* uniq = volume d'octets originaux à actualiser. [OUT] * +* letters = nombre de lettres rencontrées. [OUT] * +* * +* Description : Annihile l'intêret de rechercher un octet particulier. * +* * +* Retour : Note positive ou négative. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int unrate_byte_quality(bin_t ch, uint8_t *seen, size_t *uniq, size_t *letters) +{ + int result; /* Note à retourner */ + + switch (ch) + { + case 0x00: + case 0x20: + case 0x90: + case 0xcc: + case 0xff: + result = 12; + break; + + case 'A' ... 'Z': + case 'a' ... 'z': + if (letters == NULL) + result = 20; + else + { + result = 18; + assert(*letters > 0); + (*letters)--; + } + break; + + default: + result = 20; + break; + + } + + if (--seen[ch] == 0) + { + assert(*uniq > 0); + (*uniq)--; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : rating = note d'évaluation courante. * +* uniq = volume d'octets originaux relevés. * +* max = nombre d'octets considérés à la base. * * * * Description : Termine la notation d'un ensemble d'octets. * * * @@ -106,21 +167,14 @@ int rate_byte_quality(bin_t ch, bitfield_t *seen, size_t *letters) * * ******************************************************************************/ -int finish_quality_rating(const bitfield_t *seen, size_t max) +int finish_quality_rating(int rating, size_t uniq, size_t max) { int result; /* Note à retourner */ - size_t uniq; /* Quantié d'octets uniques */ bool bad; /* Indice de mauvaise qualité */ - uniq = popcount_for_bit_field(seen); - if (uniq == 1) { - bad = test_in_bit_field(seen, 0x00) - || test_in_bit_field(seen, 0x20) - || test_in_bit_field(seen, 0x90) - || test_in_bit_field(seen, 0xcc) - || test_in_bit_field(seen, 0xff); + bad = (rating % 12) == 0; result = (bad ? -10 * max : 2); @@ -129,6 +183,8 @@ int finish_quality_rating(const bitfield_t *seen, size_t max) else result = uniq * 2; + result += rating; + return result; } @@ -156,11 +212,14 @@ void find_best_atom(const sized_binary_t *raw, size_t maxsize, tracked_scan_atom size_t best_letters; /* Mémorisation de décompte */ size_t *ptr_letters; /* Pointeur vers le décompte */ int best_rating; /* Meilleur notation obtenue */ - bitfield_t *seen; /* Mémorise les octets déjà vus*/ + uint8_t seen[256]; /* Mémorisation des passages */ + size_t uniq; /* Nombre d'octets originaux */ size_t max_loop; /* Limitation des itérations */ + const bin_t *last; /* Dernier caractère étudié */ size_t k; /* Boucle de parcours #2 */ size_t local_letters; /* Décompte courant des lettres*/ int local_rating; /* Notation courante */ + const bin_t *first; /* Premier caractère étudié */ /* Si la chaîne fournie est plus petite que la taille d'un atome... */ if (raw->len <= maxsize) @@ -201,12 +260,15 @@ void find_best_atom(const sized_binary_t *raw, size_t maxsize, tracked_scan_atom best_letters = 0; best_rating = 0; - seen = create_bit_field(256, false); + memset(seen, 0, sizeof(seen)); + uniq = 0; + + last = raw->static_bin_data; for (k = 0; k < maxsize; k++) - best_rating += rate_byte_quality(raw->data[k], seen, ptr_letters); + best_rating += rate_byte_quality(*last++, seen, &uniq, ptr_letters); - best_rating += finish_quality_rating(seen, maxsize); + best_rating = finish_quality_rating(best_rating, uniq, maxsize); /* Parcours du reste du contenu */ @@ -214,21 +276,21 @@ void find_best_atom(const sized_binary_t *raw, size_t maxsize, tracked_scan_atom ptr_letters = (letters != NULL ? &local_letters : NULL); - for (i = 1; i < max_loop; i++) - { - local_letters = 0; - local_rating = 0; + local_letters = best_letters; + local_rating = best_rating; - reset_all_in_bit_field(seen); + first = raw->static_bin_data; - for (k = 0; k < maxsize; k++) - local_rating += rate_byte_quality(raw->data[i + k], seen, ptr_letters); + for (i = 0; i < max_loop; i++) + { + local_rating += rate_byte_quality(*last++, seen, &uniq, ptr_letters); + local_rating -= rate_byte_quality(*first++, seen, &uniq, ptr_letters); - local_rating += finish_quality_rating(seen, maxsize); + local_rating = finish_quality_rating(local_rating, uniq, maxsize); if (local_rating > best_rating) { - atom->pos = i; + atom->pos = maxsize + i; best_letters = local_letters; best_rating = local_rating; @@ -239,8 +301,6 @@ void find_best_atom(const sized_binary_t *raw, size_t maxsize, tracked_scan_atom /* Conclusion */ - delete_bit_field(seen); - atom->rem = raw->len - atom->pos - maxsize; atom->fast_check = false; @@ -447,7 +507,7 @@ bool enroll_prepared_atom(const sized_binary_t *raw, GEngineBackend *backend, tr bool result; /* Statut à retourner */ const bin_t *data; /* Données à rechercher */ - data = raw->data + atom->pos; + data = raw->static_bin_data + atom->pos; result = g_engine_backend_enroll_plain_pattern(backend, data, atom->len, atom->tmp_id); diff --git a/src/analysis/scan/patterns/tokens/atom.h b/src/analysis/scan/patterns/tokens/atom.h index 1d912d7..1ef8f40 100644 --- a/src/analysis/scan/patterns/tokens/atom.h +++ b/src/analysis/scan/patterns/tokens/atom.h @@ -30,7 +30,6 @@ #include "../backend.h" #include "../../../../arch/vmpa.h" -#include "../../../../common/bits.h" #include "../../../../common/szstr.h" @@ -51,10 +50,13 @@ typedef struct _tracked_scan_atom_t } tracked_scan_atom_t; /* Note l'intêret de rechercher un octet particulier. */ -int rate_byte_quality(bin_t, bitfield_t *, size_t *); +int rate_byte_quality(bin_t, uint8_t *, size_t *, size_t *); + +/* Annihile l'intêret de rechercher un octet particulier. */ +int unrate_byte_quality(bin_t, uint8_t *, size_t *, size_t *); /* Termine la notation d'un ensemble d'octets. */ -int finish_quality_rating(const bitfield_t *, size_t); +int finish_quality_rating(int, size_t, size_t); /* Détermine la portion idéale de recherche. */ void find_best_atom(const sized_binary_t *, size_t , tracked_scan_atom_t *, size_t *); -- cgit v0.11.2-87-g4458