add cull queue, -i subdir traversal

This commit is contained in:
vanhauser-thc
2020-09-05 12:32:10 +02:00
parent 996986bed5
commit 4b3ad5f037
9 changed files with 437 additions and 277 deletions

View File

@ -24,21 +24,22 @@ BIN_PATH = $(PREFIX)/bin
HELPER_PATH = $(PREFIX)/lib/afl HELPER_PATH = $(PREFIX)/lib/afl
DOC_PATH = $(PREFIX)/share/doc/afl DOC_PATH = $(PREFIX)/share/doc/afl
MISC_PATH = $(PREFIX)/share/afl MISC_PATH = $(PREFIX)/share/afl
MAN_PATH = $(PREFIX)/share/man/man8 MAN_PATH = $(PREFIX)/man/man8
PROGNAME = afl PROGNAME = afl
VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2) VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2)
# PROGS intentionally omit afl-as, which gets installed elsewhere. # PROGS intentionally omit afl-as, which gets installed elsewhere.
PROGS = afl-gcc afl-g++ afl-fuzz afl-showmap afl-tmin afl-gotcpu afl-analyze PROGS = afl-fuzz afl-showmap afl-tmin afl-gotcpu afl-analyze
SH_PROGS = afl-plot afl-cmin afl-cmin.bash afl-whatsup afl-system-config 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 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 "$(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" 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 CFLAGS_FLTO ?= -flto=full
else 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" 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 CFLAGS_FLTO ?= -flto=thin
else else
@ -46,7 +47,7 @@ ifeq "$(findstring android, $(shell $(CC) --version 2>/dev/null))" ""
CFLAGS_FLTO ?= -flto CFLAGS_FLTO ?= -flto
endif endif
endif endif
endif endif
endif endif
ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -fno-move-loop-invariants -fdisable-tree-cunrolli -x c - -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -fno-move-loop-invariants -fdisable-tree-cunrolli -x c - -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
@ -61,10 +62,7 @@ ifneq "$(shell uname)" "Darwin"
endif endif
endif endif
# OS X does not like _FORTIFY_SOURCE=2 # OS X does not like _FORTIFY_SOURCE=2
# _FORTIFY_SOURCE=2 does not like -O0
ifndef DEBUG
CFLAGS_OPT += -D_FORTIFY_SOURCE=2 CFLAGS_OPT += -D_FORTIFY_SOURCE=2
endif
endif endif
ifeq "$(shell uname)" "SunOS" ifeq "$(shell uname)" "SunOS"
@ -206,10 +204,7 @@ else
endif endif
ifneq "$(filter Linux GNU%,$(shell uname))" "" ifneq "$(filter Linux GNU%,$(shell uname))" ""
# _FORTIFY_SOURCE=2 does not like -O0
ifndef DEBUG
override CFLAGS += -D_FORTIFY_SOURCE=2 override CFLAGS += -D_FORTIFY_SOURCE=2
endif
LDFLAGS += -ldl -lrt LDFLAGS += -ldl -lrt
endif endif
@ -223,11 +218,7 @@ ifneq "$(findstring NetBSD, $(shell uname))" ""
LDFLAGS += -lpthread LDFLAGS += -lpthread
endif endif
ifeq "$(findstring clang, $(shell $(CC) --version 2>/dev/null))" "" TEST_CC = afl-gcc
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 COMM_HDR = include/alloc-inl.h include/config.h include/debug.h include/types.h
@ -277,28 +268,47 @@ ifdef TEST_MMAP
LDFLAGS += -Wno-deprecated-declarations LDFLAGS += -Wno-deprecated-declarations
endif endif
all: test_x86 test_shm test_python ready $(PROGS) afl-as test_build all_done .PHONY: all
all: test_x86 test_shm test_python ready $(PROGS) afl-as llvm gcc_plugin test_build all_done
man: afl-gcc all $(MANPAGES) .PHONY: llvm
llvm:
-$(MAKE) -f GNUmakefile.llvm
@test -e afl-cc || { echo "[-] Compiling afl-cc failed. You seem not to have a working compiler." ; exit 1; }
.PHONY: gcc_plugin
gcc_plugin:
-$(MAKE) -f GNUmakefile.gcc_plugin
.PHONY: man
man: $(MANPAGES)
.PHONY: test
test: tests
.PHONY: tests
tests: source-only tests: source-only
@cd test ; ./test-all.sh @cd test ; ./test-all.sh
@rm -f test/errors @rm -f test/errors
.PHONY: performance-tests
performance-tests: performance-test performance-tests: performance-test
.PHONY: test-performance
test-performance: performance-test test-performance: performance-test
.PHONY: performance-test
performance-test: source-only performance-test: source-only
@cd test ; ./test-performance.sh @cd test ; ./test-performance.sh
# hint: make targets are also listed in the top level README.md # hint: make targets are also listed in the top level README.md
.PHONY: help
help: help:
@echo "HELP --- the following make targets exist:" @echo "HELP --- the following make targets exist:"
@echo "==========================================" @echo "=========================================="
@echo "all: just the main afl++ binaries" @echo "all: just the main afl++ binaries"
@echo "binary-only: everything for binary-only fuzzing: qemu_mode, unicorn_mode, libdislocator, libtokencap" @echo "binary-only: everything for binary-only fuzzing: qemu_mode, unicorn_mode, libdislocator, libtokencap"
@echo "source-only: everything for source code fuzzing: llvm_mode, gcc_plugin, libdislocator, libtokencap" @echo "source-only: everything for source code fuzzing: gcc_plugin, libdislocator, libtokencap"
@echo "distrib: everything (for both binary-only and source code fuzzing)" @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 "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 "install: installs everything you have compiled with the build option above"
@ -322,8 +332,8 @@ help:
@echo "==========================================" @echo "=========================================="
@echo e.g.: make ASAN_BUILD=1 @echo e.g.: make ASAN_BUILD=1
.PHONY: test_x86
ifndef AFL_NO_X86 ifndef AFL_NO_X86
test_x86: test_x86:
@echo "[*] Checking for the default compiler cc..." @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=<yourCcompiler>'."; echo; exit 1 ) @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=<yourCcompiler>'."; echo; exit 1 )
@ -332,148 +342,129 @@ test_x86:
@echo "[*] Checking for the ability to compile x86 code..." @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 ) @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 @rm -f .test1
else else
test_x86: test_x86:
@echo "[!] Note: skipping x86 compilation checks (AFL_NO_X86 set)." @echo "[!] Note: skipping x86 compilation checks (AFL_NO_X86 set)."
endif endif
.PHONY: test_shm
ifeq "$(SHMAT_OK)" "1" ifeq "$(SHMAT_OK)" "1"
test_shm: test_shm:
@echo "[+] shmat seems to be working." @echo "[+] shmat seems to be working."
@rm -f .test2 @rm -f .test2
else else
test_shm: test_shm:
@echo "[-] shmat seems not to be working, switching to mmap implementation" @echo "[-] shmat seems not to be working, switching to mmap implementation"
endif endif
.PHONY: test_python
ifeq "$(PYTHON_OK)" "1" ifeq "$(PYTHON_OK)" "1"
test_python: test_python:
@rm -f .test 2> /dev/null @rm -f .test 2> /dev/null
@echo "[+] $(PYTHON_VERSION) support seems to be working." @echo "[+] $(PYTHON_VERSION) support seems to be working."
else else
test_python: test_python:
@echo "[-] You seem to need to install the package python3-dev, python2-dev or python-dev (and perhaps python[23]-apt), but it is optional so we continue" @echo "[-] You seem to need to install the package python3-dev, python2-dev or python-dev (and perhaps python[23]-apt), but it is optional so we continue"
endif endif
.PHONY: ready
ready: ready:
@echo "[+] Everything seems to be working, ready to compile." @echo "[+] Everything seems to be working, ready to compile."
afl-g++: afl-gcc
afl-gcc: src/afl-gcc.c $(COMM_HDR) | test_x86
$(CC) $(CFLAGS) $(CPPFLAGS) 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 afl-as: src/afl-as.c include/afl-as.h $(COMM_HDR) | test_x86
$(CC) $(CFLAGS) $(CPPFLAGS) src/$@.c -o $@ $(LDFLAGS) $(CC) $(CFLAGS) src/$@.c -o $@ $(LDFLAGS)
ln -sf afl-as as @ln -sf afl-as as
src/afl-performance.o : $(COMM_HDR) src/afl-performance.c include/hash.h src/afl-performance.o : $(COMM_HDR) src/afl-performance.c include/hash.h
$(CC) $(CFLAGS) $(CPPFLAGS) -Iinclude $(SPECIAL_PERFORMANCE) -O3 -fno-unroll-loops -c src/afl-performance.c -o src/afl-performance.o $(CC) -Iinclude $(SPECIAL_PERFORMANCE) -O3 -fno-unroll-loops -c src/afl-performance.c -o src/afl-performance.o
src/afl-common.o : $(COMM_HDR) src/afl-common.c include/common.h src/afl-common.o : $(COMM_HDR) src/afl-common.c include/common.h
$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(CPPFLAGS) -c src/afl-common.c -o src/afl-common.o $(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 src/afl-forkserver.o : $(COMM_HDR) src/afl-forkserver.c include/forkserver.h
$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(CPPFLAGS) -c src/afl-forkserver.c -o src/afl-forkserver.o $(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 src/afl-sharedmem.o : $(COMM_HDR) src/afl-sharedmem.c include/sharedmem.h
$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(CPPFLAGS) -c src/afl-sharedmem.c -o src/afl-sharedmem.o $(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-sharedmem.c -o src/afl-sharedmem.o
afl-fuzz: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o | test_x86 afl-fuzz: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o | test_x86
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) $(CPPFLAGS) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(PYFLAGS) $(LDFLAGS) $(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(PYFLAGS) $(LDFLAGS)
afl-showmap: src/afl-showmap.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o $(COMM_HDR) | test_x86 afl-showmap: src/afl-showmap.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o $(COMM_HDR) | test_x86
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(CPPFLAGS) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(LDFLAGS) $(CC) $(CFLAGS) $(COMPILE_STATIC) $(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 src/afl-performance.o $(COMM_HDR) | test_x86 afl-tmin: src/afl-tmin.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o $(COMM_HDR) | test_x86
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(CPPFLAGS) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(LDFLAGS) $(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(LDFLAGS)
afl-analyze: src/afl-analyze.c src/afl-common.o src/afl-sharedmem.o src/afl-performance.o $(COMM_HDR) | test_x86 afl-analyze: src/afl-analyze.c src/afl-common.o src/afl-sharedmem.o src/afl-performance.o $(COMM_HDR) | test_x86
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(CPPFLAGS) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-performance.o -o $@ $(LDFLAGS) $(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-performance.o -o $@ $(LDFLAGS)
afl-gotcpu: src/afl-gotcpu.c src/afl-common.o $(COMM_HDR) | test_x86 afl-gotcpu: src/afl-gotcpu.c src/afl-common.o $(COMM_HDR) | test_x86
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(CPPFLAGS) src/$@.c src/afl-common.o -o $@ $(LDFLAGS) $(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o -o $@ $(LDFLAGS)
.PHONY: document
document: afl-fuzz-document
# document all mutations and only do one run (use with only one input file!) # 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-performance.o | test_x86 afl-fuzz-document: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-performance.o | test_x86
$(CC) -D_DEBUG=\"1\" -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) $(CPPFLAGS) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.c src/afl-performance.o -o afl-fuzz-document $(PYFLAGS) $(LDFLAGS) $(CC) -D_DEBUG=\"1\" -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.c src/afl-performance.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) 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) $(CPPFLAGS) -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
unit_maybe_alloc: test/unittests/unit_maybe_alloc.o unit_maybe_alloc: test/unittests/unit_maybe_alloc.o
@$(CC) $(CFLAGS) $(CPPFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_maybe_alloc.o -o test/unittests/unit_maybe_alloc $(LDFLAGS) $(ASAN_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_maybe_alloc
test/unittests/unit_hash.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_hash.c $(AFL_FUZZ_FILES) src/afl-performance.o test/unittests/unit_hash.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_hash.c $(AFL_FUZZ_FILES) src/afl-performance.o
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(CPPFLAGS) -c test/unittests/unit_hash.c -o test/unittests/unit_hash.o @$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_hash.c -o test/unittests/unit_hash.o
unit_hash: test/unittests/unit_hash.o src/afl-performance.o unit_hash: test/unittests/unit_hash.o src/afl-performance.o
@$(CC) $(CFLAGS) $(CPPFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_hash $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka @$(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_hash $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
./test/unittests/unit_hash ./test/unittests/unit_hash
test/unittests/unit_rand.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_rand.c $(AFL_FUZZ_FILES) src/afl-performance.o test/unittests/unit_rand.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_rand.c $(AFL_FUZZ_FILES) src/afl-performance.o
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(CPPFLAGS) -c test/unittests/unit_rand.c -o test/unittests/unit_rand.o @$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_rand.c -o test/unittests/unit_rand.o
unit_rand: test/unittests/unit_rand.o src/afl-common.o src/afl-performance.o unit_rand: test/unittests/unit_rand.o src/afl-common.o src/afl-performance.o
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(CPPFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_rand $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka @$(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_rand $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
./test/unittests/unit_rand ./test/unittests/unit_rand
test/unittests/unit_list.o : $(COMM_HDR) include/list.h test/unittests/unit_list.c $(AFL_FUZZ_FILES) test/unittests/unit_list.o : $(COMM_HDR) include/list.h test/unittests/unit_list.c $(AFL_FUZZ_FILES)
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(CPPFLAGS) -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 unit_list: test/unittests/unit_list.o
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(CPPFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_list.o -o test/unittests/unit_list $(LDFLAGS) $(ASAN_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/unit_list
test/unittests/unit_preallocable.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_preallocable.c $(AFL_FUZZ_FILES) test/unittests/unit_preallocable.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_preallocable.c $(AFL_FUZZ_FILES)
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(CPPFLAGS) -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_preallocable: test/unittests/unit_preallocable.o unit_preallocable: test/unittests/unit_preallocable.o
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(CPPFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_preallocable.o -o test/unittests/unit_preallocable $(LDFLAGS) $(ASAN_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 ./test/unittests/unit_preallocable
.PHONY: unit_clean
unit_clean: unit_clean:
@rm -f ./test/unittests/unit_preallocable ./test/unittests/unit_list ./test/unittests/unit_maybe_alloc test/unittests/*.o @rm -f ./test/unittests/unit_preallocable ./test/unittests/unit_list ./test/unittests/unit_maybe_alloc test/unittests/*.o
.PHONY: unit
ifneq "$(shell uname)" "Darwin" ifneq "$(shell uname)" "Darwin"
unit: unit_maybe_alloc unit_preallocable unit_list unit_clean unit_rand unit_hash unit: unit_maybe_alloc unit_preallocable unit_list unit_clean unit_rand unit_hash
else else
unit: unit:
@echo [-] unit tests are skipped on Darwin \(lacks GNU linker feature --wrap\) @echo [-] unit tests are skipped on Darwin \(lacks GNU linker feature --wrap\)
endif endif
.PHONY: code-format
code-format: code-format:
./.custom-format.py -i src/*.c ./.custom-format.py -i src/*.c
./.custom-format.py -i include/*.h ./.custom-format.py -i include/*.h
./.custom-format.py -i libdislocator/*.c ./.custom-format.py -i libdislocator/*.c
./.custom-format.py -i libtokencap/*.c ./.custom-format.py -i libtokencap/*.c
./.custom-format.py -i llvm_mode/*.c ./.custom-format.py -i instrumentation/*.h
./.custom-format.py -i llvm_mode/*.h ./.custom-format.py -i instrumentation/*.cc
./.custom-format.py -i llvm_mode/*.cc ./.custom-format.py -i instrumentation/*.c
./.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 custom_mutators/*/*.c ./.custom-format.py -i custom_mutators/*/*.c
@#./.custom-format.py -i custom_mutators/*/*.h # destroys input.h :-( @#./.custom-format.py -i custom_mutators/*/*.h # destroys input.h :-(
./.custom-format.py -i examples/*/*.c ./.custom-format.py -i examples/*/*.c
@ -489,38 +480,40 @@ code-format:
./.custom-format.py -i *.c ./.custom-format.py -i *.c
.PHONY: test_build
ifndef AFL_NO_X86 ifndef AFL_NO_X86
test_build: afl-cc afl-as afl-showmap
test_build: afl-gcc afl-as afl-showmap
@echo "[*] Testing the CC wrapper and instrumentation output..." @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_AS_FORCE_INSTRUMENT=1 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 ) @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 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 echo 1 | ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr1 ./test-instr
@rm -f 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 @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
@echo "[+] All right, the instrumentation seems to be working!" @echo "[+] All right, the instrumentation seems to be working!"
else else
test_build: afl-cc afl-as afl-showmap
test_build: afl-gcc afl-as afl-showmap
@echo "[!] Note: skipping build tests (you may need to use LLVM or QEMU mode)." @echo "[!] Note: skipping build tests (you may need to use LLVM or QEMU mode)."
endif endif
.PHONY: all_done
all_done: test_build 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 @test -e afl-cc && echo "[+] Main compiler 'afl-cc' successfully built!" || { echo "[-] Main compiler 'afl-cc' failed to built, set up a working build environment first!" ; exit 1 ; }
@test -e cmplog-instructions-pass.so && echo "[+] LLVM mode for 'afl-cc' successfully built!" || echo "[-] LLVM mode for 'afl-cc' failed to built, likely you either have not llvm installed or you have not set LLVM_CONFIG pointing to e.g. llvm-config-11. See instrumenation/README.llvm.md how to do this. Highly recommended!"
@test -e SanitizerCoverageLTO.so && echo "[+] LLVM LTO mode for 'afl-cc' successfully built!" || echo "[-] LLVM LTO mode for 'afl-cc' failed to built, this would need LLVM 11+, see instrumentation/README.lto.md how to build it"
@test -e afl-gcc-pass.so && echo "[+] gcc_plugin for 'afl-cc' successfully built!" || echo "[-] gcc_plugin for 'afl-cc' failed to built, unless you really need it that is fine - or read instrumentation/README.gcc_plugin.md how to build it"
@echo "[+] All done! Be sure to review the README.md - it's pretty short and useful." @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 @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 @! 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 all .NOTPARALLEL: clean all
.PHONY: clean
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 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 .afl-* 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 afl-qemu-trace afl-gcc-fast afl-gcc-pass.so afl-g++-fast ld *.so *.8 test/unittests/*.o test/unittests/unit_maybe_alloc test/unittests/preallocable .afl-* afl-gcc afl-g++
rm -rf out_dir qemu_mode/qemu-3.1.1 *.dSYM */*.dSYM rm -rf out_dir qemu_mode/qemu-3.1.1 *.dSYM */*.dSYM
-$(MAKE) -C llvm_mode clean -$(MAKE) -f GNUmakefile.llvm clean
-$(MAKE) -C gcc_plugin clean -$(MAKE) -f GNUmakefile.gcc_plugin clean
$(MAKE) -C libdislocator clean $(MAKE) -C libdislocator clean
$(MAKE) -C libtokencap clean $(MAKE) -C libtokencap clean
$(MAKE) -C examples/afl_network_proxy clean $(MAKE) -C examples/afl_network_proxy clean
@ -530,20 +523,22 @@ clean:
$(MAKE) -C qemu_mode/libcompcov clean $(MAKE) -C qemu_mode/libcompcov clean
rm -rf qemu_mode/qemu-3.1.1 rm -rf qemu_mode/qemu-3.1.1
ifeq "$(IN_REPO)" "1" ifeq "$(IN_REPO)" "1"
test -e unicorn_mode/unicornafl/Makefile && $(MAKE) -C unicorn_mode/unicornafl clean || true test -d unicorn_mode/unicornafl && $(MAKE) -C unicorn_mode/unicornafl clean || true
else else
rm -rf qemu_mode/qemu-3.1.1.tar.xz rm -rf qemu_mode/qemu-3.1.1.tar.xz
rm -rf unicorn_mode/unicornafl rm -rf unicorn_mode/unicornafl
endif endif
.PHONY: deepclean
deepclean: clean deepclean: clean
rm -rf qemu_mode/qemu-3.1.1.tar.xz rm -rf qemu_mode/qemu-3.1.1.tar.xz
rm -rf unicorn_mode/unicornafl rm -rf unicorn_mode/unicornafl
git reset --hard >/dev/null 2>&1 || true git reset --hard >/dev/null 2>&1 || true
.PHONY: distrib
distrib: all distrib: all
-$(MAKE) -C llvm_mode -$(MAKE) -f GNUmakefile.llvm
-$(MAKE) -C gcc_plugin -$(MAKE) -f GNUmakefile.gcc_plugin
$(MAKE) -C libdislocator $(MAKE) -C libdislocator
$(MAKE) -C libtokencap $(MAKE) -C libtokencap
$(MAKE) -C examples/afl_network_proxy $(MAKE) -C examples/afl_network_proxy
@ -552,6 +547,7 @@ distrib: all
-cd qemu_mode && sh ./build_qemu_support.sh -cd qemu_mode && sh ./build_qemu_support.sh
cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh
.PHONY: binary-only
binary-only: all binary-only: all
$(MAKE) -C libdislocator $(MAKE) -C libdislocator
$(MAKE) -C libtokencap $(MAKE) -C libtokencap
@ -561,9 +557,10 @@ binary-only: all
-cd qemu_mode && sh ./build_qemu_support.sh -cd qemu_mode && sh ./build_qemu_support.sh
cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh
.PHONY: source-only
source-only: all source-only: all
-$(MAKE) -C llvm_mode -$(MAKE) -f GNUmakefile.llvm
-$(MAKE) -C gcc_plugin -$(MAKE) -f GNUmakefile.gcc_plugin
$(MAKE) -C libdislocator $(MAKE) -C libdislocator
$(MAKE) -C libtokencap $(MAKE) -C libtokencap
@#$(MAKE) -C examples/afl_network_proxy @#$(MAKE) -C examples/afl_network_proxy
@ -573,8 +570,7 @@ source-only: all
%.8: % %.8: %
@echo .TH $* 8 $(BUILD_DATE) "afl++" > $@ @echo .TH $* 8 $(BUILD_DATE) "afl++" > $@
@echo .SH NAME >> $@ @echo .SH NAME >> $@
@printf "%s" ".B $* \- " >> $@ @echo .B $* >> $@
@./$* -h 2>&1 | head -n 1 | sed -e "s/$$(printf '\e')[^m]*m//g" >> $@
@echo >> $@ @echo >> $@
@echo .SH SYNOPSIS >> $@ @echo .SH SYNOPSIS >> $@
@./$* -h 2>&1 | head -n 3 | tail -n 1 | sed 's/^\.\///' >> $@ @./$* -h 2>&1 | head -n 3 | tail -n 1 | sed 's/^\.\///' >> $@
@ -590,30 +586,28 @@ source-only: all
@echo .SH LICENSE >> $@ @echo .SH LICENSE >> $@
@echo Apache License Version 2.0, January 2004 >> $@ @echo Apache License Version 2.0, January 2004 >> $@
.PHONY: install
install: all $(MANPAGES) install: all $(MANPAGES)
install -d -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH) @install -d -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH)
rm -f $${DESTDIR}$(BIN_PATH)/afl-plot.sh @rm -f $${DESTDIR}$(BIN_PATH)/afl-plot.sh
@rm -f $${DESTDIR}$(BIN_PATH)/afl-as
install -m 755 $(PROGS) $(SH_PROGS) $${DESTDIR}$(BIN_PATH) 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-qemu-trace ]; then install -m 755 afl-qemu-trace $${DESTDIR}$(BIN_PATH); fi @if [ -f libdislocator.so ]; then set -e; install -m 755 libdislocator.so $${DESTDIR}$(HELPER_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 @if [ -f libtokencap.so ]; then set -e; install -m 755 libtokencap.so $${DESTDIR}$(HELPER_PATH); fi
if [ -f afl-clang-fast ]; then $(MAKE) -C llvm_mode install; fi @if [ -f libcompcov.so ]; then set -e; install -m 755 libcompcov.so $${DESTDIR}$(HELPER_PATH); fi
if [ -f libdislocator.so ]; then set -e; install -m 755 libdislocator.so $${DESTDIR}$(HELPER_PATH); fi @if [ -f afl-fuzz-document ]; then set -e; install -m 755 afl-fuzz-document $${DESTDIR}$(BIN_PATH); fi
if [ -f libtokencap.so ]; then set -e; install -m 755 libtokencap.so $${DESTDIR}$(HELPER_PATH); fi @if [ -f socketfuzz32.so -o -f socketfuzz64.so ]; then $(MAKE) -C examples/socket_fuzzing install; fi
if [ -f libcompcov.so ]; then set -e; install -m 755 libcompcov.so $${DESTDIR}$(HELPER_PATH); fi @if [ -f argvfuzz32.so -o -f argvfuzz64.so ]; then $(MAKE) -C examples/argv_fuzzing install; fi
if [ -f afl-fuzz-document ]; then set -e; install -m 755 afl-fuzz-document $${DESTDIR}$(BIN_PATH); fi @if [ -f examples/afl_network_proxy/afl-network-server ]; then $(MAKE) -C examples/afl_network_proxy install; fi
if [ -f socketfuzz32.so -o -f socketfuzz64.so ]; then $(MAKE) -C examples/socket_fuzzing install; fi @if [ -f examples/aflpp_driver/libAFLDriver.a ]; then install -m 644 examples/aflpp_driver/libAFLDriver.a $${DESTDIR}$(HELPER_PATH); fi
if [ -f argvfuzz32.so -o -f argvfuzz64.so ]; then $(MAKE) -C examples/argv_fuzzing install; fi @if [ -f examples/aflpp_driver/libAFLQemuDriver.a ]; then install -m 644 examples/aflpp_driver/libAFLQemuDriver.a $${DESTDIR}$(HELPER_PATH); fi
if [ -f examples/afl_network_proxy/afl-network-server ]; then $(MAKE) -C examples/afl_network_proxy install; fi -$(MAKE) -f GNUmakefile.llvm install
if [ -f libAFLDriver.a ]; then install -m 644 libAFLDriver.a $${DESTDIR}$(HELPER_PATH); fi -$(MAKE) -f GNUmakefile.gcc_plugin install
if [ -f libAFLQemuDriver.a ]; then install -m 644 libAFLQemuDriver.a $${DESTDIR}$(HELPER_PATH); fi ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-gcc
ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-g++
set -e; ln -sf afl-gcc $${DESTDIR}$(BIN_PATH)/afl-g++ @mkdir -m 0755 -p ${DESTDIR}$(MAN_PATH)
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 -m0644 *.8 ${DESTDIR}$(MAN_PATH)
install -m 755 afl-as $${DESTDIR}$(HELPER_PATH) install -m 755 afl-as $${DESTDIR}$(HELPER_PATH)
ln -sf afl-as $${DESTDIR}$(HELPER_PATH)/as ln -sf afl-as $${DESTDIR}$(HELPER_PATH)/as
install -m 644 docs/*.md $${DESTDIR}$(DOC_PATH) install -m 644 docs/*.md $${DESTDIR}$(DOC_PATH)

View File

@ -419,17 +419,14 @@ document:
./afl-compiler-rt.o: instrumentation/afl-compiler-rt.o.c | test_deps ./afl-compiler-rt.o: instrumentation/afl-compiler-rt.o.c | test_deps
$(CLANG_BIN) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -fPIC -c $< -o $@ $(CLANG_BIN) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -fPIC -c $< -o $@
ln -sf ./afl-compiler-rt.o ./afl-llvm-rt.o
./afl-compiler-rt-32.o: instrumentation/afl-compiler-rt.o.c | test_deps ./afl-compiler-rt-32.o: instrumentation/afl-compiler-rt.o.c | test_deps
@printf "[*] Building 32-bit variant of the runtime (-m32)... " @printf "[*] Building 32-bit variant of the runtime (-m32)... "
@$(CLANG_BIN) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi @$(CLANG_BIN) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
@test -e ./afl-compiler-rt-32.o && ln -sf ./afl-compiler-rt-32.o ./afl-llvm-rt-32.o
./afl-compiler-rt-64.o: instrumentation/afl-compiler-rt.o.c | test_deps ./afl-compiler-rt-64.o: instrumentation/afl-compiler-rt.o.c | test_deps
@printf "[*] Building 64-bit variant of the runtime (-m64)... " @printf "[*] Building 64-bit variant of the runtime (-m64)... "
@$(CLANG_BIN) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi @$(CLANG_BIN) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
@test -e ./afl-compiler-rt-64.o && ln -sf ./afl-compiler-rt-64.o ./afl-llvm-rt-64.o
.PHONY: test_build .PHONY: test_build
test_build: $(PROGS) test_build: $(PROGS)
@ -454,8 +451,8 @@ install: all
@if [ -f ./afl-compiler-rt.o ]; then set -e; install -m 755 ./afl-compiler-rt.o $${DESTDIR}$(HELPER_PATH); fi @if [ -f ./afl-compiler-rt.o ]; then set -e; install -m 755 ./afl-compiler-rt.o $${DESTDIR}$(HELPER_PATH); fi
@if [ -f ./afl-lto ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-lto; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-lto++; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto++; install -m 755 ./afl-llvm-lto-instrumentation.so ./afl-llvm-rt-lto*.o ./afl-llvm-lto-instrumentlist.so $${DESTDIR}$(HELPER_PATH); fi @if [ -f ./afl-lto ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-lto; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-lto++; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto++; install -m 755 ./afl-llvm-lto-instrumentation.so ./afl-llvm-rt-lto*.o ./afl-llvm-lto-instrumentlist.so $${DESTDIR}$(HELPER_PATH); fi
@if [ -f ./afl-ld-lto ]; then set -e; install -m 755 ./afl-ld-lto $${DESTDIR}$(BIN_PATH); fi @if [ -f ./afl-ld-lto ]; then set -e; install -m 755 ./afl-ld-lto $${DESTDIR}$(BIN_PATH); fi
@if [ -f ./afl-compiler-rt-32.o ]; then set -e; install -m 755 ./afl-compiler-rt-32.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-compiler-rt-32.o $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt-32.o; fi @if [ -f ./afl-compiler-rt-32.o ]; then set -e; install -m 755 ./afl-compiler-rt-32.o $${DESTDIR}$(HELPER_PATH); fi
@if [ -f ./afl-compiler-rt-64.o ]; then set -e; install -m 755 ./afl-compiler-rt-64.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-compiler-rt-64.o $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt-64.o; fi @if [ -f ./afl-compiler-rt-64.o ]; then set -e; install -m 755 ./afl-compiler-rt-64.o $${DESTDIR}$(HELPER_PATH); fi
@if [ -f ./compare-transform-pass.so ]; then set -e; install -m 755 ./*.so $${DESTDIR}$(HELPER_PATH); fi @if [ -f ./compare-transform-pass.so ]; then set -e; install -m 755 ./*.so $${DESTDIR}$(HELPER_PATH); fi
@if [ -f ./compare-transform-pass.so ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-fast ; ln -sf ./afl-c++ $${DESTDIR}$(BIN_PATH)/afl-clang-fast++ ; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf ./afl-c++ $${DESTDIR}$(BIN_PATH)/afl-clang++ ; fi @if [ -f ./compare-transform-pass.so ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-fast ; ln -sf ./afl-c++ $${DESTDIR}$(BIN_PATH)/afl-clang-fast++ ; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf ./afl-c++ $${DESTDIR}$(BIN_PATH)/afl-clang++ ; fi
@if [ -f ./SanitizerCoverageLTO.so ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto ; ln -sf ./afl-c++ $${DESTDIR}$(BIN_PATH)/afl-clang-lto++ ; fi @if [ -f ./SanitizerCoverageLTO.so ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto ; ln -sf ./afl-c++ $${DESTDIR}$(BIN_PATH)/afl-clang-lto++ ; fi

177
README.md
View File

@ -4,9 +4,9 @@
![Travis State](https://api.travis-ci.com/AFLplusplus/AFLplusplus.svg?branch=stable) ![Travis State](https://api.travis-ci.com/AFLplusplus/AFLplusplus.svg?branch=stable)
Release Version: [2.68c](https://github.com/AFLplusplus/AFLplusplus/releases) Release Version: [2.67c](https://github.com/AFLplusplus/AFLplusplus/releases)
Github Version: 3.00a Github Version: 2.67d
Repository: [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus) Repository: [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
@ -22,6 +22,26 @@
afl++ is a superior fork to Google's afl - more speed, more and better afl++ is a superior fork to Google's afl - more speed, more and better
mutations, more and better instrumentation, custom module support, etc. mutations, more and better instrumentation, custom module support, etc.
## Major changes in afl++ 3.0
With afl++ 3.0 we introduced changes that break some previous afl and afl++
behaviours:
* There are no llvm_mode and gcc_plugin subdirectories anymore and there is
only one compiler: afl-cc. All previous compilers now symlink to this one
compiler. All instrumentation source code is now in the `instrumentation/`
folder.
* qemu_mode got upgraded to QEMU 5.1, but to be able to build this a current
ninja build tool version and python3 setuptools are required.
qemu_mode also got new options like snapshotting, instrumenting specific
shared libraries, etc. and QEMU 5.1 supports more CPU targets so this is
worth it.
* When instrumenting targets, afl-cc will not supersede optimizations. This
allows to fuzz targets as same as they are built for debug or release.
* afl-fuzz' `-i` option now descends into subdirectories.
* afl-fuzz will skip over empty dictionaries and too large test cases instead
of failing.
## Contents ## Contents
1. [Features](#important-features-of-afl) 1. [Features](#important-features-of-afl)
@ -39,7 +59,7 @@
with laf-intel and redqueen, unicorn mode, gcc plugin, full *BSD, Solaris and with laf-intel and redqueen, unicorn mode, gcc plugin, full *BSD, Solaris and
Android support and much, much, much more. Android support and much, much, much more.
| Feature/Instrumentation | afl-gcc | llvm_mode | gcc_plugin | qemu_mode | unicorn_mode | | Feature/Instrumentation | afl-gcc | llvm | gcc_plugin | qemu_mode | unicorn_mode |
| -------------------------|:-------:|:---------:|:----------:|:----------------:|:------------:| | -------------------------|:-------:|:---------:|:----------:|:----------------:|:------------:|
| NeverZero | x86[_64]| x(1) | (2) | x | x | | NeverZero | x86[_64]| x(1) | (2) | x | x |
| Persistent Mode | | x | x | x86[_64]/arm[64] | x | | Persistent Mode | | x | x | x86[_64]/arm[64] | x |
@ -47,9 +67,8 @@
| CmpLog | | x | | x86[_64]/arm[64] | | | CmpLog | | x | | x86[_64]/arm[64] | |
| Selective Instrumentation| | x | x | (x)(3) | | | Selective Instrumentation| | x | x | (x)(3) | |
| Non-Colliding Coverage | | x(4) | | (x)(5) | | | Non-Colliding Coverage | | x(4) | | (x)(5) | |
| InsTrim | | x | | | |
| Ngram prev_loc Coverage | | x(6) | | | | | Ngram prev_loc Coverage | | x(6) | | | |
| Context Coverage | | x | | | | | Context Coverage | | x(6) | | | |
| Auto Dictionary | | x(7) | | | | | Auto Dictionary | | x(7) | | | |
| Snapshot LKM Support | | x | | (x)(5) | | | Snapshot LKM Support | | x | | (x)(5) | |
@ -59,11 +78,11 @@
4. with pcguard mode and LTO mode for LLVM >= 11 4. with pcguard mode and LTO mode for LLVM >= 11
5. upcoming, development in the branch 5. upcoming, development in the branch
6. not compatible with LTO instrumentation and needs at least LLVM >= 4.1 6. not compatible with LTO instrumentation and needs at least LLVM >= 4.1
7. only in LTO mode with LLVM >= 11 7. automatic in LTO mode with LLVM >= 11, an extra pass for all LLVM version that writes to a file to use with afl-fuzz' `-x`
Among others, the following features and patches have been integrated: Among others, the following features and patches have been integrated:
* NeverZero patch for afl-gcc, llvm_mode, qemu_mode and unicorn_mode which prevents a wrapping map value to zero, increases coverage * NeverZero patch for afl-gcc, instrumentation, qemu_mode and unicorn_mode which prevents a wrapping map value to zero, increases coverage
* Persistent mode, deferred forkserver and in-memory fuzzing for qemu_mode * Persistent mode, deferred forkserver and in-memory fuzzing for qemu_mode
* Unicorn mode which allows fuzzing of binaries from completely different platforms (integration provided by domenukk) * Unicorn mode which allows fuzzing of binaries from completely different platforms (integration provided by domenukk)
* The new CmpLog instrumentation for LLVM and QEMU inspired by [Redqueen](https://www.syssec.ruhr-uni-bochum.de/media/emma/veroeffentlichungen/2018/12/17/NDSS19-Redqueen.pdf) * The new CmpLog instrumentation for LLVM and QEMU inspired by [Redqueen](https://www.syssec.ruhr-uni-bochum.de/media/emma/veroeffentlichungen/2018/12/17/NDSS19-Redqueen.pdf)
@ -71,10 +90,9 @@
* AFLfast's power schedules by Marcel Böhme: [https://github.com/mboehme/aflfast](https://github.com/mboehme/aflfast) * AFLfast's power schedules by Marcel Böhme: [https://github.com/mboehme/aflfast](https://github.com/mboehme/aflfast)
* The MOpt mutator: [https://github.com/puppet-meteor/MOpt-AFL](https://github.com/puppet-meteor/MOpt-AFL) * The MOpt mutator: [https://github.com/puppet-meteor/MOpt-AFL](https://github.com/puppet-meteor/MOpt-AFL)
* LLVM mode Ngram coverage by Adrian Herrera [https://github.com/adrianherrera/afl-ngram-pass](https://github.com/adrianherrera/afl-ngram-pass) * LLVM mode Ngram coverage by Adrian Herrera [https://github.com/adrianherrera/afl-ngram-pass](https://github.com/adrianherrera/afl-ngram-pass)
* InsTrim, a CFG llvm_mode instrumentation implementation: [https://github.com/csienslab/instrim](https://github.com/csienslab/instrim)
* C. Holler's afl-fuzz Python mutator module: [https://github.com/choller/afl](https://github.com/choller/afl) * C. Holler's afl-fuzz Python mutator module: [https://github.com/choller/afl](https://github.com/choller/afl)
* Custom mutator by a library (instead of Python) by kyakdan * Custom mutator by a library (instead of Python) by kyakdan
* LAF-Intel/CompCov support for llvm_mode, qemu_mode and unicorn_mode (with enhanced capabilities) * LAF-Intel/CompCov support for instrumentation, qemu_mode and unicorn_mode (with enhanced capabilities)
* Radamsa and honggfuzz mutators (as custom mutators). * Radamsa and honggfuzz mutators (as custom mutators).
* QBDI mode to fuzz android native libraries via Quarkslab's [QBDI](https://github.com/QBDI/QBDI) framework * QBDI mode to fuzz android native libraries via Quarkslab's [QBDI](https://github.com/QBDI/QBDI) framework
* Frida and ptrace mode to fuzz binary-only libraries, etc. * Frida and ptrace mode to fuzz binary-only libraries, etc.
@ -88,7 +106,7 @@
send a mail to <afl-users+subscribe@googlegroups.com>. send a mail to <afl-users+subscribe@googlegroups.com>.
See [docs/QuickStartGuide.md](docs/QuickStartGuide.md) if you don't have time to See [docs/QuickStartGuide.md](docs/QuickStartGuide.md) if you don't have time to
read this file. read this file - however this is not recommended!
## Branches ## Branches
@ -105,13 +123,14 @@
## Help wanted ## Help wanted
We are happy to be part of [Google Summer of Code 2020](https://summerofcode.withgoogle.com/organizations/5100744400699392/)! :-) We were happy to be part of [Google Summer of Code 2020](https://summerofcode.withgoogle.com/organizations/5100744400699392/)
and we will try to participate again in 2021!
We have several ideas we would like to see in AFL++ to make it even better. We have several ideas we would like to see in AFL++ to make it even better.
However, we already work on so many things that we do not have the time for However, we already work on so many things that we do not have the time for
all the big ideas. all the big ideas.
This can be your way to support and contribute to AFL++ - extend it to This can be your way to support and contribute to AFL++ - extend it to do
something cool. something cool.
We have an idea list in [docs/ideas.md](docs/ideas.md). We have an idea list in [docs/ideas.md](docs/ideas.md).
@ -132,7 +151,7 @@ This image is automatically generated when a push to the stable repo happens.
You will find your target source code in /src in the container. You will find your target source code in /src in the container.
If you want to build afl++ yourself you have many options. If you want to build afl++ yourself you have many options.
The easiest is to build and install everything: The easiest choice is to build and install everything:
```shell ```shell
sudo apt install build-essential libtool-bin python3-dev automake flex bison libglib2.0-dev libpixman-1-dev clang python3-setuptools llvm sudo apt install build-essential libtool-bin python3-dev automake flex bison libglib2.0-dev libpixman-1-dev clang python3-setuptools llvm
@ -142,9 +161,9 @@ sudo make install
It is recommended to install the newest available gcc, clang and llvm-dev It is recommended to install the newest available gcc, clang and llvm-dev
possible in your distribution! possible in your distribution!
Note that "make distrib" also builds llvm_mode, qemu_mode, unicorn_mode and Note that "make distrib" also builds instrumentation, qemu_mode, unicorn_mode and
more. If you just want plain afl++ then do "make all", however compiling and more. If you just want plain afl++ then do "make all", however compiling and
using at least llvm_mode is highly recommended for much better results - using at least instrumentation is highly recommended for much better results -
hence in this case hence in this case
```shell ```shell
@ -156,7 +175,7 @@ These build targets exist:
* all: just the main afl++ binaries * all: just the main afl++ binaries
* binary-only: everything for binary-only fuzzing: qemu_mode, unicorn_mode, libdislocator, libtokencap * binary-only: everything for binary-only fuzzing: qemu_mode, unicorn_mode, libdislocator, libtokencap
* source-only: everything for source code fuzzing: llvm_mode, libdislocator, libtokencap * source-only: everything for source code fuzzing: instrumentation, libdislocator, libtokencap
* distrib: everything (for both binary-only and source code fuzzing) * distrib: everything (for both binary-only and source code fuzzing)
* man: creates simple man pages from the help option of the programs * man: creates simple man pages from the help option of the programs
* install: installs everything you have compiled with the build options above * install: installs everything you have compiled with the build options above
@ -212,18 +231,19 @@ If you have a binary-only target please skip to [#Instrumenting binary-only apps
Fuzzing source code is a three-step process. Fuzzing source code is a three-step process.
1. compile the target with a special compiler that prepares the target to be 1. Compile the target with a special compiler that prepares the target to be
fuzzed efficiently. This step is called "instrumenting a target". fuzzed efficiently. This step is called "instrumenting a target".
2. Prepare the fuzzing by selecting and optimizing the input corpus for the 2. Prepare the fuzzing by selecting and optimizing the input corpus for the
target. target.
3. perform the fuzzing of the target by randomly mutating input and assessing 3. Perform the fuzzing of the target by randomly mutating input and assessing
if a generated input was processed in a new path in the target binary. if a generated input was processed in a new path in the target binary.
### 1. Instrumenting that target ### 1. Instrumenting that target
#### a) Selecting the best afl++ compiler for instrumenting the target #### a) Selecting the best afl++ compiler for instrumenting the target
afl++ comes with different compilers and instrumentation options. afl++ comes with a central compiler `afl-cc` that incorporates various different
kinds of compiler targets and and instrumentation options.
The following evaluation flow will help you to select the best possible. The following evaluation flow will help you to select the best possible.
It is highly recommended to have the newest llvm version possible installed, It is highly recommended to have the newest llvm version possible installed,
@ -231,49 +251,62 @@ anything below 9 is not recommended.
``` ```
+--------------------------------+ +--------------------------------+
| clang/clang++ 11+ is available | --> use afl-clang-lto and afl-clang-lto++ | clang/clang++ 11+ is available | --> use LTO mode (afl-clang-lto/afl-clang-lto++)
+--------------------------------+ see [llvm/README.lto.md](llvm/README.lto.md) +--------------------------------+ see [instrumentation/README.lto.md](instrumentation/README.lto.md)
| |
| if not, or if the target fails with afl-clang-lto/++ | if not, or if the target fails with LTO afl-clang-lto/++
| |
v v
+---------------------------------+ +---------------------------------+
| clang/clang++ 3.3+ is available | --> use afl-clang-fast and afl-clang-fast++ | clang/clang++ 3.3+ is available | --> use LLVM mode (afl-clang-fast/afl-clang-fast++)
+---------------------------------+ see [llvm/README.md](llvm/README.md) +---------------------------------+ see [instrumentation/README.md](instrumentation/README.md)
| |
| if not, or if the target fails with afl-clang-fast/++ | if not, or if the target fails with LLVM afl-clang-fast/++
| |
v v
+--------------------------------+ +--------------------------------+
| if you want to instrument only | -> use afl-gcc-fast and afl-gcc-fast++ | if you want to instrument only | -> use GCC_PLUGIN mode (afl-gcc-fast/afl-g++-fast)
| parts of the target | see [gcc_plugin/README.md](gcc_plugin/README.md) and | parts of the target | see [instrumentation/README.gcc_plugin.md](instrumentation/README.gcc_plugin.md) and
+--------------------------------+ [gcc_plugin/README.instrument_list.md](gcc_plugin/README.instrument_list.md) +--------------------------------+ [instrumentation/README.instrument_list.md](instrumentation/README.instrument_list.md)
| |
| if not, or if you do not have a gcc with plugin support | if not, or if you do not have a gcc with plugin support
| |
v v
use afl-gcc and afl-g++ (or afl-clang and afl-clang++) use GCC mode (afl-gcc/afl-g++) (or afl-clang/afl-clang++ for clang)
``` ```
Clickable README links for the chosen compiler: Clickable README links for the chosen compiler:
* [afl-clang-lto](llvm/README.lto.md) * [LTO mode - afl-clang-lto](instrumentation/README.lto.md)
* [afl-clang-fast](llvm/README.md) * [LLVM mode - afl-clang-fast](instrumentation/README.md)
* [afl-gcc-fast](gcc_plugin/README.md) * [GCC_PLUGIN mode - afl-gcc-fast](instrumentation/README.gcc_plugin.md)
* afl-gcc has no README as it has no features * GCC mode (afl-gcc) has no README as it has no own features
You can select the mode for the afl-cc compiler by:
1. passing --afl-MODE command line options to the compiler via CFLAGS/CXXFLAGS/CPPFLAGS
2. use a symlink to afl-cc: afl-gcc, afl-g++, afl-clang, afl-clang++,
afl-clang-fast, afl-clang-fast++, afl-clang-lto, afl-clang-lto++,
afl-gcc-fast, afl-g++-fast
3. using the environment variable AFL_CC_COMPILER with MODE
MODE can be one of: LTO (afl-clang-lto*), LLVM (afl-clang-fast*), GCC_PLUGIN
(afl-g*-fast) or GCC (afl-gcc/afl-g++).
Because no afl specific command-line options are accepted (beside the
--afl-MODE command), the compile-time tools make fairly broad use of environment
variables, which can be listed with `afl-cc -hh` or by reading [docs/env_variables.md](docs/env_variables.md).
#### b) Selecting instrumentation options #### b) Selecting instrumentation options
The following options are available when you instrument with afl-clang-fast or The following options are available when you instrument with LTO mode (afl-clang-fast/afl-clang-lto):
afl-clang-lto:
* Splitting integer, string, float and switch comparisons so afl++ can easier * Splitting integer, string, float and switch comparisons so afl++ can easier
solve these. This is an important option if you do not have a very good solve these. This is an important option if you do not have a very good
and large input corpus. This technique is called laf-intel or COMPCOV. and large input corpus. This technique is called laf-intel or COMPCOV.
To use this set the following environment variable before compiling the To use this set the following environment variable before compiling the
target: `export AFL_LLVM_LAF_ALL=1` target: `export AFL_LLVM_LAF_ALL=1`
You can read more about this in [llvm/README.laf-intel.md](llvm/README.laf-intel.md) You can read more about this in [instrumentation/README.laf-intel.md](instrumentation/README.laf-intel.md)
* A different technique (and usually a better than laf-intel) is to * A different technique (and usually a better one than laf-intel) is to
instrument the target so that any compare values in the target are sent to instrument the target so that any compare values in the target are sent to
afl++ which then tries to put these values into the fuzzing data at different afl++ which then tries to put these values into the fuzzing data at different
locations. This technique is very fast and good - if the target does not locations. This technique is very fast and good - if the target does not
@ -282,12 +315,13 @@ afl-clang-lto:
If you want to use this technique, then you have to compile the target If you want to use this technique, then you have to compile the target
twice, once specifically with/for this mode, and pass this binary to afl-fuzz twice, once specifically with/for this mode, and pass this binary to afl-fuzz
via the `-c` parameter. via the `-c` parameter.
Not that you can compile also just a cmplog binary and use that for both Note that you can compile also just a cmplog binary and use that for both
however there will a performance penality. however there will be a performance penality.
You can read more about this in [llvm_mode/README.cmplog.md](llvm_mode/README.cmplog.md) You can read more about this in [instrumentation/README.cmplog.md](instrumentation/README.cmplog.md)
If you use afl-clang-fast, afl-clang-lto or afl-gcc-fast you have the option to If you use LTO, LLVM or GCC_PLUGIN mode (afl-clang-fast/afl-clang-lto/afl-gcc-fast)
selectively only instrument parts of the target that you are interested in: you have the option to selectively only instrument parts of the target that you
are interested in:
* To instrument only those parts of the target that you are interested in * To instrument only those parts of the target that you are interested in
create a file with all the filenames of the source code that should be create a file with all the filenames of the source code that should be
@ -299,29 +333,29 @@ selectively only instrument parts of the target that you are interested in:
`export AFL_LLVM_DENYLIST=denylist.txt` - depending on if you want per `export AFL_LLVM_DENYLIST=denylist.txt` - depending on if you want per
default to instrument unless noted (DENYLIST) or not perform instrumentation default to instrument unless noted (DENYLIST) or not perform instrumentation
unless requested (ALLOWLIST). unless requested (ALLOWLIST).
**NOTE:** In optimization functions might be inlined and then not match! **NOTE:** During optimization functions might be inlined and then would not match!
see [llvm_mode/README.instrument_list.md](llvm_mode/README.instrument_list.md) See [instrumentation/README.instrument_list.md](instrumentation/README.instrument_list.md)
For afl-clang-fast > 6.0 or if PCGUARD instrumentation is used then use the For afl-clang-fast > 6.0 or if PCGUARD instrumentation is used then use the
llvm sancov allow-list feature: [http://clang.llvm.org/docs/SanitizerCoverage.html](http://clang.llvm.org/docs/SanitizerCoverage.html) llvm sancov allow-list feature: [http://clang.llvm.org/docs/SanitizerCoverage.html](http://clang.llvm.org/docs/SanitizerCoverage.html)
The llvm sancov format works with the allowlist/denylist feature of afl++ The llvm sancov format works with the allowlist/denylist feature of afl++
however afl++ is more flexible in the format. however afl++'s format is more flexible.
There are many more options and modes available however these are most of the There are many more options and modes available however these are most of the
time less effective. See: time less effective. See:
* [llvm_mode/README.ctx.md](llvm_mode/README.ctx.md) * [instrumentation/README.ctx.md](instrumentation/README.ctx.md)
* [llvm_mode/README.ngram.md](llvm_mode/README.ngram.md) * [instrumentation/README.ngram.md](instrumentation/README.ngram.md)
* [llvm_mode/README.instrim.md](llvm_mode/README.instrim.md) * [instrumentation/README.instrim.md](instrumentation/README.instrim.md)
afl++ employs never zero counting in its bitmap. You can read more about this afl++ performs "never zero" counting in its bitmap. You can read more about this
here: here:
* [llvm_mode/README.neverzero.md](llvm_mode/README.neverzero.md) * [instrumentation/README.neverzero.md](instrumentation/README.neverzero.md)
#### c) Modify the target #### c) Modify the target
If the target has features that make fuzzing more difficult, e.g. If the target has features that make fuzzing more difficult, e.g.
checksums, HMAC, etc. then modify the source code so that this is checksums, HMAC, etc. then modify the source code so that this is
removed. removed.
This can even be done for productional source code be eliminating This can even be done for operational source code by eliminating
these checks within this specific defines: these checks within this specific defines:
``` ```
@ -332,13 +366,15 @@ these checks within this specific defines:
#endif #endif
``` ```
All afl++ compilers will set this preprocessor definition automatically.
#### d) Instrument the target #### d) Instrument the target
In this step the target source code is compiled so that it can be fuzzed. In this step the target source code is compiled so that it can be fuzzed.
Basically you have to tell the target build system that the selected afl++ Basically you have to tell the target build system that the selected afl++
compiler is used. Also - if possible - you should always configure the compiler is used. Also - if possible - you should always configure the
build system that the target is compiled statically and not dynamically. build system such that the target is compiled statically and not dynamically.
How to do this is described below. How to do this is described below.
Then build the target. (Usually with `make`) Then build the target. (Usually with `make`)
@ -349,20 +385,22 @@ For `configure` build systems this is usually done by:
`CC=afl-clang-fast CXX=afl-clang-fast++ ./configure --disable-shared` `CC=afl-clang-fast CXX=afl-clang-fast++ ./configure --disable-shared`
Note that if you are using the (better) afl-clang-lto compiler you also have to Note that if you are using the (better) afl-clang-lto compiler you also have to
set AR to llvm-ar[-VERSION] and RANLIB to llvm-ranlib[-VERSION] - as it is set AR to llvm-ar[-VERSION] and RANLIB to llvm-ranlib[-VERSION] - as is
described in [llvm/README.lto.md](llvm/README.lto.md) described in [instrumentation/README.lto.md](instrumentation/README.lto.md).
##### cmake ##### cmake
For `configure` build systems this is usually done by: For `cmake` build systems this is usually done by:
`mkdir build; cd build; CC=afl-clang-fast CXX=afl-clang-fast++ cmake ..` `mkdir build; cmake -DCMAKE_C_COMPILERC=afl-cc -DCMAKE_CXX_COMPILER=afl-c++ ..`
Some cmake scripts require something like `-DCMAKE_CC=... -DCMAKE_CXX=...`
or `-DCMAKE_C_COMPILER=... DCMAKE_CPP_COMPILER=...` instead.
Note that if you are using the (better) afl-clang-lto compiler you also have to Note that if you are using the (better) afl-clang-lto compiler you also have to
set AR to llvm-ar[-VERSION] and RANLIB to llvm-ranlib[-VERSION] - as it is set AR to llvm-ar[-VERSION] and RANLIB to llvm-ranlib[-VERSION] - as is
described in [llvm/README.lto.md](llvm/README.lto.md) described in [instrumentation/README.lto.md](instrumentation/README.lto.md).
##### meson
For meson you have to set the afl++ compiler with the very first command!
`CC=afl-cc CXX=afl-c++ meson`
##### other build systems or if configure/cmake didn't work ##### other build systems or if configure/cmake didn't work
@ -370,7 +408,7 @@ Sometimes cmake and configure do not pick up the afl++ compiler, or the
ranlib/ar that is needed - because this was just not foreseen by the developer ranlib/ar that is needed - because this was just not foreseen by the developer
of the target. Or they have non-standard options. Figure out if there is a of the target. Or they have non-standard options. Figure out if there is a
non-standard way to set this, otherwise set up the build normally and edit the non-standard way to set this, otherwise set up the build normally and edit the
generated build environment afterwards manually to point to the right compiler generated build environment afterwards manually to point it to the right compiler
(and/or ranlib and ar). (and/or ranlib and ar).
#### d) Better instrumentation #### d) Better instrumentation
@ -383,12 +421,12 @@ This requires the usage of afl-clang-lto or afl-clang-fast.
This is the so-called `persistent mode`, which is much, much faster but This is the so-called `persistent mode`, which is much, much faster but
requires that you code a source file that is specifically calling the target requires that you code a source file that is specifically calling the target
functions that you want to fuzz, plus a few specific afl++ functions around functions that you want to fuzz, plus a few specific afl++ functions around
it. See [llvm_mode/README.persistent_mode.md](llvm_mode/README.persistent_mode.md) for details. it. See [instrumentation/README.persistent_mode.md](instrumentation/README.persistent_mode.md) for details.
Basically if you do not fuzz a target in persistent mode then you are just Basically if you do not fuzz a target in persistent mode then you are just
doing it for a hobby and not professionally :-) doing it for a hobby and not professionally :-)
### 2. Preparing the fuzzing ### 2. Preparing the fuzzing campaign
As you fuzz the target with mutated input, having as diverse inputs for the As you fuzz the target with mutated input, having as diverse inputs for the
target as possible improves the efficiency a lot. target as possible improves the efficiency a lot.
@ -401,7 +439,7 @@ reported bugs, test suites, random downloads from the internet, unit test
case data - from all kind of PNG software. case data - from all kind of PNG software.
If the input format is not known, you can also modify a target program to write If the input format is not known, you can also modify a target program to write
away normal data it receives and processes to a file and use these. normal data it receives and processes to a file and use these.
#### b) Making the input corpus unique #### b) Making the input corpus unique
@ -432,7 +470,7 @@ for i in *; do
done done
``` ```
This can also be parallelized, e.g. with `parallel` This step can also be parallelized, e.g. with `parallel`
#### Done! #### Done!
@ -456,7 +494,7 @@ before the start of afl-fuzz as this improves performance by a x2 speed increase
#### a) Running afl-fuzz #### a) Running afl-fuzz
Before to do even a test run of afl-fuzz execute `sudo afl-system-config` (on Before you do even a test run of afl-fuzz execute `sudo afl-system-config` (on
the host if you execute afl-fuzz in a docker container). This reconfigures the the host if you execute afl-fuzz in a docker container). This reconfigures the
system for optimal speed - which afl-fuzz checks and bails otherwise. system for optimal speed - which afl-fuzz checks and bails otherwise.
Set `export AFL_SKIP_CPUFREQ=1` for afl-fuzz to skip this check if you cannot Set `export AFL_SKIP_CPUFREQ=1` for afl-fuzz to skip this check if you cannot
@ -588,7 +626,7 @@ then terminate it. The main node will pick it up and make it available to the
other secondary nodes over time. Set `export AFL_NO_AFFINITY=1` if you have no other secondary nodes over time. Set `export AFL_NO_AFFINITY=1` if you have no
free core. free core.
Note that you in nearly all cases you can never reach full coverage. A lot of Note that you in nearly all cases can never reach full coverage. A lot of
functionality is usually behind options that were not activated or fuzz e.g. functionality is usually behind options that were not activated or fuzz e.g.
if you fuzz a library to convert image formats and your target is the png to if you fuzz a library to convert image formats and your target is the png to
tiff API then you will not touch any of the other library APIs and features. tiff API then you will not touch any of the other library APIs and features.
@ -607,7 +645,7 @@ switch or honggfuzz.
#### f) Improve the speed! #### f) Improve the speed!
* Use [persistent mode](llvm_mode/README.persistent_mode.md) (x2-x20 speed increase) * Use [persistent mode](instrumentation/README.persistent_mode.md) (x2-x20 speed increase)
* If you do not use shmem persistent mode, use `AFL_TMPDIR` to point the input file on a tempfs location, see [docs/env_variables.md](docs/env_variables.md) * If you do not use shmem persistent mode, use `AFL_TMPDIR` to point the input file on a tempfs location, see [docs/env_variables.md](docs/env_variables.md)
* Linux: Use the [afl++ snapshot module](https://github.com/AFLplusplus/AFL-Snapshot-LKM) (x2 speed increase) * Linux: Use the [afl++ snapshot module](https://github.com/AFLplusplus/AFL-Snapshot-LKM) (x2 speed increase)
* Linux: Improve kernel performance: modify `/etc/default/grub`, set `GRUB_CMDLINE_LINUX_DEFAULT="ibpb=off ibrs=off kpti=off l1tf=off mds=off mitigations=off no_stf_barrier noibpb noibrs nopcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=off pti=off spec_store_bypass_disable=off spectre_v2=off stf_barrier=off"`; then `update-grub` and `reboot` (warning: makes the system more insecure) * Linux: Improve kernel performance: modify `/etc/default/grub`, set `GRUB_CMDLINE_LINUX_DEFAULT="ibpb=off ibrs=off kpti=off l1tf=off mds=off mitigations=off no_stf_barrier noibpb noibrs nopcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=off pti=off spec_store_bypass_disable=off spectre_v2=off stf_barrier=off"`; then `update-grub` and `reboot` (warning: makes the system more insecure)
@ -1035,7 +1073,6 @@ without feedback, bug reports, or patches from:
Andrea Biondo Vincent Le Garrec Andrea Biondo Vincent Le Garrec
Khaled Yakdan Kuang-che Wu Khaled Yakdan Kuang-che Wu
Josephine Calliotte Konrad Welc Josephine Calliotte Konrad Welc
Thomas Rooijakkers
``` ```
Thank you! Thank you!

View File

@ -162,8 +162,7 @@ struct queue_entry {
u8 *trace_mini; /* Trace bytes, if kept */ u8 *trace_mini; /* Trace bytes, if kept */
u32 tc_ref; /* Trace bytes ref count */ u32 tc_ref; /* Trace bytes ref count */
struct queue_entry *next, /* Next element, if any */ struct queue_entry *next; /* Next element, if any */
*next_100; /* 100 elements ahead */
}; };
@ -575,8 +574,7 @@ typedef struct afl_state {
struct queue_entry *queue, /* Fuzzing queue (linked list) */ struct queue_entry *queue, /* Fuzzing queue (linked list) */
*queue_cur, /* Current offset within the queue */ *queue_cur, /* Current offset within the queue */
*queue_top, /* Top of the list */ *queue_top; /* Top of the list */
*q_prev100; /* Previous 100 marker */
// growing buf // growing buf
struct queue_entry **queue_buf; struct queue_entry **queue_buf;

View File

@ -101,7 +101,8 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len,
if (rptr < lptr || *rptr != '"') { if (rptr < lptr || *rptr != '"') {
FATAL("Malformed name=\"value\" pair in line %u.", cur_line); WARNF("Malformed name=\"value\" pair in line %u.", cur_line);
continue;
} }
@ -141,13 +142,19 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len,
if (*lptr != '"') { if (*lptr != '"') {
FATAL("Malformed name=\"keyword\" pair in line %u.", cur_line); WARNF("Malformed name=\"keyword\" pair in line %u.", cur_line);
continue;
} }
++lptr; ++lptr;
if (!*lptr) { FATAL("Empty keyword in line %u.", cur_line); } if (!*lptr) {
WARNF("Empty keyword in line %u.", cur_line);
continue;
}
/* Okay, let's allocate memory and copy data between "...", handling /* Okay, let's allocate memory and copy data between "...", handling
\xNN escaping, \\, and \". */ \xNN escaping, \\, and \". */
@ -169,7 +176,9 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len,
case 1 ... 31: case 1 ... 31:
case 128 ... 255: case 128 ... 255:
FATAL("Non-printable characters in line %u.", cur_line); WARNF("Non-printable characters in line %u.", cur_line);
continue;
break;
case '\\': case '\\':
@ -185,7 +194,8 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len,
if (*lptr != 'x' || !isxdigit(lptr[1]) || !isxdigit(lptr[2])) { if (*lptr != 'x' || !isxdigit(lptr[1]) || !isxdigit(lptr[2])) {
FATAL("Invalid escaping (not \\xNN) in line %u.", cur_line); WARNF("Invalid escaping (not \\xNN) in line %u.", cur_line);
continue;
} }
@ -209,10 +219,11 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len,
if (afl->extras[afl->extras_cnt].len > MAX_DICT_FILE) { if (afl->extras[afl->extras_cnt].len > MAX_DICT_FILE) {
FATAL( WARNF(
"Keyword too big in line %u (%s, limit is %s)", cur_line, "Keyword too big in line %u (%s, limit is %s)", cur_line,
stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), klen), stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), klen),
stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE)); stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE));
continue;
} }
@ -232,12 +243,17 @@ static void extras_check_and_sort(afl_state_t *afl, u32 min_len, u32 max_len,
u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX]; u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX];
if (!afl->extras_cnt) { FATAL("No usable files in '%s'", dir); } if (!afl->extras_cnt) {
WARNF("No usable data in '%s'", dir);
return;
}
qsort(afl->extras, afl->extras_cnt, sizeof(struct extra_data), qsort(afl->extras, afl->extras_cnt, sizeof(struct extra_data),
compare_extras_len); compare_extras_len);
OKF("Loaded %u extra tokens, size range %s to %s.", afl->extras_cnt, ACTF("Loaded %u extra tokens, size range %s to %s.", afl->extras_cnt,
stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), min_len), stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), min_len),
stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), max_len)); stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), max_len));
@ -250,7 +266,7 @@ static void extras_check_and_sort(afl_state_t *afl, u32 min_len, u32 max_len,
if (afl->extras_cnt > afl->max_det_extras) { if (afl->extras_cnt > afl->max_det_extras) {
OKF("More than %d tokens - will use them probabilistically.", WARNF("More than %d tokens - will use them probabilistically.",
afl->max_det_extras); afl->max_det_extras);
} }
@ -320,9 +336,10 @@ void load_extras(afl_state_t *afl, u8 *dir) {
if (st.st_size > MAX_DICT_FILE) { if (st.st_size > MAX_DICT_FILE) {
WARNF( WARNF(
"Extra '%s' is very big (%s, limit is %s)", fn, "Extra '%s' is too big (%s, limit is %s)", fn,
stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), st.st_size), stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), st.st_size),
stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE)); stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE));
continue;
} }
@ -370,16 +387,74 @@ static inline u8 memcmp_nocase(u8 *m1, u8 *m2, u32 len) {
} }
/* Adds a new extra / dict entry. Used for LTO autodict. */ /* Removes duplicates from the loaded extras. This can happen if multiple files
are loaded */
void dedup_extras(afl_state_t *afl) {
if (afl->extras_cnt < 2) return;
u32 i, j, orig_cnt = afl->extras_cnt;
for (i = 0; i < afl->extras_cnt - 1; i++) {
for (j = i + 1; j < afl->extras_cnt; j++) {
restart_dedup:
// if the goto was used we could be at the end of the list
if (j >= afl->extras_cnt || afl->extras[i].len != afl->extras[j].len)
break;
if (memcmp(afl->extras[i].data, afl->extras[j].data,
afl->extras[i].len) == 0) {
ck_free(afl->extras[j].data);
if (j + 1 < afl->extras_cnt) // not at the end of the list?
memmove((char *)&afl->extras[j], (char *)&afl->extras[j + 1],
(afl->extras_cnt - j - 1) * sizeof(struct extra_data));
afl->extras_cnt--;
goto restart_dedup; // restart if several duplicates are in a row
}
}
}
if (afl->extras_cnt != orig_cnt)
afl->extras = afl_realloc((void **)&afl->extras,
afl->extras_cnt * sizeof(struct extra_data));
}
/* Adds a new extra / dict entry. */
void add_extra(afl_state_t *afl, u8 *mem, u32 len) { void add_extra(afl_state_t *afl, u8 *mem, u32 len) {
u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX]; u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX];
u32 i, found = 0;
for (i = 0; i < afl->extras_cnt; i++) {
if (afl->extras[i].len == len) {
if (memcmp(afl->extras[i].data, mem, len) == 0) return;
found = 1;
} else {
if (found) break;
}
}
if (len > MAX_DICT_FILE) { if (len > MAX_DICT_FILE) {
WARNF("Extra '%.*s' is very big (%s, limit is %s)", (int)len, mem, WARNF("Extra '%.*s' is too big (%s, limit is %s)", (int)len, mem,
stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), len), stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), len),
stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE)); stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE));
return;
} else if (len > 32) { } else if (len > 32) {
@ -405,7 +480,7 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) {
if (afl->extras_cnt == afl->max_det_extras + 1) { if (afl->extras_cnt == afl->max_det_extras + 1) {
OKF("More than %d tokens - will use them probabilistically.", WARNF("More than %d tokens - will use them probabilistically.",
afl->max_det_extras); afl->max_det_extras);
} }
@ -609,7 +684,7 @@ void load_auto(afl_state_t *afl) {
} else { } else {
OKF("No auto-generated dictionary tokens to reuse."); ACTF("No auto-generated dictionary tokens to reuse.");
} }

View File

@ -611,17 +611,17 @@ void read_foreign_testcases(afl_state_t *afl, int first) {
/* Read all testcases from the input directory, then queue them for testing. /* Read all testcases from the input directory, then queue them for testing.
Called at startup. */ Called at startup. */
void read_testcases(afl_state_t *afl) { void read_testcases(afl_state_t *afl, u8 *directory) {
struct dirent **nl; struct dirent **nl;
s32 nl_cnt; s32 nl_cnt, subdirs = 1;
u32 i; u32 i;
u8 * fn1; u8 * fn1, *dir = directory;
u8 val_buf[2][STRINGIFY_VAL_SIZE_MAX]; u8 val_buf[2][STRINGIFY_VAL_SIZE_MAX];
/* Auto-detect non-in-place resumption attempts. */ /* Auto-detect non-in-place resumption attempts. */
if (dir == NULL) {
fn1 = alloc_printf("%s/queue", afl->in_dir); fn1 = alloc_printf("%s/queue", afl->in_dir);
if (!access(fn1, F_OK)) { if (!access(fn1, F_OK)) {
@ -632,16 +632,18 @@ void read_testcases(afl_state_t *afl) {
ck_free(fn1); ck_free(fn1);
} }
dir = afl->in_dir;
}
ACTF("Scanning '%s'...", afl->in_dir); ACTF("Scanning '%s'...", dir);
/* We use scandir() + alphasort() rather than readdir() because otherwise, /* We use scandir() + alphasort() rather than readdir() because otherwise,
the ordering of test cases would vary somewhat randomly and would be the ordering of test cases would vary somewhat randomly and would be
difficult to control. */ difficult to control. */
nl_cnt = scandir(afl->in_dir, &nl, NULL, alphasort); nl_cnt = scandir(dir, &nl, NULL, alphasort);
if (nl_cnt < 0) { if (nl_cnt < 0 && directory == NULL) {
if (errno == ENOENT || errno == ENOTDIR) { if (errno == ENOENT || errno == ENOTDIR) {
@ -656,7 +658,7 @@ void read_testcases(afl_state_t *afl) {
} }
PFATAL("Unable to open '%s'", afl->in_dir); PFATAL("Unable to open '%s'", dir);
} }
@ -674,19 +676,29 @@ void read_testcases(afl_state_t *afl) {
u8 dfn[PATH_MAX]; u8 dfn[PATH_MAX];
snprintf(dfn, PATH_MAX, "%s/.state/deterministic_done/%s", afl->in_dir, snprintf(dfn, PATH_MAX, "%s/.state/deterministic_done/%s", afl->in_dir,
nl[i]->d_name); nl[i]->d_name);
u8 *fn2 = alloc_printf("%s/%s", afl->in_dir, nl[i]->d_name); u8 *fn2 = alloc_printf("%s/%s", dir, nl[i]->d_name);
u8 passed_det = 0; u8 passed_det = 0;
free(nl[i]); /* not tracked */
if (lstat(fn2, &st) || access(fn2, R_OK)) { if (lstat(fn2, &st) || access(fn2, R_OK)) {
PFATAL("Unable to access '%s'", fn2); PFATAL("Unable to access '%s'", fn2);
} }
/* This also takes care of . and .. */ /* obviously we want to skip "descending" into . and .. directories,
however it is a good idea to skip also directories that start with
a dot */
if (subdirs && S_ISDIR(st.st_mode) && nl[i]->d_name[0] != '.') {
free(nl[i]); /* not tracked */
read_testcases(afl, fn2);
ck_free(fn2);
continue;
}
free(nl[i]);
if (!S_ISREG(st.st_mode) || !st.st_size || strstr(fn2, "/README.txt")) { if (!S_ISREG(st.st_mode) || !st.st_size || strstr(fn2, "/README.txt")) {
@ -718,7 +730,7 @@ void read_testcases(afl_state_t *afl) {
free(nl); /* not tracked */ free(nl); /* not tracked */
if (!afl->queued_paths) { if (!afl->queued_paths && directory == NULL) {
SAYF("\n" cLRD "[-] " cRST SAYF("\n" cLRD "[-] " cRST
"Looks like there are no valid test cases in the input directory! The " "Looks like there are no valid test cases in the input directory! The "
@ -985,6 +997,76 @@ void perform_dry_run(afl_state_t *afl) {
} }
/* Now we remove all entries from the queue that have a duplicate trace map */
q = afl->queue;
struct queue_entry *p, *prev = NULL;
int duplicates = 0;
restart_outer_cull_loop:
while (q) {
if (q->cal_failed || !q->exec_cksum) continue;
restart_inner_cull_loop:
p = q->next;
while (p) {
if (!p->cal_failed && p->exec_cksum == q->exec_cksum) {
duplicates = 1;
--afl->pending_not_fuzzed;
// We do not remove any of the memory allocated because for
// splicing the data might still be interesting.
// We only decouple them from the linked list.
// This will result in some leaks at exit, but who cares.
// we keep the shorter file
if (p->len >= q->len) {
q->next = p->next;
goto restart_inner_cull_loop;
} else {
if (prev)
prev->next = q = p;
else
afl->queue = q = p;
goto restart_outer_cull_loop;
}
}
p = p->next;
}
prev = q;
q = q->next;
}
if (duplicates) {
afl->max_depth = 0;
q = afl->queue;
while (q) {
if (q->depth > afl->max_depth) afl->max_depth = q->depth;
q = q->next;
}
afl->q_prev100 = afl->queue = afl->queue_top = afl->queue;
}
OKF("All test cases processed."); OKF("All test cases processed.");
} }

View File

@ -1707,20 +1707,8 @@ custom_mutator_stage:
} while (tid == afl->current_entry && afl->queued_paths > 1); } while (tid == afl->current_entry && afl->queued_paths > 1);
target = afl->queue; afl->splicing_with = tid;
target = afl->queue_buf[tid];
while (tid >= 100) {
target = target->next_100;
tid -= 100;
}
while (tid--) {
target = target->next;
}
/* Make sure that the target has a reasonable length. */ /* Make sure that the target has a reasonable length. */
@ -4518,20 +4506,7 @@ pacemaker_fuzzing:
} while (tid == afl->current_entry); } while (tid == afl->current_entry);
afl->splicing_with = tid; afl->splicing_with = tid;
target = afl->queue; target = afl->queue_buf[tid];
while (tid >= 100) {
target = target->next_100;
tid -= 100;
}
while (tid--) {
target = target->next;
}
/* Make sure that the target has a reasonable length. */ /* Make sure that the target has a reasonable length. */

View File

@ -239,13 +239,6 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
afl->cycles_wo_finds = 0; afl->cycles_wo_finds = 0;
if (!(afl->queued_paths % 100)) {
afl->q_prev100->next_100 = q;
afl->q_prev100 = q;
}
struct queue_entry **queue_buf = afl_realloc( struct queue_entry **queue_buf = afl_realloc(
AFL_BUF_PARAM(queue), afl->queued_paths * sizeof(struct queue_entry *)); AFL_BUF_PARAM(queue), afl->queued_paths * sizeof(struct queue_entry *));
if (unlikely(!queue_buf)) { PFATAL("alloc"); } if (unlikely(!queue_buf)) { PFATAL("alloc"); }

View File

@ -119,8 +119,8 @@ static void usage(u8 *argv0, int more_help) {
"etc.)\n" "etc.)\n"
" -d - quick & dirty mode (skips deterministic steps)\n" " -d - quick & dirty mode (skips deterministic steps)\n"
" -n - fuzz without instrumentation (non-instrumented mode)\n" " -n - fuzz without instrumentation (non-instrumented mode)\n"
" -x dict_file - optional fuzzer dictionary (see README.md, its really " " -x dict_file - fuzzer dictionary (see README.md, specify up to 4 "
"good!)\n\n" "times)\n\n"
"Testing settings:\n" "Testing settings:\n"
" -s seed - use a fixed seed for the RNG\n" " -s seed - use a fixed seed for the RNG\n"
@ -243,11 +243,11 @@ static int stricmp(char const *a, char const *b) {
int main(int argc, char **argv_orig, char **envp) { int main(int argc, char **argv_orig, char **envp) {
s32 opt; s32 opt, i;
u64 prev_queued = 0; u64 prev_queued = 0;
u32 sync_interval_cnt = 0, seek_to, show_help = 0, map_size = MAP_SIZE; u32 sync_interval_cnt = 0, seek_to, show_help = 0, map_size = MAP_SIZE;
u8 * extras_dir = 0; u8 * extras_dir[4];
u8 mem_limit_given = 0, exit_1 = 0, debug = 0; u8 mem_limit_given = 0, exit_1 = 0, debug = 0, extras_dir_cnt = 0;
char **use_argv; char **use_argv;
struct timeval tv; struct timeval tv;
@ -450,8 +450,13 @@ int main(int argc, char **argv_orig, char **envp) {
case 'x': /* dictionary */ case 'x': /* dictionary */
if (extras_dir) { FATAL("Multiple -x options not supported"); } if (extras_dir_cnt >= 4) {
extras_dir = optarg;
FATAL("More than four -x options are not supported");
}
extras_dir[extras_dir_cnt++] = optarg;
break; break;
case 't': { /* timeout */ case 't': { /* timeout */
@ -828,10 +833,6 @@ int main(int argc, char **argv_orig, char **envp) {
"Eißfeldt, Andrea Fioraldi and Dominik Maier"); "Eißfeldt, Andrea Fioraldi and Dominik Maier");
OKF("afl++ is open source, get it at " OKF("afl++ is open source, get it at "
"https://github.com/AFLplusplus/AFLplusplus"); "https://github.com/AFLplusplus/AFLplusplus");
OKF("Power schedules from github.com/mboehme/aflfast");
OKF("Python Mutator and llvm_mode instrument file list from "
"github.com/choller/afl");
OKF("MOpt Mutator from github.com/puppet-meteor/MOpt-AFL");
if (afl->sync_id && afl->is_main_node && if (afl->sync_id && afl->is_main_node &&
afl->afl_env.afl_custom_mutator_only) { afl->afl_env.afl_custom_mutator_only) {
@ -1139,7 +1140,15 @@ int main(int argc, char **argv_orig, char **envp) {
pivot_inputs(afl); pivot_inputs(afl);
if (extras_dir) { load_extras(afl, extras_dir); } if (extras_dir_cnt) {
for (i = 0; i < extras_dir_cnt; i++)
load_extras(afl, extras_dir[i]);
dedup_extras(afl);
OKF("Loaded a total of %u extras.", afl->extras_cnt);
}
if (!afl->timeout_given) { find_timeout(afl); } if (!afl->timeout_given) { find_timeout(afl); }