diff options
Diffstat (limited to 'tools/fuzzing/rost/fast-rost.c')
-rw-r--r-- | tools/fuzzing/rost/fast-rost.c | 283 |
1 files changed, 283 insertions, 0 deletions
diff --git a/tools/fuzzing/rost/fast-rost.c b/tools/fuzzing/rost/fast-rost.c new file mode 100644 index 0000000..f161273 --- /dev/null +++ b/tools/fuzzing/rost/fast-rost.c @@ -0,0 +1,283 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * fast-rost.c - fichier d'entrée du centre de collecte, adapté pour un fuzzing optimal + * + * Copyright (C) 2023 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include <assert.h> +#include <getopt.h> +#include <libgen.h> +#include <locale.h> +#include <malloc.h> +#include <stdlib.h> +#include <string.h> + + +#include <i18n.h> + + +#include <analysis/contents/file.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 <core/core.h> +#include <core/global.h> +#include <core/logs.h> +#include <core/paths.h> +#include <plugins/pglist.h> + + + +#ifndef __AFL_FUZZ_TESTCASE_LEN + +ssize_t fuzz_len; +unsigned char fuzz_buf[1024000]; + +# define __AFL_FUZZ_TESTCASE_LEN fuzz_len +# define __AFL_FUZZ_TESTCASE_BUF fuzz_buf +# define __AFL_FUZZ_INIT() void sync(void); +# define __AFL_LOOP(x) \ + ((fuzz_len = read(0, fuzz_buf, sizeof(fuzz_buf))) > 0 ? 1 : 0) +# define __AFL_INIT() sync() + +#endif + + +__AFL_FUZZ_INIT(); + + +/****************************************************************************** +* * +* Paramètres : argc = nombre d'arguments dans la ligne de commande. * +* argv = arguments de la ligne de commande. * +* * +* Description : Point d'entrée du programme. * +* * +* Retour : EXIT_SUCCESS si le prgm s'est déroulé sans encombres. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int main(int argc, char **argv) +{ + int result; /* Bilan de l'exécution */ + bool check_only; /* Validation uniquement */ + LogMessageType verbosity; /* Niveau de filtre de message */ + GScanOptions *options; /* Options d'analyses */ + int index; /* Indice d'argument */ + int ret; /* Bilan d'un appel */ + char *edir; /* Répertoire de base effectif */ + char *target; /* Cible communiquée */ + unsigned char *afl_buf; /* Tampon de travail d'AFL */ + int afl_len; /* Taille de ce tampon */ + GContentScanner *scanner; /* Encadrement d'une recherche */ + GBinContent *content; /* Contenu à analyser */ + GScanContext *context; /* Contexte des trouvailles */ + sized_string_t padding; /* Bourrage pour le JSON */ + bool full; /* Détailler l'affichage ? */ + + static struct option long_options[] = { + { "algorithm", required_argument, NULL, 'A' }, + { "check-only", no_argument, NULL, 'C' }, + { "print-json", no_argument, NULL, 'j' }, + { "print-strings", no_argument, NULL, 's' }, + { "print-stats", no_argument, NULL, 'S' }, + { "print-tags", no_argument, NULL, 'g' }, + { "tag", required_argument, NULL, 't' }, + { "verbosity", required_argument, NULL, 'V' }, + { NULL, 0, NULL, 0 } + }; + + result = EXIT_FAILURE; + + /* Décodage des options */ + + check_only = false; + verbosity = LMT_COUNT; + + options = g_scan_options_new(); + + g_scan_options_set_backend_for_data(options, G_TYPE_ACISM_BACKEND); + + while (true) + { + ret = getopt_long(argc, argv, "A:CjsSgt:V:", long_options, &index); + if (ret == -1) break; + + switch (ret) + { + 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) + g_scan_options_set_backend_for_data(options, G_TYPE_ACISM_BACKEND); + else + g_scan_options_set_backend_for_data(options, G_TYPE_INVALID); + break; + + case 'C': + check_only = true; + g_scan_options_set_check_only(options, true); + break; + + case 'j': + g_scan_options_set_print_json(options, true); + break; + + case 's': + g_scan_options_set_print_strings(options, true); + break; + + case 'S': + g_scan_options_set_print_stats(options, true); + break; + + case 'g': + g_scan_options_set_print_tags(options, true); + break; + + case 't': + g_scan_options_select_tag(options, optarg); + break; + + case 'V': + verbosity = strtoul(optarg, NULL, 10); + break; + + } + + } + + if ((check_only && (optind + 0) != argc && (optind + 1) != argc) + || (!check_only && (optind + 1) != argc && (optind + 2) != argc)) + { + goto done; + } + + /* Actions de base */ + + if (g_scan_options_get_backend_for_data(options) == G_TYPE_INVALID) + { + goto done; + } + + /* Lancement des choses sérieuses */ + + setlocale(LC_ALL, ""); + edir = get_effective_directory(LOCALE_DIR); + bindtextdomain(PACKAGE, edir); + free(edir); + textdomain(PACKAGE); + + /* Initialisation de GTK */ + g_set_prgname("ROST"); + //gtk_init(&argc, &argv); + + /* Initialisation du programme */ + + set_batch_mode(); + + set_log_verbosity(verbosity); + + if (!load_all_core_components(true)) + goto done; + + init_all_plugins(true); + + /* Traitement des recherches */ + + if ((optind + 1) == argc) + target = argv[optind]; + else + goto done; + + __AFL_INIT(); + + afl_buf = __AFL_FUZZ_TESTCASE_BUF; + + while (__AFL_LOOP(10000)) + { + afl_len = __AFL_FUZZ_TESTCASE_LEN; + + scanner = g_content_scanner_new_from_text((char *)afl_buf, afl_len); + +#if 0 + do + { + FILE *stream; + + stream = fopen("/dev/shm/ctrl.log", "a"); + fprintf(stream, "running %d bytes => %p\n", afl_len, scanner); + fclose(stream); + + } while (0); +#endif + + if (scanner != NULL) + result = EXIT_SUCCESS; + + if (scanner != NULL && !check_only) + { + content = g_file_content_new(target); + if (content == NULL) goto bad_file_content; + + context = g_content_scanner_analyze(scanner, options, content); + + if (g_scan_options_get_print_json(options)) + { + padding.data = " "; + padding.len = 3; + + g_content_scanner_output_to_json(scanner, context, &padding, 0, STDOUT_FILENO); + + } + else + { + full = g_scan_options_get_print_strings(options); + + g_content_scanner_output_to_text(scanner, context, full, STDOUT_FILENO); + + } + + g_object_unref(G_OBJECT(context)); + g_object_unref(G_OBJECT(content)); + + bad_file_content: + + g_object_unref(G_OBJECT(scanner)); + + } + + } + + g_object_unref(G_OBJECT(options)); + + /* Sortie */ + + unload_all_core_components(false); + + done: + + return result; + +} |