diff options
author | van Hauser <vh@thc.org> | 2024-09-06 12:16:31 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-06 12:16:31 +0200 |
commit | 75d8c47a6b8ae94cd7ded2f0574e4d35a2021ab7 (patch) | |
tree | b702e4d7c53835439ed83ed9291723cb32b7ebfa | |
parent | 598a3c6b5e24bd33e84b914e145810d39f88adf6 (diff) | |
parent | 3ec794c806f9e5fbdd4bdb55cac11b2eb9d010c7 (diff) | |
download | afl++-75d8c47a6b8ae94cd7ded2f0574e4d35a2021ab7.tar.gz |
Merge pull request #2204 from AFLplusplus/dev
push to stable
-rw-r--r-- | custom_mutators/aflpp/standalone/Makefile | 2 | ||||
-rw-r--r-- | custom_mutators/aflpp/standalone/README.md | 4 | ||||
-rw-r--r-- | custom_mutators/aflpp/standalone/aflpp-standalone.c | 165 | ||||
-rw-r--r-- | custom_mutators/autotokens/autotokens.cpp | 20 | ||||
-rw-r--r-- | custom_mutators/autotokens/standalone/Makefile | 19 | ||||
-rw-r--r-- | custom_mutators/autotokens/standalone/README.md | 12 | ||||
-rw-r--r-- | custom_mutators/autotokens/standalone/autotokens-standalone.c | 192 | ||||
-rw-r--r-- | docs/Changelog.md | 2 | ||||
-rw-r--r-- | docs/INSTALL.md | 2 | ||||
-rw-r--r-- | src/afl-fuzz-init.c | 15 | ||||
-rw-r--r-- | src/afl-fuzz-queue.c | 5 | ||||
-rw-r--r-- | utils/aflpp_driver/aflpp_driver.c | 10 |
12 files changed, 387 insertions, 61 deletions
diff --git a/custom_mutators/aflpp/standalone/Makefile b/custom_mutators/aflpp/standalone/Makefile index f1e99445..d7bc840d 100644 --- a/custom_mutators/aflpp/standalone/Makefile +++ b/custom_mutators/aflpp/standalone/Makefile @@ -4,7 +4,7 @@ CFLAGS = -O3 -funroll-loops -fPIC all: aflpp-standalone aflpp-standalone: aflpp-standalone.c - $(CC) $(CFLAGS) -I../../../include -I. -o aflpp-standalone aflpp-standalone.c ../../../src/afl-performance.c + $(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -o aflpp-standalone aflpp-standalone.c ../../../src/afl-performance.c ../../../src/afl-fuzz-extras.c ../../../src/afl-common.c clean: rm -f *.o *~ aflpp-standalone core diff --git a/custom_mutators/aflpp/standalone/README.md b/custom_mutators/aflpp/standalone/README.md index a1ffb5f9..3c26a29a 100644 --- a/custom_mutators/aflpp/standalone/README.md +++ b/custom_mutators/aflpp/standalone/README.md @@ -5,6 +5,6 @@ this is the AFL++ havoc mutator as a standalone mutator just type `make` to build. ``` -aflpp-standalone inputfile outputfile [splicefile] +aflpp-standalone -h # to see all parameteres +cat file | aflpp-standalone -m 4 -x foo.dict - outputfile splicefile # example ``` - diff --git a/custom_mutators/aflpp/standalone/aflpp-standalone.c b/custom_mutators/aflpp/standalone/aflpp-standalone.c index a3789cd1..c059ce11 100644 --- a/custom_mutators/aflpp/standalone/aflpp-standalone.c +++ b/custom_mutators/aflpp/standalone/aflpp-standalone.c @@ -1,6 +1,12 @@ #include "afl-fuzz.h" #include "afl-mutations.h" +#include <unistd.h> +#include <getopt.h> + +static int max_havoc = 16, verbose; +static unsigned char *dict; + typedef struct my_mutator { afl_state_t *afl; @@ -21,14 +27,14 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) { } - if ((data->buf = malloc(1024*1024)) == NULL) { + if ((data->buf = malloc(1024 * 1024)) == NULL) { perror("afl_custom_init alloc"); return NULL; } else { - data->buf_size = 1024*1024; + data->buf_size = 1024 * 1024; } @@ -36,9 +42,23 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) { data->afl = calloc(1, sizeof(afl_state_t)); data->afl->queue_cycle = 1; data->afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY); - if (data->afl->fsrv.dev_urandom_fd < 0) { PFATAL("Unable to open /dev/urandom"); } + if (data->afl->fsrv.dev_urandom_fd < 0) { + + PFATAL("Unable to open /dev/urandom"); + + } + rand_set_seed(data->afl, getpid()); + if (dict) { + + load_extras(data->afl, dict); + if (verbose) + fprintf(stderr, "Loaded dictionary: %s (%u entries)\n", dict, + data->afl->extras_cnt); + + } + return data; } @@ -66,14 +86,20 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, } - u32 havoc_steps = 1 + rand_below(data->afl, 16); + u32 havoc_steps = 1 + rand_below(data->afl, max_havoc); + if (verbose) fprintf(stderr, "Havoc steps: %u\n", havoc_steps); /* set everything up, costly ... :( */ memcpy(data->buf, buf, buf_size); /* the mutation */ - u32 out_buf_len = afl_mutate(data->afl, data->buf, buf_size, havoc_steps, - false, true, add_buf, add_buf_size, max_size); + u32 out_buf_len; + do { + + out_buf_len = afl_mutate(data->afl, data->buf, buf_size, havoc_steps, false, + true, add_buf, add_buf_size, max_size); + + } while (out_buf_len == buf_size && memcmp(buf, data->buf, buf_size) == 0); /* return size of mutated data */ *out_buf = data->buf; @@ -84,80 +110,143 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, int main(int argc, char *argv[]) { if (argc > 1 && strncmp(argv[1], "-h", 2) == 0) { - printf("Syntax: %s [-v] [inputfile [outputfile [splicefile]]]\n\n", argv[0]); - printf("Reads a testcase from stdin when no input file (or '-') is specified,\n"); - printf("mutates according to AFL++'s mutation engine, and write to stdout when '-' or\n"); - printf("no output filename is given. As an optional third parameter you can give a file\n"); + + printf( + "Syntax: %s [-v] [-m maxmutations] [-x dict] [inputfile [outputfile " + "[splicefile]]]\n\n", + argv[0]); + printf( + "Reads a testcase from stdin when no input file (or '-') is " + "specified,\n"); + printf( + "mutates according to AFL++'s mutation engine, and write to stdout " + "when '-' or\n"); + printf( + "no output filename is given. As an optional third parameter you can " + "give a file\n"); printf("for splicing. Maximum input and output length is 1MB.\n"); - printf("The -v verbose option prints debug output to stderr.\n"); + printf("Options:\n"); + printf(" -v verbose debug output to stderr.\n"); + printf(" -m val max mutations (1-val, val default is 16)\n"); + printf(" -x file dictionary file (AFL++ format)\n"); return 0; + } - FILE *in = stdin, *out = stdout, *splice = NULL; - unsigned char *inbuf = malloc(1024 * 1024), *outbuf, *splicebuf = NULL; - int verbose = 0, splicelen = 0; + FILE *in = stdin, *out = stdout, *splice = NULL; + unsigned char *inbuf = malloc(1024 * 1024), *outbuf = NULL, *splicebuf = NULL; + int splicelen = 0, opt; + + while ((opt = getopt(argc, argv, "vm:x:")) > 0) { + + switch (opt) { + + case 'm': + max_havoc = atoi(optarg); + break; + case 'v': + verbose = 1; + break; + case 'x': + dict = optarg; + break; + default: + fprintf(stderr, "Error: unknown parameter -%c\n", opt); + exit(-1); + + } + + } + + if (max_havoc < 1) { + + fprintf(stderr, "Error: illegal -m value\n"); + exit(-1); - if (argc > 1 && strcmp(argv[1], "-v") == 0) { - verbose = 1; - argc--; - argv++; - fprintf(stderr, "Verbose active\n"); } my_mutator_t *data = afl_custom_init(NULL, 0); - if (argc > 1 && strcmp(argv[1], "-") != 0) { - if ((in = fopen(argv[1], "r")) == NULL) { + if (argc > optind && strcmp(argv[optind], "-") != 0) { + + if ((in = fopen(argv[optind], "r")) == NULL) { + perror(argv[1]); return -1; + } - if (verbose) fprintf(stderr, "Input: %s\n", argv[1]); + + if (verbose) fprintf(stderr, "Input: %s\n", argv[optind]); + } - size_t inlen = fread(inbuf, 1, 1024*1024, in); - + size_t inlen = fread(inbuf, 1, 1024 * 1024, in); + if (!inlen) { - fprintf(stderr, "Error: empty file %s\n", argv[1] ? argv[1] : "stdin"); + + fprintf(stderr, "Error: empty file %s\n", + argv[optind] ? argv[optind] : "stdin"); return -1; + } - if (argc > 2 && strcmp(argv[2], "-") != 0) { - if ((out = fopen(argv[2], "w")) == NULL) { - perror(argv[2]); + if (argc > optind + 1 && strcmp(argv[optind + 1], "-") != 0) { + + if ((out = fopen(argv[optind + 1], "w")) == NULL) { + + perror(argv[optind + 1]); return -1; + } - if (verbose) fprintf(stderr, "Output: %s\n", argv[2]); + + if (verbose) fprintf(stderr, "Output: %s\n", argv[optind + 1]); + } - if (argc > 3) { - if ((splice = fopen(argv[3], "r")) == NULL) { - perror(argv[3]); + if (argc > optind + 2) { + + if ((splice = fopen(argv[optind + 2], "r")) == NULL) { + + perror(argv[optind + 2]); return -1; + } - if (verbose) fprintf(stderr, "Splice: %s\n", argv[3]); - splicebuf = malloc(1024*1024); - size_t splicelen = fread(splicebuf, 1, 1024*1024, splice); + + if (verbose) fprintf(stderr, "Splice: %s\n", argv[optind + 2]); + splicebuf = malloc(1024 * 1024); + size_t splicelen = fread(splicebuf, 1, 1024 * 1024, splice); if (!splicelen) { - fprintf(stderr, "Error: empty file %s\n", argv[3]); + + fprintf(stderr, "Error: empty file %s\n", argv[optind + 2]); return -1; + } + if (verbose) fprintf(stderr, "Mutation splice length: %zu\n", splicelen); + } if (verbose) fprintf(stderr, "Mutation input length: %zu\n", inlen); - unsigned int outlen = afl_custom_fuzz(data, inbuf, inlen, &outbuf, splicebuf, splicelen, 1024*1024); + unsigned int outlen = afl_custom_fuzz(data, inbuf, inlen, &outbuf, splicebuf, + splicelen, 1024 * 1024); if (outlen == 0 || !outbuf) { + fprintf(stderr, "Error: no mutation data returned.\n"); return -1; + } if (verbose) fprintf(stderr, "Mutation output length: %u\n", outlen); if (fwrite(outbuf, 1, outlen, out) != outlen) { + fprintf(stderr, "Warning: incomplete write.\n"); return -1; + } - + return 0; + } + diff --git a/custom_mutators/autotokens/autotokens.cpp b/custom_mutators/autotokens/autotokens.cpp index 8135aba1..9bce3da7 100644 --- a/custom_mutators/autotokens/autotokens.cpp +++ b/custom_mutators/autotokens/autotokens.cpp @@ -39,6 +39,7 @@ extern "C" { #ifndef AFL_TXT_MAX_LEN #define AFL_TXT_MAX_LEN 65535 #endif +#define AUTOTOKENS_TXT_MIN_LEN 1 #if AUTOTOKENS_SPLICE_MIN >= AUTOTOKENS_SIZE_MIN #error SPLICE_MIN must be lower than SIZE_MIN @@ -57,8 +58,9 @@ typedef struct my_mutator { if (unlikely(debug)) fprintf #define IFDEBUG if (unlikely(debug)) +int module_disabled = 0; + static afl_state *afl_ptr; -static int module_disabled = 0; static int auto_disable = AUTOTOKENS_AUTO_DISABLE; static int debug = AUTOTOKENS_DEBUG; static int only_fav = AUTOTOKENS_ONLY_FAV; @@ -104,9 +106,9 @@ static void first_run(void *data) { if (afl_ptr->custom_only || !auto_disable) { return; } if (unlikely(afl_ptr->active_items == 1 && - afl_ptr->queue_cur->len < AFL_TXT_MIN_LEN)) { + afl_ptr->queue_cur->len < AUTOTOKENS_TXT_MIN_LEN)) { - if (afl_ptr->extras_cnt > 8) { + if (afl_ptr->extras_cnt) { u32 valid = 0; @@ -237,7 +239,7 @@ extern "C" u32 afl_custom_fuzz_count(void *data, const u8 *buf, } -extern "C" size_t afl_custom_fuzz(my_mutator_t *data, u8 *buf, size_t buf_size, +extern "C" size_t afl_custom_fuzz(void *data, u8 *buf, size_t buf_size, u8 **out_buf, u8 *add_buf, size_t add_buf_size, size_t max_size) { @@ -655,6 +657,7 @@ extern "C" unsigned char afl_custom_queue_get(void *data, if (current_id > whitespace_ids + 6 && afl_ptr->active_items == 1 && afl_ptr->queue_cur->len < AFL_TXT_MIN_LEN) { + retry_thin_air: DEBUGF(stderr, "Creating an entry from thin air...\n"); structure = new vector<u32>(); u32 item, prev, cnt = current_id >> 1; @@ -684,8 +687,6 @@ extern "C" unsigned char afl_custom_queue_get(void *data, } - create_from_thin_air = 0; - } if (entry == file_mapping.end()) { @@ -693,7 +694,7 @@ extern "C" unsigned char afl_custom_queue_get(void *data, // this input file was not analyzed for tokens yet, so let's do it! size_t len = afl_ptr->queue_cur->len; - if (len < AFL_TXT_MIN_LEN) { + if (len < AUTOTOKENS_TXT_MIN_LEN) { file_mapping[fn] = structure; // NULL ptr so we don't read the file again s = NULL; @@ -895,6 +896,7 @@ extern "C" unsigned char afl_custom_queue_get(void *data, if (tokens.size() < AUTOTOKENS_SIZE_MIN) { + if (create_from_thin_air) { goto retry_thin_air; } file_mapping[fn] = NULL; s = NULL; DEBUGF(stderr, "too few tokens\n"); @@ -955,7 +957,7 @@ extern "C" unsigned char afl_custom_queue_get(void *data, } -extern "C" my_mutator_t *afl_custom_init(afl_state *afl, unsigned int seed) { +extern "C" void *afl_custom_init(afl_state_t *afl, unsigned int seed) { (void)(seed); my_mutator_t *data = (my_mutator_t *)calloc(1, sizeof(my_mutator_t)); @@ -1070,7 +1072,7 @@ extern "C" my_mutator_t *afl_custom_init(afl_state *afl, unsigned int seed) { id_to_token[current_id] = "'"; ++current_id; - return data; + return (void *)data; } diff --git a/custom_mutators/autotokens/standalone/Makefile b/custom_mutators/autotokens/standalone/Makefile new file mode 100644 index 00000000..8d5baf13 --- /dev/null +++ b/custom_mutators/autotokens/standalone/Makefile @@ -0,0 +1,19 @@ + +CFLAGS = -g -O3 -funroll-loops -fPIC -D_STANDALONE_MODULE=1 -Wno-implicit-function-declaration +CXXFLAGS= -g -O3 -funroll-loops -fPIC -D_STANDALONE_MODULE=1 + +all: autotokens-standalone + +autotokens.o: ../autotokens.cpp + $(CXX) $(CXXFLAGS) -I../../../include -I. -I../.. -c ../autotokens.cpp + +autotokens-standalone: autotokens-standalone.c autotokens.o + $(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c autotokens-standalone.c + $(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c ../../../src/afl-performance.c + $(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c ../../../src/afl-fuzz-extras.c + $(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c ../../../src/afl-fuzz-queue.c + $(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c ../../../src/afl-common.c + $(CXX) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -o autotokens-standalone *.o + +clean: + rm -f *.o *~ autotokens-standalone core diff --git a/custom_mutators/autotokens/standalone/README.md b/custom_mutators/autotokens/standalone/README.md new file mode 100644 index 00000000..9e9babf7 --- /dev/null +++ b/custom_mutators/autotokens/standalone/README.md @@ -0,0 +1,12 @@ +# Autotokens standalone mutator + +this is a standalone version of the AFL++ autotokens custom mutator. + +just type `make` to build. + +You *MUST* use a dictionary file to have an effective grammarless grammar fuzzer! + +``` +autotokens-standalone -h # to see all parameteres +autotokens-standalone -x foo.dict inputfile outputfile # example +``` diff --git a/custom_mutators/autotokens/standalone/autotokens-standalone.c b/custom_mutators/autotokens/standalone/autotokens-standalone.c new file mode 100644 index 00000000..e7a09cb3 --- /dev/null +++ b/custom_mutators/autotokens/standalone/autotokens-standalone.c @@ -0,0 +1,192 @@ +#include "afl-fuzz.h" +#include "afl-mutations.h" + +#include <unistd.h> +#include <getopt.h> + +static int max_havoc = 16, verbose; +static unsigned char *dict, *mh = "16"; + +extern int module_disabled; + +void *afl_custom_init(afl_state_t *, unsigned int); + +int main(int argc, char *argv[]) { + + if (argc > 1 && strncmp(argv[1], "-h", 2) == 0) { + + printf( + "Syntax: %s [-v] [-m maxmutations] [-x dict] [inputfile [outputfile " + "[splicefile]]]\n\n", + argv[0]); + printf("Reads a testcase from a file (not stdin!),\n"); + printf("writes to stdout when '-' or\n"); + printf( + "no output filename is given. As an optional third parameter you can " + "give a file\n"); + printf("for splicing. Maximum input and output length is 1MB.\n"); + printf("Options:\n"); + printf(" -v verbose debug output to stderr.\n"); + printf(" -m val max mutations (1-val, val default is 16)\n"); + printf(" -x file dictionary file (AFL++ format)\n"); + printf("You can set the following environment variable parameters:\n"); + printf("AUTOTOKENS_COMMENT` - what character or string starts a comment which will be\n"); + printf(" removed. Default: \"/* ... */\"\n"); + return 0; + + } + + FILE *in = stdin, *out = stdout, *splice = NULL; + unsigned char *inbuf = malloc(1024 * 1024), *outbuf = NULL, *splicebuf = NULL; + int splicelen = 0, opt; + + while ((opt = getopt(argc, argv, "vm:x:")) > 0) { + + switch (opt) { + + case 'm': + max_havoc = atoi(optarg); + mh = optarg; + break; + case 'v': + verbose = 1; + break; + case 'x': + dict = optarg; + break; + default: + fprintf(stderr, "Error: unknown parameter -%c\n", opt); + exit(-1); + + } + + } + + if (max_havoc < 1) { + + fprintf(stderr, "Error: illegal -m value\n"); + exit(-1); + + } + + if (argc > optind && strcmp(argv[optind], "-") != 0) { + + if ((in = fopen(argv[optind], "r")) == NULL) { + + perror(argv[1]); + return -1; + + } + + if (verbose) fprintf(stderr, "Input: %s\n", argv[optind]); + + } + + size_t inlen = fread(inbuf, 1, 1024 * 1024, in); + + if (!inlen) { + + fprintf(stderr, "Error: empty file %s\n", + argv[optind] ? argv[optind] : "stdin"); + return -1; + + } + + if (argc > optind + 1 && strcmp(argv[optind + 1], "-") != 0) { + + if ((out = fopen(argv[optind + 1], "w")) == NULL) { + + perror(argv[optind + 1]); + return -1; + + } + + if (verbose) fprintf(stderr, "Output: %s\n", argv[optind + 1]); + + } + + if (argc > optind + 2) { + + if ((splice = fopen(argv[optind + 2], "r")) == NULL) { + + perror(argv[optind + 2]); + return -1; + + } + + if (verbose) fprintf(stderr, "Splice: %s\n", argv[optind + 2]); + splicebuf = malloc(1024 * 1024); + size_t splicelen = fread(splicebuf, 1, 1024 * 1024, splice); + if (!splicelen) { + + fprintf(stderr, "Error: empty file %s\n", argv[optind + 2]); + return -1; + + } + + if (verbose) fprintf(stderr, "Mutation splice length: %zu\n", splicelen); + + } + + /* configure autotokens */ + setenv("AUTOTOKENS_LEARN_DICT", "1", 0); + setenv("AUTOTOKENS_CREATE_FROM_THIN_AIR", "1", 0); + setenv("AUTOTOKENS_CHANGE_MAX", mh, 0); + + /* fake AFL++ state */ + afl_state_t *afl = (afl_state_t *)calloc(1, sizeof(afl_state_t)); + afl->queue_cycle = afl->havoc_div = afl->active_items = afl->queued_items = 1; + afl->shm.cmplog_mode = 0; + afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY); + if (afl->fsrv.dev_urandom_fd < 0) { PFATAL("Unable to open /dev/urandom"); } + + rand_set_seed(afl, getpid()); + + if (dict) { + + load_extras(afl, dict); + if (verbose) + fprintf(stderr, "Loaded dictionary: %s (%u entries)\n", dict, + afl->extras_cnt); + + } + + // setup a fake queue entry + afl->queue_buf = malloc(64); + afl->queue_buf[0] = afl->queue_cur = + (struct queue_entry *)malloc(sizeof(struct queue_entry)); + afl->queue_cur->testcase_buf = inbuf; + afl->queue_cur->fname = (u8 *)argv[optind]; + afl->queue_cur->len = inlen; + afl->queue_cur->perf_score = 100; + afl->queue_cur->favored = afl->queue_cur->is_ascii = 1; + // afl->custom_only = 1; + + void *data = (void *)afl_custom_init(afl, (u32)0); + + u8 res = afl_custom_queue_get(inbuf, (u8 *)argv[optind]); + + if (verbose) fprintf(stderr, "Mutation input length: %zu\n", inlen); + unsigned int outlen = afl_custom_fuzz(data, inbuf, inlen, &outbuf, splicebuf, + splicelen, 1024 * 1024); + + if (outlen == 0 || !outbuf) { + + fprintf(stderr, "Error: no mutation data returned.\n"); + return -1; + + } + + if (verbose) fprintf(stderr, "Mutation output length: %u\n", outlen); + + if (fwrite(outbuf, 1, outlen, out) != outlen) { + + fprintf(stderr, "Warning: incomplete write.\n"); + return -1; + + } + + return 0; + +} + diff --git a/docs/Changelog.md b/docs/Changelog.md index f7c53b08..7043202f 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -32,6 +32,8 @@ AFL type forkserver. Useful for symcc/symqemu/nautilus/etc. with AFL_LLVM_INSTRUMENT=CLASSIC - code formatting updated to llvm 18 + - improved custom_mutators/aflpp/standalone/aflpp-standalone + - added custom_mutators/autotokens/standalone/autotokens-standalone ### Version ++4.21c (release) diff --git a/docs/INSTALL.md b/docs/INSTALL.md index cea1ae6b..03f69485 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -32,7 +32,7 @@ sudo apt-get install -y gcc-$(gcc --version|head -n1|sed 's/\..*//'|sed 's/.* // sudo apt-get install -y ninja-build # for QEMU mode sudo apt-get install -y cpio libcapstone-dev # for Nyx mode sudo apt-get install -y wget curl # for Frida mode -sudo apt-get install python3-pip # for Unicorn mode +sudo apt-get install -y python3-pip # for Unicorn mode git clone https://github.com/AFLplusplus/AFLplusplus cd AFLplusplus make distrib diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 4f366b0d..d3085d42 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -495,7 +495,9 @@ static void shuffle_ptrs(afl_state_t *afl, void **ptrs, u32 cnt) { } /* Read all testcases from foreign input directories, then queue them for - testing. Called at startup and at sync intervals. + testing. Called at sync intervals. Use env AFL_IMPORT_FIRST to sync at + startup (but may delay the startup depending on the amount of fails + and speed of execution). Does not descend into subdirectories! */ void read_foreign_testcases(afl_state_t *afl, int first) { @@ -2443,20 +2445,19 @@ void check_crash_handling(void) { SAYF( "\n" cLRD "[-] " cRST - "Hmm, your system is configured to send core dump notifications to an\n" + "Your system is configured to send core dump notifications to an\n" " external utility. This will cause issues: there will be an " "extended delay\n" " between stumbling upon a crash and having this information " "relayed to the\n" " fuzzer via the standard waitpid() API.\n" - " If you're just testing, set " + " If you're just experimenting, set " "'AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1'.\n\n" - " To avoid having crashes misinterpreted as timeouts, please log in " - "as root\n" - " and temporarily modify /proc/sys/kernel/core_pattern, like so:\n\n" + " To avoid having crashes misinterpreted as timeouts, please \n" + " temporarily modify /proc/sys/kernel/core_pattern, like so:\n\n" - " echo core >/proc/sys/kernel/core_pattern\n"); + " echo core | sudo tee /proc/sys/kernel/core_pattern\n"); if (!getenv("AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES")) { diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 599d31f6..8db89775 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -455,9 +455,8 @@ void mark_as_variable(afl_state_t *afl, struct queue_entry *q) { if (symlink(ldest, fn)) { - s32 fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION); - if (fd < 0) { PFATAL("Unable to create '%s'", fn); } - close(fd); + s32 fd = permissive_create(afl, fn); + if (fd >= 0) { close(fd); } } diff --git a/utils/aflpp_driver/aflpp_driver.c b/utils/aflpp_driver/aflpp_driver.c index 9ffb2383..6e992266 100644 --- a/utils/aflpp_driver/aflpp_driver.c +++ b/utils/aflpp_driver/aflpp_driver.c @@ -80,6 +80,7 @@ extern unsigned int __afl_map_size; /*__attribute__((weak))*/ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size); __attribute__((weak)) int LLVMFuzzerInitialize(int *argc, char ***argv); +__attribute__((weak)) void LLVMFuzzerCleanup(void); __attribute__((weak)) int LLVMFuzzerRunDriver( int *argc, char ***argv, int (*callback)(const uint8_t *data, size_t size)); @@ -338,6 +339,7 @@ __attribute__((weak)) int LLVMFuzzerRunDriver( output_file = stderr; maybe_duplicate_stderr(); maybe_close_fd_mask(); + if (LLVMFuzzerInitialize) { fprintf(stderr, "Running LLVMFuzzerInitialize ...\n"); @@ -441,6 +443,14 @@ __attribute__((weak)) int LLVMFuzzerRunDriver( } + if (LLVMFuzzerCleanup) { + + fprintf(stderr, "Running LLVMFuzzerCleanup ...\n"); + LLVMFuzzerCleanup(); + fprintf(stderr, "Exiting ...\n"); + + } + return 0; } |