From 48655c2e128b0cb72f2ed1f5b2e4f8f9982a50de Mon Sep 17 00:00:00 2001 From: David Carlier Date: Tue, 31 Mar 2020 19:25:24 +0100 Subject: [PATCH 01/72] llvm_mode: using MaybeAlign wrapper over the deprecated setter. seems to be available even on LLVM 3.7 --- llvm_mode/afl-llvm-lto-instrumentation.so.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm_mode/afl-llvm-lto-instrumentation.so.cc b/llvm_mode/afl-llvm-lto-instrumentation.so.cc index 4bc16f17..89bedb8c 100644 --- a/llvm_mode/afl-llvm-lto-instrumentation.so.cc +++ b/llvm_mode/afl-llvm-lto-instrumentation.so.cc @@ -378,7 +378,7 @@ bool AFLLTOPass::runOnModule(Module &M) { M, Int32Ty, true, GlobalValue::ExternalLinkage, 0, "__afl_final_loc", 0, GlobalVariable::GeneralDynamicTLSModel, 0, false); ConstantInt *const_loc = ConstantInt::get(Int32Ty, afl_global_id); - AFLFinalLoc->setAlignment(4); + AFLFinalLoc->setAlignment(MaybeAlign(4)); AFLFinalLoc->setInitializer(const_loc); } From dfb0a65e0707a5b1fa8e87220b88d3a88a586308 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Wed, 1 Apr 2020 15:39:36 +0200 Subject: [PATCH 02/72] fix make target unit test (tested on Ubuntu 16.04) --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 61ce63bc..11db22e6 100644 --- a/Makefile +++ b/Makefile @@ -313,10 +313,10 @@ document: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/ $(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) $(CFLAGS_FLTO) -c test/unittests/unit_maybe_alloc.c -o test/unittests/unit_maybe_alloc.o + $(CC) $(CFLAGS) -c test/unittests/unit_maybe_alloc.c -o test/unittests/unit_maybe_alloc.o unit_maybe_alloc: test/unittests/unit_maybe_alloc.o - $(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf $(LDFLAGS) test/unittests/unit_maybe_alloc.o -o test/unittests/unit_maybe_alloc -ldl -lcmocka + $(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_maybe_alloc.o -o test/unittests/unit_maybe_alloc $(LDFLAGS) -lcmocka ./test/unittests/unit_maybe_alloc unit_preallocable: test/unittests/unit_preallocable.o From 36a03e3bc82c5ea4160937d3e3dc30a2a298216a Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Wed, 1 Apr 2020 15:51:34 +0200 Subject: [PATCH 03/72] add Make rule for new unit test --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 11db22e6..841384e0 100644 --- a/Makefile +++ b/Makefile @@ -315,12 +315,15 @@ document: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/ test/unittests/unit_maybe_alloc.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_maybe_alloc.c $(AFL_FUZZ_FILES) $(CC) $(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) -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) -lcmocka ./test/unittests/unit_maybe_alloc unit_preallocable: test/unittests/unit_preallocable.o - $(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf $(LDFLAGS) test/unittests/unit_preallocable.o -o test/unittests/unit_preallocable -ldl -lcmocka + $(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_preallocable.o -o test/unittests/unit_preallocable $(LDFLAGS) -lcmocka ./test/unittests/unit_preallocable From 9c1c1062be9e919c6f0dda8867ff9904f4fffc06 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 1 Apr 2020 15:55:16 +0200 Subject: [PATCH 04/72] added prealloc testcase --- test/unittests/unit_preallocable.c | 111 +++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 test/unittests/unit_preallocable.c diff --git a/test/unittests/unit_preallocable.c b/test/unittests/unit_preallocable.c new file mode 100644 index 00000000..8cd36165 --- /dev/null +++ b/test/unittests/unit_preallocable.c @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include +/* cmocka < 1.0 didn't support these features we need */ +#ifndef assert_ptr_equal +#define assert_ptr_equal(a, b) \ + _assert_int_equal(cast_ptr_to_largest_integral_type(a), \ + cast_ptr_to_largest_integral_type(b), \ + __FILE__, __LINE__) +#define CMUnitTest UnitTest +#define cmocka_unit_test unit_test +#define cmocka_run_group_tests(t, setup, teardown) run_tests(t) +#endif + + +extern void mock_assert(const int result, const char* const expression, + const char * const file, const int line); +#undef assert +#define assert(expression) \ + mock_assert((int)(expression), #expression, __FILE__, __LINE__); + +#include "afl-prealloc.h" + +/* remap exit -> assert, then use cmocka's mock_assert + (compile with `--wrap=exit`) */ +extern void exit(int status); +extern void __real_exit(int status); +void __wrap_exit(int status) { + assert(0); +} + +/* ignore all printfs */ +extern int printf(const char *format, ...); +extern int __real_printf(const char *format, ...); +int __wrap_printf(const char *format, ...) { + return 1; +} + +typedef struct prealloc_me +{ + PREALLOCABLE; + + u8 *content[128]; + +} prealloc_me_t; + +#define PREALLOCED_BUF_SIZE (64) +prealloc_me_t prealloc_me_buf[PREALLOCED_BUF_SIZE]; +size_t prealloc_me_size = 0; + +static void test_alloc_free(void **state) { + + prealloc_me_t *prealloced = NULL; + PRE_ALLOC(prealloced, prealloc_me_buf, PREALLOCED_BUF_SIZE, prealloc_me_size); + assert_non_null(prealloced); + PRE_FREE(prealloced, prealloc_me_size); + +} + +static void test_prealloc_overflow(void **state) { + + u32 i = 0; + prealloc_me_t *prealloced[PREALLOCED_BUF_SIZE + 10]; + + for (i = 0; i < PREALLOCED_BUF_SIZE + 10; i++) { + + PRE_ALLOC(prealloced[i], prealloc_me_buf, PREALLOCED_BUF_SIZE, prealloc_me_size); + assert_non_null(prealloced[i]); + + } + assert_int_equal(prealloced[0]->pre_status, PRE_STATUS_USED); + assert_int_equal(prealloced[PREALLOCED_BUF_SIZE]->pre_status, PRE_STATUS_MALLOC); + + PRE_FREE(prealloced[20], prealloc_me_size); + PRE_ALLOC(prealloced[20], prealloc_me_buf, PREALLOCED_BUF_SIZE, prealloc_me_size); + assert_non_null(prealloced[20]); + assert_int_equal(prealloced[20]->pre_status, PRE_STATUS_USED); + + PRE_FREE(prealloced[PREALLOCED_BUF_SIZE], prealloc_me_size); + PRE_FREE(prealloced[0], prealloc_me_size); + PRE_ALLOC(prealloced[PREALLOCED_BUF_SIZE], prealloc_me_buf, PREALLOCED_BUF_SIZE, prealloc_me_size); + assert_non_null(prealloced[PREALLOCED_BUF_SIZE]); + /* there should be space now! */ + assert_int_equal(prealloced[PREALLOCED_BUF_SIZE]->pre_status, PRE_STATUS_USED); + + PRE_ALLOC(prealloced[0], prealloc_me_buf, PREALLOCED_BUF_SIZE, prealloc_me_size); + assert_non_null(prealloced[0]); + /* no more space */ + assert_int_equal(prealloced[0]->pre_status, PRE_STATUS_MALLOC); + + for (i = 0; i < PREALLOCED_BUF_SIZE + 10; i++) { + + PRE_FREE(prealloced[i], prealloc_me_size); + + } + +} + +int main(int argc, char **argv) { + + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_alloc_free), + cmocka_unit_test(test_prealloc_overflow), + }; + + //return cmocka_run_group_tests (tests, setup, teardown); + return cmocka_run_group_tests (tests, NULL, NULL); + +} From 0fac7bd373ea2b578ea7d821f06f15ba3dcb0bad Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 1 Apr 2020 15:56:17 +0200 Subject: [PATCH 05/72] added (broken) list test --- Makefile | 13 +++- test/unittests/unit_list.c | 127 +++++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 test/unittests/unit_list.c diff --git a/Makefile b/Makefile index 841384e0..ab94beff 100644 --- a/Makefile +++ b/Makefile @@ -322,12 +322,21 @@ 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) -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) $(CFLAGS_FLTO) -c test/unittests/unit_list.c -o test/unittests/unit_list.o + +unit_list: test/unittests/unit_list.o + $(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf $(LDFLAGS) test/unittests/unit_list.o -o test/unittests/unit_list -ldl -lcmocka + ./test/unittests/unit_list + +test/unittests/preallocable.o : $(COMM_HDR) include/afl-prealloc.h test/unittests/preallocable.c $(AFL_FUZZ_FILES) + $(CC) $(CFLAGS) $(CFLAGS_FLTO) -c test/unittests/preallocable.c -o test/unittests/preallocable.o + unit_preallocable: test/unittests/unit_preallocable.o $(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_preallocable.o -o test/unittests/unit_preallocable $(LDFLAGS) -lcmocka ./test/unittests/unit_preallocable - -unit: unit_maybe_alloc unit_preallocable +unit: unit_maybe_alloc unit_preallocable unit_list code-format: ./.custom-format.py -i src/*.c diff --git a/test/unittests/unit_list.c b/test/unittests/unit_list.c new file mode 100644 index 00000000..6e0be7b6 --- /dev/null +++ b/test/unittests/unit_list.c @@ -0,0 +1,127 @@ +#include +#include +#include +#include +#include +/* cmocka < 1.0 didn't support these features we need */ +#ifndef assert_ptr_equal +#define assert_ptr_equal(a, b) \ + _assert_int_equal(cast_ptr_to_largest_integral_type(a), \ + cast_ptr_to_largest_integral_type(b), \ + __FILE__, __LINE__) +#define CMUnitTest UnitTest +#define cmocka_unit_test unit_test +#define cmocka_run_group_tests(t, setup, teardown) run_tests(t) +#endif + + +extern void mock_assert(const int result, const char* const expression, + const char * const file, const int line); +#undef assert +#define assert(expression) \ + mock_assert((int)(expression), #expression, __FILE__, __LINE__); + +#include "list.h" + +/* remap exit -> assert, then use cmocka's mock_assert + (compile with `--wrap=exit`) */ +extern void exit(int status); +extern void __real_exit(int status); +void __wrap_exit(int status) { + assert(0); +} + +/* ignore all printfs */ +extern int printf(const char *format, ...); +extern int __real_printf(const char *format, ...); +int __wrap_printf(const char *format, ...) { + return 1; +} + +list_t testlist; + +static void test_contains(void **state) { + + u32 one = 1; + u32 two = 2; + + list_append(&testlist, &one); + assert_true(list_contains(&testlist, &one)); + assert_false(list_contains(&testlist, &two)); + list_remove(&testlist, &one); + assert_false(list_contains(&testlist, &one)); +} + +static void test_foreach(void **state) { + + u32 one = 1; + u32 two = 2; + u32 result = 0; + + list_append(&testlist, &one); + list_append(&testlist, &two); + list_append(&testlist, &one); + + /* The list is for pointers, so int doesn't work as type directly */ + LIST_FOREACH(&testlist, u32, { + result += *el; + }); + + assert_int_equal(result, 4); + +} + +static void test_long_list(void **state) { + + u32 result1 = 0; + u32 result2 = 0; + u32 i; + + u32 vals[100]; + + for (i = 0; i < 100; i++) { + vals[i] = i; + } + + for (i = 0; i < 100; i++) { + list_append(&testlist, &vals[i]); + } + LIST_FOREACH(&testlist, u32, { + result1 += *el; + }); + printf("removing %d\n", vals[50]); + list_remove(&testlist, &vals[50]); + + LIST_FOREACH(&testlist, u32, { + printf("var: %d\n", *el); + result2 += *el; + }); + assert_int_not_equal(result1, result2); + assert_int_equal(result1 + 50, result2); + + result1 = 0; + LIST_FOREACH_CLEAR(&testlist, u32, { + result1 += *el; + }); + assert_int_equal(result1, result2); + + result1 = 0; + LIST_FOREACH(&testlist, u32, { + result1 += *el; + }); + assert_int_equal(result1, 0); + +} + +int main(int argc, char **argv) { + + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_contains), + cmocka_unit_test(test_foreach), + cmocka_unit_test(test_long_list), + }; + + //return cmocka_run_group_tests (tests, setup, teardown); + return cmocka_run_group_tests (tests, NULL, NULL); + +} From 4aec6dabdefda50a5c16637cea2300b63723a1ba Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Wed, 1 Apr 2020 16:18:44 +0200 Subject: [PATCH 06/72] fixing unit tests (again) remove CFLAGS_FLTO, put LDFLAGS near the end --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index ab94beff..23fcaeca 100644 --- a/Makefile +++ b/Makefile @@ -323,10 +323,10 @@ unit_maybe_alloc: test/unittests/unit_maybe_alloc.o ./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) $(CFLAGS_FLTO) -c test/unittests/unit_list.c -o test/unittests/unit_list.o + $(CC) $(CFLAGS) -c test/unittests/unit_list.c -o test/unittests/unit_list.o unit_list: test/unittests/unit_list.o - $(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf $(LDFLAGS) test/unittests/unit_list.o -o test/unittests/unit_list -ldl -lcmocka + $(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_list.o -o test/unittests/unit_list $(LDFLAGS) -lcmocka ./test/unittests/unit_list test/unittests/preallocable.o : $(COMM_HDR) include/afl-prealloc.h test/unittests/preallocable.c $(AFL_FUZZ_FILES) From b5c5496b2fa9703bcdf7ab685499ae976a9107f6 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 1 Apr 2020 18:19:43 +0200 Subject: [PATCH 07/72] list testcase added --- .gitignore | 2 ++ Makefile | 26 ++++++++++++++------------ include/list.h | 3 ++- test/unittests/unit_list.c | 2 +- test/unittests/unit_maybe_alloc.c | 4 +++- 5 files changed, 22 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index 2687f959..c8a92b7d 100644 --- a/.gitignore +++ b/.gitignore @@ -47,3 +47,5 @@ unicorn_mode/samples/*/\.test-* unicorn_mode/samples/*/output/ core\.* test/unittests/unit_maybe_alloc +test/unittests/unit_preallocable +test/unittests/unit_list diff --git a/Makefile b/Makefile index 23fcaeca..a193f357 100644 --- a/Makefile +++ b/Makefile @@ -64,8 +64,8 @@ ifneq "$(shell uname -m)" "x86_64" endif endif -CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT) -override CFLAGS += -Wall -g -Wno-pointer-sign -D_FORTIFY_SOURCE=2 \ +CFLAGS ?= -O2 -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)\" @@ -151,10 +151,13 @@ ifdef STATIC LDFLAGS += -lm -lpthread -lz -lutil endif +ASAN_CFLAGS=-fsanitize=address -fstack-protector-all +ASAN_LDFLAGS+=-fsanitize=address -fstack-protector-all + ifdef ASAN_BUILD $(info Compiling ASAN version of binaries) - CFLAGS+=-fsanitize=address -fstack-protector-all - LDFLAGS+=-fsanitize=address -fstack-protector-all + CFLAGS+="$ASAN_CFLAGS" + LDFLAGS+="$ASAN_LDFLAGS" endif ifdef PROFILING @@ -313,27 +316,27 @@ document: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/ $(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) -c test/unittests/unit_maybe_alloc.c -o test/unittests/unit_maybe_alloc.o + $(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) -c test/unittests/unit_preallocable.c -o test/unittests/unit_preallocable.o + $(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) -lcmocka + $(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) -c test/unittests/unit_list.c -o test/unittests/unit_list.o + $(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) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_list.o -o test/unittests/unit_list $(LDFLAGS) -lcmocka + $(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) $(CFLAGS_FLTO) -c test/unittests/preallocable.c -o test/unittests/preallocable.o + $(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) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_preallocable.o -o test/unittests/unit_preallocable $(LDFLAGS) -lcmocka + $(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 @@ -472,4 +475,3 @@ install: all $(MANPAGES) install -m 644 docs/*.md $${DESTDIR}$(DOC_PATH) cp -r testcases/ $${DESTDIR}$(MISC_PATH) cp -r dictionaries/ $${DESTDIR}$(MISC_PATH) - diff --git a/include/list.h b/include/list.h index c67b24b2..a0f23c85 100644 --- a/include/list.h +++ b/include/list.h @@ -56,7 +56,8 @@ typedef struct list { static inline element_t *get_head(list_t *list) { - return &list->element_prealloc_buf[0]; + /* The first element is the head */ + return list->element_prealloc_buf; } diff --git a/test/unittests/unit_list.c b/test/unittests/unit_list.c index 6e0be7b6..7e8ef363 100644 --- a/test/unittests/unit_list.c +++ b/test/unittests/unit_list.c @@ -93,7 +93,7 @@ static void test_long_list(void **state) { list_remove(&testlist, &vals[50]); LIST_FOREACH(&testlist, u32, { - printf("var: %d\n", *el); + // printf("var: %d\n", *el); result2 += *el; }); assert_int_not_equal(result1, result2); diff --git a/test/unittests/unit_maybe_alloc.c b/test/unittests/unit_maybe_alloc.c index 6a165dd4..a856fa08 100644 --- a/test/unittests/unit_maybe_alloc.c +++ b/test/unittests/unit_maybe_alloc.c @@ -75,7 +75,7 @@ static void test_zero_size() { char *buf = NULL; size_t size = 0; - //assert_non_null(maybe_grow(BUF_PARAMS, 0)); + assert_non_null(maybe_grow(BUF_PARAMS, 0)); free(buf); buf = NULL; size = 0; @@ -87,6 +87,8 @@ static void test_zero_size() { expect_assert_failure(ck_maybe_grow(BUF_PARAMS, 0)); + ck_free(ptr); + } static void test_unchanged_size(void **state) { From db3645c76bc8e36bfdbf615ed851c4d8d290930b Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 1 Apr 2020 18:22:02 +0200 Subject: [PATCH 08/72] O3 again --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a193f357..b5d0fd97 100644 --- a/Makefile +++ b/Makefile @@ -64,7 +64,7 @@ ifneq "$(shell uname -m)" "x86_64" endif endif -CFLAGS ?= -O2 -funroll-loops $(CFLAGS_OPT) -D_FORTIFY_SOURCE=2 +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)\" From 989a85bb054509f3b6c39670b56c5ff640431584 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 1 Apr 2020 18:56:59 +0200 Subject: [PATCH 09/72] makefile asan fix --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index b5d0fd97..29492bf0 100644 --- a/Makefile +++ b/Makefile @@ -156,8 +156,8 @@ ASAN_LDFLAGS+=-fsanitize=address -fstack-protector-all ifdef ASAN_BUILD $(info Compiling ASAN version of binaries) - CFLAGS+="$ASAN_CFLAGS" - LDFLAGS+="$ASAN_LDFLAGS" + CFLAGS+=$(ASAN_CFLAGS) + LDFLAGS+=$(ASAN_LDFLAGS) endif ifdef PROFILING From 1cce581ffe071c027d5af665cf9909e77886332e Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Wed, 1 Apr 2020 20:37:13 +0200 Subject: [PATCH 10/72] fix unit test case for long list --- test/unittests/unit_list.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/unittests/unit_list.c b/test/unittests/unit_list.c index 7e8ef363..03217112 100644 --- a/test/unittests/unit_list.c +++ b/test/unittests/unit_list.c @@ -83,6 +83,7 @@ static void test_long_list(void **state) { vals[i] = i; } + LIST_FOREACH_CLEAR(&testlist, void, {}); for (i = 0; i < 100; i++) { list_append(&testlist, &vals[i]); } @@ -97,7 +98,7 @@ static void test_long_list(void **state) { result2 += *el; }); assert_int_not_equal(result1, result2); - assert_int_equal(result1 + 50, result2); + assert_int_equal(result1, result2 + 50); result1 = 0; LIST_FOREACH_CLEAR(&testlist, u32, { From ef4eeede86d050c56689fd75aceef36000d91643 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 1 Apr 2020 20:42:50 +0200 Subject: [PATCH 11/72] el no longer has to be used in loop --- include/list.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/list.h b/include/list.h index a0f23c85..d9cd9d34 100644 --- a/include/list.h +++ b/include/list.h @@ -107,6 +107,7 @@ static inline void list_append(list_t *list, void *el) { if (!el_box) FATAL("foreach over uninitialized list"); \ while (el_box != head) { \ \ + __attribute__((unused)) \ type *el = (type *)((el_box)->data); \ /* get next so el_box can be unlinked */ \ element_t *next = el_box->next; \ From cb0bc98576ac0a7608b01571fea9ed5750190c82 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Thu, 2 Apr 2020 02:44:49 +0200 Subject: [PATCH 12/72] better asan --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 29492bf0..cb4bc653 100644 --- a/Makefile +++ b/Makefile @@ -151,8 +151,8 @@ ifdef STATIC LDFLAGS += -lm -lpthread -lz -lutil endif -ASAN_CFLAGS=-fsanitize=address -fstack-protector-all -ASAN_LDFLAGS+=-fsanitize=address -fstack-protector-all +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) @@ -182,7 +182,7 @@ endif all: test_x86 test_shm test_python ready $(PROGS) afl-as test_build all_done -man: $(MANPAGES) +man: $(MANPAGES) -$(MAKE) -C llvm_mode -$(MAKE) -C gcc_plugin From 0565fe4213b96a778895799eb61743166be35a0d Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Thu, 2 Apr 2020 12:24:39 +0200 Subject: [PATCH 13/72] 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 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! From 0c76d7e6211f39b3f233c70ace6fd746df30a140 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 2 Apr 2020 14:37:28 +0200 Subject: [PATCH 14/72] remove maybe_linking artifacts --- llvm_mode/afl-clang-fast.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index de8d3410..5fc09252 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -136,7 +136,7 @@ static void find_obj(u8 *argv0) { static void edit_params(u32 argc, char **argv, char **envp) { - u8 fortify_set = 0, asan_set = 0, x_set = 0, maybe_linking = 1, bit_mode = 0; + u8 fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0; u8 has_llvm_config = 0; u8 *name; @@ -323,8 +323,6 @@ static void edit_params(u32 argc, char **argv, char **envp) { /* Detect stray -v calls from ./configure scripts. */ - if (argc == 1 && !strcmp(argv[1], "-v")) maybe_linking = 0; - while (--argc) { u8 *cur = *(++argv); @@ -335,16 +333,11 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (!strcmp(cur, "-x")) x_set = 1; - if (!strcmp(cur, "-c") || !strcmp(cur, "-S") || !strcmp(cur, "-E")) - maybe_linking = 0; - if (!strcmp(cur, "-fsanitize=address") || !strcmp(cur, "-fsanitize=memory")) asan_set = 1; if (strstr(cur, "FORTIFY_SOURCE")) fortify_set = 1; - if (!strcmp(cur, "-shared")) maybe_linking = 0; - if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined")) continue; @@ -498,8 +491,6 @@ static void edit_params(u32 argc, char **argv, char **envp) { #endif /* ^__APPLE__ */ "_I(); } while (0)"; - // if (maybe_linking) { - if (x_set) { cc_params[cc_par_cnt++] = "-x"; @@ -534,8 +525,6 @@ static void edit_params(u32 argc, char **argv, char **envp) { #endif - // } - cc_params[cc_par_cnt] = NULL; } From 38b14c5c4495e6ab2a4e25642b5c9aa368a724cc Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Thu, 2 Apr 2020 15:18:05 +0200 Subject: [PATCH 15/72] fix make install --- GNUmakefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 8e0f0d97..1409b428 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -455,14 +455,14 @@ install: all $(MANPAGES) 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 afl-clang-fast ]; then $(MAKE) -C llvm_mode install; fi 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 + if [ -f socketfuzz32.so -o -f socketfuzz64.so ]; then $(MAKE) -C examples/socket_fuzzing install; fi + if [ -f argvfuzz32.so -o -f argvfuzz64.so ]; then $(MAKE) -C examples/argv_fuzzing install; fi 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 From 26e45e41ed05431341a3c017db649ffa8fee38ef Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 2 Apr 2020 15:38:32 +0200 Subject: [PATCH 16/72] remove MaybeAlign --- llvm_mode/afl-llvm-lto-instrumentation.so.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm_mode/afl-llvm-lto-instrumentation.so.cc b/llvm_mode/afl-llvm-lto-instrumentation.so.cc index 89bedb8c..4bc16f17 100644 --- a/llvm_mode/afl-llvm-lto-instrumentation.so.cc +++ b/llvm_mode/afl-llvm-lto-instrumentation.so.cc @@ -378,7 +378,7 @@ bool AFLLTOPass::runOnModule(Module &M) { M, Int32Ty, true, GlobalValue::ExternalLinkage, 0, "__afl_final_loc", 0, GlobalVariable::GeneralDynamicTLSModel, 0, false); ConstantInt *const_loc = ConstantInt::get(Int32Ty, afl_global_id); - AFLFinalLoc->setAlignment(MaybeAlign(4)); + AFLFinalLoc->setAlignment(4); AFLFinalLoc->setInitializer(const_loc); } From 7114663f52f095d549e438e7e1b091b172c6627f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 2 Apr 2020 16:41:33 +0200 Subject: [PATCH 17/72] small enhancements and code-format --- include/afl-fuzz.h | 6 +++--- include/list.h | 35 +++++++++++++++++------------------ src/afl-fuzz-stats.c | 26 +++++++++++++++----------- src/afl-fuzz.c | 6 +++++- 4 files changed, 40 insertions(+), 33 deletions(-) diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index a9165064..56135d0e 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -935,13 +935,13 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len, static inline u32 rand_below(afl_state_t *afl, u32 limit) { #ifdef HAVE_ARC4RANDOM - if (afl->fixed_seed) { return random() % limit; } + if (unlikely(afl->fixed_seed)) { return random() % limit; } /* The boundary not being necessarily a power of 2, we need to ensure the result uniformity. */ return arc4random_uniform(limit); #else - if (!afl->fixed_seed && unlikely(!afl->rand_cnt--)) { + if (unlikely(!afl->rand_cnt--) && likely(!afl->fixed_seed)) { ck_read(afl->fsrv.dev_urandom_fd, &afl->rand_seed, sizeof(afl->rand_seed), "/dev/urandom"); @@ -957,7 +957,7 @@ static inline u32 rand_below(afl_state_t *afl, u32 limit) { static inline u32 get_rand_seed(afl_state_t *afl) { - if (afl->fixed_seed) return (u32)afl->init_seed; + if (unlikely(afl->fixed_seed)) return (u32)afl->init_seed; return afl->rand_seed[0]; } diff --git a/include/list.h b/include/list.h index d9cd9d34..e93b4e8f 100644 --- a/include/list.h +++ b/include/list.h @@ -98,24 +98,23 @@ static inline void list_append(list_t *list, void *el) { A return from this block will return from calling func. */ -#define LIST_FOREACH(list, type, block) \ - do { \ - \ - list_t * li = (list); \ - element_t *head = get_head((li)); \ - element_t *el_box = (head)->next; \ - if (!el_box) FATAL("foreach over uninitialized list"); \ - while (el_box != head) { \ - \ - __attribute__((unused)) \ - type *el = (type *)((el_box)->data); \ - /* get next so el_box can be unlinked */ \ - element_t *next = el_box->next; \ - {block}; \ - el_box = next; \ - \ - } \ - \ +#define LIST_FOREACH(list, type, block) \ + do { \ + \ + list_t * li = (list); \ + element_t *head = get_head((li)); \ + element_t *el_box = (head)->next; \ + if (!el_box) FATAL("foreach over uninitialized list"); \ + while (el_box != head) { \ + \ + __attribute__((unused)) type *el = (type *)((el_box)->data); \ + /* get next so el_box can be unlinked */ \ + element_t *next = el_box->next; \ + {block}; \ + el_box = next; \ + \ + } \ + \ } while (0); /* In foreach: remove the current el from the list */ diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 98a97a34..169dbf2a 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -36,6 +36,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, u8 fn[PATH_MAX]; s32 fd; FILE * f; + uint32_t t_bytes = count_non_255_bytes(afl->virgin_bits); snprintf(fn, PATH_MAX, "%s/fuzzer_stats", afl->out_dir); @@ -97,6 +98,8 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, "exec_timeout : %u\n" "slowest_exec_ms : %u\n" "peak_rss_mb : %lu\n" + "var_byte_count : %u\n" + "found_edges : %u\n" "afl_banner : %s\n" "afl_version : " VERSION "\n" @@ -119,9 +122,10 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, #else (unsigned long int)(rus.ru_maxrss >> 10), #endif - afl->use_banner, afl->unicorn_mode ? "unicorn" : "", - afl->qemu_mode ? "qemu " : "", afl->dumb_mode ? " dumb " : "", - afl->no_forkserver ? "no_fsrv " : "", afl->crash_mode ? "crash " : "", + afl->var_byte_count, t_bytes, afl->use_banner, + afl->unicorn_mode ? "unicorn" : "", afl->qemu_mode ? "qemu " : "", + afl->dumb_mode ? " dumb " : "", afl->no_forkserver ? "no_fsrv " : "", + afl->crash_mode ? "crash " : "", afl->persistent_mode ? "persistent " : "", afl->deferred_mode ? "deferred " : "", (afl->unicorn_mode || afl->qemu_mode || afl->dumb_mode || @@ -257,7 +261,7 @@ void show_stats(afl_state_t *afl) { t_byte_ratio = ((double)t_bytes * 100) / MAP_SIZE; if (t_bytes) - stab_ratio = 100 - ((double)afl->var_byte_count) * 100 / t_bytes; + stab_ratio = 100 - (((double)afl->var_byte_count) * 100) / t_bytes; else stab_ratio = 100; @@ -361,9 +365,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 +449,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 +480,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 +556,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"); diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 6e86285d..ad4f5b6b 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -691,6 +691,7 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->fixed_seed) OKF("Running with fixed seed: %u", (u32)afl->init_seed); srandom((u32)afl->init_seed); + srand((u32)afl->init_seed); // in case it is a different implementation if (afl->use_radamsa) { @@ -721,11 +722,14 @@ int main(int argc, char **argv_orig, char **envp) { } -#if defined(__SANITIZE_ADDRESS__) +#if defined(__SANITIZE_ADDRESS__) if (afl->fsrv.mem_limit) { + WARNF("in the ASAN build we disable all memory limits"); afl->fsrv.mem_limit = 0; + } + #endif setup_signal_handlers(); From 2ae0208d3be8ffba76f6cf370c99efa05429ad69 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 2 Apr 2020 16:46:31 +0200 Subject: [PATCH 18/72] fix UI bug for bit flip yields --- src/afl-fuzz-stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 169dbf2a..77bbe023 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -571,7 +571,7 @@ void show_stats(afl_state_t *afl) { 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(4), afl->stage_finds[STAGE_FLIP4]), u_stringify_int(IB(5), afl->stage_cycles[STAGE_FLIP4])); } From cc65e91eeba541aa9e3b42e81df3d752814eff21 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Thu, 2 Apr 2020 17:00:35 +0200 Subject: [PATCH 19/72] 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 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 From dc0369eb10a92edd62ca2f0a473920ec36dfea53 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Thu, 2 Apr 2020 22:14:39 +0200 Subject: [PATCH 20/72] fix make install regarding MANPAGES target --- GNUmakefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 1409b428..c03d635c 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -183,8 +183,6 @@ 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 From 97cae2df9975589eb05a543f92c6ba232242fd7b Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 2 Apr 2020 23:33:55 +0200 Subject: [PATCH 21/72] no random timing for -s fixed_seed --- src/afl-fuzz-queue.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 61bf62f5..92cbab6f 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -186,7 +186,7 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { u64 fav_factor; u64 fuzz_p2 = next_pow2(q->n_fuzz); - if (afl->schedule == MMOPT || afl->schedule == RARE) + if (afl->schedule == MMOPT || afl->schedule == RARE || unlikely(afl->fixed_seed)) fav_factor = q->len << 2; else fav_factor = q->exec_us * q->len; @@ -203,7 +203,7 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { u64 top_rated_fav_factor; u64 top_rated_fuzz_p2 = next_pow2(afl->top_rated[i]->n_fuzz); - if (afl->schedule == MMOPT || afl->schedule == RARE) + if (afl->schedule == MMOPT || afl->schedule == RARE || unlikely(afl->fixed_seed)) top_rated_fav_factor = afl->top_rated[i]->len << 2; else top_rated_fav_factor = @@ -214,8 +214,17 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { else if (fuzz_p2 == top_rated_fuzz_p2) if (fav_factor > top_rated_fav_factor) continue; - if (fav_factor > afl->top_rated[i]->exec_us * afl->top_rated[i]->len) - continue; + if (afl->schedule == MMOPT || afl->schedule == RARE || unlikely(afl->fixed_seed)) { + + if (fav_factor > afl->top_rated[i]->len << 2) + continue; + + } else { + + if (fav_factor > afl->top_rated[i]->exec_us * afl->top_rated[i]->len) + continue; + + } /* Looks like we're going to win. Decrease ref count for the previous winner, discard its afl->fsrv.trace_bits[] if necessary. */ @@ -330,7 +339,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { // Longer execution time means longer work on the input, the deeper in // coverage, the better the fuzzing, right? -mh - if (afl->schedule != MMOPT && afl->schedule != RARE) { + if (afl->schedule != MMOPT && afl->schedule != RARE && likely(!afl->fixed_seed)) { if (q->exec_us * 0.1 > avg_exec_us) perf_score = 10; From ffb4767fc1adf2383173e5655d4f1fcf7e0982b6 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Fri, 3 Apr 2020 09:39:09 +0200 Subject: [PATCH 22/72] custom mutator readme --- examples/custom_mutators/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/custom_mutators/README.md b/examples/custom_mutators/README.md index 93f824cd..32acbd30 100644 --- a/examples/custom_mutators/README.md +++ b/examples/custom_mutators/README.md @@ -20,3 +20,9 @@ common.py - this can be used for common functions and helpers. wrapper_afl_min.py - mutation of XML documents, loads XmlMutatorMin.py XmlMutatorMin.py - module for XML mutation + +custom_mutator_helpers.h is an header that defines some helper routines +like surgical_havoc_mutate() that allow to perform a randomly chosen +mutation from a subset of the havoc mutations. +If you do so, you have to specify -I /path/to/AFLplusplus/include when +compiling. From 5340f2f2eba643d43311eba207e8185723dd2f06 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 3 Apr 2020 10:31:37 +0200 Subject: [PATCH 23/72] code format, small improvements --- docs/status_screen.md | 2 ++ src/afl-fuzz-bitmap.c | 18 ++++++++---------- src/afl-fuzz-queue.c | 19 +++++++++++-------- src/afl-fuzz-run.c | 9 +++------ src/afl-fuzz-stats.c | 8 ++++---- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/docs/status_screen.md b/docs/status_screen.md index 8b3d5bda..a66558b9 100644 --- a/docs/status_screen.md +++ b/docs/status_screen.md @@ -400,6 +400,8 @@ directory. This includes: - `exec_timeout` - the -t command line value - `slowest_exec_ms` - real time of the slowest execution in ms - `peak_rss_mb` - max rss usage reached during fuzzing in MB + - `edges_found` - how many edges have been found + - `var_byte_count` - how many edges are non-deterministic - `afl_banner` - banner text (e.g. the target name) - `afl_version` - the version of afl used - `target_mode` - default, persistent, qemu, unicorn, dumb diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 8ca286b2..63c3a2c2 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -177,8 +177,6 @@ u32 count_bits(u8 *mem) { } -#define FF(_b) (0xff << ((_b) << 3)) - /* Count the number of bytes set in the bitmap. Called fairly sporadically, mostly to update the status screen or calibrate and examine confirmed new paths. */ @@ -194,10 +192,10 @@ u32 count_bytes(u8 *mem) { u32 v = *(ptr++); if (!v) continue; - if (v & FF(0)) ++ret; - if (v & FF(1)) ++ret; - if (v & FF(2)) ++ret; - if (v & FF(3)) ++ret; + if (v & 0x000000ff) ++ret; + if (v & 0x0000ff00) ++ret; + if (v & 0x00ff0000) ++ret; + if (v & 0xff000000) ++ret; } @@ -222,10 +220,10 @@ u32 count_non_255_bytes(u8 *mem) { case. */ if (v == 0xffffffff) continue; - if ((v & FF(0)) != FF(0)) ++ret; - if ((v & FF(1)) != FF(1)) ++ret; - if ((v & FF(2)) != FF(2)) ++ret; - if ((v & FF(3)) != FF(3)) ++ret; + if ((v & 0x000000ff) != 0x000000ff) ++ret; + if ((v & 0x0000ff00) != 0x0000ff00) ++ret; + if ((v & 0x00ff0000) != 0x00ff0000) ++ret; + if ((v & 0xff000000) != 0xff000000) ++ret; } diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 92cbab6f..6c687ae4 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -186,7 +186,8 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { u64 fav_factor; u64 fuzz_p2 = next_pow2(q->n_fuzz); - if (afl->schedule == MMOPT || afl->schedule == RARE || unlikely(afl->fixed_seed)) + if (afl->schedule == MMOPT || afl->schedule == RARE || + unlikely(afl->fixed_seed)) fav_factor = q->len << 2; else fav_factor = q->exec_us * q->len; @@ -203,7 +204,8 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { u64 top_rated_fav_factor; u64 top_rated_fuzz_p2 = next_pow2(afl->top_rated[i]->n_fuzz); - if (afl->schedule == MMOPT || afl->schedule == RARE || unlikely(afl->fixed_seed)) + if (afl->schedule == MMOPT || afl->schedule == RARE || + unlikely(afl->fixed_seed)) top_rated_fav_factor = afl->top_rated[i]->len << 2; else top_rated_fav_factor = @@ -214,16 +216,16 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { else if (fuzz_p2 == top_rated_fuzz_p2) if (fav_factor > top_rated_fav_factor) continue; - if (afl->schedule == MMOPT || afl->schedule == RARE || unlikely(afl->fixed_seed)) { + if (afl->schedule == MMOPT || afl->schedule == RARE || + unlikely(afl->fixed_seed)) { - if (fav_factor > afl->top_rated[i]->len << 2) - continue; + if (fav_factor > afl->top_rated[i]->len << 2) continue; - } else { + } else { if (fav_factor > afl->top_rated[i]->exec_us * afl->top_rated[i]->len) continue; - + } /* Looks like we're going to win. Decrease ref count for the @@ -339,7 +341,8 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { // Longer execution time means longer work on the input, the deeper in // coverage, the better the fuzzing, right? -mh - if (afl->schedule != MMOPT && afl->schedule != RARE && likely(!afl->fixed_seed)) { + if (afl->schedule != MMOPT && afl->schedule != RARE && + likely(!afl->fixed_seed)) { if (q->exec_us * 0.1 > avg_exec_us) perf_score = 10; diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 5875eb68..47f6e9d9 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -354,17 +354,14 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, for (i = 0; i < MAP_SIZE; ++i) { - if (!afl->var_bytes[i] && - afl->first_trace[i] != afl->fsrv.trace_bits[i]) { - + if (unlikely(!afl->var_bytes[i]) && + unlikely(afl->first_trace[i] != afl->fsrv.trace_bits[i])) afl->var_bytes[i] = 1; - afl->stage_max = CAL_CYCLES_LONG; - - } } var_detected = 1; + afl->stage_max = CAL_CYCLES_LONG; } else { diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 77bbe023..d9f8c99c 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -98,8 +98,8 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, "exec_timeout : %u\n" "slowest_exec_ms : %u\n" "peak_rss_mb : %lu\n" + "edges_found : %u\n" "var_byte_count : %u\n" - "found_edges : %u\n" "afl_banner : %s\n" "afl_version : " VERSION "\n" @@ -122,7 +122,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, #else (unsigned long int)(rus.ru_maxrss >> 10), #endif - afl->var_byte_count, t_bytes, afl->use_banner, + t_bytes, afl->var_byte_count, afl->use_banner, afl->unicorn_mode ? "unicorn" : "", afl->qemu_mode ? "qemu " : "", afl->dumb_mode ? " dumb " : "", afl->no_forkserver ? "no_fsrv " : "", afl->crash_mode ? "crash " : "", @@ -260,8 +260,8 @@ void show_stats(afl_state_t *afl) { t_bytes = count_non_255_bytes(afl->virgin_bits); t_byte_ratio = ((double)t_bytes * 100) / MAP_SIZE; - if (t_bytes) - stab_ratio = 100 - (((double)afl->var_byte_count) * 100) / t_bytes; + if (likely(t_bytes) && unlikely(afl->var_byte_count)) + stab_ratio = 100 - (((double)afl->var_byte_count * 100) / t_bytes); else stab_ratio = 100; From 3f2859ec1623b772bd5df39274946cfcc3c29e00 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 3 Apr 2020 10:43:52 +0200 Subject: [PATCH 24/72] unit tests cleaning --- GNUmakefile | 5 ++++- test/unittests/unit_list.c | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index c03d635c..ff27e125 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -337,7 +337,10 @@ 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 +unit_clean: + @rm -f ./test/unittests/unit_preallocable ./test/unittests/unit_list ./test/unittests/unit_maybe_alloc test/unittests/*.o + +unit: unit_maybe_alloc unit_preallocable unit_list unit_clean code-format: ./.custom-format.py -i src/*.c diff --git a/test/unittests/unit_list.c b/test/unittests/unit_list.c index 03217112..11d3227c 100644 --- a/test/unittests/unit_list.c +++ b/test/unittests/unit_list.c @@ -90,7 +90,7 @@ static void test_long_list(void **state) { LIST_FOREACH(&testlist, u32, { result1 += *el; }); - printf("removing %d\n", vals[50]); + //printf("removing %d\n", vals[50]); list_remove(&testlist, &vals[50]); LIST_FOREACH(&testlist, u32, { From 6b5d5b11b0ecaeb018070f39174b1d001aa0cb4d Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 3 Apr 2020 14:00:29 +0200 Subject: [PATCH 25/72] update todo --- TODO.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index 1a34fba4..569735fe 100644 --- a/TODO.md +++ b/TODO.md @@ -2,7 +2,15 @@ ## Roadmap 2.63 - - get "no global vars" working + - complete custom_mutator API changes and documentation + - fix stability calculation bug + - libradamsa as a custom module? + + +## Roadmap 2.64 + + - context sensitive branch coverage in llvm_mode + ## Further down the road From 064131887b73f59b1512ab898d5fb3f7d3b700c4 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 3 Apr 2020 14:17:31 +0200 Subject: [PATCH 26/72] update todo --- TODO.md | 1 + 1 file changed, 1 insertion(+) diff --git a/TODO.md b/TODO.md index 569735fe..91297332 100644 --- a/TODO.md +++ b/TODO.md @@ -10,6 +10,7 @@ ## Roadmap 2.64 - context sensitive branch coverage in llvm_mode + - random crc32 HASH_CONST per run? because with 65536 paths we have collisions ## Further down the road From a9261c6d641f2d48053cb96c785e4e59bb0b0c50 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 4 Apr 2020 00:15:08 +0200 Subject: [PATCH 27/72] portable version of Makefile (tested with bsdmake and GNUmake) --- qemu_mode/unsigaction/Makefile | 36 ++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/qemu_mode/unsigaction/Makefile b/qemu_mode/unsigaction/Makefile index 0b306dde..d5063dab 100644 --- a/qemu_mode/unsigaction/Makefile +++ b/qemu_mode/unsigaction/Makefile @@ -1,2 +1,34 @@ -all: - @echo please use GNU make, thanks! +# +# 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 +# +.POSIX: + +_UNIQ=_QINU_ + +TARGETCANDIDATES=unsigaction32.so unsigaction64.so +_TARGETS=$(_UNIQ)$(AFL_NO_X86)$(_UNIQ) +__TARGETS=$(_TARGETS:$(_UNIQ)1$(_UNIQ)=) +TARGETS=$(__TARGETS:$(_UNIQ)$(_UNIQ)=$(TARGETCANDIDATES)) + +all: $(TARGETS) + @if [ "$(AFL_NO_X86)" != "" ]; then echo "[!] Note: skipping compilation of unsigaction (AFL_NO_X86 set)."; fi + +unsigaction32.so: + @$(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 + +unsigaction64.so: + $(CC) -m64 -fPIC -shared unsigaction.c -o unsigaction64.so + +clean: + rm -f unsigaction32.so unsigaction64.so From a7e9ce2e3370124e2175782f2c87eb7965a90e1d Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 4 Apr 2020 01:39:01 +0200 Subject: [PATCH 28/72] libtokencap, portable Makefile (for GNUmake and BSDmake) --- libtokencap/Makefile | 96 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 2 deletions(-) diff --git a/libtokencap/Makefile b/libtokencap/Makefile index 0b306dde..506d37cb 100644 --- a/libtokencap/Makefile +++ b/libtokencap/Makefile @@ -1,2 +1,94 @@ -all: - @echo please use GNU make, thanks! +# +# 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 -D_FORTIFY_SOURCE=2 +CFLAGS += -I ../include/ -Wall -g -Wno-pointer-sign + +UNAME_CMD=uname -s +_UNAME_S =$(shell $(UNAME_CMD)) # GNU make puts a space at the end, great!! +UNAME_S =$(_UNAME_S: =) +UNAME_S:sh=$(UNAME_CMD) # BSD make +_UNIQ=_QINU_ + + _OS_DL = $(_UNIQ)$(UNAME_S) + __OS_DL = $(_OS_DL:$(_UNIQ)Linux=$(_UNIQ)) + ___OS_DL = $(__OS_DL:$(_UNIQ)Darwin=$(_UNIQ)) + ____OS_DL = $(___OS_DL:$(_UNIQ)DragonFly=$(_UNIQ)) + _____OS_DL = $(____OS_DL:$(_UNIQ)$(UNAME_S)=) +______OS_DL = $(_____OS_DL:$(_UNIQ)="-ldl") + + _OS_TARGET = $(____OS_DL:$(_UNIQ)FreeBSD=$(_UNIQ)) + __OS_TARGET = $(_OS_TARGET:$(_UNIQ)OpenBSD=$(_UNIQ)) + ___OS_TARGET = $(__OS_TARGET:$(_UNIQ)NetBSD=$(_UNIQ)) +____OS_TARGET = $(___OS_TARGET:$(_UNIQ)$(UNAME_S)=) + +TARGETS = $(____OS_TARGET:$(_UNIQ)=libtokencap.so) + +LDFLAGS += $(______OS_DL) + +#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 + +debug: + @echo $(UNAME_S)$(_UNIQ) | hexdump -C + @echo from $(____OS_DL) : $(_UNIQ)$(UNAME_S) = -\> $(_____OS_DL) + @echo from $(_____OS_DL) : $(_UNIQ) = -ldl -\> $(______OS_DL) + @echo from $(____OS_DL) : $(_UNIQ)FreeBSD = $(_UNIQ) -\> $(_OS_TARGET) + @echo from $(_OS_TARGET) : $(_UNIQ)OpenBSD = $(_UNIQ) -\> $(__OS_TARGET) + @echo from $(__OS_TARGET) : $(_UNIQ)NetBSD = $(_UNIQ) -\> $(___OS_TARGET) + @echo from $(___OS_TARGET) : $(_UNIQ)$(_UNIQ) = -\> $(____OS_TARGET) + @echo from $(____OS_TARGET) : $(_UNIQ) = libtokencap.so -\> $(TARGETS) + +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 From 212925745417e29a5627edddbf837636860033aa Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 4 Apr 2020 16:16:13 +0200 Subject: [PATCH 29/72] fix silly error with uname -s --- libtokencap/Makefile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libtokencap/Makefile b/libtokencap/Makefile index 506d37cb..08316d78 100644 --- a/libtokencap/Makefile +++ b/libtokencap/Makefile @@ -24,9 +24,8 @@ CFLAGS ?= -O3 -funroll-loops -D_FORTIFY_SOURCE=2 CFLAGS += -I ../include/ -Wall -g -Wno-pointer-sign UNAME_CMD=uname -s -_UNAME_S =$(shell $(UNAME_CMD)) # GNU make puts a space at the end, great!! -UNAME_S =$(_UNAME_S: =) -UNAME_S:sh=$(UNAME_CMD) # BSD make +UNAME_S =$(shell $(UNAME_CMD))# GNU make +UNAME_S:sh=$(UNAME_CMD) # BSD make _UNIQ=_QINU_ _OS_DL = $(_UNIQ)$(UNAME_S) From 0303d315fcb29bd3f74da66faa222d17e7ac5b6f Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 4 Apr 2020 16:45:59 +0200 Subject: [PATCH 30/72] Makefile bugfix macros are generally not expanded in shell calls --- libtokencap/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libtokencap/Makefile b/libtokencap/Makefile index 08316d78..75a8d337 100644 --- a/libtokencap/Makefile +++ b/libtokencap/Makefile @@ -23,9 +23,9 @@ VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) CFLAGS ?= -O3 -funroll-loops -D_FORTIFY_SOURCE=2 CFLAGS += -I ../include/ -Wall -g -Wno-pointer-sign -UNAME_CMD=uname -s -UNAME_S =$(shell $(UNAME_CMD))# GNU make -UNAME_S:sh=$(UNAME_CMD) # BSD make + +UNAME_S =$(shell uname -s)# GNU make +UNAME_S:sh=uname -s # BSD make _UNIQ=_QINU_ _OS_DL = $(_UNIQ)$(UNAME_S) From c165165b5826580860f0b460055bb3c342a030e7 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 4 Apr 2020 18:38:38 +0200 Subject: [PATCH 31/72] unicorn_mode build script: find setuptools more reliably --- unicorn_mode/build_unicorn_support.sh | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) mode change 100755 => 100644 unicorn_mode/build_unicorn_support.sh diff --git a/unicorn_mode/build_unicorn_support.sh b/unicorn_mode/build_unicorn_support.sh old mode 100755 new mode 100644 index a8999dca..0d915238 --- a/unicorn_mode/build_unicorn_support.sh +++ b/unicorn_mode/build_unicorn_support.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#! /bin/sh # # american fuzzy lop++ - unicorn mode build script # ------------------------------------------------ @@ -107,8 +107,21 @@ done if ! type $EASY_INSTALL > /dev/null; then - # work around for unusual installs - if [ '!' -e /usr/lib/python2.7/dist-packages/easy_install.py ] && [ '!' -e /usr/local/lib/python2.7/dist-packages/easy_install.py ] && [ '!' -e /usr/pkg/lib/python2.7/dist-packages/easy_install.py ]; then + # work around for installs with executable easy_install + EASY_INSTALL_FOUND=0 + MYPYTHONPATH=`python -v &1 >/dev/null | sed -n -e '/^# \/.*\/os.py/{ s/.*matches //; s/os.py$//; p}'` + for PATHCANDIDATE in \ + "dist-packages/" \ + "site-packages/" + do + if [ -e "${MYPYTHONPATH}/${PATHCANDIDATE}/easy_install.py" ] ; then + + EASY_INSTALL_FOUND=1 + break + + fi + done + if [ '!' $EASY_INSTALL_FOUND ]; then echo "[-] Error: Python setup-tools not found. Run 'sudo apt-get install python-setuptools'." PREREQ_NOTFOUND=1 From 5ad50adaa86336f1f293d57fa70ba57de51cf5dd Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 4 Apr 2020 18:42:51 +0200 Subject: [PATCH 32/72] GNUmakefile: python config add --ldflags, silence tests --- GNUmakefile | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index ff27e125..25928210 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -71,34 +71,34 @@ override CFLAGS += -Wall -g -Wno-pointer-sign \ AFL_FUZZ_FILES = $(wildcard src/afl-fuzz*.c) -ifneq "$(shell type python3m 2>/dev/null)" "" - ifneq "$(shell type python3m-config 2>/dev/null)" "" +ifneq "$(shell command -v python3m 2>/dev/null)" "" + ifneq "$(shell command -v 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) + PYTHON_LIB ?= $(shell python3m-config --libs --embed --ldflags) 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)" "" +ifneq "$(shell command -v python3 2>/dev/null)" "" + ifneq "$(shell command -v 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) + PYTHON_LIB ?= $(shell python3-config --libs --embed --ldflags) 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)" "" +ifneq "$(shell command -v python 2>/dev/null)" "" + ifneq "$(shell command -v 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)) From 452acf3a752f3ff360a5eebc526567cd3ba9a407 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 6 Apr 2020 13:33:49 +0200 Subject: [PATCH 33/72] added AFL_LLVM_INSTRUMENT, made USE_TRACE_PC obselete and llvm_mode Makefile fix, fixed for FUSELD (for LTO) --- docs/Changelog.md | 10 +- docs/env_variables.md | 62 +++--- llvm_mode/GNUmakefile | 29 +-- llvm_mode/README.instrim.md | 7 +- llvm_mode/README.ngram.md | 5 +- llvm_mode/afl-clang-fast.c | 331 ++++++++++++++++++---------- llvm_mode/afl-llvm-pass.so.cc | 6 +- llvm_mode/afl-llvm-rt.o.c | 8 +- llvm_mode/llvm-ngram-coverage.h | 2 +- llvm_mode/split-compares-pass.so.cc | 4 +- src/afl-common.c | 15 +- 11 files changed, 291 insertions(+), 188 deletions(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index 72336b11..31a9b69a 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -34,7 +34,11 @@ sending a mail to . the last 5 queue entries - rare: puts focus on queue entries that hits rare branches, also ignores runtime - - llvm_mode: added Control Flow Integrity sanitizer (AFL_USE_CFISAN) + - llvm_mode: + - added Control Flow Integrity sanitizer (AFL_USE_CFISAN) + - added AFL_LLVM_INSTRUMENT option to control the instrumentation type + easier: DEFAULT, CFG (INSTRIM), LTO, CTX, NGRAM-x (x=2-16) + - made USE_TRACE_PC compile obsolete - LTO collision free instrumented added in llvm_mode with afl-clang-lto - note that this mode is amazing, but quite some targets won't compile - Added llvm_mode NGRAM prev_loc coverage by Adrean Herrera @@ -43,7 +47,7 @@ sending a mail to . - llvm_mode InsTrim mode: - removed workaround for bug where paths were not instrumented and imported fix by author - - made skipping 1 block functions an option and is disable by default, + - made skipping 1 block functions an option and is disabled by default, set AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK=1 to re-enable this - qemu_mode: - qemu_mode now uses solely the internal capstone version to fix builds @@ -53,6 +57,8 @@ sending a mail to . - now supports hang mode `-H` to minimize hangs - fixed potential afl-tmin missbehavior for targets with multiple hangs - Pressing Control-c in afl-cmin did not terminate it for some OS + - the custom API was rewritten and is now the same for Python and shared + libraries. ### Version ++2.62c (release): diff --git a/docs/env_variables.md b/docs/env_variables.md index ae283b1c..10a17a99 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -93,6 +93,17 @@ of the settings discussed in section #1, with the exception of: Then there are a few specific features that are only available in llvm_mode: +### Select the instrumentation mode + + - AFL_LLVM_INSTRUMENT - this configures the instrumentation mode. + Available options: + DEFAULT - classic AFL (map[cur_loc ^ prev_loc >> 1]++) + CFG - InsTrim instrumentation (see below) + LTO - LTO instrumentation (see below) + CTX - context sensitive instrumentation (see below) + NGRAM-x - deeper previous location coverage (from NGRAM-2 up to NGRAM-16) + Only one can be used. + ### LTO This is a different kind way of instrumentation: first it compiles all @@ -112,9 +123,32 @@ Then there are a few specific features that are only available in llvm_mode: - AFL_LLVM_LTO_DONTWRITEID prevents that the highest location ID written into the instrumentation is set in a global variable - Instrim, LTO and ngram modes can not be used together. See llvm_mode/README.LTO.md for more information. +### INSTRIM + + This feature increases the speed by ~15% without any disadvantages. + + - Setting AFL_LLVM_INSTRIM or AFL_LLVM_INSTRUMENT=CFG to activates this mode + + - Setting AFL_LLVM_INSTRIM_LOOPHEAD=1 expands on INSTRIM to optimize loops. + afl-fuzz will only be able to see the path the loop took, but not how + many times it was called (unless it is a complex loop). + + - Setting AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK=1 will skip instrumenting + functions with a single basic block. This is useful for most C and + some C++ targets. + + See llvm_mode/README.instrim.md + +### NGRAM + + - Setting AFL_LLVM_NGRAM_SIZE or AFL_LLVM_INSTRUMENT=NGRAM-{value} + activates ngram prev_loc coverage, good values are 2, 4 or 8 + (any value between 2 and 16 is valid). + + See llvm_mode/README.ngram.md + ### LAF-INTEL This great feature will split compares to series of single byte comparisons @@ -139,32 +173,6 @@ Then there are a few specific features that are only available in llvm_mode: See llvm_mode/README.whitelist.md for more information. -### INSTRIM - - This feature increases the speed by whopping 20% but at the cost of a - lower path discovery and therefore coverage. - - - Setting AFL_LLVM_INSTRIM activates this mode - - - Setting AFL_LLVM_INSTRIM_LOOPHEAD=1 expands on INSTRIM to optimize loops. - afl-fuzz will only be able to see the path the loop took, but not how - many times it was called (unless it is a complex loop). - - - Setting AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK=1 will skip instrumenting - functions with a single basic block. This is useful for most C and - some C++ targets. - - Instrim, LTO and ngram modes can not be used together. - See llvm_mode/README.instrim.md - -### NGRAM - - - Setting AFL_LLVM_NGRAM_SIZE activates ngram prev_loc coverage, good - values are 2, 4 or 8. - - Instrim, LTO and ngram modes can not be used together. - See llvm_mode/README.ngram.md - ### NOT_ZERO - Setting AFL_LLVM_NOT_ZERO=1 during compilation will use counters diff --git a/llvm_mode/GNUmakefile b/llvm_mode/GNUmakefile index 006d115d..e3708efa 100644 --- a/llvm_mode/GNUmakefile +++ b/llvm_mode/GNUmakefile @@ -134,15 +134,22 @@ ifeq "$(AFL_REAL_LD)" "" endif endif +AFL_CLANG_FUSELD= +ifneq "$(AFL_CLANG_FLTO)" "" +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" + AFL_CLANG_FUSELD=1 +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 + -DAFL_REAL_LD=\"$(AFL_REAL_LD)\" -DAFL_CLANG_FUSELD=\"$(AFL_CLANG_FUSELD)\" -Wno-unused-function ifdef AFL_TRACE_PC - CFLAGS += -DUSE_TRACE_PC=1 + $(info Compile option AFL_TRACE_PC is deprecated, just set AFL_LLVM_INSTRUMENT=PCGUARD to activate when compiling targets ) endif CXXFLAGS ?= -O3 -funroll-loops -D_FORTIFY_SOURCE=2 @@ -162,10 +169,6 @@ 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 @@ -180,11 +183,7 @@ ifeq "$(TEST_MMAP)" "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)" "" @@ -222,14 +221,10 @@ 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)'" @@ -327,12 +322,8 @@ all_done: test_build 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-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-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 diff --git a/llvm_mode/README.instrim.md b/llvm_mode/README.instrim.md index 5c3f32c8..b905af11 100644 --- a/llvm_mode/README.instrim.md +++ b/llvm_mode/README.instrim.md @@ -5,13 +5,12 @@ InsTrim: Lightweight Instrumentation for Coverage-guided Fuzzing ## Introduction InsTrim uses CFG and markers to instrument just what is necessary in the -binary in llvm_mode. It is about 20-25% faster but as a cost has a lower -path discovery. +binary in llvm_mode. It is about 10-15% faster without disadvantages. ## Usage -Set the environment variable `AFL_LLVM_INSTRIM=1` during compilation of -the target. +Set the environment variable `AFL_LLVM_INSTRUMENT=CFG` or `AFL_LLVM_INSTRIM=1` +during compilation of the target. There is also an advanced mode which instruments loops in a way so that afl-fuzz can see which loop path has been selected but not being able to diff --git a/llvm_mode/README.ngram.md b/llvm_mode/README.ngram.md index ef248198..3540ada0 100644 --- a/llvm_mode/README.ngram.md +++ b/llvm_mode/README.ngram.md @@ -16,5 +16,6 @@ the same results when compiling source code. ## Usage The size of `n` (i.e., the number of branches to remember) is an option -that is specified in the `AFL_LLVM_NGRAM_SIZE` environment variable. -Good values are 2, 4 or 8. +that is specified either in the `AFL_LLVM_INSTRUMENT=NGRAM-{value}` or the +`AFL_LLVM_NGRAM_SIZE` environment variable. +Good values are 2, 4 or 8, valid are 2-16. diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index 5fc09252..0e388cf4 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -29,11 +29,13 @@ #include "types.h" #include "debug.h" #include "alloc-inl.h" +#include "llvm-ngram-coverage.h" #include #include #include #include +#include #include #include @@ -41,7 +43,7 @@ static u8 * obj_path; /* Path to runtime libraries */ static u8 **cc_params; /* Parameters passed to the real CC */ static u32 cc_par_cnt = 1; /* Param count, including argv0 */ static u8 llvm_fullpath[PATH_MAX]; -static u8 lto_mode; +static u8 instrument_mode; static u8 * lto_flag = AFL_CLANG_FLTO; static u8 * march_opt = CFLAGS_OPT; static u8 debug; @@ -49,6 +51,26 @@ static u8 cwd[4096]; static u8 cmplog_mode; u8 use_stdin = 0; /* dummy */ +enum { + + INSTRUMENT_CLASSIC = 0, + INSTRUMENT_AFL = 0, + INSTRUMENT_DEFAULT = 0, + INSTRUMENT_PCGUARD = 1, + INSTRUMENT_INSTRIM = 2, + INSTRUMENT_CFG = 2, + INSTRUMENT_LTO = 3, + INSTRUMENT_CTX = 4, + INSTRUMENT_NGRAM = 5 // + ngram value of 2-16 = 7 - 21 + +}; + +char instrument_mode_string[6][16] = { + + "DEFAULT", "PCGUARD", "CFG", "LTO", "CTX", + +}; + u8 *getthecwd() { static u8 fail[] = ""; @@ -150,26 +172,11 @@ static void edit_params(u32 argc, char **argv, char **envp) { has_llvm_config = (strlen(LLVM_BINDIR) > 0); - if (!strncmp(name, "afl-clang-lto", strlen("afl-clang-lto"))) { - -#ifdef USE_TRACE_PC - FATAL("afl-clang-lto does not work with TRACE_PC mode"); -#endif + if (instrument_mode == INSTRUMENT_LTO) if (lto_flag[0] != '-') FATAL( "Using afl-clang-lto is not possible because Makefile magic did not " "identify the correct -flto flag"); - if (getenv("AFL_LLVM_INSTRIM") != NULL) - FATAL("afl-clang-lto does not work with InsTrim mode"); - if (getenv("AFL_LLVM_NGRAM_SIZE") != NULL) - FATAL("afl-clang-lto does not work with ngram coverage mode"); - lto_mode = 1; - - } - - if (getenv("AFL_LLVM_NGRAM_SIZE") != NULL && - getenv("AFL_LLVM_INSTRIM") != NULL) - FATAL("AFL_LLVM_NGRAM_SIZE and AFL_LLVM_INSTRIM cannot be used together"); if (!strcmp(name, "afl-clang-fast++") || !strcmp(name, "afl-clang-lto++")) { @@ -260,17 +267,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { } -#ifdef USE_TRACE_PC - - cc_params[cc_par_cnt++] = - "-fsanitize-coverage=trace-pc-guard"; // edge coverage by default - // cc_params[cc_par_cnt++] = "-mllvm"; - // cc_params[cc_par_cnt++] = - // "-fsanitize-coverage=trace-cmp,trace-div,trace-gep"; - // cc_params[cc_par_cnt++] = "-sanitizer-coverage-block-threshold=0"; -#else - - if (lto_mode) { + if (instrument_mode == INSTRUMENT_LTO) { char *old_path = getenv("PATH"); char *new_path = alloc_printf("%s:%s", AFL_PATH, old_path); @@ -299,8 +296,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { } else - if (getenv("USE_TRACE_PC") || getenv("AFL_USE_TRACE_PC") || - getenv("AFL_LLVM_USE_TRACE_PC") || getenv("AFL_TRACE_PC")) { + if (instrument_mode == INSTRUMENT_PCGUARD) { cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard"; // edge coverage by default @@ -310,15 +306,13 @@ static void edit_params(u32 argc, char **argv, char **envp) { cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; - if (getenv("AFL_LLVM_INSTRIM") != NULL || getenv("INSTRIM_LIB") != NULL) + if (instrument_mode == INSTRUMENT_CFG) cc_params[cc_par_cnt++] = alloc_printf("%s/libLLVMInsTrim.so", obj_path); else cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-pass.so", obj_path); } -#endif /* ^USE_TRACE_PC */ - cc_params[cc_par_cnt++] = "-Qunused-arguments"; /* Detect stray -v calls from ./configure scripts. */ @@ -389,7 +383,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (getenv("AFL_USE_CFISAN")) { - if (!lto_mode) { + if (instrument_mode != INSTRUMENT_LTO) { uint32_t i = 0, found = 0; while (envp[i] != NULL && !found) @@ -403,15 +397,6 @@ static void edit_params(u32 argc, char **argv, char **envp) { } -#ifdef USE_TRACE_PC - - if (getenv("USE_TRACE_PC") || getenv("AFL_USE_TRACE_PC") || - getenv("AFL_LLVM_USE_TRACE_PC") || getenv("AFL_TRACE_PC")) - if (getenv("AFL_INST_RATIO")) - FATAL("AFL_INST_RATIO not available at compile time with 'trace-pc'."); - -#endif /* USE_TRACE_PC */ - if (!getenv("AFL_DONT_OPTIMIZE")) { cc_params[cc_par_cnt++] = "-g"; @@ -534,7 +519,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { int main(int argc, char **argv, char **envp) { int i; - char *callname = "afl-clang-fast"; + char *callname = "afl-clang-fast", *ptr; if (getenv("AFL_DEBUG")) { @@ -545,83 +530,200 @@ int main(int argc, char **argv, char **envp) { be_quiet = 1; - if (strstr(argv[0], "afl-clang-lto") != NULL) callname = "afl-clang-lto"; - - if (argc < 2 || strcmp(argv[1], "-h") == 0) { - #ifdef USE_TRACE_PC - printf(cCYA "afl-clang-fast" VERSION cRST - " [tpcg] by \n") -#else - if (strstr(argv[0], "afl-clang-lto") == NULL) + instrument_mode = INSTRUMENT_PCGUARD; +#endif - printf("afl-clang-fast" VERSION " by \n"); + if ((ptr = getenv("AFL_LLVM_INSTRUMENT")) != NULL) { - else { + if (strncasecmp(ptr, "cfg", strlen("cfg")) == 0 || + strncasecmp(ptr, "instrim", strlen("instrim")) == 0) + instrument_mode = INSTRUMENT_CFG; + else if (strncasecmp(ptr, "pc-guard", strlen("pc-guard")) == 0 || + strncasecmp(ptr, "pcguard", strlen("pcgard")) == 0) + instrument_mode = INSTRUMENT_PCGUARD; + else if (strncasecmp(ptr, "lto", strlen("lto")) == 0) + instrument_mode = INSTRUMENT_LTO; + else if (strncasecmp(ptr, "ctx", strlen("ctx")) == 0) + instrument_mode = INSTRUMENT_CTX; + else if (strncasecmp(ptr, "ngram", strlen("ngram")) == 0) { - printf("afl-clang-lto" VERSION - " by Marc \"vanHauser\" Heuse \n"); + ptr += strlen("ngram"); + while (*ptr && (*ptr < '0' || *ptr > '9')) + ptr++; + if (!*ptr) + if ((ptr = getenv("AFL_LLVM_NGRAM_SIZE")) != NULL) + FATAL( + "you must set the NGRAM size with (e.g. for value 2) " + "AFL_LLVM_INSTRUMENT=ngram-2"); + instrument_mode = INSTRUMENT_NGRAM + atoi(ptr); + if (instrument_mode < INSTRUMENT_NGRAM + 2 || + instrument_mode > INSTRUMENT_NGRAM + NGRAM_SIZE_MAX) + FATAL( + "NGRAM instrumentation mode must be between 2 and NGRAM_SIZE_MAX " + "(%u)", + NGRAM_SIZE_MAX); + + ptr = alloc_printf("%u", instrument_mode - INSTRUMENT_NGRAM); + setenv("AFL_LLVM_NGRAM_SIZE", ptr, 1); + + } else if (strncasecmp(ptr, "classic", strlen("classic")) != 0 || + + strncasecmp(ptr, "default", strlen("default")) != 0 || + strncasecmp(ptr, "afl", strlen("afl")) != 0) + FATAL("unknown AFL_LLVM_INSTRUMENT value: %s", ptr); + + } + + if (getenv("USE_TRACE_PC") || getenv("AFL_USE_TRACE_PC") || + getenv("AFL_LLVM_USE_TRACE_PC") || getenv("AFL_TRACE_PC")) { + + if (instrument_mode == 0) + instrument_mode = INSTRUMENT_PCGUARD; + else if (instrument_mode != INSTRUMENT_PCGUARD) + FATAL("you can not set AFL_LLVM_INSTRUMENT and AFL_TRACE_PC together"); + + } + + if (getenv("AFL_LLVM_INSTRIM") || getenv("INSTRIM") || + getenv("INSTRIM_LIB")) { + + if (instrument_mode == 0) + instrument_mode = INSTRUMENT_CFG; + else if (instrument_mode != INSTRUMENT_CFG) + FATAL( + "you can not set AFL_LLVM_INSTRUMENT and AFL_LLVM_INSTRIM together"); + + } + + if (getenv("AFL_LLVM_CTX")) { + + if (instrument_mode == 0) + instrument_mode = INSTRUMENT_CTX; + else if (instrument_mode != INSTRUMENT_CTX) + FATAL("you can not set AFL_LLVM_INSTRUMENT and AFL_LLVM_CTX together"); + + } + + if (getenv("AFL_LLVM_NGRAM_SIZE")) { + + if (instrument_mode == 0) { + + instrument_mode = INSTRUMENT_NGRAM + atoi(getenv("AFL_LLVM_NGRAM_SIZE")); + if (instrument_mode < INSTRUMENT_NGRAM + 2 || + instrument_mode > INSTRUMENT_NGRAM + NGRAM_SIZE_MAX) + FATAL( + "NGRAM instrumentation mode must be between 2 and NGRAM_SIZE_MAX " + "(%u)", + NGRAM_SIZE_MAX); + + } else if (instrument_mode != INSTRUMENT_NGRAM) + + FATAL( + "you can not set AFL_LLVM_INSTRUMENT and AFL_LLVM_NGRAM_SIZE " + "together"); + + } + + if (instrument_mode < INSTRUMENT_NGRAM) + ptr = instrument_mode_string[instrument_mode]; + else + ptr = alloc_printf("NGRAM-%u", instrument_mode - INSTRUMENT_NGRAM); + + if (strstr(argv[0], "afl-clang-lto") != NULL) { + + if (instrument_mode == 0 || instrument_mode == INSTRUMENT_LTO) { + + callname = "afl-clang-lto"; + instrument_mode = INSTRUMENT_LTO; + ptr = instrument_mode_string[instrument_mode]; + + } else { + + if (!be_quiet) + WARNF("afl-clang-lto called with mode %s, using that mode instead", + ptr); } -#endif /* ^USE_TRACE_PC */ + } - SAYF( - "\n" - "%s[++] [options]\n" - "\n" - "This is a helper application for afl-fuzz. It serves as a drop-in " - "replacement\n" - "for clang, letting you recompile third-party code with the " - "required " - "runtime\n" - "instrumentation. A common use pattern would be one of the " - "following:\n\n" +#ifndef AFL_CLANG_FLTO + if (instrument_mode == INSTRUMENT_LTO) + FATAL("instrumentation mode LTO specified but LLVM support not available"); +#endif - " CC=%s/afl-clang-fast ./configure\n" - " CXX=%s/afl-clang-fast++ ./configure\n\n" + if (argc < 2 || strcmp(argv[1], "-h") == 0) { - "In contrast to the traditional afl-clang tool, this version is " - "implemented as\n" - "an LLVM pass and tends to offer improved performance with slow " - "programs.\n\n" + if (instrument_mode != INSTRUMENT_LTO) + printf("afl-clang-fast" VERSION " by in %s mode\n", + ptr); + else + printf("afl-clang-lto" VERSION + " by Marc \"vanHauser\" Heuse in %s mode\n", + ptr); - "Environment variables used:\n" - "AFL_CC: path to the C compiler to use\n" - "AFL_CXX: path to the C++ compiler to use\n" - "AFL_PATH: path to instrumenting pass and runtime " - "(afl-llvm-rt.*o)\n" - "AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n" - "AFL_NO_BUILTIN: compile for use with libtokencap.so\n" - "AFL_INST_RATIO: percentage of branches to instrument\n" - "AFL_QUIET: suppress verbose output\n" - "AFL_DEBUG: enable developer debugging output\n" - "AFL_HARDEN: adds code hardening to catch memory bugs\n" - "AFL_USE_ASAN: activate address sanitizer\n" - "AFL_USE_MSAN: activate memory sanitizer\n" - "AFL_USE_UBSAN: activate undefined behaviour sanitizer\n" - "AFL_USE_CFISAN: activate control flow sanitizer\n" - "AFL_LLVM_WHITELIST: enable whitelisting (selective " - "instrumentation)\n" - "AFL_LLVM_NOT_ZERO: use cycling trace counters that skip zero\n" - "AFL_LLVM_USE_TRACE_PC: use LLVM trace-pc-guard instrumentation\n" - "AFL_LLVM_LAF_SPLIT_COMPARES: enable cascaded comparisons\n" - "AFL_LLVM_LAF_SPLIT_SWITCHES: casc. comp. in 'switch'\n" - "AFL_LLVM_LAF_TRANSFORM_COMPARES: transform library comparison " - "function calls\n" - " to cascaded comparisons\n" - "AFL_LLVM_LAF_SPLIT_FLOATS: transform floating point comp. to " - "cascaded " - "comp.\n" - "AFL_LLVM_LAF_SPLIT_COMPARES_BITW: size limit (default 8)\n", - callname, BIN_PATH, BIN_PATH); + SAYF( + "\n" + "%s[++] [options]\n" + "\n" + "This is a helper application for afl-fuzz. It serves as a drop-in " + "replacement\n" + "for clang, letting you recompile third-party code with the " + "required " + "runtime\n" + "instrumentation. A common use pattern would be one of the " + "following:\n\n" + + " CC=%s/afl-clang-fast ./configure\n" + " CXX=%s/afl-clang-fast++ ./configure\n\n" + + "In contrast to the traditional afl-clang tool, this version is " + "implemented as\n" + "an LLVM pass and tends to offer improved performance with slow " + "programs.\n\n" + + "Environment variables used:\n" + "AFL_CC: path to the C compiler to use\n" + "AFL_CXX: path to the C++ compiler to use\n" + "AFL_PATH: path to instrumenting pass and runtime " + "(afl-llvm-rt.*o)\n" + "AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n" + "AFL_NO_BUILTIN: compile for use with libtokencap.so\n" + "AFL_INST_RATIO: percentage of branches to instrument\n" + "AFL_QUIET: suppress verbose output\n" + "AFL_DEBUG: enable developer debugging output\n" + "AFL_HARDEN: adds code hardening to catch memory bugs\n" + "AFL_USE_ASAN: activate address sanitizer\n" + "AFL_USE_MSAN: activate memory sanitizer\n" + "AFL_USE_UBSAN: activate undefined behaviour sanitizer\n" + "AFL_USE_CFISAN: activate control flow sanitizer\n" + "AFL_LLVM_WHITELIST: enable whitelisting (selective " + "instrumentation)\n" + "AFL_LLVM_NOT_ZERO: use cycling trace counters that skip zero\n" + "AFL_LLVM_LAF_SPLIT_COMPARES: enable cascaded comparisons\n" + "AFL_LLVM_LAF_SPLIT_SWITCHES: casc. comp. in 'switch'\n" + "AFL_LLVM_LAF_TRANSFORM_COMPARES: transform library comparison " + "function calls\n" + " to cascaded comparisons\n" + "AFL_LLVM_LAF_SPLIT_FLOATS: transform floating point comp. to " + "cascaded " + "comp.\n" + "AFL_LLVM_LAF_SPLIT_COMPARES_BITW: size limit (default 8)\n", + callname, BIN_PATH, BIN_PATH); SAYF( "\nafl-clang-fast specific environment variables:\n" + "AFL_LLVM_CMPLOG: log operands of comparisons (RedQueen mutator)\n" + "AFL_LLVM_INSTRUMENT: set instrumentation mode: DEFAULT, CFG " + "(INSTRIM), LTO, CTX, NGRAM-2 ... NGRAM-16\n" + "You can also use the old environment variables:" + "AFL_LLVM_CTX: use context sensitive coverage\n" + "AFL_LLVM_USE_TRACE_PC: use LLVM trace-pc-guard instrumentation\n" + "AFL_LLVM_NGRAM_SIZE: use ngram prev_loc count coverage\n" "AFL_LLVM_INSTRIM: use light weight instrumentation InsTrim\n" - "AFL_LLVM_INSTRIM_LOOPHEAD: optimize loop tracing for speed\n" - "AFL_LLVM_NGRAM_SIZE: use ngram prev_loc coverage\n" - "AFL_LLVM_CMPLOG: log operands of comparisons (RedQueen mutator)\n"); + "AFL_LLVM_INSTRIM_LOOPHEAD: optimize loop tracing for speed (sub " + "option to INSTRIM)\n"); #ifdef AFL_CLANG_FLTO SAYF( @@ -652,22 +754,17 @@ int main(int argc, char **argv, char **envp) { getenv("AFL_DEBUG") != NULL) { -#ifdef USE_TRACE_PC - SAYF(cCYA "afl-clang-fast" VERSION cRST - " [tpcg] by \n"); -#warning \ - "You do not need to specifically compile with USE_TRACE_PC anymore, setting the environment variable AFL_LLVM_USE_TRACE_PC is enough." -#else - if (strstr(argv[0], "afl-clang-lto") == NULL) + if (instrument_mode != INSTRUMENT_LTO) - SAYF(cCYA "afl-clang-fast" VERSION cRST " by \n"); + SAYF(cCYA "afl-clang-fast" VERSION cRST + " by in %s mode\n", + ptr); else SAYF(cCYA "afl-clang-lto" VERSION cRST - " by Marc \"vanHauser\" Heuse \n"); - -#endif /* ^USE_TRACE_PC */ + " by Marc \"vanHauser\" Heuse in mode %s\n", + ptr); } diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc index 5fe98d8b..56f9ffe2 100644 --- a/llvm_mode/afl-llvm-pass.so.cc +++ b/llvm_mode/afl-llvm-pass.so.cc @@ -216,11 +216,11 @@ bool AFLCoverage::runOnModule(Module &M) { if (ngram_size_str) if (sscanf(ngram_size_str, "%u", &ngram_size) != 1 || ngram_size < 2 || - ngram_size > MAX_NGRAM_SIZE) + ngram_size > NGRAM_SIZE_MAX) FATAL( - "Bad value of AFL_NGRAM_SIZE (must be between 2 and MAX_NGRAM_SIZE " + "Bad value of AFL_NGRAM_SIZE (must be between 2 and NGRAM_SIZE_MAX " "(%u))", - MAX_NGRAM_SIZE); + NGRAM_SIZE_MAX); if (ngram_size == 1) ngram_size = 0; if (ngram_size) diff --git a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c index 8fad0fbb..ade9eeef 100644 --- a/llvm_mode/afl-llvm-rt.o.c +++ b/llvm_mode/afl-llvm-rt.o.c @@ -63,10 +63,10 @@ u8 __afl_area_initial[MAP_SIZE]; u8 *__afl_area_ptr = __afl_area_initial; #ifdef __ANDROID__ -PREV_LOC_T __afl_prev_loc[MAX_NGRAM_SIZE]; +PREV_LOC_T __afl_prev_loc[NGRAM_SIZE_MAX]; u32 __afl_final_loc; #else -__thread PREV_LOC_T __afl_prev_loc[MAX_NGRAM_SIZE]; +__thread PREV_LOC_T __afl_prev_loc[NGRAM_SIZE_MAX]; __thread u32 __afl_final_loc; #endif @@ -282,7 +282,7 @@ int __afl_persistent_loop(unsigned int max_cnt) { memset(__afl_area_ptr, 0, MAP_SIZE); __afl_area_ptr[0] = 1; - memset(__afl_prev_loc, 0, MAX_NGRAM_SIZE * sizeof(PREV_LOC_T)); + memset(__afl_prev_loc, 0, NGRAM_SIZE_MAX * sizeof(PREV_LOC_T)); } @@ -299,7 +299,7 @@ int __afl_persistent_loop(unsigned int max_cnt) { raise(SIGSTOP); __afl_area_ptr[0] = 1; - memset(__afl_prev_loc, 0, MAX_NGRAM_SIZE * sizeof(PREV_LOC_T)); + memset(__afl_prev_loc, 0, NGRAM_SIZE_MAX * sizeof(PREV_LOC_T)); return 1; diff --git a/llvm_mode/llvm-ngram-coverage.h b/llvm_mode/llvm-ngram-coverage.h index 488b4fe7..12b666e9 100644 --- a/llvm_mode/llvm-ngram-coverage.h +++ b/llvm_mode/llvm-ngram-coverage.h @@ -12,7 +12,7 @@ typedef u64 PREV_LOC_T; #endif /* Maximum ngram size */ -#define MAX_NGRAM_SIZE 128U +#define NGRAM_SIZE_MAX 16U #endif diff --git a/llvm_mode/split-compares-pass.so.cc b/llvm_mode/split-compares-pass.so.cc index d296ba3d..f0615f85 100644 --- a/llvm_mode/split-compares-pass.so.cc +++ b/llvm_mode/split-compares-pass.so.cc @@ -1235,8 +1235,8 @@ bool SplitComparesTransform::runOnModule(Module &M) { int bitw = 64; - char *bitw_env = getenv("LAF_SPLIT_COMPARES_BITW"); - if (!bitw_env) bitw_env = getenv("AFL_LLVM_LAF_SPLIT_COMPARES_BITW"); + char *bitw_env = getenv("AFL_LLVM_LAF_SPLIT_COMPARES_BITW"); + if (!bitw_env) bitw_env = getenv("LAF_SPLIT_COMPARES_BITW"); if (bitw_env) { bitw = atoi(bitw_env); } enableFPSplit = getenv("AFL_LLVM_LAF_SPLIT_FLOATS") != NULL; diff --git a/src/afl-common.c b/src/afl-common.c index 920c7dfd..c1adefeb 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -57,13 +57,14 @@ char *afl_environment_variables[] = { "AFL_INST_LIBS", "AFL_INST_RATIO", "AFL_KEEP_TRACES", "AFL_KEEP_ASSEMBLY", "AFL_LD_HARD_FAIL", "AFL_LD_LIMIT_MB", "AFL_LD_NO_CALLOC_OVER", "AFL_LD_PRELOAD", "AFL_LD_VERBOSE", "AFL_LLVM_CMPLOG", "AFL_LLVM_INSTRIM", - "AFL_LLVM_INSTRIM_LOOPHEAD", "AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK", - "AFL_LLVM_LAF_SPLIT_COMPARES", "AFL_LLVM_LAF_SPLIT_COMPARES_BITW", - "AFL_LLVM_LAF_SPLIT_FLOATS", "AFL_LLVM_LAF_SPLIT_SWITCHES", - "AFL_LLVM_LAF_TRANSFORM_COMPARES", "AFL_LLVM_NGRAM_SIZE", "AFL_NGRAM_SIZE", - "AFL_LLVM_NOT_ZERO", "AFL_LLVM_WHITELIST", "AFL_NO_AFFINITY", - "AFL_LLVM_LTO_STARTID", "AFL_LLVM_LTO_DONTWRITEID", "AFL_NO_ARITH", - "AFL_NO_BUILTIN", "AFL_NO_CPU_RED", "AFL_NO_FORKSRV", "AFL_NO_UI", + "AFL_LLVM_INSTRUMENT", "AFL_LLVM_INSTRIM_LOOPHEAD", + "AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK", "AFL_LLVM_LAF_SPLIT_COMPARES", + "AFL_LLVM_LAF_SPLIT_COMPARES_BITW", "AFL_LLVM_LAF_SPLIT_FLOATS", + "AFL_LLVM_LAF_SPLIT_SWITCHES", "AFL_LLVM_LAF_TRANSFORM_COMPARES", + "AFL_LLVM_NGRAM_SIZE", "AFL_NGRAM_SIZE", "AFL_LLVM_NOT_ZERO", + "AFL_LLVM_WHITELIST", "AFL_NO_AFFINITY", "AFL_LLVM_LTO_STARTID", + "AFL_LLVM_LTO_DONTWRITEID", "AFL_NO_ARITH", "AFL_NO_BUILTIN", + "AFL_NO_CPU_RED", "AFL_NO_FORKSRV", "AFL_NO_UI", "AFL_NO_X86", // not really an env but we dont want to warn on it "AFL_PATH", "AFL_PERFORMANCE_FILE", //"AFL_PERSISTENT", // not implemented anymore, so warn additionally From da1f3bf41eb7640c40f6fa3e1cbcc694c25d9892 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Tue, 7 Apr 2020 10:50:21 +0200 Subject: [PATCH 34/72] snapshot() in llvm mode --- include/snapshot-inl.h | 59 +++++++++++++++++++++ llvm_mode/afl-llvm-rt.o.c | 106 ++++++++++++++++++++++++++++++++++++++ test-instr.c | 5 -- 3 files changed, 165 insertions(+), 5 deletions(-) create mode 100644 include/snapshot-inl.h diff --git a/include/snapshot-inl.h b/include/snapshot-inl.h new file mode 100644 index 00000000..b73a001e --- /dev/null +++ b/include/snapshot-inl.h @@ -0,0 +1,59 @@ +/* + american fuzzy lop++ - snapshot helpers routines + ------------------------------------------------ + + Originally written by Michal Zalewski + + Forkserver design by Jann Horn + + Now maintained by Marc Heuse , + Heiko Eißfeldt , + Andrea Fioraldi , + Dominik Maier + + Copyright 2016, 2017 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 + + */ + +// From AFL-Snapshot-LKM/include/afl_snapshot.h (must be kept synced) + +#include +#include +#include +#include + +#define AFL_SNAPSHOT_FILE_NAME "/dev/afl_snapshot" + +#define AFL_SNAPSHOT_IOCTL_MAGIC 44313 + +#define AFL_SNAPSHOT_IOCTL_DO _IO(AFL_SNAPSHOT_IOCTL_MAGIC, 1) +#define AFL_SNAPSHOT_IOCTL_CLEAN _IO(AFL_SNAPSHOT_IOCTL_MAGIC, 2) + +static int afl_snapshot_dev_fd; + +static int afl_snapshot_init(void) { + + afl_snapshot_dev_fd = open(AFL_SNAPSHOT_FILE_NAME, 0); + return afl_snapshot_dev_fd; + +} + +static int afl_snapshot_do() { + + return ioctl(afl_snapshot_dev_fd, AFL_SNAPSHOT_IOCTL_DO); + +} + +static int afl_snapshot_clean(void) { + + return ioctl(afl_snapshot_dev_fd, AFL_SNAPSHOT_IOCTL_CLEAN); + +} + diff --git a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c index 8fad0fbb..7ef8e165 100644 --- a/llvm_mode/afl-llvm-rt.o.c +++ b/llvm_mode/afl-llvm-rt.o.c @@ -42,6 +42,10 @@ #include #include +#ifdef __linux__ +#include "snapshot-inl.h" +#endif + /* This is a somewhat ugly hack for the experimental 'trace-pc-guard' mode. Basically, we need to make sure that the forkserver is initialized after the LLVM-generated runtime initialization pass, not before. */ @@ -177,10 +181,112 @@ static void __afl_map_shm(void) { } +#ifdef __linux__ +static void __afl_start_snapshots(void) { + + static u8 tmp[4]; + s32 child_pid; + + u8 child_stopped = 0; + + void (*old_sigchld_handler)(int) = 0; // = signal(SIGCHLD, SIG_DFL); + + /* Phone home and tell the parent that we're OK. If parent isn't there, + assume we're not running in forkserver mode and just execute program. */ + + if (write(FORKSRV_FD + 1, tmp, 4) != 4) return; + + while (1) { + + u32 was_killed; + int status; + + /* Wait for parent by reading from the pipe. Abort if read fails. */ + + if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1); + + /* If we stopped the child in persistent mode, but there was a race + condition and afl-fuzz already issued SIGKILL, write off the old + process. */ + + if (child_stopped && was_killed) { + + child_stopped = 0; + if (waitpid(child_pid, &status, 0) < 0) _exit(1); + + } + + if (!child_stopped) { + + /* Once woken up, create a clone of our process. */ + + child_pid = fork(); + if (child_pid < 0) _exit(1); + + /* In child process: close fds, resume execution. */ + + if (!child_pid) { + + signal(SIGCHLD, old_sigchld_handler); + + close(FORKSRV_FD); + close(FORKSRV_FD + 1); + + if (!afl_snapshot_do()) { raise(SIGSTOP); } + + __afl_area_ptr[0] = 1; + memset(__afl_prev_loc, 0, MAX_NGRAM_SIZE * sizeof(PREV_LOC_T)); + + fprintf(stderr, "STARTED %p...\n", __builtin_return_address(0)); + + return; + + } + + } else { + + fprintf(stderr, "child stopped\n"); + + /* Special handling for persistent mode: if the child is alive but + currently stopped, simply restart it with SIGCONT. */ + + kill(child_pid, SIGCONT); + child_stopped = 0; + + } + + /* In parent process: write PID to pipe, then wait for child. */ + + if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) _exit(1); + + if (waitpid(child_pid, &status, WUNTRACED) < 0) _exit(1); + + /* In persistent mode, the child stops itself with SIGSTOP to indicate + a successful run. In this case, we want to wake it up without forking + again. */ + + if (WIFSTOPPED(status)) child_stopped = 1; + + /* Relay wait status to pipe, then loop back. */ + + if (write(FORKSRV_FD + 1, &status, 4) != 4) _exit(1); + + } + +} + +#endif + /* Fork server logic. */ static void __afl_start_forkserver(void) { +#ifdef __linux__ + if (!is_persistent && !__afl_cmp_map && !getenv("AFL_NO_SNAPSHOT") && + afl_snapshot_init() >= 0) + __afl_start_snapshots(); +#endif + static u8 tmp[4]; s32 child_pid; diff --git a/test-instr.c b/test-instr.c index 579577a4..84ac0036 100644 --- a/test-instr.c +++ b/test-instr.c @@ -1,18 +1,13 @@ /* american fuzzy lop++ - a trivial program to test the build -------------------------------------------------------- - Originally written by Michal Zalewski - Copyright 2014 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 - */ #include From 604f17b89762a456a48b53698de6825693bcf580 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Tue, 7 Apr 2020 10:56:31 +0200 Subject: [PATCH 35/72] small fixes --- llvm_mode/afl-llvm-rt.o.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c index 7ef8e165..4d1f846c 100644 --- a/llvm_mode/afl-llvm-rt.o.c +++ b/llvm_mode/afl-llvm-rt.o.c @@ -237,16 +237,12 @@ static void __afl_start_snapshots(void) { __afl_area_ptr[0] = 1; memset(__afl_prev_loc, 0, MAX_NGRAM_SIZE * sizeof(PREV_LOC_T)); - fprintf(stderr, "STARTED %p...\n", __builtin_return_address(0)); - return; } } else { - fprintf(stderr, "child stopped\n"); - /* Special handling for persistent mode: if the child is alive but currently stopped, simply restart it with SIGCONT. */ @@ -274,7 +270,6 @@ static void __afl_start_snapshots(void) { } } - #endif /* Fork server logic. */ @@ -283,8 +278,12 @@ static void __afl_start_forkserver(void) { #ifdef __linux__ if (!is_persistent && !__afl_cmp_map && !getenv("AFL_NO_SNAPSHOT") && - afl_snapshot_init() >= 0) + afl_snapshot_init() >= 0) { + __afl_start_snapshots(); + return; + + } #endif static u8 tmp[4]; From 5b160f187d4861297174192497fd6971d6e8e535 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Tue, 7 Apr 2020 11:26:18 +0200 Subject: [PATCH 36/72] update env with AFL_NO_SNAPSHOT --- src/afl-common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/afl-common.c b/src/afl-common.c index 920c7dfd..9502d53f 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -76,7 +76,8 @@ char *afl_environment_variables[] = { "AFL_SHUFFLE_QUEUE", "AFL_SKIP_BIN_CHECK", "AFL_SKIP_CPUFREQ", "AFL_SKIP_CRASHES", "AFL_TMIN_EXACT", "AFL_TMPDIR", "AFL_TOKEN_FILE", "AFL_TRACE_PC", "AFL_USE_ASAN", "AFL_USE_MSAN", "AFL_USE_TRACE_PC", - "AFL_USE_UBSAN", "AFL_USE_CFISAN", "AFL_WINE_PATH", NULL}; + "AFL_USE_UBSAN", "AFL_USE_CFISAN", "AFL_WINE_PATH", "AFL_NO_SNAPSHOT", + NULL}; void detect_file_args(char **argv, u8 *prog_in, u8 *use_stdin) { From 9ef4b45609c4bf6448b0ae08bc644f0aa7a9f88b Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Apr 2020 03:54:49 +0200 Subject: [PATCH 37/72] ctx done --- docs/Changelog.md | 4 +- docs/env_variables.md | 14 ++++++ llvm_mode/README.ctx.md | 22 ++++++++++ llvm_mode/README.md | 30 ++++++++++--- llvm_mode/README.ngram.md | 7 +++ llvm_mode/afl-clang-fast.c | 7 ++- llvm_mode/afl-llvm-pass.so.cc | 83 +++++++++++++++++++++++++++++++++-- llvm_mode/afl-llvm-rt.o.c | 7 ++- src/afl-common.c | 2 +- 9 files changed, 162 insertions(+), 14 deletions(-) create mode 100644 llvm_mode/README.ctx.md diff --git a/docs/Changelog.md b/docs/Changelog.md index 31a9b69a..7af8a62e 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -43,7 +43,9 @@ sending a mail to . note that this mode is amazing, but quite some targets won't compile - Added llvm_mode NGRAM prev_loc coverage by Adrean Herrera (https://github.com/adrianherrera/afl-ngram-pass/), activate by setting - AFL_LLVM_NGRAM_SIZE + AFL_LLVM_INSTRUMENT=NGRAM- or AFL_LLVM_NGRAM_SIZE= + - Added llvm_mode context sensitive branch coverage, activated by setting + AFL_LLVM_INSTRUMENT=CTX or AFL_LLVM_CTX=1 - llvm_mode InsTrim mode: - removed workaround for bug where paths were not instrumented and imported fix by author diff --git a/docs/env_variables.md b/docs/env_variables.md index 10a17a99..802e7bd0 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -146,6 +146,20 @@ Then there are a few specific features that are only available in llvm_mode: - Setting AFL_LLVM_NGRAM_SIZE or AFL_LLVM_INSTRUMENT=NGRAM-{value} activates ngram prev_loc coverage, good values are 2, 4 or 8 (any value between 2 and 16 is valid). + It is highly recommended to increase the MAP_SIZE_POW2 definition in + config.h to at least 18 and maybe up to 20 for this as otherwise too + many map collisions occur. + + See llvm_mode/README.ctx.md + +### CTX + + - Setting AFL_LLVM_CTX or AFL_LLVM_INSTRUMENT=CTX + activates context sensitive branch coverage - meaning that each edge + is additionally combined with its caller. + It is highly recommended to increase the MAP_SIZE_POW2 definition in + config.h to at least 18 and maybe up to 20 for this as otherwise too + many map collisions occur. See llvm_mode/README.ngram.md diff --git a/llvm_mode/README.ctx.md b/llvm_mode/README.ctx.md new file mode 100644 index 00000000..14255313 --- /dev/null +++ b/llvm_mode/README.ctx.md @@ -0,0 +1,22 @@ +# AFL Context Sensitive Branch Coverage + +## What is this? + +This is an LLVM-based implementation of the context sensitive branch coverage. + +Basically every function gets it's own ID and that ID is combined with the +edges of the called functions. + +So if both function A and function B call a function C, the coverage +collected in C will be different. + +In math the coverage is collected as follows: +`map[current_location_ID ^ previous_location_ID >> 1 ^ previous_callee_ID] += 1` + +## Usage + +Set the `AFL_LLVM_INSTRUMENT=CTX` or `AFL_LLVM_CTX=1` environment variable. + +It is highly recommended to increase the MAP_SIZE_POW2 definition in +config.h to at least 18 and maybe up to 20 for this as otherwise too +many map collisions occur. diff --git a/llvm_mode/README.md b/llvm_mode/README.md index e6c47c9c..805bb659 100644 --- a/llvm_mode/README.md +++ b/llvm_mode/README.md @@ -92,13 +92,33 @@ which C/C++ files to actually instrument. See [README.whitelist](README.whitelis For splitting memcmp, strncmp, etc. please see [README.laf-intel](README.laf-intel.md) -Then there is an optimized instrumentation strategy that uses CFGs and -markers to just instrument what is needed. This increases speed by 20-25% -however has a lower path discovery. -If you want to use this, set AFL_LLVM_INSTRIM=1 +Then there are different ways of instrumenting the target: + +1. There is an optimized instrumentation strategy that uses CFGs and +markers to just instrument what is needed. This increases speed by 10-15% +without any disadvantages +If you want to use this, set AFL_LLVM_INSTRUMENT=CFG or AFL_LLVM_INSTRIM=1 See [README.instrim](README.instrim.md) -A new instrumentation called CmpLog is also available as an alternative to +2. An even better instrumentation strategy uses LTO and link time +instrumentation. Note that not all targets can compile in this mode, however +if it works it is the best option you can use. +Simply use afl-clang-lto/afl-clang-lto++ to use this option. +See [README.lto](README.lto.md) + +3. Alternativly you can choose a completely different coverage method: + +3a. N-GRAM coverage - which combines the previous visited edges with the +current one. This explodes the map but on the other hand has proven to be +effective for fuzzing. +See [README.ngram](README.ngram.md) + +3b. Context sensitive coverage - which combines the visited edges with an +individual caller ID (the function that called the current one) +[README.ctx](README.ctx.md) + +Then - additionally to one of the instrumentation options above - there is +a very effective new instrumentation option called CmpLog as an alternative to laf-intel that allow AFL++ to apply mutations similar to Redqueen. See [README.cmplog](README.cmplog.md) diff --git a/llvm_mode/README.ngram.md b/llvm_mode/README.ngram.md index 3540ada0..de3ba432 100644 --- a/llvm_mode/README.ngram.md +++ b/llvm_mode/README.ngram.md @@ -13,9 +13,16 @@ is built on top of AFL's QEMU mode. This is essentially a port that uses LLVM vectorized instructions to achieve the same results when compiling source code. +In math the branch coverage is performed as follows: +`map[current_location ^ prev_location[0] >> 1 ^ prev_location[1] >> 1 ^ ... up to n-1`] += 1` + ## Usage The size of `n` (i.e., the number of branches to remember) is an option that is specified either in the `AFL_LLVM_INSTRUMENT=NGRAM-{value}` or the `AFL_LLVM_NGRAM_SIZE` environment variable. Good values are 2, 4 or 8, valid are 2-16. + +It is highly recommended to increase the MAP_SIZE_POW2 definition in +config.h to at least 18 and maybe up to 20 for this as otherwise too +many map collisions occur. diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index 0e388cf4..657d1a84 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -544,9 +544,12 @@ int main(int argc, char **argv, char **envp) { instrument_mode = INSTRUMENT_PCGUARD; else if (strncasecmp(ptr, "lto", strlen("lto")) == 0) instrument_mode = INSTRUMENT_LTO; - else if (strncasecmp(ptr, "ctx", strlen("ctx")) == 0) + else if (strncasecmp(ptr, "ctx", strlen("ctx")) == 0) { + instrument_mode = INSTRUMENT_CTX; - else if (strncasecmp(ptr, "ngram", strlen("ngram")) == 0) { + setenv("AFL_LLVM_CTX", "1", 1); + + } else if (strncasecmp(ptr, "ngram", strlen("ngram")) == 0) { ptr += strlen("ngram"); while (*ptr && (*ptr < '0' || *ptr > '9')) diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc index 56f9ffe2..31d00fec 100644 --- a/llvm_mode/afl-llvm-pass.so.cc +++ b/llvm_mode/afl-llvm-pass.so.cc @@ -124,6 +124,8 @@ class AFLCoverage : public ModulePass { protected: std::list myWhitelist; uint32_t ngram_size = 0; + uint32_t debug = 0; + char * ctx_str = NULL; }; @@ -179,6 +181,8 @@ bool AFLCoverage::runOnModule(Module &M) { char be_quiet = 0; + if (getenv("AFL_DEBUG")) debug = 1; + if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) { SAYF(cCYA "afl-llvm-pass" VERSION cRST @@ -209,6 +213,7 @@ bool AFLCoverage::runOnModule(Module &M) { char *ngram_size_str = getenv("AFL_LLVM_NGRAM_SIZE"); if (!ngram_size_str) ngram_size_str = getenv("AFL_NGRAM_SIZE"); + ctx_str = getenv("AFL_LLVM_CTX"); #ifdef AFL_HAVE_VECTOR_INTRINSICS /* Decide previous location vector size (must be a power of two) */ @@ -228,9 +233,8 @@ bool AFLCoverage::runOnModule(Module &M) { else #else if (ngram_size_str) - FATAL( - "Sorry, n-gram branch coverage is not supported with llvm version %s!", - LLVM_VERSION_STRING); + FATAL("Sorry, NGRAM branch coverage is not supported with llvm version %s!", + LLVM_VERSION_STRING); #endif PrevLocSize = 1; @@ -239,6 +243,9 @@ bool AFLCoverage::runOnModule(Module &M) { if (ngram_size) PrevLocTy = VectorType::get(IntLocTy, PrevLocVecSize); #endif + if (ctx_str && ngram_size_str) + FATAL("you must decide between NGRAM and CTX instrumentation"); + /* Get globals for the SHM region and the previous location. Note that __afl_prev_loc is thread-local. */ @@ -246,6 +253,17 @@ bool AFLCoverage::runOnModule(Module &M) { new GlobalVariable(M, PointerType::get(Int8Ty, 0), false, GlobalValue::ExternalLinkage, 0, "__afl_area_ptr"); GlobalVariable *AFLPrevLoc; + GlobalVariable *AFLContext; + + if (ctx_str) +#ifdef __ANDROID__ + AFLContext = new GlobalVariable( + M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_ctx"); +#else + AFLContext = new GlobalVariable( + M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_ctx", 0, + GlobalVariable::GeneralDynamicTLSModel, 0, false); +#endif #ifdef AFL_HAVE_VECTOR_INTRINSICS if (ngram_size) @@ -291,14 +309,70 @@ bool AFLCoverage::runOnModule(Module &M) { ConstantInt *Zero = ConstantInt::get(Int8Ty, 0); ConstantInt *One = ConstantInt::get(Int8Ty, 1); + LoadInst *PrevCtx; // CTX sensitive coverage + /* Instrument all the things! */ int inst_blocks = 0; for (auto &F : M) { + if (debug) + fprintf(stderr, "FUNCTION: %s (%zu)\n", F.getName().str().c_str(), + F.size()); + if (isBlacklisted(&F)) continue; + // AllocaInst *CallingContext = nullptr; + + if (ctx_str && F.size() > 1) { // Context sensitive coverage + // load the context ID of the previous function and write to to a local + // variable on the stack + auto bb = &F.getEntryBlock(); + BasicBlock::iterator IP = bb->getFirstInsertionPt(); + IRBuilder<> IRB(&(*IP)); + PrevCtx = IRB.CreateLoad(AFLContext); + PrevCtx->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); + + // does the function have calls? and is any of the calls larger than one + // basic block? + int has_calls = 0; + for (auto &BB : F) { + + if (has_calls) break; + for (auto &IN : BB) { + + CallInst *callInst = nullptr; + if ((callInst = dyn_cast(&IN))) { + + Function *Callee = callInst->getCalledFunction(); + if (!Callee || Callee->size() < 2) + continue; + else { + + has_calls = 1; + break; + + } + + } + + } + + } + + // if yes we store a context ID for this function in the global var + if (has_calls) { + + ConstantInt *NewCtx = ConstantInt::get(Int32Ty, AFL_R(MAP_SIZE)); + StoreInst * StoreCtx = IRB.CreateStore(NewCtx, AFLContext); + StoreCtx->setMetadata(M.getMDKindID("nosanitize"), + MDNode::get(C, None)); + + } + + } + for (auto &BB : F) { BasicBlock::iterator IP = BB.getFirstInsertionPt(); @@ -484,6 +558,9 @@ bool AFLCoverage::runOnModule(Module &M) { PrevLocTrans = IRB.CreateXorReduce(PrevLoc); else #endif + if (ctx_str) + PrevLocTrans = IRB.CreateZExt(IRB.CreateXor(PrevLoc, PrevCtx), Int32Ty); + else PrevLocTrans = IRB.CreateZExt(PrevLoc, IRB.getInt32Ty()); /* Load SHM pointer */ diff --git a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c index ade9eeef..31dc16fd 100644 --- a/llvm_mode/afl-llvm-rt.o.c +++ b/llvm_mode/afl-llvm-rt.o.c @@ -65,13 +65,16 @@ u8 *__afl_area_ptr = __afl_area_initial; #ifdef __ANDROID__ PREV_LOC_T __afl_prev_loc[NGRAM_SIZE_MAX]; u32 __afl_final_loc; +u32 __afl_prev_ctx; +u32 __afl_cmp_counter #else __thread PREV_LOC_T __afl_prev_loc[NGRAM_SIZE_MAX]; __thread u32 __afl_final_loc; +__thread u32 __afl_prev_ctx; +__thread u32 __afl_cmp_counter; #endif -struct cmp_map *__afl_cmp_map; -__thread u32 __afl_cmp_counter; + struct cmp_map *__afl_cmp_map; /* Running in persistent mode? */ diff --git a/src/afl-common.c b/src/afl-common.c index c1adefeb..f6eed3a1 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -57,7 +57,7 @@ char *afl_environment_variables[] = { "AFL_INST_LIBS", "AFL_INST_RATIO", "AFL_KEEP_TRACES", "AFL_KEEP_ASSEMBLY", "AFL_LD_HARD_FAIL", "AFL_LD_LIMIT_MB", "AFL_LD_NO_CALLOC_OVER", "AFL_LD_PRELOAD", "AFL_LD_VERBOSE", "AFL_LLVM_CMPLOG", "AFL_LLVM_INSTRIM", - "AFL_LLVM_INSTRUMENT", "AFL_LLVM_INSTRIM_LOOPHEAD", + "AFL_LLVM_CTX", "AFL_LLVM_INSTRUMENT", "AFL_LLVM_INSTRIM_LOOPHEAD", "AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK", "AFL_LLVM_LAF_SPLIT_COMPARES", "AFL_LLVM_LAF_SPLIT_COMPARES_BITW", "AFL_LLVM_LAF_SPLIT_FLOATS", "AFL_LLVM_LAF_SPLIT_SWITCHES", "AFL_LLVM_LAF_TRANSFORM_COMPARES", From a5036499d282f2c60a3e8cd9a900ed27d8217640 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Apr 2020 04:28:13 +0200 Subject: [PATCH 38/72] update readme --- README.md | 6 ++++-- TODO.md | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e1ca5949..8d167f7e 100644 --- a/README.md +++ b/README.md @@ -74,10 +74,12 @@ | Non-colliding coverage | | x(4) | | (x)(5) | | | InsTrim | | x | | | | | Ngram prev_loc coverage | | x(6) | | | | + | Context coverage | | x | | | | + | Snapshot LKM support | | x | | (x)(5) | | neverZero: - (1) only in LLVM >= 9.0 due to a bug in LLVM in previous versions + (1) default for LLVM >= 9.0, env var for older version due an efficiency bug in llvm <= 8 (2) GCC creates non-performant code, hence it is disabled in gcc_plugin @@ -87,7 +89,7 @@ (5) upcoming, development in the branch - (6) not compatible with LTO and InsTrim modes + (6) not compatible with LTO and InsTrim and needs at least LLVM >= 4.1 So all in all this is the best-of afl that is currently out there :-) diff --git a/TODO.md b/TODO.md index 91297332..ffb8f647 100644 --- a/TODO.md +++ b/TODO.md @@ -11,7 +11,7 @@ - context sensitive branch coverage in llvm_mode - random crc32 HASH_CONST per run? because with 65536 paths we have collisions - + - namespace for targets? e.g. network ## Further down the road From 91dc7776ecc52ce92b2bc985d0fa86f84bf72586 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Tue, 7 Apr 2020 20:05:57 +0100 Subject: [PATCH 39/72] Android build fix proposal. LTO flag is recognised but however broken on Android (tested with armv7 arch). Thus giving the choice not to enable it. In fortify mode, open required O_CREAT or O_TMPFILE when mode is set. --- GNUmakefile | 2 ++ src/afl-fuzz-extras.c | 2 +- src/afl-showmap.c | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 25928210..0cbeaa81 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -36,6 +36,7 @@ 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 "$(findstring android, $(shell $(CC) --version 2>/dev/null))" "" 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 @@ -47,6 +48,7 @@ else endif 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" diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 4dd1647c..16806934 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -451,7 +451,7 @@ void load_auto(afl_state_t *afl) { u8 *fn = alloc_printf("%s/.state/auto_extras/auto_%06u", afl->in_dir, i); s32 fd, len; - fd = open(fn, O_RDONLY, 0600); + fd = open(fn, O_RDONLY); if (fd < 0) { diff --git a/src/afl-showmap.c b/src/afl-showmap.c index f8a38c36..e4463dc4 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -154,7 +154,8 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) { if (!strncmp(outfile, "/dev/", 5)) { - fd = open(outfile, O_WRONLY, 0600); + fd = open(outfile, O_WRONLY); + if (fd < 0) PFATAL("Unable to open '%s'", fsrv->out_file); } else if (!strcmp(outfile, "-")) { From dbe6b1da44690f482f3c8dfe10d147da8cbdb1ef Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Wed, 8 Apr 2020 08:14:42 +0200 Subject: [PATCH 40/72] gcc_plugin fix compile for USEMMAP --- gcc_plugin/GNUmakefile | 2 +- gcc_plugin/afl-gcc-rt.o.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/gcc_plugin/GNUmakefile b/gcc_plugin/GNUmakefile index 4c7a0313..9a404966 100644 --- a/gcc_plugin/GNUmakefile +++ b/gcc_plugin/GNUmakefile @@ -29,7 +29,7 @@ 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 \ +CFLAGS = -Wall -I../include -Wno-pointer-sign \ -DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \ -DGCC_VERSION=\"$(GCCVER)\" -DGCC_BINDIR=\"$(GCCBINDIR)\" \ -Wno-unused-function diff --git a/gcc_plugin/afl-gcc-rt.o.c b/gcc_plugin/afl-gcc-rt.o.c index 77bb5325..30606150 100644 --- a/gcc_plugin/afl-gcc-rt.o.c +++ b/gcc_plugin/afl-gcc-rt.o.c @@ -25,6 +25,9 @@ #include "../config.h" #include "../types.h" +#ifdef USEMMAP +#include +#endif #include #include #include From 11e3122843e352e1ed51788d256133e019d64069 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Wed, 8 Apr 2020 08:16:55 +0200 Subject: [PATCH 41/72] gcc_plugin: portable Makefile --- gcc_plugin/Makefile | 161 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 159 insertions(+), 2 deletions(-) diff --git a/gcc_plugin/Makefile b/gcc_plugin/Makefile index 0b306dde..1c6f365f 100644 --- a/gcc_plugin/Makefile +++ b/gcc_plugin/Makefile @@ -1,2 +1,159 @@ -all: - @echo please use GNU make, thanks! +# +# 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) +VERSION:sh= grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2 + +CFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=2 +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++ + +MYCC=$(CC:clang=gcc) +MYCXX=$(CXX:clang++=g++) + +PLUGIN_PATH = $(shell $(MYCC) -print-file-name=plugin) +PLUGIN_PATH:sh= $(MYCC) -print-file-name=plugin +PLUGIN_FLAGS = -fPIC -fno-rtti -I"$(PLUGIN_PATH)/include" +HASH=\# + +GCCVER = $(shell $(MYCC) --version 2>/dev/null | awk 'NR == 1 {print $$NF}') +GCCBINDIR = $(shell dirname `command -v $(MYCC)` 2>/dev/null ) + +_SHMAT_OK= $(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' | $(MYCC) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 ) +_SHMAT_OK:sh= 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' | $(MYCC) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 + +IGNORE_MMAP=$(TEST_MMAP:1=0) +__SHMAT_OK=$(_SHMAT_OK)$(IGNORE_MMAP) +___SHMAT_OK=$(__SHMAT_OK:10=0) +SHMAT_OK=$(___SHMAT_OK:1=1) +_CFLAGS_ADD=$(SHMAT_OK:1=) +CFLAGS_ADD=$(_CFLAGS_ADD:0=-DUSEMMAP=1) + +_LDFLAGS_ADD=$(SHMAT_OK:1=) +LDFLAGS_ADD=$(_LDFLAGS_ADD:0=-lrt) + +CFLAGS += $(CFLAGS_ADD) +LDFLAGS += $(LDFLAGS_ADD) + +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 + +debug: + @echo _SHMAT_OK = $(_SHMAT_OK) + @echo IGNORE_MMAP = $(IGNORE_MMAP) + @echo __SHMAT_OK = $(__SHMAT_OK) + @echo ___SHMAT_OK = $(___SHMAT_OK) + @echo SHMAT_OK = $(SHMAT_OK) + +test_shm: + @if [ "$(SHMAT_OK)" == "1" ]; then \ + echo "[+] shmat seems to be working."; \ + rm -f .test2; \ + else \ + echo "[-] shmat seems not to be working, switching to mmap implementation"; \ + fi + +test_deps: + @echo "[*] Checking for working '$(MYCC)'..." + @type $(MYCC) >/dev/null 2>&1 || ( echo "[-] Oops, can't find '$(MYCC)'. Make sure that it's in your \$$PATH (or set \$$CC and \$$CXX)."; exit 1 ) +# @echo "[*] Checking for gcc for plugin support..." +# @$(MYCC) -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 `$(MYCC) -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 + $(MYCC) $(CFLAGS) -c $< -o $@ $(LDFLAGS) + +../afl-gcc-fast: afl-gcc-fast.c afl-common.o | test_deps + $(MYCC) -DAFL_GCC_CC=\"$(MYCC)\" -DAFL_GCC_CXX=\"$(MYCXX)\" $(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 + $(MYCXX) $(CXXEFLAGS) $(PLUGIN_FLAGS) -shared $< -o $@ + +../afl-gcc-rt.o: afl-gcc-rt.o.c | test_deps + $(MYCC) $(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 From 3bf88da0912118820bce06fabc1de590364cfcdc Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Wed, 8 Apr 2020 08:50:30 +0200 Subject: [PATCH 42/72] libdislocator: make Makefile portable --- libdislocator/GNUmakefile | 44 -------------------------------------- libdislocator/Makefile | 45 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 46 deletions(-) delete mode 100644 libdislocator/GNUmakefile diff --git a/libdislocator/GNUmakefile b/libdislocator/GNUmakefile deleted file mode 100644 index 3ee37088..00000000 --- a/libdislocator/GNUmakefile +++ /dev/null @@ -1,44 +0,0 @@ -# -# 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 0b306dde..201f1e92 100644 --- a/libdislocator/Makefile +++ b/libdislocator/Makefile @@ -1,2 +1,43 @@ -all: - @echo please use GNU make, thanks! +# +# 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 -D_FORTIFY_SOURCE=2 +CFLAGS += -I ../include/ -Wall -g -Wno-pointer-sign + +CFLAGS_ADD=$(USEHUGEPAGE:1=-DUSEHUGEPAGE) +CFLAGS += $(CFLAGS_ADD) + +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) + From 2900d51e5d110a526f89df4af70f10fbfc9cf595 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Wed, 8 Apr 2020 10:20:53 +0200 Subject: [PATCH 43/72] socket_fuzzing Makefile: make it portable --- examples/socket_fuzzing/GNUmakefile | 48 ----------------------- examples/socket_fuzzing/Makefile | 61 ++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 50 deletions(-) delete mode 100644 examples/socket_fuzzing/GNUmakefile diff --git a/examples/socket_fuzzing/GNUmakefile b/examples/socket_fuzzing/GNUmakefile deleted file mode 100644 index ad921664..00000000 --- a/examples/socket_fuzzing/GNUmakefile +++ /dev/null @@ -1,48 +0,0 @@ -# -# 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 0b306dde..2fdc58ee 100644 --- a/examples/socket_fuzzing/Makefile +++ b/examples/socket_fuzzing/Makefile @@ -1,2 +1,59 @@ -all: - @echo please use GNU make, thanks! +# +# 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 + +UNAME_SAYS_LINUX=$(shell uname | grep -E '^Linux|^GNU' >/dev/null; echo $$?) +UNAME_SAYS_LINUX:sh=uname | grep -E '^Linux|^GNU' >/dev/null; echo $$? + +_LDFLAGS_ADD=$(UNAME_SAYS_LINUX:1=) +LDFLAGS_ADD=$(_LDFLAGS_ADD:0=-ldl) +LDFLAGS += $(LDFLAGS_ADD) + +# on gcc for arm there is no -m32, but -mbe32 +M32FLAG = -m32 +M64FLAG = -m64 + +CC_IS_GCC=$(shell $(CC) --version 2>/dev/null | grep gcc; echo $$?) +CC_IS_ARMCOMPILER=$(shell $(CC) -v 2>&1 >/dev/null | grep arm; echo $$?) + +_M32FLAG=$(CC_IS_GCC)$(CC_IS_ARMCOMPILER) +__M32FLAG=$(_M32FLAG:00=-mbe32) +___M32FLAG=$(__M32FLAG:$(CC_IS_GCC)$(CC_IS_ARMCOMPILER)=-m32) +M32FLAG=$(___M32FLAG) +#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 From 9aa10ef7caf6dfd3dc0bc602b46d3b8b8087333d Mon Sep 17 00:00:00 2001 From: hexcoder Date: Wed, 8 Apr 2020 10:39:32 +0200 Subject: [PATCH 44/72] fix travis --- llvm_mode/afl-llvm-rt.o.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c index e2fd5190..f6c60a11 100644 --- a/llvm_mode/afl-llvm-rt.o.c +++ b/llvm_mode/afl-llvm-rt.o.c @@ -238,7 +238,7 @@ static void __afl_start_snapshots(void) { if (!afl_snapshot_do()) { raise(SIGSTOP); } __afl_area_ptr[0] = 1; - memset(__afl_prev_loc, 0, MAX_NGRAM_SIZE * sizeof(PREV_LOC_T)); + memset(__afl_prev_loc, 0, NGRAM_SIZE_MAX * sizeof(PREV_LOC_T)); return; From 48e366d7a8507997bb386b181401f37a421bd843 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Wed, 8 Apr 2020 10:44:42 +0200 Subject: [PATCH 45/72] argv_fuzzing Makefile: portable version --- examples/argv_fuzzing/GNUmakefile | 51 --------------------------- examples/argv_fuzzing/Makefile | 58 +++++++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 53 deletions(-) delete mode 100644 examples/argv_fuzzing/GNUmakefile diff --git a/examples/argv_fuzzing/GNUmakefile b/examples/argv_fuzzing/GNUmakefile deleted file mode 100644 index 34192e39..00000000 --- a/examples/argv_fuzzing/GNUmakefile +++ /dev/null @@ -1,51 +0,0 @@ -# -# 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 0b306dde..104d0f55 100644 --- a/examples/argv_fuzzing/Makefile +++ b/examples/argv_fuzzing/Makefile @@ -1,2 +1,56 @@ -all: - @echo please use GNU make, thanks! +# +# 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 + +UNAME_SAYS_LINUX=$(shell uname | grep -E '^Linux|^GNU' >/dev/null; echo $$?) +UNAME_SAYS_LINUX:sh=uname | grep -E '^Linux|^GNU' >/dev/null; echo $$? + +_LDFLAGS_ADD=$(UNAME_SAYS_LINUX:1=) +LDFLAGS_ADD=$(_LDFLAGS_ADD:0=-ldl) +LDFLAGS += $(LDFLAGS_ADD) + +# on gcc for arm there is no -m32, but -mbe32 +M32FLAG = -m32 +M64FLAG = -m64 + +CC_IS_GCC=$(shell $(CC) --version 2>/dev/null | grep gcc; echo $$?) +CC_IS_ARMCOMPILER=$(shell $(CC) -v 2>&1 >/dev/null | grep arm; echo $$?) + +_M32FLAG=$(CC_IS_GCC)$(CC_IS_ARMCOMPILER) +__M32FLAG=$(_M32FLAG:00=-mbe32) +___M32FLAG=$(__M32FLAG:$(CC_IS_GCC)$(CC_IS_ARMCOMPILER)=-m32) +M32FLAG=$(___M32FLAG) + +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 From 968295ed815aefdaf89286fa2e14d7971311a698 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Apr 2020 12:34:01 +0200 Subject: [PATCH 46/72] added snapshot feature to documentation --- docs/Changelog.md | 1 + docs/env_variables.md | 3 +++ llvm_mode/README.md | 12 +++++++++--- llvm_mode/README.snapshot.md | 12 ++++++++++++ src/afl-fuzz.c | 1 + 5 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 llvm_mode/README.snapshot.md diff --git a/docs/Changelog.md b/docs/Changelog.md index 7af8a62e..424b61dc 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -35,6 +35,7 @@ sending a mail to . - rare: puts focus on queue entries that hits rare branches, also ignores runtime - llvm_mode: + - added SNAPSHOT feature (using https://github.com/AFLplusplus/AFL-Snapshot-LKM) - added Control Flow Integrity sanitizer (AFL_USE_CFISAN) - added AFL_LLVM_INSTRUMENT option to control the instrumentation type easier: DEFAULT, CFG (INSTRIM), LTO, CTX, NGRAM-x (x=2-16) diff --git a/docs/env_variables.md b/docs/env_variables.md index 802e7bd0..cd002145 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -257,6 +257,9 @@ checks or alter some of the more exotic semantics of the tool: - AFL_NO_ARITH causes AFL to skip most of the deterministic arithmetics. This can be useful to speed up the fuzzing of text-based file formats. + - AFL_NO_SNAPSHOT will advice afl-fuzz not to use the snapshot feature + if the snapshot lkm is loaded + - AFL_SHUFFLE_QUEUE randomly reorders the input queue on startup. Requested by some users for unorthodox parallelized fuzzing setups, but not advisable otherwise. diff --git a/llvm_mode/README.md b/llvm_mode/README.md index 805bb659..607350fb 100644 --- a/llvm_mode/README.md +++ b/llvm_mode/README.md @@ -129,12 +129,18 @@ is not optimal and was only fixed in llvm 9. You can set this with AFL_LLVM_NOT_ZERO=1 See [README.neverzero](README.neverzero.md) -## 4) Gotchas, feedback, bugs +## 4) Snapshot feature + +To speed up fuzzing you can use a linux loadable kernel module which enables +a snapshot feature. +See [README.snapshot](README.snapshot.md) + +## 5) Gotchas, feedback, bugs This is an early-stage mechanism, so field reports are welcome. You can send bug reports to . -## 5) Bonus feature #1: deferred initialization +## 6) Bonus feature #1: deferred initialization AFL tries to optimize performance by executing the targeted binary just once, stopping it just before main(), and then cloning this "master" process to get @@ -182,7 +188,7 @@ will keep working normally when compiled with a tool other than afl-clang-fast. Finally, recompile the program with afl-clang-fast (afl-gcc or afl-clang will *not* generate a deferred-initialization binary) - and you should be all set! -## 6) Bonus feature #2: persistent mode +## 7) Bonus feature #2: persistent mode Some libraries provide APIs that are stateless, or whose state can be reset in between processing different input files. When such a reset is performed, a diff --git a/llvm_mode/README.snapshot.md b/llvm_mode/README.snapshot.md new file mode 100644 index 00000000..6bf76b3d --- /dev/null +++ b/llvm_mode/README.snapshot.md @@ -0,0 +1,12 @@ +# AFL++ snapshot feature + +Snapshot is a mechanic that makes a snapshot from a process and then restores +it's state, which is faster then forking it again. + +All targets compiled with llvm_mode are automatically enabled for the +snapshot feature. + +To use the snapshot feature for fuzzing compile and load this kernel +module: [https://github.com/AFLplusplus/AFL-Snapshot-LKM](https://github.com/AFLplusplus/AFL-Snapshot-LKM) + +Note that is has little value for persistent (__AFL_LOOP) fuzzing. diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index ad4f5b6b..e348f758 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -165,6 +165,7 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) { "AFL_FORCE_UI: force showing the status screen (for virtual consoles)\n" "AFL_NO_CPU_RED: avoid red color for showing very high cpu usage\n" "AFL_SKIP_CPUFREQ: do not warn about variable cpu clocking\n" + "AFL_NO_SNAPSHOT: do not use the snapshot feature (if the snapshot lkm is loaded\n" "AFL_NO_FORKSRV: run target via execve instead of using the forkserver\n" "AFL_NO_ARITH: skip arithmetic mutations in deterministic stage\n" "AFL_SHUFFLE_QUEUE: reorder the input queue randomly on startup\n" From 055ca98fb2a98f81bbe9e419eeea840d256490e9 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Apr 2020 12:52:14 +0200 Subject: [PATCH 47/72] add missing piece for CTX coverage --- llvm_mode/afl-llvm-pass.so.cc | 16 ++++++++++++++++ llvm_mode/afl-llvm-rt.o.c | 2 ++ 2 files changed, 18 insertions(+) diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc index 31d00fec..058ab71f 100644 --- a/llvm_mode/afl-llvm-pass.so.cc +++ b/llvm_mode/afl-llvm-pass.so.cc @@ -682,6 +682,22 @@ bool AFLCoverage::runOnModule(Module &M) { } + // in CTX mode we have to restore the original context for the caller - + // she might be calling other functions which need the correct CTX + if (ctx_str) { + + Instruction *Inst = BB.getTerminator(); + if (isa(Inst) || isa(Inst)) { + + IRBuilder<> Post_IRB(Inst); + StoreInst * RestoreCtx = Post_IRB.CreateStore(PrevCtx, AFLContext); + RestoreCtx->setMetadata(M.getMDKindID("nosanitize"), + MDNode::get(C, None)); + + } + + } + inst_blocks++; } diff --git a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c index f6c60a11..aac7d061 100644 --- a/llvm_mode/afl-llvm-rt.o.c +++ b/llvm_mode/afl-llvm-rt.o.c @@ -273,6 +273,7 @@ static void __afl_start_snapshots(void) { } } + #endif /* Fork server logic. */ @@ -287,6 +288,7 @@ static void __afl_start_forkserver(void) { return; } + #endif static u8 tmp[4]; From 15e0319c98d134b39f0d4fce3f4658872154e1b1 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Apr 2020 13:12:14 +0200 Subject: [PATCH 48/72] update todo --- TODO.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/TODO.md b/TODO.md index ffb8f647..22fab6b1 100644 --- a/TODO.md +++ b/TODO.md @@ -4,14 +4,15 @@ - complete custom_mutator API changes and documentation - fix stability calculation bug - - libradamsa as a custom module? - + - fix afl-cmin bug ## Roadmap 2.64 - context sensitive branch coverage in llvm_mode - random crc32 HASH_CONST per run? because with 65536 paths we have collisions - namespace for targets? e.g. network + - libradamsa as a custom module? + - laf-intel build auto-dictionary? ## Further down the road From 7663e7dd05ca7d3da6120c63bd8bacf3c2894817 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Wed, 8 Apr 2020 17:38:45 +0200 Subject: [PATCH 49/72] fix compilation in OpenBSD --- src/afl-fuzz-bitmap.c | 1 + src/afl-fuzz-init.c | 1 + src/afl-fuzz-queue.c | 1 + src/afl-fuzz-stats.c | 1 + 4 files changed, 4 insertions(+) diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 63c3a2c2..6b6a07e2 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -23,6 +23,7 @@ */ +#include #include "afl-fuzz.h" /* Write bitmap to file. The bitmap is useful mostly for the secret diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index e2495524..b81ec1c8 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -23,6 +23,7 @@ */ +#include #include "afl-fuzz.h" #ifdef HAVE_AFFINITY diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 6c687ae4..aad4f3c0 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -22,6 +22,7 @@ */ +#include #include "afl-fuzz.h" /* Mark deterministic checks as done for a particular queue entry. We use the diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index d9f8c99c..48185298 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -23,6 +23,7 @@ */ +#include #include "afl-fuzz.h" /* Update stats file for unattended monitoring. */ From 1b5b54fe94afa3d34f9ce165e38f45fe47e6a821 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Apr 2020 15:49:34 +0200 Subject: [PATCH 50/72] fix limits.h include --- src/afl-fuzz-bitmap.c | 2 +- src/afl-fuzz-init.c | 2 +- src/afl-fuzz-queue.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 6b6a07e2..c5347dcb 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -23,8 +23,8 @@ */ -#include #include "afl-fuzz.h" +#include /* Write bitmap to file. The bitmap is useful mostly for the secret -B option, to focus a separate fuzzing session on a particular diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index b81ec1c8..efdde463 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -23,8 +23,8 @@ */ -#include #include "afl-fuzz.h" +#include #ifdef HAVE_AFFINITY diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index aad4f3c0..174d7d92 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -22,8 +22,8 @@ */ -#include #include "afl-fuzz.h" +#include /* Mark deterministic checks as done for a particular queue entry. We use the .state file to avoid repeating deterministic fuzzing when resuming aborted From 67e9ef43a7cd4b664a76993fc8baa5b97106cb1f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Apr 2020 17:22:31 +0200 Subject: [PATCH 51/72] llvm_mode android fix --- llvm_mode/afl-llvm-rt.o.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c index aac7d061..4b140e14 100644 --- a/llvm_mode/afl-llvm-rt.o.c +++ b/llvm_mode/afl-llvm-rt.o.c @@ -70,7 +70,7 @@ u8 *__afl_area_ptr = __afl_area_initial; PREV_LOC_T __afl_prev_loc[NGRAM_SIZE_MAX]; u32 __afl_final_loc; u32 __afl_prev_ctx; -u32 __afl_cmp_counter +u32 __afl_cmp_counter; #else __thread PREV_LOC_T __afl_prev_loc[NGRAM_SIZE_MAX]; __thread u32 __afl_final_loc; From 729dbf7dda1fb2ddae0e1687533d17d228beb92a Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Wed, 8 Apr 2020 17:53:25 +0000 Subject: [PATCH 52/72] afl-fuzz: add usage info when no python support is there, use it in test.sh --- src/afl-fuzz.c | 2 + test/test.sh | 146 +++++++++++++++++++++++++------------------------ 2 files changed, 78 insertions(+), 70 deletions(-) diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index e348f758..a4c5cfb5 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -198,6 +198,8 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) { #ifdef USE_PYTHON SAYF("Compiled with %s module support, see docs/custom_mutator.md\n", (char *)PYTHON_VERSION); +#else + SAYF("Compiled without python module support\n"); #endif SAYF("For additional help please consult %s/README.md\n\n", doc_path); diff --git a/test/test.sh b/test/test.sh index a04df384..f6725dad 100755 --- a/test/test.sh +++ b/test/test.sh @@ -471,8 +471,9 @@ test -e ../afl-clang-lto -a -e ../afl-llvm-lto-instrumentation.so && { } $ECHO "$BLUE[*] Testing: gcc_plugin" -export AFL_CC=`command -v gcc` test -e ../afl-gcc-fast -a -e ../afl-gcc-rt.o && { + SAVE_AFL_CC=${AFL_CC} + export AFL_CC=`command -v gcc` ../afl-gcc-fast -o test-instr.plain.gccpi ../test-instr.c > /dev/null 2>&1 AFL_HARDEN=1 ../afl-gcc-fast -o test-compcov.harden.gccpi test-compcov.c > /dev/null 2>&1 test -e test-instr.plain.gccpi && { @@ -574,6 +575,7 @@ test -e ../afl-gcc-fast -a -e ../afl-gcc-rt.o && { CODE=1 } rm -f test-persistent + export AFL_CC=${SAVE_AFL_CC} # restore the default compiler } || { $ECHO "$YELLOW[-] gcc_plugin not compiled, cannot test" INCOMPLETE=1 @@ -894,82 +896,86 @@ test -d ../unicorn_mode/unicornafl && { } $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__/ +test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && { + test `uname -s` = 'Darwin' && { + CUSTOM_MUTATOR_PATH=$( realpath ../examples/custom_mutators ) } || { - ls . - ls ${CUSTOM_MUTATOR_PATH} - $ECHO "$RED[!] cannot compile the test program or the custom mutator" - CODE=1 + 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 - #test "$CODE" = 1 && { $ECHO "$YELLOW[!] custom mutator tests currently will not fail travis" ; CODE=0 ; } + # 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 - make -C ../examples/custom_mutators clean > /dev/null 2>&1 - rm -f test-custom-mutator + # 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 + } + + #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 + } || { + $ECHO "$YELLOW[-] no custom mutators in $CUSTOM_MUTATOR_PATH, cannot test" + INCOMPLETE=1 + } + unset CUSTOM_MUTATOR_PATH } || { - $ECHO "$YELLOW[-] no custom mutators in $CUSTOM_MUTATOR_PATH, cannot test" + $ECHO "$YELLOW[-] no python support in afl-fuzz, cannot test" INCOMPLETE=1 } -unset CUSTOM_MUTATOR_PATH $ECHO "$BLUE[*] Execution cmocka Unit-Tests $GREY" unset AFL_CC From 133a8cea1c56e58497c5e32de2a8fc8d72d56074 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Apr 2020 17:57:11 +0200 Subject: [PATCH 53/72] llvm_mode ctx: move function terminator instrumentation before skipping blocks --- llvm_mode/afl-llvm-pass.so.cc | 35 ++++++++++++++++++----------------- llvm_mode/afl-llvm-rt.o.c | 2 +- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc index 058ab71f..b4249802 100644 --- a/llvm_mode/afl-llvm-pass.so.cc +++ b/llvm_mode/afl-llvm-pass.so.cc @@ -317,6 +317,7 @@ bool AFLCoverage::runOnModule(Module &M) { for (auto &F : M) { + int has_calls = 0; if (debug) fprintf(stderr, "FUNCTION: %s (%zu)\n", F.getName().str().c_str(), F.size()); @@ -336,7 +337,7 @@ bool AFLCoverage::runOnModule(Module &M) { // does the function have calls? and is any of the calls larger than one // basic block? - int has_calls = 0; + has_calls = 0; for (auto &BB : F) { if (has_calls) break; @@ -487,6 +488,22 @@ bool AFLCoverage::runOnModule(Module &M) { } + // in CTX mode we have to restore the original context for the caller - + // she might be calling other functions which need the correct CTX + if (ctx_str && has_calls) { + + Instruction *Inst = BB.getTerminator(); + if (isa(Inst) || isa(Inst)) { + + IRBuilder<> Post_IRB(Inst); + StoreInst * RestoreCtx = Post_IRB.CreateStore(PrevCtx, AFLContext); + RestoreCtx->setMetadata(M.getMDKindID("nosanitize"), + MDNode::get(C, None)); + + } + + } + if (AFL_R(100) >= inst_ratio) continue; /* Make up cur_loc */ @@ -682,22 +699,6 @@ bool AFLCoverage::runOnModule(Module &M) { } - // in CTX mode we have to restore the original context for the caller - - // she might be calling other functions which need the correct CTX - if (ctx_str) { - - Instruction *Inst = BB.getTerminator(); - if (isa(Inst) || isa(Inst)) { - - IRBuilder<> Post_IRB(Inst); - StoreInst * RestoreCtx = Post_IRB.CreateStore(PrevCtx, AFLContext); - RestoreCtx->setMetadata(M.getMDKindID("nosanitize"), - MDNode::get(C, None)); - - } - - } - inst_blocks++; } diff --git a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c index 4b140e14..3651fd97 100644 --- a/llvm_mode/afl-llvm-rt.o.c +++ b/llvm_mode/afl-llvm-rt.o.c @@ -78,7 +78,7 @@ __thread u32 __afl_prev_ctx; __thread u32 __afl_cmp_counter; #endif - struct cmp_map *__afl_cmp_map; +struct cmp_map *__afl_cmp_map; /* Running in persistent mode? */ From b32b9bd1d50324ae1f0219c5f161785f84db1851 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Wed, 8 Apr 2020 18:16:08 +0200 Subject: [PATCH 54/72] fix damage in test.sh --- test/test.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/test.sh b/test/test.sh index f6725dad..871345f0 100755 --- a/test/test.sh +++ b/test/test.sh @@ -575,7 +575,7 @@ test -e ../afl-gcc-fast -a -e ../afl-gcc-rt.o && { CODE=1 } rm -f test-persistent - export AFL_CC=${SAVE_AFL_CC} # restore the default compiler + export AFL_CC=${SAVE_AFL_CC} } || { $ECHO "$YELLOW[-] gcc_plugin not compiled, cannot test" INCOMPLETE=1 @@ -903,6 +903,7 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && { 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 && { + unset AFL_CC # Compile the vulnerable program ../afl-clang-fast -o test-custom-mutator test-custom-mutator.c > /dev/null 2>&1 # Compile the custom mutator From 3353a23fcbce32f51dd43fe5bb6d619576573e72 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Apr 2020 18:19:38 +0200 Subject: [PATCH 55/72] one more include move --- src/afl-fuzz-stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 48185298..850555b5 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -23,8 +23,8 @@ */ -#include #include "afl-fuzz.h" +#include /* Update stats file for unattended monitoring. */ From 7793ca4055fd29f1d0a4223d1f122694fbafb1e4 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Apr 2020 18:28:35 +0200 Subject: [PATCH 56/72] fix travis - heiko test your changes on linux pls ;) --- test/test.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/test.sh b/test/test.sh index 871345f0..0666ca36 100755 --- a/test/test.sh +++ b/test/test.sh @@ -616,7 +616,6 @@ test -e ../libdislocator.so && { rm -f test-compcov test -e ../libradamsa.so && { # on FreeBSD need to set AFL_CC - test `uname -s` = 'FreeBSD' && { if type clang >/dev/null; then export AFL_CC=`command -v clang` @@ -653,6 +652,16 @@ test -e ../libradamsa.so && { INCOMPLETE=1 } +test -z "$AFL_CC" && { + if type gcc >/dev/null; then + export AFL_CC=gcc + else + if type clang >/dev/null; then + export AFL_CC=clang + fi + fi +} + $ECHO "$BLUE[*] Testing: qemu_mode" test -e ../afl-qemu-trace && { gcc -pie -fPIE -o test-instr ../test-instr.c From 30fa7b80065ff09afc68f1eb0563437dd64d0020 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Apr 2020 19:17:21 +0200 Subject: [PATCH 57/72] remove todo --- TODO.md | 1 - 1 file changed, 1 deletion(-) diff --git a/TODO.md b/TODO.md index 22fab6b1..c807d740 100644 --- a/TODO.md +++ b/TODO.md @@ -4,7 +4,6 @@ - complete custom_mutator API changes and documentation - fix stability calculation bug - - fix afl-cmin bug ## Roadmap 2.64 From b4869d0663a9bbcd6301af1822fd9af06335c23e Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Wed, 8 Apr 2020 21:23:18 +0200 Subject: [PATCH 58/72] unicorn_mode/samples/persistent Makefile portable version --- unicorn_mode/samples/persistent/GNUmakefile | 42 ------------------ unicorn_mode/samples/persistent/Makefile | 49 ++++++++++++++++++++- 2 files changed, 47 insertions(+), 44 deletions(-) delete mode 100644 unicorn_mode/samples/persistent/GNUmakefile diff --git a/unicorn_mode/samples/persistent/GNUmakefile b/unicorn_mode/samples/persistent/GNUmakefile deleted file mode 100644 index fe100490..00000000 --- a/unicorn_mode/samples/persistent/GNUmakefile +++ /dev/null @@ -1,42 +0,0 @@ -# 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 0b306dde..96aedacb 100644 --- a/unicorn_mode/samples/persistent/Makefile +++ b/unicorn_mode/samples/persistent/Makefile @@ -1,2 +1,47 @@ -all: - @echo please use GNU make, thanks! +# UnicornAFL Usage +# Original Unicorn Example Makefile by Nguyen Anh Quynh , 2015 +# Adapted for AFL++ by domenukk , 2020 +.POSIX: +UNAME_S =$(shell uname -s)# GNU make +UNAME_S:sh=uname -s # BSD make +_UNIQ=_QINU_ + +LIBDIR = ../../unicornafl +BIN_EXT = +AR_EXT = a + +# Verbose output? +V ?= 0 + +CFLAGS += -Wall -Werror -I../../unicornafl/include + +LDFLAGS += -L$(LIBDIR) -lpthread -lm + +_LRT = $(_UNIQ)$(UNAME_S:Linux=) +__LRT = $(_LRT:$(_UNIQ)=-lrt) +LRT = $(__LRT:$(_UNIQ)=) + +LDFLAGS += $(LRT) + +_CC = $(_UNIQ)$(CROSS) +__CC = $(_CC:$(_UNIQ)=$(CC)) +MYCC = $(__CC:$(_UNIQ)$(CROSS)=$(CROSS)gcc) + +.PHONY: all clean + +all: harness + +clean: + rm -rf *.o harness harness-debug + +harness.o: harness.c ../../unicornafl/include/unicorn/*.h + ${MYCC} ${CFLAGS} -O3 -c $< + +harness-debug.o: harness.c ../../unicornafl/include/unicorn/*.h + ${MYCC} ${CFLAGS} -g -c $< -o $@ + +harness: harness.o + ${MYCC} -L${LIBDIR} $< ../../unicornafl/libunicornafl.a $(LDFLAGS) -o $@ + +debug: harness-debug.o + ${MYCC} -L${LIBDIR} $< ../../unicornafl/libunicornafl.a $(LDFLAGS) -o harness-debug From cb52b1757d7efe811f344aade17259b8951c3ea2 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Wed, 8 Apr 2020 21:39:11 +0200 Subject: [PATCH 59/72] Makefile cleanup --- gcc_plugin/Makefile | 2 +- libdislocator/Makefile | 2 +- .../libradamsa/{Makefile => GNUmakefile} | 0 unicorn_mode/samples/c/GNUmakefile | 42 ---------------- unicorn_mode/samples/c/Makefile | 49 ++++++++++++++++++- unicorn_mode/samples/persistent/Makefile | 8 +-- 6 files changed, 53 insertions(+), 50 deletions(-) rename src/third_party/libradamsa/{Makefile => GNUmakefile} (100%) delete mode 100644 unicorn_mode/samples/c/GNUmakefile diff --git a/gcc_plugin/Makefile b/gcc_plugin/Makefile index 1c6f365f..3b507c6b 100644 --- a/gcc_plugin/Makefile +++ b/gcc_plugin/Makefile @@ -36,7 +36,7 @@ CFLAGS = -Wall -I../include -Wno-pointer-sign \ -Wno-unused-function CXXFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=2 -CXXEFLAGS := $(CXXFLAGS) -Wall +CXXEFLAGS = $(CXXFLAGS) -Wall CC ?= gcc CXX ?= g++ diff --git a/libdislocator/Makefile b/libdislocator/Makefile index 201f1e92..37fd4fd6 100644 --- a/libdislocator/Makefile +++ b/libdislocator/Makefile @@ -28,7 +28,7 @@ all: libdislocator.so VPATH = .. libdislocator.so: libdislocator.so.c ../config.h - $(CC) $(CFLAGS) -shared -fPIC $< -o ../$@ $(LDFLAGS) + $(CC) $(CFLAGS) -shared -fPIC libdislocator.so.c -o ../$@ $(LDFLAGS) .NOTPARALLEL: clean diff --git a/src/third_party/libradamsa/Makefile b/src/third_party/libradamsa/GNUmakefile similarity index 100% rename from src/third_party/libradamsa/Makefile rename to src/third_party/libradamsa/GNUmakefile diff --git a/unicorn_mode/samples/c/GNUmakefile b/unicorn_mode/samples/c/GNUmakefile deleted file mode 100644 index fe100490..00000000 --- a/unicorn_mode/samples/c/GNUmakefile +++ /dev/null @@ -1,42 +0,0 @@ -# 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 0b306dde..cb491e10 100644 --- a/unicorn_mode/samples/c/Makefile +++ b/unicorn_mode/samples/c/Makefile @@ -1,2 +1,47 @@ -all: - @echo please use GNU make, thanks! +# UnicornAFL Usage +# Original Unicorn Example Makefile by Nguyen Anh Quynh , 2015 +# Adapted for AFL++ by domenukk , 2020 +.POSIX: +UNAME_S =$(shell uname -s)# GNU make +UNAME_S:sh=uname -s # BSD make +_UNIQ=_QINU_ + +LIBDIR = ../../unicornafl +BIN_EXT = +AR_EXT = a + +# Verbose output? +V ?= 0 + +CFLAGS += -Wall -Werror -I../../unicornafl/include + +LDFLAGS += -L$(LIBDIR) -lpthread -lm + +_LRT = $(_UNIQ)$(UNAME_S:Linux=) +__LRT = $(_LRT:$(_UNIQ)=-lrt) +LRT = $(__LRT:$(_UNIQ)=) + +LDFLAGS += $(LRT) + +_CC = $(_UNIQ)$(CROSS) +__CC = $(_CC:$(_UNIQ)=$(CC)) +MYCC = $(__CC:$(_UNIQ)$(CROSS)=$(CROSS)gcc) + +.PHONY: all clean + +all: harness + +clean: + rm -rf *.o harness harness-debug + +harness.o: harness.c ../../unicornafl/include/unicorn/*.h + ${MYCC} ${CFLAGS} -O3 -c harness.c + +harness-debug.o: harness.c ../../unicornafl/include/unicorn/*.h + ${MYCC} ${CFLAGS} -g -c harness.c -o $@ + +harness: harness.o + ${MYCC} -L${LIBDIR} harness.o ../../unicornafl/libunicornafl.a $(LDFLAGS) -o $@ + +debug: harness-debug.o + ${MYCC} -L${LIBDIR} harness.o ../../unicornafl/libunicornafl.a $(LDFLAGS) -o harness-debug diff --git a/unicorn_mode/samples/persistent/Makefile b/unicorn_mode/samples/persistent/Makefile index 96aedacb..cb491e10 100644 --- a/unicorn_mode/samples/persistent/Makefile +++ b/unicorn_mode/samples/persistent/Makefile @@ -35,13 +35,13 @@ clean: rm -rf *.o harness harness-debug harness.o: harness.c ../../unicornafl/include/unicorn/*.h - ${MYCC} ${CFLAGS} -O3 -c $< + ${MYCC} ${CFLAGS} -O3 -c harness.c harness-debug.o: harness.c ../../unicornafl/include/unicorn/*.h - ${MYCC} ${CFLAGS} -g -c $< -o $@ + ${MYCC} ${CFLAGS} -g -c harness.c -o $@ harness: harness.o - ${MYCC} -L${LIBDIR} $< ../../unicornafl/libunicornafl.a $(LDFLAGS) -o $@ + ${MYCC} -L${LIBDIR} harness.o ../../unicornafl/libunicornafl.a $(LDFLAGS) -o $@ debug: harness-debug.o - ${MYCC} -L${LIBDIR} $< ../../unicornafl/libunicornafl.a $(LDFLAGS) -o harness-debug + ${MYCC} -L${LIBDIR} harness.o ../../unicornafl/libunicornafl.a $(LDFLAGS) -o harness-debug From 88a852ef0ff9d62049e2ca8bc0675493d868eaa7 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Wed, 8 Apr 2020 22:21:32 +0000 Subject: [PATCH 60/72] fix gcc_plugin Makefile (VPATH) --- gcc_plugin/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc_plugin/Makefile b/gcc_plugin/Makefile index 3b507c6b..3da2e4f6 100644 --- a/gcc_plugin/Makefile +++ b/gcc_plugin/Makefile @@ -127,7 +127,7 @@ all_done: test_build .NOTPARALLEL: clean -vpath % .. +VPATH = .. %.8: % @echo .TH $* 8 `date "+%Y-%m-%d"` "afl++" > ../$@ @echo .SH NAME >> ../$@ From 77949acaee4f6beec6b7ed095b99c0b2cdc772b4 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Apr 2020 23:15:42 +0200 Subject: [PATCH 61/72] fix review comments by Heiko --- llvm_mode/README.snapshot.md | 4 ++-- llvm_mode/afl-clang-fast.c | 31 +++++++++++++++++-------------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/llvm_mode/README.snapshot.md b/llvm_mode/README.snapshot.md index 6bf76b3d..cae86a4a 100644 --- a/llvm_mode/README.snapshot.md +++ b/llvm_mode/README.snapshot.md @@ -1,7 +1,7 @@ # AFL++ snapshot feature -Snapshot is a mechanic that makes a snapshot from a process and then restores -it's state, which is faster then forking it again. +Snapshotting is a feature that makes a snapshot from a process and then +restores it's state, which is faster then forking it again. All targets compiled with llvm_mode are automatically enabled for the snapshot feature. diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index 657d1a84..e2b44def 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -294,22 +294,25 @@ static void edit_params(u32 argc, char **argv, char **envp) { cc_params[cc_par_cnt++] = lto_flag; - } else - - if (instrument_mode == INSTRUMENT_PCGUARD) { - - cc_params[cc_par_cnt++] = - "-fsanitize-coverage=trace-pc-guard"; // edge coverage by default - } else { - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = "-load"; - cc_params[cc_par_cnt++] = "-Xclang"; - if (instrument_mode == INSTRUMENT_CFG) - cc_params[cc_par_cnt++] = alloc_printf("%s/libLLVMInsTrim.so", obj_path); - else - cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-pass.so", obj_path); + if (instrument_mode == INSTRUMENT_PCGUARD) { + + cc_params[cc_par_cnt++] = + "-fsanitize-coverage=trace-pc-guard"; // edge coverage by default + + } else { + + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = "-load"; + cc_params[cc_par_cnt++] = "-Xclang"; + if (instrument_mode == INSTRUMENT_CFG) + cc_params[cc_par_cnt++] = + alloc_printf("%s/libLLVMInsTrim.so", obj_path); + else + cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-pass.so", obj_path); + + } } From 54359be31a16ebfad62e4ce4f2ec26bb658d59e4 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Apr 2020 23:16:49 +0200 Subject: [PATCH 62/72] fix review comments by Heiko --- src/afl-fuzz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index a4c5cfb5..5010c3ea 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -165,7 +165,7 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) { "AFL_FORCE_UI: force showing the status screen (for virtual consoles)\n" "AFL_NO_CPU_RED: avoid red color for showing very high cpu usage\n" "AFL_SKIP_CPUFREQ: do not warn about variable cpu clocking\n" - "AFL_NO_SNAPSHOT: do not use the snapshot feature (if the snapshot lkm is loaded\n" + "AFL_NO_SNAPSHOT: do not use the snapshot feature (if the snapshot lkm is loaded)\n" "AFL_NO_FORKSRV: run target via execve instead of using the forkserver\n" "AFL_NO_ARITH: skip arithmetic mutations in deterministic stage\n" "AFL_SHUFFLE_QUEUE: reorder the input queue randomly on startup\n" From 361c2ac576a9fd4f996dd5f55b7a6f8a1a59eefe Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Wed, 8 Apr 2020 23:45:28 +0200 Subject: [PATCH 63/72] fix compile for MacOSX -DFORTIFY_SOURCE=2 is problematic --- GNUmakefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/GNUmakefile b/GNUmakefile index 0cbeaa81..a2a4bcaf 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -54,6 +54,7 @@ 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 + CFLAGS_OPT += -D_FORTIFY_SOURCE=2 endif ifneq "$(shell uname -m)" "x86_64" @@ -66,7 +67,7 @@ ifneq "$(shell uname -m)" "x86_64" endif endif -CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT) -D_FORTIFY_SOURCE=2 +CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT) override CFLAGS += -Wall -g -Wno-pointer-sign \ -I include/ -Werror -DAFL_PATH=\"$(HELPER_PATH)\" \ -DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\" From 9efa96fe0c5cab4d360517b7820ffa610b0d6461 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Thu, 9 Apr 2020 01:40:03 +0200 Subject: [PATCH 64/72] fixed critical whitespace --- unicorn_mode/build_unicorn_support.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/unicorn_mode/build_unicorn_support.sh b/unicorn_mode/build_unicorn_support.sh index 0d915238..df2a7f6d 100644 --- a/unicorn_mode/build_unicorn_support.sh +++ b/unicorn_mode/build_unicorn_support.sh @@ -1,10 +1,10 @@ -#! /bin/sh +#!/bin/sh # # american fuzzy lop++ - unicorn mode build script # ------------------------------------------------ # # Originally written by Nathan Voss -# +# # Adapted from code by Andrew Griffiths and # Michal Zalewski # @@ -24,7 +24,7 @@ # # This script downloads, patches, and builds a version of Unicorn with # minor tweaks to allow Unicorn-emulated binaries to be run under -# afl-fuzz. +# afl-fuzz. # # The modifications reside in patches/*. The standalone Unicorn library # will be written to /usr/lib/libunicornafl.so, and the Python bindings @@ -46,7 +46,7 @@ if [ ! "$PLT" = "Linux" ] && [ ! "$PLT" = "Darwin" ] && [ ! "$PLT" = "FreeBSD" ] echo "[-] Error: Unicorn instrumentation is unsupported on $PLT." exit 1 - + fi if [ ! -f "../config.h" ]; then @@ -199,7 +199,7 @@ echo 0 | ../../../afl-showmap -U -m none -t 2000 -q -o .test-instr0 -- $PYTHONBI if [ -s .test-instr0 ] then - + echo "[+] Instrumentation tests passed. " echo '[+] Make sure to adapt older scripts to `import unicornafl` and use `uc.afl_forkserver_start`' echo ' or `uc.afl_fuzz` to kick off fuzzing.' From 650bd1c17956d4f426a8cc65792e9c2f38d8a7dc Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Thu, 9 Apr 2020 08:58:35 +0200 Subject: [PATCH 65/72] Update README.snapshot.md --- llvm_mode/README.snapshot.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/llvm_mode/README.snapshot.md b/llvm_mode/README.snapshot.md index cae86a4a..9c12a8ba 100644 --- a/llvm_mode/README.snapshot.md +++ b/llvm_mode/README.snapshot.md @@ -10,3 +10,7 @@ To use the snapshot feature for fuzzing compile and load this kernel module: [https://github.com/AFLplusplus/AFL-Snapshot-LKM](https://github.com/AFLplusplus/AFL-Snapshot-LKM) Note that is has little value for persistent (__AFL_LOOP) fuzzing. + +## Notes + +Snapshot does not work with multithreaded targets yet. Still in WIP, it is now usable only for single threaded applications. From 3c546341e38ccac7e53f6d2e5840140eb4a11827 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 9 Apr 2020 09:08:04 +0200 Subject: [PATCH 66/72] fix indention --- GNUmakefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/GNUmakefile b/GNUmakefile index a2a4bcaf..ecc475b3 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -54,7 +54,8 @@ 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 - CFLAGS_OPT += -D_FORTIFY_SOURCE=2 + # OS X does not like _FORTIFY_SOURCE=2 + CFLAGS_OPT += -D_FORTIFY_SOURCE=2 endif ifneq "$(shell uname -m)" "x86_64" From f06acc4e27f7a5859046bae5276ff80d530e11af Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 9 Apr 2020 09:14:12 +0200 Subject: [PATCH 67/72] push new version --- README.md | 4 ++-- docs/Changelog.md | 2 +- include/config.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8d167f7e..8f817841 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ ![Travis State](https://api.travis-ci.com/AFLplusplus/AFLplusplus.svg?branch=master) - Release Version: [2.62c](https://github.com/AFLplusplus/AFLplusplus/releases) + Release Version: [2.63c](https://github.com/AFLplusplus/AFLplusplus/releases) - Github Version: 2.62d + Github Version: 2.63d includes all necessary/interesting changes from Google's afl 2.56b diff --git a/docs/Changelog.md b/docs/Changelog.md index 424b61dc..70753fcc 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -9,7 +9,7 @@ Want to stay in the loop on major new features? Join our mailing list by sending a mail to . -### Version ++2.62d (develop): +### Version ++2.63c (release): ! the repository was moved from vanhauser-thc to AFLplusplus. It is now an own organisation :) diff --git a/include/config.h b/include/config.h index a87c5e84..6b50be60 100644 --- a/include/config.h +++ b/include/config.h @@ -28,7 +28,7 @@ /* Version string: */ // c = release, d = volatile github dev, e = experimental branch -#define VERSION "++2.62d" +#define VERSION "++2.63c" /****************************************************** * * From b55421d4a119fd26a253fe114fb39ec685de4c57 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 9 Apr 2020 10:30:24 +0200 Subject: [PATCH 68/72] 2.63d init --- docs/Changelog.md | 4 ++++ include/config.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index 70753fcc..dd135b7e 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -9,6 +9,10 @@ Want to stay in the loop on major new features? Join our mailing list by sending a mail to . +### Version ++2.63d (development): + - ... + + ### Version ++2.63c (release): ! the repository was moved from vanhauser-thc to AFLplusplus. It is now diff --git a/include/config.h b/include/config.h index 6b50be60..cf73772f 100644 --- a/include/config.h +++ b/include/config.h @@ -28,7 +28,7 @@ /* Version string: */ // c = release, d = volatile github dev, e = experimental branch -#define VERSION "++2.63c" +#define VERSION "++2.63d" /****************************************************** * * From 45e569845e2f4e3023cb46d93c0638034e6df424 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 9 Apr 2020 10:36:28 +0200 Subject: [PATCH 69/72] LTO llvm11 (#302) * new LTO mode for llvm 11 * remove unneeded afl-ld and env vars --- docs/Changelog.md | 2 +- llvm_mode/GNUmakefile | 34 +- llvm_mode/README.lto.md | 163 +--- llvm_mode/afl-clang-fast.c | 21 +- llvm_mode/afl-ld.c | 839 ------------------- llvm_mode/afl-llvm-lto-instrumentation.so.cc | 5 +- 6 files changed, 60 insertions(+), 1004 deletions(-) delete mode 100644 llvm_mode/afl-ld.c diff --git a/docs/Changelog.md b/docs/Changelog.md index dd135b7e..18f38551 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -45,7 +45,7 @@ sending a mail to . easier: DEFAULT, CFG (INSTRIM), LTO, CTX, NGRAM-x (x=2-16) - made USE_TRACE_PC compile obsolete - LTO collision free instrumented added in llvm_mode with afl-clang-lto - - note that this mode is amazing, but quite some targets won't compile + this mode is amazing but requires you to build llvm 11 yourself - Added llvm_mode NGRAM prev_loc coverage by Adrean Herrera (https://github.com/adrianherrera/afl-ngram-pass/), activate by setting AFL_LLVM_INSTRUMENT=NGRAM- or AFL_LLVM_NGRAM_SIZE= diff --git a/llvm_mode/GNUmakefile b/llvm_mode/GNUmakefile index e3708efa..ce60dd1c 100644 --- a/llvm_mode/GNUmakefile +++ b/llvm_mode/GNUmakefile @@ -58,19 +58,20 @@ 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 +endif + +ifeq "$(LLVM_MAJOR)" "11" + $(info [+] llvm_mode detected llvm 11, enabling afl-clang-lto LTO implementation) LLVM_LTO = 1 endif ifeq "$(LLVM_LTO)" "0" - $(info [+] llvm_mode detected llvm < 9, afl-clang-lto LTO will not be build.) + $(info [+] llvm_mode detected llvm < 11, afl-clang-lto LTO will not be build.) endif ifeq "$(LLVM_APPLE)" "1" @@ -125,14 +126,18 @@ else 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) +ifeq "$(LLVM_LTO)" "1" + ifneq "$(AFL_CLANG_FLTO)" "" + ifeq "$(AFL_REAL_LD)" "" + ifneq "$(shell readlink $(LLVM_BINDIR)/ld.lld 2>&1)" "" + AFL_REAL_LD = $(LLVM_BINDIR)/ld.lld + else + $(warn ld.lld not found, can not enable LTO mode) + LLVM_LTO = 0 + endif + endif endif endif -endif AFL_CLANG_FUSELD= ifneq "$(AFL_CLANG_FLTO)" "" @@ -257,10 +262,11 @@ 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" + @-export AFL_QUIET=1 AFL_PATH=.. PATH="..:$(PATH)" ; ../afl-clang-lto -o .test-instr ../test-instr.c && echo "[+] afl-clang-lto seems 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) @@ -275,9 +281,9 @@ 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 +../afl-llvm-lto-instrumentation.so: afl-llvm-lto-instrumentation.so.cc ifeq "$(LLVM_LTO)" "1" - $(CXX) $(CLANG_CFL) -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) + $(CXX) $(CLANG_CFL) -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) endif # laf @@ -323,7 +329,7 @@ all_done: test_build install: all install -d -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH) 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 ]; 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-llvm-lto-instrumentation.so $${DESTDIR}$(HELPER_PATH); install -m 755 ../afl-llvm-lto-whitelist.so $${DESTDIR}$(HELPER_PATH); fi 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 diff --git a/llvm_mode/README.lto.md b/llvm_mode/README.lto.md index 28b3b045..a3c7ddc3 100644 --- a/llvm_mode/README.lto.md +++ b/llvm_mode/README.lto.md @@ -2,16 +2,15 @@ ## TLDR; -1. This compile mode is very frickle if it works it is amazing, if it fails - - well use afl-clang-fast +This version requires a current llvm 11 compiled from the github master. -2. Use afl-clang-lto/afl-clang-lto++ because it is faster and gives better +1. Use afl-clang-lto/afl-clang-lto++ because it is faster and gives better coverage than anything else that is out there in the AFL world -3. You can use it together with llvm_mode: laf-intel and whitelisting +2. You can use it together with llvm_mode: laf-intel and whitelisting features and can be combined with cmplog/Redqueen -4. It only works with llvm 9 (and likely 10+ but is not tested there yet) +3. It only works with llvm 11 (current github master state) ## Introduction and problem description @@ -63,6 +62,26 @@ afl-llvm-lto++2.62d by Marc "vanHauser" Heuse [+] Linker was successful ``` +## Building llvm 11 + +``` +$ sudo apt install binutils-dev +$ git clone https://github.com/llvm/llvm-project +$ cd llvm-project +$ mkdir build +$ cd build +$ cmake -DLLVM_ENABLE_PROJECTS='clang;clang-tools-extra;compiler-rt;libclc;libcxx;libcxxabi;libunwind;lld' -DLLVM_BINUTILS_INCDIR=/usr/include/ ../llvm/ +$ make +$ export PATH=`pwd`/bin:$PATH +$ export LLVM_CONFIG=`pwd`/bin/llcm-config +$ cd /path/to/AFLplusplus/ +$ make +$ cd llvm_mode +$ make +$ cd .. +$ make install +``` + ## How to use afl-clang-lto Just use afl-clang-lto like you did afl-clang-fast or afl-gcc. @@ -94,129 +113,12 @@ AR=llvm-ar RANLIB=llvm-ranlib CC=afl-clang-lto CXX=afl-clang-lto++ ./configure - ``` and on some target you have to to AR=/RANLIB= even for make as the configure script does not save it ... -### "linking globals named '...': symbol multiply defined" error - -The target program is using multiple global variables or functions with the -same name. This is a common error when compiling a project with LTO, and -the fix is `-Wl,--allow-multiple-definition` - however llvm-link which we -need to link all llvm IR LTO files does not support this - yet (hopefully). -Hence if you see this error either you have to remove the duplicate global -variable (think `#ifdef` ...) or you are out of luck. :-( - -### "expected top-level entity" + binary ouput error - -This happens if multiple .a archives are to be linked and they contain the -same object filenames, the first in LTO form, the other in ELF form. -This can not be fixed programmatically, but can be fixed by hand. -You can try to delete the file from either archive -(`llvm-ar d .a .o`) or performing the llvm-linking, optimizing -and instrumentation by hand (see below). - -### "undefined reference to ..." - -This *can* be the opposite situation of the "expected top-level entity" error - -the library with the ELF file is before the LTO library. -However it can also be a bug in the program - try to compile it normally. If -fails then it is a bug in the program. -Solutions: You can try to delete the file from either archive, e.g. -(`llvm-ar d .a .o`) or performing the llvm-linking, optimizing -and instrumentation by hand (see below). - -### "File format not recognized" - -This happens if the build system has fixed LDFLAGS, CPPFLAGS, CXXFLAGS and/or -CFLAGS. Ensure that they all contain the `-flto` flag that afl-clang-lto was -compiled with (you can see that by typing `afl-clang-lto -h` and inspecting -the last line of the help output) and add them otherwise - -### clang is hardcoded to /bin/ld - -Some clang packages have 'ld' hardcoded to /bin/ld. This is an issue as this -prevents "our" afl-ld being called. - --fuse-ld=/path/to/afl-ld should be set through makefile magic in llvm_mode - -if it is supported - however if this fails you can try: -``` -LDFLAGS=-fuse-ld=&1 | grep afl-clang-lto | tail -n 1` - -2. run this command prepended with AFL_DEBUG=1 and collect the afl-ld command - parameters, e.g. `AFL_DEBUG=1 afl-clang-lto[++] .... | grep /afl/ld` - -3. for every .a archive you want to instrument unpack it into a seperate - directory, e.g. - `mkdir archive1.dir ; cd archive1.dir ; llvm-link x ../.a` - -4. run `file archive*.dir/*.o` and make two lists, one containing all ELF files - and one containing all LLVM IR bitcode files. - You do the same for all .o files of the ../afl/ld command options - -5. Create a single bitcode file by using llvm-link, e.g. - `llvm-link -o all-bitcode.bc ` - If this fails it is game over - or you modify the source code - -6. Run the optimizer on the new bitcode file: - `opt -O3 --polly -o all-optimized.bc all-bitcode.bc` - -7. Instrument the optimized bitcode file: - `opt --load=$AFL_PATH/afl-llvm-lto-instrumentation.so --disable-opt --afl-lto all-optimized.bc -o all-instrumented.bc - -8. If the parameter `--allow-multiple-definition` is not in the list, add it - as first command line option. - -9. Link everything together. - a) You use the afl-ld command and instead of e.g. `/usr/local/lib/afl/ld` - you replace that with `ld`, the real linker. - b) Every .a archive you instrumented files from you remove the .a - or -l from the command - c) If you have entries in your ELF files list (see step 4), you put them to - the command line - but them in the same order! - d) put the all-instrumented.bc before the first library or .o file - e) run the command and hope it compiles, if it doesn't you have to analyze - what the issue is and fix that in the approriate step above. - -Yes this is long and complicated. That is why there is afl-ld doing this and -that why this can easily fail and not all different ways how it *can* fail can -be implemented ... - ### compiling programs still fail afl-clang-lto is still work in progress. -Complex targets are still likely not to compile and this needs to be fixed. Please report issues at: [https://github.com/AFLplusplus/AFLplusplus/issues/226](https://github.com/AFLplusplus/AFLplusplus/issues/226) -Known issues: -* ffmpeg -* bogofilter -* libjpeg-turbo-1.3.1 - ## Upcoming Work 1. Currently the LTO whitelist feature does not allow to not instrument main, start and init functions @@ -225,15 +127,6 @@ Known issues: Result: faster fork in the target and faster map analysis in afl-fuzz => more speed :-) -## Tested and working targets - -* libpng-1.2.53 -* libxml2-2.9.2 -* tiff-4.0.4 -* unrar-nonfree-5.6.6 -* exiv 0.27 -* jpeg-6b - ## History This was originally envisioned by hexcoder- in Summer 2019, however we saw no @@ -252,11 +145,17 @@ very difficult with a program that has so many paths and therefore so many dependencies. At lot of stratgies were implemented - and failed. And then sat solvers were tried, but with over 10.000 variables that turned out to be a dead-end too. + The final idea to solve this came from domenukk who proposed to insert a block into an edge and then just use incremental counters ... and this worked! After some trials and errors to implement this vanhauser-thc found out that there is actually an llvm function for this: SplitEdge() :-) + Still more problems came up though as this only works without bugs from llvm 9 onwards, and with high optimization the link optimization ruins the instrumented control flow graph. -As long as there are no larger changes in llvm this all should work well now ... + +This is all now fixed with llvm 11. The llvm's own linker is now able to +load passes and this bypasses all problems we had. + +Happy end :) diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index e2b44def..9d8ebdec 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -269,12 +269,6 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (instrument_mode == INSTRUMENT_LTO) { - char *old_path = getenv("PATH"); - char *new_path = alloc_printf("%s:%s", AFL_PATH, old_path); - - setenv("PATH", new_path, 1); - setenv("AFL_LD", "1", 1); - if (getenv("AFL_LLVM_WHITELIST") != NULL) { cc_params[cc_par_cnt++] = "-Xclang"; @@ -285,13 +279,10 @@ static void edit_params(u32 argc, char **argv, char **envp) { } -#ifdef AFL_CLANG_FUSELD - cc_params[cc_par_cnt++] = alloc_printf("-fuse-ld=%s/afl-ld", AFL_PATH); -#endif - - cc_params[cc_par_cnt++] = "-B"; - cc_params[cc_par_cnt++] = AFL_PATH; - + cc_params[cc_par_cnt++] = alloc_printf("-fuse-ld=%s", AFL_REAL_LD); + cc_params[cc_par_cnt++] = "-Wl,--allow-multiple-definition"; + cc_params[cc_par_cnt++] = alloc_printf( + "-Wl,-mllvm=-load=%s/afl-llvm-lto-instrumentation.so", obj_path); cc_params[cc_par_cnt++] = lto_flag; } else { @@ -738,9 +729,7 @@ int main(int argc, char **argv, char **envp) { "bb\n" "AFL_LLVM_LTO_DONTWRITEID: don't write the highest ID used to a " "global var\n" - "AFL_REAL_LD: use this linker instead of the compiled in path\n" - "AFL_LD_PASSTHROUGH: do not perform instrumentation (for configure " - "scripts)\n" + "AFL_REAL_LD: use this lld linker instead of the compiled in path\n" "\nafl-clang-lto was built with linker target \"%s\" and LTO flags " "\"%s\"\n" "If anything fails - be sure to read README.lto.md!\n", diff --git a/llvm_mode/afl-ld.c b/llvm_mode/afl-ld.c deleted file mode 100644 index eb46c85c..00000000 --- a/llvm_mode/afl-ld.c +++ /dev/null @@ -1,839 +0,0 @@ -/* - american fuzzy lop++ - wrapper for GNU ld - ----------------------------------------- - - Written by Marc Heuse for afl++ - - Maintained by Marc Heuse , - Heiko Eißfeldt - Andrea Fioraldi - Dominik Maier - - 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 - - The sole purpose of this wrapper is to preprocess clang LTO files before - linking by ld and perform the instrumentation on the whole program. - -*/ - -#define AFL_MAIN - -#include "config.h" -#include "types.h" -#include "debug.h" -#include "alloc-inl.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#define MAX_PARAM_COUNT 4096 - -static u8 **ld_params, /* Parameters passed to the real 'ld' */ - **link_params, /* Parameters passed to 'llvm-link' */ - **opt_params, /* Parameters passed to 'opt' opt */ - **inst_params; /* Parameters passed to 'opt' inst */ - -static u8 *input_file; /* Originally specified input file */ -static u8 *final_file, /* Instrumented file for the real 'ld' */ - *linked_file, /* file where we link all files */ - *modified_file; /* file that was optimized before instr */ -static u8 *afl_path = AFL_PATH; -static u8 *real_ld = AFL_REAL_LD; -static u8 cwd[4096]; -static u8 *tmp_dir; -static u8 *ar_dir; -static u8 ar_dir_cnt; -static u8 *libdirs[254]; -static u8 libdir_cnt; - -static u8 be_quiet, /* Quiet mode (no stderr output) */ - debug, /* AFL_DEBUG */ - passthrough, /* AFL_LD_PASSTHROUGH - no link+optimize*/ - we_link, /* we have bc/ll -> link + optimize */ - just_version; /* Just show version? */ - -static u32 ld_param_cnt = 1, /* Number of params to 'ld' */ - link_param_cnt = 1, /* Number of params to 'llvm-link' */ - opt_param_cnt = 1, /* Number of params to 'opt' opt */ - inst_param_cnt = 1; /* Number of params to 'opt' instr */ - -/* This function wipes a directory - our AR unpack directory in this case */ -static u8 wipe_directory(u8 *path) { - - DIR * d; - struct dirent *d_ent; - - d = opendir(path); - - if (!d) return 0; - - while ((d_ent = readdir(d))) { - - if (strcmp(d_ent->d_name, ".") != 0 && strcmp(d_ent->d_name, "..") != 0) { - - u8 *fname = alloc_printf("%s/%s", path, d_ent->d_name); - if (unlink(fname)) PFATAL("Unable to delete '%s'", fname); - ck_free(fname); - - } - - } - - closedir(d); - - return !!rmdir(path); - -} - -/* remove temporary files on fatal errors */ -static void at_exit_handler(void) { - - if (!getenv("AFL_KEEP_ASSEMBLY")) { - - if (linked_file) { - - unlink(linked_file); - linked_file = NULL; - - } - - if (modified_file) { - - unlink(modified_file); - modified_file = NULL; - - } - - if (final_file) { - - unlink(final_file); - final_file = NULL; - - } - - if (ar_dir != NULL) { - - wipe_directory(ar_dir); - ar_dir = NULL; - - } - - } - -} - -/* This function checks if the parameter is a) an existing file and b) - if it is a BC or LL file, if both are true it returns 1 and 0 otherwise */ -int is_llvm_file(const char *file) { - - int fd; - u8 buf[5]; - - if ((fd = open(file, O_RDONLY)) < 0) { - - if (debug) SAYF(cMGN "[D] " cRST "File %s not found", file); - return 0; - - } - - if (read(fd, buf, 4) != 4) return 0; - buf[sizeof(buf) - 1] = 0; - - close(fd); - - if (strncmp(buf, "; Mo", 4) == 0) return 1; - - if (buf[0] == 'B' && buf[1] == 'C' && buf[2] == 0xc0 && buf[3] == 0xde) - return 1; - - return 0; - -} - -/* Return the current working directory, not thread safe ;-) */ -u8 *getthecwd() { - - static u8 fail[] = ""; - if (getcwd(cwd, sizeof(cwd)) == NULL) return fail; - return cwd; - -} - -/* Check if an ar extracted file is already in the parameter list */ -int is_duplicate(u8 **params, u32 ld_param_cnt, u8 *ar_file) { - - for (uint32_t i = 0; i < ld_param_cnt; i++) - if (params[i] != NULL) - if (strcmp(params[i], ar_file) == 0) return 1; - - return 0; - -} - -/* Examine and modify parameters to pass to 'ld', 'llvm-link' and 'llmv-ar'. - Note that the file name is always the last parameter passed by GCC, - so we exploit this property to keep the code "simple". */ -static void edit_params(int argc, char **argv) { - - u32 i, have_lto = 0, libdir_index; - u8 libdir_file[4096]; - - if (tmp_dir == NULL) { - - tmp_dir = getenv("TMPDIR"); - if (!tmp_dir) tmp_dir = getenv("TEMP"); - if (!tmp_dir) tmp_dir = getenv("TMP"); - if (!tmp_dir) tmp_dir = "/tmp"; - - } - - linked_file = - alloc_printf("%s/.afl-%u-%u-1.ll", tmp_dir, getpid(), (u32)time(NULL)); - modified_file = - alloc_printf("%s/.afl-%u-%u-2.bc", tmp_dir, getpid(), (u32)time(NULL)); - final_file = - alloc_printf("%s/.afl-%u-%u-3.bc", tmp_dir, getpid(), (u32)time(NULL)); - - ld_params = ck_alloc(4096 * sizeof(u8 *)); - link_params = ck_alloc(4096 * sizeof(u8 *)); - inst_params = ck_alloc(12 * sizeof(u8 *)); - opt_params = ck_alloc(12 * sizeof(u8 *)); - - ld_params[0] = (u8 *)real_ld; - ld_params[ld_param_cnt++] = "--allow-multiple-definition"; - - link_params[0] = alloc_printf("%s/%s", LLVM_BINDIR, "llvm-link"); - link_params[link_param_cnt++] = "-S"; // we create the linked file as .ll - link_params[link_param_cnt++] = "-o"; - link_params[link_param_cnt++] = linked_file; - - opt_params[0] = alloc_printf("%s/%s", LLVM_BINDIR, "opt"); - if (getenv("AFL_DONT_OPTIMIZE") == NULL) - opt_params[opt_param_cnt++] = "-O3"; - else - opt_params[opt_param_cnt++] = "-O0"; - - // opt_params[opt_param_cnt++] = "-S"; // only when debugging - opt_params[opt_param_cnt++] = linked_file; // input: .ll file - opt_params[opt_param_cnt++] = "-o"; - opt_params[opt_param_cnt++] = modified_file; // output: .bc file - - inst_params[0] = alloc_printf("%s/%s", LLVM_BINDIR, "opt"); - inst_params[inst_param_cnt++] = - alloc_printf("--load=%s/afl-llvm-lto-instrumentation.so", afl_path); - // inst_params[inst_param_cnt++] = "-S"; // only when debugging - inst_params[inst_param_cnt++] = "--disable-opt"; - inst_params[inst_param_cnt++] = "--afl-lto"; - inst_params[inst_param_cnt++] = modified_file; // input: .bc file - inst_params[inst_param_cnt++] = "-o"; - inst_params[inst_param_cnt++] = final_file; // output: .bc file - - // first we must collect all library search paths - for (i = 1; i < argc; i++) - if (strlen(argv[i]) > 2 && argv[i][0] == '-' && argv[i][1] == 'L') - libdirs[libdir_cnt++] = argv[i] + 2; - - // then we inspect all options to the target linker - for (i = 1; i < argc; i++) { - - if (ld_param_cnt >= MAX_PARAM_COUNT || link_param_cnt >= MAX_PARAM_COUNT) - FATAL( - "Too many command line parameters because of unpacking .a archives, " - "this would need to be done by hand ... sorry! :-("); - - if (strncmp(argv[i], "-flto", 5) == 0) have_lto = 1; - - if (!strcmp(argv[i], "-version")) { - - just_version = 1; - ld_params[1] = argv[i]; - ld_params[2] = NULL; - final_file = input_file; - return; - - } - - if (strcmp(argv[i], "--afl") == 0) { - - if (!be_quiet) OKF("afl++ test command line flag detected, exiting."); - exit(0); - - } - - // if a -l library is linked and no .so is found but an .a archive is there - // then the archive will be used. So we have to emulate this and check - // if an archive will be used and if yes we will instrument it too - libdir_file[0] = 0; - libdir_index = libdir_cnt; - if (strncmp(argv[i], "-l", 2) == 0 && libdir_cnt > 0 && - strncmp(argv[i], "-lgcc", 5) != 0) { - - u8 found = 0; - - for (uint32_t j = 0; j < libdir_cnt && !found; j++) { - - snprintf(libdir_file, sizeof(libdir_file), "%s/lib%s%s", libdirs[j], - argv[i] + 2, ".so"); - if (access(libdir_file, R_OK) != 0) { // no .so found? - - snprintf(libdir_file, sizeof(libdir_file), "%s/lib%s%s", libdirs[j], - argv[i] + 2, ".a"); - if (access(libdir_file, R_OK) == 0) { // but .a found? - - libdir_index = j; - found = 1; - if (debug) SAYF(cMGN "[D] " cRST "Found %s\n", libdir_file); - - } - - } else { - - found = 1; - if (debug) SAYF(cMGN "[D] " cRST "Found %s\n", libdir_file); - - } - - } - - } - - // is the parameter an .a AR archive? If so, unpack and check its files - if (libdir_index < libdir_cnt || - (argv[i][0] != '-' && strlen(argv[i]) > 2 && - argv[i][strlen(argv[i]) - 1] == 'a' && - argv[i][strlen(argv[i]) - 2] == '.')) { - - // This gets a bit odd. I encountered several .a files being linked and - // where the same "foo.o" was in both .a archives. llvm-link does not - // like this so we have to work around that ... - - u8 this_wd[4096], *this_ar; - u8 ar_params_cnt = 4; - u8 * ar_params[ar_params_cnt]; - u8 * file = argv[i]; - s32 pid, status; - DIR * arx; - struct dirent *dir_ent; - - if (libdir_index < libdir_cnt) file = libdir_file; - - if (ar_dir_cnt == 0) { // first archive, we setup up the basics - - ar_dir = alloc_printf("%s/.afl-%u-%u.dir", tmp_dir, getpid(), - (u32)time(NULL)); - if (mkdir(ar_dir, 0700) != 0) - FATAL("can not create temporary directory %s", ar_dir); - - } - - if (getcwd(this_wd, sizeof(this_wd)) == NULL) - FATAL("can not get the current working directory"); - if (chdir(ar_dir) != 0) - FATAL("can not chdir to temporary directory %s", ar_dir); - if (file[0] == '/') - this_ar = file; - else - this_ar = alloc_printf("%s/%s", this_wd, file); - ar_params[0] = alloc_printf("%s/%s", LLVM_BINDIR, "llvm-ar"); - ar_params[1] = "x"; - ar_params[2] = this_ar; - ar_params[3] = NULL; - - if (!be_quiet) OKF("Running ar unpacker on %s into %s", this_ar, ar_dir); - - if (debug) { - - SAYF(cMGN "[D]" cRST " cd \"%s\";", getthecwd()); - for (uint32_t j = 0; j < ar_params_cnt; j++) - SAYF(" \"%s\"", ar_params[j]); - SAYF("\n"); - - } - - if (!(pid = fork())) { - - execvp(ar_params[0], (char **)ar_params); - FATAL("Oops, failed to execute '%s'", ar_params[0]); - - } - - if (pid < 0) FATAL("fork() failed"); - if (waitpid(pid, &status, 0) <= 0) FATAL("waitpid() failed"); - if (WEXITSTATUS(status) != 0) exit(WEXITSTATUS(status)); - - if (chdir(this_wd) != 0) - FATAL("can not chdir back to our working directory %s", this_wd); - - if (!(arx = opendir(ar_dir))) FATAL("can not open directory %s", ar_dir); - - while ((dir_ent = readdir(arx)) != NULL) { - - u8 *ar_file = alloc_printf("%s/%s", ar_dir, dir_ent->d_name); - - if (dir_ent->d_name[strlen(dir_ent->d_name) - 1] == 'o' && - dir_ent->d_name[strlen(dir_ent->d_name) - 2] == '.') { - - if (passthrough || is_llvm_file(ar_file) == 0) { - - if (is_duplicate(ld_params, ld_param_cnt, ar_file) == 0) { - - ld_params[ld_param_cnt++] = ar_file; - if (debug) - SAYF(cMGN "[D] " cRST "not a LTO link file: %s\n", ar_file); - - } - - } else { - - if (is_duplicate(link_params, link_param_cnt, ar_file) == 0) { - - if (we_link == 0) { // we have to honor order ... - - ld_params[ld_param_cnt++] = final_file; - we_link = 1; - - } - - link_params[link_param_cnt++] = ar_file; - if (debug) SAYF(cMGN "[D] " cRST "is a link file: %s\n", ar_file); - - } - - } - - } else - - if (dir_ent->d_name[0] != '.' && !be_quiet) - WARNF("Unusual file found in ar archive %s: %s", argv[i], ar_file); - - } - - closedir(arx); - ar_dir_cnt++; - - continue; - - } - - if (passthrough || argv[i][0] == '-' || is_llvm_file(argv[i]) == 0) { - - // -O3 fucks up the CFG and instrumentation, so we downgrade to O2 - // which is as we want things. Lets hope this is not too different - // in the various llvm versions! - if (strncmp(argv[i], "-plugin-opt=O", 13) == 0 && - !getenv("AFL_DONT_OPTIMIZE")) - ld_params[ld_param_cnt++] = "-plugin-opt=O2"; - else - ld_params[ld_param_cnt++] = argv[i]; - - } else { - - if (we_link == 0) { // we have to honor order ... - ld_params[ld_param_cnt++] = final_file; - we_link = 1; - - } - - link_params[link_param_cnt++] = argv[i]; - - } - - } - - // if (have_lto == 0) ld_params[ld_param_cnt++] = AFL_CLANG_FLTO; // maybe we - // should not ... - ld_params[ld_param_cnt] = NULL; - link_params[link_param_cnt] = NULL; - opt_params[opt_param_cnt] = NULL; - inst_params[inst_param_cnt] = NULL; - -} - -/* clean AFL_PATH from PATH */ - -void clean_path() { - - char *tmp, *newpath = NULL, *path = getenv("PATH"); - u8 done = 0; - - if (debug) - SAYF(cMGN "[D]" cRST " old PATH=%s, AFL_PATH=%s\n", path, AFL_PATH); - - // wipe AFL paths from PATH that we set - // we added two paths so we remove the two paths - while (!done) { - - if (*path == 0) - done = 1; - else if (*path++ == ':') - done = 1; - - } - - while (*path == ':') - path++; - - // AFL_PATH could be additionally in PATH so check and remove to not call our - // 'ld' - const size_t pathlen = strlen(path); - const size_t afl_pathlen = strlen(AFL_PATH); - newpath = malloc(pathlen + 1); - if (strcmp(AFL_PATH, "/bin") != 0 && strcmp(AFL_PATH, "/usr/bin") != 0 && - afl_pathlen > 1 && (tmp = strstr(path, AFL_PATH)) != NULL && // it exists - (tmp == path || - (tmp > path && - tmp[-1] == ':')) && // either starts with it or has a colon before - (tmp + afl_pathlen == path + pathlen || - (tmp + afl_pathlen < - path + (pathlen && tmp[afl_pathlen] == - ':')) // end with it or has a colon at the end - )) { - - int one_colon = 1; - - if (tmp > path) { - - memcpy(newpath, path, tmp - path); - newpath[tmp - path - 1] = 0; // remove ':' - one_colon = 0; - - } - - if (tmp + afl_pathlen < path + pathlen) tmp += afl_pathlen + one_colon; - - setenv("PATH", newpath, 1); - - } else - - setenv("PATH", path, 1); - - if (debug) SAYF(cMGN "[D]" cRST " new PATH=%s\n", getenv("PATH")); - free(newpath); - -} - -/* Main entry point */ - -int main(int argc, char **argv) { - - s32 pid, i; - int status; - u8 *ptr, exe[4096], exe2[4096], proc[32], val[2] = " "; - int have_afl_ld_caller = 0; - - if (isatty(2) && !getenv("AFL_QUIET") && !getenv("AFL_DEBUG")) { - - if (getenv("AFL_LD") != NULL) - SAYF(cCYA "afl-ld" VERSION cRST - " by Marc \"vanHauser\" Heuse (level %d)\n", - have_afl_ld_caller); - - } else - - be_quiet = 1; - - if (getenv("AFL_DEBUG") != NULL) debug = 1; - if (getenv("AFL_PATH") != NULL) afl_path = getenv("AFL_PATH"); - if (getenv("AFL_LD_PASSTHROUGH") != NULL) passthrough = 1; - if (getenv("AFL_REAL_LD") != NULL) real_ld = getenv("AFL_REAL_LD"); - if (real_ld == NULL || strlen(real_ld) < 2) real_ld = "/bin/ld"; - if (real_ld != NULL && real_ld[0] != '/') - real_ld = alloc_printf("/bin/%s", real_ld); - - if ((ptr = getenv("AFL_LD_CALLER")) != NULL) have_afl_ld_caller = atoi(ptr); - val[0] = 0x31 + have_afl_ld_caller; - setenv("AFL_LD_CALLER", val, 1); - - if (debug) { - - SAYF(cMGN "[D] " cRST - "AFL_LD=%s, set AFL_LD_CALLER=%s, have_afl_ld_caller=%d, " - "real_ld=%s\n", - getenv("AFL_LD"), val, have_afl_ld_caller, real_ld); - SAYF(cMGN "[D]" cRST " cd \"%s\";", getthecwd()); - for (i = 0; i < argc; i++) - SAYF(" \"%s\"", argv[i]); - SAYF("\n"); - - } - - sprintf(proc, "/proc/%d/exe", getpid()); - if (readlink(proc, exe, sizeof(exe) - 1) > 0) { - - if (readlink(real_ld, exe2, sizeof(exe2) - 1) < 1) exe2[0] = 0; - exe[sizeof(exe) - 1] = 0; - exe[sizeof(exe2) - 1] = 0; - if (strcmp(exe, real_ld) == 0 || strcmp(exe, exe2) == 0) - PFATAL(cLRD "[!] " cRST - "Error: real 'ld' path points to afl-ld, set AFL_REAL_LD to " - "the real 'ld' program!"); - - } - - if (have_afl_ld_caller > 1) - PFATAL(cLRD "[!] " cRST - "Error: afl-ld calls itself in a loop, set AFL_REAL_LD to the " - "real 'ld' program!"); - - if (argc < 2) { - - SAYF( - "\n" - "This is a helper application for afl-fuzz. It is a wrapper around GNU " - "'ld',\n" - "executed by the toolchain whenever using " - "afl-clang-lto/afl-clang-lto++.\n" - "You probably don't want to run this program directly.\n\n" - - "Environment variables:\n" - " AFL_LD_PASSTHROUGH do not link+optimize == no instrumentation\n" - " AFL_REAL_LD point to the real ld if necessary\n" - - "\nafl-ld was compiled with the fixed real 'ld' path of %s and the " - "clang " - "bin path of %s\n\n", - real_ld, LLVM_BINDIR); - - exit(1); - - } - - if (getenv("AFL_LD") == NULL) { - - /* if someone install clang/ld into the same directory as afl++ then - they are out of luck ... */ - - if (have_afl_ld_caller == 1) { clean_path(); } - - if (real_ld != NULL && strlen(real_ld) > 1) execvp(real_ld, argv); - execvp("ld", argv); // fallback - PFATAL("Oops, failed to execute 'ld' - check your PATH"); - - } - - atexit(at_exit_handler); // ensure to wipe temp files if things fail - - edit_params(argc, argv); // here most of the magic happens :-) - - if (debug) - SAYF(cMGN "[D] " cRST - "param counts: ar:%u lib:%u ld:%u link:%u opt:%u instr:%u\n", - ar_dir_cnt, libdir_cnt, ld_param_cnt, link_param_cnt, opt_param_cnt, - inst_param_cnt); - - if (!just_version) { - - if (we_link == 0) { - - if (!getenv("AFL_QUIET")) - WARNF("No LTO input file found, cannot instrument!"); - - } else { - - /* first we link all files */ - if (!be_quiet) OKF("Running bitcode linker, creating %s", linked_file); - - if (debug) { - - SAYF(cMGN "[D]" cRST " cd \"%s\";", getthecwd()); - for (i = 0; i < link_param_cnt; i++) - SAYF(" \"%s\"", link_params[i]); - SAYF("\n"); - - } - - if (!(pid = fork())) { - - execvp(link_params[0], (char **)link_params); - FATAL("Oops, failed to execute '%s'", link_params[0]); - - } - - if (pid < 0) PFATAL("fork() failed"); - if (waitpid(pid, &status, 0) <= 0) PFATAL("waitpid() failed"); - if (WEXITSTATUS(status) != 0) { - - SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD - "\n[-] PROGRAM ABORT : " cRST); - SAYF( - "llvm-link failed! Probable causes:\n\n" - " #1 If the error is \"linking globals named '...': symbol " - "multiply defined\"\n" - " then there is nothing we can do - llvm-link is missing an " - "important feature\n\n" - " #2 If the error is \"expected top-level entity\" and then " - "binary output, this\n" - " is because the same file is present in different .a archives " - "in different\n" - " formats. This can be fixed by manual doing the steps afl-ld " - "is doing but\n" - " programmatically - sorry!\n\n"); - exit(WEXITSTATUS(status)); - - } - - /* then we perform an optimization on the collected objects files */ - if (!be_quiet) - OKF("Performing optimization via opt, creating %s", modified_file); - if (debug) { - - SAYF(cMGN "[D]" cRST " cd \"%s\";", getthecwd()); - for (i = 0; i < opt_param_cnt; i++) - SAYF(" \"%s\"", opt_params[i]); - SAYF("\n"); - - } - - if (!(pid = fork())) { - - execvp(opt_params[0], (char **)opt_params); - FATAL("Oops, failed to execute '%s'", opt_params[0]); - - } - - if (pid < 0) PFATAL("fork() failed"); - if (waitpid(pid, &status, 0) <= 0) PFATAL("waitpid() failed"); - if (WEXITSTATUS(status) != 0) exit(WEXITSTATUS(status)); - - /* then we run the instrumentation through the optimizer */ - if (!be_quiet) - OKF("Performing instrumentation via opt, creating %s", final_file); - if (debug) { - - SAYF(cMGN "[D]" cRST " cd \"%s\";", getthecwd()); - for (i = 0; i < inst_param_cnt; i++) - SAYF(" \"%s\"", inst_params[i]); - SAYF("\n"); - - } - - if (!(pid = fork())) { - - execvp(inst_params[0], (char **)inst_params); - FATAL("Oops, failed to execute '%s'", inst_params[0]); - - } - - if (pid < 0) PFATAL("fork() failed"); - if (waitpid(pid, &status, 0) <= 0) PFATAL("waitpid() failed"); - if (WEXITSTATUS(status) != 0) exit(WEXITSTATUS(status)); - - } - - /* next step - run the linker! :-) */ - - } - - if (!be_quiet) OKF("Running real linker %s", real_ld); - if (debug) { - - SAYF(cMGN "[D]" cRST " cd \"%s\";", getthecwd()); - for (i = 0; i < ld_param_cnt; i++) - SAYF(" \"%s\"", ld_params[i]); - SAYF("\n"); - - } - - if (!(pid = fork())) { - - clean_path(); - - unsetenv("AFL_LD"); - - if (strlen(real_ld) > 1) execvp(real_ld, (char **)ld_params); - execvp("ld", (char **)ld_params); // fallback - FATAL("Oops, failed to execute 'ld' - check your PATH"); - - } - - if (pid < 0) PFATAL("fork() failed"); - - if (waitpid(pid, &status, 0) <= 0) PFATAL("waitpid() failed"); - if (debug) SAYF(cMGN "[D] " cRST "linker result: %d\n", status); - - if (!just_version) { - - if (!getenv("AFL_KEEP_ASSEMBLY")) { - - if (linked_file) { - - unlink(linked_file); - linked_file = NULL; - - } - - if (modified_file) { - - unlink(modified_file); - modified_file = NULL; - - } - - if (final_file) { - - unlink(final_file); - final_file = NULL; - - } - - if (ar_dir != NULL) { - - wipe_directory(ar_dir); - ar_dir = NULL; - - } - - } else { - - if (!be_quiet) { - - SAYF( - "[!] afl-ld: keeping link file %s, optimized bitcode %s and " - "instrumented bitcode %s", - linked_file, modified_file, final_file); - if (ar_dir_cnt > 0 && ar_dir) - SAYF(" and ar archive unpack directory %s", ar_dir); - SAYF("\n"); - - } - - } - - if (status == 0) { - - if (!be_quiet) OKF("Linker was successful"); - - } else { - - SAYF(cLRD "[-] " cRST - "Linker failed, please investigate and send a bug report. Most " - "likely an 'ld' option is incompatible with %s. Try " - "AFL_KEEP_ASSEMBLY=1 and AFL_DEBUG=1 for replaying.\n", - AFL_CLANG_FLTO); - - } - - } - - exit(WEXITSTATUS(status)); - -} - diff --git a/llvm_mode/afl-llvm-lto-instrumentation.so.cc b/llvm_mode/afl-llvm-lto-instrumentation.so.cc index 4bc16f17..2a9b17b2 100644 --- a/llvm_mode/afl-llvm-lto-instrumentation.so.cc +++ b/llvm_mode/afl-llvm-lto-instrumentation.so.cc @@ -378,7 +378,8 @@ bool AFLLTOPass::runOnModule(Module &M) { M, Int32Ty, true, GlobalValue::ExternalLinkage, 0, "__afl_final_loc", 0, GlobalVariable::GeneralDynamicTLSModel, 0, false); ConstantInt *const_loc = ConstantInt::get(Int32Ty, afl_global_id); - AFLFinalLoc->setAlignment(4); + MaybeAlign Align = MaybeAlign(4); + AFLFinalLoc->setAlignment(Align); AFLFinalLoc->setInitializer(const_loc); } @@ -423,5 +424,5 @@ static RegisterPass X("afl-lto", "afl++ LTO instrumentation pass", false, false); static RegisterStandardPasses RegisterAFLLTOPass( - PassManagerBuilder::EP_OptimizerLast, registerAFLLTOPass); + PassManagerBuilder::EP_FullLinkTimeOptimizationLast, registerAFLLTOPass); From d55196352ce9cd93abab111b337b102fe4be2027 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 9 Apr 2020 11:49:40 +0200 Subject: [PATCH 70/72] fix compilers for empty AFL_CC/AFL_CXX env --- docs/Changelog.md | 4 +++- gcc_plugin/afl-gcc-fast.c | 4 ++-- llvm_mode/GNUmakefile | 13 +------------ llvm_mode/afl-clang-fast.c | 4 ++-- src/afl-gcc.c | 10 +++++----- test/test.sh | 2 ++ 6 files changed, 15 insertions(+), 22 deletions(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index 18f38551..0ec330a7 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -10,7 +10,9 @@ sending a mail to . ### Version ++2.63d (development): - - ... + - LTO mode now requires llvm11 - but compiles all targets! :) + - if AFL_CC/AFL_CXX is set but empty afl compilers did fail, fixed + (this bug is in vanilla afl too) ### Version ++2.63c (release): diff --git a/gcc_plugin/afl-gcc-fast.c b/gcc_plugin/afl-gcc-fast.c index fbda08b6..8953c523 100644 --- a/gcc_plugin/afl-gcc-fast.c +++ b/gcc_plugin/afl-gcc-fast.c @@ -121,12 +121,12 @@ static void edit_params(u32 argc, char **argv) { if (!strcmp(name, "afl-g++-fast")) { u8 *alt_cxx = getenv("AFL_CXX"); - cc_params[0] = alt_cxx ? alt_cxx : (u8 *)AFL_GCC_CXX; + cc_params[0] = alt_cxx && *alt_cxx ? alt_cxx : (u8 *)AFL_GCC_CXX; } else { u8 *alt_cc = getenv("AFL_CC"); - cc_params[0] = alt_cc ? alt_cc : (u8 *)AFL_GCC_CC; + cc_params[0] = alt_cc && *alt_cc ? alt_cc : (u8 *)AFL_GCC_CC; } diff --git a/llvm_mode/GNUmakefile b/llvm_mode/GNUmakefile index ce60dd1c..7432b061 100644 --- a/llvm_mode/GNUmakefile +++ b/llvm_mode/GNUmakefile @@ -188,7 +188,7 @@ ifeq "$(TEST_MMAP)" "1" LDFLAGS += -lrt endif - 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 + PROGS = ../afl-clang-fast ../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 # If prerequisites are not given, warn, do not build anything, and exit with code 0 ifeq "$(LLVMVER)" "" @@ -256,17 +256,6 @@ ifeq "$(LLVM_LTO)" "1" 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 -o .test-instr ../test-instr.c && echo "[+] afl-clang-lto seems 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) diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index 9d8ebdec..26ee0bab 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -185,7 +185,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { snprintf(llvm_fullpath, sizeof(llvm_fullpath), "%s/clang++", LLVM_BINDIR); else sprintf(llvm_fullpath, "clang++"); - cc_params[0] = alt_cxx ? alt_cxx : (u8 *)llvm_fullpath; + cc_params[0] = alt_cxx && *alt_cxx ? alt_cxx : (u8 *)llvm_fullpath; } else { @@ -194,7 +194,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { snprintf(llvm_fullpath, sizeof(llvm_fullpath), "%s/clang", LLVM_BINDIR); else sprintf(llvm_fullpath, "clang"); - cc_params[0] = alt_cc ? alt_cc : (u8 *)llvm_fullpath; + cc_params[0] = alt_cc && *alt_cc ? alt_cc : (u8 *)llvm_fullpath; } diff --git a/src/afl-gcc.c b/src/afl-gcc.c index b0153b49..32cd36cb 100644 --- a/src/afl-gcc.c +++ b/src/afl-gcc.c @@ -142,12 +142,12 @@ static void edit_params(u32 argc, char **argv) { if (!strcmp(name, "afl-clang++")) { u8 *alt_cxx = getenv("AFL_CXX"); - cc_params[0] = alt_cxx ? alt_cxx : (u8 *)"clang++"; + cc_params[0] = alt_cxx && *alt_cxx ? alt_cxx : (u8 *)"clang++"; } else { u8 *alt_cc = getenv("AFL_CC"); - cc_params[0] = alt_cc ? alt_cc : (u8 *)"clang"; + cc_params[0] = alt_cc && *alt_cc ? alt_cc : (u8 *)"clang"; } @@ -187,17 +187,17 @@ static void edit_params(u32 argc, char **argv) { if (!strcmp(name, "afl-g++")) { u8 *alt_cxx = getenv("AFL_CXX"); - cc_params[0] = alt_cxx ? alt_cxx : (u8 *)"g++"; + cc_params[0] = alt_cxx && *alt_cxx ? alt_cxx : (u8 *)"g++"; } else if (!strcmp(name, "afl-gcj")) { u8 *alt_cc = getenv("AFL_GCJ"); - cc_params[0] = alt_cc ? alt_cc : (u8 *)"gcj"; + cc_params[0] = alt_cc && *alt_cc ? alt_cc : (u8 *)"gcj"; } else { u8 *alt_cc = getenv("AFL_CC"); - cc_params[0] = alt_cc ? alt_cc : (u8 *)"gcc"; + cc_params[0] = alt_cc && *alt_cc ? alt_cc : (u8 *)"gcc"; } diff --git a/test/test.sh b/test/test.sh index 0666ca36..c673337e 100755 --- a/test/test.sh +++ b/test/test.sh @@ -581,6 +581,8 @@ test -e ../afl-gcc-fast -a -e ../afl-gcc-rt.o && { INCOMPLETE=1 } +test -z "$AFL_CC" && unset AFL_CC + $ECHO "$BLUE[*] Testing: shared library extensions" cc $CFLAGS -o test-compcov test-compcov.c > /dev/null 2>&1 test -e ../libtokencap.so && { From e354235ebb46ab8451b96a1fd21003a37f59f86f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 9 Apr 2020 13:13:07 +0200 Subject: [PATCH 71/72] lto module clean-up (#303) --- llvm_mode/afl-llvm-lto-instrumentation.so.cc | 87 ++------------------ 1 file changed, 7 insertions(+), 80 deletions(-) diff --git a/llvm_mode/afl-llvm-lto-instrumentation.so.cc b/llvm_mode/afl-llvm-lto-instrumentation.so.cc index 2a9b17b2..93968984 100644 --- a/llvm_mode/afl-llvm-lto-instrumentation.so.cc +++ b/llvm_mode/afl-llvm-lto-instrumentation.so.cc @@ -23,12 +23,6 @@ */ -// CONFIG OPTION: -// If #define USE_SPLIT is used, then the llvm::SplitEdge function is used -// instead of our own implementation. Ours looks better and will -// compile everywhere. But it is not working for complex code. yet. damn. -#define USE_SPLIT - #define AFL_LLVM_PASS #include "config.h" @@ -44,31 +38,17 @@ #include #include "llvm/Config/llvm-config.h" -#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 5 -typedef long double max_align_t; -#endif - #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" - -#ifdef USE_SPLIT #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/MemorySSAUpdater.h" -#endif - -#if LLVM_VERSION_MAJOR > 3 || \ - (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4) #include "llvm/IR/DebugInfo.h" #include "llvm/IR/CFG.h" -#else -#include "llvm/DebugInfo.h" -#include "llvm/Support/CFG.h" -#endif using namespace llvm; @@ -91,7 +71,6 @@ class AFLLTOPass : public ModulePass { } -#ifdef USE_SPLIT void getAnalysisUsage(AnalysisUsage &AU) const override { ModulePass::getAnalysisUsage(AU); @@ -100,8 +79,6 @@ class AFLLTOPass : public ModulePass { } -#endif - // Calculate the number of average collisions that would occur if all // location IDs would be assigned randomly (like normal afl/afl++). // This uses the "balls in bins" algorithm. @@ -179,20 +156,14 @@ bool AFLLTOPass::runOnModule(Module &M) { LLVMContext &C = M.getContext(); - IntegerType * Int8Ty = IntegerType::getInt8Ty(C); - IntegerType * Int32Ty = IntegerType::getInt32Ty(C); - struct timeval tv; - struct timezone tz; - u32 rand_seed; + IntegerType *Int8Ty = IntegerType::getInt8Ty(C); + IntegerType *Int32Ty = IntegerType::getInt32Ty(C); - /* Setup random() so we get Actually Random(TM) outputs from AFL_R() */ - gettimeofday(&tv, &tz); - rand_seed = tv.tv_sec ^ tv.tv_usec ^ getpid(); - AFL_SR(rand_seed); + if (getenv("AFL_DEBUG")) debug = 1; /* Show a banner */ - if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) { + if ((isatty(2) && !getenv("AFL_QUIET")) || debug) { SAYF(cCYA "afl-llvm-lto" VERSION cRST " by Marc \"vanHauser\" Heuse \n"); @@ -201,10 +172,6 @@ bool AFLLTOPass::runOnModule(Module &M) { be_quiet = 1; -#if LLVM_VERSION_MAJOR < 9 - char *neverZero_counters_str = getenv("AFL_LLVM_NOT_ZERO"); -#endif - /* Get globals for the SHM region and the previous location. Note that __afl_prev_loc is thread-local. */ @@ -224,12 +191,6 @@ bool AFLLTOPass::runOnModule(Module &M) { if (F.size() < 2) continue; if (isBlacklisted(&F)) continue; -#ifdef USE_SPLIT - // DominatorTree &DT = - // getAnalysis(F).getDomTree(); LoopInfo & LI = - // getAnalysis(F).getLoopInfo(); -#endif - std::vector InsBlocks; for (auto &BB : F) { @@ -274,11 +235,7 @@ bool AFLLTOPass::runOnModule(Module &M) { for (uint32_t j = 0; j < Successors.size(); j++) { -#ifdef USE_SPLIT BasicBlock *newBB = llvm::SplitEdge(origBB, Successors[j]); -#else - BasicBlock *newBB = BasicBlock::Create(C, "", &F, nullptr); -#endif if (!newBB) { @@ -287,12 +244,8 @@ bool AFLLTOPass::runOnModule(Module &M) { } -#ifdef USE_SPLIT BasicBlock::iterator IP = newBB->getFirstInsertionPt(); IRBuilder<> IRB(&(*IP)); -#else - IRBuilder<> IRB(&(*newBB)); -#endif /* Set the ID of the inserted basic block */ @@ -313,38 +266,12 @@ bool AFLLTOPass::runOnModule(Module &M) { Value *Incr = IRB.CreateAdd(Counter, One); -#if LLVM_VERSION_MAJOR < 9 - if (neverZero_counters_str != - NULL) { // with llvm 9 we make this the default as the bug in - // llvm is then fixed -#endif - auto cf = IRB.CreateICmpEQ(Incr, Zero); - auto carry = IRB.CreateZExt(cf, Int8Ty); - Incr = IRB.CreateAdd(Incr, carry); -#if LLVM_VERSION_MAJOR < 9 - - } - -#endif + auto cf = IRB.CreateICmpEQ(Incr, Zero); + auto carry = IRB.CreateZExt(cf, Int8Ty); + Incr = IRB.CreateAdd(Incr, carry); IRB.CreateStore(Incr, MapPtrIdx) ->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); -#ifdef USE_SPLIT - // nothing -#else - - // Unconditional jump to the destination BB - - IRB.CreateBr(Successors[j]); - - // Replace the original destination to this newly inserted BB - - origBB->replacePhiUsesWith(Successors[j], newBB); - BasicBlock *S = Successors[j]; - S->replacePhiUsesWith(origBB, newBB); - TI->setSuccessor(j, newBB); - -#endif // done :) inst_blocks++; From 1fab45024ba2c9f39f63d0078ca35c4ffd52b035 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 9 Apr 2020 13:17:56 +0200 Subject: [PATCH 72/72] check for empty AFL env vars --- src/afl-common.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/afl-common.c b/src/afl-common.c index 73b3fa8a..7eee5265 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -353,7 +353,7 @@ void check_environment_vars(char **envp) { if (be_quiet) return; int index = 0, found = 0; - char *env; + char *env, *val; while ((env = envp[index++]) != NULL) { if (strncmp(env, "ALF_", 4) == 0) { @@ -367,10 +367,21 @@ void check_environment_vars(char **envp) { while (match == 0 && afl_environment_variables[i] != NULL) if (strncmp(env, afl_environment_variables[i], strlen(afl_environment_variables[i])) == 0 && - env[strlen(afl_environment_variables[i])] == '=') + env[strlen(afl_environment_variables[i])] == '=') { + match = 1; - else + if ((val = getenv(afl_environment_variables[i])) && !*val) + WARNF( + "AFL environment variable %s defined but is empty, this can " + "lead to unexpected consequences", + afl_environment_variables[i]); + + } else { + i++; + + } + if (match == 0) { WARNF("Mistyped AFL environment variable: %s", env);