diff options
-rw-r--r-- | examples/custom_mutators/README.md | 3 | ||||
-rw-r--r-- | examples/custom_mutators/example.py | 1 | ||||
-rw-r--r-- | examples/custom_mutators/simple_example.c | 74 | ||||
-rw-r--r-- | src/afl-fuzz-mutators.c | 25 | ||||
-rw-r--r-- | test/test-multiple-mutators.c | 7 | ||||
-rwxr-xr-x | test/test.sh | 21 |
6 files changed, 107 insertions, 24 deletions
diff --git a/examples/custom_mutators/README.md b/examples/custom_mutators/README.md index 6fc7be6c..99fb9da3 100644 --- a/examples/custom_mutators/README.md +++ b/examples/custom_mutators/README.md @@ -6,6 +6,9 @@ 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 python2.7 to compile python2 scripts! +simple_example.c - most simplest example. generates a random sized buffer + filled with 'A' + 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 diff --git a/examples/custom_mutators/example.py b/examples/custom_mutators/example.py index 9e95eed6..3c3fa8c1 100644 --- a/examples/custom_mutators/example.py +++ b/examples/custom_mutators/example.py @@ -21,6 +21,7 @@ COMMANDS = [ b"GET", b"PUT", b"DEL", + b"AAAAAAAAAAAAAAAAA", ] diff --git a/examples/custom_mutators/simple_example.c b/examples/custom_mutators/simple_example.c new file mode 100644 index 00000000..a351d787 --- /dev/null +++ b/examples/custom_mutators/simple_example.c @@ -0,0 +1,74 @@ +// This simple example just creates random buffer <= 100 filled with 'A' +// needs -I /path/to/AFLplusplus/include +#include "custom_mutator_helpers.h" + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#ifndef _FIXED_CHAR + #define 0x41 +#endif + +typedef struct my_mutator { + + afl_t *afl; + + // Reused buffers: + BUF_VAR(u8, fuzz); + +} my_mutator_t; + +my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) { + + srand(seed); + my_mutator_t *data = calloc(1, sizeof(my_mutator_t)); + if (!data) { + + perror("afl_custom_init alloc"); + return NULL; + + } + + data->afl = afl; + + return data; + +} + +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) { + + int size = (rand() % 100) + 1; + if (size > max_size) size = max_size; + u8 *mutated_out = maybe_grow(BUF_PARAMS(data, fuzz), size); + if (!mutated_out) { + + *out_buf = NULL; + perror("custom mutator allocation (maybe_grow)"); + return 0; /* afl-fuzz will very likely error out after this. */ + + } + + memset(mutated_out, _FIXED_CHAR, size); + + *out_buf = mutated_out; + return size; + +} + +/** + * Deinitialize everything + * + * @param data The data ptr from afl_custom_init + */ +void afl_custom_deinit(my_mutator_t *data) { + + free(data->fuzz_buf); + free(data); + +} + diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 027add49..6bd13e2b 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -117,7 +117,7 @@ void destroy_custom_mutators(afl_state_t *afl) { LIST_FOREACH_CLEAR(&afl->custom_mutator_list, struct custom_mutator, { if (!el->data) { FATAL("Deintializing NULL mutator"); } - el->afl_custom_deinit(el->data); + if (el->afl_custom_deinit) el->afl_custom_deinit(el->data); if (el->dh) dlclose(el->dh); if (el->pre_save_buf) { @@ -166,32 +166,37 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { } + /* "afl_custom_deinit", optional for backward compatibility */ + mutator->afl_custom_deinit = dlsym(dh, "afl_custom_deinit"); + if (!mutator->afl_custom_deinit) WARNF("Symbol 'afl_custom_init' not found."); + /* "afl_custom_pre_save", optional */ mutator->afl_custom_pre_save = dlsym(dh, "afl_custom_pre_save"); if (!mutator->afl_custom_pre_save) - WARNF("Symbol 'afl_custom_pre_save' not found."); + ACTF("optional symbol 'afl_custom_pre_save' not found."); u8 notrim = 0; /* "afl_custom_init_trim", optional */ mutator->afl_custom_init_trim = dlsym(dh, "afl_custom_init_trim"); if (!mutator->afl_custom_init_trim) - WARNF("Symbol 'afl_custom_init_trim' not found."); + ACTF("optional symbol 'afl_custom_init_trim' not found."); /* "afl_custom_trim", optional */ mutator->afl_custom_trim = dlsym(dh, "afl_custom_trim"); - if (!mutator->afl_custom_trim) WARNF("Symbol 'afl_custom_trim' not found."); + if (!mutator->afl_custom_trim) + ACTF("optional symbol 'afl_custom_trim' not found."); /* "afl_custom_post_trim", optional */ mutator->afl_custom_post_trim = dlsym(dh, "afl_custom_post_trim"); if (!mutator->afl_custom_post_trim) - WARNF("Symbol 'afl_custom_post_trim' not found."); + ACTF("optional symbol 'afl_custom_post_trim' not found."); if (notrim) { mutator->afl_custom_init_trim = NULL; mutator->afl_custom_trim = NULL; mutator->afl_custom_post_trim = NULL; - WARNF( + ACTF( "Custom mutator does not implement all three trim APIs, standard " "trimming will be used."); @@ -200,23 +205,23 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { /* "afl_custom_havoc_mutation", optional */ mutator->afl_custom_havoc_mutation = dlsym(dh, "afl_custom_havoc_mutation"); if (!mutator->afl_custom_havoc_mutation) - WARNF("Symbol 'afl_custom_havoc_mutation' not found."); + ACTF("optional symbol 'afl_custom_havoc_mutation' not found."); /* "afl_custom_havoc_mutation", optional */ mutator->afl_custom_havoc_mutation_probability = dlsym(dh, "afl_custom_havoc_mutation_probability"); if (!mutator->afl_custom_havoc_mutation_probability) - WARNF("Symbol 'afl_custom_havoc_mutation_probability' not found."); + ACTF("optional symbol 'afl_custom_havoc_mutation_probability' not found."); /* "afl_custom_queue_get", optional */ mutator->afl_custom_queue_get = dlsym(dh, "afl_custom_queue_get"); if (!mutator->afl_custom_queue_get) - WARNF("Symbol 'afl_custom_queue_get' not found."); + ACTF("optional symbol 'afl_custom_queue_get' not found."); /* "afl_custom_queue_new_entry", optional */ mutator->afl_custom_queue_new_entry = dlsym(dh, "afl_custom_queue_new_entry"); if (!mutator->afl_custom_queue_new_entry) - WARNF("Symbol 'afl_custom_queue_new_entry' not found"); + ACTF("optional symbol 'afl_custom_queue_new_entry' not found"); OKF("Custom mutator '%s' installed successfully.", fn); diff --git a/test/test-multiple-mutators.c b/test/test-multiple-mutators.c index 0f6f5c64..dafc817c 100644 --- a/test/test-multiple-mutators.c +++ b/test/test-multiple-mutators.c @@ -12,11 +12,10 @@ int main(int argc, char **argv) { int a = 0; - char s[16]; - memset(s, 0, 16); - read(0, s, 0xa0); + char s[100]; + read(0, s, 100); - if (s[17] != '\x00') { abort(); } + if (s[7] == 'B') { abort(); } return 0; diff --git a/test/test.sh b/test/test.sh index 919d7a9c..1d06780b 100755 --- a/test/test.sh +++ b/test/test.sh @@ -970,16 +970,17 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && { } } # 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 && { + cc -D_FIXED_CHAR=0x41 -g -fPIC -shared -I../include ../examples/custom_mutators/simple_example.c -o libexamplemutator.so > /dev/null 2>&1 + cc -D_FIXED_CHAR=0x42 -g -fPIC -shared -I../include ../examples/custom_mutators/simple_example.c -o libexamplemutator2.so > /dev/null 2>&1 + test -e test-custom-mutator -a -e ./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" + $ECHO "$GREY[*] running afl-fuzz for the C mutator, this will take approx 5 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 + AFL_CUSTOM_MUTATOR_LIBRARY=./libexamplemutator.so AFL_CUSTOM_MUTATOR_ONLY=1 ../afl-fuzz -V1 -m ${MEM_LIMIT} -i in -o out -- ./test-custom-mutator >>errors 2>&1 } >>errors 2>&1 # Check results @@ -996,10 +997,10 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && { # Clean rm -rf out errors - #Run afl-fuzz w/ multiple C mutators - $ECHO "$GREY[*] running afl-fuzz with multiple custom C mutators, this will take approx 20 seconds" + # Run afl-fuzz w/ multiple C mutators + $ECHO "$GREY[*] running afl-fuzz with multiple custom C mutators, this will take approx 5 seconds" { - AFL_CUSTOM_MUTATOR_LIBRARY="${CUSTOM_MUTATOR_PATH}/libexamplemutator.so;${CUSTOM_MUTATOR_PATH}/libexamplemutator.so" ../afl-fuzz -V20 -m ${MEM_LIMIT} -i in -o out -- ./test-multiple-mutators >>errors 2>&1 + AFL_CUSTOM_MUTATOR_LIBRARY="./libexamplemutator.so;./libexamplemutator2.so" AFL_CUSTOM_MUTATOR_ONLY=1 ../afl-fuzz -V1 -m ${MEM_LIMIT} -i in -o out -- ./test-multiple-mutators >>errors 2>&1 } >>errors 2>&1 test -n "$( ls out/crashes/id:000000* 2>/dev/null )" && { # TODO: update here @@ -1016,11 +1017,11 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && { 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" + $ECHO "$GREY[*] running afl-fuzz for the Python mutator, this will take approx 5 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 + AFL_CUSTOM_MUTATOR_ONLY=1 ../afl-fuzz -V5 -m ${MEM_LIMIT} -i in -o out -- ./test-custom-mutator >>errors 2>&1 unset PYTHONPATH unset AFL_PYTHON_MODULE } >>errors 2>&1 @@ -1039,7 +1040,7 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && { # Clean rm -rf in out errors rm -rf ${CUSTOM_MUTATOR_PATH}/__pycache__/ - rm -f test-multiple-mutators + rm -f test-multiple-mutators test-custom-mutator libexamplemutator.so libexamplemutator2.so } || { ls . ls ${CUSTOM_MUTATOR_PATH} |