diff options
-rw-r--r-- | docs/custom_mutators.md | 7 | ||||
-rw-r--r-- | examples/README.md | 8 | ||||
-rw-r--r-- | examples/custom_mutators/Makefile | 7 | ||||
-rw-r--r-- | examples/custom_mutators/example.c | 33 | ||||
-rw-r--r-- | examples/custom_mutators/example.py | 19 | ||||
-rw-r--r-- | include/afl-fuzz.h | 3 | ||||
-rw-r--r-- | llvm_mode/Makefile | 2 | ||||
-rw-r--r-- | src/afl-fuzz-mutators.c | 4 | ||||
-rw-r--r-- | src/afl-fuzz-one.c | 4 | ||||
-rw-r--r-- | src/afl-fuzz-python.c | 4 | ||||
-rw-r--r-- | test/test-custom-mutator.c | 19 | ||||
-rwxr-xr-x | test/test.sh | 126 |
12 files changed, 168 insertions, 68 deletions
diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index 2163b2d5..ef97b8d3 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -30,7 +30,8 @@ C/C++: 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); +size_t afl_custom_write_to_testcase(uint8_t* buf, size_t buf_size, + uint8_t* out_buf, size_t out_buf_size); 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); @@ -111,7 +112,7 @@ def queue_new_entry(filename_new_queue, filename_orig_queue): - `queue_new_entry` (optional): - This methods is called after adding a new test case to the queue. + This methods is called after adding a new test case to the queue. ### Trimming Support @@ -167,7 +168,7 @@ a fallback to the builtin default trimming routine. Optionally, the following environment variables are supported: - `AFL_CUSTOM_MUTATOR_ONLY` - + Disable all other mutation stages. This can prevent broken testcases (those that your Python module can't work with anymore) to fill up your queue. Best combined with a custom trimming routine (see below) because diff --git a/examples/README.md b/examples/README.md index 37fae1a0..6c09caeb 100644 --- a/examples/README.md +++ b/examples/README.md @@ -3,8 +3,6 @@ Here's a quick overview of the stuff you can find in this directory: - custom_mutstors - An example custom mutator - - - python_mutators - Python mutators examples - argv_fuzzing - a simple wrapper to allow cmdline to be fuzzed (e.g., to test setuid programs). @@ -15,8 +13,8 @@ Here's a quick overview of the stuff you can find in this directory: - bash_shellshock - a simple hack used to find a bunch of post-Shellshock bugs in bash. - - canvas_harness - a test harness used to find browser bugs with a - corpus generated using simple image parsing + - canvas_harness - a test harness used to find browser bugs with a + corpus generated using simple image parsing binaries & afl-fuzz. - clang_asm_normalize - a script that makes it easy to instrument @@ -34,7 +32,7 @@ Here's a quick overview of the stuff you can find in this directory: mode to speed up certain fuzzing jobs. - post_library - an example of how to build postprocessors for AFL. - + - socket_fuzzing - a LD_PRELOAD library 'redirects' a socket to stdin for fuzzing access with afl++ 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/examples/custom_mutators/example.c b/examples/custom_mutators/example.c index a9764f5b..c8200b26 100644 --- a/examples/custom_mutators/example.c +++ b/examples/custom_mutators/example.c @@ -142,32 +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; } - *out_buf = data->pre_save_buf; + 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] = '+'; - 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] = '+'; + *out_buf = pre_save_buf; - return out_buf_size; + return buf_size + 5; } diff --git a/examples/custom_mutators/example.py b/examples/custom_mutators/example.py index 6bacfa05..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. @@ -27,6 +34,10 @@ def init(seed): random.seed(seed) +def deinit(): + pass + + def fuzz(buf, add_buf, max_size): ''' Called per fuzzing iteration. @@ -44,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 @@ -164,11 +176,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/include/afl-fuzz.h b/include/afl-fuzz.h index a265c1a3..fcbc09e5 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -566,9 +566,6 @@ typedef struct afl_state { /* Custom mutators */ struct custom_mutator *mutator; -#ifdef USE_PYTHON - struct custom_mutator *py_mutator; -#endif /* cmplog forkserver ids */ s32 cmplog_fsrv_ctl_fd, cmplog_fsrv_st_fd; diff --git a/llvm_mode/Makefile b/llvm_mode/Makefile index 5b6fcca4..006d115d 100644 --- a/llvm_mode/Makefile +++ b/llvm_mode/Makefile @@ -329,7 +329,7 @@ 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; ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-lto; 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 + 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 diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 754b2190..1a5528a2 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -193,8 +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)); } diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index b1bbad0a..2e49e19b 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)) { @@ -1649,7 +1647,7 @@ custom_mutator_stage: } - out_buf = ck_maybe_grow(BUF_PARAMS(out), len); + /* `(afl->)out_buf` may have been changed by the call to custom_fuzz */ memcpy(out_buf, in_buf, len); } diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index 91e5b084..12c3a09d 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) { @@ -302,6 +303,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); + afl->mutator->data = py_mutator; if (!py_mutator) { FATAL("Failed to load python mutator."); } PyObject **py_functions = py_mutator->py_functions; diff --git a/test/test-custom-mutator.c b/test/test-custom-mutator.c new file mode 100644 index 00000000..83baafab --- /dev/null +++ b/test/test-custom-mutator.c @@ -0,0 +1,19 @@ +/** + * Reference: https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/blob/master/4_libprotobuf_aflpp_custom_mutator/vuln.c + */ + +#include <stdio.h> +#include <string.h> +#include <math.h> +#include <stdlib.h> +#include <unistd.h> + +int main(int argc, char *argv[]) +{ + char str[100]; + read(0, str, 100); + if( str[6] == 'A') { + abort(); + } + return 0; +} diff --git a/test/test.sh b/test/test.sh index ec4e71d0..3e1b6c43 100755 --- a/test/test.sh +++ b/test/test.sh @@ -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,88 @@ 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 # 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 + make -C ../examples/custom_mutators libexamplemutator.so > /dev/null 2>&1 + 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" + { + AFL_CUSTOM_MUTATOR_LIBRARY=${CUSTOM_MUTATOR_PATH}/libexamplemutator.so ../afl-fuzz -V10 -m ${MEM_LIMIT} -i in -o out -- ./test-custom-mutator >>errors 2>&1 + } >>errors 2>&1 + + # Check results + 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 + 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 >>errors 2>&1 + unset PYTHONPATH + unset AFL_PYTHON_MODULE + } >>errors 2>&1 + + # Check results + 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 + 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" |