From 24945cea340b7b0ca0fe2ccad7b67519dda1c1bd Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 28 Jan 2024 22:27:09 +0100 Subject: Implement a basic support for Hyperscan. --- configure.ac | 15 + src/Makefile.am | 2 +- src/analysis/scan/patterns/backends/Makefile.am | 6 +- .../scan/patterns/backends/hyperscan-int.h | 67 +++ src/analysis/scan/patterns/backends/hyperscan.c | 648 +++++++++++++++++++++ src/analysis/scan/patterns/backends/hyperscan.h | 59 ++ src/rost.c | 13 +- 7 files changed, 802 insertions(+), 8 deletions(-) create mode 100644 src/analysis/scan/patterns/backends/hyperscan-int.h create mode 100644 src/analysis/scan/patterns/backends/hyperscan.c create mode 100644 src/analysis/scan/patterns/backends/hyperscan.h diff --git a/configure.ac b/configure.ac index 55e8f65..cfb94bd 100644 --- a/configure.ac +++ b/configure.ac @@ -541,6 +541,20 @@ if test "x$enable_magic_support" = "xyes"; then fi +#--- Checks for Hyperscan + +PKG_CHECK_MODULES(LIBHS,libhs >= 5.4.9,[libhs_found=yes],[libhs_found=no]) + +if test "$libhs_found" = "yes"; then + libhs_version=`pkg-config libhs --modversion` +else + libhs_version='-' +fi + +AC_SUBST(LIBHS_CFLAGS) +AC_SUBST(LIBHS_LIBS) + + #--- Checks for Python if test "x$enable_debug" = "xyes"; then @@ -822,6 +836,7 @@ echo The cryptography and SSL/TLS toolkit......... : $libssl_version echo The client URL library....................... : $libcurl_version echo The YAML support library..................... : $libyaml_version echo The magic number recognition library......... : $libmagic_version +echo The high-performance matching library........ : $libhs_version echo echo Available Python programming language........ : $python3_version diff --git a/src/Makefile.am b/src/Makefile.am index e7aa395..9dc053e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -59,7 +59,7 @@ libchrysacore_la_LDFLAGS = \ -avoid-version -ldl -lm \ $(TOOLKIT_LIBS) $(LIBXML_LIBS) \ $(LIBSQLITE_LIBS) $(LIBARCHIVE_LIBS) \ - $(LIBSSL_LIBS) + $(LIBSSL_LIBS) $(LIBHS_LIBS) if BUILD_CURL_SUPPORT diff --git a/src/analysis/scan/patterns/backends/Makefile.am b/src/analysis/scan/patterns/backends/Makefile.am index 672b7ff..23b0163 100644 --- a/src/analysis/scan/patterns/backends/Makefile.am +++ b/src/analysis/scan/patterns/backends/Makefile.am @@ -6,11 +6,13 @@ libanalysisscanpatternsbackends_la_SOURCES = \ acism-int.h \ acism.h acism.c \ bitap-int.h \ - bitap.h bitap.c + bitap.h bitap.c \ + hyperscan-int.h \ + hyperscan.h hyperscan.c # Cf. https://www.gnu.org/software/automake/manual/html_node/Per_002dObject-Flags.html -AM_CFLAGS = $(LIBGOBJ_CFLAGS) +AM_CFLAGS = $(LIBGOBJ_CFLAGS) $(LIBHS_CFLAGS) diff --git a/src/analysis/scan/patterns/backends/hyperscan-int.h b/src/analysis/scan/patterns/backends/hyperscan-int.h new file mode 100644 index 0000000..31d271b --- /dev/null +++ b/src/analysis/scan/patterns/backends/hyperscan-int.h @@ -0,0 +1,67 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * hyperscan-int.h - prototypes internes pour la méthode de recherche basée sur la bibliothèque Hyperscan d'Intel + * + * Copyright (C) 2024 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _ANALYSIS_SCAN_PATTERNS_BACKENDS_HYPERSCAN_INT_H +#define _ANALYSIS_SCAN_PATTERNS_BACKENDS_HYPERSCAN_INT_H + + +#include "hyperscan.h" + + +#include "../backend-int.h" + + + +#define EXPR_COVERAGE_START 0 +#define EXPR_COVERAGE_COUNT 1 +#define EXPR_COVERAGE_END 1 + + +/* Méthode de recherche basée sur une bibliothèque d'Intel : Hyperscan (instance) */ +struct _GHyperscanBackend +{ + GEngineBackend parent; /* A laisser en premier */ + + const uint8_t **atoms; /* Motif remarquable */ + size_t *lengths; /* Nombre d'octets considérés */ + uint32_t *coverages; /* Départ et quantité de suivis*/ + size_t allocated; /* Nombre d'éléments alloués */ + size_t used; /* Nombre d'éléments utiles */ + + unsigned int *lit_ids; /* Identifiants internes */ + + hs_database_t *database; /* Compilation d'éléments */ + hs_scratch_t *scratch; /* Espace de travail */ + +}; + +/* Méthode de recherche basée sur une bibliothèque d'Intel : Hyperscan (classe) */ +struct _GHyperscanBackendClass +{ + GEngineBackendClass parent; /* A laisser en premier */ + +}; + + + +#endif /* _ANALYSIS_SCAN_PATTERNS_BACKENDS_HYPERSCAN_INT_H */ diff --git a/src/analysis/scan/patterns/backends/hyperscan.c b/src/analysis/scan/patterns/backends/hyperscan.c new file mode 100644 index 0000000..5d535e3 --- /dev/null +++ b/src/analysis/scan/patterns/backends/hyperscan.c @@ -0,0 +1,648 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * hyperscan.c - méthode de recherche basée sur la bibliothèque Hyperscan d'Intel + * + * Copyright (C) 2024 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "hyperscan.h" + + +#include +#include + + +#include + + +#include "hyperscan-int.h" +#include "../../../../core/logs.h" + + + +/* ---------------------- IMPLANTATION D'UNE NOUVELLE APPROCHE ---------------------- */ + + +/* Initialise la classe des méthodes basée sur Hyperscan. */ +static void g_hyperscan_backend_class_init(GHyperscanBackendClass *); + +/* Initialise une instance de méthodes basée sur Hyperscan. */ +static void g_hyperscan_backend_init(GHyperscanBackend *); + +/* Supprime toutes les références externes. */ +static void g_hyperscan_backend_dispose(GHyperscanBackend *); + +/* Procède à la libération totale de la mémoire. */ +static void g_hyperscan_backend_finalize(GHyperscanBackend *); + + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + +/* Indique la taille maximale des suites d'octets recherchées. */ +size_t g_hyperscan_backend_get_atom_max_size(const GHyperscanBackend *); + +/* Inscrit dans le moteur une chaîne de caractères à rechercher. */ +static bool g_hyperscan_backend_enroll_plain_pattern(GHyperscanBackend *, const uint8_t *, size_t, uint32_t [2]); + +/* Met en ordre les derniers détails avant un premier scan. */ +static bool g_hyperscan_backend_warm_up(GHyperscanBackend *); + +/* Récupère les identifiants finaux pour un motif recherché. */ +static patid_t g_hyperscan_backend_build_plain_pattern_id(const GHyperscanBackend *, const uint32_t [2]); + +/* Détermine le nombre d'identifiants constitués. */ +static size_t g_hyperscan_backend_count_plain_pattern_ids(const GHyperscanBackend *); + +/* Informations utiles au traitement d'un événement */ +typedef struct _hyperscan_context_t +{ + const size_t *lengths; /* Nombre d'octets considérés */ + const uint32_t *coverages; /* Départ et quantité de suivis*/ + +#ifndef NDEBUG + size_t used; /* Nombre d'éléments utiles */ + const unsigned int *lit_ids; /* Identifiants internes */ +#endif + + GUMemSlice **matches; /* Zones d'enregistrements */ + +} hyperscan_context_t; + +/* Prend note d'une correspondance trouvée par Hyperscan. */ +static int handle_hyperscan_match_event(unsigned int, unsigned long long, unsigned long long, unsigned int, const hyperscan_context_t *); + +/* Parcours un contenu binaire à la recherche de motifs. */ +static void g_hyperscan_backend_run_scan(const GHyperscanBackend *, GScanContext *); + +/* Imprime quelques faits quant aux éléments mis en place. */ +static void g_hyperscan_backend_output_stats(const GHyperscanBackend *); + + + +/* ---------------------------------------------------------------------------------- */ +/* IMPLANTATION D'UNE NOUVELLE APPROCHE */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour un moteur de recherche pour données. */ +G_DEFINE_TYPE(GHyperscanBackend, g_hyperscan_backend, G_TYPE_ENGINE_BACKEND); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des méthodes basée sur Hyperscan. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_hyperscan_backend_class_init(GHyperscanBackendClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GEngineBackendClass *backend; /* Version de classe parente */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_hyperscan_backend_dispose; + object->finalize = (GObjectFinalizeFunc)g_hyperscan_backend_finalize; + + backend = G_ENGINE_BACKEND_CLASS(klass); + + backend->get_max_size = (get_backend_atom_max_size_fc)g_hyperscan_backend_get_atom_max_size; + backend->enroll_plain = (enroll_plain_into_backend_fc)g_hyperscan_backend_enroll_plain_pattern; + backend->warm_up = (warm_up_backend_fc)g_hyperscan_backend_warm_up; + backend->build_id = (build_backend_plain_pattern_id_fc)g_hyperscan_backend_build_plain_pattern_id; + backend->count_ids = (count_backend_plain_pattern_ids_fc)g_hyperscan_backend_count_plain_pattern_ids; + backend->run_scan = (run_backend_scan_fc)g_hyperscan_backend_run_scan; + backend->output = (output_backend_stats_fc)g_hyperscan_backend_output_stats; + +} + + +/****************************************************************************** +* * +* Paramètres : backend = instance à initialiser. * +* * +* Description : Initialise une instance de méthodes basée sur Hyperscan. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_hyperscan_backend_init(GHyperscanBackend *backend) +{ + backend->atoms = NULL; + backend->lengths = NULL; + backend->coverages = NULL; + backend->allocated = 0; + backend->used = 0; + + backend->database = NULL; + backend->scratch = NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : backend = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_hyperscan_backend_dispose(GHyperscanBackend *backend) +{ + G_OBJECT_CLASS(g_hyperscan_backend_parent_class)->dispose(G_OBJECT(backend)); + +} + + +/****************************************************************************** +* * +* Paramètres : backend = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_hyperscan_backend_finalize(GHyperscanBackend *backend) +{ + if (backend->atoms != NULL) + free(backend->atoms); + + if (backend->lengths != NULL) + free(backend->lengths); + + if (backend->coverages != NULL) + free(backend->coverages); + + if (backend->scratch != NULL) + hs_free_scratch(backend->scratch); + + if (backend->database != NULL) + hs_free_database(backend->database); + + G_OBJECT_CLASS(g_hyperscan_backend_parent_class)->finalize(G_OBJECT(backend)); + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée une méthode de recherche avec la bibliothèque Hyperscan.* +* * +* Retour : Méthode mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GEngineBackend *g_hyperscan_backend_new(void) +{ + GHyperscanBackend *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_HYPERSCAN_BACKEND, NULL); + + return G_ENGINE_BACKEND(result); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : backend = moteur de recherche à consulter. * +* * +* Description : Indique la taille maximale des suites d'octets recherchées. * +* * +* Retour : Valeur strictement positive. * +* * +* Remarques : - * +* * +******************************************************************************/ + +size_t g_hyperscan_backend_get_atom_max_size(const GHyperscanBackend *backend) +{ + size_t result; /* Taille à faire connaître */ + + result = ~0; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : backend = moteur de recherche à manipuler. * +* plain = chaîne de caractères classique à intégrer. * +* len = taille de cette chaîne. * +* tmp_id = identifiants temporaires vers le motif. [OUT] * +* * +* Description : Inscrit dans le moteur une chaîne de caractères à rechercher.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_hyperscan_backend_enroll_plain_pattern(GHyperscanBackend *backend, const uint8_t *plain, size_t len, uint32_t tmp_id[2]) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + int ret; /* Bilan d'une comparaison */ + + result = true; + + /*Recherche d'un motif déjà sollicité */ + + for (i = 0; i < backend->used; i++) + { + if (backend->lengths[i] != len) + continue; + + ret = memcmp(backend->atoms[i], plain, backend->lengths[i]); + + if (ret == 0) + { + tmp_id[0] = i; + tmp_id[1] = backend->coverages[i * 2 + EXPR_COVERAGE_COUNT]; + + backend->coverages[i * 2 + EXPR_COVERAGE_COUNT]++; + break; + + } + + } + + /* Introduction d'un nouveau motif au besoin */ + + if (i == backend->used) + { + if (backend->used == backend->allocated) + { + if (backend->allocated == 0) + backend->allocated = 64; + else + backend->allocated *= 2; + + backend->atoms = realloc(backend->atoms, backend->allocated * sizeof(const uint8_t *)); + backend->lengths = realloc(backend->lengths, backend->allocated * sizeof(size_t)); + backend->coverages = realloc(backend->coverages, backend->allocated * 2 * sizeof(uint32_t)); + + } + + backend->atoms[i] = plain; + backend->lengths[i] = len; + backend->coverages[i * 2 + EXPR_COVERAGE_COUNT] = 1; + + backend->used++; + + tmp_id[0] = i; + tmp_id[1] = 0; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : backend = moteur de recherche à préparer. * +* * +* Description : Met en ordre les derniers détails avant un premier scan. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_hyperscan_backend_warm_up(GHyperscanBackend *backend) +{ + bool result; /* Bilan à retourner */ + uint32_t current_start; /* Indice de gestionnaire */ + size_t i; /* Boucle de parcours */ + hs_compile_error_t *error; /* Compléments d'information */ + hs_error_t ret; /* Code de retour */ + + hs_platform_info_t platform; + + result = false; + + /* Mise à jour de la couverture des gestionnaires de suivi */ + + current_start = 0; + + for (i = 0; i < backend->used; i++) + { + backend->coverages[i * 2 + EXPR_COVERAGE_START] = current_start; + backend->coverages[i * 2 + EXPR_COVERAGE_END] += current_start; + + current_start = backend->coverages[i * 2 + EXPR_COVERAGE_END]; + + } + + /* Enregistrement des expressions à prendre en compte */ + + backend->lit_ids = malloc(backend->used * sizeof(unsigned)); + + for (i = 0; i < backend->used; i++) + backend->lit_ids[i] = i; + + //hs_populate_platform(&platform); + + //platform.tune = 1; + + //platform.cpu_features = HS_CPU_FEATURES_AVX512; + + ret = hs_compile_lit_multi((const char *const *)backend->atoms, NULL, backend->lit_ids, backend->lengths, + backend->used, HS_MODE_BLOCK, NULL, &backend->database, &error); + + + //printf("ret: %d -vs- %d\n", ret, HS_SUCCESS); + + if (ret != HS_SUCCESS) + { + log_variadic_message(LMT_EXT_ERROR, _("Unable to compile %zu patterns: \"%s\""), + backend->used, error->message); + printf("FAILED: %s\n", error->message); + hs_free_compile_error(error); + goto exit; + } + +#if 0 + do + { + //hs_platform_info_t platform; + char *__info; + + //hs_populate_platform(&platform); + + printf("TUNE: %u\n", platform.tune); + + printf("CPU: %llx - AVX2? %d - AVX512? %d\n", platform.cpu_features, + platform.cpu_features & HS_CPU_FEATURES_AVX2, + platform.cpu_features & HS_CPU_FEATURES_AVX512); + + hs_database_info(backend->database, &__info); + + printf("INFO: %s\n", __info); + + } + while (0); +#endif + + /* Création d'un espace de travail */ + + ret = hs_alloc_scratch(backend->database, &backend->scratch); + + //printf("ret: %d -vs- %d\n", ret, HS_SUCCESS); + + if (ret != HS_SUCCESS) + { + log_variadic_message(LMT_EXT_ERROR, _("Unable to allocate scratch space")); + goto exit; + } + + result = true; + + exit: + + //printf("result: %d\n", result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : backend = moteur de recherche à manipuler. * +* tmp_id = identifiants temporaires vers le motif. [OUT] * +* * +* Description : Récupère les identifiants finaux pour un motif recherché. * +* * +* Retour : Identifiant constitué ou INVALID_PATTERN_ID en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static patid_t g_hyperscan_backend_build_plain_pattern_id(const GHyperscanBackend *backend, const uint32_t tmp_id[2]) +{ + patid_t result; /* Identifiant à retourner */ + size_t index; /* Indice reconstitué */ + + assert(tmp_id[0] < backend->used); + + index = tmp_id[0] * 2; + + result = backend->coverages[index + EXPR_COVERAGE_START] + tmp_id[1]; + + assert(result < backend->coverages[index + EXPR_COVERAGE_END]); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : backend = moteur de recherche à manipuler. * +* * +* Description : Détermine le nombre d'identifiants constitués. * +* * +* Retour : Quantité de gestionnaires de suivi à prévoir. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static size_t g_hyperscan_backend_count_plain_pattern_ids(const GHyperscanBackend *backend) +{ + size_t result; /* Quantité à retourner */ + + if (backend->used == 0) + result = 0; + else + result = backend->coverages[(backend->used - 1) * 2 + EXPR_COVERAGE_END]; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : backend = moteur de recherche à manipuler. * +* context = lieu d'enregistrement des résultats. * +* * +* Description : Prend note d'une correspondance trouvée par Hyperscan. * +* * +* Retour : 0 afin de poursuivre les recherches. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int handle_hyperscan_match_event(unsigned int id, unsigned long long from, unsigned long long to, unsigned int flags, const hyperscan_context_t *context) +{ + phys_t offset; /* Point de départ établi */ + const uint32_t *coverage_base; /* Base des suivis */ + uint32_t k; /* Boucle de parcours */ + uint32_t final_k; /* Dernier indice à traiter */ + + //return 0; + +#ifndef NDEBUG + assert(id < context->used); + assert(id == context->lit_ids[id]); +#endif + + offset = to - context->lengths[id]; + + coverage_base = context->coverages + id * 2; + + k = coverage_base[EXPR_COVERAGE_START]; + final_k = coverage_base[EXPR_COVERAGE_END]; + + for (; k < final_k; k++) + g_umem_slice_put_uint64(context->matches[k], offset); + + return 0; + +} + + + +/****************************************************************************** +* * +* Paramètres : backend = moteur de recherche à manipuler. * +* context = lieu d'enregistrement des résultats. * +* * +* Description : Parcours un contenu binaire à la recherche de motifs. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_hyperscan_backend_run_scan(const GHyperscanBackend *backend, GScanContext *context) +{ + GBinContent *content; /* Contenu binaire manipulé */ + phys_t dlen; /* Quantité de données */ + vmpa2t pos; /* Point de départ ciblé */ + const bin_t *data; /* Données à analyser */ +#ifndef NDEBUG + siez_t count; /* Nombre de zones prévues */ +#endif + hyperscan_context_t hcontext; /* Rassemblement d'informations*/ + GUMemSlice **matches; /* Zones d'enregistrements */ + hs_error_t ret; /* Code de retour */ + + /* Récupération d'un accès aux données */ + + content = g_scan_context_get_content(context); + + dlen = g_binary_content_compute_size(content); + + g_binary_content_compute_start_pos(content, &pos); + data = g_binary_content_get_raw_access(content, &pos, dlen); + + /* Préparation de l'accès aux éléments utiles */ + + hcontext.lengths = backend->lengths; + hcontext.coverages = backend->coverages; + +#ifndef NDEBUG + hcontext.used = backend->used; + hcontext.lit_ids = backend->lit_ids; +#endif + +#ifndef NDEBUG + matches = g_scan_context_get_match_storages(context, &count); + assert(count == backend->used); +#else + matches = g_scan_context_get_match_storages(context, (size_t []){ 0 }); +#endif + + hcontext.matches = matches; + + /* Lancement de l'analyse */ + + ret = hs_scan(backend->database, (const char *)data, dlen, + 0 /* Arg. inutilisé */, backend->scratch, + (match_event_handler)handle_hyperscan_match_event, &hcontext); + + + //printf("ret ok? %d\n", ret == HS_SUCCESS); + + + + g_object_unref(G_OBJECT(content)); + +} + + +/****************************************************************************** +* * +* Paramètres : backend = moteur de recherche à consulter. * +* * +* Description : Imprime quelques faits quant aux éléments mis en place. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_hyperscan_backend_output_stats(const GHyperscanBackend *backend) +{ + printf("TODO: %s\n", __FUNCTION__); + +} diff --git a/src/analysis/scan/patterns/backends/hyperscan.h b/src/analysis/scan/patterns/backends/hyperscan.h new file mode 100644 index 0000000..d8c0f92 --- /dev/null +++ b/src/analysis/scan/patterns/backends/hyperscan.h @@ -0,0 +1,59 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * hyperscan.h - prototypes pour la méthode de recherche basée sur la bibliothèque Hyperscan d'Intel + * + * Copyright (C) 2024 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _ANALYSIS_SCAN_PATTERNS_BACKENDS_HYPERSCAN_H +#define _ANALYSIS_SCAN_PATTERNS_BACKENDS_HYPERSCAN_H + + +#include +#include + + +#include "../backend.h" + + + +#define G_TYPE_HYPERSCAN_BACKEND g_hyperscan_backend_get_type() +#define G_HYPERSCAN_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_HYPERSCAN_BACKEND, GHyperscanBackend)) +#define G_IS_HYPERSCAN_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_HYPERSCAN_BACKEND)) +#define G_HYPERSCAN_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_HYPERSCAN_BACKEND, GHyperscanBackendClass)) +#define G_IS_HYPERSCAN_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_HYPERSCAN_BACKEND)) +#define G_HYPERSCAN_BACKEND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_HYPERSCAN_BACKEND, GHyperscanBackendClass)) + + +/* Méthode de recherche basée sur une bibliothèque d'Intel : Hyperscan (instance) */ +typedef struct _GHyperscanBackend GHyperscanBackend; + +/* Méthode de recherche basée sur une bibliothèque d'Intel : Hyperscan (classe) */ +typedef struct _GHyperscanBackendClass GHyperscanBackendClass; + + +/* Indique le type défini pour un moteur de recherche pour données. */ +GType g_hyperscan_backend_get_type(void); + +/* Crée une méthode de recherche avec la bibliothèque Hyperscan. */ +GEngineBackend *g_hyperscan_backend_new(void); + + + +#endif /* _ANALYSIS_SCAN_PATTERNS_BACKENDS_HYPERSCAN_H */ diff --git a/src/rost.c b/src/rost.c index d397a2c..4a052c3 100644 --- a/src/rost.c +++ b/src/rost.c @@ -39,8 +39,9 @@ #include "analysis/scan/core.h" #include "analysis/scan/options.h" #include "analysis/scan/scanner.h" -#include "analysis/scan/patterns/backends/bitap.h" #include "analysis/scan/patterns/backends/acism.h" +#include "analysis/scan/patterns/backends/bitap.h" +#include "analysis/scan/patterns/backends/hyperscan.h" #include "core/core.h" #include "core/global.h" #include "core/logs.h" @@ -92,7 +93,7 @@ static void show_rost_help(const char *name) printf("\n"); - printf("\t-A --algorithm=NAME\tSelect one of the available algorithms for data: bitmap, acism (default: acsim).\n"); + printf("\t-A --algorithm=NAME\tSelect one of the available algorithms for data: acism, bitmap, hyperscan (default: acsim).\n"); printf("\t-C --check-only\t\tValidate the rule syntax without performing a scan (discard the file/dir argument).\n"); printf("\t-j --print-json\t\tPrint matching strings in JSON format instead of simple text.\n"); printf("\t-s --print-strings\tPrint matching strings (default text format only).\n"); @@ -298,10 +299,12 @@ int main(int argc, char **argv) break; case 'A': - if (strcmp(optarg, "bitmap") == 0) - g_scan_options_set_backend_for_data(options, G_TYPE_BITAP_BACKEND); - else if (strcmp(optarg, "acism") == 0) + if (strcmp(optarg, "acism") == 0) g_scan_options_set_backend_for_data(options, G_TYPE_ACISM_BACKEND); + else if (strcmp(optarg, "bitmap") == 0) + g_scan_options_set_backend_for_data(options, G_TYPE_BITAP_BACKEND); + else if (strcmp(optarg, "hyperscan") == 0) + g_scan_options_set_backend_for_data(options, G_TYPE_HYPERSCAN_BACKEND); else g_scan_options_set_backend_for_data(options, G_TYPE_INVALID); break; -- cgit v0.11.2-87-g4458