From c75b403bb7eb44a37b1df8e37fca016a0277a7dc Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 24 Mar 2020 08:44:18 +0100 Subject: fix doc link --- examples/custom_mutators/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples/custom_mutators') diff --git a/examples/custom_mutators/README.md b/examples/custom_mutators/README.md index 93f824cd..e5af5516 100644 --- a/examples/custom_mutators/README.md +++ b/examples/custom_mutators/README.md @@ -1,7 +1,7 @@ # Examples for the custom mutator These are example and helper files for the custom mutator feature. -See [docs/python_mutators.md](../docs/custom_mutators.md) for more information +See [docs/custom_mutators.md](../docs/custom_mutators.md) for more information Note that if you compile with python3.7 you must use python3 scripts, and if you use pyton2.7 to compile python2 scripts! -- cgit 1.4.1 From 6d3dc83c5dde31ccb74e04815a04b85b05761b30 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 25 Mar 2020 11:31:01 +0100 Subject: code format --- examples/custom_mutators/custom_mutator_helpers.h | 11 +- examples/custom_mutators/example.c | 29 ++++-- include/afl-fuzz.h | 19 ++-- include/common.h | 25 +++-- llvm_mode/afl-clang-fast.c | 38 +++---- src/afl-fuzz-mutators.c | 22 ++-- src/afl-fuzz-one.c | 7 +- src/afl-fuzz-python.c | 46 +++++---- src/afl-fuzz-queue.c | 3 +- src/afl-fuzz-run.c | 8 +- src/afl-fuzz-stats.c | 119 +++++++++++----------- 11 files changed, 175 insertions(+), 152 deletions(-) (limited to 'examples/custom_mutators') diff --git a/examples/custom_mutators/custom_mutator_helpers.h b/examples/custom_mutators/custom_mutator_helpers.h index 844ccf94..cd3a15f0 100644 --- a/examples/custom_mutators/custom_mutator_helpers.h +++ b/examples/custom_mutators/custom_mutator_helpers.h @@ -7,11 +7,13 @@ #define RAND_BELOW(limit) (rand() % (limit)) -typedef struct{} afl_t; +typedef struct { + +} afl_t; static void surgical_havoc_mutate(u8 *out_buf, s32 begin, s32 end) { - static s8 interesting_8[] = {INTERESTING_8}; + static s8 interesting_8[] = {INTERESTING_8}; static s16 interesting_16[] = {INTERESTING_8, INTERESTING_16}; static s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32}; @@ -111,8 +113,8 @@ static void surgical_havoc_mutate(u8 *out_buf, s32 begin, s32 end) { (s64)interesting_32[RAND_BELOW(sizeof(interesting_32) >> 2)]; break; case 1: - *(u64 *)(out_buf + byte_idx) = - SWAP64((s64)interesting_32[RAND_BELOW(sizeof(interesting_32) >> 2)]); + *(u64 *)(out_buf + byte_idx) = SWAP64( + (s64)interesting_32[RAND_BELOW(sizeof(interesting_32) >> 2)]); break; } @@ -266,3 +268,4 @@ static void surgical_havoc_mutate(u8 *out_buf, s32 begin, s32 end) { } #endif + diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index 560a5919..2df17dec 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -23,7 +23,6 @@ static const char *commands[] = { }; - typedef struct my_mutator { afl_t *afl; @@ -34,21 +33,26 @@ typedef struct my_mutator { /** * Initialize this custom mutator * - * @param[in] afl a pointer to the internal state object. Can be ignored for now. - * @param[in] seed A seed for this mutator - the same seed should always mutate in the same way. + * @param[in] afl a pointer to the internal state object. Can be ignored for + * now. + * @param[in] seed A seed for this mutator - the same seed should always mutate + * in the same way. * @return Pointer to the data object this custom mutator instance should use. * There may be multiple instances of this mutator in one afl-fuzz run! * Returns NULL on error. */ my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) { - srand(seed); // needed also by surgical_havoc_mutate() + srand(seed); // needed also by surgical_havoc_mutate() my_mutator_t *data = calloc(1, sizeof(my_mutator_t)); if (!data) { + perror("afl_custom_init alloc"); return NULL; + } + data->afl = afl; return data; @@ -71,8 +75,8 @@ my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) { */ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t **buf, size_t buf_size, uint8_t *add_buf, - size_t add_buf_size, // add_buf can be NULL - size_t max_size) { + size_t add_buf_size, // add_buf can be NULL + size_t max_size) { // Make sure that the packet size does not exceed the maximum size expected by // the fuzzer @@ -113,7 +117,8 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t **buf, size_t buf_size, * will release the memory after saving the test case. * @return Size of the output buffer after processing */ -size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, uint8_t **out_buf) { +size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, + uint8_t **out_buf) { size_t out_buf_size; @@ -183,7 +188,8 @@ int afl_custom_init_trim(my_mutator_t *data, uint8_t *buf, size_t buf_size) { * the memory after saving the test case. * @param[out] out_buf_size Pointer to the size of the trimmed test case */ -void afl_custom_trim(my_mutator_t *data, uint8_t **out_buf, size_t *out_buf_size) { +void afl_custom_trim(my_mutator_t *data, uint8_t **out_buf, + size_t *out_buf_size) { *out_buf_size = trim_buf_size - 1; @@ -233,8 +239,8 @@ int afl_custom_post_trim(my_mutator_t *data, int success) { * not produce data larger than max_size. * @return Size of the mutated output. */ -size_t afl_custom_havoc_mutation(my_mutator_t *data, uint8_t **buf, size_t buf_size, - size_t max_size) { +size_t afl_custom_havoc_mutation(my_mutator_t *data, uint8_t **buf, + size_t buf_size, size_t max_size) { if (buf_size == 0) { @@ -292,7 +298,8 @@ uint8_t afl_custom_queue_get(my_mutator_t *data, const uint8_t *filename) { * @param filename_new_queue File name of the new queue entry * @param filename_orig_queue File name of the original queue entry */ -void afl_custom_queue_new_entry(my_mutator_t *data, const uint8_t *filename_new_queue, +void afl_custom_queue_new_entry(my_mutator_t * data, + const uint8_t *filename_new_queue, const uint8_t *filename_orig_queue) { /* Additional analysis on the original or new test case */ diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 7dddefb0..d610ac29 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -290,8 +290,8 @@ typedef struct py_mutator { PyObject *py_module; PyObject *py_functions[PY_FUNC_COUNT]; - void *afl_state; - void *py_data; + void * afl_state; + void * py_data; } py_mutator_t; @@ -592,7 +592,7 @@ struct custom_mutator { const char *name; void * dh; - void *data; /* custom mutator data ptr */ + void *data; /* custom mutator data ptr */ /* hooks for the custom mutator function */ @@ -620,8 +620,8 @@ struct custom_mutator { * not produce data larger than max_size. * @return Size of the mutated output. */ - size_t (*afl_custom_fuzz)(void *data, u8 **buf, size_t buf_size, - u8 *add_buf, size_t add_buf_size, size_t max_size); + size_t (*afl_custom_fuzz)(void *data, u8 **buf, size_t buf_size, u8 *add_buf, + size_t add_buf_size, size_t max_size); /** * A post-processing function to use right before AFL writes the test case to @@ -711,8 +711,8 @@ struct custom_mutator { * not produce data larger than max_size. * @return Size of the mutated output. */ - size_t (*afl_custom_havoc_mutation)(void *data, u8 **buf, - size_t buf_size, size_t max_size); + size_t (*afl_custom_havoc_mutation)(void *data, u8 **buf, size_t buf_size, + size_t max_size); /** * Return the probability (in percentage) that afl_custom_havoc_mutation @@ -748,9 +748,8 @@ struct custom_mutator { * @param filename_orig_queue File name of the original queue entry. This * argument can be NULL while initializing the fuzzer */ - void (*afl_custom_queue_new_entry)(void *data, - const u8 * filename_new_queue, - const u8 * filename_orig_queue); + void (*afl_custom_queue_new_entry)(void *data, const u8 *filename_new_queue, + const u8 *filename_orig_queue); /** * Deinitialize the custom mutator. * diff --git a/include/common.h b/include/common.h index 97076004..8b21b55f 100644 --- a/include/common.h +++ b/include/common.h @@ -78,7 +78,7 @@ static u64 get_cur_time_us(void) { Will return buf for convenience. */ static u8 *stringify_int(u8 *buf, size_t len, u64 val) { - +\ #define CHK_FORMAT(_divisor, _limit_mult, _fmt, _cast) \ do { \ \ @@ -233,23 +233,22 @@ static u8 *stringify_time_diff(u8 *buf, size_t len, u64 cur_ms, u64 event_ms) { } - /* Unsafe Describe integer. The buf sizes are not checked. This is unsafe but fast. Will return buf for convenience. */ static u8 *u_stringify_int(u8 *buf, u64 val) { - -#define CHK_FORMAT(_divisor, _limit_mult, _fmt, _cast) \ - do { \ - \ - if (val < (_divisor) * (_limit_mult)) { \ - \ - sprintf(buf, _fmt, ((_cast)val) / (_divisor)); \ - return buf; \ - \ - } \ - \ +\ +#define CHK_FORMAT(_divisor, _limit_mult, _fmt, _cast) \ + do { \ + \ + if (val < (_divisor) * (_limit_mult)) { \ + \ + sprintf(buf, _fmt, ((_cast)val) / (_divisor)); \ + return buf; \ + \ + } \ + \ } while (0) /* 0-9999 */ diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index 34df5671..7050e22d 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -485,37 +485,37 @@ static void edit_params(u32 argc, char **argv) { // if (maybe_linking) { - if (x_set) { + if (x_set) { - cc_params[cc_par_cnt++] = "-x"; - cc_params[cc_par_cnt++] = "none"; + cc_params[cc_par_cnt++] = "-x"; + cc_params[cc_par_cnt++] = "none"; - } + } #ifndef __ANDROID__ - switch (bit_mode) { + switch (bit_mode) { - case 0: - cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-rt.o", obj_path); - break; + case 0: + cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-rt.o", obj_path); + break; - case 32: - cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-rt-32.o", obj_path); + case 32: + cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-rt-32.o", obj_path); - if (access(cc_params[cc_par_cnt - 1], R_OK)) - FATAL("-m32 is not supported by your compiler"); + if (access(cc_params[cc_par_cnt - 1], R_OK)) + FATAL("-m32 is not supported by your compiler"); - break; + break; - case 64: - cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-rt-64.o", obj_path); + case 64: + cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-rt-64.o", obj_path); - if (access(cc_params[cc_par_cnt - 1], R_OK)) - FATAL("-m64 is not supported by your compiler"); + if (access(cc_params[cc_par_cnt - 1], R_OK)) + FATAL("-m64 is not supported by your compiler"); - break; + break; - } + } #endif diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 3e6ad466..0b0c3394 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -78,8 +78,7 @@ void destroy_custom_mutator(afl_state_t *afl) { afl->mutator->afl_custom_deinit(afl->mutator->data); - if (afl->mutator->dh) - dlclose(afl->mutator->dh); + if (afl->mutator->dh) dlclose(afl->mutator->dh); ck_free(afl->mutator); afl->mutator = NULL; @@ -103,11 +102,13 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) { /* Mutator */ /* "afl_custom_init", required */ afl->mutator->afl_custom_init = dlsym(dh, "afl_custom_init"); - if (!afl->mutator->afl_custom_init) FATAL("Symbol 'afl_custom_init' not found."); + if (!afl->mutator->afl_custom_init) + FATAL("Symbol 'afl_custom_init' not found."); /* "afl_custom_deinit", required */ afl->mutator->afl_custom_deinit = dlsym(dh, "afl_custom_deinit"); - if (!afl->mutator->afl_custom_deinit) FATAL("Symbol 'afl_custom_deinit' not found."); + if (!afl->mutator->afl_custom_deinit) + FATAL("Symbol 'afl_custom_deinit' not found."); /* "afl_custom_fuzz" or "afl_custom_mutator", required */ afl->mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_fuzz"); @@ -198,7 +199,8 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { /* Initialize trimming in the custom mutator */ afl->stage_cur = 0; - afl->stage_max = afl->mutator->afl_custom_init_trim(afl->mutator->data, in_buf, q->len); + afl->stage_max = + afl->mutator->afl_custom_init_trim(afl->mutator->data, in_buf, q->len); if (afl->not_on_tty && afl->debug) SAYF("[Custom Trimming] START: Max %d iterations, %u bytes", afl->stage_max, @@ -206,7 +208,8 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { while (afl->stage_cur < afl->stage_max) { - sprintf(afl->stage_name_buf, "ptrim %s", u_stringify_int(val_buf, trim_exec)); + sprintf(afl->stage_name_buf, "ptrim %s", + u_stringify_int(val_buf, trim_exec)); u32 cksum; @@ -250,7 +253,8 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { } /* Tell the custom mutator that the trimming was successful */ - afl->stage_cur = afl->mutator->afl_custom_post_trim(afl->mutator->data, 1); + afl->stage_cur = + afl->mutator->afl_custom_post_trim(afl->mutator->data, 1); if (afl->not_on_tty && afl->debug) SAYF("[Custom Trimming] SUCCESS: %d/%d iterations (now at %u bytes)", @@ -259,7 +263,8 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { } else { /* Tell the custom mutator that the trimming was unsuccessful */ - afl->stage_cur = afl->mutator->afl_custom_post_trim(afl->mutator->data, 0); + afl->stage_cur = + afl->mutator->afl_custom_post_trim(afl->mutator->data, 0); if (afl->not_on_tty && afl->debug) SAYF("[Custom Trimming] FAILURE: %d/%d iterations", afl->stage_cur, afl->stage_max); @@ -304,3 +309,4 @@ abort_trimming: return fault; } + diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index bcd9135a..7cc5e0d9 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -360,7 +360,8 @@ u8 fuzz_one_original(afl_state_t *afl) { /* The custom mutator will decide to skip this test case or not. */ - if (!afl->mutator->afl_custom_queue_get(afl->mutator->data, afl->queue_cur->fname)) + if (!afl->mutator->afl_custom_queue_get(afl->mutator->data, + afl->queue_cur->fname)) return 1; } @@ -1723,8 +1724,8 @@ havoc_stage: if (stacked_custom && rand_below(afl, 100) < stacked_custom_prob) { - temp_len = afl->mutator->afl_custom_havoc_mutation(afl->mutator->data, &out_buf, - temp_len, MAX_FILE); + temp_len = afl->mutator->afl_custom_havoc_mutation( + afl->mutator->data, &out_buf, temp_len, MAX_FILE); } diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index d3027d2b..418497d0 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -29,8 +29,10 @@ #ifdef USE_PYTHON static void *unsupported(afl_state_t *afl, unsigned int seed) { + FATAL("Python Mutator cannot be called twice yet"); return NULL; + } size_t fuzz_py(void *py_mutator, u8 **buf, size_t buf_size, u8 *add_buf, @@ -77,7 +79,8 @@ size_t fuzz_py(void *py_mutator, u8 **buf, size_t buf_size, u8 *add_buf, PyTuple_SetItem(py_args, 2, py_value); - py_value = PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_FUZZ], py_args); + py_value = PyObject_CallObject( + ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_FUZZ], py_args); Py_DECREF(py_args); @@ -99,7 +102,6 @@ size_t fuzz_py(void *py_mutator, u8 **buf, size_t buf_size, u8 *add_buf, } - static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { if (!module_name) return NULL; @@ -223,7 +225,8 @@ void finalize_py_module(void *py_mutator) { } -static void init_py(afl_state_t *afl, py_mutator_t *py_mutator, unsigned int seed) { +static void init_py(afl_state_t *afl, py_mutator_t *py_mutator, + unsigned int seed) { PyObject *py_args, *py_value; @@ -244,7 +247,8 @@ static void init_py(afl_state_t *afl, py_mutator_t *py_mutator, unsigned int see PyTuple_SetItem(py_args, 0, py_value); - py_value = PyObject_CallObject(py_mutator->py_functions[PY_FUNC_INIT], py_args); + py_value = + PyObject_CallObject(py_mutator->py_functions[PY_FUNC_INIT], py_args); Py_DECREF(py_args); @@ -289,9 +293,7 @@ void load_custom_mutator_py(afl_state_t *afl, char *module_name) { py_mutator_t *py_mutator; py_mutator = init_py_module(afl, module_name); - if (!py_mutator) { - FATAL("Failed to load python mutator."); - } + if (!py_mutator) { FATAL("Failed to load python mutator."); } PyObject **py_functions = py_mutator->py_functions; @@ -334,7 +336,6 @@ void load_custom_mutator_py(afl_state_t *afl, char *module_name) { } - size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf) { size_t out_buf_size; @@ -350,7 +351,8 @@ size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf) { PyTuple_SetItem(py_args, 0, py_value); - py_value = PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_PRE_SAVE], py_args); + py_value = PyObject_CallObject( + ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_PRE_SAVE], py_args); Py_DECREF(py_args); @@ -386,7 +388,8 @@ u32 init_trim_py(void *py_mutator, u8 *buf, size_t buf_size) { PyTuple_SetItem(py_args, 0, py_value); - py_value = PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_INIT_TRIM], py_args); + py_value = PyObject_CallObject( + ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_INIT_TRIM], py_args); Py_DECREF(py_args); if (py_value != NULL) { @@ -424,7 +427,8 @@ u32 post_trim_py(void *py_mutator, u8 success) { PyTuple_SetItem(py_args, 0, py_value); - py_value = PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_POST_TRIM], py_args); + py_value = PyObject_CallObject( + ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_POST_TRIM], py_args); Py_DECREF(py_args); if (py_value != NULL) { @@ -451,7 +455,8 @@ void trim_py(void *py_mutator, u8 **out_buf, size_t *out_buf_size) { PyObject *py_args, *py_value; py_args = PyTuple_New(0); - py_value = PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_TRIM], py_args); + py_value = PyObject_CallObject( + ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_TRIM], py_args); Py_DECREF(py_args); if (py_value != NULL) { @@ -503,8 +508,9 @@ size_t havoc_mutation_py(void *py_mutator, u8 **buf, size_t buf_size, PyTuple_SetItem(py_args, 1, py_value); - py_value = - PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_HAVOC_MUTATION], py_args); + py_value = PyObject_CallObject( + ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_HAVOC_MUTATION], + py_args); Py_DECREF(py_args); @@ -533,7 +539,9 @@ u8 havoc_mutation_probability_py(void *py_mutator) { py_args = PyTuple_New(0); py_value = PyObject_CallObject( - ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY], py_args); + ((py_mutator_t *)py_mutator) + ->py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY], + py_args); Py_DECREF(py_args); if (py_value != NULL) { @@ -573,7 +581,8 @@ u8 queue_get_py(void *py_mutator, const u8 *filename) { PyTuple_SetItem(py_args, 0, py_value); // Call Python function - py_value = PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_QUEUE_GET], py_args); + py_value = PyObject_CallObject( + ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_QUEUE_GET], py_args); Py_DECREF(py_args); if (py_value != NULL) { @@ -642,8 +651,9 @@ void queue_new_entry_py(void *py_mutator, const u8 *filename_new_queue, PyTuple_SetItem(py_args, 1, py_value); // Call - py_value = - PyObject_CallObject(((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_QUEUE_NEW_ENTRY], py_args); + py_value = PyObject_CallObject( + ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_QUEUE_NEW_ENTRY], + py_args); Py_DECREF(py_args); if (py_value == NULL) { diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index b036969f..73da449a 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -147,7 +147,8 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { /* At the initialization stage, queue_cur is NULL */ if (afl->queue_cur) fname_orig = afl->queue_cur->fname; - afl->mutator->afl_custom_queue_new_entry(afl->mutator->data, fname, fname_orig); + afl->mutator->afl_custom_queue_new_entry(afl->mutator->data, fname, + fname_orig); } diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 2b207a9e..e8ef3049 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -217,8 +217,8 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) { if (afl->mutator && afl->mutator->afl_custom_pre_save) { u8 * new_data; - size_t new_size = - afl->mutator->afl_custom_pre_save(afl->mutator->data, mem, len, &new_data); + size_t new_size = afl->mutator->afl_custom_pre_save(afl->mutator->data, mem, + len, &new_data); ck_write(fd, new_data, new_size, afl->fsrv.out_file); free(new_data); @@ -627,8 +627,8 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { u32 remove_pos = remove_len; sprintf(afl->stage_name_buf, "trim %s/%s", - u_stringify_int(val_bufs[0], remove_len), - u_stringify_int(val_bufs[1], remove_len)); + u_stringify_int(val_bufs[0], remove_len), + u_stringify_int(val_bufs[1], remove_len)); afl->stage_cur = 0; afl->stage_max = q->len / remove_len; diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index dc16df8f..5536c201 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -361,9 +361,9 @@ void show_stats(afl_state_t *afl) { /* Lord, forgive me this. */ - SAYF(SET_G1 bSTG bLT bH bSTOP cCYA + SAYF(SET_G1 bSTG bLT bH bSTOP cCYA " process timing " bSTG bH30 bH5 bH bHB bH bSTOP cCYA - " overall results " bSTG bH2 bH2 bRT "\n"); + " overall results " bSTG bH2 bH2 bRT "\n"); if (afl->dumb_mode) { @@ -406,8 +406,7 @@ void show_stats(afl_state_t *afl) { (afl->last_path_time || afl->resuming_fuzz || afl->queue_cycle == 1 || afl->in_bitmap || afl->crash_mode)) { - u_stringify_time_diff(time_tmp, cur_ms, - afl->last_path_time); + u_stringify_time_diff(time_tmp, cur_ms, afl->last_path_time); SAYF(bV bSTOP " last new path : " cRST "%-33s ", time_tmp); } else { @@ -446,9 +445,9 @@ void show_stats(afl_state_t *afl) { " uniq hangs : " cRST "%-6s" bSTG bV "\n", time_tmp, tmp); - SAYF(bVR bH bSTOP cCYA + SAYF(bVR bH bSTOP cCYA " cycle progress " bSTG bH10 bH5 bH2 bH2 bHB bH bSTOP cCYA - " map coverage " bSTG bH bHT bH20 bH2 bVL "\n"); + " map coverage " bSTG bH bHT bH20 bH2 bVL "\n"); /* This gets funny because we want to print several variable-length variables together, but then cram them into a fixed-width field - so we need to @@ -477,9 +476,9 @@ void show_stats(afl_state_t *afl) { SAYF(bSTOP " count coverage : " cRST "%-21s" bSTG bV "\n", tmp); - SAYF(bVR bH bSTOP cCYA + SAYF(bVR bH bSTOP cCYA " stage progress " bSTG bH10 bH5 bH2 bH2 bX bH bSTOP cCYA - " findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n"); + " findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n"); sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_favored), ((double)afl->queued_favored) * 100 / afl->queued_paths); @@ -533,30 +532,27 @@ void show_stats(afl_state_t *afl) { if (afl->stats_avg_exec < 100) { - sprintf(tmp, "%s/sec (%s)", - u_stringify_float(IB(0), afl->stats_avg_exec), - afl->stats_avg_exec < 20 ? "zzzz..." : "slow!"); + sprintf(tmp, "%s/sec (%s)", u_stringify_float(IB(0), afl->stats_avg_exec), + afl->stats_avg_exec < 20 ? "zzzz..." : "slow!"); SAYF(bV bSTOP " exec speed : " cLRD "%-20s ", tmp); } else { - sprintf(tmp, "%s/sec", - u_stringify_float(IB(0), afl->stats_avg_exec)); + sprintf(tmp, "%s/sec", u_stringify_float(IB(0), afl->stats_avg_exec)); SAYF(bV bSTOP " exec speed : " cRST "%-20s ", tmp); } - sprintf(tmp, "%s (%s%s unique)", - u_stringify_int(IB(0), afl->total_tmouts), - u_stringify_int(IB(1), afl->unique_tmouts), - (afl->unique_hangs >= KEEP_UNIQUE_HANG) ? "+" : ""); + sprintf(tmp, "%s (%s%s unique)", u_stringify_int(IB(0), afl->total_tmouts), + u_stringify_int(IB(1), afl->unique_tmouts), + (afl->unique_hangs >= KEEP_UNIQUE_HANG) ? "+" : ""); SAYF(bSTG bV bSTOP " total tmouts : " cRST "%-22s" bSTG bV "\n", tmp); /* Aaaalmost there... hold on! */ - SAYF(bVR bH cCYA bSTOP + SAYF(bVR bH cCYA bSTOP " fuzzing strategy yields " bSTG bH10 bHT bH10 bH5 bHB bH bSTOP cCYA " path geometry " bSTG bH5 bH2 bVL "\n"); @@ -567,12 +563,12 @@ void show_stats(afl_state_t *afl) { } else { sprintf(tmp, "%s/%s, %s/%s, %s/%s", - u_stringify_int(IB(0), afl->stage_finds[STAGE_FLIP1]), - u_stringify_int(IB(1), afl->stage_cycles[STAGE_FLIP1]), - u_stringify_int(IB(2), afl->stage_finds[STAGE_FLIP2]), - u_stringify_int(IB(3), afl->stage_cycles[STAGE_FLIP2]), - u_stringify_int(IB(3), afl->stage_finds[STAGE_FLIP4]), - u_stringify_int(IB(5), afl->stage_cycles[STAGE_FLIP4])); + u_stringify_int(IB(0), afl->stage_finds[STAGE_FLIP1]), + u_stringify_int(IB(1), afl->stage_cycles[STAGE_FLIP1]), + u_stringify_int(IB(2), afl->stage_finds[STAGE_FLIP2]), + u_stringify_int(IB(3), afl->stage_cycles[STAGE_FLIP2]), + u_stringify_int(IB(3), afl->stage_finds[STAGE_FLIP4]), + u_stringify_int(IB(5), afl->stage_cycles[STAGE_FLIP4])); } @@ -582,12 +578,12 @@ void show_stats(afl_state_t *afl) { if (!afl->skip_deterministic) sprintf(tmp, "%s/%s, %s/%s, %s/%s", - u_stringify_int(IB(0), afl->stage_finds[STAGE_FLIP8]), - u_stringify_int(IB(1), afl->stage_cycles[STAGE_FLIP8]), - u_stringify_int(IB(2), afl->stage_finds[STAGE_FLIP16]), - u_stringify_int(IB(3), afl->stage_cycles[STAGE_FLIP16]), - u_stringify_int(IB(4), afl->stage_finds[STAGE_FLIP32]), - u_stringify_int(IB(5), afl->stage_cycles[STAGE_FLIP32])); + u_stringify_int(IB(0), afl->stage_finds[STAGE_FLIP8]), + u_stringify_int(IB(1), afl->stage_cycles[STAGE_FLIP8]), + u_stringify_int(IB(2), afl->stage_finds[STAGE_FLIP16]), + u_stringify_int(IB(3), afl->stage_cycles[STAGE_FLIP16]), + u_stringify_int(IB(4), afl->stage_finds[STAGE_FLIP32]), + u_stringify_int(IB(5), afl->stage_cycles[STAGE_FLIP32])); SAYF(bV bSTOP " byte flips : " cRST "%-36s " bSTG bV bSTOP " pending : " cRST "%-10s" bSTG bV "\n", @@ -595,12 +591,12 @@ void show_stats(afl_state_t *afl) { if (!afl->skip_deterministic) sprintf(tmp, "%s/%s, %s/%s, %s/%s", - u_stringify_int(IB(0), afl->stage_finds[STAGE_ARITH8]), - u_stringify_int(IB(1), afl->stage_cycles[STAGE_ARITH8]), - u_stringify_int(IB(2), afl->stage_finds[STAGE_ARITH16]), - u_stringify_int(IB(3), afl->stage_cycles[STAGE_ARITH16]), - u_stringify_int(IB(4), afl->stage_finds[STAGE_ARITH32]), - u_stringify_int(IB(5), afl->stage_cycles[STAGE_ARITH32])); + u_stringify_int(IB(0), afl->stage_finds[STAGE_ARITH8]), + u_stringify_int(IB(1), afl->stage_cycles[STAGE_ARITH8]), + u_stringify_int(IB(2), afl->stage_finds[STAGE_ARITH16]), + u_stringify_int(IB(3), afl->stage_cycles[STAGE_ARITH16]), + u_stringify_int(IB(4), afl->stage_finds[STAGE_ARITH32]), + u_stringify_int(IB(5), afl->stage_cycles[STAGE_ARITH32])); SAYF(bV bSTOP " arithmetics : " cRST "%-36s " bSTG bV bSTOP " pend fav : " cRST "%-10s" bSTG bV "\n", @@ -621,25 +617,26 @@ void show_stats(afl_state_t *afl) { if (!afl->skip_deterministic) sprintf(tmp, "%s/%s, %s/%s, %s/%s", - u_stringify_int(IB(0), afl->stage_finds[STAGE_EXTRAS_UO]), - u_stringify_int(IB(1), afl->stage_cycles[STAGE_EXTRAS_UO]), - u_stringify_int(IB(2), afl->stage_finds[STAGE_EXTRAS_UI]), - u_stringify_int(IB(3), afl->stage_cycles[STAGE_EXTRAS_UI]), - u_stringify_int(IB(4), afl->stage_finds[STAGE_EXTRAS_AO]), - u_stringify_int(IB(5), afl->stage_cycles[STAGE_EXTRAS_AO])); + u_stringify_int(IB(0), afl->stage_finds[STAGE_EXTRAS_UO]), + u_stringify_int(IB(1), afl->stage_cycles[STAGE_EXTRAS_UO]), + u_stringify_int(IB(2), afl->stage_finds[STAGE_EXTRAS_UI]), + u_stringify_int(IB(3), afl->stage_cycles[STAGE_EXTRAS_UI]), + u_stringify_int(IB(4), afl->stage_finds[STAGE_EXTRAS_AO]), + u_stringify_int(IB(5), afl->stage_cycles[STAGE_EXTRAS_AO])); SAYF(bV bSTOP " dictionary : " cRST "%-36s " bSTG bV bSTOP " imported : " cRST "%-10s" bSTG bV "\n", tmp, - afl->sync_id ? u_stringify_int(IB(0), afl->queued_imported) : (u8 *)"n/a"); + afl->sync_id ? u_stringify_int(IB(0), afl->queued_imported) + : (u8 *)"n/a"); sprintf(tmp, "%s/%s, %s/%s, %s/%s", - u_stringify_int(IB(0), afl->stage_finds[STAGE_HAVOC]), - u_stringify_int(IB(2), afl->stage_cycles[STAGE_HAVOC]), - u_stringify_int(IB(3), afl->stage_finds[STAGE_SPLICE]), - u_stringify_int(IB(4), afl->stage_cycles[STAGE_SPLICE]), - u_stringify_int(IB(5), afl->stage_finds[STAGE_RADAMSA]), - u_stringify_int(IB(6), afl->stage_cycles[STAGE_RADAMSA])); + u_stringify_int(IB(0), afl->stage_finds[STAGE_HAVOC]), + u_stringify_int(IB(2), afl->stage_cycles[STAGE_HAVOC]), + u_stringify_int(IB(3), afl->stage_finds[STAGE_SPLICE]), + u_stringify_int(IB(4), afl->stage_cycles[STAGE_SPLICE]), + u_stringify_int(IB(5), afl->stage_finds[STAGE_RADAMSA]), + u_stringify_int(IB(6), afl->stage_cycles[STAGE_RADAMSA])); SAYF(bV bSTOP " havoc/rad : " cRST "%-36s " bSTG bV bSTOP, tmp); @@ -660,14 +657,14 @@ void show_stats(afl_state_t *afl) { if (afl->shm.cmplog_mode) { sprintf(tmp, "%s/%s, %s/%s, %s/%s, %s/%s", - u_stringify_int(IB(0), afl->stage_finds[STAGE_PYTHON]), - u_stringify_int(IB(1), afl->stage_cycles[STAGE_PYTHON]), - u_stringify_int(IB(2), afl->stage_finds[STAGE_CUSTOM_MUTATOR]), - u_stringify_int(IB(3), afl->stage_cycles[STAGE_CUSTOM_MUTATOR]), - u_stringify_int(IB(4), afl->stage_finds[STAGE_COLORIZATION]), - u_stringify_int(IB(5), afl->stage_cycles[STAGE_COLORIZATION]), - u_stringify_int(IB(6), afl->stage_finds[STAGE_ITS]), - u_stringify_int(IB(7), afl->stage_cycles[STAGE_ITS])); + u_stringify_int(IB(0), afl->stage_finds[STAGE_PYTHON]), + u_stringify_int(IB(1), afl->stage_cycles[STAGE_PYTHON]), + u_stringify_int(IB(2), afl->stage_finds[STAGE_CUSTOM_MUTATOR]), + u_stringify_int(IB(3), afl->stage_cycles[STAGE_CUSTOM_MUTATOR]), + u_stringify_int(IB(4), afl->stage_finds[STAGE_COLORIZATION]), + u_stringify_int(IB(5), afl->stage_cycles[STAGE_COLORIZATION]), + u_stringify_int(IB(6), afl->stage_finds[STAGE_ITS]), + u_stringify_int(IB(7), afl->stage_cycles[STAGE_ITS])); SAYF(bV bSTOP " custom/rq : " cRST "%-36s " bSTG bVR bH20 bH2 bH bRB "\n", tmp); @@ -675,10 +672,10 @@ void show_stats(afl_state_t *afl) { } else { sprintf(tmp, "%s/%s, %s/%s", - u_stringify_int(IB(0), afl->stage_finds[STAGE_PYTHON]), - u_stringify_int(IB(1), afl->stage_cycles[STAGE_PYTHON]), - u_stringify_int(IB(2), afl->stage_finds[STAGE_CUSTOM_MUTATOR]), - u_stringify_int(IB(3), afl->stage_cycles[STAGE_CUSTOM_MUTATOR])); + u_stringify_int(IB(0), afl->stage_finds[STAGE_PYTHON]), + u_stringify_int(IB(1), afl->stage_cycles[STAGE_PYTHON]), + u_stringify_int(IB(2), afl->stage_finds[STAGE_CUSTOM_MUTATOR]), + u_stringify_int(IB(3), afl->stage_cycles[STAGE_CUSTOM_MUTATOR])); SAYF(bV bSTOP " py/custom : " cRST "%-36s " bSTG bVR bH20 bH2 bH bRB "\n", tmp); -- cgit 1.4.1 From e9c7610cb7d309f4c7fd1fd6435c29e736869772 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 25 Mar 2020 21:54:52 +0100 Subject: edited custom mutator pre_save api --- docs/custom_mutators.md | 2 +- examples/custom_mutators/example.c | 25 +++++++++++------ include/afl-fuzz.h | 12 +++++++-- src/afl-fuzz-mutators.c | 21 ++++++++++++++- src/afl-fuzz-python.c | 55 +++++++++++++++++++++++++++++++++----- src/afl-fuzz-run.c | 52 +++++++++++++++++++++++++++++------ 6 files changed, 140 insertions(+), 27 deletions(-) (limited to 'examples/custom_mutators') diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index 14d8f518..ecbd50ba 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -30,7 +30,7 @@ C/C++: void afl_custom_init(unsigned int seed); size_t afl_custom_fuzz(uint8_t** buf, size_t buf_size, uint8_t* add_buf, size_t add_buf_size, size_t max_size); -size_t afl_custom_pre_save(uint8_t* buf, size_t buf_size, uint8_t** out_buf); +size_t afl_custom_write_to_testcase(uint8_t* buf, size_t buf_size, uint8_t** out_buf); uint32_t afl_custom_init_trim(uint8_t* buf, size_t buf_size); void afl_custom_trim(uint8_t** out_buf, size_t* out_buf_size); uint32_t afl_custom_post_trim(uint8_t success); diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index 2df17dec..3e708db8 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -12,6 +12,7 @@ #include #include #include +#include #define DATA_SIZE (100) @@ -112,21 +113,29 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t **buf, size_t buf_size, * @param[in] data pointer returned in afl_custom_init for this fuzz case * @param[in] buf Buffer containing the test case to be executed * @param[in] buf_size Size of the test case - * @param[out] out_buf Pointer to the buffer containing the test case after + * @param[in] out_buf Pointer to the buffer containing the test case after * processing. External library should allocate memory for out_buf. AFL++ * will release the memory after saving the test case. - * @return Size of the output buffer after processing + * out_buf will always be at least as large as buf. + * @param[in] out_buf_size The maximum size we may use. + * In case we need to have this bigger, simply return that. + * @return Size of the output buffer after processing or the needed amount. + * return 0 to indicate the original buf should be used. */ size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, - uint8_t **out_buf) { + uint8_t *out_buf, size_t out_buf_size) { - size_t out_buf_size; + // In case we need more than out_buf_size, we return that amount and get + // called again. + if (out_buf_size < 32000) return 32000; + memcpy(out_buf, buf, buf_size); out_buf_size = buf_size; - - // External mutator should allocate memory for `out_buf` - *out_buf = malloc(out_buf_size); - memcpy(*out_buf, buf, out_buf_size); + out_buf[0] = 'A'; + out_buf[1] = 'F'; + out_buf[2] = 'L'; + out_buf[3] = '+'; + out_buf[4] = '+'; return out_buf_size; diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index d610ac29..8bf66403 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -30,6 +30,9 @@ #define AFL_MAIN #define MESSAGES_TO_STDOUT +/* We preallocate a buffer of this size for afl_custom_pre_save */ +#define PRE_SAVE_BUF_INIT_SIZE (16384) + #ifndef _GNU_SOURCE #define _GNU_SOURCE 1 #endif @@ -293,6 +296,9 @@ typedef struct py_mutator { void * afl_state; void * py_data; + PyObject *scratch_buf; + size_t scratch_size; + } py_mutator_t; #endif @@ -591,6 +597,8 @@ struct custom_mutator { const char *name; void * dh; + u8 * pre_save_buf; + size_t pre_save_size; void *data; /* custom mutator data ptr */ @@ -639,7 +647,7 @@ struct custom_mutator { * @return Size of the output buffer after processing */ size_t (*afl_custom_pre_save)(void *data, u8 *buf, size_t buf_size, - u8 **out_buf); + u8 *out_buf, size_t out_buf_size); /** * This method is called at the start of each trimming operation and receives @@ -775,7 +783,7 @@ u8 trim_case_custom(afl_state_t *, struct queue_entry *q, u8 *in_buf); void finalize_py_module(void *); -size_t pre_save_py(void *, u8 *, size_t, u8 **); +size_t pre_save_py(void *, u8 *, size_t, u8 *, size_t); u32 init_trim_py(void *, u8 *, size_t); u32 post_trim_py(void *, u8); void trim_py(void *, u8 **, size_t *); diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 0b0c3394..fac97f8e 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -80,6 +80,14 @@ void destroy_custom_mutator(afl_state_t *afl) { if (afl->mutator->dh) dlclose(afl->mutator->dh); + if (afl->mutator->pre_save_buf) { + + ck_free(afl->mutator->pre_save_buf); + afl->mutator->pre_save_buf = NULL; + afl->mutator->pre_save_size = 0; + + } + ck_free(afl->mutator); afl->mutator = NULL; @@ -91,6 +99,8 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) { void *dh; afl->mutator = ck_alloc(sizeof(struct custom_mutator)); + afl->mutator->pre_save_buf = NULL; + afl->mutator->pre_save_size = 0; afl->mutator->name = fn; ACTF("Loading custom mutator library from '%s'...", fn); @@ -125,9 +135,18 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) { /* "afl_custom_pre_save", optional */ afl->mutator->afl_custom_pre_save = dlsym(dh, "afl_custom_pre_save"); - if (!afl->mutator->afl_custom_pre_save) + if (!afl->mutator->afl_custom_pre_save) { + WARNF("Symbol 'afl_custom_pre_save' not found."); + } else { + + /* if we have a pre_save hook, prealloc some memory. */ + afl->mutator->pre_save_buf = ck_alloc(PRE_SAVE_BUF_INIT_SIZE * sizeof(u8)); + afl->mutator->pre_save_size = PRE_SAVE_BUF_INIT_SIZE; + + } + u8 notrim = 0; /* "afl_custom_init_trim", optional */ afl->mutator->afl_custom_init_trim = dlsym(dh, "afl_custom_init_trim"); diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index 418497d0..b053e8d5 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -287,6 +287,8 @@ void deinit_py(void *py_mutator) { void load_custom_mutator_py(afl_state_t *afl, char *module_name) { afl->mutator = ck_alloc(sizeof(struct custom_mutator)); + afl->mutator->pre_save_buf = NULL; + afl->mutator->pre_save_size = 0; afl->mutator->name = module_name; ACTF("Loading Python mutator library from '%s'...", module_name); @@ -305,8 +307,14 @@ void load_custom_mutator_py(afl_state_t *afl, char *module_name) { is quite different from the custom mutator. */ afl->mutator->afl_custom_fuzz = fuzz_py; - if (py_functions[PY_FUNC_PRE_SAVE]) + if (py_functions[PY_FUNC_PRE_SAVE]) { + afl->mutator->afl_custom_pre_save = pre_save_py; + /* if we have a pre_save hook, prealloc some memory. */ + afl->mutator->pre_save_buf = ck_alloc(PRE_SAVE_BUF_INIT_SIZE * sizeof(u8)); + afl->mutator->pre_save_size = PRE_SAVE_BUF_INIT_SIZE; + + } if (py_functions[PY_FUNC_INIT_TRIM]) afl->mutator->afl_custom_init_trim = init_trim_py; @@ -336,10 +344,33 @@ void load_custom_mutator_py(afl_state_t *afl, char *module_name) { } -size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf) { +size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 *out_buf, + size_t out_buf_size) { - size_t out_buf_size; + size_t py_out_buf_size; PyObject *py_args, *py_value; + + if (((py_mutator_t *)py_mutator)->scratch_buf) { + + /* We are being recalled from an earlier run + where we didn't have enough mem. */ + if (((py_mutator_t *)py_mutator)->scratch_size < out_buf_size) { + + FATAL("out_buf is still too small after resizing in custom mutator."); + + } + + py_value = ((py_mutator_t *)py_mutator)->scratch_buf; + py_out_buf_size = ((py_mutator_t *)py_mutator)->scratch_size; + ((py_mutator_t *)py_mutator)->scratch_buf = NULL; + py_out_buf_size = 0; + + memcpy(out_buf, PyByteArray_AsString(py_value), py_out_buf_size); + Py_DECREF(py_value); + return py_out_buf_size; + + } + py_args = PyTuple_New(1); py_value = PyByteArray_FromStringAndSize(buf, buf_size); if (!py_value) { @@ -358,11 +389,21 @@ size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf) { if (py_value != NULL) { - out_buf_size = PyByteArray_Size(py_value); - *out_buf = malloc(out_buf_size); - memcpy(*out_buf, PyByteArray_AsString(py_value), out_buf_size); + py_out_buf_size = PyByteArray_Size(py_value); + if (py_out_buf_size > out_buf_size) { + + /* Not enough space! + We will get called again right after resizing the buf. + Keep the references to our data for now. */ + ((py_mutator_t *)py_mutator)->scratch_buf = py_value; + ((py_mutator_t *)py_mutator)->scratch_size = py_out_buf_size; + return py_out_buf_size; + + } + + memcpy(out_buf, PyByteArray_AsString(py_value), py_out_buf_size); Py_DECREF(py_value); - return out_buf_size; + return py_out_buf_size; } else { diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index e8ef3049..a539b469 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -216,14 +216,49 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) { if (afl->mutator && afl->mutator->afl_custom_pre_save) { - u8 * new_data; - size_t new_size = afl->mutator->afl_custom_pre_save(afl->mutator->data, mem, - len, &new_data); - ck_write(fd, new_data, new_size, afl->fsrv.out_file); - free(new_data); + if (unlikely(afl->mutator->pre_save_size < len)) { + + afl->mutator->pre_save_buf = + ck_realloc(afl->mutator->pre_save_buf, len * sizeof(u8)); + afl->mutator->pre_save_size = len; + + } + + u8 buf_written = 0; + while (!buf_written) { + + buf_written = 1; + size_t new_size = afl->mutator->afl_custom_pre_save( + afl->mutator->data, mem, len, afl->mutator->pre_save_buf, + afl->mutator->pre_save_size); + + if (unlikely(new_size) == 0) { + + /* custom_pre_save wants us to use the old buf */ + ck_write(fd, mem, len, afl->fsrv.out_file); + + } else if (unlikely(new_size) > afl->mutator->pre_save_size) { + + /* The custom func needs more space. + Realloc and call again. */ + afl->mutator->pre_save_buf = + ck_realloc(afl->mutator->pre_save_buf, new_size * sizeof(u8)); + afl->mutator->pre_save_size = new_size; + buf_written = 0; + continue; + + } else { + + /* everything as planned. use the new data. */ + ck_write(fd, afl->mutator->pre_save_buf, new_size, afl->fsrv.out_file); + + } + + } } else { + /* boring uncustom. */ ck_write(fd, mem, len, afl->fsrv.out_file); } @@ -505,8 +540,8 @@ void sync_fuzzers(afl_state_t *afl) { afl->stage_cur = 0; afl->stage_max = 0; - /* For every file queued by this fuzzer, parse ID and see if we have looked - at it before; exec a test case if not. */ + /* For every file queued by this fuzzer, parse ID and see if we have + looked at it before; exec a test case if not. */ while ((qd_ent = readdir(qd))) { @@ -645,7 +680,8 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { if (afl->stop_soon || fault == FAULT_ERROR) goto abort_trimming; - /* Note that we don't keep track of crashes or hangs here; maybe TODO? */ + /* Note that we don't keep track of crashes or hangs here; maybe TODO? + */ cksum = hash32(afl->fsrv.trace_bits, MAP_SIZE, HASH_CONST); -- cgit 1.4.1 From d6a7630fe2938621db05e616fe6b1b21dfaf21b3 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Thu, 26 Mar 2020 19:44:44 +0100 Subject: more api --- docs/custom_mutators.md | 3 +- examples/custom_mutators/example.c | 35 ++++++++++++++++++++---- include/afl-fuzz.h | 19 ++++++------- src/afl-fuzz-mutators.c | 11 +------- src/afl-fuzz-python.c | 56 ++++++++++---------------------------- src/afl-fuzz-run.c | 45 ++++++------------------------ src/afl-fuzz-stats.c | 14 +++++----- 7 files changed, 71 insertions(+), 112 deletions(-) (limited to 'examples/custom_mutators') diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index ecbd50ba..2163b2d5 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -27,7 +27,7 @@ performed with the custom mutator. C/C++: ```c -void afl_custom_init(unsigned int seed); +void afl_custom_init(void *afl, unsigned int seed); size_t afl_custom_fuzz(uint8_t** buf, size_t buf_size, uint8_t* add_buf, size_t add_buf_size, size_t max_size); size_t afl_custom_write_to_testcase(uint8_t* buf, size_t buf_size, uint8_t** out_buf); @@ -39,6 +39,7 @@ uint8_t afl_custom_havoc_mutation_probability(void); uint8_t afl_custom_queue_get(const uint8_t* filename); void afl_custom_queue_new_entry(const uint8_t* filename_new_queue, const uint8_t* filename_orig_queue); +void afl_custom_deinit(void *data); ``` Python: diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index 3e708db8..04b72c77 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -15,6 +15,7 @@ #include #define DATA_SIZE (100) +#define INITIAL_BUF_SIZE (16384) static const char *commands[] = { @@ -28,6 +29,8 @@ typedef struct my_mutator { afl_t *afl; // any additional data here! + size_t pre_save_size; + u8 * pre_save_buf; } my_mutator_t; @@ -56,6 +59,16 @@ my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) { data->afl = afl; + data->pre_save_buf = malloc(INITIAL_BUF_SIZE); + if (!data->pre_save_buf) { + + free(data); + return NULL; + + } + + data->pre_save_size = INITIAL_BUF_SIZE; + return data; } @@ -125,12 +138,23 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t **buf, size_t buf_size, size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, uint8_t *out_buf, size_t out_buf_size) { - // In case we need more than out_buf_size, we return that amount and get - // called again. - if (out_buf_size < 32000) return 32000; + if (data->pre_save_size < buf_size + 5) { + + data->pre_save_buf = realloc(data->pre_save_buf, buf_size + 5); + if (!data->pre_save_buf) { + + perror("custom mutator realloc"); + free(data); + return -1; + + } + + data->pre_save_size = buf_size + 5; + + } - memcpy(out_buf, buf, buf_size); - out_buf_size = buf_size; + memcpy(out_buf + 5, buf, buf_size); + out_buf_size = buf_size + 5; out_buf[0] = 'A'; out_buf[1] = 'F'; out_buf[2] = 'L'; @@ -322,6 +346,7 @@ void afl_custom_queue_new_entry(my_mutator_t * data, */ void afl_custom_deinit(my_mutator_t *data) { + free(data->pre_save_buf); free(data); } diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 8bf66403..530a4b6a 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -30,9 +30,6 @@ #define AFL_MAIN #define MESSAGES_TO_STDOUT -/* We preallocate a buffer of this size for afl_custom_pre_save */ -#define PRE_SAVE_BUF_INIT_SIZE (16384) - #ifndef _GNU_SOURCE #define _GNU_SOURCE 1 #endif @@ -296,8 +293,8 @@ typedef struct py_mutator { void * afl_state; void * py_data; - PyObject *scratch_buf; - size_t scratch_size; + u8 * pre_save_buf; + size_t pre_save_size; } py_mutator_t; @@ -641,13 +638,13 @@ struct custom_mutator { * @param[in] data pointer returned in afl_custom_init for this fuzz case * @param[in] buf Buffer containing the test case to be executed * @param[in] buf_size Size of the test case - * @param[out] out_buf Pointer to the buffer of storing the test case after - * processing. External library should allocate memory for out_buf. AFL++ - * will release the memory after saving the test case. - * @return Size of the output buffer after processing + * @param[out] out_buf Pointer to the buffer storing the test case after + * processing. External library should allocate memory for out_buf. + * It can chose to alter buf in-place, if the space is large enough. + * @return Size of the output buffer. */ size_t (*afl_custom_pre_save)(void *data, u8 *buf, size_t buf_size, - u8 *out_buf, size_t out_buf_size); + u8 **out_buf); /** * This method is called at the start of each trimming operation and receives @@ -783,7 +780,7 @@ u8 trim_case_custom(afl_state_t *, struct queue_entry *q, u8 *in_buf); void finalize_py_module(void *); -size_t pre_save_py(void *, u8 *, size_t, u8 *, size_t); +size_t pre_save_py(void *, u8 *, size_t, u8 **); u32 init_trim_py(void *, u8 *, size_t); u32 post_trim_py(void *, u8); void trim_py(void *, u8 **, size_t *); diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index fac97f8e..9d8610c0 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -135,18 +135,9 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) { /* "afl_custom_pre_save", optional */ afl->mutator->afl_custom_pre_save = dlsym(dh, "afl_custom_pre_save"); - if (!afl->mutator->afl_custom_pre_save) { - + if (!afl->mutator->afl_custom_pre_save) WARNF("Symbol 'afl_custom_pre_save' not found."); - } else { - - /* if we have a pre_save hook, prealloc some memory. */ - afl->mutator->pre_save_buf = ck_alloc(PRE_SAVE_BUF_INIT_SIZE * sizeof(u8)); - afl->mutator->pre_save_size = PRE_SAVE_BUF_INIT_SIZE; - - } - u8 notrim = 0; /* "afl_custom_init_trim", optional */ afl->mutator->afl_custom_init_trim = dlsym(dh, "afl_custom_init_trim"); diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index b053e8d5..6fbdb678 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -307,14 +307,8 @@ void load_custom_mutator_py(afl_state_t *afl, char *module_name) { is quite different from the custom mutator. */ afl->mutator->afl_custom_fuzz = fuzz_py; - if (py_functions[PY_FUNC_PRE_SAVE]) { - + if (py_functions[PY_FUNC_PRE_SAVE]) afl->mutator->afl_custom_pre_save = pre_save_py; - /* if we have a pre_save hook, prealloc some memory. */ - afl->mutator->pre_save_buf = ck_alloc(PRE_SAVE_BUF_INIT_SIZE * sizeof(u8)); - afl->mutator->pre_save_size = PRE_SAVE_BUF_INIT_SIZE; - - } if (py_functions[PY_FUNC_INIT_TRIM]) afl->mutator->afl_custom_init_trim = init_trim_py; @@ -344,39 +338,18 @@ void load_custom_mutator_py(afl_state_t *afl, char *module_name) { } -size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 *out_buf, - size_t out_buf_size) { - - size_t py_out_buf_size; - PyObject *py_args, *py_value; - - if (((py_mutator_t *)py_mutator)->scratch_buf) { - - /* We are being recalled from an earlier run - where we didn't have enough mem. */ - if (((py_mutator_t *)py_mutator)->scratch_size < out_buf_size) { - - FATAL("out_buf is still too small after resizing in custom mutator."); - - } - - py_value = ((py_mutator_t *)py_mutator)->scratch_buf; - py_out_buf_size = ((py_mutator_t *)py_mutator)->scratch_size; - ((py_mutator_t *)py_mutator)->scratch_buf = NULL; - py_out_buf_size = 0; +size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf) { - memcpy(out_buf, PyByteArray_AsString(py_value), py_out_buf_size); - Py_DECREF(py_value); - return py_out_buf_size; - - } + size_t py_out_buf_size; + PyObject * py_args, *py_value; + py_mutator_t *py = (py_mutator_t *)py_mutator; py_args = PyTuple_New(1); py_value = PyByteArray_FromStringAndSize(buf, buf_size); if (!py_value) { Py_DECREF(py_args); - FATAL("Failed to convert arguments"); + FATAL("Failed to convert arguments in custom pre_save"); } @@ -390,25 +363,26 @@ size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 *out_buf, if (py_value != NULL) { py_out_buf_size = PyByteArray_Size(py_value); - if (py_out_buf_size > out_buf_size) { + + if (py_out_buf_size > py->pre_save_size) { /* Not enough space! - We will get called again right after resizing the buf. - Keep the references to our data for now. */ - ((py_mutator_t *)py_mutator)->scratch_buf = py_value; - ((py_mutator_t *)py_mutator)->scratch_size = py_out_buf_size; - return py_out_buf_size; + Let's resize our buf */ + py->pre_save_buf = ck_realloc(py->pre_save_buf, py_out_buf_size); + py->pre_save_size = py_out_buf_size; } - memcpy(out_buf, PyByteArray_AsString(py_value), py_out_buf_size); + memcpy(py->pre_save_buf, PyByteArray_AsString(py_value), py_out_buf_size); Py_DECREF(py_value); + + *out_buf = py->pre_save_buf; return py_out_buf_size; } else { PyErr_Print(); - FATAL("Call failed"); + FATAL("Python custom mutator: pre_save call failed."); } diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index a539b469..a43bfad2 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -214,47 +214,18 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) { lseek(fd, 0, SEEK_SET); - if (afl->mutator && afl->mutator->afl_custom_pre_save) { + if (unlikely(afl->mutator && afl->mutator->afl_custom_pre_save)) { - if (unlikely(afl->mutator->pre_save_size < len)) { + u8 *new_buf = NULL; - afl->mutator->pre_save_buf = - ck_realloc(afl->mutator->pre_save_buf, len * sizeof(u8)); - afl->mutator->pre_save_size = len; + size_t new_size = afl->mutator->afl_custom_pre_save(afl->mutator->data, mem, + len, &new_buf); - } - - u8 buf_written = 0; - while (!buf_written) { - - buf_written = 1; - size_t new_size = afl->mutator->afl_custom_pre_save( - afl->mutator->data, mem, len, afl->mutator->pre_save_buf, - afl->mutator->pre_save_size); - - if (unlikely(new_size) == 0) { - - /* custom_pre_save wants us to use the old buf */ - ck_write(fd, mem, len, afl->fsrv.out_file); - - } else if (unlikely(new_size) > afl->mutator->pre_save_size) { - - /* The custom func needs more space. - Realloc and call again. */ - afl->mutator->pre_save_buf = - ck_realloc(afl->mutator->pre_save_buf, new_size * sizeof(u8)); - afl->mutator->pre_save_size = new_size; - buf_written = 0; - continue; - - } else { - - /* everything as planned. use the new data. */ - ck_write(fd, afl->mutator->pre_save_buf, new_size, afl->fsrv.out_file); + if (unlikely(new_size <= 0 || !new_buf)) + FATAL("Custom_pre_save failed (ret: %ld)", new_size); - } - - } + /* everything as planned. use the new data. */ + ck_write(fd, new_buf, new_size, afl->fsrv.out_file); } else { diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 53c162a2..5536c201 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -361,9 +361,9 @@ void show_stats(afl_state_t *afl) { /* Lord, forgive me this. */ - SAYF(SET_G1 bSTG bLT bH bSTOP cCYA + SAYF(SET_G1 bSTG bLT bH bSTOP cCYA " process timing " bSTG bH30 bH5 bH bHB bH bSTOP cCYA - " overall results " bSTG bH2 bH2 bRT "\n"); + " overall results " bSTG bH2 bH2 bRT "\n"); if (afl->dumb_mode) { @@ -445,9 +445,9 @@ void show_stats(afl_state_t *afl) { " uniq hangs : " cRST "%-6s" bSTG bV "\n", time_tmp, tmp); - SAYF(bVR bH bSTOP cCYA + SAYF(bVR bH bSTOP cCYA " cycle progress " bSTG bH10 bH5 bH2 bH2 bHB bH bSTOP cCYA - " map coverage " bSTG bH bHT bH20 bH2 bVL "\n"); + " map coverage " bSTG bH bHT bH20 bH2 bVL "\n"); /* This gets funny because we want to print several variable-length variables together, but then cram them into a fixed-width field - so we need to @@ -476,9 +476,9 @@ void show_stats(afl_state_t *afl) { SAYF(bSTOP " count coverage : " cRST "%-21s" bSTG bV "\n", tmp); - SAYF(bVR bH bSTOP cCYA + SAYF(bVR bH bSTOP cCYA " stage progress " bSTG bH10 bH5 bH2 bH2 bX bH bSTOP cCYA - " findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n"); + " findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n"); sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_favored), ((double)afl->queued_favored) * 100 / afl->queued_paths); @@ -552,7 +552,7 @@ void show_stats(afl_state_t *afl) { /* Aaaalmost there... hold on! */ - SAYF(bVR bH cCYA bSTOP + SAYF(bVR bH cCYA bSTOP " fuzzing strategy yields " bSTG bH10 bHT bH10 bH5 bHB bH bSTOP cCYA " path geometry " bSTG bH5 bH2 bVL "\n"); -- cgit 1.4.1 From 604f122819bbcba6a041b4b471805a3b586916cc Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Thu, 26 Mar 2020 19:47:16 +0100 Subject: docu --- examples/custom_mutators/example.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'examples/custom_mutators') diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index 04b72c77..220d0ca1 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -126,17 +126,14 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t **buf, size_t buf_size, * @param[in] data pointer returned in afl_custom_init for this fuzz case * @param[in] buf Buffer containing the test case to be executed * @param[in] buf_size Size of the test case - * @param[in] out_buf Pointer to the buffer containing the test case after - * processing. External library should allocate memory for out_buf. AFL++ - * will release the memory after saving the test case. - * out_buf will always be at least as large as buf. - * @param[in] out_buf_size The maximum size we may use. - * In case we need to have this bigger, simply return that. + * @param[out] out_buf Pointer to the buffer containing the test case after + * processing. External library should allocate memory for out_buf. + * The buf pointer may be reused (up to the given buf_size); * @return Size of the output buffer after processing or the needed amount. - * return 0 to indicate the original buf should be used. + * A return smaller 1 indicates an error. */ size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, - uint8_t *out_buf, size_t out_buf_size) { + uint8_t **out_buf) { if (data->pre_save_size < buf_size + 5) { -- cgit 1.4.1 From 932eae7343c59aee7ade950e5e233ac71acaf745 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Thu, 26 Mar 2020 19:48:26 +0100 Subject: example fixed --- examples/custom_mutators/example.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'examples/custom_mutators') diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index 220d0ca1..8a45d87f 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -149,14 +149,15 @@ size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, data->pre_save_size = buf_size + 5; } - - memcpy(out_buf + 5, buf, buf_size); - out_buf_size = buf_size + 5; - out_buf[0] = 'A'; - out_buf[1] = 'F'; - out_buf[2] = 'L'; - out_buf[3] = '+'; - out_buf[4] = '+'; + *out_buf = data->pre_save_buf; + + memcpy(*out_buf + 5, buf, buf_size); + size_t out_buf_size = buf_size + 5; + *out_buf[0] = 'A'; + *out_buf[1] = 'F'; + *out_buf[2] = 'L'; + *out_buf[3] = '+'; + *out_buf[4] = '+'; return out_buf_size; -- cgit 1.4.1 From e71c2937de8a19cf9b3627b86894cafabcd45513 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 27 Mar 2020 23:30:15 +0100 Subject: code format --- examples/custom_mutators/example.c | 1 + include/afl-fuzz.h | 17 ++++++++--------- include/alloc-inl.h | 13 ++++++++++--- llvm_mode/afl-clang-fast.c | 10 +++++----- llvm_mode/afl-llvm-pass.so.cc | 7 ++++++- src/afl-fuzz-bitmap.c | 22 +++++++++++++--------- src/afl-fuzz-init.c | 11 ++++------- src/afl-fuzz-one.c | 30 +++++++++++++----------------- src/afl-fuzz-queue.c | 8 +++++--- src/afl-fuzz-stats.c | 2 +- 10 files changed, 66 insertions(+), 55 deletions(-) (limited to 'examples/custom_mutators') diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index 8a45d87f..4b0a461b 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -149,6 +149,7 @@ size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, data->pre_save_size = buf_size + 5; } + *out_buf = data->pre_save_buf; memcpy(*out_buf + 5, buf, buf_size); diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 2154d860..32eaf4af 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -583,27 +583,26 @@ typedef struct afl_state { u8 clean_trace_custom[MAP_SIZE]; u8 first_trace[MAP_SIZE]; -/*needed for afl_fuzz_one */ -// TODO: see which we can reuse - u8 *out_buf; + /*needed for afl_fuzz_one */ + // TODO: see which we can reuse + u8 * out_buf; size_t out_size; - u8 *out_scratch_buf; + u8 * out_scratch_buf; size_t out_scratch_size; - u8 *eff_buf; + u8 * eff_buf; size_t eff_size; - u8 *in_buf; + u8 * in_buf; size_t in_size; - u8 *in_scratch_buf; + u8 * in_scratch_buf; size_t in_scratch_size; - u8 *ex_buf; + u8 * ex_buf; size_t ex_size; - } afl_state_t; /* A global pointer to all instances is needed (for now) for signals to arrive diff --git a/include/alloc-inl.h b/include/alloc-inl.h index 75b038c1..92d29c1e 100644 --- a/include/alloc-inl.h +++ b/include/alloc-inl.h @@ -774,7 +774,8 @@ static inline void TRK_ck_free(void *ptr, const char *file, const char *func, Will FATAL if size_needed is <1 or *size is negative. @return For convenience, this function returns *buf. */ -static inline void *ck_maybe_grow(void **buf, size_t *size, size_t size_needed) { +static inline void *ck_maybe_grow(void **buf, size_t *size, + size_t size_needed) { /* Oops. found a bug? */ if (unlikely(size_needed < 1)) FATAL("cannot grow to non-positive size"); @@ -785,21 +786,27 @@ static inline void *ck_maybe_grow(void **buf, size_t *size, size_t size_needed) /* No inital size was set */ if (*size == 0) *size = INITIAL_GROWTH_SIZE; while (*size < size_needed) { + *size *= 2; + } + *buf = ck_realloc(*buf, *size); return *buf; } /* Swaps buf1 ptr and buf2 ptr, as well as their sizes */ -static inline void swap_bufs(void **buf1, size_t *size1, void **buf2, size_t *size2) { - void *scratch_buf = *buf1; +static inline void swap_bufs(void **buf1, size_t *size1, void **buf2, + size_t *size2) { + + void * scratch_buf = *buf1; size_t scratch_size = *size1; *buf1 = *buf2; *size1 = *size2; *buf2 = scratch_buf; *size2 = scratch_size; + } #undef INITIAL_GROWTH_SIZE diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index c45c8799..99bc8d03 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -397,15 +397,15 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (getenv("AFL_USE_CFISAN")) { - if (!lto_mode) { - + if (!lto_mode) { + uint32_t i = 0, found = 0; while (envp[i] != NULL && !found) - if (strncmp("-flto", envp[i++], 5) == 0) - found = 1; + if (strncmp("-flto", envp[i++], 5) == 0) found = 1; if (!found) cc_params[cc_par_cnt++] = "-flto"; - + } + cc_params[cc_par_cnt++] = "-fsanitize=cfi"; cc_params[cc_par_cnt++] = "-fvisibility=hidden"; diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc index 1c0a3c93..f6ead9ec 100644 --- a/llvm_mode/afl-llvm-pass.so.cc +++ b/llvm_mode/afl-llvm-pass.so.cc @@ -132,8 +132,11 @@ class AFLCoverage : public ModulePass { char AFLCoverage::ID = 0; /* needed up to 3.9.0 */ -#if LLVM_VERSION_MAJOR == 3 && (LLVM_VERSION_MINOR < 9 || (LLVM_VERSION_MINOR == 9 && LLVM_VERSION_PATCH < 1)) +#if LLVM_VERSION_MAJOR == 3 && \ + (LLVM_VERSION_MINOR < 9 || \ + (LLVM_VERSION_MINOR == 9 && LLVM_VERSION_PATCH < 1)) uint64_t PowerOf2Ceil(unsigned in) { + uint64_t in64 = in - 1; in64 |= (in64 >> 1); in64 |= (in64 >> 2); @@ -142,7 +145,9 @@ uint64_t PowerOf2Ceil(unsigned in) { in64 |= (in64 >> 16); in64 |= (in64 >> 32); return in64 + 1; + } + #endif bool AFLCoverage::runOnModule(Module &M) { diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index bb01ad21..8ca286b2 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -31,7 +31,7 @@ void write_bitmap(afl_state_t *afl) { - u8 fname[PATH_MAX]; + u8 fname[PATH_MAX]; s32 fd; if (!afl->bitmap_changed) return; @@ -461,7 +461,7 @@ u8 *describe_op(afl_state_t *afl, u8 hnb) { static void write_crash_readme(afl_state_t *afl) { - u8 fn[PATH_MAX]; + u8 fn[PATH_MAX]; s32 fd; FILE *f; @@ -558,12 +558,13 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { #ifndef SIMPLE_FILES - queue_fn = alloc_printf("%s/queue/id:%06u,%s", afl->out_dir, afl->queued_paths, - describe_op(afl, hnb)); + queue_fn = alloc_printf("%s/queue/id:%06u,%s", afl->out_dir, + afl->queued_paths, describe_op(afl, hnb)); #else - queue_fn = alloc_printf("%s/queue/id_%06u", afl->out_dir, afl->queued_paths); + queue_fn = + alloc_printf("%s/queue/id_%06u", afl->out_dir, afl->queued_paths); #endif /* ^!SIMPLE_FILES */ @@ -645,11 +646,12 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { #ifndef SIMPLE_FILES snprintf(fn, PATH_MAX, "%s/hangs/id:%06llu,%s", afl->out_dir, - afl->unique_hangs, describe_op(afl, 0)); + afl->unique_hangs, describe_op(afl, 0)); #else - snprintf(fn, PATH_MAX, "%s/hangs/id_%06llu", afl->out_dir, afl->unique_hangs); + snprintf(fn, PATH_MAX, "%s/hangs/id_%06llu", afl->out_dir, + afl->unique_hangs); #endif /* ^!SIMPLE_FILES */ @@ -687,11 +689,13 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { #ifndef SIMPLE_FILES - snprintf(fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s", afl->out_dir, afl->unique_crashes, afl->kill_signal, describe_op(afl, 0)); + snprintf(fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s", afl->out_dir, + afl->unique_crashes, afl->kill_signal, describe_op(afl, 0)); #else - snprintf(fn, PATH_MAX, "%s/crashes/id_%06llu_%02u", afl->out_dir, afl->unique_crashes, afl->kill_signal); + snprintf(fn, PATH_MAX, "%s/crashes/id_%06llu_%02u", afl->out_dir, + afl->unique_crashes, afl->kill_signal); #endif /* ^!SIMPLE_FILES */ diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 1033c587..19092204 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -76,7 +76,7 @@ void bind_to_free_cpu(afl_state_t *afl) { while ((de = readdir(d))) { - u8 fn[PATH_MAX]; + u8 fn[PATH_MAX]; FILE *f; u8 tmp[MAX_LINE]; u8 has_vmsize = 0; @@ -85,11 +85,7 @@ void bind_to_free_cpu(afl_state_t *afl) { snprintf(fn, PATH_MAX, "/proc/%s/status", de->d_name); - if (!(f = fopen(fn, "r"))) { - - continue; - - } + if (!(f = fopen(fn, "r"))) { continue; } while (fgets(tmp, MAX_LINE, f)) { @@ -368,7 +364,8 @@ void read_testcases(afl_state_t *afl) { struct stat st; u8 dfn[PATH_MAX]; - snprintf(dfn, PATH_MAX, "%s/.state/deterministic_done/%s", afl->in_dir, nl[i]->d_name); + snprintf(dfn, PATH_MAX, "%s/.state/deterministic_done/%s", afl->in_dir, + nl[i]->d_name); u8 *fn2 = alloc_printf("%s/%s", afl->in_dir, nl[i]->d_name); u8 passed_det = 0; diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 6c1d69ad..c731ebc6 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1957,7 +1957,9 @@ havoc_stage: clone_to = rand_below(afl, temp_len); - new_buf = ck_maybe_grow((void **)&afl->out_scratch_buf, &afl->out_scratch_size, temp_len + clone_len); + new_buf = + ck_maybe_grow((void **)&afl->out_scratch_buf, + &afl->out_scratch_size, temp_len + clone_len); /* Head */ @@ -1977,8 +1979,8 @@ havoc_stage: memcpy(new_buf + clone_to + clone_len, out_buf + clone_to, temp_len - clone_to); - - swap_bufs((void **)&afl->out_buf, &afl->out_size, (void **)&afl->out_scratch_buf, &afl->out_scratch_size); + swap_bufs((void **)&afl->out_buf, &afl->out_size, + (void **)&afl->out_scratch_buf, &afl->out_scratch_size); out_buf = new_buf; temp_len += clone_len; @@ -2072,7 +2074,8 @@ havoc_stage: if (temp_len + extra_len >= MAX_FILE) break; - new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + extra_len); + new_buf = + ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + extra_len); /* Head */ memcpy(new_buf, out_buf, insert_at); @@ -2088,7 +2091,8 @@ havoc_stage: if (temp_len + extra_len >= MAX_FILE) break; - new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + extra_len); + new_buf = + ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + extra_len); /* Head */ memcpy(new_buf, out_buf, insert_at); @@ -2236,11 +2240,7 @@ retry_splicing: locate_diffs(in_buf, new_buf, MIN(len, target->len), &f_diff, &l_diff); - if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { - - goto retry_splicing; - - } + if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { goto retry_splicing; } /* Split somewhere between the first and last differing byte. */ @@ -2308,11 +2308,7 @@ radamsa_stage: } - if (common_fuzz_stuff(afl, tmp_buf, temp_len)) { - - goto abandon_entry; - - } + if (common_fuzz_stuff(afl, tmp_buf, temp_len)) { goto abandon_entry; } } @@ -3885,7 +3881,8 @@ pacemaker_fuzzing: clone_to = rand_below(afl, temp_len); - new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + clone_len); + new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), + temp_len + clone_len); /* Head */ @@ -4399,7 +4396,6 @@ u8 fuzz_one(afl_state_t *afl) { return key_val_lv; - #undef BUF_PARAMS } diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index b5ae1255..4f1bd041 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -30,10 +30,11 @@ void mark_as_det_done(afl_state_t *afl, struct queue_entry *q) { - u8 fn[PATH_MAX]; + u8 fn[PATH_MAX]; s32 fd; - snprintf(fn, PATH_MAX, "%s/queue/.state/deterministic_done/%s", afl->out_dir, strrchr(q->fname, '/') + 1); + snprintf(fn, PATH_MAX, "%s/queue/.state/deterministic_done/%s", afl->out_dir, + strrchr(q->fname, '/') + 1); fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600); if (fd < 0) PFATAL("Unable to create '%s'", fn); @@ -79,7 +80,8 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) { q->fs_redundant = state; - sprintf(fn, "%s/queue/.state/redundant_edges/%s", afl->out_dir, strrchr(q->fname, '/') + 1); + sprintf(fn, "%s/queue/.state/redundant_edges/%s", afl->out_dir, + strrchr(q->fname, '/') + 1); if (state) { diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index d6403830..7fde2fdc 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -33,7 +33,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, struct rusage rus; unsigned long long int cur_time = get_cur_time(); - u8 fn[PATH_MAX]; + u8 fn[PATH_MAX]; s32 fd; FILE * f; -- cgit 1.4.1 From 9785b15ed264951b006093f9ee4564820c153593 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sat, 28 Mar 2020 04:57:44 +0100 Subject: more custom mutator remodelling --- examples/custom_mutators/custom_mutator_helpers.h | 61 ++++++++++++ examples/custom_mutators/example.c | 113 ++++++++++++---------- examples/post_library/post_library.so.c | 84 +++++++++++----- examples/post_library/post_library_png.so.c | 71 +++++++++++--- include/afl-fuzz.h | 41 +++++--- src/afl-fuzz-cmplog.c | 9 +- src/afl-fuzz-globals.c | 2 + src/afl-fuzz-init.c | 14 ++- src/afl-fuzz-mutators.c | 24 ++--- src/afl-fuzz-one.c | 29 +++++- src/afl-fuzz-python.c | 64 +++++++----- src/afl-fuzz-run.c | 9 +- 12 files changed, 370 insertions(+), 151 deletions(-) (limited to 'examples/custom_mutators') diff --git a/examples/custom_mutators/custom_mutator_helpers.h b/examples/custom_mutators/custom_mutator_helpers.h index cd3a15f0..0dc00d96 100644 --- a/examples/custom_mutators/custom_mutator_helpers.h +++ b/examples/custom_mutators/custom_mutator_helpers.h @@ -5,8 +5,18 @@ #include "types.h" #include +#define INITIAL_GROWTH_SIZE (64) + #define RAND_BELOW(limit) (rand() % (limit)) +/* Use in a struct: creates a name_buf and a name_size variable. */ +#define BUF_VAR(type, name) \ + type * name##_buf; \ + size_t name##_size; +/* this filles in `&structptr->something_buf, &structptr->something_size`. */ +#define BUF_PARAMS(struct, name) \ + (void **)&struct->name##_buf, &struct->name##_size + typedef struct { } afl_t; @@ -267,5 +277,56 @@ static void surgical_havoc_mutate(u8 *out_buf, s32 begin, s32 end) { } +/* This function makes sure *size is > size_needed after call. + It changes buf and size in-place, if needed. + It will realloc *buf otherwise. + *size will grow exponentially as per: + https://blog.mozilla.org/nnethercote/2014/11/04/please-grow-your-buffers-exponentially/ + Will return NULL if size_needed is <1 or *size is negative or malloc Failed. + @return For convenience, this function returns *buf. NULL on error. + */ +static inline void *maybe_grow(void **buf, size_t *size, size_t size_needed) { + + /* Oops. found a bug? */ + if (unlikely(size_needed < 1)) return NULL; + + /* No need to realloc */ + if (likely(*size >= size_needed)) return *buf; + if (unlikely(*size < 0)) return NULL; + /* No inital size was set */ + if (*size == 0) *size = INITIAL_GROWTH_SIZE; + while (*size < size_needed) { + + *size *= 2; + if ((*size) < 0) { + + /* An overflow occurred. Fall back to size_needed */ + *size = size_needed; + + } + + } + + *buf = realloc(*buf, *size); + + return *buf; + +} + +/* Swaps buf1 ptr and buf2 ptr, as well as their sizes */ +static inline void swap_bufs(void **buf1, size_t *size1, void **buf2, + size_t *size2) { + + void * scratch_buf = *buf1; + size_t scratch_size = *size1; + *buf1 = *buf2; + *size1 = *size2; + *buf2 = scratch_buf; + *size2 = scratch_size; + +} + +#undef INITIAL_GROWTH_SIZE + #endif diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index 4b0a461b..54fc9d47 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -15,7 +15,6 @@ #include #define DATA_SIZE (100) -#define INITIAL_BUF_SIZE (16384) static const char *commands[] = { @@ -28,9 +27,19 @@ static const char *commands[] = { typedef struct my_mutator { afl_t *afl; + // any additional data here! - size_t pre_save_size; - u8 * pre_save_buf; + uint8_t *trim_buf; + size_t trim_buf_size; + int trimmming_steps; + int cur_step; + + // Reused buffers: + BUF_VAR(u8, fuzz); + BUF_VAR(u8, data); + BUF_VAR(u8, havoc); + BUF_VAR(u8, trim_out); + BUF_VAR(u8, pre_save); } my_mutator_t; @@ -59,16 +68,6 @@ my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) { data->afl = afl; - data->pre_save_buf = malloc(INITIAL_BUF_SIZE); - if (!data->pre_save_buf) { - - free(data); - return NULL; - - } - - data->pre_save_size = INITIAL_BUF_SIZE; - return data; } @@ -85,20 +84,25 @@ my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) { * @param[in] add_buf_size Size of the additional test case * @param[in] max_size Maximum size of the mutated output. The mutation must not * produce data larger than max_size. - * @return Size of the mutated output. + * @return Size of the mutated output. Negative return will abort fuzzing. */ -size_t afl_custom_fuzz(my_mutator_t *data, uint8_t **buf, size_t buf_size, - uint8_t *add_buf, - size_t add_buf_size, // add_buf can be NULL - size_t max_size) { +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, // add_buf can be NULL + size_t max_size) { // Make sure that the packet size does not exceed the maximum size expected by // the fuzzer size_t mutated_size = DATA_SIZE <= max_size ? DATA_SIZE : max_size; - if (mutated_size > buf_size) *buf = realloc(*buf, mutated_size); + // maybe_grow is optimized to be quick for reused buffers. + u8 *mutated_out = maybe_grow(BUF_PARAMS(data, fuzz), mutated_size); + if (!mutated_out) { + + perror("custom mutator allocation (maybe_grow)"); + return -1; /* afl-fuzz will very likely error out after this. */ - uint8_t *mutated_out = *buf; + } // Randomly select a command string to add as a header to the packet memcpy(mutated_out, commands[rand() % 3], 3); @@ -112,6 +116,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t **buf, size_t buf_size, } + *out_buf = mutated_out; return mutated_size; } @@ -137,11 +142,10 @@ size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, if (data->pre_save_size < buf_size + 5) { - data->pre_save_buf = realloc(data->pre_save_buf, buf_size + 5); + data->pre_save_buf = maybe_grow(BUF_PARAMS(data, pre_save), buf_size + 5); if (!data->pre_save_buf) { - perror("custom mutator realloc"); - free(data); + perror("custom mutator realloc failed."); return -1; } @@ -164,11 +168,6 @@ size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, } -static uint8_t *trim_buf; -static size_t trim_buf_size; -static int trimmming_steps; -static int cur_step; - /** * This method is called at the start of each trimming operation and receives * the initial buffer. It should return the amount of iteration steps possible @@ -193,20 +192,20 @@ static int cur_step; int afl_custom_init_trim(my_mutator_t *data, uint8_t *buf, size_t buf_size) { // We simply trim once - trimmming_steps = 1; + data->trimmming_steps = 1; - cur_step = 0; - trim_buf = buf; - trim_buf_size = buf_size; + data->cur_step = 0; + data->trim_buf = buf; + data->trim_buf_size = buf_size; - return trimmming_steps; + return data->trimmming_steps; } /** * This method is called for each trimming operation. It doesn't have any * arguments because we already have the initial buffer from init_trim and we - * can memorize the current state in global variables. This can also save + * can memorize the current state in *data. This can also save * reparsing steps for each iteration. It should return the trimmed input * buffer, where the returned data must not exceed the initial input data in * length. Returning anything that is larger than the original data (passed @@ -216,19 +215,18 @@ int afl_custom_init_trim(my_mutator_t *data, uint8_t *buf, size_t buf_size) { * * @param[in] data pointer returned in afl_custom_init for this fuzz case * @param[out] out_buf Pointer to the buffer containing the trimmed test case. - * External library should allocate memory for out_buf. AFL++ will release - * the memory after saving the test case. - * @param[out] out_buf_size Pointer to the size of the trimmed test case + * External library should allocate memory for out_buf. + * AFL++ will not release the memory after saving the test case. + * Keep a ref in *data. + * @return Pointer to the size of the trimmed test case */ -void afl_custom_trim(my_mutator_t *data, uint8_t **out_buf, - size_t *out_buf_size) { +size_t afl_custom_trim(my_mutator_t *data, uint8_t **out_buf) { - *out_buf_size = trim_buf_size - 1; + size_t ret = data->trim_buf_size - 1; - // External mutator should allocate memory for `out_buf` - *out_buf = malloc(*out_buf_size); + *out_buf = maybe_grow(BUF_PARAMS(data, trim_out), ret); // Remove the last byte of the trimming input - memcpy(*out_buf, trim_buf, *out_buf_size); + memcpy(*out_buf, data->trim_buf, ret); } @@ -248,12 +246,12 @@ int afl_custom_post_trim(my_mutator_t *data, int success) { if (success) { - ++cur_step; - return cur_step; + ++data->cur_step; + return data->cur_step; } - return trimmming_steps; + return data->trimmming_steps; } @@ -264,26 +262,33 @@ int afl_custom_post_trim(my_mutator_t *data, int success) { * (Optional) * * @param[in] data pointer returned in afl_custom_init for this fuzz case - * @param[inout] buf Pointer to the input data to be mutated and the mutated + * @param[in] buf Pointer to the input data to be mutated and the mutated * output * @param[in] buf_size Size of input data + * @param[out] out_buf The output buffer. buf can be reused, if the content + * fits. * @param[in] max_size Maximum size of the mutated output. The mutation must * not produce data larger than max_size. * @return Size of the mutated output. */ -size_t afl_custom_havoc_mutation(my_mutator_t *data, uint8_t **buf, - size_t buf_size, size_t max_size) { +size_t afl_custom_havoc_mutation(my_mutator_t *data, u8 *buf, size_t buf_size, + u8 **out_buf, size_t max_size) { if (buf_size == 0) { - *buf = realloc(*buf, 1); - **buf = rand() % 256; + *out_buf = maybe_grow(BUF_PARAMS(data, havoc), 1); + **out_buf = rand() % 256; buf_size = 1; + } else { + + // We reuse buf here. It's legal and faster. + *out_buf = buf; + } size_t victim = rand() % buf_size; - (*buf)[victim] += rand() % 10; + (*out_buf)[victim] += rand() % 10; return buf_size; @@ -346,6 +351,10 @@ void afl_custom_queue_new_entry(my_mutator_t * data, void afl_custom_deinit(my_mutator_t *data) { free(data->pre_save_buf); + free(data->havoc_buf); + free(data->data_buf); + free(data->fuzz_buf); + free(data->trim_out_buf); free(data); } diff --git a/examples/post_library/post_library.so.c b/examples/post_library/post_library.so.c index 5d2685cd..735aae9b 100644 --- a/examples/post_library/post_library.so.c +++ b/examples/post_library/post_library.so.c @@ -3,6 +3,7 @@ -------------------------------------------------- Originally written by Michal Zalewski + Edited by Dominik Maier, 2020 Copyright 2015 Google Inc. All rights reserved. @@ -41,22 +42,23 @@ AFL will call the afl_postprocess() function for every mutated output buffer. From there, you have three choices: - 1) If you don't want to modify the test case, simply return the original - buffer pointer ('in_buf'). + 1) If you don't want to modify the test case, simply set `*out_buf = in_buf` + and return the original `len`. 2) If you want to skip this test case altogether and have AFL generate a - new one, return NULL. Use this sparingly - it's faster than running - the target program with patently useless inputs, but still wastes CPU - time. + new one, return 0 or set `*out_buf = NULL`. + Use this sparingly - it's faster than running the target program + with patently useless inputs, but still wastes CPU time. 3) If you want to modify the test case, allocate an appropriately-sized buffer, move the data into that buffer, make the necessary changes, and - then return the new pointer. You can update *len if necessary, too. + then return the new pointer as out_buf. Return an appropriate len + afterwards. Note that the buffer will *not* be freed for you. To avoid memory leaks, you need to free it or reuse it on subsequent calls (as shown below). - *** DO NOT MODIFY THE ORIGINAL 'in_buf' BUFFER. *** + *** Feel free to reuse the original 'in_buf' BUFFER and return it. *** Aight. The example below shows a simple postprocessor that tries to make sure that all input files start with "GIF89a". @@ -74,47 +76,83 @@ #define HEADER "GIF89a" -/* The actual postprocessor routine called by afl-fuzz: */ +typedef struct post_state { + + unsigned char *buf; + size_t size; + +} post_state_t; + +void *afl_postprocess_init(void *afl) { + + post_state_t *state = malloc(sizeof(post_state_t)); + if (!state) { -const unsigned char *afl_postprocess(const unsigned char *in_buf, - unsigned int * len) { + perror("malloc"); + return NULL; - static unsigned char *saved_buf; - unsigned char * new_buf; + } + + state->buf = calloc(sizeof(unsigned char), 4096); + if (!state->buf) { return NULL; } + + return state; + +} + +/* The actual postprocessor routine called by afl-fuzz: */ + +size_t afl_postprocess(post_state_t *data, unsigned char *in_buf, + unsigned int len, unsigned char **out_buf) { /* Skip execution altogether for buffers shorter than 6 bytes (just to - show how it's done). We can trust *len to be sane. */ + show how it's done). We can trust len to be sane. */ - if (*len < strlen(HEADER)) return NULL; + if (len < strlen(HEADER)) return 0; /* Do nothing for buffers that already start with the expected header. */ - if (!memcmp(in_buf, HEADER, strlen(HEADER))) return in_buf; + if (!memcmp(in_buf, HEADER, strlen(HEADER))) { + + *out_buf = in_buf; + return len; + + } /* Allocate memory for new buffer, reusing previous allocation if possible. */ - new_buf = realloc(saved_buf, *len); + *out_buf = realloc(data->buf, len); /* If we're out of memory, the most graceful thing to do is to return the original buffer and give up on modifying it. Let AFL handle OOM on its own later on. */ - if (!new_buf) return in_buf; - saved_buf = new_buf; + if (!*out_buf) { + + *out_buf = in_buf; + return len; + + } /* Copy the original data to the new location. */ - memcpy(new_buf, in_buf, *len); + memcpy(*out_buf, in_buf, len); /* Insert the new header. */ - memcpy(new_buf, HEADER, strlen(HEADER)); + memcpy(*out_buf, HEADER, strlen(HEADER)); - /* Return modified buffer. No need to update *len in this particular case, - as we're not changing it. */ + /* Return the new len. It hasn't changed, so it's just len. */ - return new_buf; + return len; } +/* Gets called afterwards */ +void afl_postprocess_deinit(post_state_t *data) { + + free(data->buf); + free(data); + +} diff --git a/examples/post_library/post_library_png.so.c b/examples/post_library/post_library_png.so.c index 60ab318f..8597c88c 100644 --- a/examples/post_library/post_library_png.so.c +++ b/examples/post_library/post_library_png.so.c @@ -5,6 +5,7 @@ Originally written by Michal Zalewski Copyright 2015 Google Inc. All rights reserved. + Adapted to the new API, 2020 by Dominik Maier Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -35,11 +36,32 @@ #define UP4K(_i) ((((_i) >> 12) + 1) << 12) -const unsigned char *afl_postprocess(const unsigned char *in_buf, - unsigned int * len) { +typedef struct post_state { - static unsigned char *saved_buf; - static unsigned int saved_len; + unsigned char *buf; + size_t size; + +} post_state_t; + +void *afl_postprocess_init(void *afl) { + + post_state_t *state = malloc(sizeof(post_state_t)); + if (!state) { + + perror("malloc"); + return NULL; + + } + + state->buf = calloc(sizeof(unsigned char), 4096); + if (!state->buf) { return NULL; } + + return state; + +} + +size_t afl_postprocess(post_state_t *data, const unsigned char *in_buf, + unsigned int len, const unsigned char **out_buf) { unsigned char *new_buf = (unsigned char *)in_buf; unsigned int pos = 8; @@ -47,12 +69,17 @@ const unsigned char *afl_postprocess(const unsigned char *in_buf, /* Don't do anything if there's not enough room for the PNG header (8 bytes). */ - if (*len < 8) return in_buf; + if (len < 8) { + + *out_buf = in_buf; + return len; + + } /* Minimum size of a zero-length PNG chunk is 12 bytes; if we don't have that, we can bail out. */ - while (pos + 12 <= *len) { + while (pos + 12 <= len) { unsigned int chunk_len, real_cksum, file_cksum; @@ -62,7 +89,7 @@ const unsigned char *afl_postprocess(const unsigned char *in_buf, /* Bail out if chunk size is too big or goes past EOF. */ - if (chunk_len > 1024 * 1024 || pos + 12 + chunk_len > *len) break; + if (chunk_len > 1024 * 1024 || pos + 12 + chunk_len > len) break; /* Chunk checksum is calculated for chunk ID (dword) and the actual payload. */ @@ -82,17 +109,23 @@ const unsigned char *afl_postprocess(const unsigned char *in_buf, if (new_buf == in_buf) { - if (*len <= saved_len) { + if (len <= data->size) { - new_buf = saved_buf; + new_buf = data->buf; } else { - new_buf = realloc(saved_buf, UP4K(*len)); - if (!new_buf) return in_buf; - saved_buf = new_buf; - saved_len = UP4K(*len); - memcpy(new_buf, in_buf, *len); + new_buf = realloc(data->buf, UP4K(len)); + if (!new_buf) { + + *out_buf = in_buf; + return len; + + } + + data->buf = new_buf; + data->size = UP4K(len); + memcpy(new_buf, in_buf, len); } @@ -108,7 +141,15 @@ const unsigned char *afl_postprocess(const unsigned char *in_buf, } - return new_buf; + *out_buf = new_buf; + return len; } +/* Gets called afterwards */ +void afl_postprocess_deinit(post_state_t *data) { + + free(data->buf); + free(data); + +} diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 32eaf4af..5f9891bc 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -293,9 +293,18 @@ typedef struct py_mutator { void * afl_state; void * py_data; + u8 * fuzz_buf; + size_t fuzz_size; + u8 * pre_save_buf; size_t pre_save_size; + u8 * trim_buf; + size_t trim_size; + + u8 * havoc_buf; + size_t havoc_size; + } py_mutator_t; #endif @@ -544,7 +553,11 @@ typedef struct afl_state { struct extra_data *a_extras; /* Automatically selected extras */ u32 a_extras_cnt; /* Total number of tokens available */ - u8 *(*post_handler)(u8 *buf, u32 *len); + /* afl_postprocess API */ + void *(*post_init)(struct afl_state *afl); + size_t (*post_handler)(void *data, u8 *buf, u32 len, u8 **out_buf); + void *(*post_deinit)(void *data); + void *post_data; /* CmpLog */ @@ -643,10 +656,10 @@ struct custom_mutator { * @param[in] add_buf_size Size of the additional test case * @param[in] max_size Maximum size of the mutated output. The mutation must * not produce data larger than max_size. - * @return Size of the mutated output. + * @return Size of the mutated output. Negative on error will abort exeuction. */ - size_t (*afl_custom_fuzz)(void *data, u8 **buf, size_t buf_size, u8 *add_buf, - size_t add_buf_size, size_t max_size); + 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); /** * A post-processing function to use right before AFL writes the test case to @@ -704,9 +717,9 @@ struct custom_mutator { * @param[out] out_buf Pointer to the buffer containing the trimmed test case. * External library should allocate memory for out_buf. AFL++ will release * the memory after saving the test case. - * @param[out] out_buf_size Pointer to the size of the trimmed test case + * @return the size of the trimmed test case */ - void (*afl_custom_trim)(void *data, u8 **out_buf, size_t *out_buf_size); + size_t (*afl_custom_trim)(void *data, u8 **out_buf); /** * This method is called after each trim operation to inform you if your @@ -728,16 +741,18 @@ struct custom_mutator { * * (Optional) * - * @param data pointer returned in afl_custom_init for this fuzz case - * @param[inout] buf Pointer to the input data to be mutated and the mutated + * @param[in] data pointer returned in afl_custom_init for this fuzz case + * @param[in] buf Pointer to the input data to be mutated and the mutated * output * @param[in] buf_size Size of input data + * @param[out] out_buf The new buffer. It's legal to reuse *buf if it's < + * buf_size. * @param[in] max_size Maximum size of the mutated output. The mutation must * not produce data larger than max_size. - * @return Size of the mutated output. + * @return Size of the mutated output (out_size). */ - size_t (*afl_custom_havoc_mutation)(void *data, u8 **buf, size_t buf_size, - size_t max_size); + size_t (*afl_custom_havoc_mutation)(void *data, u8 *buf, size_t buf_size, + u8 **out_buf, size_t max_size); /** * Return the probability (in percentage) that afl_custom_havoc_mutation @@ -803,8 +818,8 @@ void finalize_py_module(void *); size_t pre_save_py(void *, u8 *, size_t, u8 **); u32 init_trim_py(void *, u8 *, size_t); u32 post_trim_py(void *, u8); -void trim_py(void *, u8 **, size_t *); -size_t havoc_mutation_py(void *, u8 **, size_t, size_t); +size_t trim_py(void *, u8 **); +size_t havoc_mutation_py(void *, u8 *, size_t, u8 **, size_t); u8 havoc_mutation_probability_py(void *); u8 queue_get_py(void *, const u8 *); void queue_new_entry_py(void *, const u8 *, const u8 *); diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c index 6c6f05ac..7c398507 100644 --- a/src/afl-fuzz-cmplog.c +++ b/src/afl-fuzz-cmplog.c @@ -527,8 +527,13 @@ u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { if (afl->post_handler) { - out_buf = afl->post_handler(out_buf, &len); - if (!out_buf || !len) return 0; + u8 *post_buf = NULL; + + size_t post_len = + afl->post_handler(afl->post_data, out_buf, len, &post_buf); + if (!post_buf || !post_len) return 0; + out_buf = post_buf; + len = post_len; } diff --git a/src/afl-fuzz-globals.c b/src/afl-fuzz-globals.c index 3e573dd2..1d99e1fa 100644 --- a/src/afl-fuzz-globals.c +++ b/src/afl-fuzz-globals.c @@ -349,6 +349,8 @@ void read_afl_environment(afl_state_t *afl, char **envp) { void afl_state_deinit(afl_state_t *afl) { + if (afl->post_deinit) afl->post_deinit(afl->post_data); + free(afl->out_buf); free(afl->out_scratch_buf); free(afl->eff_buf); diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index a69c3b61..fe2be4d2 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -270,7 +270,9 @@ void setup_post(afl_state_t *afl) { void *dh; u8 * fn = afl->afl_env.afl_post_library; + u8 tbuf[6]; u32 tlen = 6; + strncpy(tbuf, "hello", tlen); if (!fn) return; @@ -281,10 +283,20 @@ void setup_post(afl_state_t *afl) { afl->post_handler = dlsym(dh, "afl_postprocess"); if (!afl->post_handler) FATAL("Symbol 'afl_postprocess' not found."); + afl->post_init = dlsym(dh, "afl_postprocess_init"); + if (!afl->post_init) FATAL("Symbol 'afl_postprocess_init' not found."); + afl->post_deinit = dlsym(dh, "afl_postprocess_deinit"); + if (!afl->post_deinit) FATAL("Symbol 'afl_postprocess_deinit' not found."); /* Do a quick test. It's better to segfault now than later =) */ - afl->post_handler("hello", &tlen); + u8 *post_buf = NULL; + afl->post_data = afl->post_init(afl); + if (!afl->post_data) FATAL("Could not initialize post handler."); + + size_t post_len = afl->post_handler(afl->post_data, tbuf, tlen, &post_buf); + if (!post_len || !post_buf) + SAYF("Empty return in test post handler for buf=\"hello\\0\"."); OKF("Postprocessor installed successfully."); diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 41bc69c8..0692ebb0 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -7,6 +7,7 @@ Now maintained by Marc Heuse , Heiko Eißfeldt and Andrea Fioraldi + Dominik Maier Copyright 2016, 2017 Google Inc. All rights reserved. Copyright 2019-2020 AFLplusplus Project. All rights reserved. @@ -192,7 +193,8 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) { /* Initialize the custom mutator */ if (afl->mutator->afl_custom_init) - afl->mutator->data = afl->mutator->afl_custom_init(afl, rand_below(afl, 0xFFFFFFFF)); + afl->mutator->data = + afl->mutator->afl_custom_init(afl, rand_below(afl, 0xFFFFFFFF)); } @@ -218,17 +220,18 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { while (afl->stage_cur < afl->stage_max) { + u8 *retbuf = NULL; + sprintf(afl->stage_name_buf, "ptrim %s", u_stringify_int(val_buf, trim_exec)); u32 cksum; - u8 * retbuf = NULL; - size_t retlen = 0; - - afl->mutator->afl_custom_trim(afl->mutator->data, &retbuf, &retlen); + size_t retlen = afl->mutator->afl_custom_trim(afl->mutator->data, &retbuf); - if (retlen > orig_len) + if (unlikely(retlen < 0 || !retbuf)) + FATAL("custom_trim failed (ret %zd)", retlen); + else if (unlikely(retlen > orig_len)) FATAL( "Trimmed data returned by custom mutator is larger than original " "data"); @@ -238,12 +241,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { fault = run_target(afl, afl->fsrv.exec_tmout); ++afl->trim_execs; - if (afl->stop_soon || fault == FAULT_ERROR) { - - ck_free(retbuf); - goto abort_trimming; - - } + if (afl->stop_soon || fault == FAULT_ERROR) { goto abort_trimming; } cksum = hash32(afl->fsrv.trace_bits, MAP_SIZE, HASH_CONST); @@ -281,8 +279,6 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { } - ck_free(retbuf); - /* Since this can be slow, update the screen every now and then. */ if (!(trim_exec++ % afl->stats_update_freq)) show_stats(afl); diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 024b4665..8dfafb7b 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1612,15 +1612,20 @@ custom_mutator_stage: ck_read(fd, new_buf, target->len, target->fname); close(fd); - // TODO: clean up this mess. + u8 *mutated_buf = NULL; + size_t mutated_size = afl->mutator->afl_custom_fuzz( - afl->mutator->data, &out_buf, len, new_buf, target->len, max_seed_size); + afl->mutator->data, out_buf, len, &mutated_buf, new_buf, target->len, + max_seed_size); + + if (unlikely(mutated_size < 0)) + FATAL("custom_fuzz returned %zd", mutated_size); if (mutated_size > len) afl->out_size = mutated_size; if (mutated_size > 0) { - if (common_fuzz_stuff(afl, out_buf, (u32)mutated_size)) { + if (common_fuzz_stuff(afl, mutated_buf, (u32)mutated_size)) { goto abandon_entry; @@ -1726,8 +1731,22 @@ havoc_stage: if (stacked_custom && rand_below(afl, 100) < stacked_custom_prob) { - temp_len = afl->mutator->afl_custom_havoc_mutation( - afl->mutator->data, &out_buf, temp_len, MAX_FILE); + u8 * custom_havoc_buf = NULL; + size_t new_len = afl->mutator->afl_custom_havoc_mutation( + afl->mutator->data, out_buf, temp_len, &custom_havoc_buf, MAX_FILE); + if (unlikely(new_len < 0)) + FATAL("Error in custom_havoc (return %zd)", new_len); + if (likely(new_len > 0 && custom_havoc_buf)) { + + temp_len = new_len; + if (out_buf != custom_havoc_buf) { + + ck_maybe_grow(BUF_PARAMS(out), temp_len); + memcpy(out_buf, custom_havoc_buf, temp_len); + + } + + } } diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index 6fbdb678..f9f71929 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -35,15 +35,22 @@ static void *unsupported(afl_state_t *afl, unsigned int seed) { } -size_t fuzz_py(void *py_mutator, u8 **buf, size_t buf_size, u8 *add_buf, - size_t add_buf_size, size_t max_size) { +/* sorry for this makro... +it just filles in `&py_mutator->something_buf, &py_mutator->something_size`. */ +#define BUF_PARAMS(name) \ + (void **)&((py_mutator_t *)py_mutator)->name##_buf, \ + &((py_mutator_t *)py_mutator)->name##_size + +size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf, + u8 *add_buf, size_t add_buf_size, size_t max_size) { size_t mutated_size; PyObject *py_args, *py_value; py_args = PyTuple_New(3); + py_mutator_t *py = (py_mutator_t *)py_mutator; /* buf */ - py_value = PyByteArray_FromStringAndSize(*buf, buf_size); + py_value = PyByteArray_FromStringAndSize(buf, buf_size); if (!py_value) { Py_DECREF(py_args); @@ -79,17 +86,17 @@ size_t fuzz_py(void *py_mutator, u8 **buf, size_t buf_size, u8 *add_buf, PyTuple_SetItem(py_args, 2, py_value); - py_value = PyObject_CallObject( - ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_FUZZ], py_args); + py_value = PyObject_CallObject(py->py_functions[PY_FUNC_FUZZ], py_args); Py_DECREF(py_args); if (py_value != NULL) { mutated_size = PyByteArray_Size(py_value); - if (buf_size < mutated_size) *buf = ck_realloc(*buf, mutated_size); - memcpy(*buf, PyByteArray_AsString(py_value), mutated_size); + *out_buf = ck_maybe_grow(BUF_PARAMS(fuzz), mutated_size); + + memcpy(*out_buf, PyByteArray_AsString(py_value), mutated_size); Py_DECREF(py_value); return mutated_size; @@ -364,14 +371,8 @@ size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf) { py_out_buf_size = PyByteArray_Size(py_value); - if (py_out_buf_size > py->pre_save_size) { - - /* Not enough space! - Let's resize our buf */ - py->pre_save_buf = ck_realloc(py->pre_save_buf, py_out_buf_size); - py->pre_save_size = py_out_buf_size; - - } + ck_maybe_grow((void **)&py->pre_save_buf, &py->pre_save_size, + py_out_buf_size); memcpy(py->pre_save_buf, PyByteArray_AsString(py_value), py_out_buf_size); Py_DECREF(py_value); @@ -465,9 +466,10 @@ u32 post_trim_py(void *py_mutator, u8 success) { } -void trim_py(void *py_mutator, u8 **out_buf, size_t *out_buf_size) { +size_t trim_py(void *py_mutator, u8 **out_buf) { PyObject *py_args, *py_value; + size_t ret; py_args = PyTuple_New(0); py_value = PyObject_CallObject( @@ -476,9 +478,9 @@ void trim_py(void *py_mutator, u8 **out_buf, size_t *out_buf_size) { if (py_value != NULL) { - *out_buf_size = PyByteArray_Size(py_value); - *out_buf = malloc(*out_buf_size); - memcpy(*out_buf, PyByteArray_AsString(py_value), *out_buf_size); + ret = PyByteArray_Size(py_value); + *out_buf = ck_maybe_grow(BUF_PARAMS(trim), ret); + memcpy(*out_buf, PyByteArray_AsString(py_value), ret); Py_DECREF(py_value); } else { @@ -488,17 +490,19 @@ void trim_py(void *py_mutator, u8 **out_buf, size_t *out_buf_size) { } + return ret; + } -size_t havoc_mutation_py(void *py_mutator, u8 **buf, size_t buf_size, - size_t max_size) { +size_t havoc_mutation_py(void *py_mutator, u8 *buf, size_t buf_size, + u8 **out_buf, size_t max_size) { size_t mutated_size; PyObject *py_args, *py_value; py_args = PyTuple_New(2); /* buf */ - py_value = PyByteArray_FromStringAndSize(*buf, buf_size); + py_value = PyByteArray_FromStringAndSize(buf, buf_size); if (!py_value) { Py_DECREF(py_args); @@ -532,9 +536,19 @@ size_t havoc_mutation_py(void *py_mutator, u8 **buf, size_t buf_size, if (py_value != NULL) { mutated_size = PyByteArray_Size(py_value); - if (buf_size < mutated_size) *buf = ck_realloc(*buf, mutated_size); + if (mutated_size <= buf_size) { + + /* We reuse the input buf here. */ + *out_buf = buf; + + } else { - memcpy(*buf, PyByteArray_AsString(py_value), mutated_size); + /* A new buf is needed... */ + *out_buf = ck_maybe_grow(BUF_PARAMS(havoc), mutated_size); + + } + + memcpy(*out_buf, PyByteArray_AsString(py_value), mutated_size); Py_DECREF(py_value); return mutated_size; @@ -680,5 +694,7 @@ void queue_new_entry_py(void *py_mutator, const u8 *filename_new_queue, } +#undef BUF_PARAMS + #endif /* USE_PYTHON */ diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index a43bfad2..9ba2c5f7 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -741,8 +741,13 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { if (afl->post_handler) { - out_buf = afl->post_handler(out_buf, &len); - if (!out_buf || !len) return 0; + u8 *post_buf = NULL; + + size_t post_len = + afl->post_handler(afl->post_data, out_buf, len, &post_buf); + if (!post_buf || !post_len) return 0; + out_buf = post_buf; + len = post_len; } -- cgit 1.4.1 From ab5e0703dab404a77cd4726f720db99bed1a0c71 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sat, 28 Mar 2020 11:55:10 +0100 Subject: tiny changes in custom mut api --- examples/custom_mutators/example.c | 46 ++++++++++++++++++++++++-------------- include/afl-fuzz.h | 6 +++-- src/afl-fuzz-mutators.c | 2 +- src/afl-fuzz-one.c | 6 ++--- src/afl-fuzz-python.c | 2 +- src/afl-fuzz-run.c | 2 +- 6 files changed, 39 insertions(+), 25 deletions(-) (limited to 'examples/custom_mutators') diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index 54fc9d47..9a62d1a7 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -29,16 +29,15 @@ typedef struct my_mutator { afl_t *afl; // any additional data here! - uint8_t *trim_buf; - size_t trim_buf_size; - int trimmming_steps; - int cur_step; + size_t trim_size_current; + int trimmming_steps; + int cur_step; // Reused buffers: BUF_VAR(u8, fuzz); BUF_VAR(u8, data); BUF_VAR(u8, havoc); - BUF_VAR(u8, trim_out); + BUF_VAR(u8, trim); BUF_VAR(u8, pre_save); } my_mutator_t; @@ -52,7 +51,7 @@ typedef struct my_mutator { * in the same way. * @return Pointer to the data object this custom mutator instance should use. * There may be multiple instances of this mutator in one afl-fuzz run! - * Returns NULL on error. + * Return NULL on error. */ my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) { @@ -80,11 +79,13 @@ my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) { * @param[in] data pointer returned in afl_custom_init for this fuzz case * @param[in] buf Pointer to input data to be mutated * @param[in] buf_size Size of input data + * @param[out] out_buf the buffer we will work on. we can reuse *buf. NULL on + * error. * @param[in] add_buf Buffer containing the additional test case * @param[in] add_buf_size Size of the additional test case * @param[in] max_size Maximum size of the mutated output. The mutation must not * produce data larger than max_size. - * @return Size of the mutated output. Negative return will abort fuzzing. + * @return Size of the mutated output. */ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, u8 **out_buf, uint8_t *add_buf, @@ -100,7 +101,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, if (!mutated_out) { perror("custom mutator allocation (maybe_grow)"); - return -1; /* afl-fuzz will very likely error out after this. */ + return 0; /* afl-fuzz will very likely error out after this. */ } @@ -135,7 +136,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, * processing. External library should allocate memory for out_buf. * The buf pointer may be reused (up to the given buf_size); * @return Size of the output buffer after processing or the needed amount. - * A return smaller 1 indicates an error. + * A return of 0 indicates an error. */ size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, uint8_t **out_buf) { @@ -146,7 +147,8 @@ size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, if (!data->pre_save_buf) { perror("custom mutator realloc failed."); - return -1; + *out_buf = NULL; + return 0; } @@ -195,8 +197,11 @@ int afl_custom_init_trim(my_mutator_t *data, uint8_t *buf, size_t buf_size) { data->trimmming_steps = 1; data->cur_step = 0; - data->trim_buf = buf; - data->trim_buf_size = buf_size; + + maybe_grow(BUF_PARAMS(data, trim), buf_size); + memcpy(data->trim_buf, buf, buf_size); + + data->trim_size_current = buf_size; return data->trimmming_steps; @@ -218,15 +223,15 @@ int afl_custom_init_trim(my_mutator_t *data, uint8_t *buf, size_t buf_size) { * External library should allocate memory for out_buf. * AFL++ will not release the memory after saving the test case. * Keep a ref in *data. + * *out_buf = NULL is treated as error. * @return Pointer to the size of the trimmed test case */ size_t afl_custom_trim(my_mutator_t *data, uint8_t **out_buf) { - size_t ret = data->trim_buf_size - 1; + *out_buf = data->trim_buf; - *out_buf = maybe_grow(BUF_PARAMS(data, trim_out), ret); // Remove the last byte of the trimming input - memcpy(*out_buf, data->trim_buf, ret); + return data->trim_size_current - 1; } @@ -266,7 +271,7 @@ int afl_custom_post_trim(my_mutator_t *data, int success) { * output * @param[in] buf_size Size of input data * @param[out] out_buf The output buffer. buf can be reused, if the content - * fits. + * fits. *out_buf = NULL is treated as error. * @param[in] max_size Maximum size of the mutated output. The mutation must * not produce data larger than max_size. * @return Size of the mutated output. @@ -277,6 +282,13 @@ size_t afl_custom_havoc_mutation(my_mutator_t *data, u8 *buf, size_t buf_size, if (buf_size == 0) { *out_buf = maybe_grow(BUF_PARAMS(data, havoc), 1); + if (!*out_buf) { + + perror("custom havoc: maybe_grow"); + return 0; + + } + **out_buf = rand() % 256; buf_size = 1; @@ -354,7 +366,7 @@ void afl_custom_deinit(my_mutator_t *data) { free(data->havoc_buf); free(data->data_buf); free(data->fuzz_buf); - free(data->trim_out_buf); + free(data->trim_buf); free(data); } diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 5f9891bc..79878cb6 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -649,14 +649,16 @@ struct custom_mutator { * (Optional for now. Required in the future) * * @param data pointer returned in afl_custom_init for this fuzz case - * @param[inout] buf Pointer to the input data to be mutated and the mutated + * @param[in] buf Pointer to the input data to be mutated and the mutated * output * @param[in] buf_size Size of the input/output data + * @param[out] out_buf the new buffer. We may reuse *buf if large enough. + * *out_buf = NULL is treated as FATAL. * @param[in] add_buf Buffer containing the additional test case * @param[in] add_buf_size Size of the additional test case * @param[in] max_size Maximum size of the mutated output. The mutation must * not produce data larger than max_size. - * @return Size of the mutated output. Negative on error will abort exeuction. + * @return Size of the mutated output. */ 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); diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 0692ebb0..f14a57bb 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -229,7 +229,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { size_t retlen = afl->mutator->afl_custom_trim(afl->mutator->data, &retbuf); - if (unlikely(retlen < 0 || !retbuf)) + if (unlikely(!retbuf)) FATAL("custom_trim failed (ret %zd)", retlen); else if (unlikely(retlen > orig_len)) FATAL( diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 8dfafb7b..b1bbad0a 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1618,8 +1618,8 @@ custom_mutator_stage: afl->mutator->data, out_buf, len, &mutated_buf, new_buf, target->len, max_seed_size); - if (unlikely(mutated_size < 0)) - FATAL("custom_fuzz returned %zd", mutated_size); + if (unlikely(!mutated_buf)) + FATAL("Error in custom_fuzz. Size returned: %zd", mutated_size); if (mutated_size > len) afl->out_size = mutated_size; @@ -1734,7 +1734,7 @@ havoc_stage: u8 * custom_havoc_buf = NULL; size_t new_len = afl->mutator->afl_custom_havoc_mutation( afl->mutator->data, out_buf, temp_len, &custom_havoc_buf, MAX_FILE); - if (unlikely(new_len < 0)) + if (unlikely(!custom_havoc_buf)) FATAL("Error in custom_havoc (return %zd)", new_len); if (likely(new_len > 0 && custom_havoc_buf)) { diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index 6f8982c0..76b5ca80 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -103,7 +103,7 @@ size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf, } else { PyErr_Print(); - FATAL("Call failed"); + FATAL("python custom fuzz: call failed"); } diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 315539d1..90cb2ed5 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -221,7 +221,7 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) { size_t new_size = afl->mutator->afl_custom_pre_save(afl->mutator->data, mem, len, &new_buf); - if (unlikely(new_size <= 0 || !new_buf)) + if (unlikely(!new_buf)) FATAL("Custom_pre_save failed (ret: %lu)", (long unsigned)new_size); /* everything as planned. use the new data. */ -- cgit 1.4.1 From 81873d97f8a24a874a52f56aae5ca87745f1aaec Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sat, 28 Mar 2020 12:58:56 +0100 Subject: error handling for custom mutators --- examples/custom_mutators/custom_mutator_helpers.h | 49 ++++++++++++++--------- examples/custom_mutators/example.c | 15 ++++--- include/afl-fuzz.h | 13 +++--- include/alloc-inl.h | 6 +-- src/afl-fuzz-mutators.c | 3 +- src/afl-fuzz-python.c | 4 +- 6 files changed, 54 insertions(+), 36 deletions(-) (limited to 'examples/custom_mutators') diff --git a/examples/custom_mutators/custom_mutator_helpers.h b/examples/custom_mutators/custom_mutator_helpers.h index 0dc00d96..e5ce3569 100644 --- a/examples/custom_mutators/custom_mutator_helpers.h +++ b/examples/custom_mutators/custom_mutator_helpers.h @@ -277,37 +277,48 @@ static void surgical_havoc_mutate(u8 *out_buf, s32 begin, s32 end) { } + +/* This function calculates the next power of 2 greater or equal its argument. + @return The rounded up power of 2 (if no overflow) or 0 on overflow. +*/ +static inline size_t next_pow2(size_t in) { + if (in == 0 || in > (size_t)-1) return 0; /* avoid undefined behaviour under-/overflow */ + size_t out = in - 1; + out |= out >> 1; + out |= out >> 2; + out |= out >> 4; + out |= out >> 8; + out |= out >> 16; + return out + 1; +} + /* This function makes sure *size is > size_needed after call. - It changes buf and size in-place, if needed. It will realloc *buf otherwise. *size will grow exponentially as per: https://blog.mozilla.org/nnethercote/2014/11/04/please-grow-your-buffers-exponentially/ - Will return NULL if size_needed is <1 or *size is negative or malloc Failed. - @return For convenience, this function returns *buf. NULL on error. + Will return NULL and free *buf if size_needed is <1 or realloc failed. + @return For convenience, this function returns *buf. */ -static inline void *maybe_grow(void **buf, size_t *size, size_t size_needed) { - - /* Oops. found a bug? */ - if (unlikely(size_needed < 1)) return NULL; +static inline void *maybe_grow(void **buf, size_t *size, + size_t size_needed) { /* No need to realloc */ - if (likely(*size >= size_needed)) return *buf; - if (unlikely(*size < 0)) return NULL; - /* No inital size was set */ - if (*size == 0) *size = INITIAL_GROWTH_SIZE; - while (*size < size_needed) { - - *size *= 2; - if ((*size) < 0) { + if (likely(size_needed && *size >= size_needed)) return *buf; - /* An overflow occurred. Fall back to size_needed */ - *size = size_needed; + /* No initial size was set */ + if (size_needed < INITIAL_GROWTH_SIZE) size_needed = INITIAL_GROWTH_SIZE; - } + /* grow exponentially */ + size_t next_size = next_pow2(size_needed); + /* handle overflow */ + if (!next_size) { + next_size = size_needed; } - *buf = realloc(*buf, *size); + /* alloc */ + *buf = realloc(*buf, next_size); + *size = *buf ? next_size : 0; return *buf; diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index 9a62d1a7..488ece81 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -100,6 +100,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, u8 *mutated_out = maybe_grow(BUF_PARAMS(data, fuzz), mutated_size); if (!mutated_out) { + *out_buf = NULL; perror("custom mutator allocation (maybe_grow)"); return 0; /* afl-fuzz will very likely error out after this. */ @@ -189,16 +190,20 @@ size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, * @param data pointer returned in afl_custom_init for this fuzz case * @param buf Buffer containing the test case * @param buf_size Size of the test case - * @return The amount of possible iteration steps to trim the input + * @return The amount of possible iteration steps to trim the input. + * negative on error. */ -int afl_custom_init_trim(my_mutator_t *data, uint8_t *buf, size_t buf_size) { +int32_t afl_custom_init_trim(my_mutator_t *data, uint8_t *buf, size_t buf_size) { // We simply trim once data->trimmming_steps = 1; data->cur_step = 0; - maybe_grow(BUF_PARAMS(data, trim), buf_size); + if (!maybe_grow(BUF_PARAMS(data, trim), buf_size)) { + perror("init_trim grow"); + return -1; + } memcpy(data->trim_buf, buf, buf_size); data->trim_size_current = buf_size; @@ -245,9 +250,9 @@ size_t afl_custom_trim(my_mutator_t *data, uint8_t **out_buf) { * @param[in] data pointer returned in afl_custom_init for this fuzz case * @param success Indicates if the last trim operation was successful. * @return The next trim iteration index (from 0 to the maximum amount of - * steps returned in init_trim) + * steps returned in init_trim). negative ret on failure. */ -int afl_custom_post_trim(my_mutator_t *data, int success) { +int32_t afl_custom_post_trim(my_mutator_t *data, int success) { if (success) { diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 79878cb6..a265c1a3 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -700,9 +700,10 @@ struct custom_mutator { * @param data pointer returned in afl_custom_init for this fuzz case * @param buf Buffer containing the test case * @param buf_size Size of the test case - * @return The amount of possible iteration steps to trim the input + * @return The amount of possible iteration steps to trim the input. + * Negative on error. */ - u32 (*afl_custom_init_trim)(void *data, u8 *buf, size_t buf_size); + s32 (*afl_custom_init_trim)(void *data, u8 *buf, size_t buf_size); /** * This method is called for each trimming operation. It doesn't have any @@ -733,9 +734,9 @@ struct custom_mutator { * @param data pointer returned in afl_custom_init for this fuzz case * @param success Indicates if the last trim operation was successful. * @return The next trim iteration index (from 0 to the maximum amount of - * steps returned in init_trim) + * steps returned in init_trim). Negative on error. */ - u32 (*afl_custom_post_trim)(void *data, u8 success); + s32 (*afl_custom_post_trim)(void *data, u8 success); /** * Perform a single custom mutation on a given input. @@ -818,8 +819,8 @@ u8 trim_case_custom(afl_state_t *, struct queue_entry *q, u8 *in_buf); void finalize_py_module(void *); size_t pre_save_py(void *, u8 *, size_t, u8 **); -u32 init_trim_py(void *, u8 *, size_t); -u32 post_trim_py(void *, u8); +s32 init_trim_py(void *, u8 *, size_t); +s32 post_trim_py(void *, u8); size_t trim_py(void *, u8 **); size_t havoc_mutation_py(void *, u8 *, size_t, u8 **, size_t); u8 havoc_mutation_probability_py(void *); diff --git a/include/alloc-inl.h b/include/alloc-inl.h index b8c83db4..91564932 100644 --- a/include/alloc-inl.h +++ b/include/alloc-inl.h @@ -767,10 +767,10 @@ static inline void TRK_ck_free(void *ptr, const char *file, const char *func, #endif /* _WANT_ORIGINAL_AFL_ALLOC */ -/* This function calculates the lowest power of 2 greater or equal its argument. +/* This function calculates the next power of 2 greater or equal its argument. @return The rounded up power of 2 (if no overflow) or 0 on overflow. */ -static inline size_t powerOf2Ceil(size_t in) { +static inline size_t next_pow2(size_t in) { if (in == 0 || in > (size_t)-1) return 0; /* avoid undefined behaviour under-/overflow */ size_t out = in - 1; out |= out >> 1; @@ -801,7 +801,7 @@ static inline void *ck_maybe_grow(void **buf, size_t *size, if (size_needed < INITIAL_GROWTH_SIZE) size_needed = INITIAL_GROWTH_SIZE; /* grow exponentially */ - size_t next_size = powerOf2Ceil(size_needed); + size_t next_size = next_pow2(size_needed); /* handle overflow */ if (!next_size) { diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index f14a57bb..90d7de40 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -213,7 +213,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { afl->stage_cur = 0; afl->stage_max = afl->mutator->afl_custom_init_trim(afl->mutator->data, in_buf, q->len); - + if (unlikely(afl->stage_max) < 0) FATAL("custom_init_trim error ret: %d", afl->stage_max); if (afl->not_on_tty && afl->debug) SAYF("[Custom Trimming] START: Max %d iterations, %u bytes", afl->stage_max, q->len); @@ -273,6 +273,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { /* Tell the custom mutator that the trimming was unsuccessful */ afl->stage_cur = afl->mutator->afl_custom_post_trim(afl->mutator->data, 0); + if (unlikely(afl->stage_cur < 0)) FATAL("Error ret in custom_post_trim: %d", afl->stage_cur); if (afl->not_on_tty && afl->debug) SAYF("[Custom Trimming] FAILURE: %d/%d iterations", afl->stage_cur, afl->stage_max); diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index 76b5ca80..91e5b084 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -388,7 +388,7 @@ size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf) { } -u32 init_trim_py(void *py_mutator, u8 *buf, size_t buf_size) { +s32 init_trim_py(void *py_mutator, u8 *buf, size_t buf_size) { PyObject *py_args, *py_value; @@ -426,7 +426,7 @@ u32 init_trim_py(void *py_mutator, u8 *buf, size_t buf_size) { } -u32 post_trim_py(void *py_mutator, u8 success) { +s32 post_trim_py(void *py_mutator, u8 success) { PyObject *py_args, *py_value; -- cgit 1.4.1 From 98545f30aa52c1b82b88e54088848b90e178a929 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sat, 28 Mar 2020 12:59:41 +0100 Subject: code format --- examples/custom_mutators/custom_mutator_helpers.h | 13 ++++++------- examples/custom_mutators/example.c | 6 +++++- include/alloc-inl.h | 9 +++++---- src/afl-fuzz-mutators.c | 6 ++++-- 4 files changed, 20 insertions(+), 14 deletions(-) (limited to 'examples/custom_mutators') diff --git a/examples/custom_mutators/custom_mutator_helpers.h b/examples/custom_mutators/custom_mutator_helpers.h index e5ce3569..0848321f 100644 --- a/examples/custom_mutators/custom_mutator_helpers.h +++ b/examples/custom_mutators/custom_mutator_helpers.h @@ -277,12 +277,13 @@ static void surgical_havoc_mutate(u8 *out_buf, s32 begin, s32 end) { } - /* This function calculates the next power of 2 greater or equal its argument. @return The rounded up power of 2 (if no overflow) or 0 on overflow. */ static inline size_t next_pow2(size_t in) { - if (in == 0 || in > (size_t)-1) return 0; /* avoid undefined behaviour under-/overflow */ + + if (in == 0 || in > (size_t)-1) + return 0; /* avoid undefined behaviour under-/overflow */ size_t out = in - 1; out |= out >> 1; out |= out >> 2; @@ -290,6 +291,7 @@ static inline size_t next_pow2(size_t in) { out |= out >> 8; out |= out >> 16; return out + 1; + } /* This function makes sure *size is > size_needed after call. @@ -299,8 +301,7 @@ static inline size_t next_pow2(size_t in) { Will return NULL and free *buf if size_needed is <1 or realloc failed. @return For convenience, this function returns *buf. */ -static inline void *maybe_grow(void **buf, size_t *size, - size_t size_needed) { +static inline void *maybe_grow(void **buf, size_t *size, size_t size_needed) { /* No need to realloc */ if (likely(size_needed && *size >= size_needed)) return *buf; @@ -312,9 +313,7 @@ static inline void *maybe_grow(void **buf, size_t *size, size_t next_size = next_pow2(size_needed); /* handle overflow */ - if (!next_size) { - next_size = size_needed; - } + if (!next_size) { next_size = size_needed; } /* alloc */ *buf = realloc(*buf, next_size); diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index 488ece81..a9764f5b 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -193,7 +193,8 @@ size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, * @return The amount of possible iteration steps to trim the input. * negative on error. */ -int32_t afl_custom_init_trim(my_mutator_t *data, uint8_t *buf, size_t buf_size) { +int32_t afl_custom_init_trim(my_mutator_t *data, uint8_t *buf, + size_t buf_size) { // We simply trim once data->trimmming_steps = 1; @@ -201,9 +202,12 @@ int32_t afl_custom_init_trim(my_mutator_t *data, uint8_t *buf, size_t buf_size) data->cur_step = 0; if (!maybe_grow(BUF_PARAMS(data, trim), buf_size)) { + perror("init_trim grow"); return -1; + } + memcpy(data->trim_buf, buf, buf_size); data->trim_size_current = buf_size; diff --git a/include/alloc-inl.h b/include/alloc-inl.h index 91564932..4211e398 100644 --- a/include/alloc-inl.h +++ b/include/alloc-inl.h @@ -771,7 +771,9 @@ static inline void TRK_ck_free(void *ptr, const char *file, const char *func, @return The rounded up power of 2 (if no overflow) or 0 on overflow. */ static inline size_t next_pow2(size_t in) { - if (in == 0 || in > (size_t)-1) return 0; /* avoid undefined behaviour under-/overflow */ + + if (in == 0 || in > (size_t)-1) + return 0; /* avoid undefined behaviour under-/overflow */ size_t out = in - 1; out |= out >> 1; out |= out >> 2; @@ -779,6 +781,7 @@ static inline size_t next_pow2(size_t in) { out |= out >> 8; out |= out >> 16; return out + 1; + } /* This function makes sure *size is > size_needed after call. @@ -804,9 +807,7 @@ static inline void *ck_maybe_grow(void **buf, size_t *size, size_t next_size = next_pow2(size_needed); /* handle overflow */ - if (!next_size) { - next_size = size_needed; - } + if (!next_size) { next_size = size_needed; } /* alloc */ *buf = ck_realloc(*buf, next_size); diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 90d7de40..754b2190 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -213,7 +213,8 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { afl->stage_cur = 0; afl->stage_max = afl->mutator->afl_custom_init_trim(afl->mutator->data, in_buf, q->len); - if (unlikely(afl->stage_max) < 0) FATAL("custom_init_trim error ret: %d", afl->stage_max); + if (unlikely(afl->stage_max) < 0) + FATAL("custom_init_trim error ret: %d", afl->stage_max); if (afl->not_on_tty && afl->debug) SAYF("[Custom Trimming] START: Max %d iterations, %u bytes", afl->stage_max, q->len); @@ -273,7 +274,8 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { /* Tell the custom mutator that the trimming was unsuccessful */ afl->stage_cur = afl->mutator->afl_custom_post_trim(afl->mutator->data, 0); - if (unlikely(afl->stage_cur < 0)) FATAL("Error ret in custom_post_trim: %d", afl->stage_cur); + if (unlikely(afl->stage_cur < 0)) + FATAL("Error ret in custom_post_trim: %d", afl->stage_cur); if (afl->not_on_tty && afl->debug) SAYF("[Custom Trimming] FAILURE: %d/%d iterations", afl->stage_cur, afl->stage_max); -- cgit 1.4.1 From 245304f5938a700e93a3403b30509dea55a6549e Mon Sep 17 00:00:00 2001 From: h1994st Date: Fri, 27 Mar 2020 02:03:20 -0400 Subject: Add a test case for the custom mutator - Update the Makefile in examples/custom_mutators - Add a test program for testing the custom mutator - Update test.sh for testing the custom mutator - [TODO] Update the result checking criterias of the custom mutator in test.sh --- examples/custom_mutators/Makefile | 7 ++- test/test-custom-mutator.c | 20 ++++++ test/test.sh | 128 ++++++++++++++++++++++++++++++-------- 3 files changed, 127 insertions(+), 28 deletions(-) create mode 100644 test/test-custom-mutator.c (limited to 'examples/custom_mutators') diff --git a/examples/custom_mutators/Makefile b/examples/custom_mutators/Makefile index a83e87fe..463cefb1 100644 --- a/examples/custom_mutators/Makefile +++ b/examples/custom_mutators/Makefile @@ -1,2 +1,7 @@ -all: +all: libexamplemutator.so + +libexamplemutator.so: $(CC) $(CFLAGS) -fPIC -shared -g -I ../../include example.c -o libexamplemutator.so + +clean: + rm -rf libexamplemutator.so diff --git a/test/test-custom-mutator.c b/test/test-custom-mutator.c new file mode 100644 index 00000000..b44c3634 --- /dev/null +++ b/test/test-custom-mutator.c @@ -0,0 +1,20 @@ +/** + * Reference: https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/blob/master/4_libprotobuf_aflpp_custom_mutator/vuln.c + */ + +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + char str[100]={ }; + read(0, str, 100); + int *ptr = NULL; + if( str[0] == 'P') { + *ptr = 123; + } + return 0; +} diff --git a/test/test.sh b/test/test.sh index ec4e71d0..725ae9e4 100755 --- a/test/test.sh +++ b/test/test.sh @@ -60,8 +60,8 @@ unset AFL_QEMU_PERSISTENT_GPR unset AFL_QEMU_PERSISTENT_RET unset AFL_QEMU_PERSISTENT_HOOK unset AFL_QEMU_PERSISTENT_CNT -unset AFL_POST_LIBRARY -unset AFL_CUSTOM_MUTATOR_LIBRARY + +export unset AFL_CUSTOM_MUTATOR_LIBRARY=unset AFL_POST_LIBRARY unset AFL_PYTHON_MODULE unset AFL_PRELOAD unset LD_PRELOAD @@ -73,7 +73,7 @@ export ASAN_OPTIONS=detect_leaks=0:allocator_may_return_null=1:abort_on_error=1: # on OpenBSD we need to work with llvm from /usr/local/bin test -e /usr/local/bin/opt && { export PATH=/usr/local/bin:${PATH} -} +} # on MacOS X we prefer afl-clang over afl-gcc, because # afl-gcc does not work there test `uname -s` = 'Darwin' -o `uname -s` = 'FreeBSD' && { @@ -142,11 +142,11 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc CODE=1 } rm -f test-compcov.harden - } || { + } || { $ECHO "$RED[!] ${AFL_GCC} hardened mode compilation failed" CODE=1 } - # now we want to be sure that afl-fuzz is working + # now we want to be sure that afl-fuzz is working # make sure core_pattern is set to core on linux (test "$(uname -s)" = "Linux" && test "$(sysctl kernel.core_pattern)" != "kernel.core_pattern = core" && { $ECHO "$YELLOW[-] we should not run afl-fuzz with enabled core dumps. Run 'sudo sh afl-system-config'.$RESET" @@ -210,13 +210,13 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc unset AFL_QUIET } rm -f test-instr.plain - } || { + } || { $ECHO "$YELLOW[-] afl is not compiled, cannot test" INCOMPLETE=1 } -} || { +} || { $ECHO "$YELLOW[-] not an intel platform, cannot test afl-gcc" -} +} $ECHO "$BLUE[*] Testing: llvm_mode, afl-showmap, afl-fuzz, afl-cmin and afl-tmin" test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { @@ -248,7 +248,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { CODE=1 } } - } || { + } || { $ECHO "$RED[!] llvm_mode instrumentation failed" CODE=1 } @@ -265,11 +265,11 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { CODE=1 } rm -f test-compcov.harden - } || { + } || { $ECHO "$RED[!] llvm_mode hardened mode compilation failed" CODE=1 } - # now we want to be sure that afl-fuzz is working + # now we want to be sure that afl-fuzz is working (test "$(uname -s)" = "Linux" && test "$(sysctl kernel.core_pattern)" != "kernel.core_pattern = core" && { $ECHO "$YELLOW[-] we should not run afl-fuzz with enabled core dumps. Run 'sudo sh afl-system-config'.$RESET" true @@ -373,7 +373,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { $ECHO "$RED[!] llvm_mode whitelist feature failed" CODE=1 } - } || { + } || { $ECHO "$RED[!] llvm_mode whitelist feature compilation failed" CODE=1 } @@ -426,7 +426,7 @@ test -e ../afl-clang-lto -a -e ../afl-llvm-lto-instrumentation.so && { CODE=1 } } - } || { + } || { $ECHO "$RED[!] llvm_mode LTO instrumentation failed" CODE=1 } @@ -447,7 +447,7 @@ test -e ../afl-clang-lto -a -e ../afl-llvm-lto-instrumentation.so && { # $ECHO "$RED[!] llvm_mode LTO whitelist feature failed" # CODE=1 # } -# } || { +# } || { # $ECHO "$RED[!] llvm_mode LTO whitelist feature compilation failed" # CODE=1 # } @@ -483,7 +483,7 @@ test -e ../afl-gcc-fast -a -e ../afl-gcc-rt.o && { diff test-instr.plain.0 test-instr.plain.1 > /dev/null 2>&1 && { $ECHO "$RED[!] gcc_plugin instrumentation should be different on different input but is not" CODE=1 - } || { + } || { $ECHO "$GREEN[+] gcc_plugin instrumentation present and working correctly" TUPLES=`echo 0|../afl-showmap -m ${MEM_LIMIT} -o /dev/null -- ./test-instr.plain.gccpi 2>&1 | grep Captur | awk '{print$3}'` test "$TUPLES" -gt 3 -a "$TUPLES" -lt 7 && { @@ -516,7 +516,7 @@ test -e ../afl-gcc-fast -a -e ../afl-gcc-rt.o && { $ECHO "$RED[!] gcc_plugin hardened mode compilation failed" CODE=1 } - # now we want to be sure that afl-fuzz is working + # now we want to be sure that afl-fuzz is working (test "$(uname -s)" = "Linux" && test "$(sysctl kernel.core_pattern)" != "kernel.core_pattern = core" && { $ECHO "$YELLOW[-] we should not run afl-fuzz with enabled core dumps. Run 'sudo sh afl-system-config'.$RESET" true @@ -552,11 +552,11 @@ test -e ../afl-gcc-fast -a -e ../afl-gcc-rt.o && { test -e test-compcov && { echo 1 | ../afl-showmap -m ${MEM_LIMIT} -o - -r -- ./test-compcov 2>&1 | grep -q "Captured 1 tuples" && { $ECHO "$GREEN[+] gcc_plugin whitelist feature works correctly" - } || { + } || { $ECHO "$RED[!] gcc_plugin whitelist feature failed" CODE=1 } - } || { + } || { $ECHO "$RED[!] gcc_plugin whitelist feature compilation failed" CODE=1 } @@ -585,7 +585,7 @@ test -e ../libtokencap.so && { AFL_TOKEN_FILE=token.out LD_PRELOAD=../libtokencap.so DYLD_INSERT_LIBRARIES=../libtokencap.so DYLD_FORCE_FLAT_NAMESPACE=1 ./test-compcov foobar > /dev/null 2>&1 grep -q BUGMENOT token.out > /dev/null 2>&1 && { $ECHO "$GREEN[+] libtokencap did successfully capture tokens" - } || { + } || { $ECHO "$RED[!] libtokencap did not capture tokens" CODE=1 } @@ -604,7 +604,7 @@ test -e ../libdislocator.so && { $ECHO "$RED[!] libdislocator did not detect the memory corruption" CODE=1 } || { - $ECHO "$GREEN[+] libdislocator did successfully detect the memory corruption" + $ECHO "$GREEN[+] libdislocator did successfully detect the memory corruption" } rm -f test.out core test-compcov.core core.test-compcov } || { @@ -700,7 +700,7 @@ test -e ../afl-qemu-trace && { test -e ../libcompcov.so && { $ECHO "$GREY[*] running afl-fuzz for qemu_mode compcov, this will take approx 10 seconds" { - export AFL_PRELOAD=../libcompcov.so + export AFL_PRELOAD=../libcompcov.so export AFL_COMPCOV_LEVEL=2 ../afl-fuzz -m ${MEM_LIMIT} -V10 -Q -i in -o out -- ./test-compcov >>errors 2>&1 unset AFL_PRELOAD @@ -720,10 +720,10 @@ test -e ../afl-qemu-trace && { INCOMPLETE=1 } rm -f errors - } || { + } || { $ECHO "$YELLOW[-] not an intel or arm platform, cannot test qemu_mode compcov" } - + test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc" -o "$SYS" = "aarch64" -o ! "${SYS%%arm*}" && { $ECHO "$GREY[*] running afl-fuzz for persistent qemu_mode, this will take approx 10 seconds" { @@ -757,9 +757,9 @@ test -e ../afl-qemu-trace && { exit 1 } rm -rf in out errors - } || { + } || { $ECHO "$YELLOW[-] not an intel or arm platform, cannot test persistent qemu_mode" - } + } test -e ../qemu_mode/unsigaction/unsigaction32.so && { ${AFL_CC} -o test-unsigaction32 -m32 test-unsigaction.c >> errors 2>&1 && { @@ -824,7 +824,7 @@ test -e ../afl-qemu-trace && { $ECHO "$RED[!] gcc compilation of test targets failed - what is going on??" CODE=1 } - + rm -f test-instr test-compcov } || { $ECHO "$YELLOW[-] qemu_mode is not compiled, cannot test" @@ -887,12 +887,86 @@ test -d ../unicorn_mode/unicornafl && { $ECHO "$RED[!] missing sample binaries in unicorn_mode/samples/ - what is going on??" CODE=1 } - + } || { $ECHO "$YELLOW[-] unicorn_mode is not compiled, cannot test" INCOMPLETE=1 } +$ECHO "$BLUE[*] Testing: custom mutator" +unset AFL_CC # Line 474 sets AFL_CC to "gcc". We reset it to use the default compiler +CUSTOM_MUTATOR_PATH=../examples/custom_mutators +test -e test-custom-mutator.c -a -e ${CUSTOM_MUTATOR_PATH}/example.c -a -e ${CUSTOM_MUTATOR_PATH}/example.c && { + # Compile the vulnerable program + ../afl-clang-fast -o test-custom-mutator test-custom-mutator.c + # Compile the custom mutator + make -C ../examples/custom_mutators libexamplemutator.so + test -e test-custom-mutator -a -e ${CUSTOM_MUTATOR_PATH}/libexamplemutator.so && { + # Create input directory + mkdir -p in + echo 00000 > in/in + + # Run afl-fuzz w/ the C mutator + $ECHO "$GREY[*] running afl-fuzz for the C mutator, this will take approx 10 seconds" + { + export AFL_CUSTOM_MUTATOR_LIBRARY=${CUSTOM_MUTATOR_PATH}/libexamplemutator.so + ../afl-fuzz -V10 -m ${MEM_LIMIT} -i in -o out -- ./test-custom-mutator + unset AFL_CUSTOM_MUTATOR_LIBRARY + } >>errors 2>&1 + + # Check results + test -n "$( ls out/queue/id:000001* 2>/dev/null )" && { # TODO: update here + $ECHO "$GREEN[+] afl-fuzz is working correctly with the C mutator" + } || { + echo CUT------------------------------------------------------------------CUT + cat errors + echo CUT------------------------------------------------------------------CUT + $ECHO "$RED[!] afl-fuzz is not working correctly with the C mutator" + CODE=1 + } + + # Clean + rm -rf out errors + + # Run afl-fuzz w/ the Python mutator + $ECHO "$GREY[*] running afl-fuzz for the Python mutator, this will take approx 10 seconds" + { + export PYTHONPATH=${CUSTOM_MUTATOR_PATH} + export AFL_PYTHON_MODULE=example + ../afl-fuzz -V10 -m ${MEM_LIMIT} -i in -o out -- ./test-custom-mutator + unset PYTHONPATH + unset AFL_PYTHON_MODULE + } >>errors 2>&1 + + # Check results + test -n "$( ls out/queue/id:000001* 2>/dev/null )" && { # TODO: update here + $ECHO "$GREEN[+] afl-fuzz is working correctly with the Python mutator" + } || { + echo CUT------------------------------------------------------------------CUT + cat errors + echo CUT------------------------------------------------------------------CUT + $ECHO "$RED[!] afl-fuzz is not working correctly with the Python mutator" + CODE=1 + } + + # Clean + rm -rf in out errors + rm -rf ${CUSTOM_MUTATOR_PATH}/__pycache__/ + } || { + ls . + ls ${CUSTOM_MUTATOR_PATH} + $ECHO "$RED[!] cannot compile the test program or the custom mutator" + CODE=1 + } + + make -C ../examples/custom_mutators clean > /dev/null 2>&1 + rm -f test-custom-mutator +} || { + $ECHO "$YELLOW[-] no custom mutators in $CUSTOM_MUTATOR_PATH, cannot test" + INCOMPLETE=1 +} +unset CUSTOM_MUTATOR_PATH + $ECHO "$GREY[*] all test cases completed.$RESET" test "$INCOMPLETE" = "0" && $ECHO "$GREEN[+] all test cases executed" test "$INCOMPLETE" = "1" && $ECHO "$YELLOW[-] not all test cases were executed" -- cgit 1.4.1 From d568559f01b1a7609f8a0c4f7afea513375725e4 Mon Sep 17 00:00:00 2001 From: h1994st Date: Fri, 27 Mar 2020 21:03:06 -0400 Subject: Fix typo --- examples/custom_mutators/example.py | 3 +-- test/test.sh | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'examples/custom_mutators') diff --git a/examples/custom_mutators/example.py b/examples/custom_mutators/example.py index 6bacfa05..6b58188e 100644 --- a/examples/custom_mutators/example.py +++ b/examples/custom_mutators/example.py @@ -164,11 +164,10 @@ def fuzz(buf, add_buf, max_size): # ''' # Called after adding a new test case to the queue # -# @type filename_new_queue: str +# @type filename_new_queue: str # @param filename_new_queue: File name of the new queue entry # # @type filename_orig_queue: str # @param filename_orig_queue: File name of the original queue entry # ''' # pass - diff --git a/test/test.sh b/test/test.sh index 0d3c7199..11c4be25 100755 --- a/test/test.sh +++ b/test/test.sh @@ -60,8 +60,8 @@ unset AFL_QEMU_PERSISTENT_GPR unset AFL_QEMU_PERSISTENT_RET unset AFL_QEMU_PERSISTENT_HOOK unset AFL_QEMU_PERSISTENT_CNT - -export unset AFL_CUSTOM_MUTATOR_LIBRARY=unset AFL_POST_LIBRARY +unset AFL_POST_LIBRARY +unset AFL_CUSTOM_MUTATOR_LIBRARY unset AFL_PYTHON_MODULE unset AFL_PRELOAD unset LD_PRELOAD -- cgit 1.4.1 From 0dd8ed9171cdbee3360f4b7f6a9fd91e7478a508 Mon Sep 17 00:00:00 2001 From: h1994st Date: Sat, 28 Mar 2020 00:52:29 -0400 Subject: Fix invalid memory access bug in `afl_custom_pre_save` of example.c --- examples/custom_mutators/example.c | 16 +++++++++------- src/afl-fuzz-python.c | 3 ++- 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'examples/custom_mutators') diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index a9764f5b..7d827029 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -157,15 +157,17 @@ size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, } - *out_buf = data->pre_save_buf; + uint8_t *pre_save_buf = data->pre_save_buf; - memcpy(*out_buf + 5, buf, buf_size); + memcpy(pre_save_buf + 5, buf, buf_size); size_t out_buf_size = buf_size + 5; - *out_buf[0] = 'A'; - *out_buf[1] = 'F'; - *out_buf[2] = 'L'; - *out_buf[3] = '+'; - *out_buf[4] = '+'; + pre_save_buf[0] = 'A'; + pre_save_buf[1] = 'F'; + pre_save_buf[2] = 'L'; + pre_save_buf[3] = '+'; + pre_save_buf[4] = '+'; + + *out_buf = pre_save_buf; return out_buf_size; diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index 91e5b084..01503d2c 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -133,8 +133,8 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { if (py_module != NULL) { u8 py_notrim = 0, py_idx; + /* init, required */ py_functions[PY_FUNC_INIT] = PyObject_GetAttrString(py_module, "init"); - py_functions[PY_FUNC_DEINIT] = PyObject_GetAttrString(py_module, "deinit"); py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "fuzz"); py_functions[PY_FUNC_PRE_SAVE] = PyObject_GetAttrString(py_module, "pre_save"); @@ -151,6 +151,7 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { PyObject_GetAttrString(py_module, "queue_get"); py_functions[PY_FUNC_QUEUE_NEW_ENTRY] = PyObject_GetAttrString(py_module, "queue_new_entry"); + py_functions[PY_FUNC_DEINIT] = PyObject_GetAttrString(py_module, "deinit"); for (py_idx = 0; py_idx < PY_FUNC_COUNT; ++py_idx) { -- cgit 1.4.1 From 71edae4a0fd7ca64a6f2c87768d14136ac04b0a1 Mon Sep 17 00:00:00 2001 From: h1994st Date: Sun, 29 Mar 2020 01:06:28 -0400 Subject: example.py: add deinit() --- examples/custom_mutators/example.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'examples/custom_mutators') diff --git a/examples/custom_mutators/example.py b/examples/custom_mutators/example.py index 6b58188e..7919d3d3 100644 --- a/examples/custom_mutators/example.py +++ b/examples/custom_mutators/example.py @@ -27,6 +27,10 @@ def init(seed): random.seed(seed) +def deinit(): + pass + + def fuzz(buf, add_buf, max_size): ''' Called per fuzzing iteration. -- cgit 1.4.1 From 64e1d3a975b5d4f017fabdc921cb59128db1c18a Mon Sep 17 00:00:00 2001 From: h1994st Date: Sun, 29 Mar 2020 01:22:44 -0400 Subject: test.sh: "trusty-amd64" does not work well with "realpath". Use "readlink -f" for Ubuntu instead. --- examples/custom_mutators/example.py | 12 ++++++++++-- test/test.sh | 16 ++++++++++------ 2 files changed, 20 insertions(+), 8 deletions(-) (limited to 'examples/custom_mutators') diff --git a/examples/custom_mutators/example.py b/examples/custom_mutators/example.py index 7919d3d3..9e95eed6 100644 --- a/examples/custom_mutators/example.py +++ b/examples/custom_mutators/example.py @@ -17,6 +17,13 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/. import random +COMMANDS = [ + b"GET", + b"PUT", + b"DEL", +] + + def init(seed): ''' Called once when AFLFuzz starts up. Used to seed our RNG. @@ -48,8 +55,9 @@ def fuzz(buf, add_buf, max_size): @rtype: bytearray @return: A new bytearray containing the mutated data ''' - ret = bytearray(buf) - # Do something interesting with ret + ret = bytearray(100) + + ret[:3] = random.choice(COMMANDS) return ret diff --git a/test/test.sh b/test/test.sh index 11c4be25..c9ce3489 100755 --- a/test/test.sh +++ b/test/test.sh @@ -894,9 +894,13 @@ test -d ../unicorn_mode/unicornafl && { } $ECHO "$BLUE[*] Testing: custom mutator" -unset AFL_CC # Line 474 sets AFL_CC to "gcc". We reset it to use the default compiler -CUSTOM_MUTATOR_PATH=$( realpath ../examples/custom_mutators ) -test -e test-custom-mutator.c -a -e ${CUSTOM_MUTATOR_PATH}/example.c -a -e ${CUSTOM_MUTATOR_PATH}/example.c && { +unset AFL_CC # Test case "gcc_plugin" sets AFL_CC to "gcc". We reset it to use the default compiler +test `uname -s` = 'Darwin' && { + CUSTOM_MUTATOR_PATH=$( realpath ../examples/custom_mutators ) +} || { + CUSTOM_MUTATOR_PATH=$( readlink -f ../examples/custom_mutators ) +} +test -e test-custom-mutator.c -a -e ${CUSTOM_MUTATOR_PATH}/example.c -a -e ${CUSTOM_MUTATOR_PATH}/example.py && { # Compile the vulnerable program ../afl-clang-fast -o test-custom-mutator test-custom-mutator.c > /dev/null 2>&1 # Compile the custom mutator @@ -904,7 +908,7 @@ test -e test-custom-mutator.c -a -e ${CUSTOM_MUTATOR_PATH}/example.c -a -e ${CUS test -e test-custom-mutator -a -e ${CUSTOM_MUTATOR_PATH}/libexamplemutator.so && { # Create input directory mkdir -p in - echo 00000 > in/in + echo "00000" > in/in # Run afl-fuzz w/ the C mutator $ECHO "$GREY[*] running afl-fuzz for the C mutator, this will take approx 10 seconds" @@ -915,7 +919,7 @@ test -e test-custom-mutator.c -a -e ${CUSTOM_MUTATOR_PATH}/example.c -a -e ${CUS } >>errors 2>&1 # Check results - test -n "$( ls out/queue/id:000001* 2>/dev/null )" && { # TODO: update here + test -n "$( ls out/crashes/id:000000* 2>/dev/null )" && { # TODO: update here $ECHO "$GREEN[+] afl-fuzz is working correctly with the C mutator" } || { echo CUT------------------------------------------------------------------CUT @@ -939,7 +943,7 @@ test -e test-custom-mutator.c -a -e ${CUSTOM_MUTATOR_PATH}/example.c -a -e ${CUS } >>errors 2>&1 # Check results - test -n "$( ls out/queue/id:000001* 2>/dev/null )" && { # TODO: update here + test -n "$( ls out/crashes/id:000000* 2>/dev/null )" && { # TODO: update here $ECHO "$GREEN[+] afl-fuzz is working correctly with the Python mutator" } || { echo CUT------------------------------------------------------------------CUT -- cgit 1.4.1 From 61ea39861271fd54a193a14d3adbb72c072df75f Mon Sep 17 00:00:00 2001 From: h1994st Date: Mon, 30 Mar 2020 05:21:01 -0400 Subject: Fix heap allocation bug - Reason: `afl->out_size` is not consistent with the actual allocation of `afl->out_buf`. The deleted line in `src/afl-fuzz-one.c` may change `afl->out_size`, but `afl->out_buf` is not changed --- examples/custom_mutators/example.c | 12 ++++++------ src/afl-fuzz-one.c | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'examples/custom_mutators') diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index 7d827029..ec47104d 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -159,13 +159,13 @@ size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, uint8_t *pre_save_buf = data->pre_save_buf; - memcpy(pre_save_buf + 5, buf, buf_size); + memcpy(pre_save_buf, buf, buf_size); size_t out_buf_size = buf_size + 5; - pre_save_buf[0] = 'A'; - pre_save_buf[1] = 'F'; - pre_save_buf[2] = 'L'; - pre_save_buf[3] = '+'; - pre_save_buf[4] = '+'; + pre_save_buf[buf_size + 0] = 'A'; + pre_save_buf[buf_size + 1] = 'F'; + pre_save_buf[buf_size + 2] = 'L'; + pre_save_buf[buf_size + 3] = '+'; + pre_save_buf[buf_size + 4] = '+'; *out_buf = pre_save_buf; diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index b1bbad0a..29dd73ad 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1621,8 +1621,6 @@ custom_mutator_stage: if (unlikely(!mutated_buf)) FATAL("Error in custom_fuzz. Size returned: %zd", mutated_size); - if (mutated_size > len) afl->out_size = mutated_size; - if (mutated_size > 0) { if (common_fuzz_stuff(afl, mutated_buf, (u32)mutated_size)) { @@ -1650,6 +1648,8 @@ custom_mutator_stage: } out_buf = ck_maybe_grow(BUF_PARAMS(out), len); + // ??? (h1994st): this line may be not necessary, as we do not modify the + // content of "out_buf". memcpy(out_buf, in_buf, len); } -- cgit 1.4.1 From c36c34cf9e3c7f34466efbb191100b6ae699091c Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Mon, 30 Mar 2020 16:38:51 +0200 Subject: fixed example --- examples/custom_mutators/example.c | 33 ++++++++++++--------------------- src/afl-fuzz-one.c | 6 ++---- 2 files changed, 14 insertions(+), 25 deletions(-) (limited to 'examples/custom_mutators') diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index ec47104d..c8200b26 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -142,34 +142,25 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size, uint8_t **out_buf) { - if (data->pre_save_size < buf_size + 5) { + uint8_t *pre_save_buf = maybe_grow(BUF_PARAMS(data, pre_save), buf_size + 5); + if (!pre_save_buf) { - data->pre_save_buf = maybe_grow(BUF_PARAMS(data, pre_save), buf_size + 5); - if (!data->pre_save_buf) { - - perror("custom mutator realloc failed."); - *out_buf = NULL; - return 0; - - } - - data->pre_save_size = buf_size + 5; + perror("custom mutator realloc failed."); + *out_buf = NULL; + return 0; } - uint8_t *pre_save_buf = data->pre_save_buf; - - memcpy(pre_save_buf, buf, buf_size); - size_t out_buf_size = buf_size + 5; - pre_save_buf[buf_size + 0] = 'A'; - pre_save_buf[buf_size + 1] = 'F'; - pre_save_buf[buf_size + 2] = 'L'; - pre_save_buf[buf_size + 3] = '+'; - pre_save_buf[buf_size + 4] = '+'; + memcpy(pre_save_buf + 5, buf, buf_size); + pre_save_buf[0] = 'A'; + pre_save_buf[1] = 'F'; + pre_save_buf[2] = 'L'; + pre_save_buf[3] = '+'; + pre_save_buf[4] = '+'; *out_buf = pre_save_buf; - return out_buf_size; + return buf_size + 5; } diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index c61c9084..2e49e19b 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1647,10 +1647,8 @@ custom_mutator_stage: } - /* `afl->out_buf` is actually not changed in the loop. Since `ck_maybe_grow` - is cheap, we still keep the following line but remove `memcpy`. */ - out_buf = ck_maybe_grow(BUF_PARAMS(out), len); - // memcpy(out_buf, in_buf, len); + /* `(afl->)out_buf` may have been changed by the call to custom_fuzz */ + memcpy(out_buf, in_buf, len); } -- cgit 1.4.1 From c8bdf0790f7d19078d9ec5705fc04eefd8615988 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Tue, 31 Mar 2020 14:01:22 +0200 Subject: reenabled custom mutator report --- examples/custom_mutators/Makefile | 2 +- llvm_mode/afl-clang-fast.c | 1 - src/afl-fuzz-one.c | 1 + test/test.sh | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) (limited to 'examples/custom_mutators') diff --git a/examples/custom_mutators/Makefile b/examples/custom_mutators/Makefile index 463cefb1..9849f3f4 100644 --- a/examples/custom_mutators/Makefile +++ b/examples/custom_mutators/Makefile @@ -1,7 +1,7 @@ all: libexamplemutator.so libexamplemutator.so: - $(CC) $(CFLAGS) -fPIC -shared -g -I ../../include example.c -o libexamplemutator.so + $(CC) $(CFLAGS) -D_FORTIFY_SOURCE=2 -O3 -fPIC -shared -g -I ../../include example.c -o libexamplemutator.so clean: rm -rf libexamplemutator.so diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index 99bc8d03..de8d3410 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -48,7 +48,6 @@ static u8 debug; static u8 cwd[4096]; static u8 cmplog_mode; u8 use_stdin = 0; /* dummy */ -u8 be_quiet = 0; u8 *getthecwd() { diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 2e49e19b..b20bde90 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1648,6 +1648,7 @@ custom_mutator_stage: } /* `(afl->)out_buf` may have been changed by the call to custom_fuzz */ + /* TODO: Only do this when `mutated_buf` == `out_buf`? Branch vs Memcpy. */ memcpy(out_buf, in_buf, len); } diff --git a/test/test.sh b/test/test.sh index 0dc58cc8..a04df384 100755 --- a/test/test.sh +++ b/test/test.sh @@ -961,7 +961,7 @@ test -e test-custom-mutator.c -a -e ${CUSTOM_MUTATOR_PATH}/example.c -a -e ${CUS CODE=1 } - test "$CODE" = 1 && { $ECHO "$YELLOW[!] custom mutator tests currently will not fail travis" ; CODE=0 ; } + #test "$CODE" = 1 && { $ECHO "$YELLOW[!] custom mutator tests currently will not fail travis" ; CODE=0 ; } make -C ../examples/custom_mutators clean > /dev/null 2>&1 rm -f test-custom-mutator -- cgit 1.4.1 From d374648ce3d106e5aaa95da379188df56d364e3c Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 1 Apr 2020 02:07:52 +0200 Subject: docs --- examples/README.md | 2 +- examples/custom_mutators/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'examples/custom_mutators') diff --git a/examples/README.md b/examples/README.md index 6c09caeb..3c5aa9f2 100644 --- a/examples/README.md +++ b/examples/README.md @@ -2,7 +2,7 @@ Here's a quick overview of the stuff you can find in this directory: - - custom_mutstors - An example custom mutator + - custom_mutators - example custom mutators in python an c - argv_fuzzing - a simple wrapper to allow cmdline to be fuzzed (e.g., to test setuid programs). diff --git a/examples/custom_mutators/README.md b/examples/custom_mutators/README.md index e5af5516..15c6ffc5 100644 --- a/examples/custom_mutators/README.md +++ b/examples/custom_mutators/README.md @@ -4,7 +4,7 @@ These are example and helper files for the custom mutator feature. See [docs/custom_mutators.md](../docs/custom_mutators.md) for more information Note that if you compile with python3.7 you must use python3 scripts, and if -you use pyton2.7 to compile python2 scripts! +you use python2.7 to compile python2 scripts! example.c - this is a simple example written in C and should be compiled to a shared library. Use make to compile it and produce libexamplemutator.so -- cgit 1.4.1 From 0565fe4213b96a778895799eb61743166be35a0d Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Thu, 2 Apr 2020 12:24:39 +0200 Subject: rename all 'Makefile' to 'GNUmakefile', use -Werror for -flto checks --- GNUmakefile | 477 +++++++++++++++++++++++++++ Makefile | 479 +--------------------------- examples/argv_fuzzing/GNUmakefile | 51 +++ examples/argv_fuzzing/Makefile | 53 +-- examples/custom_mutators/GNUmakefile | 7 + examples/custom_mutators/Makefile | 9 +- examples/socket_fuzzing/GNUmakefile | 48 +++ examples/socket_fuzzing/Makefile | 50 +-- gcc_plugin/GNUmakefile | 160 ++++++++++ gcc_plugin/Makefile | 162 +--------- libdislocator/GNUmakefile | 44 +++ libdislocator/Makefile | 46 +-- libtokencap/GNUmakefile | 63 ++++ libtokencap/Makefile | 65 +--- llvm_mode/GNUmakefile | 375 ++++++++++++++++++++++ llvm_mode/Makefile | 377 +--------------------- qemu_mode/libcompcov/GNUmakefile | 44 +++ qemu_mode/libcompcov/Makefile | 46 +-- qemu_mode/unsigaction/GNUmakefile | 34 ++ qemu_mode/unsigaction/Makefile | 34 +- src/third_party/libradamsa/GNUmakefile | 26 ++ src/third_party/libradamsa/Makefile | 28 +- unicorn_mode/samples/c/GNUmakefile | 42 +++ unicorn_mode/samples/c/Makefile | 44 +-- unicorn_mode/samples/persistent/GNUmakefile | 42 +++ unicorn_mode/samples/persistent/Makefile | 44 +-- 26 files changed, 1438 insertions(+), 1412 deletions(-) create mode 100644 GNUmakefile create mode 100644 examples/argv_fuzzing/GNUmakefile create mode 100644 examples/custom_mutators/GNUmakefile create mode 100644 examples/socket_fuzzing/GNUmakefile create mode 100644 gcc_plugin/GNUmakefile create mode 100644 libdislocator/GNUmakefile create mode 100644 libtokencap/GNUmakefile create mode 100644 llvm_mode/GNUmakefile create mode 100644 qemu_mode/libcompcov/GNUmakefile create mode 100644 qemu_mode/unsigaction/GNUmakefile create mode 100644 src/third_party/libradamsa/GNUmakefile create mode 100644 unicorn_mode/samples/c/GNUmakefile create mode 100644 unicorn_mode/samples/persistent/GNUmakefile (limited to 'examples/custom_mutators') diff --git a/GNUmakefile b/GNUmakefile new file mode 100644 index 00000000..8e0f0d97 --- /dev/null +++ b/GNUmakefile @@ -0,0 +1,477 @@ +# +# american fuzzy lop++ - makefile +# ----------------------------- +# +# Originally written by Michal Zalewski +# +# Copyright 2013, 2014, 2015, 2016, 2017 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# + +# For Heiko: +#TEST_MMAP=1 +# the hash character is treated differently in different make versions +# so use a variable for '#' +HASH=\# + +PREFIX ?= /usr/local +BIN_PATH = $(PREFIX)/bin +HELPER_PATH = $(PREFIX)/lib/afl +DOC_PATH = $(PREFIX)/share/doc/afl +MISC_PATH = $(PREFIX)/share/afl +MAN_PATH = $(PREFIX)/man/man8 + +PROGNAME = afl +VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2) + +# PROGS intentionally omit afl-as, which gets installed elsewhere. + +PROGS = afl-gcc afl-fuzz afl-showmap afl-tmin afl-gotcpu afl-analyze +SH_PROGS = afl-plot afl-cmin afl-cmin.bash afl-whatsup afl-system-config +MANPAGES=$(foreach p, $(PROGS) $(SH_PROGS), $(p).8) afl-as.8 +ASAN_OPTIONS=detect_leaks=0 + +ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -flto=full -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" + CFLAGS_FLTO ?= -flto=full +else + ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -flto=thin -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" + CFLAGS_FLTO ?= -flto=thin + else + ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -flto -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" + CFLAGS_FLTO ?= -flto + endif + endif +endif + +ifneq "$(shell uname)" "Darwin" + ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -march=native -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" + CFLAGS_OPT = -march=native + endif +endif + +ifneq "$(shell uname -m)" "x86_64" + ifneq "$(shell uname -m)" "i386" + ifneq "$(shell uname -m)" "amd64" + ifneq "$(shell uname -m)" "i86pc" + AFL_NO_X86=1 + endif + endif + endif +endif + +CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT) -D_FORTIFY_SOURCE=2 +override CFLAGS += -Wall -g -Wno-pointer-sign \ + -I include/ -Werror -DAFL_PATH=\"$(HELPER_PATH)\" \ + -DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\" + +AFL_FUZZ_FILES = $(wildcard src/afl-fuzz*.c) + +ifneq "$(shell type python3m 2>/dev/null)" "" + ifneq "$(shell type python3m-config 2>/dev/null)" "" + PYTHON_INCLUDE ?= $(shell python3m-config --includes) + PYTHON_VERSION ?= $(strip $(shell python3m --version 2>&1)) + # Starting with python3.8, we need to pass the `embed` flag. Earier versions didn't know this flag. + ifeq "$(shell python3m-config --embed --libs 2>/dev/null | grep -q lpython && echo 1 )" "1" + PYTHON_LIB ?= $(shell python3m-config --libs --embed) + else + PYTHON_LIB ?= $(shell python3m-config --ldflags) + endif + endif +endif + +ifneq "$(shell type python3 2>/dev/null)" "" + ifneq "$(shell type python3-config 2>/dev/null)" "" + PYTHON_INCLUDE ?= $(shell python3-config --includes) + PYTHON_VERSION ?= $(strip $(shell python3 --version 2>&1)) + # Starting with python3.8, we need to pass the `embed` flag. Earier versions didn't know this flag. + ifeq "$(shell python3-config --embed --libs 2>/dev/null | grep -q lpython && echo 1 )" "1" + PYTHON_LIB ?= $(shell python3-config --libs --embed) + else + PYTHON_LIB ?= $(shell python3-config --ldflags) + endif + endif +endif + +ifneq "$(shell type python 2>/dev/null)" "" + ifneq "$(shell type python-config 2>/dev/null)" "" + PYTHON_INCLUDE ?= $(shell python-config --includes) + PYTHON_LIB ?= $(shell python-config --ldflags) + PYTHON_VERSION ?= $(strip $(shell python --version 2>&1)) + endif +endif + +ifdef SOURCE_DATE_EPOCH + BUILD_DATE ?= $(shell date -u -d "@$(SOURCE_DATE_EPOCH)" "+%Y-%m-%d" 2>/dev/null || date -u -r "$(SOURCE_DATE_EPOCH)" "+%Y-%m-%d" 2>/dev/null || date -u "+%Y-%m-%d") +else + BUILD_DATE ?= $(shell date "+%Y-%m-%d") +endif + +ifneq "$(filter Linux GNU%,$(shell uname))" "" + LDFLAGS += -ldl +endif + +ifneq "$(findstring FreeBSD, $(shell uname))" "" + CFLAGS += -pthread + LDFLAGS += -lpthread +endif + +ifneq "$(findstring NetBSD, $(shell uname))" "" + CFLAGS += -pthread + LDFLAGS += -lpthread +endif + +ifeq "$(findstring clang, $(shell $(CC) --version 2>/dev/null))" "" + TEST_CC = afl-gcc +else + TEST_CC = afl-clang +endif + +COMM_HDR = include/alloc-inl.h include/config.h include/debug.h include/types.h + +ifeq "$(shell echo '$(HASH)include @int main() {return 0; }' | tr @ '\n' | $(CC) $(CFLAGS) -x c - -o .test $(PYTHON_INCLUDE) $(LDFLAGS) $(PYTHON_LIB) 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" + PYTHON_OK=1 + PYFLAGS=-DUSE_PYTHON $(PYTHON_INCLUDE) $(LDFLAGS) $(PYTHON_LIB) -DPYTHON_VERSION="\"$(PYTHON_VERSION)\"" +else + PYTHON_OK=0 + PYFLAGS= +endif + +ifdef STATIC + $(info Compiling static version of binaries) + # Disable python for static compilation to simplify things + PYTHON_OK=0 + PYFLAGS= + + CFLAGS += -static + LDFLAGS += -lm -lpthread -lz -lutil +endif + +ASAN_CFLAGS=-fsanitize=address -fstack-protector-all -fno-omit-frame-pointer +ASAN_LDFLAGS+=-fsanitize=address -fstack-protector-all -fno-omit-frame-pointer + +ifdef ASAN_BUILD + $(info Compiling ASAN version of binaries) + CFLAGS+=$(ASAN_CFLAGS) + LDFLAGS+=$(ASAN_LDFLAGS) +endif + +ifdef PROFILING + $(info Compiling profiling version of binaries) + CFLAGS+=-pg + LDFLAGS+=-pg +endif + +ifeq "$(shell echo '$(HASH)include @$(HASH)include @int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) $(CFLAGS) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1" + SHMAT_OK=1 +else + SHMAT_OK=0 + CFLAGS+=-DUSEMMAP=1 + LDFLAGS+=-Wno-deprecated-declarations +endif + +ifeq "$(TEST_MMAP)" "1" + SHMAT_OK=0 + CFLAGS+=-DUSEMMAP=1 + LDFLAGS+=-Wno-deprecated-declarations +endif + +all: test_x86 test_shm test_python ready $(PROGS) afl-as test_build all_done + +man: $(MANPAGES) + -$(MAKE) -C llvm_mode + -$(MAKE) -C gcc_plugin + +tests: source-only + @cd test ; ./test.sh + @rm -f test/errors + +performance-tests: performance-test +test-performance: performance-test + +performance-test: source-only + @cd test ; ./test-performance.sh + + +help: + @echo "HELP --- the following make targets exist:" + @echo "==========================================" + @echo "all: just the main afl++ binaries" + @echo "binary-only: everything for binary-only fuzzing: qemu_mode, unicorn_mode, libdislocator, libtokencap, radamsa" + @echo "source-only: everything for source code fuzzing: llvm_mode, gcc_plugin, libdislocator, libtokencap, radamsa" + @echo "distrib: everything (for both binary-only and source code fuzzing)" + @echo "man: creates simple man pages from the help option of the programs" + @echo "install: installs everything you have compiled with the build option above" + @echo "clean: cleans everything. for qemu_mode it means it deletes all downloads as well" + @echo "code-format: format the code, do this before you commit and send a PR please!" + @echo "tests: this runs the test framework. It is more catered for the developers, but if you run into problems this helps pinpointing the problem" + @echo "unit: perform unit tests (based on cmocka)" + @echo "document: creates afl-fuzz-document which will only do one run and save all manipulated inputs into out/queue/mutations" + @echo "help: shows these build options :-)" + @echo "==========================================" + @echo "Recommended: \"distrib\" or \"source-only\", then \"install\"" + @echo + @echo Known build environment options: + @echo "==========================================" + @echo STATIC - compile AFL++ static + @echo ASAN_BUILD - compiles with memory sanitizer for debug purposes + @echo PROFILING - compile afl-fuzz with profiling information + @echo AFL_NO_X86 - if compiling on non-intel/amd platforms + @echo "==========================================" + @echo e.g.: make ASAN_BUILD=1 + +ifndef AFL_NO_X86 + +test_x86: + @echo "[*] Checking for the default compiler cc..." + @type $(CC) >/dev/null || ( echo; echo "Oops, looks like there is no compiler '"$(CC)"' in your path."; echo; echo "Don't panic! You can restart with '"$(_)" CC='."; echo; exit 1 ) + @echo "[*] Checking for the ability to compile x86 code..." + @echo 'main() { __asm__("xorb %al, %al"); }' | $(CC) $(CFLAGS) -w -x c - -o .test1 || ( echo; echo "Oops, looks like your compiler can't generate x86 code."; echo; echo "Don't panic! You can use the LLVM or QEMU mode, but see docs/INSTALL first."; echo "(To ignore this error, set AFL_NO_X86=1 and try again.)"; echo; exit 1 ) + @rm -f .test1 + +else + +test_x86: + @echo "[!] Note: skipping x86 compilation checks (AFL_NO_X86 set)." + +endif + + +ifeq "$(SHMAT_OK)" "1" + +test_shm: + @echo "[+] shmat seems to be working." + @rm -f .test2 + +else + +test_shm: + @echo "[-] shmat seems not to be working, switching to mmap implementation" + +endif + + +ifeq "$(PYTHON_OK)" "1" + +test_python: + @rm -f .test 2> /dev/null + @echo "[+] $(PYTHON_VERSION) support seems to be working." + +else + +test_python: + @echo "[-] You seem to need to install the package python3-dev or python2-dev (and perhaps python[23]-apt), but it is optional so we continue" + +endif + + +ready: + @echo "[+] Everything seems to be working, ready to compile." + +afl-gcc: src/afl-gcc.c $(COMM_HDR) | test_x86 + $(CC) $(CFLAGS) src/$@.c -o $@ $(LDFLAGS) + set -e; for i in afl-g++ afl-clang afl-clang++; do ln -sf afl-gcc $$i; done + +afl-as: src/afl-as.c include/afl-as.h $(COMM_HDR) | test_x86 + $(CC) $(CFLAGS) src/$@.c -o $@ $(LDFLAGS) + ln -sf afl-as as + +src/afl-common.o : $(COMM_HDR) src/afl-common.c include/common.h + $(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-common.c -o src/afl-common.o + +src/afl-forkserver.o : $(COMM_HDR) src/afl-forkserver.c include/forkserver.h + $(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-forkserver.c -o src/afl-forkserver.o + +src/afl-sharedmem.o : $(COMM_HDR) src/afl-sharedmem.c include/sharedmem.h + $(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-sharedmem.c -o src/afl-sharedmem.o + +radamsa: src/third_party/libradamsa/libradamsa.so + cp src/third_party/libradamsa/libradamsa.so . + +src/third_party/libradamsa/libradamsa.so: src/third_party/libradamsa/libradamsa.c src/third_party/libradamsa/radamsa.h + $(MAKE) -C src/third_party/libradamsa/ CFLAGS="$(CFLAGS)" + +afl-fuzz: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o | test_x86 + $(CC) $(CFLAGS) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(PYFLAGS) $(LDFLAGS) + +afl-showmap: src/afl-showmap.c src/afl-common.o src/afl-sharedmem.o $(COMM_HDR) | test_x86 + $(CC) $(CFLAGS) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(LDFLAGS) + +afl-tmin: src/afl-tmin.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o $(COMM_HDR) | test_x86 + $(CC) $(CFLAGS) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(LDFLAGS) + +afl-analyze: src/afl-analyze.c src/afl-common.o src/afl-sharedmem.o $(COMM_HDR) | test_x86 + $(CC) $(CFLAGS) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o -o $@ $(LDFLAGS) + +afl-gotcpu: src/afl-gotcpu.c src/afl-common.o $(COMM_HDR) | test_x86 + $(CC) $(CFLAGS) src/$@.c src/afl-common.o -o $@ $(LDFLAGS) + + +# document all mutations and only do one run (use with only one input file!) +document: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o | test_x86 + $(CC) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o afl-fuzz-document $(PYFLAGS) $(LDFLAGS) + +test/unittests/unit_maybe_alloc.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_maybe_alloc.c $(AFL_FUZZ_FILES) + $(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_maybe_alloc.c -o test/unittests/unit_maybe_alloc.o + +test/unittests/unit_preallocable.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_preallocable.c $(AFL_FUZZ_FILES) + $(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_preallocable.c -o test/unittests/unit_preallocable.o + +unit_maybe_alloc: test/unittests/unit_maybe_alloc.o + $(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_maybe_alloc.o -o test/unittests/unit_maybe_alloc $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka + ./test/unittests/unit_maybe_alloc + +test/unittests/unit_list.o : $(COMM_HDR) include/list.h test/unittests/unit_list.c $(AFL_FUZZ_FILES) + $(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_list.c -o test/unittests/unit_list.o + +unit_list: test/unittests/unit_list.o + $(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_list.o -o test/unittests/unit_list $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka + ./test/unittests/unit_list + +test/unittests/preallocable.o : $(COMM_HDR) include/afl-prealloc.h test/unittests/preallocable.c $(AFL_FUZZ_FILES) + $(CC) $(CFLAGS) $(ASAN_CFLAGS) $(CFLAGS_FLTO) -c test/unittests/preallocable.c -o test/unittests/preallocable.o + +unit_preallocable: test/unittests/unit_preallocable.o + $(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_preallocable.o -o test/unittests/unit_preallocable $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka + ./test/unittests/unit_preallocable + +unit: unit_maybe_alloc unit_preallocable unit_list + +code-format: + ./.custom-format.py -i src/*.c + ./.custom-format.py -i include/*.h + ./.custom-format.py -i libdislocator/*.c + ./.custom-format.py -i libtokencap/*.c + ./.custom-format.py -i llvm_mode/*.c + ./.custom-format.py -i llvm_mode/*.h + ./.custom-format.py -i llvm_mode/*.cc + ./.custom-format.py -i gcc_plugin/*.c + #./.custom-format.py -i gcc_plugin/*.h + ./.custom-format.py -i gcc_plugin/*.cc + ./.custom-format.py -i examples/*/*.c + ./.custom-format.py -i examples/*/*.h + ./.custom-format.py -i qemu_mode/patches/*.h + ./.custom-format.py -i qemu_mode/libcompcov/*.c + ./.custom-format.py -i qemu_mode/libcompcov/*.cc + ./.custom-format.py -i qemu_mode/libcompcov/*.h + ./.custom-format.py -i qbdi_mode/*.c + ./.custom-format.py -i qbdi_mode/*.cpp + ./.custom-format.py -i *.h + ./.custom-format.py -i *.c + + +ifndef AFL_NO_X86 + +test_build: afl-gcc afl-as afl-showmap + @echo "[*] Testing the CC wrapper and instrumentation output..." + @unset AFL_USE_ASAN AFL_USE_MSAN AFL_CC; AFL_DEBUG=1 AFL_INST_RATIO=100 AFL_PATH=. ./$(TEST_CC) $(CFLAGS) test-instr.c -o test-instr $(LDFLAGS) 2>&1 | grep 'afl-as' >/dev/null || (echo "Oops, afl-as did not get called from "$(TEST_CC)". This is normally achieved by "$(CC)" honoring the -B option."; exit 1 ) + ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null + echo 1 | ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr1 ./test-instr + @rm -f test-instr + @cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation does not seem to be behaving correctly!"; echo; echo "Please post to https://github.com/AFLplusplus/AFLplusplus/issues to troubleshoot the issue."; echo; exit 1; fi + @echo "[+] All right, the instrumentation seems to be working!" + +else + +test_build: afl-gcc afl-as afl-showmap + @echo "[!] Note: skipping build tests (you may need to use LLVM or QEMU mode)." + +endif + + +all_done: test_build + @if [ ! "`type clang 2>/dev/null`" = "" ]; then echo "[+] LLVM users: see llvm_mode/README.md for a faster alternative to afl-gcc."; fi + @echo "[+] All done! Be sure to review the README.md - it's pretty short and useful." + @if [ "`uname`" = "Darwin" ]; then printf "\nWARNING: Fuzzing on MacOS X is slow because of the unusually high overhead of\nfork() on this OS. Consider using Linux or *BSD. You can also use VirtualBox\n(virtualbox.org) to put AFL inside a Linux or *BSD VM.\n\n"; fi + @! tty <&1 >/dev/null || printf "\033[0;30mNOTE: If you can read this, your terminal probably uses white background.\nThis will make the UI hard to read. See docs/status_screen.md for advice.\033[0m\n" 2>/dev/null + +.NOTPARALLEL: clean + +clean: + rm -f $(PROGS) libradamsa.so afl-fuzz-document afl-as as afl-g++ afl-clang afl-clang++ *.o src/*.o *~ a.out core core.[1-9][0-9]* *.stackdump .test .test1 .test2 test-instr .test-instr0 .test-instr1 qemu_mode/qemu-3.1.1.tar.xz afl-qemu-trace afl-gcc-fast afl-gcc-pass.so afl-gcc-rt.o afl-g++-fast ld *.so *.8 test/unittests/*.o test/unittests/unit_maybe_alloc test/unittests/preallocable + rm -rf out_dir qemu_mode/qemu-3.1.1 *.dSYM */*.dSYM + -$(MAKE) -C llvm_mode clean + -$(MAKE) -C gcc_plugin clean + $(MAKE) -C libdislocator clean + $(MAKE) -C libtokencap clean + $(MAKE) -C examples/socket_fuzzing clean + $(MAKE) -C examples/argv_fuzzing clean + $(MAKE) -C qemu_mode/unsigaction clean + $(MAKE) -C qemu_mode/libcompcov clean + $(MAKE) -C src/third_party/libradamsa/ clean + -rm -rf unicorn_mode/unicornafl + +distrib: all radamsa + -$(MAKE) -C llvm_mode + -$(MAKE) -C gcc_plugin + $(MAKE) -C libdislocator + $(MAKE) -C libtokencap + $(MAKE) -C examples/socket_fuzzing + $(MAKE) -C examples/argv_fuzzing + cd qemu_mode && sh ./build_qemu_support.sh + cd unicorn_mode && sh ./build_unicorn_support.sh + +binary-only: all radamsa + $(MAKE) -C libdislocator + $(MAKE) -C libtokencap + $(MAKE) -C examples/socket_fuzzing + $(MAKE) -C examples/argv_fuzzing + cd qemu_mode && sh ./build_qemu_support.sh + cd unicorn_mode && sh ./build_unicorn_support.sh + +source-only: all radamsa + -$(MAKE) -C llvm_mode + -$(MAKE) -C gcc_plugin + $(MAKE) -C libdislocator + $(MAKE) -C libtokencap + +%.8: % + @echo .TH $* 8 $(BUILD_DATE) "afl++" > $@ + @echo .SH NAME >> $@ + @echo .B $* >> $@ + @echo >> $@ + @echo .SH SYNOPSIS >> $@ + @./$* -h 2>&1 | head -n 3 | tail -n 1 | sed 's/^\.\///' >> $@ + @echo >> $@ + @echo .SH OPTIONS >> $@ + @echo .nf >> $@ + @./$* -hh 2>&1 | tail -n +4 >> $@ + @echo >> $@ + @echo .SH AUTHOR >> $@ + @echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Heiko \"hexcoder-\" Eissfeldt , Andrea Fioraldi and Dominik Maier " >> $@ + @echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> $@ + @echo >> $@ + @echo .SH LICENSE >> $@ + @echo Apache License Version 2.0, January 2004 >> $@ + +install: all $(MANPAGES) + install -d -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH) + rm -f $${DESTDIR}$(BIN_PATH)/afl-plot.sh + install -m 755 $(PROGS) $(SH_PROGS) $${DESTDIR}$(BIN_PATH) + rm -f $${DESTDIR}$(BIN_PATH)/afl-as + if [ -f afl-qemu-trace ]; then install -m 755 afl-qemu-trace $${DESTDIR}$(BIN_PATH); fi + if [ -f afl-gcc-fast ]; then set e; install -m 755 afl-gcc-fast $${DESTDIR}$(BIN_PATH); ln -sf afl-gcc-fast $${DESTDIR}$(BIN_PATH)/afl-g++-fast; install -m 755 afl-gcc-pass.so afl-gcc-rt.o $${DESTDIR}$(HELPER_PATH); fi + $(MAKE) -C llvm_mode install + if [ -f libdislocator.so ]; then set -e; install -m 755 libdislocator.so $${DESTDIR}$(HELPER_PATH); fi + if [ -f libtokencap.so ]; then set -e; install -m 755 libtokencap.so $${DESTDIR}$(HELPER_PATH); fi + if [ -f libcompcov.so ]; then set -e; install -m 755 libcompcov.so $${DESTDIR}$(HELPER_PATH); fi + if [ -f libradamsa.so ]; then set -e; install -m 755 libradamsa.so $${DESTDIR}$(HELPER_PATH); fi + if [ -f afl-fuzz-document ]; then set -e; install -m 755 afl-fuzz-document $${DESTDIR}$(BIN_PATH); fi + $(MAKE) -C examples/socket_fuzzing install + $(MAKE) -C examples/argv_fuzzing install + + set -e; ln -sf afl-gcc $${DESTDIR}$(BIN_PATH)/afl-g++ + set -e; if [ -f afl-clang-fast ] ; then ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang++ ; else ln -sf afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang++; fi + + mkdir -m 0755 -p ${DESTDIR}$(MAN_PATH) + install -m0644 *.8 ${DESTDIR}$(MAN_PATH) + + install -m 755 afl-as $${DESTDIR}$(HELPER_PATH) + ln -sf afl-as $${DESTDIR}$(HELPER_PATH)/as + install -m 644 docs/*.md $${DESTDIR}$(DOC_PATH) + cp -r testcases/ $${DESTDIR}$(MISC_PATH) + cp -r dictionaries/ $${DESTDIR}$(MISC_PATH) diff --git a/Makefile b/Makefile index cb4bc653..0b306dde 100644 --- a/Makefile +++ b/Makefile @@ -1,477 +1,2 @@ -# -# american fuzzy lop++ - makefile -# ----------------------------- -# -# Originally written by Michal Zalewski -# -# Copyright 2013, 2014, 2015, 2016, 2017 Google Inc. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# - -# For Heiko: -#TEST_MMAP=1 -# the hash character is treated differently in different make versions -# so use a variable for '#' -HASH=\# - -PREFIX ?= /usr/local -BIN_PATH = $(PREFIX)/bin -HELPER_PATH = $(PREFIX)/lib/afl -DOC_PATH = $(PREFIX)/share/doc/afl -MISC_PATH = $(PREFIX)/share/afl -MAN_PATH = $(PREFIX)/man/man8 - -PROGNAME = afl -VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2) - -# PROGS intentionally omit afl-as, which gets installed elsewhere. - -PROGS = afl-gcc afl-fuzz afl-showmap afl-tmin afl-gotcpu afl-analyze -SH_PROGS = afl-plot afl-cmin afl-cmin.bash afl-whatsup afl-system-config -MANPAGES=$(foreach p, $(PROGS) $(SH_PROGS), $(p).8) afl-as.8 -ASAN_OPTIONS=detect_leaks=0 - -ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -x c - -flto=full -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" - CFLAGS_FLTO ?= -flto=full -else - ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -x c - -flto=thin -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" - CFLAGS_FLTO ?= -flto=thin - else - ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -x c - -flto -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" - CFLAGS_FLTO ?= -flto - endif - endif -endif - -ifneq "$(shell uname)" "Darwin" - ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -x c - -march=native -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" - CFLAGS_OPT = -march=native - endif -endif - -ifneq "$(shell uname -m)" "x86_64" - ifneq "$(shell uname -m)" "i386" - ifneq "$(shell uname -m)" "amd64" - ifneq "$(shell uname -m)" "i86pc" - AFL_NO_X86=1 - endif - endif - endif -endif - -CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT) -D_FORTIFY_SOURCE=2 -override CFLAGS += -Wall -g -Wno-pointer-sign \ - -I include/ -Werror -DAFL_PATH=\"$(HELPER_PATH)\" \ - -DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\" - -AFL_FUZZ_FILES = $(wildcard src/afl-fuzz*.c) - -ifneq "$(shell type python3m 2>/dev/null)" "" - ifneq "$(shell type python3m-config 2>/dev/null)" "" - PYTHON_INCLUDE ?= $(shell python3m-config --includes) - PYTHON_VERSION ?= $(strip $(shell python3m --version 2>&1)) - # Starting with python3.8, we need to pass the `embed` flag. Earier versions didn't know this flag. - ifeq "$(shell python3m-config --embed --libs 2>/dev/null | grep -q lpython && echo 1 )" "1" - PYTHON_LIB ?= $(shell python3m-config --libs --embed) - else - PYTHON_LIB ?= $(shell python3m-config --ldflags) - endif - endif -endif - -ifneq "$(shell type python3 2>/dev/null)" "" - ifneq "$(shell type python3-config 2>/dev/null)" "" - PYTHON_INCLUDE ?= $(shell python3-config --includes) - PYTHON_VERSION ?= $(strip $(shell python3 --version 2>&1)) - # Starting with python3.8, we need to pass the `embed` flag. Earier versions didn't know this flag. - ifeq "$(shell python3-config --embed --libs 2>/dev/null | grep -q lpython && echo 1 )" "1" - PYTHON_LIB ?= $(shell python3-config --libs --embed) - else - PYTHON_LIB ?= $(shell python3-config --ldflags) - endif - endif -endif - -ifneq "$(shell type python 2>/dev/null)" "" - ifneq "$(shell type python-config 2>/dev/null)" "" - PYTHON_INCLUDE ?= $(shell python-config --includes) - PYTHON_LIB ?= $(shell python-config --ldflags) - PYTHON_VERSION ?= $(strip $(shell python --version 2>&1)) - endif -endif - -ifdef SOURCE_DATE_EPOCH - BUILD_DATE ?= $(shell date -u -d "@$(SOURCE_DATE_EPOCH)" "+%Y-%m-%d" 2>/dev/null || date -u -r "$(SOURCE_DATE_EPOCH)" "+%Y-%m-%d" 2>/dev/null || date -u "+%Y-%m-%d") -else - BUILD_DATE ?= $(shell date "+%Y-%m-%d") -endif - -ifneq "$(filter Linux GNU%,$(shell uname))" "" - LDFLAGS += -ldl -endif - -ifneq "$(findstring FreeBSD, $(shell uname))" "" - CFLAGS += -pthread - LDFLAGS += -lpthread -endif - -ifneq "$(findstring NetBSD, $(shell uname))" "" - CFLAGS += -pthread - LDFLAGS += -lpthread -endif - -ifeq "$(findstring clang, $(shell $(CC) --version 2>/dev/null))" "" - TEST_CC = afl-gcc -else - TEST_CC = afl-clang -endif - -COMM_HDR = include/alloc-inl.h include/config.h include/debug.h include/types.h - -ifeq "$(shell echo '$(HASH)include @int main() {return 0; }' | tr @ '\n' | $(CC) $(CFLAGS) -x c - -o .test $(PYTHON_INCLUDE) $(LDFLAGS) $(PYTHON_LIB) 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" - PYTHON_OK=1 - PYFLAGS=-DUSE_PYTHON $(PYTHON_INCLUDE) $(LDFLAGS) $(PYTHON_LIB) -DPYTHON_VERSION="\"$(PYTHON_VERSION)\"" -else - PYTHON_OK=0 - PYFLAGS= -endif - -ifdef STATIC - $(info Compiling static version of binaries) - # Disable python for static compilation to simplify things - PYTHON_OK=0 - PYFLAGS= - - CFLAGS += -static - LDFLAGS += -lm -lpthread -lz -lutil -endif - -ASAN_CFLAGS=-fsanitize=address -fstack-protector-all -fno-omit-frame-pointer -ASAN_LDFLAGS+=-fsanitize=address -fstack-protector-all -fno-omit-frame-pointer - -ifdef ASAN_BUILD - $(info Compiling ASAN version of binaries) - CFLAGS+=$(ASAN_CFLAGS) - LDFLAGS+=$(ASAN_LDFLAGS) -endif - -ifdef PROFILING - $(info Compiling profiling version of binaries) - CFLAGS+=-pg - LDFLAGS+=-pg -endif - -ifeq "$(shell echo '$(HASH)include @$(HASH)include @int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) $(CFLAGS) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1" - SHMAT_OK=1 -else - SHMAT_OK=0 - CFLAGS+=-DUSEMMAP=1 - LDFLAGS+=-Wno-deprecated-declarations -endif - -ifeq "$(TEST_MMAP)" "1" - SHMAT_OK=0 - CFLAGS+=-DUSEMMAP=1 - LDFLAGS+=-Wno-deprecated-declarations -endif - -all: test_x86 test_shm test_python ready $(PROGS) afl-as test_build all_done - -man: $(MANPAGES) - -$(MAKE) -C llvm_mode - -$(MAKE) -C gcc_plugin - -tests: source-only - @cd test ; ./test.sh - @rm -f test/errors - -performance-tests: performance-test -test-performance: performance-test - -performance-test: source-only - @cd test ; ./test-performance.sh - - -help: - @echo "HELP --- the following make targets exist:" - @echo "==========================================" - @echo "all: just the main afl++ binaries" - @echo "binary-only: everything for binary-only fuzzing: qemu_mode, unicorn_mode, libdislocator, libtokencap, radamsa" - @echo "source-only: everything for source code fuzzing: llvm_mode, gcc_plugin, libdislocator, libtokencap, radamsa" - @echo "distrib: everything (for both binary-only and source code fuzzing)" - @echo "man: creates simple man pages from the help option of the programs" - @echo "install: installs everything you have compiled with the build option above" - @echo "clean: cleans everything. for qemu_mode it means it deletes all downloads as well" - @echo "code-format: format the code, do this before you commit and send a PR please!" - @echo "tests: this runs the test framework. It is more catered for the developers, but if you run into problems this helps pinpointing the problem" - @echo "unit: perform unit tests (based on cmocka)" - @echo "document: creates afl-fuzz-document which will only do one run and save all manipulated inputs into out/queue/mutations" - @echo "help: shows these build options :-)" - @echo "==========================================" - @echo "Recommended: \"distrib\" or \"source-only\", then \"install\"" - @echo - @echo Known build environment options: - @echo "==========================================" - @echo STATIC - compile AFL++ static - @echo ASAN_BUILD - compiles with memory sanitizer for debug purposes - @echo PROFILING - compile afl-fuzz with profiling information - @echo AFL_NO_X86 - if compiling on non-intel/amd platforms - @echo "==========================================" - @echo e.g.: make ASAN_BUILD=1 - -ifndef AFL_NO_X86 - -test_x86: - @echo "[*] Checking for the default compiler cc..." - @type $(CC) >/dev/null || ( echo; echo "Oops, looks like there is no compiler '"$(CC)"' in your path."; echo; echo "Don't panic! You can restart with '"$(_)" CC='."; echo; exit 1 ) - @echo "[*] Checking for the ability to compile x86 code..." - @echo 'main() { __asm__("xorb %al, %al"); }' | $(CC) $(CFLAGS) -w -x c - -o .test1 || ( echo; echo "Oops, looks like your compiler can't generate x86 code."; echo; echo "Don't panic! You can use the LLVM or QEMU mode, but see docs/INSTALL first."; echo "(To ignore this error, set AFL_NO_X86=1 and try again.)"; echo; exit 1 ) - @rm -f .test1 - -else - -test_x86: - @echo "[!] Note: skipping x86 compilation checks (AFL_NO_X86 set)." - -endif - - -ifeq "$(SHMAT_OK)" "1" - -test_shm: - @echo "[+] shmat seems to be working." - @rm -f .test2 - -else - -test_shm: - @echo "[-] shmat seems not to be working, switching to mmap implementation" - -endif - - -ifeq "$(PYTHON_OK)" "1" - -test_python: - @rm -f .test 2> /dev/null - @echo "[+] $(PYTHON_VERSION) support seems to be working." - -else - -test_python: - @echo "[-] You seem to need to install the package python3-dev or python2-dev (and perhaps python[23]-apt), but it is optional so we continue" - -endif - - -ready: - @echo "[+] Everything seems to be working, ready to compile." - -afl-gcc: src/afl-gcc.c $(COMM_HDR) | test_x86 - $(CC) $(CFLAGS) src/$@.c -o $@ $(LDFLAGS) - set -e; for i in afl-g++ afl-clang afl-clang++; do ln -sf afl-gcc $$i; done - -afl-as: src/afl-as.c include/afl-as.h $(COMM_HDR) | test_x86 - $(CC) $(CFLAGS) src/$@.c -o $@ $(LDFLAGS) - ln -sf afl-as as - -src/afl-common.o : $(COMM_HDR) src/afl-common.c include/common.h - $(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-common.c -o src/afl-common.o - -src/afl-forkserver.o : $(COMM_HDR) src/afl-forkserver.c include/forkserver.h - $(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-forkserver.c -o src/afl-forkserver.o - -src/afl-sharedmem.o : $(COMM_HDR) src/afl-sharedmem.c include/sharedmem.h - $(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-sharedmem.c -o src/afl-sharedmem.o - -radamsa: src/third_party/libradamsa/libradamsa.so - cp src/third_party/libradamsa/libradamsa.so . - -src/third_party/libradamsa/libradamsa.so: src/third_party/libradamsa/libradamsa.c src/third_party/libradamsa/radamsa.h - $(MAKE) -C src/third_party/libradamsa/ CFLAGS="$(CFLAGS)" - -afl-fuzz: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o | test_x86 - $(CC) $(CFLAGS) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(PYFLAGS) $(LDFLAGS) - -afl-showmap: src/afl-showmap.c src/afl-common.o src/afl-sharedmem.o $(COMM_HDR) | test_x86 - $(CC) $(CFLAGS) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(LDFLAGS) - -afl-tmin: src/afl-tmin.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o $(COMM_HDR) | test_x86 - $(CC) $(CFLAGS) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(LDFLAGS) - -afl-analyze: src/afl-analyze.c src/afl-common.o src/afl-sharedmem.o $(COMM_HDR) | test_x86 - $(CC) $(CFLAGS) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o -o $@ $(LDFLAGS) - -afl-gotcpu: src/afl-gotcpu.c src/afl-common.o $(COMM_HDR) | test_x86 - $(CC) $(CFLAGS) src/$@.c src/afl-common.o -o $@ $(LDFLAGS) - - -# document all mutations and only do one run (use with only one input file!) -document: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o | test_x86 - $(CC) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o afl-fuzz-document $(PYFLAGS) $(LDFLAGS) - -test/unittests/unit_maybe_alloc.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_maybe_alloc.c $(AFL_FUZZ_FILES) - $(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_maybe_alloc.c -o test/unittests/unit_maybe_alloc.o - -test/unittests/unit_preallocable.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_preallocable.c $(AFL_FUZZ_FILES) - $(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_preallocable.c -o test/unittests/unit_preallocable.o - -unit_maybe_alloc: test/unittests/unit_maybe_alloc.o - $(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_maybe_alloc.o -o test/unittests/unit_maybe_alloc $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka - ./test/unittests/unit_maybe_alloc - -test/unittests/unit_list.o : $(COMM_HDR) include/list.h test/unittests/unit_list.c $(AFL_FUZZ_FILES) - $(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_list.c -o test/unittests/unit_list.o - -unit_list: test/unittests/unit_list.o - $(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_list.o -o test/unittests/unit_list $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka - ./test/unittests/unit_list - -test/unittests/preallocable.o : $(COMM_HDR) include/afl-prealloc.h test/unittests/preallocable.c $(AFL_FUZZ_FILES) - $(CC) $(CFLAGS) $(ASAN_CFLAGS) $(CFLAGS_FLTO) -c test/unittests/preallocable.c -o test/unittests/preallocable.o - -unit_preallocable: test/unittests/unit_preallocable.o - $(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_preallocable.o -o test/unittests/unit_preallocable $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka - ./test/unittests/unit_preallocable - -unit: unit_maybe_alloc unit_preallocable unit_list - -code-format: - ./.custom-format.py -i src/*.c - ./.custom-format.py -i include/*.h - ./.custom-format.py -i libdislocator/*.c - ./.custom-format.py -i libtokencap/*.c - ./.custom-format.py -i llvm_mode/*.c - ./.custom-format.py -i llvm_mode/*.h - ./.custom-format.py -i llvm_mode/*.cc - ./.custom-format.py -i gcc_plugin/*.c - #./.custom-format.py -i gcc_plugin/*.h - ./.custom-format.py -i gcc_plugin/*.cc - ./.custom-format.py -i examples/*/*.c - ./.custom-format.py -i examples/*/*.h - ./.custom-format.py -i qemu_mode/patches/*.h - ./.custom-format.py -i qemu_mode/libcompcov/*.c - ./.custom-format.py -i qemu_mode/libcompcov/*.cc - ./.custom-format.py -i qemu_mode/libcompcov/*.h - ./.custom-format.py -i qbdi_mode/*.c - ./.custom-format.py -i qbdi_mode/*.cpp - ./.custom-format.py -i *.h - ./.custom-format.py -i *.c - - -ifndef AFL_NO_X86 - -test_build: afl-gcc afl-as afl-showmap - @echo "[*] Testing the CC wrapper and instrumentation output..." - @unset AFL_USE_ASAN AFL_USE_MSAN AFL_CC; AFL_DEBUG=1 AFL_INST_RATIO=100 AFL_PATH=. ./$(TEST_CC) $(CFLAGS) test-instr.c -o test-instr $(LDFLAGS) 2>&1 | grep 'afl-as' >/dev/null || (echo "Oops, afl-as did not get called from "$(TEST_CC)". This is normally achieved by "$(CC)" honoring the -B option."; exit 1 ) - ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null - echo 1 | ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr1 ./test-instr - @rm -f test-instr - @cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation does not seem to be behaving correctly!"; echo; echo "Please post to https://github.com/AFLplusplus/AFLplusplus/issues to troubleshoot the issue."; echo; exit 1; fi - @echo "[+] All right, the instrumentation seems to be working!" - -else - -test_build: afl-gcc afl-as afl-showmap - @echo "[!] Note: skipping build tests (you may need to use LLVM or QEMU mode)." - -endif - - -all_done: test_build - @if [ ! "`type clang 2>/dev/null`" = "" ]; then echo "[+] LLVM users: see llvm_mode/README.md for a faster alternative to afl-gcc."; fi - @echo "[+] All done! Be sure to review the README.md - it's pretty short and useful." - @if [ "`uname`" = "Darwin" ]; then printf "\nWARNING: Fuzzing on MacOS X is slow because of the unusually high overhead of\nfork() on this OS. Consider using Linux or *BSD. You can also use VirtualBox\n(virtualbox.org) to put AFL inside a Linux or *BSD VM.\n\n"; fi - @! tty <&1 >/dev/null || printf "\033[0;30mNOTE: If you can read this, your terminal probably uses white background.\nThis will make the UI hard to read. See docs/status_screen.md for advice.\033[0m\n" 2>/dev/null - -.NOTPARALLEL: clean - -clean: - rm -f $(PROGS) libradamsa.so afl-fuzz-document afl-as as afl-g++ afl-clang afl-clang++ *.o src/*.o *~ a.out core core.[1-9][0-9]* *.stackdump .test .test1 .test2 test-instr .test-instr0 .test-instr1 qemu_mode/qemu-3.1.1.tar.xz afl-qemu-trace afl-gcc-fast afl-gcc-pass.so afl-gcc-rt.o afl-g++-fast ld *.so *.8 test/unittests/*.o test/unittests/unit_maybe_alloc test/unittests/preallocable - rm -rf out_dir qemu_mode/qemu-3.1.1 *.dSYM */*.dSYM - -$(MAKE) -C llvm_mode clean - -$(MAKE) -C gcc_plugin clean - $(MAKE) -C libdislocator clean - $(MAKE) -C libtokencap clean - $(MAKE) -C examples/socket_fuzzing clean - $(MAKE) -C examples/argv_fuzzing clean - $(MAKE) -C qemu_mode/unsigaction clean - $(MAKE) -C qemu_mode/libcompcov clean - $(MAKE) -C src/third_party/libradamsa/ clean - -rm -rf unicorn_mode/unicornafl - -distrib: all radamsa - -$(MAKE) -C llvm_mode - -$(MAKE) -C gcc_plugin - $(MAKE) -C libdislocator - $(MAKE) -C libtokencap - $(MAKE) -C examples/socket_fuzzing - $(MAKE) -C examples/argv_fuzzing - cd qemu_mode && sh ./build_qemu_support.sh - cd unicorn_mode && sh ./build_unicorn_support.sh - -binary-only: all radamsa - $(MAKE) -C libdislocator - $(MAKE) -C libtokencap - $(MAKE) -C examples/socket_fuzzing - $(MAKE) -C examples/argv_fuzzing - cd qemu_mode && sh ./build_qemu_support.sh - cd unicorn_mode && sh ./build_unicorn_support.sh - -source-only: all radamsa - -$(MAKE) -C llvm_mode - -$(MAKE) -C gcc_plugin - $(MAKE) -C libdislocator - $(MAKE) -C libtokencap - -%.8: % - @echo .TH $* 8 $(BUILD_DATE) "afl++" > $@ - @echo .SH NAME >> $@ - @echo .B $* >> $@ - @echo >> $@ - @echo .SH SYNOPSIS >> $@ - @./$* -h 2>&1 | head -n 3 | tail -n 1 | sed 's/^\.\///' >> $@ - @echo >> $@ - @echo .SH OPTIONS >> $@ - @echo .nf >> $@ - @./$* -hh 2>&1 | tail -n +4 >> $@ - @echo >> $@ - @echo .SH AUTHOR >> $@ - @echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Heiko \"hexcoder-\" Eissfeldt , Andrea Fioraldi and Dominik Maier " >> $@ - @echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> $@ - @echo >> $@ - @echo .SH LICENSE >> $@ - @echo Apache License Version 2.0, January 2004 >> $@ - -install: all $(MANPAGES) - install -d -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH) - rm -f $${DESTDIR}$(BIN_PATH)/afl-plot.sh - install -m 755 $(PROGS) $(SH_PROGS) $${DESTDIR}$(BIN_PATH) - rm -f $${DESTDIR}$(BIN_PATH)/afl-as - if [ -f afl-qemu-trace ]; then install -m 755 afl-qemu-trace $${DESTDIR}$(BIN_PATH); fi - if [ -f afl-gcc-fast ]; then set e; install -m 755 afl-gcc-fast $${DESTDIR}$(BIN_PATH); ln -sf afl-gcc-fast $${DESTDIR}$(BIN_PATH)/afl-g++-fast; install -m 755 afl-gcc-pass.so afl-gcc-rt.o $${DESTDIR}$(HELPER_PATH); fi - $(MAKE) -C llvm_mode install - if [ -f libdislocator.so ]; then set -e; install -m 755 libdislocator.so $${DESTDIR}$(HELPER_PATH); fi - if [ -f libtokencap.so ]; then set -e; install -m 755 libtokencap.so $${DESTDIR}$(HELPER_PATH); fi - if [ -f libcompcov.so ]; then set -e; install -m 755 libcompcov.so $${DESTDIR}$(HELPER_PATH); fi - if [ -f libradamsa.so ]; then set -e; install -m 755 libradamsa.so $${DESTDIR}$(HELPER_PATH); fi - if [ -f afl-fuzz-document ]; then set -e; install -m 755 afl-fuzz-document $${DESTDIR}$(BIN_PATH); fi - $(MAKE) -C examples/socket_fuzzing install - $(MAKE) -C examples/argv_fuzzing install - - set -e; ln -sf afl-gcc $${DESTDIR}$(BIN_PATH)/afl-g++ - set -e; if [ -f afl-clang-fast ] ; then ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang++ ; else ln -sf afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang++; fi - - mkdir -m 0755 -p ${DESTDIR}$(MAN_PATH) - install -m0644 *.8 ${DESTDIR}$(MAN_PATH) - - install -m 755 afl-as $${DESTDIR}$(HELPER_PATH) - ln -sf afl-as $${DESTDIR}$(HELPER_PATH)/as - install -m 644 docs/*.md $${DESTDIR}$(DOC_PATH) - cp -r testcases/ $${DESTDIR}$(MISC_PATH) - cp -r dictionaries/ $${DESTDIR}$(MISC_PATH) +all: + @echo please use GNU make, thanks! diff --git a/examples/argv_fuzzing/GNUmakefile b/examples/argv_fuzzing/GNUmakefile new file mode 100644 index 00000000..34192e39 --- /dev/null +++ b/examples/argv_fuzzing/GNUmakefile @@ -0,0 +1,51 @@ +# +# american fuzzy lop++ - argvfuzz +# -------------------------------- +# +# Copyright 2019-2020 Kjell Braden +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# + +.PHONY: all install clean + +PREFIX ?= /usr/local +BIN_PATH = $(PREFIX)/bin +HELPER_PATH = $(PREFIX)/lib/afl + +CFLAGS = -fPIC -Wall -Wextra +LDFLAGS = -shared + +ifneq "$(filter Linux GNU%,$(shell uname))" "" + LDFLAGS += -ldl +endif + +# on gcc for arm there is no -m32, but -mbe32 +M32FLAG = -m32 +M64FLAG = -m64 +ifeq "$(findstring clang, $(shell $(CC) --version 2>/dev/null))" "" + ifneq (,$(findstring arm, "$(shell $(CC) -v 2>&1 >/dev/null)")) + M32FLAG = -mbe32 + endif +endif + + +all: argvfuzz32.so argvfuzz64.so + +argvfuzz32.so: argvfuzz.c + -$(CC) $(M32FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ || echo "argvfuzz32 build failure (that's fine)" + +argvfuzz64.so: argvfuzz.c + -$(CC) $(M64FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ || echo "argvfuzz64 build failure (that's fine)" + +install: argvfuzz32.so argvfuzz64.so + install -d -m 755 $(DESTDIR)$(HELPER_PATH)/ + if [ -f argvfuzz32.so ]; then set -e; install -m 755 argvfuzz32.so $(DESTDIR)$(HELPER_PATH)/; fi + if [ -f argvfuzz64.so ]; then set -e; install -m 755 argvfuzz64.so $(DESTDIR)$(HELPER_PATH)/; fi + +clean: + rm -f argvfuzz32.so argvfuzz64.so diff --git a/examples/argv_fuzzing/Makefile b/examples/argv_fuzzing/Makefile index 34192e39..0b306dde 100644 --- a/examples/argv_fuzzing/Makefile +++ b/examples/argv_fuzzing/Makefile @@ -1,51 +1,2 @@ -# -# american fuzzy lop++ - argvfuzz -# -------------------------------- -# -# Copyright 2019-2020 Kjell Braden -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# - -.PHONY: all install clean - -PREFIX ?= /usr/local -BIN_PATH = $(PREFIX)/bin -HELPER_PATH = $(PREFIX)/lib/afl - -CFLAGS = -fPIC -Wall -Wextra -LDFLAGS = -shared - -ifneq "$(filter Linux GNU%,$(shell uname))" "" - LDFLAGS += -ldl -endif - -# on gcc for arm there is no -m32, but -mbe32 -M32FLAG = -m32 -M64FLAG = -m64 -ifeq "$(findstring clang, $(shell $(CC) --version 2>/dev/null))" "" - ifneq (,$(findstring arm, "$(shell $(CC) -v 2>&1 >/dev/null)")) - M32FLAG = -mbe32 - endif -endif - - -all: argvfuzz32.so argvfuzz64.so - -argvfuzz32.so: argvfuzz.c - -$(CC) $(M32FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ || echo "argvfuzz32 build failure (that's fine)" - -argvfuzz64.so: argvfuzz.c - -$(CC) $(M64FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ || echo "argvfuzz64 build failure (that's fine)" - -install: argvfuzz32.so argvfuzz64.so - install -d -m 755 $(DESTDIR)$(HELPER_PATH)/ - if [ -f argvfuzz32.so ]; then set -e; install -m 755 argvfuzz32.so $(DESTDIR)$(HELPER_PATH)/; fi - if [ -f argvfuzz64.so ]; then set -e; install -m 755 argvfuzz64.so $(DESTDIR)$(HELPER_PATH)/; fi - -clean: - rm -f argvfuzz32.so argvfuzz64.so +all: + @echo please use GNU make, thanks! diff --git a/examples/custom_mutators/GNUmakefile b/examples/custom_mutators/GNUmakefile new file mode 100644 index 00000000..9849f3f4 --- /dev/null +++ b/examples/custom_mutators/GNUmakefile @@ -0,0 +1,7 @@ +all: libexamplemutator.so + +libexamplemutator.so: + $(CC) $(CFLAGS) -D_FORTIFY_SOURCE=2 -O3 -fPIC -shared -g -I ../../include example.c -o libexamplemutator.so + +clean: + rm -rf libexamplemutator.so diff --git a/examples/custom_mutators/Makefile b/examples/custom_mutators/Makefile index 9849f3f4..0b306dde 100644 --- a/examples/custom_mutators/Makefile +++ b/examples/custom_mutators/Makefile @@ -1,7 +1,2 @@ -all: libexamplemutator.so - -libexamplemutator.so: - $(CC) $(CFLAGS) -D_FORTIFY_SOURCE=2 -O3 -fPIC -shared -g -I ../../include example.c -o libexamplemutator.so - -clean: - rm -rf libexamplemutator.so +all: + @echo please use GNU make, thanks! diff --git a/examples/socket_fuzzing/GNUmakefile b/examples/socket_fuzzing/GNUmakefile new file mode 100644 index 00000000..ad921664 --- /dev/null +++ b/examples/socket_fuzzing/GNUmakefile @@ -0,0 +1,48 @@ +# +# american fuzzy lop++ - socket_fuzz +# ---------------------------------- +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# + +.PHONY: all install clean + +PREFIX ?= /usr/local +BIN_PATH = $(PREFIX)/bin +HELPER_PATH = $(PREFIX)/lib/afl + +CFLAGS = -fPIC -Wall -Wextra +LDFLAGS = -shared + +ifneq "$(filter Linux GNU%,$(shell uname))" "" + LDFLAGS += -ldl +endif + +# on gcc for arm there is no -m32, but -mbe32 +M32FLAG = -m32 +M64FLAG = -m64 +ifeq "$(findstring clang, $(shell $(CC) --version 2>/dev/null))" "" + ifneq (,$(findstring arm, "$(shell $(CC) -v 2>&1 >/dev/null)")) + M32FLAG = -mbe32 + endif +endif + +all: socketfuzz32.so socketfuzz64.so + +socketfuzz32.so: socketfuzz.c + -$(CC) $(M32FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ || echo "socketfuzz32 build failure (that's fine)" + +socketfuzz64.so: socketfuzz.c + -$(CC) $(M64FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ || echo "socketfuzz64 build failure (that's fine)" + +install: socketfuzz32.so socketfuzz64.so + install -d -m 755 $(DESTDIR)$(HELPER_PATH)/ + if [ -f socketfuzz32.so ]; then set -e; install -m 755 socketfuzz32.so $(DESTDIR)$(HELPER_PATH)/; fi + if [ -f socketfuzz64.so ]; then set -e; install -m 755 socketfuzz64.so $(DESTDIR)$(HELPER_PATH)/; fi + +clean: + rm -f socketfuzz32.so socketfuzz64.so diff --git a/examples/socket_fuzzing/Makefile b/examples/socket_fuzzing/Makefile index ad921664..0b306dde 100644 --- a/examples/socket_fuzzing/Makefile +++ b/examples/socket_fuzzing/Makefile @@ -1,48 +1,2 @@ -# -# american fuzzy lop++ - socket_fuzz -# ---------------------------------- -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# - -.PHONY: all install clean - -PREFIX ?= /usr/local -BIN_PATH = $(PREFIX)/bin -HELPER_PATH = $(PREFIX)/lib/afl - -CFLAGS = -fPIC -Wall -Wextra -LDFLAGS = -shared - -ifneq "$(filter Linux GNU%,$(shell uname))" "" - LDFLAGS += -ldl -endif - -# on gcc for arm there is no -m32, but -mbe32 -M32FLAG = -m32 -M64FLAG = -m64 -ifeq "$(findstring clang, $(shell $(CC) --version 2>/dev/null))" "" - ifneq (,$(findstring arm, "$(shell $(CC) -v 2>&1 >/dev/null)")) - M32FLAG = -mbe32 - endif -endif - -all: socketfuzz32.so socketfuzz64.so - -socketfuzz32.so: socketfuzz.c - -$(CC) $(M32FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ || echo "socketfuzz32 build failure (that's fine)" - -socketfuzz64.so: socketfuzz.c - -$(CC) $(M64FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ || echo "socketfuzz64 build failure (that's fine)" - -install: socketfuzz32.so socketfuzz64.so - install -d -m 755 $(DESTDIR)$(HELPER_PATH)/ - if [ -f socketfuzz32.so ]; then set -e; install -m 755 socketfuzz32.so $(DESTDIR)$(HELPER_PATH)/; fi - if [ -f socketfuzz64.so ]; then set -e; install -m 755 socketfuzz64.so $(DESTDIR)$(HELPER_PATH)/; fi - -clean: - rm -f socketfuzz32.so socketfuzz64.so +all: + @echo please use GNU make, thanks! diff --git a/gcc_plugin/GNUmakefile b/gcc_plugin/GNUmakefile new file mode 100644 index 00000000..4c7a0313 --- /dev/null +++ b/gcc_plugin/GNUmakefile @@ -0,0 +1,160 @@ +# +# american fuzzy lop++ - GCC plugin instrumentation +# ----------------------------------------------- +# +# Written by Austin Seipp and +# Laszlo Szekeres and +# Michal Zalewski and +# Heiko Eißfeldt +# +# GCC integration design is based on the LLVM design, which comes +# from Laszlo Szekeres. +# +# Copyright 2015 Google Inc. All rights reserved. +# Copyright 2019-2020 AFLplusplus Project. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# + +PREFIX ?= /usr/local +HELPER_PATH ?= $(PREFIX)/lib/afl +BIN_PATH ?= $(PREFIX)/bin +DOC_PATH ?= $(PREFIX)/share/doc/afl +MAN_PATH ?= $(PREFIX)/man/man8 + +VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2) + +CFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=2 +override CFLAGS = -Wall -I../include -Wno-pointer-sign \ + -DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \ + -DGCC_VERSION=\"$(GCCVER)\" -DGCC_BINDIR=\"$(GCCBINDIR)\" \ + -Wno-unused-function + +CXXFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=2 +CXXEFLAGS := $(CXXFLAGS) -Wall + +CC ?= gcc +CXX ?= g++ + +ifeq "clang" "$(CC)" + CC = gcc + CXX = g++ +endif + +ifeq "clang++" "$(CXX)" + CC = gcc + CXX = g++ +endif + +PLUGIN_FLAGS = -fPIC -fno-rtti -I"$(shell $(CC) -print-file-name=plugin)/include" +HASH=\# + +GCCVER = $(shell $(CC) --version 2>/dev/null | awk 'NR == 1 {print $$NF}') +GCCBINDIR = $(shell dirname `command -v $(CC)` 2>/dev/null ) + +ifeq "$(shell echo '$(HASH)include @$(HASH)include @int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1" + SHMAT_OK=1 +else + SHMAT_OK=0 + CFLAGS+=-DUSEMMAP=1 + LDFLAGS += -lrt +endif + +ifeq "$(TEST_MMAP)" "1" + SHMAT_OK=0 + CFLAGS+=-DUSEMMAP=1 + LDFLAGS += -lrt +endif + +PROGS = ../afl-gcc-fast ../afl-gcc-pass.so ../afl-gcc-rt.o + + +all: test_shm test_deps $(PROGS) afl-gcc-fast.8 test_build all_done + +ifeq "$(SHMAT_OK)" "1" + +test_shm: + @echo "[+] shmat seems to be working." + @rm -f .test2 + +else + +test_shm: + @echo "[-] shmat seems not to be working, switching to mmap implementation" + +endif + + +test_deps: + @echo "[*] Checking for working '$(CC)'..." + @type $(CC) >/dev/null 2>&1 || ( echo "[-] Oops, can't find '$(CC)'. Make sure that it's in your \$$PATH (or set \$$CC and \$$CXX)."; exit 1 ) +# @echo "[*] Checking for gcc for plugin support..." +# @$(CC) -v 2>&1 | grep -q -- --enable-plugin || ( echo "[-] Oops, this gcc has not been configured with plugin support."; exit 1 ) + @echo "[*] Checking for gcc plugin development header files..." + @test -d `$(CC) -print-file-name=plugin`/include || ( echo "[-] Oops, can't find gcc header files. Be sure to install 'gcc-X-plugin-dev'."; exit 1 ) + @echo "[*] Checking for '../afl-showmap'..." + @test -f ../afl-showmap || ( echo "[-] Oops, can't find '../afl-showmap'. Be sure to compile AFL first."; exit 1 ) + @echo "[+] All set and ready to build." + +afl-common.o: ../src/afl-common.c + $(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS) + +../afl-gcc-fast: afl-gcc-fast.c afl-common.o | test_deps + $(CC) -DAFL_GCC_CC=\"$(CC)\" -DAFL_GCC_CXX=\"$(CXX)\" $(CFLAGS) $< afl-common.o -o $@ $(LDFLAGS) + ln -sf afl-gcc-fast ../afl-g++-fast + +../afl-gcc-pass.so: afl-gcc-pass.so.cc | test_deps + $(CXX) $(CXXEFLAGS) $(PLUGIN_FLAGS) -shared $< -o $@ + +../afl-gcc-rt.o: afl-gcc-rt.o.c | test_deps + $(CC) $(CFLAGS) -fPIC -c $< -o $@ + +test_build: $(PROGS) + @echo "[*] Testing the CC wrapper and instrumentation output..." + unset AFL_USE_ASAN AFL_USE_MSAN; AFL_QUIET=1 AFL_INST_RATIO=100 AFL_PATH=. AFL_CC=$(CC) ../afl-gcc-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS) +# unset AFL_USE_ASAN AFL_USE_MSAN; AFL_INST_RATIO=100 AFL_PATH=. AFL_CC=$(CC) ../afl-gcc-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS) + ASAN_OPTIONS=detect_leaks=0 ../afl-showmap -m none -q -o .test-instr0 ./test-instr ../$@ + @echo .SH NAME >> ../$@ + @echo .B $* >> ../$@ + @echo >> ../$@ + @echo .SH SYNOPSIS >> ../$@ + @../$* -h 2>&1 | head -n 3 | tail -n 1 | sed 's/^\.\///' >> ../$@ + @echo >> ../$@ + @echo .SH OPTIONS >> ../$@ + @echo .nf >> ../$@ + @../$* -h 2>&1 | tail -n +4 >> ../$@ + @echo >> ../$@ + @echo .SH AUTHOR >> ../$@ + @echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Heiko \"hexcoder-\" Eissfeldt , Andrea Fioraldi and Dominik Maier " >> ../$@ + @echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> ../$@ + @echo >> ../$@ + @echo .SH LICENSE >> ../$@ + @echo Apache License Version 2.0, January 2004 >> ../$@ + ln -sf afl-gcc-fast.8 ../afl-g++-fast.8 + +install: all + install -m 755 ../afl-gcc-fast $${DESTDIR}$(BIN_PATH) + install -m 755 ../afl-gcc-pass.so ../afl-gcc-rt.o $${DESTDIR}$(HELPER_PATH) + install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.md + install -m 644 -T README.whitelist.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.whitelist.md + +clean: + rm -f *.o *.so *~ a.out core core.[1-9][0-9]* test-instr .test-instr0 .test-instr1 .test2 + rm -f $(PROGS) afl-common.o ../afl-g++-fast ../afl-g*-fast.8 diff --git a/gcc_plugin/Makefile b/gcc_plugin/Makefile index 4c7a0313..0b306dde 100644 --- a/gcc_plugin/Makefile +++ b/gcc_plugin/Makefile @@ -1,160 +1,2 @@ -# -# american fuzzy lop++ - GCC plugin instrumentation -# ----------------------------------------------- -# -# Written by Austin Seipp and -# Laszlo Szekeres and -# Michal Zalewski and -# Heiko Eißfeldt -# -# GCC integration design is based on the LLVM design, which comes -# from Laszlo Szekeres. -# -# Copyright 2015 Google Inc. All rights reserved. -# Copyright 2019-2020 AFLplusplus Project. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# - -PREFIX ?= /usr/local -HELPER_PATH ?= $(PREFIX)/lib/afl -BIN_PATH ?= $(PREFIX)/bin -DOC_PATH ?= $(PREFIX)/share/doc/afl -MAN_PATH ?= $(PREFIX)/man/man8 - -VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2) - -CFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=2 -override CFLAGS = -Wall -I../include -Wno-pointer-sign \ - -DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \ - -DGCC_VERSION=\"$(GCCVER)\" -DGCC_BINDIR=\"$(GCCBINDIR)\" \ - -Wno-unused-function - -CXXFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=2 -CXXEFLAGS := $(CXXFLAGS) -Wall - -CC ?= gcc -CXX ?= g++ - -ifeq "clang" "$(CC)" - CC = gcc - CXX = g++ -endif - -ifeq "clang++" "$(CXX)" - CC = gcc - CXX = g++ -endif - -PLUGIN_FLAGS = -fPIC -fno-rtti -I"$(shell $(CC) -print-file-name=plugin)/include" -HASH=\# - -GCCVER = $(shell $(CC) --version 2>/dev/null | awk 'NR == 1 {print $$NF}') -GCCBINDIR = $(shell dirname `command -v $(CC)` 2>/dev/null ) - -ifeq "$(shell echo '$(HASH)include @$(HASH)include @int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1" - SHMAT_OK=1 -else - SHMAT_OK=0 - CFLAGS+=-DUSEMMAP=1 - LDFLAGS += -lrt -endif - -ifeq "$(TEST_MMAP)" "1" - SHMAT_OK=0 - CFLAGS+=-DUSEMMAP=1 - LDFLAGS += -lrt -endif - -PROGS = ../afl-gcc-fast ../afl-gcc-pass.so ../afl-gcc-rt.o - - -all: test_shm test_deps $(PROGS) afl-gcc-fast.8 test_build all_done - -ifeq "$(SHMAT_OK)" "1" - -test_shm: - @echo "[+] shmat seems to be working." - @rm -f .test2 - -else - -test_shm: - @echo "[-] shmat seems not to be working, switching to mmap implementation" - -endif - - -test_deps: - @echo "[*] Checking for working '$(CC)'..." - @type $(CC) >/dev/null 2>&1 || ( echo "[-] Oops, can't find '$(CC)'. Make sure that it's in your \$$PATH (or set \$$CC and \$$CXX)."; exit 1 ) -# @echo "[*] Checking for gcc for plugin support..." -# @$(CC) -v 2>&1 | grep -q -- --enable-plugin || ( echo "[-] Oops, this gcc has not been configured with plugin support."; exit 1 ) - @echo "[*] Checking for gcc plugin development header files..." - @test -d `$(CC) -print-file-name=plugin`/include || ( echo "[-] Oops, can't find gcc header files. Be sure to install 'gcc-X-plugin-dev'."; exit 1 ) - @echo "[*] Checking for '../afl-showmap'..." - @test -f ../afl-showmap || ( echo "[-] Oops, can't find '../afl-showmap'. Be sure to compile AFL first."; exit 1 ) - @echo "[+] All set and ready to build." - -afl-common.o: ../src/afl-common.c - $(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS) - -../afl-gcc-fast: afl-gcc-fast.c afl-common.o | test_deps - $(CC) -DAFL_GCC_CC=\"$(CC)\" -DAFL_GCC_CXX=\"$(CXX)\" $(CFLAGS) $< afl-common.o -o $@ $(LDFLAGS) - ln -sf afl-gcc-fast ../afl-g++-fast - -../afl-gcc-pass.so: afl-gcc-pass.so.cc | test_deps - $(CXX) $(CXXEFLAGS) $(PLUGIN_FLAGS) -shared $< -o $@ - -../afl-gcc-rt.o: afl-gcc-rt.o.c | test_deps - $(CC) $(CFLAGS) -fPIC -c $< -o $@ - -test_build: $(PROGS) - @echo "[*] Testing the CC wrapper and instrumentation output..." - unset AFL_USE_ASAN AFL_USE_MSAN; AFL_QUIET=1 AFL_INST_RATIO=100 AFL_PATH=. AFL_CC=$(CC) ../afl-gcc-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS) -# unset AFL_USE_ASAN AFL_USE_MSAN; AFL_INST_RATIO=100 AFL_PATH=. AFL_CC=$(CC) ../afl-gcc-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS) - ASAN_OPTIONS=detect_leaks=0 ../afl-showmap -m none -q -o .test-instr0 ./test-instr ../$@ - @echo .SH NAME >> ../$@ - @echo .B $* >> ../$@ - @echo >> ../$@ - @echo .SH SYNOPSIS >> ../$@ - @../$* -h 2>&1 | head -n 3 | tail -n 1 | sed 's/^\.\///' >> ../$@ - @echo >> ../$@ - @echo .SH OPTIONS >> ../$@ - @echo .nf >> ../$@ - @../$* -h 2>&1 | tail -n +4 >> ../$@ - @echo >> ../$@ - @echo .SH AUTHOR >> ../$@ - @echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Heiko \"hexcoder-\" Eissfeldt , Andrea Fioraldi and Dominik Maier " >> ../$@ - @echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> ../$@ - @echo >> ../$@ - @echo .SH LICENSE >> ../$@ - @echo Apache License Version 2.0, January 2004 >> ../$@ - ln -sf afl-gcc-fast.8 ../afl-g++-fast.8 - -install: all - install -m 755 ../afl-gcc-fast $${DESTDIR}$(BIN_PATH) - install -m 755 ../afl-gcc-pass.so ../afl-gcc-rt.o $${DESTDIR}$(HELPER_PATH) - install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.md - install -m 644 -T README.whitelist.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.whitelist.md - -clean: - rm -f *.o *.so *~ a.out core core.[1-9][0-9]* test-instr .test-instr0 .test-instr1 .test2 - rm -f $(PROGS) afl-common.o ../afl-g++-fast ../afl-g*-fast.8 +all: + @echo please use GNU make, thanks! diff --git a/libdislocator/GNUmakefile b/libdislocator/GNUmakefile new file mode 100644 index 00000000..3ee37088 --- /dev/null +++ b/libdislocator/GNUmakefile @@ -0,0 +1,44 @@ +# +# american fuzzy lop++ - libdislocator +# ---------------------------------- +# +# Originally written by Michal Zalewski +# +# Copyright 2016 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# + +PREFIX ?= /usr/local +HELPER_PATH = $(PREFIX)/lib/afl + +VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) + +CFLAGS ?= -O3 -funroll-loops +override CFLAGS += -I ../include/ -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign + +ifdef USEHUGEPAGE + CFLAGS += -DUSEHUGEPAGE +endif + +all: libdislocator.so + +VPATH = .. +libdislocator.so: libdislocator.so.c ../config.h + $(CC) $(CFLAGS) -shared -fPIC $< -o ../$@ $(LDFLAGS) + +.NOTPARALLEL: clean + +clean: + rm -f *.o *.so *~ a.out core core.[1-9][0-9]* + rm -f ../libdislocator.so + +install: all + install -m 755 -d $${DESTDIR}$(HELPER_PATH) + install -m 755 ../libdislocator.so $${DESTDIR}$(HELPER_PATH) + install -m 644 README.dislocator.md $${DESTDIR}$(HELPER_PATH) + diff --git a/libdislocator/Makefile b/libdislocator/Makefile index 3ee37088..0b306dde 100644 --- a/libdislocator/Makefile +++ b/libdislocator/Makefile @@ -1,44 +1,2 @@ -# -# american fuzzy lop++ - libdislocator -# ---------------------------------- -# -# Originally written by Michal Zalewski -# -# Copyright 2016 Google Inc. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# - -PREFIX ?= /usr/local -HELPER_PATH = $(PREFIX)/lib/afl - -VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) - -CFLAGS ?= -O3 -funroll-loops -override CFLAGS += -I ../include/ -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign - -ifdef USEHUGEPAGE - CFLAGS += -DUSEHUGEPAGE -endif - -all: libdislocator.so - -VPATH = .. -libdislocator.so: libdislocator.so.c ../config.h - $(CC) $(CFLAGS) -shared -fPIC $< -o ../$@ $(LDFLAGS) - -.NOTPARALLEL: clean - -clean: - rm -f *.o *.so *~ a.out core core.[1-9][0-9]* - rm -f ../libdislocator.so - -install: all - install -m 755 -d $${DESTDIR}$(HELPER_PATH) - install -m 755 ../libdislocator.so $${DESTDIR}$(HELPER_PATH) - install -m 644 README.dislocator.md $${DESTDIR}$(HELPER_PATH) - +all: + @echo please use GNU make, thanks! diff --git a/libtokencap/GNUmakefile b/libtokencap/GNUmakefile new file mode 100644 index 00000000..5fcd7731 --- /dev/null +++ b/libtokencap/GNUmakefile @@ -0,0 +1,63 @@ +# +# american fuzzy lop++ - libtokencap +# -------------------------------- +# +# Originally written by Michal Zalewski +# +# Copyright 2016 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# + +PREFIX ?= /usr/local +HELPER_PATH = $(PREFIX)/lib/afl +DOC_PATH ?= $(PREFIX)/share/doc/afl +MAN_PATH ?= $(PREFIX)/man/man8 + +VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) + +CFLAGS ?= -O3 -funroll-loops +override CFLAGS += -I ../include/ -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign + +ifeq "$(shell uname)" "Linux" + TARGETS = libtokencap.so + LDFLAGS += -ldl +endif +ifeq "$(shell uname)" "Darwin" + TARGETS = libtokencap.so + LDFLAGS += -ldl +endif +ifeq "$(shell uname)" "FreeBSD" + TARGETS = libtokencap.so +endif +ifeq "$(shell uname)" "OpenBSD" + TARGETS = libtokencap.so +endif +ifeq "$(shell uname)" "NetBSD" + TARGETS = libtokencap.so +endif +ifeq "$(shell uname)" "DragonFly" + TARGETS = libtokencap.so + LDFLAGS += -ldl +endif +all: $(TARGETS) + +VPATH = .. +libtokencap.so: libtokencap.so.c ../config.h + $(CC) $(CFLAGS) -shared -fPIC $< -o ../$@ $(LDFLAGS) + +.NOTPARALLEL: clean + +clean: + rm -f *.o *.so *~ a.out core core.[1-9][0-9]* + rm -f ../libtokencap.so + +install: all + install -m 755 -d $${DESTDIR}$(HELPER_PATH) + install -m 755 ../libtokencap.so $${DESTDIR}$(HELPER_PATH) + install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.tokencap.md + diff --git a/libtokencap/Makefile b/libtokencap/Makefile index 5fcd7731..0b306dde 100644 --- a/libtokencap/Makefile +++ b/libtokencap/Makefile @@ -1,63 +1,2 @@ -# -# american fuzzy lop++ - libtokencap -# -------------------------------- -# -# Originally written by Michal Zalewski -# -# Copyright 2016 Google Inc. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# - -PREFIX ?= /usr/local -HELPER_PATH = $(PREFIX)/lib/afl -DOC_PATH ?= $(PREFIX)/share/doc/afl -MAN_PATH ?= $(PREFIX)/man/man8 - -VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) - -CFLAGS ?= -O3 -funroll-loops -override CFLAGS += -I ../include/ -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign - -ifeq "$(shell uname)" "Linux" - TARGETS = libtokencap.so - LDFLAGS += -ldl -endif -ifeq "$(shell uname)" "Darwin" - TARGETS = libtokencap.so - LDFLAGS += -ldl -endif -ifeq "$(shell uname)" "FreeBSD" - TARGETS = libtokencap.so -endif -ifeq "$(shell uname)" "OpenBSD" - TARGETS = libtokencap.so -endif -ifeq "$(shell uname)" "NetBSD" - TARGETS = libtokencap.so -endif -ifeq "$(shell uname)" "DragonFly" - TARGETS = libtokencap.so - LDFLAGS += -ldl -endif -all: $(TARGETS) - -VPATH = .. -libtokencap.so: libtokencap.so.c ../config.h - $(CC) $(CFLAGS) -shared -fPIC $< -o ../$@ $(LDFLAGS) - -.NOTPARALLEL: clean - -clean: - rm -f *.o *.so *~ a.out core core.[1-9][0-9]* - rm -f ../libtokencap.so - -install: all - install -m 755 -d $${DESTDIR}$(HELPER_PATH) - install -m 755 ../libtokencap.so $${DESTDIR}$(HELPER_PATH) - install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.tokencap.md - +all: + @echo please use GNU make, thanks! diff --git a/llvm_mode/GNUmakefile b/llvm_mode/GNUmakefile new file mode 100644 index 00000000..006d115d --- /dev/null +++ b/llvm_mode/GNUmakefile @@ -0,0 +1,375 @@ +# +# american fuzzy lop++ - LLVM instrumentation +# ----------------------------------------- +# +# Written by Laszlo Szekeres and +# Michal Zalewski +# +# LLVM integration design comes from Laszlo Szekeres. +# +# Copyright 2015, 2016 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# + +# For Heiko: +#TEST_MMAP=1 +HASH=\# + +PREFIX ?= /usr/local +HELPER_PATH ?= $(PREFIX)/lib/afl +BIN_PATH ?= $(PREFIX)/bin +DOC_PATH ?= $(PREFIX)/share/doc/afl +MISC_PATH ?= $(PREFIX)/share/afl +MAN_PATH ?= $(PREFIX)/man/man8 + +VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2) + +ifeq "$(shell uname)" "OpenBSD" + LLVM_CONFIG ?= $(BIN_PATH)/llvm-config + HAS_OPT = $(shell test -x $(BIN_PATH)/opt && echo 0 || echo 1) + ifeq "$(HAS_OPT)" "1" + $(error llvm_mode needs a complete llvm installation (versions 3.8.0 up to 11) -> e.g. "pkg_add llvm-7.0.1p9") + endif +else + LLVM_CONFIG ?= llvm-config +endif + +LLVMVER = $(shell $(LLVM_CONFIG) --version 2>/dev/null ) +LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^3\.[0-7]|^1[2-9]' && echo 1 || echo 0 ) +LLVM_NEW_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[0-9]' && echo 1 || echo 0 ) +LLVM_MAJOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/\..*//') +LLVM_BINDIR = $(shell $(LLVM_CONFIG) --bindir 2>/dev/null) +LLVM_STDCXX = gnu++11 +LLVM_APPLE = $(shell clang -v 2>&1 | grep -iq apple && echo 1 || echo 0) +LLVM_LTO = 0 + +ifeq "$(LLVMVER)" "" + $(warning [!] llvm_mode needs llvm-config, which was not found) +endif + +ifeq "$(LLVM_UNSUPPORTED)" "1" + $(warning llvm_mode only supports llvm versions 3.8.0 up to 11) +endif + +ifeq "$(LLVM_MAJOR)" "9" + $(info [+] llvm_mode detected llvm 9, enabling neverZero implementation) + $(info [+] llvm_mode detected llvm 9, enabling afl-clang-lto LTO implementation) + LLVM_LTO = 1 +endif + +ifeq "$(LLVM_NEW_API)" "1" + $(info [+] llvm_mode detected llvm 10+, enabling neverZero implementation and c++14) + $(info [+] llvm_mode detected llvm 9, enabling afl-clang-lto LTO implementation) + LLVM_STDCXX = c++14 + LLVM_LTO = 1 +endif + +ifeq "$(LLVM_LTO)" "0" + $(info [+] llvm_mode detected llvm < 9, afl-clang-lto LTO will not be build.) +endif + +ifeq "$(LLVM_APPLE)" "1" + $(warning llvm_mode will not compile with Xcode clang...) +endif + +# We were using llvm-config --bindir to get the location of clang, but +# this seems to be busted on some distros, so using the one in $PATH is +# probably better. + +CC = $(LLVM_BINDIR)/clang +CXX = $(LLVM_BINDIR)/clang++ + +ifeq "$(shell test -e $(CC) || echo 1 )" "1" + # llvm-config --bindir may not providing a valid path, so ... + ifeq "$(shell test -e '$(BIN_DIR)/clang' && echo 1)" "1" + # we found one in the local install directory, lets use these + CC = $(BIN_DIR)/clang + CXX = $(BIN_DIR)/clang++ + else + # hope for the best + $(warning we have trouble finding clang/clang++ - llvm-config is not helping us) + CC = clang + CXX = clang++ + endif +endif + +# sanity check. +# Are versions of clang --version and llvm-config --version equal? +CLANGVER = $(shell $(CC) --version | sed -E -ne '/^.*version\ ([0-9]\.[0-9]\.[0-9]).*/s//\1/p') + +ifneq "$(CLANGVER)" "$(LLVMVER)" + CC = $(shell $(LLVM_CONFIG) --bindir)/clang + CXX = $(shell $(LLVM_CONFIG) --bindir)/clang++ +endif + +# After we set CC/CXX we can start makefile magic tests + +ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -march=native -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" + CFLAGS_OPT = -march=native +endif + +ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -flto=full -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" + AFL_CLANG_FLTO ?= -flto=full +else + ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -flto=thin -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" + AFL_CLANG_FLTO ?= -flto=thin + else + ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -flto -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" + AFL_CLANG_FLTO ?= -flto + endif + endif +endif + +ifneq "$(AFL_CLANG_FLTO)" "" +ifeq "$(AFL_REAL_LD)" "" + AFL_REAL_LD = $(shell readlink /bin/ld 2>/dev/null) + ifeq "$(AFL_REAL_LD)" "" + AFL_REAL_LD = $(shell readlink /usr/bin/ld 2>/dev/null) + endif +endif +endif + +CFLAGS ?= -O3 -funroll-loops -D_FORTIFY_SOURCE=2 +override CFLAGS = -Wall \ + -g -Wno-pointer-sign -I ../include/ \ + -DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \ + -DLLVM_BINDIR=\"$(LLVM_BINDIR)\" -DVERSION=\"$(VERSION)\" \ + -DLLVM_VERSION=\"$(LLVMVER)\" -DAFL_CLANG_FLTO=\"$(AFL_CLANG_FLTO)\" \ + -DAFL_REAL_LD=\"$(AFL_REAL_LD)\" -Wno-unused-function +ifdef AFL_TRACE_PC + CFLAGS += -DUSE_TRACE_PC=1 +endif + +CXXFLAGS ?= -O3 -funroll-loops -D_FORTIFY_SOURCE=2 +override CXXFLAGS += -Wall -g -I ../include/ \ + -DVERSION=\"$(VERSION)\" -Wno-variadic-macros + +CLANG_CFL = `$(LLVM_CONFIG) --cxxflags` -Wl,-znodelete -fno-rtti -fpic $(CXXFLAGS) +CLANG_LFL = `$(LLVM_CONFIG) --ldflags` $(LDFLAGS) + + +# User teor2345 reports that this is required to make things work on MacOS X. +ifeq "$(shell uname)" "Darwin" + CLANG_LFL += -Wl,-flat_namespace -Wl,-undefined,suppress +endif + +ifeq "$(shell uname)" "OpenBSD" + CLANG_LFL += `$(LLVM_CONFIG) --libdir`/libLLVM.so +endif + +ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -fuse-ld=`command -v ld` -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" + CFLAGS += -DAFL_CLANG_FUSELD=1 +endif + +ifeq "$(shell echo '$(HASH)include @$(HASH)include @int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1" + SHMAT_OK=1 +else + SHMAT_OK=0 + CFLAGS+=-DUSEMMAP=1 + LDFLAGS += -lrt +endif + +ifeq "$(TEST_MMAP)" "1" + SHMAT_OK=0 + CFLAGS+=-DUSEMMAP=1 + LDFLAGS += -lrt +endif + +ifndef AFL_TRACE_PC + PROGS = ../afl-clang-fast ../afl-ld ../afl-llvm-pass.so ../afl-llvm-lto-whitelist.so ../afl-llvm-lto-instrumentation.so ../libLLVMInsTrim.so ../afl-llvm-rt.o ../afl-llvm-rt-32.o ../afl-llvm-rt-64.o ../compare-transform-pass.so ../split-compares-pass.so ../split-switches-pass.so ../cmplog-routines-pass.so ../cmplog-instructions-pass.so +else + PROGS = ../afl-clang-fast ../afl-llvm-rt.o ../afl-llvm-rt-32.o ../afl-llvm-rt-64.o ../compare-transform-pass.so ../split-compares-pass.so ../split-switches-pass.so ../cmplog-routines-pass.so ../cmplog-instructions-pass.so +endif + +# If prerequisites are not given, warn, do not build anything, and exit with code 0 +ifeq "$(LLVMVER)" "" + NO_BUILD = 1 +endif + +ifneq "$(LLVM_UNSUPPORTED)$(LLVM_APPLE)" "00" + NO_BUILD = 1 +endif + +ifeq "$(NO_BUILD)" "1" + TARGETS = no_build +else + TARGETS = test_shm test_deps $(PROGS) afl-clang-fast.8 test_build all_done +endif + +LLVM_MIN_4_0_1 = $(shell awk 'function tonum(ver, a) {split(ver,a,"."); return a[1]*1000000+a[2]*1000+a[3]} BEGIN { exit tonum(ARGV[1]) >= tonum(ARGV[2]) }' $(LLVMVER) 4.0.1; echo $$?) + +all: $(TARGETS) + +ifeq "$(SHMAT_OK)" "1" + +test_shm: + @echo "[+] shmat seems to be working." + @rm -f .test2 + +else + +test_shm: + @echo "[-] shmat seems not to be working, switching to mmap implementation" + +endif + +no_build: + @printf "%b\\n" "\\033[0;31mPrerequisites are not met, skipping build llvm_mode\\033[0m" + +test_deps: +ifndef AFL_TRACE_PC + @echo "[*] Checking for working 'llvm-config'..." + ifneq "$(LLVM_APPLE)" "1" + @type $(LLVM_CONFIG) >/dev/null 2>&1 || ( echo "[-] Oops, can't find 'llvm-config'. Install clang or set \$$LLVM_CONFIG or \$$PATH beforehand."; echo " (Sometimes, the binary will be named llvm-config-3.5 or something like that.)"; exit 1 ) + endif +else + @echo "[!] Note: using -fsanitize=trace-pc mode (this will fail with older LLVM)." +endif + @echo "[*] Checking for working '$(CC)'..." + @type $(CC) >/dev/null 2>&1 || ( echo "[-] Oops, can't find '$(CC)'. Make sure that it's in your \$$PATH (or set \$$CC and \$$CXX)."; exit 1 ) + @echo "[*] Checking for matching versions of '$(CC)' and '$(LLVM_CONFIG)'" +ifneq "$(CLANGVER)" "$(LLVMVER)" + @echo "[!] WARNING: we have llvm-config version $(LLVMVER) and a clang version $(CLANGVER)" + @echo "[!] Retrying with the clang compiler from llvm: CC=`llvm-config --bindir`/clang" +else + @echo "[*] We have llvm-config version $(LLVMVER) with a clang version $(CLANGVER), good." +endif + @echo "[*] Checking for '../afl-showmap'..." + @test -f ../afl-showmap || ( echo "[-] Oops, can't find '../afl-showmap'. Be sure to compile AFL first."; exit 1 ) + @echo "[+] All set and ready to build." + +afl-common.o: ../src/afl-common.c + $(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS) + +../afl-clang-fast: afl-clang-fast.c afl-common.o | test_deps + $(CC) $(CFLAGS) $< afl-common.o -o $@ $(LDFLAGS) -DCFLAGS_OPT=\"$(CFLAGS_OPT)\" + ln -sf afl-clang-fast ../afl-clang-fast++ +ifneq "$(AFL_CLANG_FLTO)" "" +ifeq "$(LLVM_LTO)" "1" + ln -sf afl-clang-fast ../afl-clang-lto + ln -sf afl-clang-fast ../afl-clang-lto++ +endif +endif + +../afl-ld: afl-ld.c +ifneq "$(AFL_CLANG_FLTO)" "" +ifeq "$(LLVM_LTO)" "1" + $(CC) $(CFLAGS) $< -o $@ $(LDFLAGS) + ln -sf afl-ld ../ld + @rm -f .test-instr + @-export AFL_QUIET=1 AFL_PATH=.. PATH="..:$(PATH)" ; ../afl-clang-lto -Wl,--afl -o .test-instr ../test-instr.c && echo "[+] afl-clang-lto and afl-ld seem to work fine :)" || echo "[!] WARNING: clang seems to have a hardcoded "'/bin/ld'" - check README.lto" + @rm -f .test-instr +endif +endif +../libLLVMInsTrim.so: LLVMInsTrim.so.cc MarkNodes.cc | test_deps + -$(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) + +../afl-llvm-pass.so: afl-llvm-pass.so.cc | test_deps +ifeq "$(LLVM_MIN_4_0_1)" "0" + $(info [!] N-gram branch coverage instrumentation is not available for llvm version $(LLVMVER)) +endif + $(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) + +../afl-llvm-lto-whitelist.so: afl-llvm-lto-whitelist.so.cc +ifeq "$(LLVM_LTO)" "1" + $(CXX) $(CLANG_CFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) +endif + +../afl-llvm-lto-instrumentation.so: afl-llvm-lto-instrumentation.so.cc MarkNodes.cc +ifeq "$(LLVM_LTO)" "1" + $(CXX) $(CLANG_CFL) -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) +endif + +# laf +../split-switches-pass.so: split-switches-pass.so.cc | test_deps + $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) +../compare-transform-pass.so: compare-transform-pass.so.cc | test_deps + $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) +../split-compares-pass.so: split-compares-pass.so.cc | test_deps + $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) +# /laf + +../cmplog-routines-pass.so: cmplog-routines-pass.cc | test_deps + $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) + +../cmplog-instructions-pass.so: cmplog-instructions-pass.cc | test_deps + $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) + +../afl-llvm-rt.o: afl-llvm-rt.o.c | test_deps + $(CC) $(CFLAGS) -fPIC -c $< -o $@ + +../afl-llvm-rt-32.o: afl-llvm-rt.o.c | test_deps + @printf "[*] Building 32-bit variant of the runtime (-m32)... " + @$(CC) $(CFLAGS) -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi + +../afl-llvm-rt-64.o: afl-llvm-rt.o.c | test_deps + @printf "[*] Building 64-bit variant of the runtime (-m64)... " + @$(CC) $(CFLAGS) -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi + +test_build: $(PROGS) + @echo "[*] Testing the CC wrapper and instrumentation output..." + unset AFL_USE_ASAN AFL_USE_MSAN AFL_INST_RATIO; AFL_QUIET=1 AFL_PATH=. AFL_CC=$(CC) AFL_LLVM_LAF_SPLIT_SWITCHES=1 AFL_LLVM_LAF_TRANSFORM_COMPARES=1 AFL_LLVM_LAF_SPLIT_COMPARES=1 ../afl-clang-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS) + ASAN_OPTIONS=detect_leaks=0 ../afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null + echo 1 | ASAN_OPTIONS=detect_leaks=0 ../afl-showmap -m none -q -o .test-instr1 ./test-instr + @rm -f test-instr + @cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation does not seem to be behaving correctly!"; echo; echo "Please post to https://github.com/AFLplusplus/AFLplusplus/issues to troubleshoot the issue."; echo; exit 1; fi + @echo "[+] All right, the instrumentation seems to be working!" + +all_done: test_build + @echo "[+] All done! You can now use '../afl-clang-fast' to compile programs." + +.NOTPARALLEL: clean + +install: all + install -d -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH) +ifndef AFL_TRACE_PC + if [ -f ../afl-clang-fast -a -f ../libLLVMInsTrim.so -a -f ../afl-llvm-rt.o ]; then set -e; install -m 755 ../afl-clang-fast $${DESTDIR}$(BIN_PATH); ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-fast++; install -m 755 ../libLLVMInsTrim.so ../afl-llvm-pass.so ../afl-llvm-rt.o $${DESTDIR}$(HELPER_PATH); fi + if [ -f afl-clang-lto -a -f afl-ld ]; then set -e; install -m 755 afl-clang-lto $${DESTDIR}$(BIN_PATH); ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-lto++; install -m 755 afl-ld $${DESTDIR}$(HELPER_PATH); ln -sf afl-ld $${DESTDIR}$(HELPER_PATH)/ld; install -m 755 afl-llvm-lto-instrumentation.so $${DESTDIR}$(HELPER_PATH); install -m 755 afl-llvm-lto-whitelist.so $${DESTDIR}$(HELPER_PATH); fi +else + if [ -f ../afl-clang-fast -a -f ../afl-llvm-rt.o ]; then set -e; install -m 755 ../afl-clang-fast $${DESTDIR}$(BIN_PATH); ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-fast++; install -m 755 ../afl-llvm-rt.o $${DESTDIR}$(HELPER_PATH); fi +endif + if [ -f ../afl-llvm-rt-32.o ]; then set -e; install -m 755 ../afl-llvm-rt-32.o $${DESTDIR}$(HELPER_PATH); fi + if [ -f ../afl-llvm-rt-64.o ]; then set -e; install -m 755 ../afl-llvm-rt-64.o $${DESTDIR}$(HELPER_PATH); fi + if [ -f ../compare-transform-pass.so ]; then set -e; install -m 755 ../compare-transform-pass.so $${DESTDIR}$(HELPER_PATH); fi + if [ -f ../split-compares-pass.so ]; then set -e; install -m 755 ../split-compares-pass.so $${DESTDIR}$(HELPER_PATH); fi + if [ -f ../split-switches-pass.so ]; then set -e; install -m 755 ../split-switches-pass.so $${DESTDIR}$(HELPER_PATH); fi + if [ -f ../cmplog-instructions-pass.so ]; then set -e; install -m 755 ../cmplog-*-pass.so $${DESTDIR}$(HELPER_PATH); fi + set -e; if [ -f ../afl-clang-fast ] ; then ln -sf ../afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf ../afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang++ ; else ln -sf ../afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf ../afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang++; fi + install -m 644 README.*.md $${DESTDIR}$(DOC_PATH)/ + install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.llvm_mode.md + +vpath % .. +%.8: % + @echo .TH $* 8 `date "+%Y-%m-%d"` "afl++" > ../$@ + @echo .SH NAME >> ../$@ + @echo .B $* >> ../$@ + @echo >> ../$@ + @echo .SH SYNOPSIS >> ../$@ + @../$* -h 2>&1 | head -n 3 | tail -n 1 | sed 's/^\.\///' >> ../$@ + @echo >> ../$@ + @echo .SH OPTIONS >> ../$@ + @echo .nf >> ../$@ + @../$* -h 2>&1 | tail -n +4 >> ../$@ + @echo >> ../$@ + @echo .SH AUTHOR >> ../$@ + @echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Heiko \"hexcoder-\" Eissfeldt , Andrea Fioraldi and Dominik Maier " >> ../$@ + @echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> ../$@ + @echo >> ../$@ + @echo .SH LICENSE >> ../$@ + @echo Apache License Version 2.0, January 2004 >> ../$@ + ln -sf afl-clang-fast.8 ../afl-clang-fast++.8 +ifneq "$(AFL_CLANG_FLTO)" "" +ifeq "$(LLVM_LTO)" "1" + ln -sf afl-clang-fast.8 ../afl-clang-lto.8 + ln -sf afl-clang-fast.8 ../afl-clang-lto++.8 +endif +endif + +clean: + rm -f *.o *.so *~ a.out core core.[1-9][0-9]* .test2 test-instr .test-instr0 .test-instr1 *.dwo + rm -f $(PROGS) afl-common.o ../afl-clang-fast++ ../afl-clang-lto ../afl-clang-lto++ ../afl-clang*.8 ../ld diff --git a/llvm_mode/Makefile b/llvm_mode/Makefile index 006d115d..0b306dde 100644 --- a/llvm_mode/Makefile +++ b/llvm_mode/Makefile @@ -1,375 +1,2 @@ -# -# american fuzzy lop++ - LLVM instrumentation -# ----------------------------------------- -# -# Written by Laszlo Szekeres and -# Michal Zalewski -# -# LLVM integration design comes from Laszlo Szekeres. -# -# Copyright 2015, 2016 Google Inc. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# - -# For Heiko: -#TEST_MMAP=1 -HASH=\# - -PREFIX ?= /usr/local -HELPER_PATH ?= $(PREFIX)/lib/afl -BIN_PATH ?= $(PREFIX)/bin -DOC_PATH ?= $(PREFIX)/share/doc/afl -MISC_PATH ?= $(PREFIX)/share/afl -MAN_PATH ?= $(PREFIX)/man/man8 - -VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2) - -ifeq "$(shell uname)" "OpenBSD" - LLVM_CONFIG ?= $(BIN_PATH)/llvm-config - HAS_OPT = $(shell test -x $(BIN_PATH)/opt && echo 0 || echo 1) - ifeq "$(HAS_OPT)" "1" - $(error llvm_mode needs a complete llvm installation (versions 3.8.0 up to 11) -> e.g. "pkg_add llvm-7.0.1p9") - endif -else - LLVM_CONFIG ?= llvm-config -endif - -LLVMVER = $(shell $(LLVM_CONFIG) --version 2>/dev/null ) -LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^3\.[0-7]|^1[2-9]' && echo 1 || echo 0 ) -LLVM_NEW_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[0-9]' && echo 1 || echo 0 ) -LLVM_MAJOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/\..*//') -LLVM_BINDIR = $(shell $(LLVM_CONFIG) --bindir 2>/dev/null) -LLVM_STDCXX = gnu++11 -LLVM_APPLE = $(shell clang -v 2>&1 | grep -iq apple && echo 1 || echo 0) -LLVM_LTO = 0 - -ifeq "$(LLVMVER)" "" - $(warning [!] llvm_mode needs llvm-config, which was not found) -endif - -ifeq "$(LLVM_UNSUPPORTED)" "1" - $(warning llvm_mode only supports llvm versions 3.8.0 up to 11) -endif - -ifeq "$(LLVM_MAJOR)" "9" - $(info [+] llvm_mode detected llvm 9, enabling neverZero implementation) - $(info [+] llvm_mode detected llvm 9, enabling afl-clang-lto LTO implementation) - LLVM_LTO = 1 -endif - -ifeq "$(LLVM_NEW_API)" "1" - $(info [+] llvm_mode detected llvm 10+, enabling neverZero implementation and c++14) - $(info [+] llvm_mode detected llvm 9, enabling afl-clang-lto LTO implementation) - LLVM_STDCXX = c++14 - LLVM_LTO = 1 -endif - -ifeq "$(LLVM_LTO)" "0" - $(info [+] llvm_mode detected llvm < 9, afl-clang-lto LTO will not be build.) -endif - -ifeq "$(LLVM_APPLE)" "1" - $(warning llvm_mode will not compile with Xcode clang...) -endif - -# We were using llvm-config --bindir to get the location of clang, but -# this seems to be busted on some distros, so using the one in $PATH is -# probably better. - -CC = $(LLVM_BINDIR)/clang -CXX = $(LLVM_BINDIR)/clang++ - -ifeq "$(shell test -e $(CC) || echo 1 )" "1" - # llvm-config --bindir may not providing a valid path, so ... - ifeq "$(shell test -e '$(BIN_DIR)/clang' && echo 1)" "1" - # we found one in the local install directory, lets use these - CC = $(BIN_DIR)/clang - CXX = $(BIN_DIR)/clang++ - else - # hope for the best - $(warning we have trouble finding clang/clang++ - llvm-config is not helping us) - CC = clang - CXX = clang++ - endif -endif - -# sanity check. -# Are versions of clang --version and llvm-config --version equal? -CLANGVER = $(shell $(CC) --version | sed -E -ne '/^.*version\ ([0-9]\.[0-9]\.[0-9]).*/s//\1/p') - -ifneq "$(CLANGVER)" "$(LLVMVER)" - CC = $(shell $(LLVM_CONFIG) --bindir)/clang - CXX = $(shell $(LLVM_CONFIG) --bindir)/clang++ -endif - -# After we set CC/CXX we can start makefile magic tests - -ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -march=native -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" - CFLAGS_OPT = -march=native -endif - -ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -flto=full -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" - AFL_CLANG_FLTO ?= -flto=full -else - ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -flto=thin -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" - AFL_CLANG_FLTO ?= -flto=thin - else - ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -flto -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" - AFL_CLANG_FLTO ?= -flto - endif - endif -endif - -ifneq "$(AFL_CLANG_FLTO)" "" -ifeq "$(AFL_REAL_LD)" "" - AFL_REAL_LD = $(shell readlink /bin/ld 2>/dev/null) - ifeq "$(AFL_REAL_LD)" "" - AFL_REAL_LD = $(shell readlink /usr/bin/ld 2>/dev/null) - endif -endif -endif - -CFLAGS ?= -O3 -funroll-loops -D_FORTIFY_SOURCE=2 -override CFLAGS = -Wall \ - -g -Wno-pointer-sign -I ../include/ \ - -DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \ - -DLLVM_BINDIR=\"$(LLVM_BINDIR)\" -DVERSION=\"$(VERSION)\" \ - -DLLVM_VERSION=\"$(LLVMVER)\" -DAFL_CLANG_FLTO=\"$(AFL_CLANG_FLTO)\" \ - -DAFL_REAL_LD=\"$(AFL_REAL_LD)\" -Wno-unused-function -ifdef AFL_TRACE_PC - CFLAGS += -DUSE_TRACE_PC=1 -endif - -CXXFLAGS ?= -O3 -funroll-loops -D_FORTIFY_SOURCE=2 -override CXXFLAGS += -Wall -g -I ../include/ \ - -DVERSION=\"$(VERSION)\" -Wno-variadic-macros - -CLANG_CFL = `$(LLVM_CONFIG) --cxxflags` -Wl,-znodelete -fno-rtti -fpic $(CXXFLAGS) -CLANG_LFL = `$(LLVM_CONFIG) --ldflags` $(LDFLAGS) - - -# User teor2345 reports that this is required to make things work on MacOS X. -ifeq "$(shell uname)" "Darwin" - CLANG_LFL += -Wl,-flat_namespace -Wl,-undefined,suppress -endif - -ifeq "$(shell uname)" "OpenBSD" - CLANG_LFL += `$(LLVM_CONFIG) --libdir`/libLLVM.so -endif - -ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -fuse-ld=`command -v ld` -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" - CFLAGS += -DAFL_CLANG_FUSELD=1 -endif - -ifeq "$(shell echo '$(HASH)include @$(HASH)include @int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1" - SHMAT_OK=1 -else - SHMAT_OK=0 - CFLAGS+=-DUSEMMAP=1 - LDFLAGS += -lrt -endif - -ifeq "$(TEST_MMAP)" "1" - SHMAT_OK=0 - CFLAGS+=-DUSEMMAP=1 - LDFLAGS += -lrt -endif - -ifndef AFL_TRACE_PC - PROGS = ../afl-clang-fast ../afl-ld ../afl-llvm-pass.so ../afl-llvm-lto-whitelist.so ../afl-llvm-lto-instrumentation.so ../libLLVMInsTrim.so ../afl-llvm-rt.o ../afl-llvm-rt-32.o ../afl-llvm-rt-64.o ../compare-transform-pass.so ../split-compares-pass.so ../split-switches-pass.so ../cmplog-routines-pass.so ../cmplog-instructions-pass.so -else - PROGS = ../afl-clang-fast ../afl-llvm-rt.o ../afl-llvm-rt-32.o ../afl-llvm-rt-64.o ../compare-transform-pass.so ../split-compares-pass.so ../split-switches-pass.so ../cmplog-routines-pass.so ../cmplog-instructions-pass.so -endif - -# If prerequisites are not given, warn, do not build anything, and exit with code 0 -ifeq "$(LLVMVER)" "" - NO_BUILD = 1 -endif - -ifneq "$(LLVM_UNSUPPORTED)$(LLVM_APPLE)" "00" - NO_BUILD = 1 -endif - -ifeq "$(NO_BUILD)" "1" - TARGETS = no_build -else - TARGETS = test_shm test_deps $(PROGS) afl-clang-fast.8 test_build all_done -endif - -LLVM_MIN_4_0_1 = $(shell awk 'function tonum(ver, a) {split(ver,a,"."); return a[1]*1000000+a[2]*1000+a[3]} BEGIN { exit tonum(ARGV[1]) >= tonum(ARGV[2]) }' $(LLVMVER) 4.0.1; echo $$?) - -all: $(TARGETS) - -ifeq "$(SHMAT_OK)" "1" - -test_shm: - @echo "[+] shmat seems to be working." - @rm -f .test2 - -else - -test_shm: - @echo "[-] shmat seems not to be working, switching to mmap implementation" - -endif - -no_build: - @printf "%b\\n" "\\033[0;31mPrerequisites are not met, skipping build llvm_mode\\033[0m" - -test_deps: -ifndef AFL_TRACE_PC - @echo "[*] Checking for working 'llvm-config'..." - ifneq "$(LLVM_APPLE)" "1" - @type $(LLVM_CONFIG) >/dev/null 2>&1 || ( echo "[-] Oops, can't find 'llvm-config'. Install clang or set \$$LLVM_CONFIG or \$$PATH beforehand."; echo " (Sometimes, the binary will be named llvm-config-3.5 or something like that.)"; exit 1 ) - endif -else - @echo "[!] Note: using -fsanitize=trace-pc mode (this will fail with older LLVM)." -endif - @echo "[*] Checking for working '$(CC)'..." - @type $(CC) >/dev/null 2>&1 || ( echo "[-] Oops, can't find '$(CC)'. Make sure that it's in your \$$PATH (or set \$$CC and \$$CXX)."; exit 1 ) - @echo "[*] Checking for matching versions of '$(CC)' and '$(LLVM_CONFIG)'" -ifneq "$(CLANGVER)" "$(LLVMVER)" - @echo "[!] WARNING: we have llvm-config version $(LLVMVER) and a clang version $(CLANGVER)" - @echo "[!] Retrying with the clang compiler from llvm: CC=`llvm-config --bindir`/clang" -else - @echo "[*] We have llvm-config version $(LLVMVER) with a clang version $(CLANGVER), good." -endif - @echo "[*] Checking for '../afl-showmap'..." - @test -f ../afl-showmap || ( echo "[-] Oops, can't find '../afl-showmap'. Be sure to compile AFL first."; exit 1 ) - @echo "[+] All set and ready to build." - -afl-common.o: ../src/afl-common.c - $(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS) - -../afl-clang-fast: afl-clang-fast.c afl-common.o | test_deps - $(CC) $(CFLAGS) $< afl-common.o -o $@ $(LDFLAGS) -DCFLAGS_OPT=\"$(CFLAGS_OPT)\" - ln -sf afl-clang-fast ../afl-clang-fast++ -ifneq "$(AFL_CLANG_FLTO)" "" -ifeq "$(LLVM_LTO)" "1" - ln -sf afl-clang-fast ../afl-clang-lto - ln -sf afl-clang-fast ../afl-clang-lto++ -endif -endif - -../afl-ld: afl-ld.c -ifneq "$(AFL_CLANG_FLTO)" "" -ifeq "$(LLVM_LTO)" "1" - $(CC) $(CFLAGS) $< -o $@ $(LDFLAGS) - ln -sf afl-ld ../ld - @rm -f .test-instr - @-export AFL_QUIET=1 AFL_PATH=.. PATH="..:$(PATH)" ; ../afl-clang-lto -Wl,--afl -o .test-instr ../test-instr.c && echo "[+] afl-clang-lto and afl-ld seem to work fine :)" || echo "[!] WARNING: clang seems to have a hardcoded "'/bin/ld'" - check README.lto" - @rm -f .test-instr -endif -endif -../libLLVMInsTrim.so: LLVMInsTrim.so.cc MarkNodes.cc | test_deps - -$(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) - -../afl-llvm-pass.so: afl-llvm-pass.so.cc | test_deps -ifeq "$(LLVM_MIN_4_0_1)" "0" - $(info [!] N-gram branch coverage instrumentation is not available for llvm version $(LLVMVER)) -endif - $(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) - -../afl-llvm-lto-whitelist.so: afl-llvm-lto-whitelist.so.cc -ifeq "$(LLVM_LTO)" "1" - $(CXX) $(CLANG_CFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) -endif - -../afl-llvm-lto-instrumentation.so: afl-llvm-lto-instrumentation.so.cc MarkNodes.cc -ifeq "$(LLVM_LTO)" "1" - $(CXX) $(CLANG_CFL) -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) -endif - -# laf -../split-switches-pass.so: split-switches-pass.so.cc | test_deps - $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) -../compare-transform-pass.so: compare-transform-pass.so.cc | test_deps - $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) -../split-compares-pass.so: split-compares-pass.so.cc | test_deps - $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) -# /laf - -../cmplog-routines-pass.so: cmplog-routines-pass.cc | test_deps - $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) - -../cmplog-instructions-pass.so: cmplog-instructions-pass.cc | test_deps - $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) - -../afl-llvm-rt.o: afl-llvm-rt.o.c | test_deps - $(CC) $(CFLAGS) -fPIC -c $< -o $@ - -../afl-llvm-rt-32.o: afl-llvm-rt.o.c | test_deps - @printf "[*] Building 32-bit variant of the runtime (-m32)... " - @$(CC) $(CFLAGS) -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi - -../afl-llvm-rt-64.o: afl-llvm-rt.o.c | test_deps - @printf "[*] Building 64-bit variant of the runtime (-m64)... " - @$(CC) $(CFLAGS) -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi - -test_build: $(PROGS) - @echo "[*] Testing the CC wrapper and instrumentation output..." - unset AFL_USE_ASAN AFL_USE_MSAN AFL_INST_RATIO; AFL_QUIET=1 AFL_PATH=. AFL_CC=$(CC) AFL_LLVM_LAF_SPLIT_SWITCHES=1 AFL_LLVM_LAF_TRANSFORM_COMPARES=1 AFL_LLVM_LAF_SPLIT_COMPARES=1 ../afl-clang-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS) - ASAN_OPTIONS=detect_leaks=0 ../afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null - echo 1 | ASAN_OPTIONS=detect_leaks=0 ../afl-showmap -m none -q -o .test-instr1 ./test-instr - @rm -f test-instr - @cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation does not seem to be behaving correctly!"; echo; echo "Please post to https://github.com/AFLplusplus/AFLplusplus/issues to troubleshoot the issue."; echo; exit 1; fi - @echo "[+] All right, the instrumentation seems to be working!" - -all_done: test_build - @echo "[+] All done! You can now use '../afl-clang-fast' to compile programs." - -.NOTPARALLEL: clean - -install: all - install -d -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH) -ifndef AFL_TRACE_PC - if [ -f ../afl-clang-fast -a -f ../libLLVMInsTrim.so -a -f ../afl-llvm-rt.o ]; then set -e; install -m 755 ../afl-clang-fast $${DESTDIR}$(BIN_PATH); ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-fast++; install -m 755 ../libLLVMInsTrim.so ../afl-llvm-pass.so ../afl-llvm-rt.o $${DESTDIR}$(HELPER_PATH); fi - if [ -f afl-clang-lto -a -f afl-ld ]; then set -e; install -m 755 afl-clang-lto $${DESTDIR}$(BIN_PATH); ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-lto++; install -m 755 afl-ld $${DESTDIR}$(HELPER_PATH); ln -sf afl-ld $${DESTDIR}$(HELPER_PATH)/ld; install -m 755 afl-llvm-lto-instrumentation.so $${DESTDIR}$(HELPER_PATH); install -m 755 afl-llvm-lto-whitelist.so $${DESTDIR}$(HELPER_PATH); fi -else - if [ -f ../afl-clang-fast -a -f ../afl-llvm-rt.o ]; then set -e; install -m 755 ../afl-clang-fast $${DESTDIR}$(BIN_PATH); ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-fast++; install -m 755 ../afl-llvm-rt.o $${DESTDIR}$(HELPER_PATH); fi -endif - if [ -f ../afl-llvm-rt-32.o ]; then set -e; install -m 755 ../afl-llvm-rt-32.o $${DESTDIR}$(HELPER_PATH); fi - if [ -f ../afl-llvm-rt-64.o ]; then set -e; install -m 755 ../afl-llvm-rt-64.o $${DESTDIR}$(HELPER_PATH); fi - if [ -f ../compare-transform-pass.so ]; then set -e; install -m 755 ../compare-transform-pass.so $${DESTDIR}$(HELPER_PATH); fi - if [ -f ../split-compares-pass.so ]; then set -e; install -m 755 ../split-compares-pass.so $${DESTDIR}$(HELPER_PATH); fi - if [ -f ../split-switches-pass.so ]; then set -e; install -m 755 ../split-switches-pass.so $${DESTDIR}$(HELPER_PATH); fi - if [ -f ../cmplog-instructions-pass.so ]; then set -e; install -m 755 ../cmplog-*-pass.so $${DESTDIR}$(HELPER_PATH); fi - set -e; if [ -f ../afl-clang-fast ] ; then ln -sf ../afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf ../afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang++ ; else ln -sf ../afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf ../afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang++; fi - install -m 644 README.*.md $${DESTDIR}$(DOC_PATH)/ - install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.llvm_mode.md - -vpath % .. -%.8: % - @echo .TH $* 8 `date "+%Y-%m-%d"` "afl++" > ../$@ - @echo .SH NAME >> ../$@ - @echo .B $* >> ../$@ - @echo >> ../$@ - @echo .SH SYNOPSIS >> ../$@ - @../$* -h 2>&1 | head -n 3 | tail -n 1 | sed 's/^\.\///' >> ../$@ - @echo >> ../$@ - @echo .SH OPTIONS >> ../$@ - @echo .nf >> ../$@ - @../$* -h 2>&1 | tail -n +4 >> ../$@ - @echo >> ../$@ - @echo .SH AUTHOR >> ../$@ - @echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Heiko \"hexcoder-\" Eissfeldt , Andrea Fioraldi and Dominik Maier " >> ../$@ - @echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> ../$@ - @echo >> ../$@ - @echo .SH LICENSE >> ../$@ - @echo Apache License Version 2.0, January 2004 >> ../$@ - ln -sf afl-clang-fast.8 ../afl-clang-fast++.8 -ifneq "$(AFL_CLANG_FLTO)" "" -ifeq "$(LLVM_LTO)" "1" - ln -sf afl-clang-fast.8 ../afl-clang-lto.8 - ln -sf afl-clang-fast.8 ../afl-clang-lto++.8 -endif -endif - -clean: - rm -f *.o *.so *~ a.out core core.[1-9][0-9]* .test2 test-instr .test-instr0 .test-instr1 *.dwo - rm -f $(PROGS) afl-common.o ../afl-clang-fast++ ../afl-clang-lto ../afl-clang-lto++ ../afl-clang*.8 ../ld +all: + @echo please use GNU make, thanks! diff --git a/qemu_mode/libcompcov/GNUmakefile b/qemu_mode/libcompcov/GNUmakefile new file mode 100644 index 00000000..f06ac2af --- /dev/null +++ b/qemu_mode/libcompcov/GNUmakefile @@ -0,0 +1,44 @@ +# +# american fuzzy lop++ - libcompcov +# -------------------------------- +# +# Written by Andrea Fioraldi +# +# Copyright 2019-2020 Andrea Fioraldi. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# + +PREFIX ?= /usr/local +HELPER_PATH = $(PREFIX)/lib/afl +DOC_PATH ?= $(PREFIX)/share/doc/afl +MAN_PATH ?= $(PREFIX)/man/man8 + +VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) + +CFLAGS ?= -O3 -funroll-loops -I ../../include/ +CFLAGS += -Wall -Wno-unused-result -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign +LDFLAGS += -ldl + +all: libcompcov.so + +libcompcov.so: libcompcov.so.c ../../config.h + $(CC) $(CFLAGS) -shared -fPIC $< -o ../../$@ $(LDFLAGS) + +.NOTPARALLEL: clean + +clean: + rm -f *.o *.so *~ a.out core core.[1-9][0-9]* + rm -f ../../libcompcov.so compcovtest + +compcovtest: compcovtest.cc + $(CXX) -std=c++11 $< -o $@ + +install: all + install -m 755 ../../libcompcov.so $${DESTDIR}$(HELPER_PATH) + install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.compcov.md + diff --git a/qemu_mode/libcompcov/Makefile b/qemu_mode/libcompcov/Makefile index f06ac2af..0b306dde 100644 --- a/qemu_mode/libcompcov/Makefile +++ b/qemu_mode/libcompcov/Makefile @@ -1,44 +1,2 @@ -# -# american fuzzy lop++ - libcompcov -# -------------------------------- -# -# Written by Andrea Fioraldi -# -# Copyright 2019-2020 Andrea Fioraldi. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# - -PREFIX ?= /usr/local -HELPER_PATH = $(PREFIX)/lib/afl -DOC_PATH ?= $(PREFIX)/share/doc/afl -MAN_PATH ?= $(PREFIX)/man/man8 - -VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) - -CFLAGS ?= -O3 -funroll-loops -I ../../include/ -CFLAGS += -Wall -Wno-unused-result -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign -LDFLAGS += -ldl - -all: libcompcov.so - -libcompcov.so: libcompcov.so.c ../../config.h - $(CC) $(CFLAGS) -shared -fPIC $< -o ../../$@ $(LDFLAGS) - -.NOTPARALLEL: clean - -clean: - rm -f *.o *.so *~ a.out core core.[1-9][0-9]* - rm -f ../../libcompcov.so compcovtest - -compcovtest: compcovtest.cc - $(CXX) -std=c++11 $< -o $@ - -install: all - install -m 755 ../../libcompcov.so $${DESTDIR}$(HELPER_PATH) - install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.compcov.md - +all: + @echo please use GNU make, thanks! diff --git a/qemu_mode/unsigaction/GNUmakefile b/qemu_mode/unsigaction/GNUmakefile new file mode 100644 index 00000000..31fa8c55 --- /dev/null +++ b/qemu_mode/unsigaction/GNUmakefile @@ -0,0 +1,34 @@ +# +# american fuzzy lop++ - unsigaction +# -------------------------------- +# +# Written by Andrea Fioraldi +# +# Copyright 2019-2020 Andrea Fioraldi. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# + +ifndef AFL_NO_X86 + +all: lib_i386 lib_amd64 + +lib_i386: + @$(CC) -m32 -fPIC -shared unsigaction.c -o unsigaction32.so 2>/dev/null ; if [ "$$?" = "0" ]; then echo "unsigaction32 build success"; else echo "unsigaction32 build failure (that's fine)"; fi + +lib_amd64: + $(CC) -fPIC -shared unsigaction.c -o unsigaction64.so + +clean: + rm -f unsigaction32.so unsigaction64.so + +else + +all: + @echo "[!] Note: skipping compilation of unsigaction (AFL_NO_X86 set)." + +endif diff --git a/qemu_mode/unsigaction/Makefile b/qemu_mode/unsigaction/Makefile index 31fa8c55..0b306dde 100644 --- a/qemu_mode/unsigaction/Makefile +++ b/qemu_mode/unsigaction/Makefile @@ -1,34 +1,2 @@ -# -# american fuzzy lop++ - unsigaction -# -------------------------------- -# -# Written by Andrea Fioraldi -# -# Copyright 2019-2020 Andrea Fioraldi. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# - -ifndef AFL_NO_X86 - -all: lib_i386 lib_amd64 - -lib_i386: - @$(CC) -m32 -fPIC -shared unsigaction.c -o unsigaction32.so 2>/dev/null ; if [ "$$?" = "0" ]; then echo "unsigaction32 build success"; else echo "unsigaction32 build failure (that's fine)"; fi - -lib_amd64: - $(CC) -fPIC -shared unsigaction.c -o unsigaction64.so - -clean: - rm -f unsigaction32.so unsigaction64.so - -else - all: - @echo "[!] Note: skipping compilation of unsigaction (AFL_NO_X86 set)." - -endif + @echo please use GNU make, thanks! diff --git a/src/third_party/libradamsa/GNUmakefile b/src/third_party/libradamsa/GNUmakefile new file mode 100644 index 00000000..c5a78ead --- /dev/null +++ b/src/third_party/libradamsa/GNUmakefile @@ -0,0 +1,26 @@ +CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) + +all: libradamsa.so + +# These can be overriden: +CFLAGS ?= -march=native $(CFLAGS_FLTO) + +# These are required: (otherwise radamsa gets very very slooooow) +CFLAGS += -O3 -funroll-loops + +libradamsa.so: libradamsa.a + $(CC) $(CFLAGS) -shared libradamsa.a -o libradamsa.so + +libradamsa.a: libradamsa.c radamsa.h + @echo " ***************************************************************" + @echo " * Compiling libradamsa, wait some minutes (~3 on modern CPUs) *" + @echo " ***************************************************************" + $(CC) -fPIC $(CFLAGS) -I $(CUR_DIR) -o libradamsa.a -c libradamsa.c + +test: libradamsa.a libradamsa-test.c + $(CC) $(CFLAGS) -I $(CUR_DIR) -o libradamsa-test libradamsa-test.c libradamsa.a + ./libradamsa-test libradamsa-test.c | grep "library test passed" + rm /tmp/libradamsa-*.fuzz + +clean: + rm -f libradamsa.a libradamsa.so libradamsa-test diff --git a/src/third_party/libradamsa/Makefile b/src/third_party/libradamsa/Makefile index c5a78ead..0b306dde 100644 --- a/src/third_party/libradamsa/Makefile +++ b/src/third_party/libradamsa/Makefile @@ -1,26 +1,2 @@ -CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) - -all: libradamsa.so - -# These can be overriden: -CFLAGS ?= -march=native $(CFLAGS_FLTO) - -# These are required: (otherwise radamsa gets very very slooooow) -CFLAGS += -O3 -funroll-loops - -libradamsa.so: libradamsa.a - $(CC) $(CFLAGS) -shared libradamsa.a -o libradamsa.so - -libradamsa.a: libradamsa.c radamsa.h - @echo " ***************************************************************" - @echo " * Compiling libradamsa, wait some minutes (~3 on modern CPUs) *" - @echo " ***************************************************************" - $(CC) -fPIC $(CFLAGS) -I $(CUR_DIR) -o libradamsa.a -c libradamsa.c - -test: libradamsa.a libradamsa-test.c - $(CC) $(CFLAGS) -I $(CUR_DIR) -o libradamsa-test libradamsa-test.c libradamsa.a - ./libradamsa-test libradamsa-test.c | grep "library test passed" - rm /tmp/libradamsa-*.fuzz - -clean: - rm -f libradamsa.a libradamsa.so libradamsa-test +all: + @echo please use GNU make, thanks! diff --git a/unicorn_mode/samples/c/GNUmakefile b/unicorn_mode/samples/c/GNUmakefile new file mode 100644 index 00000000..fe100490 --- /dev/null +++ b/unicorn_mode/samples/c/GNUmakefile @@ -0,0 +1,42 @@ +# UnicornAFL Usage +# Original Unicorn Example Makefile by Nguyen Anh Quynh , 2015 +# Adapted for AFL++ by domenukk , 2020 + +UNAME_S := $(shell uname -s) + +LIBDIR = ../../unicornafl +BIN_EXT = +AR_EXT = a + +# Verbose output? +V ?= 0 + +CFLAGS += -Wall -Werror -I../../unicornafl/include + +LDFLAGS += -L$(LIBDIR) -lpthread -lm +ifeq ($(UNAME_S), Linux) +LDFLAGS += -lrt +endif + +ifneq ($(CROSS),) +CC = $(CROSS)gcc +endif + +.PHONY: all clean + +all: harness + +clean: + rm -rf *.o harness harness-debug + +harness.o: harness.c ../../unicornafl/include/unicorn/*.h + ${CC} ${CFLAGS} -O3 -c $< + +harness-debug.o: harness.c ../../unicornafl/include/unicorn/*.h + ${CC} ${CFLAGS} -g -c $< -o $@ + +harness: harness.o + ${CC} -L${LIBDIR} $< ../../unicornafl/libunicornafl.a $(LDFLAGS) -o $@ + +debug: harness-debug.o + ${CC} -L${LIBDIR} $< ../../unicornafl/libunicornafl.a $(LDFLAGS) -o harness-debug diff --git a/unicorn_mode/samples/c/Makefile b/unicorn_mode/samples/c/Makefile index fe100490..0b306dde 100644 --- a/unicorn_mode/samples/c/Makefile +++ b/unicorn_mode/samples/c/Makefile @@ -1,42 +1,2 @@ -# UnicornAFL Usage -# Original Unicorn Example Makefile by Nguyen Anh Quynh , 2015 -# Adapted for AFL++ by domenukk , 2020 - -UNAME_S := $(shell uname -s) - -LIBDIR = ../../unicornafl -BIN_EXT = -AR_EXT = a - -# Verbose output? -V ?= 0 - -CFLAGS += -Wall -Werror -I../../unicornafl/include - -LDFLAGS += -L$(LIBDIR) -lpthread -lm -ifeq ($(UNAME_S), Linux) -LDFLAGS += -lrt -endif - -ifneq ($(CROSS),) -CC = $(CROSS)gcc -endif - -.PHONY: all clean - -all: harness - -clean: - rm -rf *.o harness harness-debug - -harness.o: harness.c ../../unicornafl/include/unicorn/*.h - ${CC} ${CFLAGS} -O3 -c $< - -harness-debug.o: harness.c ../../unicornafl/include/unicorn/*.h - ${CC} ${CFLAGS} -g -c $< -o $@ - -harness: harness.o - ${CC} -L${LIBDIR} $< ../../unicornafl/libunicornafl.a $(LDFLAGS) -o $@ - -debug: harness-debug.o - ${CC} -L${LIBDIR} $< ../../unicornafl/libunicornafl.a $(LDFLAGS) -o harness-debug +all: + @echo please use GNU make, thanks! diff --git a/unicorn_mode/samples/persistent/GNUmakefile b/unicorn_mode/samples/persistent/GNUmakefile new file mode 100644 index 00000000..fe100490 --- /dev/null +++ b/unicorn_mode/samples/persistent/GNUmakefile @@ -0,0 +1,42 @@ +# UnicornAFL Usage +# Original Unicorn Example Makefile by Nguyen Anh Quynh , 2015 +# Adapted for AFL++ by domenukk , 2020 + +UNAME_S := $(shell uname -s) + +LIBDIR = ../../unicornafl +BIN_EXT = +AR_EXT = a + +# Verbose output? +V ?= 0 + +CFLAGS += -Wall -Werror -I../../unicornafl/include + +LDFLAGS += -L$(LIBDIR) -lpthread -lm +ifeq ($(UNAME_S), Linux) +LDFLAGS += -lrt +endif + +ifneq ($(CROSS),) +CC = $(CROSS)gcc +endif + +.PHONY: all clean + +all: harness + +clean: + rm -rf *.o harness harness-debug + +harness.o: harness.c ../../unicornafl/include/unicorn/*.h + ${CC} ${CFLAGS} -O3 -c $< + +harness-debug.o: harness.c ../../unicornafl/include/unicorn/*.h + ${CC} ${CFLAGS} -g -c $< -o $@ + +harness: harness.o + ${CC} -L${LIBDIR} $< ../../unicornafl/libunicornafl.a $(LDFLAGS) -o $@ + +debug: harness-debug.o + ${CC} -L${LIBDIR} $< ../../unicornafl/libunicornafl.a $(LDFLAGS) -o harness-debug diff --git a/unicorn_mode/samples/persistent/Makefile b/unicorn_mode/samples/persistent/Makefile index fe100490..0b306dde 100644 --- a/unicorn_mode/samples/persistent/Makefile +++ b/unicorn_mode/samples/persistent/Makefile @@ -1,42 +1,2 @@ -# UnicornAFL Usage -# Original Unicorn Example Makefile by Nguyen Anh Quynh , 2015 -# Adapted for AFL++ by domenukk , 2020 - -UNAME_S := $(shell uname -s) - -LIBDIR = ../../unicornafl -BIN_EXT = -AR_EXT = a - -# Verbose output? -V ?= 0 - -CFLAGS += -Wall -Werror -I../../unicornafl/include - -LDFLAGS += -L$(LIBDIR) -lpthread -lm -ifeq ($(UNAME_S), Linux) -LDFLAGS += -lrt -endif - -ifneq ($(CROSS),) -CC = $(CROSS)gcc -endif - -.PHONY: all clean - -all: harness - -clean: - rm -rf *.o harness harness-debug - -harness.o: harness.c ../../unicornafl/include/unicorn/*.h - ${CC} ${CFLAGS} -O3 -c $< - -harness-debug.o: harness.c ../../unicornafl/include/unicorn/*.h - ${CC} ${CFLAGS} -g -c $< -o $@ - -harness: harness.o - ${CC} -L${LIBDIR} $< ../../unicornafl/libunicornafl.a $(LDFLAGS) -o $@ - -debug: harness-debug.o - ${CC} -L${LIBDIR} $< ../../unicornafl/libunicornafl.a $(LDFLAGS) -o harness-debug +all: + @echo please use GNU make, thanks! -- cgit 1.4.1 From cc65e91eeba541aa9e3b42e81df3d752814eff21 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Thu, 2 Apr 2020 17:00:35 +0200 Subject: restore portable Makefiles --- examples/custom_mutators/GNUmakefile | 7 ------ examples/custom_mutators/Makefile | 9 +++++-- qemu_mode/libcompcov/GNUmakefile | 44 -------------------------------- qemu_mode/libcompcov/Makefile | 46 ++++++++++++++++++++++++++++++++-- src/third_party/libradamsa/GNUmakefile | 26 ------------------- src/third_party/libradamsa/Makefile | 28 +++++++++++++++++++-- 6 files changed, 77 insertions(+), 83 deletions(-) delete mode 100644 examples/custom_mutators/GNUmakefile delete mode 100644 qemu_mode/libcompcov/GNUmakefile delete mode 100644 src/third_party/libradamsa/GNUmakefile (limited to 'examples/custom_mutators') diff --git a/examples/custom_mutators/GNUmakefile b/examples/custom_mutators/GNUmakefile deleted file mode 100644 index 9849f3f4..00000000 --- a/examples/custom_mutators/GNUmakefile +++ /dev/null @@ -1,7 +0,0 @@ -all: libexamplemutator.so - -libexamplemutator.so: - $(CC) $(CFLAGS) -D_FORTIFY_SOURCE=2 -O3 -fPIC -shared -g -I ../../include example.c -o libexamplemutator.so - -clean: - rm -rf libexamplemutator.so diff --git a/examples/custom_mutators/Makefile b/examples/custom_mutators/Makefile index 0b306dde..9849f3f4 100644 --- a/examples/custom_mutators/Makefile +++ b/examples/custom_mutators/Makefile @@ -1,2 +1,7 @@ -all: - @echo please use GNU make, thanks! +all: libexamplemutator.so + +libexamplemutator.so: + $(CC) $(CFLAGS) -D_FORTIFY_SOURCE=2 -O3 -fPIC -shared -g -I ../../include example.c -o libexamplemutator.so + +clean: + rm -rf libexamplemutator.so diff --git a/qemu_mode/libcompcov/GNUmakefile b/qemu_mode/libcompcov/GNUmakefile deleted file mode 100644 index f06ac2af..00000000 --- a/qemu_mode/libcompcov/GNUmakefile +++ /dev/null @@ -1,44 +0,0 @@ -# -# american fuzzy lop++ - libcompcov -# -------------------------------- -# -# Written by Andrea Fioraldi -# -# Copyright 2019-2020 Andrea Fioraldi. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# - -PREFIX ?= /usr/local -HELPER_PATH = $(PREFIX)/lib/afl -DOC_PATH ?= $(PREFIX)/share/doc/afl -MAN_PATH ?= $(PREFIX)/man/man8 - -VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) - -CFLAGS ?= -O3 -funroll-loops -I ../../include/ -CFLAGS += -Wall -Wno-unused-result -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign -LDFLAGS += -ldl - -all: libcompcov.so - -libcompcov.so: libcompcov.so.c ../../config.h - $(CC) $(CFLAGS) -shared -fPIC $< -o ../../$@ $(LDFLAGS) - -.NOTPARALLEL: clean - -clean: - rm -f *.o *.so *~ a.out core core.[1-9][0-9]* - rm -f ../../libcompcov.so compcovtest - -compcovtest: compcovtest.cc - $(CXX) -std=c++11 $< -o $@ - -install: all - install -m 755 ../../libcompcov.so $${DESTDIR}$(HELPER_PATH) - install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.compcov.md - diff --git a/qemu_mode/libcompcov/Makefile b/qemu_mode/libcompcov/Makefile index 0b306dde..f06ac2af 100644 --- a/qemu_mode/libcompcov/Makefile +++ b/qemu_mode/libcompcov/Makefile @@ -1,2 +1,44 @@ -all: - @echo please use GNU make, thanks! +# +# american fuzzy lop++ - libcompcov +# -------------------------------- +# +# Written by Andrea Fioraldi +# +# Copyright 2019-2020 Andrea Fioraldi. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# + +PREFIX ?= /usr/local +HELPER_PATH = $(PREFIX)/lib/afl +DOC_PATH ?= $(PREFIX)/share/doc/afl +MAN_PATH ?= $(PREFIX)/man/man8 + +VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) + +CFLAGS ?= -O3 -funroll-loops -I ../../include/ +CFLAGS += -Wall -Wno-unused-result -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign +LDFLAGS += -ldl + +all: libcompcov.so + +libcompcov.so: libcompcov.so.c ../../config.h + $(CC) $(CFLAGS) -shared -fPIC $< -o ../../$@ $(LDFLAGS) + +.NOTPARALLEL: clean + +clean: + rm -f *.o *.so *~ a.out core core.[1-9][0-9]* + rm -f ../../libcompcov.so compcovtest + +compcovtest: compcovtest.cc + $(CXX) -std=c++11 $< -o $@ + +install: all + install -m 755 ../../libcompcov.so $${DESTDIR}$(HELPER_PATH) + install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.compcov.md + diff --git a/src/third_party/libradamsa/GNUmakefile b/src/third_party/libradamsa/GNUmakefile deleted file mode 100644 index c5a78ead..00000000 --- a/src/third_party/libradamsa/GNUmakefile +++ /dev/null @@ -1,26 +0,0 @@ -CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) - -all: libradamsa.so - -# These can be overriden: -CFLAGS ?= -march=native $(CFLAGS_FLTO) - -# These are required: (otherwise radamsa gets very very slooooow) -CFLAGS += -O3 -funroll-loops - -libradamsa.so: libradamsa.a - $(CC) $(CFLAGS) -shared libradamsa.a -o libradamsa.so - -libradamsa.a: libradamsa.c radamsa.h - @echo " ***************************************************************" - @echo " * Compiling libradamsa, wait some minutes (~3 on modern CPUs) *" - @echo " ***************************************************************" - $(CC) -fPIC $(CFLAGS) -I $(CUR_DIR) -o libradamsa.a -c libradamsa.c - -test: libradamsa.a libradamsa-test.c - $(CC) $(CFLAGS) -I $(CUR_DIR) -o libradamsa-test libradamsa-test.c libradamsa.a - ./libradamsa-test libradamsa-test.c | grep "library test passed" - rm /tmp/libradamsa-*.fuzz - -clean: - rm -f libradamsa.a libradamsa.so libradamsa-test diff --git a/src/third_party/libradamsa/Makefile b/src/third_party/libradamsa/Makefile index 0b306dde..c5a78ead 100644 --- a/src/third_party/libradamsa/Makefile +++ b/src/third_party/libradamsa/Makefile @@ -1,2 +1,26 @@ -all: - @echo please use GNU make, thanks! +CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) + +all: libradamsa.so + +# These can be overriden: +CFLAGS ?= -march=native $(CFLAGS_FLTO) + +# These are required: (otherwise radamsa gets very very slooooow) +CFLAGS += -O3 -funroll-loops + +libradamsa.so: libradamsa.a + $(CC) $(CFLAGS) -shared libradamsa.a -o libradamsa.so + +libradamsa.a: libradamsa.c radamsa.h + @echo " ***************************************************************" + @echo " * Compiling libradamsa, wait some minutes (~3 on modern CPUs) *" + @echo " ***************************************************************" + $(CC) -fPIC $(CFLAGS) -I $(CUR_DIR) -o libradamsa.a -c libradamsa.c + +test: libradamsa.a libradamsa-test.c + $(CC) $(CFLAGS) -I $(CUR_DIR) -o libradamsa-test libradamsa-test.c libradamsa.a + ./libradamsa-test libradamsa-test.c | grep "library test passed" + rm /tmp/libradamsa-*.fuzz + +clean: + rm -f libradamsa.a libradamsa.so libradamsa-test -- cgit 1.4.1