diff options
Diffstat (limited to 'src/analysis/scan/patterns/tokens/atom.c')
| -rw-r--r-- | src/analysis/scan/patterns/tokens/atom.c | 228 |
1 files changed, 179 insertions, 49 deletions
diff --git a/src/analysis/scan/patterns/tokens/atom.c b/src/analysis/scan/patterns/tokens/atom.c index 52f239c..4f2ad67 100644 --- a/src/analysis/scan/patterns/tokens/atom.c +++ b/src/analysis/scan/patterns/tokens/atom.c @@ -26,6 +26,7 @@ #include <assert.h> #include <malloc.h> +#include <math.h> @@ -43,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. * @@ -54,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 */ @@ -69,7 +71,7 @@ int rate_byte_quality(bin_t ch, bitfield_t *seen, size_t *letters) break; case 'A' ... 'Z': - case 'z' ... 'z': + case 'a' ... 'z': if (letters == NULL) result = 20; else @@ -85,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; @@ -94,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. * * * @@ -105,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); @@ -128,6 +183,8 @@ int finish_quality_rating(const bitfield_t *seen, size_t max) else result = uniq * 2; + result += rating; + return result; } @@ -154,12 +211,16 @@ void find_best_atom(const sized_binary_t *raw, size_t maxsize, tracked_scan_atom bin_t ch; /* Octets à étudier */ size_t best_letters; /* Mémorisation de décompte */ size_t *ptr_letters; /* Pointeur vers le décompte */ + int raw_rating; /* Notation brute de séquence */ + uint8_t seen[256]; /* Mémorisation des passages */ + size_t uniq; /* Nombre d'octets originaux */ + const bin_t *last; /* Dernier caractère étudié */ int best_rating; /* Meilleur notation obtenue */ - bitfield_t *seen; /* Mémorise les octets déjà vus*/ size_t max_loop; /* Limitation des itérations */ 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) @@ -168,6 +229,8 @@ void find_best_atom(const sized_binary_t *raw, size_t maxsize, tracked_scan_atom atom->len = raw->len; atom->rem = 0; + atom->fast_check = true; + if (letters != NULL) { *letters = 0; @@ -196,14 +259,17 @@ void find_best_atom(const sized_binary_t *raw, size_t maxsize, tracked_scan_atom ptr_letters = (letters != NULL ? &best_letters : NULL); best_letters = 0; - best_rating = 0; + raw_rating = 0; + + memset(seen, 0, sizeof(seen)); + uniq = 0; - seen = create_bit_field(256, false); + last = raw->static_bin_data; for (k = 0; k < maxsize; k++) - best_rating += rate_byte_quality(raw->data[k], seen, ptr_letters); + raw_rating += rate_byte_quality(*last++, seen, &uniq, ptr_letters); - best_rating += finish_quality_rating(seen, maxsize); + best_rating = finish_quality_rating(raw_rating, uniq, maxsize); /* Parcours du reste du contenu */ @@ -211,21 +277,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++) + { + raw_rating += rate_byte_quality(*last++, seen, &uniq, ptr_letters); + raw_rating -= unrate_byte_quality(*first++, seen, &uniq, ptr_letters); - local_rating += finish_quality_rating(seen, maxsize); + local_rating = finish_quality_rating(raw_rating , uniq, maxsize); if (local_rating > best_rating) { - atom->pos = i; + atom->pos = i + 1; best_letters = local_letters; best_rating = local_rating; @@ -236,15 +302,18 @@ 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; + if (letters != NULL) *letters = best_letters; } + assert((atom->fast_check && atom->pos == 0 && atom->rem == 0) + || (!atom->fast_check && (atom->pos != 0 || atom->rem != 0))); + } @@ -340,11 +409,11 @@ sized_binary_t *make_atoms_case_insensitive(const sized_binary_t *src, const tra /****************************************************************************** * * -* Paramètres : byte = octet partiel à interpréter. * -* mask = valeur du masque à appliquer. * +* Paramètres : bytes = octets partiels avec leur masque à interpréter. * +* len = quantité d'octets à interpréter. * * produced = nombre de contenus générés. [OUT] * * * -* Description : Etablit la liste des cas de figures avec un octet partiel. * +* Description : Etablit la liste des cas de figures avec des octets partiels.* * * * Retour : Liste de toutes les combinaisons possibles. * * * @@ -352,28 +421,66 @@ sized_binary_t *make_atoms_case_insensitive(const sized_binary_t *src, const tra * * ******************************************************************************/ -sized_binary_t *make_atoms_from_masked_byte(bin_t value, bin_t mask, size_t *produced) +sized_binary_t *make_atoms_from_masked_bytes(const masked_byte_t *bytes, size_t len, size_t *produced) { sized_binary_t *result; /* Liste à retourner */ + size_t seq_len; /* Taille de séquence retenue */ + size_t repeat_times; /* Répétitions pour remplissage*/ + sized_binary_t *maxiter; /* Borne de fin de parcours */ size_t i; /* Boucle de parcours #1 */ + sized_binary_t *iter; /* Boucle de parcours #2 */ + size_t j; /* Boucle de parcours #3 */ + size_t k; /* Boucle de parcours #4 */ + + seq_len = (len > MASK_MAX_LEN_FOR_ATOMS ? MASK_MAX_LEN_FOR_ATOMS : len); - *produced = 16; + /** + * Si l'usage de la fonction pow() disparaît, la bibliothèque m + * peut être retirée de libchrysacore_la_LDFLAGS dans le Makefile + * principal. + */ + repeat_times = pow(16, seq_len - 1); + + *produced = 16 * repeat_times; /* Création du réceptacle */ - result = malloc(16 * sizeof(tracked_scan_atom_t)); + result = malloc(*produced * sizeof(tracked_scan_atom_t)); + + maxiter = result + *produced; /* Remplissage */ - for (i = 0; i < 16; i++) + for (i = 0; i < seq_len; i++) { - result[i].data = malloc(1); - result[i].len = 1; + for (iter = result; iter < maxiter; ) + { + for (j = 0; j < 16; j++) + { + assert(bytes[i].mask == 0x0f || bytes[i].mask == 0xf0); - if (mask == 0x0f) - result[i].data[0] = value | (i << 4); - else - result[i].data[0] = value | i; + for (k = 0; k < repeat_times; k++) + { + if (i == 0) + { + iter->data = malloc(seq_len); + iter->len = seq_len; + } + + if (bytes[i].mask == 0x0f) + iter->data[i] = bytes[i].value | (j << 4); + else + iter->data[i] = bytes[i].value | j; + + iter++; + + } + + } + + } + + repeat_times /= 16; } @@ -385,11 +492,10 @@ sized_binary_t *make_atoms_from_masked_byte(bin_t value, bin_t mask, size_t *pro /****************************************************************************** * * * Paramètres : raw = définition de la bribe à enregistrer. * -* context = contexte de l'analyse à mener. * * backend = moteur de recherche à préchauffer. * * atom = informations de suivi constituées. [OUT] * * * -* Description : Enregistre l'atome déterminé d'une série d'octets. * +* Description : Amorce l'insertion de l'atome déterminé d'une série d'octets.* * * * Retour : Bilan de l'opération à renvoyer. * * * @@ -397,14 +503,38 @@ sized_binary_t *make_atoms_from_masked_byte(bin_t value, bin_t mask, size_t *pro * * ******************************************************************************/ -bool enroll_prepared_atom(const sized_binary_t *raw, GScanContext *context, GEngineBackend *backend, tracked_scan_atom_t *atom) +bool enroll_prepared_atom(const sized_binary_t *raw, GEngineBackend *backend, tracked_scan_atom_t *atom) { 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); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : atom = informations de suivi constituées. [OUT] * +* backend = moteur de recherche à préchauffer. * +* * +* Description : Récupère un identifiant final pour un atome d'octets. * +* * +* Retour : Bilan de l'opération à renvoyer. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool build_atom_pattern_id(tracked_scan_atom_t *atom, GEngineBackend *backend) +{ + bool result; /* Statut à retourner */ - atom->pid = g_engine_backend_enroll_plain_pattern(backend, context, data, atom->len); + atom->pid = g_engine_backend_build_plain_pattern_id(backend, atom->tmp_id); result = (atom->pid != INVALID_PATTERN_ID); |
