mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-06 23:31:33 +00:00
commit
75d8c47a6b
@ -4,7 +4,7 @@ CFLAGS = -O3 -funroll-loops -fPIC
|
|||||||
all: aflpp-standalone
|
all: aflpp-standalone
|
||||||
|
|
||||||
aflpp-standalone: aflpp-standalone.c
|
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:
|
clean:
|
||||||
rm -f *.o *~ aflpp-standalone core
|
rm -f *.o *~ aflpp-standalone core
|
||||||
|
@ -5,6 +5,6 @@ this is the AFL++ havoc mutator as a standalone mutator
|
|||||||
just type `make` to build.
|
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
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
#include "afl-fuzz.h"
|
#include "afl-fuzz.h"
|
||||||
#include "afl-mutations.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 {
|
typedef struct my_mutator {
|
||||||
|
|
||||||
afl_state_t *afl;
|
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");
|
perror("afl_custom_init alloc");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
} else {
|
} 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 = calloc(1, sizeof(afl_state_t));
|
||||||
data->afl->queue_cycle = 1;
|
data->afl->queue_cycle = 1;
|
||||||
data->afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY);
|
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());
|
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;
|
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 ... :( */
|
/* set everything up, costly ... :( */
|
||||||
memcpy(data->buf, buf, buf_size);
|
memcpy(data->buf, buf, buf_size);
|
||||||
|
|
||||||
/* the mutation */
|
/* the mutation */
|
||||||
u32 out_buf_len = afl_mutate(data->afl, data->buf, buf_size, havoc_steps,
|
u32 out_buf_len;
|
||||||
false, true, add_buf, add_buf_size, max_size);
|
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 */
|
/* return size of mutated data */
|
||||||
*out_buf = data->buf;
|
*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[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
if (argc > 1 && strncmp(argv[1], "-h", 2) == 0) {
|
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(
|
||||||
printf("mutates according to AFL++'s mutation engine, and write to stdout when '-' or\n");
|
"Syntax: %s [-v] [-m maxmutations] [-x dict] [inputfile [outputfile "
|
||||||
printf("no output filename is given. As an optional third parameter you can give a file\n");
|
"[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("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;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *in = stdin, *out = stdout, *splice = NULL;
|
FILE *in = stdin, *out = stdout, *splice = NULL;
|
||||||
unsigned char *inbuf = malloc(1024 * 1024), *outbuf, *splicebuf = NULL;
|
unsigned char *inbuf = malloc(1024 * 1024), *outbuf = NULL, *splicebuf = NULL;
|
||||||
int verbose = 0, splicelen = 0;
|
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);
|
my_mutator_t *data = afl_custom_init(NULL, 0);
|
||||||
|
|
||||||
if (argc > 1 && strcmp(argv[1], "-") != 0) {
|
if (argc > optind && strcmp(argv[optind], "-") != 0) {
|
||||||
if ((in = fopen(argv[1], "r")) == NULL) {
|
|
||||||
|
if ((in = fopen(argv[optind], "r")) == NULL) {
|
||||||
|
|
||||||
perror(argv[1]);
|
perror(argv[1]);
|
||||||
return -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) {
|
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;
|
return -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc > 2 && strcmp(argv[2], "-") != 0) {
|
if (argc > optind + 1 && strcmp(argv[optind + 1], "-") != 0) {
|
||||||
if ((out = fopen(argv[2], "w")) == NULL) {
|
|
||||||
perror(argv[2]);
|
if ((out = fopen(argv[optind + 1], "w")) == NULL) {
|
||||||
|
|
||||||
|
perror(argv[optind + 1]);
|
||||||
return -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 (argc > optind + 2) {
|
||||||
if ((splice = fopen(argv[3], "r")) == NULL) {
|
|
||||||
perror(argv[3]);
|
if ((splice = fopen(argv[optind + 2], "r")) == NULL) {
|
||||||
|
|
||||||
|
perror(argv[optind + 2]);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (verbose) fprintf(stderr, "Splice: %s\n", argv[3]);
|
|
||||||
splicebuf = malloc(1024*1024);
|
if (verbose) fprintf(stderr, "Splice: %s\n", argv[optind + 2]);
|
||||||
size_t splicelen = fread(splicebuf, 1, 1024*1024, splice);
|
splicebuf = malloc(1024 * 1024);
|
||||||
|
size_t splicelen = fread(splicebuf, 1, 1024 * 1024, splice);
|
||||||
if (!splicelen) {
|
if (!splicelen) {
|
||||||
fprintf(stderr, "Error: empty file %s\n", argv[3]);
|
|
||||||
|
fprintf(stderr, "Error: empty file %s\n", argv[optind + 2]);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose) fprintf(stderr, "Mutation splice length: %zu\n", splicelen);
|
if (verbose) fprintf(stderr, "Mutation splice length: %zu\n", splicelen);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose) fprintf(stderr, "Mutation input length: %zu\n", inlen);
|
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) {
|
if (outlen == 0 || !outbuf) {
|
||||||
|
|
||||||
fprintf(stderr, "Error: no mutation data returned.\n");
|
fprintf(stderr, "Error: no mutation data returned.\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose) fprintf(stderr, "Mutation output length: %u\n", outlen);
|
if (verbose) fprintf(stderr, "Mutation output length: %u\n", outlen);
|
||||||
|
|
||||||
if (fwrite(outbuf, 1, outlen, out) != outlen) {
|
if (fwrite(outbuf, 1, outlen, out) != outlen) {
|
||||||
|
|
||||||
fprintf(stderr, "Warning: incomplete write.\n");
|
fprintf(stderr, "Warning: incomplete write.\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ extern "C" {
|
|||||||
#ifndef AFL_TXT_MAX_LEN
|
#ifndef AFL_TXT_MAX_LEN
|
||||||
#define AFL_TXT_MAX_LEN 65535
|
#define AFL_TXT_MAX_LEN 65535
|
||||||
#endif
|
#endif
|
||||||
|
#define AUTOTOKENS_TXT_MIN_LEN 1
|
||||||
|
|
||||||
#if AUTOTOKENS_SPLICE_MIN >= AUTOTOKENS_SIZE_MIN
|
#if AUTOTOKENS_SPLICE_MIN >= AUTOTOKENS_SIZE_MIN
|
||||||
#error SPLICE_MIN must be lower than SIZE_MIN
|
#error SPLICE_MIN must be lower than SIZE_MIN
|
||||||
@ -57,8 +58,9 @@ typedef struct my_mutator {
|
|||||||
if (unlikely(debug)) fprintf
|
if (unlikely(debug)) fprintf
|
||||||
#define IFDEBUG if (unlikely(debug))
|
#define IFDEBUG if (unlikely(debug))
|
||||||
|
|
||||||
|
int module_disabled = 0;
|
||||||
|
|
||||||
static afl_state *afl_ptr;
|
static afl_state *afl_ptr;
|
||||||
static int module_disabled = 0;
|
|
||||||
static int auto_disable = AUTOTOKENS_AUTO_DISABLE;
|
static int auto_disable = AUTOTOKENS_AUTO_DISABLE;
|
||||||
static int debug = AUTOTOKENS_DEBUG;
|
static int debug = AUTOTOKENS_DEBUG;
|
||||||
static int only_fav = AUTOTOKENS_ONLY_FAV;
|
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 (afl_ptr->custom_only || !auto_disable) { return; }
|
||||||
|
|
||||||
if (unlikely(afl_ptr->active_items == 1 &&
|
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;
|
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,
|
u8 **out_buf, u8 *add_buf,
|
||||||
size_t add_buf_size, size_t max_size) {
|
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 &&
|
if (current_id > whitespace_ids + 6 && afl_ptr->active_items == 1 &&
|
||||||
afl_ptr->queue_cur->len < AFL_TXT_MIN_LEN) {
|
afl_ptr->queue_cur->len < AFL_TXT_MIN_LEN) {
|
||||||
|
|
||||||
|
retry_thin_air:
|
||||||
DEBUGF(stderr, "Creating an entry from thin air...\n");
|
DEBUGF(stderr, "Creating an entry from thin air...\n");
|
||||||
structure = new vector<u32>();
|
structure = new vector<u32>();
|
||||||
u32 item, prev, cnt = current_id >> 1;
|
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()) {
|
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!
|
// this input file was not analyzed for tokens yet, so let's do it!
|
||||||
size_t len = afl_ptr->queue_cur->len;
|
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
|
file_mapping[fn] = structure; // NULL ptr so we don't read the file again
|
||||||
s = NULL;
|
s = NULL;
|
||||||
@ -895,6 +896,7 @@ extern "C" unsigned char afl_custom_queue_get(void *data,
|
|||||||
|
|
||||||
if (tokens.size() < AUTOTOKENS_SIZE_MIN) {
|
if (tokens.size() < AUTOTOKENS_SIZE_MIN) {
|
||||||
|
|
||||||
|
if (create_from_thin_air) { goto retry_thin_air; }
|
||||||
file_mapping[fn] = NULL;
|
file_mapping[fn] = NULL;
|
||||||
s = NULL;
|
s = NULL;
|
||||||
DEBUGF(stderr, "too few tokens\n");
|
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);
|
(void)(seed);
|
||||||
my_mutator_t *data = (my_mutator_t *)calloc(1, sizeof(my_mutator_t));
|
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] = "'";
|
id_to_token[current_id] = "'";
|
||||||
++current_id;
|
++current_id;
|
||||||
|
|
||||||
return data;
|
return (void *)data;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
19
custom_mutators/autotokens/standalone/Makefile
Normal file
19
custom_mutators/autotokens/standalone/Makefile
Normal file
@ -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
|
12
custom_mutators/autotokens/standalone/README.md
Normal file
12
custom_mutators/autotokens/standalone/README.md
Normal file
@ -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
|
||||||
|
```
|
192
custom_mutators/autotokens/standalone/autotokens-standalone.c
Normal file
192
custom_mutators/autotokens/standalone/autotokens-standalone.c
Normal file
@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -32,6 +32,8 @@
|
|||||||
AFL type forkserver. Useful for symcc/symqemu/nautilus/etc. with
|
AFL type forkserver. Useful for symcc/symqemu/nautilus/etc. with
|
||||||
AFL_LLVM_INSTRUMENT=CLASSIC
|
AFL_LLVM_INSTRUMENT=CLASSIC
|
||||||
- code formatting updated to llvm 18
|
- code formatting updated to llvm 18
|
||||||
|
- improved custom_mutators/aflpp/standalone/aflpp-standalone
|
||||||
|
- added custom_mutators/autotokens/standalone/autotokens-standalone
|
||||||
|
|
||||||
|
|
||||||
### Version ++4.21c (release)
|
### Version ++4.21c (release)
|
||||||
|
@ -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 ninja-build # for QEMU mode
|
||||||
sudo apt-get install -y cpio libcapstone-dev # for Nyx 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 -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
|
git clone https://github.com/AFLplusplus/AFLplusplus
|
||||||
cd AFLplusplus
|
cd AFLplusplus
|
||||||
make distrib
|
make distrib
|
||||||
|
@ -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
|
/* 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! */
|
Does not descend into subdirectories! */
|
||||||
|
|
||||||
void read_foreign_testcases(afl_state_t *afl, int first) {
|
void read_foreign_testcases(afl_state_t *afl, int first) {
|
||||||
@ -2443,20 +2445,19 @@ void check_crash_handling(void) {
|
|||||||
|
|
||||||
SAYF(
|
SAYF(
|
||||||
"\n" cLRD "[-] " cRST
|
"\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 "
|
" external utility. This will cause issues: there will be an "
|
||||||
"extended delay\n"
|
"extended delay\n"
|
||||||
" between stumbling upon a crash and having this information "
|
" between stumbling upon a crash and having this information "
|
||||||
"relayed to the\n"
|
"relayed to the\n"
|
||||||
" fuzzer via the standard waitpid() API.\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"
|
"'AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1'.\n\n"
|
||||||
|
|
||||||
" To avoid having crashes misinterpreted as timeouts, please log in "
|
" To avoid having crashes misinterpreted as timeouts, please \n"
|
||||||
"as root\n"
|
" temporarily modify /proc/sys/kernel/core_pattern, like so:\n\n"
|
||||||
" and 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")) {
|
if (!getenv("AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES")) {
|
||||||
|
|
||||||
|
@ -455,9 +455,8 @@ void mark_as_variable(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
|
|
||||||
if (symlink(ldest, fn)) {
|
if (symlink(ldest, fn)) {
|
||||||
|
|
||||||
s32 fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
|
s32 fd = permissive_create(afl, fn);
|
||||||
if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
|
if (fd >= 0) { close(fd); }
|
||||||
close(fd);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +80,7 @@ extern unsigned int __afl_map_size;
|
|||||||
/*__attribute__((weak))*/ int LLVMFuzzerTestOneInput(const uint8_t *Data,
|
/*__attribute__((weak))*/ int LLVMFuzzerTestOneInput(const uint8_t *Data,
|
||||||
size_t Size);
|
size_t Size);
|
||||||
__attribute__((weak)) int LLVMFuzzerInitialize(int *argc, char ***argv);
|
__attribute__((weak)) int LLVMFuzzerInitialize(int *argc, char ***argv);
|
||||||
|
__attribute__((weak)) void LLVMFuzzerCleanup(void);
|
||||||
__attribute__((weak)) int LLVMFuzzerRunDriver(
|
__attribute__((weak)) int LLVMFuzzerRunDriver(
|
||||||
int *argc, char ***argv, int (*callback)(const uint8_t *data, size_t size));
|
int *argc, char ***argv, int (*callback)(const uint8_t *data, size_t size));
|
||||||
|
|
||||||
@ -338,6 +339,7 @@ __attribute__((weak)) int LLVMFuzzerRunDriver(
|
|||||||
output_file = stderr;
|
output_file = stderr;
|
||||||
maybe_duplicate_stderr();
|
maybe_duplicate_stderr();
|
||||||
maybe_close_fd_mask();
|
maybe_close_fd_mask();
|
||||||
|
|
||||||
if (LLVMFuzzerInitialize) {
|
if (LLVMFuzzerInitialize) {
|
||||||
|
|
||||||
fprintf(stderr, "Running LLVMFuzzerInitialize ...\n");
|
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;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user