From fcd21256780fd21c55e72e9338b3992c60db22dc Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 4 Apr 2023 15:47:53 +0200 Subject: prepare for strategies --- custom_mutators/aflpp/Makefile | 10 ++++++ custom_mutators/aflpp/README.md | 8 +++++ custom_mutators/aflpp/aflpp.c | 68 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 custom_mutators/aflpp/Makefile create mode 100644 custom_mutators/aflpp/README.md create mode 100644 custom_mutators/aflpp/aflpp.c (limited to 'custom_mutators/aflpp') diff --git a/custom_mutators/aflpp/Makefile b/custom_mutators/aflpp/Makefile new file mode 100644 index 00000000..8efdf3e4 --- /dev/null +++ b/custom_mutators/aflpp/Makefile @@ -0,0 +1,10 @@ + +CFLAGS = -O3 -funroll-loops -fPIC -Wl,-Bsymbolic + +all: aflpp-mutator.so + +aflpp-mutator.so: aflpp.c + $(CC) $(CFLAGS) -I../../include -I. -shared -o aflpp-mutator.so aflpp.c ../../src/afl-performance.c + +clean: + rm -f *.o *~ *.so core diff --git a/custom_mutators/aflpp/README.md b/custom_mutators/aflpp/README.md new file mode 100644 index 00000000..04d605c1 --- /dev/null +++ b/custom_mutators/aflpp/README.md @@ -0,0 +1,8 @@ +# custum mutator: AFL++ + +this is the AFL++ havoc mutator as a custom mutator module for AFL++. + +just type `make` to build + +```AFL_CUSTOM_MUTATOR_LIBRARY=custom_mutators/aflpp/aflpp-mutator.so afl-fuzz ...``` + diff --git a/custom_mutators/aflpp/aflpp.c b/custom_mutators/aflpp/aflpp.c new file mode 100644 index 00000000..2b69ad9c --- /dev/null +++ b/custom_mutators/aflpp/aflpp.c @@ -0,0 +1,68 @@ +#include "afl-mutations.h" + +typedef struct my_mutator { + + afl_state_t *afl; + u8 *buf; + +} my_mutator_t; + +my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) { + + (void)seed; + + my_mutator_t *data = calloc(1, sizeof(my_mutator_t)); + if (!data) { + + perror("afl_custom_init alloc"); + return NULL; + + } + + data->buf = malloc(MAX_FILE); + if (!data->buf) { + + perror("afl_custom_init alloc"); + return NULL; + + } + + data->afl = afl; + + return data; + +} + +/* here we run the AFL++ mutator, which is the best! */ + +size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, + u8 **out_buf, uint8_t *add_buf, size_t add_buf_size, + size_t max_size) { + + u32 havoc_steps = 1 + rand_below(data->afl, 16); + + /* 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); + + /* return size of mutated data */ + *out_buf = data->buf; + return out_buf_len; + +} + +/** + * Deinitialize everything + * + * @param data The data ptr from afl_custom_init + */ +void afl_custom_deinit(my_mutator_t *data) { + + free(data->buf); + free(data); + +} + -- cgit 1.4.1 From 32ffa2664cdfa2cc377df12cbf6efdcecbc2e78a Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 4 Apr 2023 16:23:19 +0200 Subject: max_len support --- custom_mutators/aflpp/aflpp.c | 27 +++++++++++++-- include/afl-mutations.h | 76 +++++++++++++++++++++++++++---------------- 2 files changed, 72 insertions(+), 31 deletions(-) (limited to 'custom_mutators/aflpp') diff --git a/custom_mutators/aflpp/aflpp.c b/custom_mutators/aflpp/aflpp.c index 2b69ad9c..e15d0391 100644 --- a/custom_mutators/aflpp/aflpp.c +++ b/custom_mutators/aflpp/aflpp.c @@ -4,6 +4,7 @@ typedef struct my_mutator { afl_state_t *afl; u8 *buf; + u32 buf_size; } my_mutator_t; @@ -19,12 +20,15 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) { } - data->buf = malloc(MAX_FILE); - if (!data->buf) { + if ((data->buf = malloc(MAX_FILE)) == NULL) { perror("afl_custom_init alloc"); return NULL; + } else { + + data->buf_size = MAX_FILE; + } data->afl = afl; @@ -39,6 +43,23 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, u8 **out_buf, uint8_t *add_buf, size_t add_buf_size, size_t max_size) { + if (max_size > data->buf_size) { + + u8 *ptr = realloc(data->buf, max_size); + + if (ptr) { + + return 0; + + } else { + + data->buf = ptr; + data->buf_size = max_size; + + } + + } + u32 havoc_steps = 1 + rand_below(data->afl, 16); /* set everything up, costly ... :( */ @@ -46,7 +67,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t 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); + false, true, add_buf, add_buf_size, max_size); /* return size of mutated data */ *out_buf = data->buf; diff --git a/include/afl-mutations.h b/include/afl-mutations.h index 43b7927d..e3f69214 100644 --- a/include/afl-mutations.h +++ b/include/afl-mutations.h @@ -6,7 +6,8 @@ #include "afl-mutations.h" // needs afl-fuzz.h u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32t steps, bool is_text, - bool is_exploration, u8 *splice_buf, u32 splice_len); + bool is_exploration, u8 *splice_buf, u32 splice_len, + u32 max_len); Returns: u32 - the length of the mutated data return in *buf. 0 = error @@ -21,6 +22,7 @@ splice_buf - a buffer from another corpus item to splice with. If NULL then no splicing splice_len - the length of the splice buffer. If 0 then no splicing + u32 max_len - the maximum size the mutated buffer may grow to */ #ifndef _ANDROID_ASHMEM_H @@ -76,16 +78,13 @@ enum { }; -unsigned int mutation_strategy_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = {}; -unsigned int mutation_strategy_exploration_binary[MUT_STRATEGY_ARRAY_SIZE] = {}; -unsigned int mutation_strategy_exploitation_text[MUT_STRATEGY_ARRAY_SIZE] = {}; -unsigned int mutation_strategy_exploitation_binary[MUT_STRATEGY_ARRAY_SIZE] = - {}; +u32 mutation_strategy_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = {}; +u32 mutation_strategy_exploration_binary[MUT_STRATEGY_ARRAY_SIZE] = {}; +u32 mutation_strategy_exploitation_text[MUT_STRATEGY_ARRAY_SIZE] = {}; +u32 mutation_strategy_exploitation_binary[MUT_STRATEGY_ARRAY_SIZE] = {}; -unsigned int afl_mutate(afl_state_t *, unsigned char *, unsigned int, - unsigned int, bool, bool, unsigned char *, - unsigned int); -u32 choose_block_len(afl_state_t *, u32); +u32 afl_mutate(afl_state_t *, u8 *, u32, u32, bool, bool, u8 *, u32, u32); +u32 choose_block_len(afl_state_t *, u32); /* Helper to choose random block len for block operations in fuzz_one(). Doesn't return zero, provided that max_len is > 0. */ @@ -131,18 +130,39 @@ inline u32 choose_block_len(afl_state_t *afl, u32 limit) { } -unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len, - unsigned int steps, bool is_text, bool is_exploration, - unsigned char *splice_buf, unsigned int splice_len) { +inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps, + bool is_text, bool is_exploration, u8 *splice_buf, + u32 splice_len, u32 max_len) { if (!buf || !len) { return 0; } - u32 *mutation_array; - static unsigned char *tmp_buf = NULL; + u32 *mutation_array; + static u8 *tmp_buf = NULL; + static u32 tmp_buf_size = 0; - if (!tmp_buf) { + if (max_len > tmp_buf_size) { - if ((tmp_buf = malloc(MAX_FILE)) == NULL) { return 0; } + if (tmp_buf) { + + u8 *ptr = realloc(tmp_buf, max_len); + + if (!ptr) { + + return 0; + + } else { + + tmp_buf = ptr; + + } + + } else { + + if ((tmp_buf = malloc(max_len)) == NULL) { return 0; } + + } + + tmp_buf_size = max_len; } @@ -150,11 +170,11 @@ unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len, if (is_exploration) { - mutation_array = (unsigned int *)&mutation_strategy_exploration_text; + mutation_array = (u32 *)&mutation_strategy_exploration_text; } else { - mutation_array = (unsigned int *)&mutation_strategy_exploitation_text; + mutation_array = (u32 *)&mutation_strategy_exploitation_text; } @@ -162,17 +182,17 @@ unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len, if (is_exploration) { - mutation_array = (unsigned int *)&mutation_strategy_exploration_binary; + mutation_array = (u32 *)&mutation_strategy_exploration_binary; } else { - mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary; + mutation_array = (u32 *)&mutation_strategy_exploitation_binary; } } - for (unsigned int step = 0; step < steps; ++step) { + for (u32 step = 0; step < steps; ++step) { retry_havoc_step: @@ -400,7 +420,7 @@ unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len, case MUT_CLONE_OVERWRITE: { - if (likely(len + HAVOC_BLK_XL < MAX_FILE)) { + if (likely(len + HAVOC_BLK_XL < max_len)) { /* Clone bytes. */ @@ -439,7 +459,7 @@ unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len, case MUT_CLONE_INSERT: { - if (likely(len + HAVOC_BLK_XL < MAX_FILE)) { + if (likely(len + HAVOC_BLK_XL < max_len)) { /* Insert a block of constant bytes (25%). */ @@ -622,7 +642,7 @@ unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len, } while (unlikely(i == j)); - unsigned char temp = buf[off + i]; + u8 temp = buf[off + i]; buf[off + i] = buf[off + j]; buf[off + j] = temp; @@ -872,7 +892,7 @@ unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len, u32 use_extra = rand_below(afl, afl->extras_cnt); u32 extra_len = afl->extras[use_extra].len; - if (unlikely(len + extra_len >= MAX_FILE)) { goto retry_havoc_step; } + if (unlikely(len + extra_len >= max_len)) { goto retry_havoc_step; } u8 *ptr = afl->extras[use_extra].data; u32 insert_at = rand_below(afl, len + 1); @@ -912,7 +932,7 @@ unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len, u32 use_extra = rand_below(afl, afl->a_extras_cnt); u32 extra_len = afl->a_extras[use_extra].len; - if (unlikely(len + extra_len >= MAX_FILE)) { goto retry_havoc_step; } + if (unlikely(len + extra_len >= max_len)) { goto retry_havoc_step; } u8 *ptr = afl->a_extras[use_extra].data; u32 insert_at = rand_below(afl, len + 1); @@ -952,7 +972,7 @@ unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len, if (unlikely(!splice_buf || !splice_len)) { goto retry_havoc_step; } - if (unlikely(len + HAVOC_BLK_XL >= MAX_FILE)) { goto retry_havoc_step; } + if (unlikely(len + HAVOC_BLK_XL >= max_len)) { goto retry_havoc_step; } /* insert mode */ -- cgit 1.4.1 From d1ec5dc089ff29e596083a90fa64dcd77060e6bc Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 15 May 2023 15:11:16 +0200 Subject: standalone mutator --- custom_mutators/aflpp/standalone/Makefile | 10 ++ custom_mutators/aflpp/standalone/README.md | 10 ++ .../aflpp/standalone/aflpp-standalone.c | 167 +++++++++++++++++++++ 3 files changed, 187 insertions(+) create mode 100644 custom_mutators/aflpp/standalone/Makefile create mode 100644 custom_mutators/aflpp/standalone/README.md create mode 100644 custom_mutators/aflpp/standalone/aflpp-standalone.c (limited to 'custom_mutators/aflpp') diff --git a/custom_mutators/aflpp/standalone/Makefile b/custom_mutators/aflpp/standalone/Makefile new file mode 100644 index 00000000..f1e99445 --- /dev/null +++ b/custom_mutators/aflpp/standalone/Makefile @@ -0,0 +1,10 @@ + +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 + +clean: + rm -f *.o *~ aflpp-standalone core diff --git a/custom_mutators/aflpp/standalone/README.md b/custom_mutators/aflpp/standalone/README.md new file mode 100644 index 00000000..f5f94c5f --- /dev/null +++ b/custom_mutators/aflpp/standalone/README.md @@ -0,0 +1,10 @@ +# AFL++ standalone mutator + +this is the AFL++ havoc mutator as a standalone mutator + +just type `make` to build. + +``` +aflpp-standalone inputfile outputfile +``` + diff --git a/custom_mutators/aflpp/standalone/aflpp-standalone.c b/custom_mutators/aflpp/standalone/aflpp-standalone.c new file mode 100644 index 00000000..337b7937 --- /dev/null +++ b/custom_mutators/aflpp/standalone/aflpp-standalone.c @@ -0,0 +1,167 @@ +#include "afl-mutations.h" + +s8 interesting_8[] = {INTERESTING_8}; +s16 interesting_16[] = {INTERESTING_8, INTERESTING_16}; +s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32}; + +typedef struct my_mutator { + + afl_state_t *afl; + u8 *buf; + u32 buf_size; + +} my_mutator_t; + +my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) { + + (void)seed; + + my_mutator_t *data = calloc(1, sizeof(my_mutator_t)); + if (!data) { + + perror("afl_custom_init alloc"); + return NULL; + + } + + if ((data->buf = malloc(1024*1024)) == NULL) { + + perror("afl_custom_init alloc"); + return NULL; + + } else { + + data->buf_size = 1024*1024; + + } + + /* fake AFL++ state */ + data->afl = calloc(1, sizeof(afl_state_t)); + data->afl->queue_cycle = 1; + data->afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY); + rand_set_seed(data->afl, getpid()); + + return data; + +} + +/* here we run the AFL++ mutator, which is the best! */ + +size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, + u8 **out_buf, uint8_t *add_buf, size_t add_buf_size, + size_t max_size) { + + if (max_size > data->buf_size) { + + u8 *ptr = realloc(data->buf, max_size); + + if (ptr) { + + return 0; + + } else { + + data->buf = ptr; + data->buf_size = max_size; + + } + + } + + u32 havoc_steps = 1 + rand_below(data->afl, 16); + + /* 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); + + /* return size of mutated data */ + *out_buf = data->buf; + return out_buf_len; + +} + +int main(int argc, char *argv[]) { + + if (argc > 1 && strncmp(argv[1], "-h", 2) == 0) { + + printf("Syntax: $0 [-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("for splicing. Maximum input and output length is 1MB.\n"); + printf("The -v verbose option prints debug output to stderr\n"); + return 0; + + } + + FILE *in = stdin, *out = stdout, *splice = NULL; + unsigned char *inbuf = malloc(1024 * 1024), *outbuf, *splicebuf = NULL; + int verbose = 0, splicelen = 0; + + 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) { + perror(argv[1]); + return -1; + } + if (verbose) fprintf(stderr, "Input: %s\n", argv[1]); + } + + size_t inlen = fread(inbuf, 1, 1024*1024, in); + + if (!inlen) { + fprintf(stderr, "Error: empty file %s\n", argv[1] ? argv[1] : "stdin"); + return -1; + } + + if (argc > 2 && strcmp(argv[2], "-") != 0) { + if ((out = fopen(argv[2], "w")) == NULL) { + perror(argv[2]); + return -1; + } + if (verbose) fprintf(stderr, "Output: %s\n", argv[2]); + } + + if (argc > 3) { + if ((splice = fopen(argv[3], "r")) == NULL) { + perror(argv[3]); + 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 (!splicelen) { + fprintf(stderr, "Error: empty file %s\n", argv[3]); + 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); + + if (outlen == 0 || !outbuf) { + fprintf(stderr, "Error: no mutation data returned.\n"); + return -1; + } + + if (verbose) fprintf(stderr, "Mutation output length: %zu\n", outlen); + + if (fwrite(outbuf, 1, outlen, out) != outlen) { + fprintf(stderr, "Warning: incomplete write.\n"); + return -1; + } + + return 0; +} -- cgit 1.4.1 From ab148aeed81d755399e257c0c17fe4cbb9be3d48 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 15 May 2023 15:12:26 +0200 Subject: standalone mutator --- custom_mutators/aflpp/standalone/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'custom_mutators/aflpp') diff --git a/custom_mutators/aflpp/standalone/README.md b/custom_mutators/aflpp/standalone/README.md index f5f94c5f..a1ffb5f9 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 +aflpp-standalone inputfile outputfile [splicefile] ``` -- cgit 1.4.1 From 9a55bbdb44c1508a0b08728db2dacaebc9c43277 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 15 May 2023 15:17:33 +0200 Subject: fix --- custom_mutators/aflpp/standalone/aflpp-standalone.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'custom_mutators/aflpp') diff --git a/custom_mutators/aflpp/standalone/aflpp-standalone.c b/custom_mutators/aflpp/standalone/aflpp-standalone.c index 337b7937..91bac4a8 100644 --- a/custom_mutators/aflpp/standalone/aflpp-standalone.c +++ b/custom_mutators/aflpp/standalone/aflpp-standalone.c @@ -86,15 +86,13 @@ 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: $0 [-v] [inputfile [outputfile [splicefile]]]\n\n", argv[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("for splicing. Maximum input and output length is 1MB.\n"); - printf("The -v verbose option prints debug output to stderr\n"); + printf("The -v verbose option prints debug output to stderr.\n"); return 0; - } FILE *in = stdin, *out = stdout, *splice = NULL; -- cgit 1.4.1