Merge pull request #428 from AFLplusplus/dev

Dev
This commit is contained in:
van Hauser
2020-06-29 18:36:06 +02:00
committed by GitHub
68 changed files with 63366 additions and 31521 deletions

4
.gitignore vendored
View File

@ -18,6 +18,7 @@ afl-gcc-fast
afl-g++-fast afl-g++-fast
afl-gotcpu afl-gotcpu
afl-ld afl-ld
afl-ld-lto
afl-qemu-trace afl-qemu-trace
afl-showmap afl-showmap
afl-tmin afl-tmin
@ -45,9 +46,12 @@ ld
qemu_mode/qemu-* qemu_mode/qemu-*
unicorn_mode/samples/*/\.test-* unicorn_mode/samples/*/\.test-*
unicorn_mode/samples/*/output/ unicorn_mode/samples/*/output/
unicorn_mode/unicornafl
core\.* core\.*
test/unittests/unit_maybe_alloc test/unittests/unit_maybe_alloc
test/unittests/unit_preallocable test/unittests/unit_preallocable
test/unittests/unit_list test/unittests/unit_list
test/unittests/unit_rand
test/unittests/unit_hash
examples/afl_network_proxy/afl-network-server examples/afl_network_proxy/afl-network-server
examples/afl_network_proxy/afl-network-client examples/afl_network_proxy/afl-network-client

View File

@ -69,10 +69,11 @@ ifeq "$(shell uname)" "SunOS"
endif endif
ifdef STATIC ifdef STATIC
$(info Compiling static version of binaries) $(info Compiling static version of binaries, disabling python though)
# Disable python for static compilation to simplify things # Disable python for static compilation to simplify things
PYTHON_OK=0 PYTHON_OK=0
PYFLAGS= PYFLAGS=
PYTHON_INCLUDE=/
CFLAGS_OPT += -static CFLAGS_OPT += -static
LDFLAGS += -lm -lpthread -lz -lutil LDFLAGS += -lm -lpthread -lz -lutil
@ -96,7 +97,7 @@ endif
CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT) CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT)
override CFLAGS += -Wall -g -Wno-pointer-sign -Wmissing-declarations\ override CFLAGS += -Wall -g -Wno-pointer-sign -Wmissing-declarations\
-I include/ -Werror -DAFL_PATH=\"$(HELPER_PATH)\" \ -I include/ -DAFL_PATH=\"$(HELPER_PATH)\" \
-DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\"
ifeq "$(shell uname -s)" "FreeBSD" ifeq "$(shell uname -s)" "FreeBSD"
@ -121,7 +122,7 @@ endif
ifeq "$(shell uname -s)" "Haiku" ifeq "$(shell uname -s)" "Haiku"
SHMAT_OK=0 SHMAT_OK=0
override CFLAGS += -DUSEMMAP=1 -Wno-error=format -fpic override CFLAGS += -DUSEMMAP=1 -Wno-error=format -fPIC
LDFLAGS += -Wno-deprecated-declarations -lgnu LDFLAGS += -Wno-deprecated-declarations -lgnu
SPECIAL_PERFORMANCE += -DUSEMMAP=1 SPECIAL_PERFORMANCE += -DUSEMMAP=1
endif endif
@ -199,12 +200,12 @@ ifneq "$(filter Linux GNU%,$(shell uname))" ""
endif endif
ifneq "$(findstring FreeBSD, $(shell uname))" "" ifneq "$(findstring FreeBSD, $(shell uname))" ""
CFLAGS += -pthread override CFLAGS += -pthread
LDFLAGS += -lpthread LDFLAGS += -lpthread
endif endif
ifneq "$(findstring NetBSD, $(shell uname))" "" ifneq "$(findstring NetBSD, $(shell uname))" ""
CFLAGS += -pthread override CFLAGS += -pthread
LDFLAGS += -lpthread LDFLAGS += -lpthread
endif endif
@ -244,7 +245,7 @@ endif
ifdef ASAN_BUILD ifdef ASAN_BUILD
$(info Compiling ASAN version of binaries) $(info Compiling ASAN version of binaries)
CFLAGS+=$(ASAN_CFLAGS) override CFLAGS+=$(ASAN_CFLAGS)
LDFLAGS+=$(ASAN_LDFLAGS) LDFLAGS+=$(ASAN_LDFLAGS)
endif endif
@ -252,14 +253,14 @@ ifeq "$(shell echo '$(HASH)include <sys/ipc.h>@$(HASH)include <sys/shm.h>@int ma
SHMAT_OK=1 SHMAT_OK=1
else else
SHMAT_OK=0 SHMAT_OK=0
CFLAGS+=-DUSEMMAP=1 override CFLAGS+=-DUSEMMAP=1
LDFLAGS+=-Wno-deprecated-declarations LDFLAGS += -Wno-deprecated-declarations -lrt
endif endif
ifeq "$(TEST_MMAP)" "1" ifdef TEST_MMAP
SHMAT_OK=0 SHMAT_OK=0
CFLAGS+=-DUSEMMAP=1 override CFLAGS += -DUSEMMAP=1
LDFLAGS+=-Wno-deprecated-declarations LDFLAGS += -Wno-deprecated-declarations -lrt
endif endif
all: test_x86 test_shm test_python ready $(PROGS) afl-as test_build all_done all: test_x86 test_shm test_python ready $(PROGS) afl-as test_build all_done
@ -282,8 +283,8 @@ 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, radamsa" @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, radamsa" @echo "source-only: everything for source code fuzzing: llvm_mode, 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"
@ -311,6 +312,8 @@ 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 )
@echo "[*] Testing the PATH environment variable..."
@test "$${PATH}" != "$${PATH#.:}" && { echo "Please remove current directory '.' from PATH to avoid recursion of 'as', thanks!"; echo; exit 1; } || :
@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
@ -374,12 +377,6 @@ src/afl-forkserver.o : $(COMM_HDR) src/afl-forkserver.c include/forkserver.h
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) -c src/afl-sharedmem.c -o src/afl-sharedmem.o $(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 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) 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)
@ -397,19 +394,30 @@ afl-gotcpu: src/afl-gotcpu.c src/afl-common.o $(COMM_HDR) | test_x86
# 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-forkserver.o src/afl-performance.o | test_x86 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) -g -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o 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) -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) $(ASAN_CFLAGS) -c test/unittests/unit_preallocable.c -o test/unittests/unit_preallocable.o
unit_maybe_alloc: test/unittests/unit_maybe_alloc.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 @$(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
@$(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
@$(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_hash $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
./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
@$(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
@$(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_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) -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
@ -417,8 +425,8 @@ 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 @$(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/preallocable.o : $(COMM_HDR) include/afl-prealloc.h test/unittests/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) $(CFLAGS_FLTO) -c test/unittests/preallocable.c -o test/unittests/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) -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
@ -429,7 +437,7 @@ unit_clean:
ifneq "$(shell uname)" "Darwin" ifneq "$(shell uname)" "Darwin"
unit: unit_maybe_alloc unit_preallocable unit_list unit_clean unit: unit_maybe_alloc unit_preallocable unit_list unit_clean unit_rand unit_hash
else else
@ -449,6 +457,8 @@ code-format:
./.custom-format.py -i gcc_plugin/*.c ./.custom-format.py -i gcc_plugin/*.c
#./.custom-format.py -i gcc_plugin/*.h #./.custom-format.py -i gcc_plugin/*.h
./.custom-format.py -i gcc_plugin/*.cc ./.custom-format.py -i gcc_plugin/*.cc
./.custom-format.py -i custom_mutators/*/*.c
./.custom-format.py -i custom_mutators/*/*.h
./.custom-format.py -i examples/*/*.c ./.custom-format.py -i examples/*/*.c
./.custom-format.py -i examples/*/*.h ./.custom-format.py -i examples/*/*.h
./.custom-format.py -i test/*.c ./.custom-format.py -i test/*.c
@ -501,7 +511,6 @@ clean:
$(MAKE) -C examples/argv_fuzzing clean $(MAKE) -C examples/argv_fuzzing clean
$(MAKE) -C qemu_mode/unsigaction clean $(MAKE) -C qemu_mode/unsigaction clean
$(MAKE) -C qemu_mode/libcompcov clean $(MAKE) -C qemu_mode/libcompcov clean
$(MAKE) -C src/third_party/libradamsa/ 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 -d unicorn_mode/unicornafl && $(MAKE) -C unicorn_mode/unicornafl clean || true test -d unicorn_mode/unicornafl && $(MAKE) -C unicorn_mode/unicornafl clean || true
@ -515,7 +524,7 @@ deepclean: clean
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
distrib: all radamsa distrib: all
-$(MAKE) -C llvm_mode -$(MAKE) -C llvm_mode
-$(MAKE) -C gcc_plugin -$(MAKE) -C gcc_plugin
$(MAKE) -C libdislocator $(MAKE) -C libdislocator
@ -524,18 +533,18 @@ distrib: all radamsa
$(MAKE) -C examples/socket_fuzzing $(MAKE) -C examples/socket_fuzzing
$(MAKE) -C examples/argv_fuzzing $(MAKE) -C examples/argv_fuzzing
-cd qemu_mode && sh ./build_qemu_support.sh -cd qemu_mode && sh ./build_qemu_support.sh
cd unicorn_mode && sh ./build_unicorn_support.sh cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh
binary-only: all radamsa binary-only: all
$(MAKE) -C libdislocator $(MAKE) -C libdislocator
$(MAKE) -C libtokencap $(MAKE) -C libtokencap
$(MAKE) -C examples/afl_network_proxy $(MAKE) -C examples/afl_network_proxy
$(MAKE) -C examples/socket_fuzzing $(MAKE) -C examples/socket_fuzzing
$(MAKE) -C examples/argv_fuzzing $(MAKE) -C examples/argv_fuzzing
-cd qemu_mode && sh ./build_qemu_support.sh -cd qemu_mode && sh ./build_qemu_support.sh
cd unicorn_mode && sh ./build_unicorn_support.sh cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh
source-only: all radamsa source-only: all
-$(MAKE) -C llvm_mode -$(MAKE) -C llvm_mode
-$(MAKE) -C gcc_plugin -$(MAKE) -C gcc_plugin
$(MAKE) -C libdislocator $(MAKE) -C libdislocator
@ -574,7 +583,6 @@ install: all $(MANPAGES)
if [ -f libdislocator.so ]; then set -e; install -m 755 libdislocator.so $${DESTDIR}$(HELPER_PATH); 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 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 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 if [ -f afl-fuzz-document ]; then set -e; install -m 755 afl-fuzz-document $${DESTDIR}$(BIN_PATH); fi
if [ -f socketfuzz32.so -o -f socketfuzz64.so ]; then $(MAKE) -C examples/socket_fuzzing install; fi 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 if [ -f argvfuzz32.so -o -f argvfuzz64.so ]; then $(MAKE) -C examples/argv_fuzzing install; fi

View File

@ -54,7 +54,7 @@
* Win32 PE binary-only fuzzing with QEMU and Wine * Win32 PE binary-only fuzzing with QEMU and Wine
* Radamsa mutator (enable with `-R` to add or `-RR` to run it exclusively). * Radamsa mutator (as a custom mutator).
* QBDI mode to fuzz android native libraries via QBDI framework * QBDI mode to fuzz android native libraries via QBDI framework
@ -167,8 +167,8 @@ is what you should choose.
These build targets exist: 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, radamsa * binary-only: everything for binary-only fuzzing: qemu_mode, unicorn_mode, libdislocator, libtokencap
* source-only: everything for source code fuzzing: llvm_mode, libdislocator, libtokencap, radamsa * source-only: everything for source code fuzzing: llvm_mode, 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
@ -371,14 +371,15 @@ therefore may increase the code coverage.
The available schedules are: The available schedules are:
- explore (default) - explore (default, original AFL)
- fast - exploit (original AFL)
- coe - fast (AFLfast)
- quad - coe (AFLfast)
- lin - quad (AFLfast)
- exploit - lin (AFLfast)
- mmopt (experimental) - rare (afl++ experimental)
- rare (experimental) - mmopt (afl++ experimental)
- seek (afl++ experimental)
In parallel mode (-M/-S, several instances with the shared queue), we suggest to In parallel mode (-M/-S, several instances with the shared queue), we suggest to
run the main node using the explore or fast schedule (-p explore) and the secondary run the main node using the explore or fast schedule (-p explore) and the secondary

View File

@ -4,9 +4,7 @@
- AFL_MAP_SIZE for qemu_mode and unicorn_mode - AFL_MAP_SIZE for qemu_mode and unicorn_mode
- namespace for targets? e.g. network - namespace for targets? e.g. network
- libradamsa as a custom module?
- learn from honggfuzz (mutations, maybe ptrace?) - learn from honggfuzz (mutations, maybe ptrace?)
- mutations from compiler fuzzer, e.g. https://github.com/agroce/afl-compiler-fuzzer/blob/2758cbfa32621ddfee5c8da6adf59a9531367263/afl-fuzz.c#L5077
- CPU affinity for many cores? There seems to be an issue > 96 cores - CPU affinity for many cores? There seems to be an issue > 96 cores
## Further down the road ## Further down the road
@ -15,6 +13,9 @@ afl-fuzz:
- ascii_only mode for mutation output - or use a custom mutator for this? - ascii_only mode for mutation output - or use a custom mutator for this?
- setting min_len/max_len/start_offset/end_offset limits for mutation output - setting min_len/max_len/start_offset/end_offset limits for mutation output
llvm_mode:
- LTO - imitate sancov
gcc_plugin: gcc_plugin:
- (wait for submission then decide) - (wait for submission then decide)
- laf-intel - laf-intel

View File

@ -134,7 +134,6 @@ Environment variables used:
AFL_KEEP_TRACES: leave the temporary <out_dir>\.traces directory AFL_KEEP_TRACES: leave the temporary <out_dir>\.traces directory
AFL_PATH: path for the afl-showmap binary AFL_PATH: path for the afl-showmap binary
AFL_SKIP_BIN_CHECK: skip check for target binary AFL_SKIP_BIN_CHECK: skip check for target binary
AFL_ALLOW_TMP: allow unsafe use of input/output directories under {/var}/tmp
_EOF_ _EOF_
exit 1 exit 1
fi fi
@ -142,29 +141,29 @@ fi
# Do a sanity check to discourage the use of /tmp, since we can't really # Do a sanity check to discourage the use of /tmp, since we can't really
# handle this safely from a shell script. # handle this safely from a shell script.
if [ "$AFL_ALLOW_TMP" = "" ]; then #if [ "$AFL_ALLOW_TMP" = "" ]; then
#
echo "$IN_DIR" | grep -qE '^(/var)?/tmp/' # echo "$IN_DIR" | grep -qE '^(/var)?/tmp/'
T1="$?" # T1="$?"
#
echo "$TARGET_BIN" | grep -qE '^(/var)?/tmp/' # echo "$TARGET_BIN" | grep -qE '^(/var)?/tmp/'
T2="$?" # T2="$?"
#
echo "$OUT_DIR" | grep -qE '^(/var)?/tmp/' # echo "$OUT_DIR" | grep -qE '^(/var)?/tmp/'
T3="$?" # T3="$?"
#
echo "$STDIN_FILE" | grep -qE '^(/var)?/tmp/' # echo "$STDIN_FILE" | grep -qE '^(/var)?/tmp/'
T4="$?" # T4="$?"
#
echo "$PWD" | grep -qE '^(/var)?/tmp/' # echo "$PWD" | grep -qE '^(/var)?/tmp/'
T5="$?" # T5="$?"
#
if [ "$T1" = "0" -o "$T2" = "0" -o "$T3" = "0" -o "$T4" = "0" -o "$T5" = "0" ]; then # if [ "$T1" = "0" -o "$T2" = "0" -o "$T3" = "0" -o "$T4" = "0" -o "$T5" = "0" ]; then
echo "[-] Error: do not use this script in /tmp or /var/tmp." 1>&2 # echo "[-] Error: do not use this script in /tmp or /var/tmp." 1>&2
exit 1 # exit 1
fi # fi
#
fi #fi
# If @@ is specified, but there's no -f, let's come up with a temporary input # If @@ is specified, but there's no -f, let's come up with a temporary input
# file name. # file name.
@ -246,7 +245,7 @@ if [ ! "$STDIN_FILE" = "" ]; then
fi fi
if [ "$AFL_PATH" = "" ]; then if [ "$AFL_PATH" = "" ]; then
SHOWMAP="${0%/afl-cmin}/afl-showmap" SHOWMAP="${0%/afl-cmin.bash}/afl-showmap"
else else
SHOWMAP="$AFL_PATH/afl-showmap" SHOWMAP="$AFL_PATH/afl-showmap"
fi fi

View File

@ -15,6 +15,10 @@
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
get_abs_path() {
echo $(cd "`dirname "$1"`" && pwd)/"`basename "$1"`"
}
echo "progress plotting utility for afl-fuzz by Michal Zalewski" echo "progress plotting utility for afl-fuzz by Michal Zalewski"
echo echo
@ -31,40 +35,40 @@ an empty directory where this tool can write the resulting plots to.
The program will put index.html and three PNG images in the output directory; The program will put index.html and three PNG images in the output directory;
you should be able to view it with any web browser of your choice. you should be able to view it with any web browser of your choice.
Environment variables used:
AFL_ALLOW_TMP: allow /var/tmp or /tmp for input and output directories
_EOF_ _EOF_
exit 1 exit 1
fi fi
if [ "$AFL_ALLOW_TMP" = "" ]; then inputdir=`get_abs_path "$1"`
outputdir=`get_abs_path "$2"`
echo "$1" | grep -qE '^(/var)?/tmp/' #if [ "$AFL_ALLOW_TMP" = "" ]; then
T1="$?" #
# echo "$inputdir" | grep -qE '^(/var)?/tmp/'
# T1="$?"
#
# echo "$outputdir" | grep -qE '^(/var)?/tmp/'
# T2="$?"
#
# if [ "$T1" = "0" -o "$T2" = "0" ]; then
#
# echo "[-] Error: this script shouldn't be used with shared /tmp directories." 1>&2
# exit 1
#
# fi
#
#fi
echo "$2" | grep -qE '^(/var)?/tmp/' if [ ! -f "$inputdir/plot_data" ]; then
T2="$?"
if [ "$T1" = "0" -o "$T2" = "0" ]; then
echo "[-] Error: this script shouldn't be used with shared /tmp directories." 1>&2
exit 1
fi
fi
if [ ! -f "$1/plot_data" ]; then
echo "[-] Error: input directory is not valid (missing 'plot_data')." 1>&2 echo "[-] Error: input directory is not valid (missing 'plot_data')." 1>&2
exit 1 exit 1
fi fi
BANNER="`cat "$1/fuzzer_stats" | grep '^afl_banner ' | cut -d: -f2- | cut -b2-`" BANNER="`cat "$inputdir/fuzzer_stats" 2> /dev/null | grep '^afl_banner ' | cut -d: -f2- | cut -b2-`"
test "$BANNER" = "" && BANNER="(none)" test "$BANNER" = "" && BANNER="(none)"
@ -77,17 +81,17 @@ if [ "$GNUPLOT" = "" ]; then
fi fi
mkdir "$2" 2>/dev/null mkdir "$outputdir" 2>/dev/null
if [ ! -d "$2" ]; then if [ ! -d "$outputdir" ]; then
echo "[-] Error: unable to create the output directory - pick another location." 1>&2 echo "[-] Error: unable to create the output directory - pick another location." 1>&2
exit 1 exit 1
fi fi
rm -f "$2/high_freq.png" "$2/low_freq.png" "$2/exec_speed.png" rm -f "$outputdir/high_freq.png" "$outputdir/low_freq.png" "$outputdir/exec_speed.png"
mv -f "$2/index.html" "$2/index.html.orig" 2>/dev/null mv -f "$outputdir/index.html" "$outputdir/index.html.orig" 2>/dev/null
echo "[*] Generating plots..." echo "[*] Generating plots..."
@ -96,7 +100,7 @@ echo "[*] Generating plots..."
cat <<_EOF_ cat <<_EOF_
set terminal png truecolor enhanced size 1000,300 butt set terminal png truecolor enhanced size 1000,300 butt
set output '$2/high_freq.png' set output '$outputdir/high_freq.png'
set xdata time set xdata time
set timefmt '%s' set timefmt '%s'
@ -114,31 +118,31 @@ set key outside
set autoscale xfixmin set autoscale xfixmin
set autoscale xfixmax set autoscale xfixmax
plot '$1/plot_data' using 1:4 with filledcurve x1 title 'total paths' linecolor rgb '#000000' fillstyle transparent solid 0.2 noborder, \\ plot '$inputdir/plot_data' using 1:4 with filledcurve x1 title 'total paths' linecolor rgb '#000000' fillstyle transparent solid 0.2 noborder, \\
'' using 1:3 with filledcurve x1 title 'current path' linecolor rgb '#f0f0f0' fillstyle transparent solid 0.5 noborder, \\ '' using 1:3 with filledcurve x1 title 'current path' linecolor rgb '#f0f0f0' fillstyle transparent solid 0.5 noborder, \\
'' using 1:5 with lines title 'pending paths' linecolor rgb '#0090ff' linewidth 3, \\ '' using 1:5 with lines title 'pending paths' linecolor rgb '#0090ff' linewidth 3, \\
'' using 1:6 with lines title 'pending favs' linecolor rgb '#c00080' linewidth 3, \\ '' using 1:6 with lines title 'pending favs' linecolor rgb '#c00080' linewidth 3, \\
'' using 1:2 with lines title 'cycles done' linecolor rgb '#c000f0' linewidth 3 '' using 1:2 with lines title 'cycles done' linecolor rgb '#c000f0' linewidth 3
set terminal png truecolor enhanced size 1000,200 butt set terminal png truecolor enhanced size 1000,200 butt
set output '$2/low_freq.png' set output '$outputdir/low_freq.png'
plot '$1/plot_data' using 1:8 with filledcurve x1 title '' linecolor rgb '#c00080' fillstyle transparent solid 0.2 noborder, \\ plot '$inputdir/plot_data' using 1:8 with filledcurve x1 title '' linecolor rgb '#c00080' fillstyle transparent solid 0.2 noborder, \\
'' using 1:8 with lines title ' uniq crashes' linecolor rgb '#c00080' linewidth 3, \\ '' using 1:8 with lines title ' uniq crashes' linecolor rgb '#c00080' linewidth 3, \\
'' using 1:9 with lines title 'uniq hangs' linecolor rgb '#c000f0' linewidth 3, \\ '' using 1:9 with lines title 'uniq hangs' linecolor rgb '#c000f0' linewidth 3, \\
'' using 1:10 with lines title 'levels' linecolor rgb '#0090ff' linewidth 3 '' using 1:10 with lines title 'levels' linecolor rgb '#0090ff' linewidth 3
set terminal png truecolor enhanced size 1000,200 butt set terminal png truecolor enhanced size 1000,200 butt
set output '$2/exec_speed.png' set output '$outputdir/exec_speed.png'
plot '$1/plot_data' using 1:11 with filledcurve x1 title '' linecolor rgb '#0090ff' fillstyle transparent solid 0.2 noborder, \\ plot '$inputdir/plot_data' using 1:11 with filledcurve x1 title '' linecolor rgb '#0090ff' fillstyle transparent solid 0.2 noborder, \\
'$1/plot_data' using 1:11 with lines title ' execs/sec' linecolor rgb '#0090ff' linewidth 3 smooth bezier; '$inputdir/plot_data' using 1:11 with lines title ' execs/sec' linecolor rgb '#0090ff' linewidth 3 smooth bezier;
_EOF_ _EOF_
) | gnuplot ) | gnuplot
if [ ! -s "$2/exec_speed.png" ]; then if [ ! -s "$outputdir/exec_speed.png" ]; then
echo "[-] Error: something went wrong! Perhaps you have an ancient version of gnuplot?" 1>&2 echo "[-] Error: something went wrong! Perhaps you have an ancient version of gnuplot?" 1>&2
exit 1 exit 1
@ -147,10 +151,10 @@ fi
echo "[*] Generating index.html..." echo "[*] Generating index.html..."
cat >"$2/index.html" <<_EOF_ cat >"$outputdir/index.html" <<_EOF_
<table style="font-family: 'Trebuchet MS', 'Tahoma', 'Arial', 'Helvetica'"> <table style="font-family: 'Trebuchet MS', 'Tahoma', 'Arial', 'Helvetica'">
<tr><td style="width: 18ex"><b>Banner:</b></td><td>$BANNER</td></tr> <tr><td style="width: 18ex"><b>Banner:</b></td><td>$BANNER</td></tr>
<tr><td><b>Directory:</b></td><td>$1</td></tr> <tr><td><b>Directory:</b></td><td>$inputdir</td></tr>
<tr><td><b>Generated on:</b></td><td>`date`</td></tr> <tr><td><b>Generated on:</b></td><td>`date`</td></tr>
</table> </table>
<p> <p>
@ -164,8 +168,8 @@ _EOF_
# served by Apache or other HTTP daemon. Since the plots aren't horribly # served by Apache or other HTTP daemon. Since the plots aren't horribly
# sensitive, this seems like a reasonable trade-off. # sensitive, this seems like a reasonable trade-off.
chmod 755 "$2" chmod 755 "$outputdir"
chmod 644 "$2/high_freq.png" "$2/low_freq.png" "$2/exec_speed.png" "$2/index.html" chmod 644 "$outputdir/high_freq.png" "$outputdir/low_freq.png" "$outputdir/exec_speed.png" "$outputdir/index.html"
echo "[+] All done - enjoy your charts!" echo "[+] All done - enjoy your charts!"

12
custom_mutators/README.md Normal file
View File

@ -0,0 +1,12 @@
# production ready custom mutators
This directory holds ready to use custom mutators.
Just type "make" in the individual subdirectories.
Use with e.g.
`AFL_CUSTOM_MUTATOR_LIBRARY=custom_mutators/radamsa/radamsa-mutator.so afl-fuzz ....`
and add `AFL_CUSTOM_MUTATOR_ONLY=1` if you only want to use the custom mutator.
Multiple custom mutators can be used by separating their paths with `:` in the environment variable.

View File

@ -1,15 +1,15 @@
CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
all: libradamsa.so all: radamsa-mutator.so
# These can be overriden: # These can be overriden:
CFLAGS ?= -march=native $(CFLAGS_FLTO) CFLAGS ?= $(CFLAGS_FLTO)
# These are required: (otherwise radamsa gets very very slooooow) # These are required: (otherwise radamsa gets very very slooooow)
CFLAGS += -O3 -funroll-loops CFLAGS += -O3 -funroll-loops
libradamsa.so: libradamsa.a #libradamsa.so: libradamsa.a
$(CC) $(CFLAGS) -shared libradamsa.a -o libradamsa.so # $(CC) $(CFLAGS) -shared libradamsa.a -o libradamsa.so
libradamsa.a: libradamsa.c radamsa.h libradamsa.a: libradamsa.c radamsa.h
@echo " ***************************************************************" @echo " ***************************************************************"
@ -17,10 +17,14 @@ libradamsa.a: libradamsa.c radamsa.h
@echo " ***************************************************************" @echo " ***************************************************************"
$(CC) -fPIC $(CFLAGS) -I $(CUR_DIR) -o libradamsa.a -c libradamsa.c $(CC) -fPIC $(CFLAGS) -I $(CUR_DIR) -o libradamsa.a -c libradamsa.c
radamsa-mutator.so: radamsa-mutator.c libradamsa.a
$(CC) $(CFLAGS) -g -I. -I../../include -shared -fPIC -c radamsa-mutator.c
$(CC) $(CFLAGS) -shared -fPIC -o radamsa-mutator.so radamsa-mutator.o libradamsa.a
test: libradamsa.a libradamsa-test.c test: libradamsa.a libradamsa-test.c
$(CC) $(CFLAGS) -I $(CUR_DIR) -o libradamsa-test libradamsa-test.c libradamsa.a $(CC) $(CFLAGS) -I $(CUR_DIR) -o libradamsa-test libradamsa-test.c libradamsa.a
./libradamsa-test libradamsa-test.c | grep "library test passed" ./libradamsa-test libradamsa-test.c | grep "library test passed"
rm /tmp/libradamsa-*.fuzz rm /tmp/libradamsa-*.fuzz
clean: clean:
rm -f libradamsa.a libradamsa.so libradamsa-test rm -f radamsa-mutator.so libradamsa.a libradamsa-test *.o *~ core

View File

@ -1,4 +1,4 @@
# libradamsa # custum mutator: libradamsa
Pretranslated radamsa library. This code belongs to the radamsa author. Pretranslated radamsa library. This code belongs to the radamsa author.

View File

@ -0,0 +1,342 @@
#ifndef CUSTOM_MUTATOR_HELPERS
#define CUSTOM_MUTATOR_HELPERS
#include "config.h"
#include "types.h"
#include <stdlib.h>
#define INITIAL_GROWTH_SIZE (64)
#define RAND_BELOW(limit) (rand() % (limit))
/* Use in a struct: creates a name_buf and a name_size variable. */
#define BUF_VAR(type, name) \
type * name##_buf; \
size_t name##_size;
/* this filles in `&structptr->something_buf, &structptr->something_size`. */
#define BUF_PARAMS(struct, name) \
(void **)&struct->name##_buf, &struct->name##_size
typedef struct {
} afl_t;
static void surgical_havoc_mutate(u8 *out_buf, s32 begin, s32 end) {
static s8 interesting_8[] = {INTERESTING_8};
static s16 interesting_16[] = {INTERESTING_8, INTERESTING_16};
static s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32};
switch (RAND_BELOW(12)) {
case 0: {
/* Flip a single bit somewhere. Spooky! */
s32 bit_idx = ((RAND_BELOW(end - begin) + begin) << 3) + RAND_BELOW(8);
out_buf[bit_idx >> 3] ^= 128 >> (bit_idx & 7);
break;
}
case 1: {
/* Set byte to interesting value. */
u8 val = interesting_8[RAND_BELOW(sizeof(interesting_8))];
out_buf[(RAND_BELOW(end - begin) + begin)] = val;
break;
}
case 2: {
/* Set word to interesting value, randomly choosing endian. */
if (end - begin < 2) break;
s32 byte_idx = (RAND_BELOW(end - begin) + begin);
if (byte_idx >= end - 1) break;
switch (RAND_BELOW(2)) {
case 0:
*(u16 *)(out_buf + byte_idx) =
interesting_16[RAND_BELOW(sizeof(interesting_16) >> 1)];
break;
case 1:
*(u16 *)(out_buf + byte_idx) =
SWAP16(interesting_16[RAND_BELOW(sizeof(interesting_16) >> 1)]);
break;
}
break;
}
case 3: {
/* Set dword to interesting value, randomly choosing endian. */
if (end - begin < 4) break;
s32 byte_idx = (RAND_BELOW(end - begin) + begin);
if (byte_idx >= end - 3) break;
switch (RAND_BELOW(2)) {
case 0:
*(u32 *)(out_buf + byte_idx) =
interesting_32[RAND_BELOW(sizeof(interesting_32) >> 2)];
break;
case 1:
*(u32 *)(out_buf + byte_idx) =
SWAP32(interesting_32[RAND_BELOW(sizeof(interesting_32) >> 2)]);
break;
}
break;
}
case 4: {
/* Set qword to interesting value, randomly choosing endian. */
if (end - begin < 8) break;
s32 byte_idx = (RAND_BELOW(end - begin) + begin);
if (byte_idx >= end - 7) break;
switch (RAND_BELOW(2)) {
case 0:
*(u64 *)(out_buf + byte_idx) =
(s64)interesting_32[RAND_BELOW(sizeof(interesting_32) >> 2)];
break;
case 1:
*(u64 *)(out_buf + byte_idx) = SWAP64(
(s64)interesting_32[RAND_BELOW(sizeof(interesting_32) >> 2)]);
break;
}
break;
}
case 5: {
/* Randomly subtract from byte. */
out_buf[(RAND_BELOW(end - begin) + begin)] -= 1 + RAND_BELOW(ARITH_MAX);
break;
}
case 6: {
/* Randomly add to byte. */
out_buf[(RAND_BELOW(end - begin) + begin)] += 1 + RAND_BELOW(ARITH_MAX);
break;
}
case 7: {
/* Randomly subtract from word, random endian. */
if (end - begin < 2) break;
s32 byte_idx = (RAND_BELOW(end - begin) + begin);
if (byte_idx >= end - 1) break;
if (RAND_BELOW(2)) {
*(u16 *)(out_buf + byte_idx) -= 1 + RAND_BELOW(ARITH_MAX);
} else {
u16 num = 1 + RAND_BELOW(ARITH_MAX);
*(u16 *)(out_buf + byte_idx) =
SWAP16(SWAP16(*(u16 *)(out_buf + byte_idx)) - num);
}
break;
}
case 8: {
/* Randomly add to word, random endian. */
if (end - begin < 2) break;
s32 byte_idx = (RAND_BELOW(end - begin) + begin);
if (byte_idx >= end - 1) break;
if (RAND_BELOW(2)) {
*(u16 *)(out_buf + byte_idx) += 1 + RAND_BELOW(ARITH_MAX);
} else {
u16 num = 1 + RAND_BELOW(ARITH_MAX);
*(u16 *)(out_buf + byte_idx) =
SWAP16(SWAP16(*(u16 *)(out_buf + byte_idx)) + num);
}
break;
}
case 9: {
/* Randomly subtract from dword, random endian. */
if (end - begin < 4) break;
s32 byte_idx = (RAND_BELOW(end - begin) + begin);
if (byte_idx >= end - 3) break;
if (RAND_BELOW(2)) {
*(u32 *)(out_buf + byte_idx) -= 1 + RAND_BELOW(ARITH_MAX);
} else {
u32 num = 1 + RAND_BELOW(ARITH_MAX);
*(u32 *)(out_buf + byte_idx) =
SWAP32(SWAP32(*(u32 *)(out_buf + byte_idx)) - num);
}
break;
}
case 10: {
/* Randomly add to dword, random endian. */
if (end - begin < 4) break;
s32 byte_idx = (RAND_BELOW(end - begin) + begin);
if (byte_idx >= end - 3) break;
if (RAND_BELOW(2)) {
*(u32 *)(out_buf + byte_idx) += 1 + RAND_BELOW(ARITH_MAX);
} else {
u32 num = 1 + RAND_BELOW(ARITH_MAX);
*(u32 *)(out_buf + byte_idx) =
SWAP32(SWAP32(*(u32 *)(out_buf + byte_idx)) + num);
}
break;
}
case 11: {
/* Just set a random byte to a random value. Because,
why not. We use XOR with 1-255 to eliminate the
possibility of a no-op. */
out_buf[(RAND_BELOW(end - begin) + begin)] ^= 1 + RAND_BELOW(255);
break;
}
}
}
/* This function calculates the next power of 2 greater or equal its argument.
@return The rounded up power of 2 (if no overflow) or 0 on overflow.
*/
static inline size_t next_pow2(size_t in) {
if (in == 0 || in > (size_t)-1)
return 0; /* avoid undefined behaviour under-/overflow */
size_t out = in - 1;
out |= out >> 1;
out |= out >> 2;
out |= out >> 4;
out |= out >> 8;
out |= out >> 16;
return out + 1;
}
/* This function makes sure *size is > size_needed after call.
It will realloc *buf otherwise.
*size will grow exponentially as per:
https://blog.mozilla.org/nnethercote/2014/11/04/please-grow-your-buffers-exponentially/
Will return NULL and free *buf if size_needed is <1 or realloc failed.
@return For convenience, this function returns *buf.
*/
static inline void *maybe_grow(void **buf, size_t *size, size_t size_needed) {
/* No need to realloc */
if (likely(size_needed && *size >= size_needed)) return *buf;
/* No initial size was set */
if (size_needed < INITIAL_GROWTH_SIZE) size_needed = INITIAL_GROWTH_SIZE;
/* grow exponentially */
size_t next_size = next_pow2(size_needed);
/* handle overflow */
if (!next_size) { next_size = size_needed; }
/* alloc */
*buf = realloc(*buf, next_size);
*size = *buf ? next_size : 0;
return *buf;
}
/* Swaps buf1 ptr and buf2 ptr, as well as their sizes */
static inline void swap_bufs(void **buf1, size_t *size1, void **buf2,
size_t *size2) {
void * scratch_buf = *buf1;
size_t scratch_size = *size1;
*buf1 = *buf2;
*size1 = *size2;
*buf2 = scratch_buf;
*size2 = scratch_size;
}
#undef INITIAL_GROWTH_SIZE
#endif

View File

@ -0,0 +1,81 @@
#include <radamsa.h>
#include <stdio.h>
#include <inttypes.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
size_t filesize(char *filename) {
struct stat st;
stat(filename, &st);
return st.st_size;
}
#define BUFSIZE 1024 * 1024
void fail(char *why) {
printf("fail: %s\n", why);
exit(1);
}
void write_output(char *data, size_t len, int num) {
char path[32];
int fd;
int wrote;
sprintf(path, "/tmp/libradamsa-%d.fuzz", num);
fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
printf("Opened %s -> %d\n", path, fd);
if (fd < 0) { fail("failed to open output file"); }
wrote = write(fd, data, len);
printf("wrote %d of %zu bytes\n", wrote, len);
if (wrote != len) { fail("failed to write all of output at once"); }
close(fd);
printf("Wrote %zu bytes to %s\n", len, path);
}
int main(int nargs, char **argv) {
char * spath = argv[1];
int fd = open(spath, O_RDONLY, 0);
size_t len;
char * input;
char * output;
int seed = 0;
if (fd < 0) { fail("cannot open input file"); }
len = filesize(spath);
input = malloc(len);
output = malloc(BUFSIZE);
if (!input || !output) { fail("failed to allocate buffers\n"); }
radamsa_init();
if (len != read(fd, input, len)) {
fail("failed to read the entire sample at once");
}
while (seed++ < 100) {
size_t n;
n = radamsa((uint8_t *)input, len, (uint8_t *)output, BUFSIZE, seed);
write_output(output, n, seed);
printf("Fuzzed %zu -> %zu bytes\n", len, n);
}
printf("library test passed\n");
free(output);
free(input);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,70 @@
// This simple example just creates random buffer <= 100 filled with 'A'
// needs -I /path/to/AFLplusplus/include
//#include "custom_mutator_helpers.h"
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "radamsa.h"
#include "custom_mutator_helpers.h"
typedef struct my_mutator {
afl_t *afl;
u8 *mutator_buf;
unsigned int seed;
} my_mutator_t;
my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) {
srand(seed);
my_mutator_t *data = calloc(1, sizeof(my_mutator_t));
if (!data) {
perror("afl_custom_init alloc");
return NULL;
}
if ((data->mutator_buf = malloc(MAX_FILE)) == NULL) {
perror("mutator_buf alloc");
return NULL;
}
data->afl = afl;
data->seed = seed;
radamsa_init();
return data;
}
size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
u8 **out_buf, uint8_t *add_buf, size_t add_buf_size,
size_t max_size) {
*out_buf = data->mutator_buf;
return radamsa(buf, buf_size, data->mutator_buf, max_size, data->seed++);
}
/**
* Deinitialize everything
*
* @param data The data ptr from afl_custom_init
*/
void afl_custom_deinit(my_mutator_t *data) {
free(data->mutator_buf);
free(data);
}

View File

@ -0,0 +1,10 @@
#include <inttypes.h>
#include <stddef.h>
void radamsa_init(void);
size_t radamsa(uint8_t *ptr, size_t len, uint8_t *target, size_t max,
unsigned int seed);
size_t radamsa_inplace(uint8_t *ptr, size_t len, size_t max, unsigned int seed);

View File

@ -14,6 +14,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
- -S secondary nodes now only sync from the main node to increase - -S secondary nodes now only sync from the main node to increase
performance, the -M main node still syncs from everyone. Added checks performance, the -M main node still syncs from everyone. Added checks
that ensure exactly one main node is present and warn otherwise that ensure exactly one main node is present and warn otherwise
- Add -D after -S to force a secondary to perform deterministic fuzzing
- If no main node is present at a sync one secondary node automatically - If no main node is present at a sync one secondary node automatically
becomes a temporary main node until a real main nodes shows up becomes a temporary main node until a real main nodes shows up
- Fixed a mayor performance issue we inherited from AFLfast - Fixed a mayor performance issue we inherited from AFLfast
@ -23,11 +24,15 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
- Ensure that the targets are killed on exit - Ensure that the targets are killed on exit
- fix/update to MOpt (thanks to arnow117) - fix/update to MOpt (thanks to arnow117)
- added MOpt dictionary support from repo - added MOpt dictionary support from repo
- added experimental SEEK power schedule. It is EXPLORE with ignoring
the runtime and less focus on the length of the test case
- llvm_mode: - llvm_mode:
- the default instrumentation is now PCGUARD if the llvm version is >= 7, - the default instrumentation is now PCGUARD if the llvm version is >= 7,
as it is faster and provides better coverage. The original afl as it is faster and provides better coverage. The original afl
instrumentation can be set via AFL_LLVM_INSTRUMENT=AFL. This is instrumentation can be set via AFL_LLVM_INSTRUMENT=AFL. This is
automatically done when the WHITELIST feature is used. automatically done when the WHITELIST feature is used.
- PCGUARD mode is now even better because we made it collision free - plus
it has a fixed map size, so it is also faster! :)
- some targets want a ld variant for LD that is not gcc/clang but ld, - some targets want a ld variant for LD that is not gcc/clang but ld,
added afl-ld-lto to solve this added afl-ld-lto to solve this
- lowered minimum required llvm version to 3.4 (except LLVMInsTrim, which - lowered minimum required llvm version to 3.4 (except LLVMInsTrim, which
@ -44,9 +49,15 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
- Unicornafl - Unicornafl
- Added powerPC support from unicorn/next - Added powerPC support from unicorn/next
- rust bindings! - rust bindings!
- CMPLOG/Redqueen now also works for MMAP sharedmem
- ensure shmem is released on errors
- we moved radamsa to be a custom mutator in ./custom_mutators/. It is not
compiled by default anymore.
- allow running in /tmp (only unsafe with umask 0)
- persistent mode shared memory testcase handover (instead of via - persistent mode shared memory testcase handover (instead of via
files/stdin) - 10-100% performance increase files/stdin) - 10-100% performance increase
- General support for 64 bit PowerPC, RiscV, Sparc etc. - General support for 64 bit PowerPC, RiscV, Sparc etc.
- fix afl-cmin.bash
- slightly better performance compilation options for afl++ and targets - slightly better performance compilation options for afl++ and targets
- fixed afl-gcc/afl-as that could break on fast systems reusing pids in - fixed afl-gcc/afl-as that could break on fast systems reusing pids in
the same second the same second

View File

@ -1,9 +0,0 @@
# libradamsa
Pretranslated radamsa library. This code belongs to the radamsa author.
> Original repository: https://gitlab.com/akihe/radamsa
> Source commit: 7b2cc2d0
> The code here is adapted for AFL++ with minor changes respect the original version

View File

@ -6,7 +6,7 @@ for future AFL++ versions.
For GSOC2020 interested students please see For GSOC2020 interested students please see
[https://github.com/AFLplusplus/AFLplusplus/issues/208](https://github.com/AFLplusplus/AFLplusplus/issues/208) [https://github.com/AFLplusplus/AFLplusplus/issues/208](https://github.com/AFLplusplus/AFLplusplus/issues/208)
## Flexible Grammar Mutator ## Flexible Grammar Mutator (currently in development)
Currently, AFL++'s mutation does not have deeper knowledge about the fuzzed Currently, AFL++'s mutation does not have deeper knowledge about the fuzzed
binary, apart from feedback, even though the developer may have insights binary, apart from feedback, even though the developer may have insights
@ -25,41 +25,21 @@ various results.
Mentor: andreafioraldi Mentor: andreafioraldi
## Expand on the MOpt mutator
Work on the MOpt mutator that is already in AFL++.
This is an excellent mutations scheduler based on Particle Swarm
Optimization but the current implementation schedule only the mutations
that were present on AFL.
AFL++ added a lot of optional mutators like the Input-2-State one based
on Redqueen, the Radamsa mutator, the Custom mutator (the user can define
its own mutator) and the work is to generalize MOpt for all the current
and future mutators.
Mentor: vanhauser-thc or andreafioraldi
## perf-fuzz Linux Kernel Module ## perf-fuzz Linux Kernel Module
Either Port the patch to the upcoming Ubuntu LTS 20.04 default kernel Expand on [snapshot LKM](https://github.com/AFLplusplus/AFL-Snapshot-LKM)
and provide a qemu-kvm image or find a different userspace snapshot To make it thread safe, can snapshot several processes at once and increase
solution that has a good performance and is reliable, e.g. with docker. overall performance.
[perf-fuzz](https://gts3.org/assets/papers/2017/xu:os-fuzz.pdf)
The perf-fuzz kernel can be found at [https://github.com/sslab-gatech/perf-fuzz](https://github.com/sslab-gatech/perf-fuzz)
There also is/was a FreeBSD project at [https://github.com/veracode-research/freebsd-perf-fuzz](https://github.com/veracode-research/freebsd-perf-fuzz)
This enables snapshot fuzzing on Linux with an incredible performance!
Mentor: any Mentor: any
Idea/Issue tracker: [https://github.com/AFLplusplus/AFLplusplus/issues/248](https://github.com/AFLplusplus/AFLplusplus/issues/248)
## QEMU 4-based Instrumentation ## QEMU 5-based Instrumentation
First tests to use QEMU 4 for binary-only AFL++ showed that caching behavior First tests to use QEMU 4 for binary-only AFL++ showed that caching behavior
changed, which vastly decreases fuzzing speeds. changed, which vastly decreases fuzzing speeds.
This is the cause why, right now, we cannot switch to QEMU 4.2. In this task test if QEMU 5 performs better and port the afl++ QEMU 3.1
patches to QEMU 5.
Understanding the current instrumentation and fixing the current caching Understanding the current instrumentation and fixing the current caching
issues will be needed. issues will be needed.
@ -86,7 +66,7 @@ Either improve a single mutator thorugh learning of many different bugs
Mentor: domenukk Mentor: domenukk
## Reengineer `afl-fuzz` as Thread Safe, Embeddable Library ## Reengineer `afl-fuzz` as Thread Safe, Embeddable Library (currently in development)
Right now, afl-fuzz is single threaded, cannot safely be embedded in tools, Right now, afl-fuzz is single threaded, cannot safely be embedded in tools,
and not multi-threaded. It makes use of a large number of globals, must always and not multi-threaded. It makes use of a large number of globals, must always

View File

@ -21,6 +21,7 @@ We find that AFL's exploitation-based constant schedule assigns **too much energ
| `-p exploit` (AFL) | ![LIN](http://latex.codecogs.com/gif.latex?p%28i%29%20%3D%20%5Calpha%28i%29) | | `-p exploit` (AFL) | ![LIN](http://latex.codecogs.com/gif.latex?p%28i%29%20%3D%20%5Calpha%28i%29) |
| `-p mmopt` | Experimental: `explore` with no weighting to runtime and increased weighting on the last 5 queue entries | | `-p mmopt` | Experimental: `explore` with no weighting to runtime and increased weighting on the last 5 queue entries |
| `-p rare` | Experimental: `rare` puts focus on queue entries that hit rare edges | | `-p rare` | Experimental: `rare` puts focus on queue entries that hit rare edges |
| `-p seek` | Experimental: `seek` is EXPLORE but ignoring the runtime of the queue input and less focus on the size |
where *α(i)* is the performance score that AFL uses to compute for the seed input *i*, *β(i)>1* is a constant, *s(i)* is the number of times that seed *i* has been chosen from the queue, *f(i)* is the number of generated inputs that exercise the same path as seed *i*, and *μ* is the average number of generated inputs exercising a path. where *α(i)* is the performance score that AFL uses to compute for the seed input *i*, *β(i)>1* is a constant, *s(i)* is the number of times that seed *i* has been chosen from the queue, *f(i)* is the number of generated inputs that exercise the same path as seed *i*, and *μ* is the average number of generated inputs exercising a path.
More details can be found in the paper that was accepted at the [23rd ACM Conference on Computer and Communications Security (CCS'16)](https://www.sigsac.org/ccs/CCS2016/accepted-papers/). More details can be found in the paper that was accepted at the [23rd ACM Conference on Computer and Communications Security (CCS'16)](https://www.sigsac.org/ccs/CCS2016/accepted-papers/).

View File

@ -7,19 +7,22 @@ ifneq "" "$(LLVM_BINDIR)"
LLVM_BINDIR := $(LLVM_BINDIR)/ LLVM_BINDIR := $(LLVM_BINDIR)/
endif endif
FLAGS=-O3 -funroll-loops FLAGS=-O3 -funroll-loops -g
all: libAFLDriver.a libAFLQemuDriver.a aflpp_qemu_driver_hook.so all: libAFLDriver.a libAFLQemuDriver.a aflpp_qemu_driver_hook.so
aflpp_driver.o: aflpp_driver.cpp aflpp_driver.o: aflpp_driver.cpp
$(LLVM_BINDIR)clang++ $(FLAGS) -stdlib=libc++ -funroll-loops -std=c++11 -c aflpp_driver.cpp $(LLVM_BINDIR)clang++ $(FLAGS) -stdlib=libc++ -std=c++11 -c aflpp_driver.cpp
libAFLDriver.a: aflpp_driver.o libAFLDriver.a: aflpp_driver.o
ar ru libAFLDriver.a aflpp_driver.o ar ru libAFLDriver.a aflpp_driver.o
debug: debug:
$(LLVM_BINDIR)clang++ -I../../include -D_DEBUG=\"1\" $(FLAGS) -stdlib=libc++ -funroll-loops -std=c++11 -c aflpp_driver.cpp $(LLVM_BINDIR)clang++ -Wno-deprecated -I../../include $(FLAGS) -D_DEBUG=\"1\" -c -o afl-performance.o ../../src/afl-performance.c
ar ru libAFLDriver.a aflpp_driver.o $(LLVM_BINDIR)clang++ -I../../include -D_DEBUG=\"1\" -g -stdlib=libc++ -funroll-loops -std=c++11 -c aflpp_driver.cpp
#$(LLVM_BINDIR)clang++ -S -emit-llvm -Wno-deprecated -I../../include $(FLAGS) -D_DEBUG=\"1\" -c -o afl-performance.ll ../../src/afl-performance.c
#$(LLVM_BINDIR)clang++ -S -emit-llvm -I../../include -D_DEBUG=\"1\" -g -stdlib=libc++ -funroll-loops -std=c++11 -c aflpp_driver.cpp
ar ru libAFLDriver.a afl-performance.o aflpp_driver.o
aflpp_qemu_driver.o: aflpp_qemu_driver.c aflpp_qemu_driver.o: aflpp_qemu_driver.c
$(LLVM_BINDIR)clang $(FLAGS) -O0 -funroll-loops -c aflpp_qemu_driver.c $(LLVM_BINDIR)clang $(FLAGS) -O0 -funroll-loops -c aflpp_qemu_driver.c
@ -33,8 +36,9 @@ aflpp_qemu_driver_hook.so: aflpp_qemu_driver_hook.o
aflpp_qemu_driver_hook.o: aflpp_qemu_driver_hook.c aflpp_qemu_driver_hook.o: aflpp_qemu_driver_hook.c
$(LLVM_BINDIR)clang -fPIC $(FLAGS) -funroll-loops -c aflpp_qemu_driver_hook.c $(LLVM_BINDIR)clang -fPIC $(FLAGS) -funroll-loops -c aflpp_qemu_driver_hook.c
test: libAFLDriver.a aflpp_driver_test.cpp test: debug
afl-clang-fast++ -I../../include -Wl,--allow-multiple-definition -stdlib=libc++ -funroll-loops -std=c++11 -o aflpp_driver_test aflpp_driver_test.cpp libAFLDriver.a #clang++ -S -emit-llvm -D_DEBUG=\"1\" -I../../include -Wl,--allow-multiple-definition -stdlib=libc++ -funroll-loops -std=c++11 -o aflpp_driver_test.ll aflpp_driver_test.cpp
afl-clang-fast++ -D_DEBUG=\"1\" -I../../include -Wl,--allow-multiple-definition -stdlib=libc++ -funroll-loops -std=c++11 -o aflpp_driver_test aflpp_driver_test.cpp libAFLDriver.a
clean: clean:
rm -f *.o libAFLDriver*.a libAFLQemuDriver.a aflpp_qemu_driver_hook.so *~ core aflpp_driver_test rm -f *.o libAFLDriver*.a libAFLQemuDriver.a aflpp_qemu_driver_hook.so *~ core aflpp_driver_test

View File

@ -277,7 +277,7 @@ int main(int argc, char **argv) {
int num_runs = 0; int num_runs = 0;
while (__afl_persistent_loop(N)) { while (__afl_persistent_loop(N)) {
#ifdef _DEBUG #ifdef _DEBUG
fprintf(stderr, "CLIENT crc: %08x len: %u\n", hash32(__afl_fuzz_ptr, *__afl_fuzz_len, 0xa5b35705), *__afl_fuzz_len); fprintf(stderr, "CLIENT crc: %016llx len: %u\n", hash64(__afl_fuzz_ptr, *__afl_fuzz_len, 0xa5b35705), *__afl_fuzz_len);
fprintf(stderr, "RECV:"); fprintf(stderr, "RECV:");
for (int i = 0; i < *__afl_fuzz_len; i++) for (int i = 0; i < *__afl_fuzz_len; i++)
fprintf(stderr, "%02x", __afl_fuzz_ptr[i]); fprintf(stderr, "%02x", __afl_fuzz_ptr[i]);

View File

@ -5,7 +5,7 @@
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
fprintf(stderr, "FUNC crc: %08x len: %lu\n", hash32(Data, Size, 0xa5b35705), Size); fprintf(stderr, "FUNC crc: %016llx len: %lu\n", hash64((u8*)Data, (unsigned int) Size, (unsigned long long int) 0xa5b35705), Size);
if (Size < 5) if (Size < 5)
return 0; return 0;

View File

@ -49,9 +49,13 @@ int main(int argc, char **argv) {
len = __AFL_FUZZ_TESTCASE_LEN; len = __AFL_FUZZ_TESTCASE_LEN;
fprintf(stderr, "input: %zd \"%s\"\n", len, buf);
/* do we have enough data? */ /* do we have enough data? */
if (len < 8) continue; if (len < 8) continue;
if (strcmp((char *)buf, "thisisateststring") == 0) printf("teststring\n");
if (buf[0] == 'f') { if (buf[0] == 'f') {
printf("one\n"); printf("one\n");

View File

@ -29,10 +29,11 @@ MAN_PATH ?= $(PREFIX)/man/man8
VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2) VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2)
CFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=2 CFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=2
CFLAGS = -Wall -I../include -Wno-pointer-sign \ CFLAGS_SAFE := -Wall -I../include -Wno-pointer-sign \
-DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \ -DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
-DGCC_VERSION=\"$(GCCVER)\" -DGCC_BINDIR=\"$(GCCBINDIR)\" \ -DGCC_VERSION=\"$(GCCVER)\" -DGCC_BINDIR=\"$(GCCBINDIR)\" \
-Wno-unused-function -Wno-unused-function
override CFLAGS += $(CFLAGS_SAFE)
CXXFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=2 CXXFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=2
CXXEFLAGS := $(CXXFLAGS) -Wall CXXEFLAGS := $(CXXFLAGS) -Wall
@ -60,12 +61,12 @@ ifeq "$(shell echo '$(HASH)include <sys/ipc.h>@$(HASH)include <sys/shm.h>@int ma
SHMAT_OK=1 SHMAT_OK=1
else else
SHMAT_OK=0 SHMAT_OK=0
CFLAGS+=-DUSEMMAP=1 override CFLAGS += -DUSEMMAP=1
endif endif
ifeq "$(TEST_MMAP)" "1" ifeq "$(TEST_MMAP)" "1"
SHMAT_OK=0 SHMAT_OK=0
CFLAGS+=-DUSEMMAP=1 override CFLAGS += -DUSEMMAP=1
endif endif
ifneq "$(shell uname -s)" "Haiku" ifneq "$(shell uname -s)" "Haiku"
@ -113,7 +114,7 @@ afl-common.o: ../src/afl-common.c
$(CXX) $(CXXEFLAGS) $(PLUGIN_FLAGS) -shared $< -o $@ $(CXX) $(CXXEFLAGS) $(PLUGIN_FLAGS) -shared $< -o $@
../afl-gcc-rt.o: afl-gcc-rt.o.c | test_deps ../afl-gcc-rt.o: afl-gcc-rt.o.c | test_deps
$(CC) $(CFLAGS) -fPIC -c $< -o $@ $(CC) $(CFLAGS_SAFE) -fPIC -c $< -o $@
test_build: $(PROGS) test_build: $(PROGS)
@echo "[*] Testing the CC wrapper and instrumentation output..." @echo "[*] Testing the CC wrapper and instrumentation output..."

View File

@ -49,6 +49,7 @@
#include "sharedmem.h" #include "sharedmem.h"
#include "forkserver.h" #include "forkserver.h"
#include "common.h" #include "common.h"
#include "hash.h"
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
@ -188,10 +189,11 @@ enum {
/* 15 */ STAGE_HAVOC, /* 15 */ STAGE_HAVOC,
/* 16 */ STAGE_SPLICE, /* 16 */ STAGE_SPLICE,
/* 17 */ STAGE_PYTHON, /* 17 */ STAGE_PYTHON,
/* 18 */ STAGE_RADAMSA, /* 18 */ STAGE_CUSTOM_MUTATOR,
/* 19 */ STAGE_CUSTOM_MUTATOR, /* 19 */ STAGE_COLORIZATION,
/* 20 */ STAGE_COLORIZATION, /* 20 */ STAGE_ITS,
/* 21 */ STAGE_ITS,
STAGE_NUM_MAX
}; };
@ -233,6 +235,7 @@ enum {
/* 05 */ QUAD, /* Quadratic schedule */ /* 05 */ QUAD, /* Quadratic schedule */
/* 06 */ RARE, /* Rare edges */ /* 06 */ RARE, /* Rare edges */
/* 07 */ MMOPT, /* Modified MOPT schedule */ /* 07 */ MMOPT, /* Modified MOPT schedule */
/* 08 */ SEEK, /* EXPLORE that ignores timings */
POWER_SCHEDULES_NUM POWER_SCHEDULES_NUM
@ -426,9 +429,6 @@ typedef struct afl_state {
u8 schedule; /* Power schedule (default: EXPLORE)*/ u8 schedule; /* Power schedule (default: EXPLORE)*/
u8 havoc_max_mult; u8 havoc_max_mult;
u8 use_radamsa;
size_t (*radamsa_mutate_ptr)(u8 *, size_t, u8 *, size_t, u32);
u8 skip_deterministic, /* Skip deterministic stages? */ u8 skip_deterministic, /* Skip deterministic stages? */
use_splicing, /* Recombine input files? */ use_splicing, /* Recombine input files? */
non_instrumented_mode, /* Run in non-instrumented mode? */ non_instrumented_mode, /* Run in non-instrumented mode? */
@ -972,13 +972,16 @@ static inline u32 rand_below(afl_state_t *afl, u32 limit) {
} }
static inline u32 get_rand_seed(afl_state_t *afl) { static inline s64 rand_get_seed(afl_state_t *afl) {
if (unlikely(afl->fixed_seed)) { return (u32)afl->init_seed; } if (unlikely(afl->fixed_seed)) { return afl->init_seed; }
return afl->rand_seed[0]; return afl->rand_seed[0];
} }
/* initialize randomness with a given seed. Can be called again at any time. */
void rand_set_seed(afl_state_t *afl, s64 init_seed);
/* Find first power of two greater or equal to val (assuming val under /* Find first power of two greater or equal to val (assuming val under
2^63). */ 2^63). */

View File

@ -60,7 +60,7 @@ typedef enum prealloc_status {
\ \
if ((prealloc_counter) >= (prealloc_size)) { \ if ((prealloc_counter) >= (prealloc_size)) { \
\ \
el_ptr = malloc(sizeof(*el_ptr)); \ el_ptr = (void *)malloc(sizeof(*el_ptr)); \
if (!el_ptr) { FATAL("error in list.h -> out of memory for element!"); } \ if (!el_ptr) { FATAL("error in list.h -> out of memory for element!"); } \
el_ptr->pre_status = PRE_STATUS_MALLOC; \ el_ptr->pre_status = PRE_STATUS_MALLOC; \
\ \

View File

@ -170,10 +170,10 @@ static inline u8 *DFL_ck_strdup(u8 *str) {
size = strlen((char *)str) + 1; size = strlen((char *)str) + 1;
ALLOC_CHECK_SIZE(size); ALLOC_CHECK_SIZE(size);
ret = malloc(size); ret = (u8 *)malloc(size);
ALLOC_CHECK_RESULT(ret, size); ALLOC_CHECK_RESULT(ret, size);
return memcpy(ret, str, size); return (u8 *)memcpy(ret, str, size);
} }
@ -204,7 +204,7 @@ static inline u8 *DFL_ck_memdup_str(u8 *mem, u32 size) {
if (!mem || !size) { return NULL; } if (!mem || !size) { return NULL; }
ALLOC_CHECK_SIZE(size); ALLOC_CHECK_SIZE(size);
ret = malloc(size + 1); ret = (u8 *)malloc(size + 1);
ALLOC_CHECK_RESULT(ret, size); ALLOC_CHECK_RESULT(ret, size);
memcpy(ret, mem, size); memcpy(ret, mem, size);

View File

@ -262,7 +262,7 @@
\ \
} while (0) } while (0)
/* Die with FAULT() or PFAULT() depending on the value of res (used to /* Die with FATAL() or PFATAL() depending on the value of res (used to
interpret different failure modes for read(), write(), etc). */ interpret different failure modes for read(), write(), etc). */
#define RPFATAL(res, x...) \ #define RPFATAL(res, x...) \

View File

@ -30,8 +30,8 @@
#include "types.h" #include "types.h"
u32 hash32(const void *key, u32 len, u32 seed); u32 hash32(u8 *key, u32 len, u32 seed);
u64 hash64(const void *key, u32 len, u64 seed); u64 hash64(u8 *key, u32 len, u64 seed);
#if 0 #if 0
@ -41,7 +41,7 @@ The following code is disabled because xxh3 is 30% faster
#define ROL64(_x, _r) ((((u64)(_x)) << (_r)) | (((u64)(_x)) >> (64 - (_r)))) #define ROL64(_x, _r) ((((u64)(_x)) << (_r)) | (((u64)(_x)) >> (64 - (_r))))
static inline u32 hash32(const void *key, u32 len, u32 seed) { static inline u32 hash32(u8 *key, u32 len, u32 seed) {
const u64 *data = (u64 *)key; const u64 *data = (u64 *)key;
u64 h1 = seed ^ len; u64 h1 = seed ^ len;

View File

@ -38,6 +38,8 @@ typedef struct sharedmem {
/* ================ Proteas ================ */ /* ================ Proteas ================ */
int g_shm_fd; int g_shm_fd;
char g_shm_file_path[L_tmpnam]; char g_shm_file_path[L_tmpnam];
int cmplog_g_shm_fd;
char cmplog_g_shm_file_path[L_tmpnam];
/* ========================================= */ /* ========================================= */
#else #else
s32 shm_id; /* ID of the SHM region */ s32 shm_id; /* ID of the SHM region */

View File

@ -48,6 +48,7 @@ typedef uint32_t u32;
#define FS_OPT_SNAPSHOT 0x20000000 #define FS_OPT_SNAPSHOT 0x20000000
#define FS_OPT_AUTODICT 0x10000000 #define FS_OPT_AUTODICT 0x10000000
#define FS_OPT_SHDMEM_FUZZ 0x01000000 #define FS_OPT_SHDMEM_FUZZ 0x01000000
#define FS_OPT_OLD_AFLPP_WORKAROUND 0x0f000000
// FS_OPT_MAX_MAPSIZE is 8388608 = 0x800000 = 2^23 = 1 << 22 // FS_OPT_MAX_MAPSIZE is 8388608 = 0x800000 = 2^23 = 1 << 22
#define FS_OPT_MAX_MAPSIZE ((0x00fffffe >> 1) + 1) #define FS_OPT_MAX_MAPSIZE ((0x00fffffe >> 1) + 1)
#define FS_OPT_GET_MAPSIZE(x) (((x & 0x00fffffe) >> 1) + 1) #define FS_OPT_GET_MAPSIZE(x) (((x & 0x00fffffe) >> 1) + 1)

View File

@ -37,9 +37,12 @@
#include <sys/param.h> #include <sys/param.h>
#endif #endif
#if defined(__linux__) && !defined(__ANDROID__) #if (defined(__linux__) && !defined(__ANDROID__)) || defined(__HAIKU__)
#include <unistd.h> #include <unistd.h>
#ifdef __linux__
#include <sys/syscall.h> #include <sys/syscall.h>
#include <malloc.h>
#endif
#ifdef __NR_getrandom #ifdef __NR_getrandom
#define arc4random_buf(p, l) \ #define arc4random_buf(p, l) \
do { \ do { \

View File

@ -38,7 +38,8 @@ ______OS_DL = $(_____OS_DL:$(_UNIQ)="-ldl")
_OS_TARGET = $(____OS_DL:$(_UNIQ)FreeBSD=$(_UNIQ)) _OS_TARGET = $(____OS_DL:$(_UNIQ)FreeBSD=$(_UNIQ))
__OS_TARGET = $(_OS_TARGET:$(_UNIQ)OpenBSD=$(_UNIQ)) __OS_TARGET = $(_OS_TARGET:$(_UNIQ)OpenBSD=$(_UNIQ))
___OS_TARGET = $(__OS_TARGET:$(_UNIQ)NetBSD=$(_UNIQ)) ___OS_TARGET = $(__OS_TARGET:$(_UNIQ)NetBSD=$(_UNIQ))
____OS_TARGET = $(___OS_TARGET:$(_UNIQ)$(UNAME_S)=) ____OS_TARGET = $(___OS_TARGET:$(_UNIQ)Haiku=$(_UNIQ))
_____OS_TARGET = $(___OS_TARGET:$(_UNIQ)$(UNAME_S)=)
TARGETS = $(____OS_TARGET:$(_UNIQ)=libtokencap.so) TARGETS = $(____OS_TARGET:$(_UNIQ)=libtokencap.so)

View File

@ -34,7 +34,8 @@
#include "../config.h" #include "../config.h"
#if !defined __linux__ && !defined __APPLE__ && !defined __FreeBSD__ && \ #if !defined __linux__ && !defined __APPLE__ && !defined __FreeBSD__ && \
!defined __OpenBSD__ && !defined __NetBSD__ && !defined __DragonFly__ !defined __OpenBSD__ && !defined __NetBSD__ && !defined __DragonFly__ && \
!defined(__HAIKU__)
#error "Sorry, this library is unsupported in this platform for now!" #error "Sorry, this library is unsupported in this platform for now!"
#endif /* !__linux__ && !__APPLE__ && ! __FreeBSD__ && ! __OpenBSD__ && \ #endif /* !__linux__ && !__APPLE__ && ! __FreeBSD__ && ! __OpenBSD__ && \
!__NetBSD__*/ !__NetBSD__*/
@ -49,6 +50,8 @@
#include <sys/user.h> #include <sys/user.h>
#endif #endif
#include <sys/mman.h> #include <sys/mman.h>
#elif defined __HAIKU__
#include <kernel/image.h>
#endif #endif
#include <dlfcn.h> #include <dlfcn.h>
@ -230,6 +233,19 @@ static void __tokencap_load_mappings(void) {
} }
munmap(buf, len); munmap(buf, len);
#elif defined __HAIKU__
image_info ii;
int32_t group = 0;
while (get_next_image_info(0, &group, &ii) == B_OK) {
__tokencap_ro[__tokencap_ro_cnt].st = ii.text;
__tokencap_ro[__tokencap_ro_cnt].en = ((char *)ii.text) + ii.text_size;
if (++__tokencap_ro_cnt == MAX_MAPPINGS) break;
}
#endif #endif
} }

View File

@ -196,24 +196,31 @@ ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -fuse-ld=`com
endif endif
endif endif
CFLAGS ?= -O3 -funroll-loops -fpic -D_FORTIFY_SOURCE=2 CFLAGS ?= -O3 -funroll-loops -fPIC -D_FORTIFY_SOURCE=2
override CFLAGS += -Wall \ CFLAGS_SAFE := -Wall -g -Wno-pointer-sign -I ../include/ \
-g -Wno-pointer-sign -I ../include/ \
-DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \ -DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
-DLLVM_BINDIR=\"$(LLVM_BINDIR)\" -DVERSION=\"$(VERSION)\" \ -DLLVM_BINDIR=\"$(LLVM_BINDIR)\" -DVERSION=\"$(VERSION)\" \
-DLLVM_LIBDIR=\"$(LLVM_LIBDIR)\" -DLLVM_VERSION=\"$(LLVMVER)\" \ -DLLVM_LIBDIR=\"$(LLVM_LIBDIR)\" -DLLVM_VERSION=\"$(LLVMVER)\" \
-DAFL_CLANG_FLTO=\"$(AFL_CLANG_FLTO)\" \ -DAFL_CLANG_FLTO=\"$(AFL_CLANG_FLTO)\" \
-DAFL_REAL_LD=\"$(AFL_REAL_LD)\" -DAFL_CLANG_FUSELD=\"$(AFL_CLANG_FUSELD)\" \ -DAFL_REAL_LD=\"$(AFL_REAL_LD)\" -DAFL_CLANG_FUSELD=\"$(AFL_CLANG_FUSELD)\" \
-DCLANG_BIN=\"$(CLANG_BIN)\" -DCLANGPP_BIN=\"$(CLANGPP_BIN)\" -DUSE_BINDIR=$(USE_BINDIR) -Wno-unused-function -DCLANG_BIN=\"$(CLANG_BIN)\" -DCLANGPP_BIN=\"$(CLANGPP_BIN)\" -DUSE_BINDIR=$(USE_BINDIR) -Wno-unused-function
override CFLAGS += $(CFLAGS_SAFE)
ifdef AFL_TRACE_PC ifdef AFL_TRACE_PC
$(info Compile option AFL_TRACE_PC is deprecated, just set AFL_LLVM_INSTRUMENT=PCGUARD to activate when compiling targets ) $(info Compile option AFL_TRACE_PC is deprecated, just set AFL_LLVM_INSTRUMENT=PCGUARD to activate when compiling targets )
endif endif
CXXFLAGS ?= -O3 -funroll-loops -fpic -D_FORTIFY_SOURCE=2 CXXFLAGS ?= -O3 -funroll-loops -fPIC -D_FORTIFY_SOURCE=2
override CXXFLAGS += -Wall -g -I ../include/ \ override CXXFLAGS += -Wall -g -I ../include/ \
-DVERSION=\"$(VERSION)\" -Wno-variadic-macros -DVERSION=\"$(VERSION)\" -Wno-variadic-macros
CLANG_CFL = `$(LLVM_CONFIG) --cxxflags` -fno-rtti -fpic $(CXXFLAGS) ifneq "$(shell $(LLVM_CONFIG) --includedir) 2> /dev/null" ""
CLANG_CFL = -I$(shell $(LLVM_CONFIG) --includedir)
endif
ifneq "$(LLVM_CONFIG)" ""
CLANG_CFL += -I$(shell dirname $(LLVM_CONFIG))/../include
endif
CLANG_CPPFL = `$(LLVM_CONFIG) --cxxflags` -fno-rtti -fPIC $(CXXFLAGS)
CLANG_LFL = `$(LLVM_CONFIG) --ldflags` $(LDFLAGS) CLANG_LFL = `$(LLVM_CONFIG) --ldflags` $(LDFLAGS)
@ -221,12 +228,12 @@ CLANG_LFL = `$(LLVM_CONFIG) --ldflags` $(LDFLAGS)
ifeq "$(shell uname)" "Darwin" ifeq "$(shell uname)" "Darwin"
CLANG_LFL += -Wl,-flat_namespace -Wl,-undefined,suppress CLANG_LFL += -Wl,-flat_namespace -Wl,-undefined,suppress
else else
CLANG_CFL += -Wl,-znodelete CLANG_CPPFL += -Wl,-znodelete
endif endif
ifeq "$(shell uname)" "OpenBSD" ifeq "$(shell uname)" "OpenBSD"
CLANG_LFL += `$(LLVM_CONFIG) --libdir`/libLLVM.so CLANG_LFL += `$(LLVM_CONFIG) --libdir`/libLLVM.so
CLANG_CFL += -mno-retpoline CLANG_CPPFL += -mno-retpoline
CFLAGS += -mno-retpoline CFLAGS += -mno-retpoline
# Needed for unwind symbols # Needed for unwind symbols
LDFLAGS += -lc++abi LDFLAGS += -lc++abi
@ -304,7 +311,7 @@ afl-common.o: ../src/afl-common.c
$(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS) $(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS)
../afl-clang-fast: afl-clang-fast.c afl-common.o | test_deps ../afl-clang-fast: afl-clang-fast.c afl-common.o | test_deps
$(CC) $(CFLAGS) $< afl-common.o -o $@ $(LDFLAGS) -DCFLAGS_OPT=\"$(CFLAGS_OPT)\" $(CC) $(CLANG_CFL) $(CFLAGS) $< afl-common.o -o $@ $(LDFLAGS) -DCFLAGS_OPT=\"$(CFLAGS_OPT)\"
ln -sf afl-clang-fast ../afl-clang-fast++ ln -sf afl-clang-fast ../afl-clang-fast++
ifneq "$(AFL_CLANG_FLTO)" "" ifneq "$(AFL_CLANG_FLTO)" ""
ifeq "$(LLVM_LTO)" "1" ifeq "$(LLVM_LTO)" "1"
@ -317,17 +324,17 @@ afl-llvm-common.o: afl-llvm-common.cc afl-llvm-common.h
$(CXX) $(CFLAGS) `$(LLVM_CONFIG) --cxxflags` -fno-rtti -fPIC -std=$(LLVM_STDCXX) -c $< -o $@ $(CXX) $(CFLAGS) `$(LLVM_CONFIG) --cxxflags` -fno-rtti -fPIC -std=$(LLVM_STDCXX) -c $< -o $@
../libLLVMInsTrim.so: LLVMInsTrim.so.cc MarkNodes.cc afl-llvm-common.o | test_deps ../libLLVMInsTrim.so: LLVMInsTrim.so.cc MarkNodes.cc afl-llvm-common.o | test_deps
-$(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) afl-llvm-common.o -$(CXX) $(CLANG_CPPFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) afl-llvm-common.o
../afl-llvm-pass.so: afl-llvm-pass.so.cc afl-llvm-common.o | test_deps ../afl-llvm-pass.so: afl-llvm-pass.so.cc afl-llvm-common.o | test_deps
ifeq "$(LLVM_MIN_4_0_1)" "0" ifeq "$(LLVM_MIN_4_0_1)" "0"
$(info [!] N-gram branch coverage instrumentation is not available for llvm version $(LLVMVER)) $(info [!] N-gram branch coverage instrumentation is not available for llvm version $(LLVMVER))
endif endif
$(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o $(CXX) $(CLANG_CPPFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
../afl-llvm-lto-whitelist.so: afl-llvm-lto-whitelist.so.cc afl-llvm-common.o ../afl-llvm-lto-whitelist.so: afl-llvm-lto-whitelist.so.cc afl-llvm-common.o
ifeq "$(LLVM_LTO)" "1" ifeq "$(LLVM_LTO)" "1"
$(CXX) $(CLANG_CFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o $(CXX) $(CLANG_CPPFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
endif endif
../afl-ld-lto: afl-ld-lto.c ../afl-ld-lto: afl-ld-lto.c
@ -337,47 +344,47 @@ endif
../afl-llvm-lto-instrumentation.so: afl-llvm-lto-instrumentation.so.cc afl-llvm-common.o ../afl-llvm-lto-instrumentation.so: afl-llvm-lto-instrumentation.so.cc afl-llvm-common.o
ifeq "$(LLVM_LTO)" "1" ifeq "$(LLVM_LTO)" "1"
$(CXX) $(CLANG_CFL) -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o $(CXX) $(CLANG_CPPFL) -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
$(CLANG_BIN) $(CFLAGS) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -fPIC -c afl-llvm-rt-lto.o.c -o ../afl-llvm-rt-lto.o $(CLANG_BIN) $(CFLAGS_SAFE) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -fPIC -c afl-llvm-rt-lto.o.c -o ../afl-llvm-rt-lto.o
@$(CLANG_BIN) $(CFLAGS) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -m64 -fPIC -c afl-llvm-rt-lto.o.c -o ../afl-llvm-rt-lto-64.o 2>/dev/null; if [ "$$?" = "0" ]; then : ; fi @$(CLANG_BIN) $(CFLAGS_SAFE) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -m64 -fPIC -c afl-llvm-rt-lto.o.c -o ../afl-llvm-rt-lto-64.o 2>/dev/null; if [ "$$?" = "0" ]; then : ; fi
@$(CLANG_BIN) $(CFLAGS) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -m32 -fPIC -c afl-llvm-rt-lto.o.c -o ../afl-llvm-rt-lto-32.o 2>/dev/null; if [ "$$?" = "0" ]; then : ; fi @$(CLANG_BIN) $(CFLAGS_SAFE) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -m32 -fPIC -c afl-llvm-rt-lto.o.c -o ../afl-llvm-rt-lto-32.o 2>/dev/null; if [ "$$?" = "0" ]; then : ; fi
endif endif
../afl-llvm-lto-instrim.so: afl-llvm-lto-instrim.so.cc afl-llvm-common.o ../afl-llvm-lto-instrim.so: afl-llvm-lto-instrim.so.cc afl-llvm-common.o
ifeq "$(LLVM_LTO)" "1" ifeq "$(LLVM_LTO)" "1"
$(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) afl-llvm-common.o $(CXX) $(CLANG_CPPFL) -DLLVMInsTrim_EXPORTS -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) afl-llvm-common.o
endif endif
# laf # laf
../split-switches-pass.so: split-switches-pass.so.cc afl-llvm-common.o | test_deps ../split-switches-pass.so: split-switches-pass.so.cc afl-llvm-common.o | test_deps
$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o $(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
../compare-transform-pass.so: compare-transform-pass.so.cc afl-llvm-common.o | test_deps ../compare-transform-pass.so: compare-transform-pass.so.cc afl-llvm-common.o | test_deps
$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o $(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
../split-compares-pass.so: split-compares-pass.so.cc afl-llvm-common.o | test_deps ../split-compares-pass.so: split-compares-pass.so.cc afl-llvm-common.o | test_deps
$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o $(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
# /laf # /laf
../cmplog-routines-pass.so: cmplog-routines-pass.cc afl-llvm-common.o | test_deps ../cmplog-routines-pass.so: cmplog-routines-pass.cc afl-llvm-common.o | test_deps
$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o $(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
../cmplog-instructions-pass.so: cmplog-instructions-pass.cc afl-llvm-common.o | test_deps ../cmplog-instructions-pass.so: cmplog-instructions-pass.cc afl-llvm-common.o | test_deps
$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o $(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
document: document:
$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) -Wno-unused-result -fPIC -c afl-llvm-rt.o.c -o ../afl-llvm-rt.o $(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS_SAFE) -O3 -Wno-unused-result -fPIC -c afl-llvm-rt.o.c -o ../afl-llvm-rt.o
@$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) -Wno-unused-result -m32 -fPIC -c afl-llvm-rt.o.c -o ../afl-llvm-rt-32.o 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi @$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS_SAFE) -O3 -Wno-unused-result -m32 -fPIC -c afl-llvm-rt.o.c -o ../afl-llvm-rt-32.o 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
@$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) -Wno-unused-result -m64 -fPIC -c afl-llvm-rt.o.c -o ../afl-llvm-rt-64.o 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi @$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS_SAFE) -O3 -Wno-unused-result -m64 -fPIC -c afl-llvm-rt.o.c -o ../afl-llvm-rt-64.o 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
../afl-llvm-rt.o: afl-llvm-rt.o.c | test_deps ../afl-llvm-rt.o: afl-llvm-rt.o.c | test_deps
$(CLANG_BIN) $(CFLAGS) -Wno-unused-result -fPIC -c $< -o $@ $(CLANG_BIN) $(CFLAGS_SAFE) -O3 -Wno-unused-result -fPIC -c $< -o $@
../afl-llvm-rt-32.o: afl-llvm-rt.o.c | test_deps ../afl-llvm-rt-32.o: afl-llvm-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) $(CFLAGS) -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi @$(CLANG_BIN) $(CFLAGS_SAFE) -O3 -Wno-unused-result -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 ../afl-llvm-rt-64.o: afl-llvm-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) $(CFLAGS) -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi @$(CLANG_BIN) $(CFLAGS_SAFE) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
test_build: $(PROGS) test_build: $(PROGS)
@echo "[*] Testing the CC wrapper and instrumentation output..." @echo "[*] Testing the CC wrapper and instrumentation output..."

View File

@ -103,6 +103,7 @@ struct InsTrim : public ModulePass {
bool runOnModule(Module &M) override { bool runOnModule(Module &M) override {
char be_quiet = 0; char be_quiet = 0;
setvbuf(stdout, NULL, _IONBF, 0);
if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) { if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) {

View File

@ -39,6 +39,8 @@
#include <limits.h> #include <limits.h>
#include <assert.h> #include <assert.h>
#include "llvm/Config/llvm-config.h"
static u8 * obj_path; /* Path to runtime libraries */ static u8 * obj_path; /* Path to runtime libraries */
static u8 **cc_params; /* Parameters passed to the real CC */ static u8 **cc_params; /* Parameters passed to the real CC */
static u32 cc_par_cnt = 1; /* Param count, including argv0 */ static u32 cc_par_cnt = 1; /* Param count, including argv0 */

View File

@ -112,6 +112,9 @@ struct InsTrimLTO : public ModulePass {
char be_quiet = 0; char be_quiet = 0;
char * ptr; char * ptr;
uint32_t locations = 0, functions = 0;
setvbuf(stdout, NULL, _IONBF, 0);
if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) { if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) {
@ -561,6 +564,8 @@ struct InsTrimLTO : public ModulePass {
if (F.size() < function_minimum_size) continue; if (F.size() < function_minimum_size) continue;
if (isBlacklisted(&F)) continue; if (isBlacklisted(&F)) continue;
functions++;
// whitelist check // whitelist check
AttributeList Attrs = F.getAttributes(); AttributeList Attrs = F.getAttributes();
if (Attrs.hasAttribute(-1, StringRef("skipinstrument"))) { if (Attrs.hasAttribute(-1, StringRef("skipinstrument"))) {
@ -657,6 +662,7 @@ struct InsTrimLTO : public ModulePass {
if (PI == PE) { if (PI == PE) {
L = ConstantInt::get(Int32Ty, afl_global_id++); L = ConstantInt::get(Int32Ty, afl_global_id++);
locations++;
} else { } else {
@ -668,6 +674,7 @@ struct InsTrimLTO : public ModulePass {
auto It = PredMap.insert({PBB, afl_global_id++}); auto It = PredMap.insert({PBB, afl_global_id++});
unsigned Label = It.first->second; unsigned Label = It.first->second;
PN->addIncoming(ConstantInt::get(Int32Ty, Label), PBB); PN->addIncoming(ConstantInt::get(Int32Ty, Label), PBB);
locations++;
} }
@ -885,7 +892,7 @@ struct InsTrimLTO : public ModulePass {
for (BasicBlock *Succ : successors(Pred)) for (BasicBlock *Succ : successors(Pred))
if (Succ != NULL) count++; if (Succ != NULL) count++;
if (count > 1) return true; if (count > 1) would_instrument = true;
} }
@ -910,11 +917,12 @@ struct InsTrimLTO : public ModulePass {
getenv("AFL_USE_MSAN") ? ", MSAN" : "", getenv("AFL_USE_MSAN") ? ", MSAN" : "",
getenv("AFL_USE_CFISAN") ? ", CFISAN" : "", getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
getenv("AFL_USE_UBSAN") ? ", UBSAN" : ""); getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
OKF("Instrumented %u locations (%llu, %llu) with no collisions (on " OKF("Instrumented %u locations for %u edges in %u functions (%llu, "
"%llu) with no collisions (on "
"average %llu collisions would be in afl-gcc/afl-clang-fast for %u " "average %llu collisions would be in afl-gcc/afl-clang-fast for %u "
"edges) (%s mode).", "edges) (%s mode).",
inst_blocks, total_rs, total_hs, calculateCollisions(edges), edges, inst_blocks, locations, functions, total_rs, total_hs,
modeline); calculateCollisions(edges), edges, modeline);
} }

View File

@ -109,6 +109,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
IntegerType *Int64Ty = IntegerType::getInt64Ty(C); IntegerType *Int64Ty = IntegerType::getInt64Ty(C);
/* Show a banner */ /* Show a banner */
setvbuf(stdout, NULL, _IONBF, 0);
if ((isatty(2) && !getenv("AFL_QUIET")) || debug) { if ((isatty(2) && !getenv("AFL_QUIET")) || debug) {
@ -162,7 +163,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
} }
if (debug) { fprintf(stderr, "map address is %lu\n", map_addr); } if (debug) { fprintf(stderr, "map address is 0x%lx\n", map_addr); }
/* Get/set the globals for the SHM region. */ /* Get/set the globals for the SHM region. */

View File

@ -111,6 +111,7 @@ bool AFLwhitelist::runOnModule(Module &M) {
/* Show a banner */ /* Show a banner */
char be_quiet = 0; char be_quiet = 0;
setvbuf(stdout, NULL, _IONBF, 0);
if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) { if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) {

View File

@ -140,6 +140,7 @@ bool AFLCoverage::runOnModule(Module &M) {
/* Show a banner */ /* Show a banner */
char be_quiet = 0; char be_quiet = 0;
setvbuf(stdout, NULL, _IONBF, 0);
if (getenv("AFL_DEBUG")) debug = 1; if (getenv("AFL_DEBUG")) debug = 1;

View File

@ -183,6 +183,9 @@ static void __afl_map_shm(void) {
if (__afl_final_loc) { if (__afl_final_loc) {
if (__afl_final_loc % 8)
__afl_final_loc = (((__afl_final_loc + 7) >> 3) << 3);
__afl_map_size = __afl_final_loc; __afl_map_size = __afl_final_loc;
if (__afl_final_loc > MAP_SIZE) { if (__afl_final_loc > MAP_SIZE) {
@ -392,7 +395,10 @@ static void __afl_start_snapshots(void) {
if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1); if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1);
if ((was_killed & (0xffffffff & (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ))) == if (getenv("AFL_DEBUG"))
fprintf(stderr, "target forkserver recv: %08x\n", was_killed);
if ((was_killed & (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) ==
(FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) { (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) {
__afl_map_shm_fuzz(); __afl_map_shm_fuzz();
@ -591,6 +597,9 @@ static void __afl_start_forkserver(void) {
if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1); if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1);
if (getenv("AFL_DEBUG"))
fprintf(stderr, "target forkserver recv: %08x\n", was_killed);
if ((was_killed & (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) == if ((was_killed & (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) ==
(FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) { (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) {
@ -871,7 +880,7 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
while (start < stop) { while (start < stop) {
if (R(100) < inst_ratio) if (R(100) < inst_ratio)
*start = R(MAP_SIZE - 1) + 1; *start = ++__afl_final_loc;
else else
*start = 0; *start = 0;

View File

@ -20,7 +20,8 @@ MAN_PATH ?= $(PREFIX)/man/man8
VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2)
CFLAGS ?= -O3 -funroll-loops -I ../../include/ CFLAGS ?= -O3 -funroll-loops
CFLAGS += -I ../../include/
CFLAGS += -Wall -Wno-unused-result -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign CFLAGS += -Wall -Wno-unused-result -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign
LDFLAGS += -ldl LDFLAGS += -ldl

View File

@ -1049,6 +1049,9 @@ int main(int argc, char **argv, char **envp) {
check_environment_vars(envp); check_environment_vars(envp);
sharedmem_t shm = {0}; sharedmem_t shm = {0};
/* initialize cmplog_mode */
shm.cmplog_mode = 0;
trace_bits = afl_shm_init(&shm, map_size, 0); trace_bits = afl_shm_init(&shm, map_size, 0);
atexit(at_exit_handler); atexit(at_exit_handler);
setup_signal_handlers(); setup_signal_handlers();

View File

@ -54,6 +54,7 @@ char *afl_environment_variables[] = {
"AFL_CMIN_CRASHES_ONLY", "AFL_CODE_END", "AFL_CODE_START", "AFL_CMIN_CRASHES_ONLY", "AFL_CODE_END", "AFL_CODE_START",
"AFL_COMPCOV_BINNAME", "AFL_COMPCOV_LEVEL", "AFL_CUSTOM_MUTATOR_LIBRARY", "AFL_COMPCOV_BINNAME", "AFL_COMPCOV_LEVEL", "AFL_CUSTOM_MUTATOR_LIBRARY",
"AFL_CUSTOM_MUTATOR_ONLY", "AFL_CXX", "AFL_DEBUG", "AFL_DEBUG_CHILD_OUTPUT", "AFL_CUSTOM_MUTATOR_ONLY", "AFL_CXX", "AFL_DEBUG", "AFL_DEBUG_CHILD_OUTPUT",
"AFL_DEBUG_GDB",
//"AFL_DEFER_FORKSRV", // not implemented anymore, so warn additionally //"AFL_DEFER_FORKSRV", // not implemented anymore, so warn additionally
"AFL_DISABLE_TRIM", "AFL_DONT_OPTIMIZE", "AFL_DUMB_FORKSRV", "AFL_DISABLE_TRIM", "AFL_DONT_OPTIMIZE", "AFL_DUMB_FORKSRV",
"AFL_ENTRYPOINT", "AFL_EXIT_WHEN_DONE", "AFL_FAST_CAL", "AFL_FORCE_UI", "AFL_ENTRYPOINT", "AFL_EXIT_WHEN_DONE", "AFL_FAST_CAL", "AFL_FORCE_UI",

View File

@ -525,6 +525,10 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
if ((status & FS_OPT_ENABLED) == FS_OPT_ENABLED) { if ((status & FS_OPT_ENABLED) == FS_OPT_ENABLED) {
// workaround for recent afl++ versions
if ((status & FS_OPT_OLD_AFLPP_WORKAROUND) == FS_OPT_OLD_AFLPP_WORKAROUND)
status = (status & 0xf0ffffff);
if ((status & FS_OPT_SNAPSHOT) == FS_OPT_SNAPSHOT) { if ((status & FS_OPT_SNAPSHOT) == FS_OPT_SNAPSHOT) {
fsrv->snapshot = 1; fsrv->snapshot = 1;
@ -569,7 +573,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
if (unlikely(tmp_map_size % 8)) { if (unlikely(tmp_map_size % 8)) {
// should not happen // should not happen
WARNF("Target reported non-aligned map size of %ud", tmp_map_size); WARNF("Target reported non-aligned map size of %u", tmp_map_size);
tmp_map_size = (((tmp_map_size + 8) >> 3) << 3); tmp_map_size = (((tmp_map_size + 8) >> 3) << 3);
} }
@ -596,9 +600,9 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
// this is not afl-fuzz - we deny and return // this is not afl-fuzz - we deny and return
if (fsrv->use_shmem_fuzz) if (fsrv->use_shmem_fuzz)
status = (FS_OPT_ENABLED | FS_OPT_AUTODICT | FS_OPT_SHDMEM_FUZZ); status = (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ);
else else
status = (FS_OPT_ENABLED | FS_OPT_AUTODICT); status = (FS_OPT_ENABLED);
if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) { if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) {
FATAL("Writing to forkserver failed."); FATAL("Writing to forkserver failed.");
@ -610,7 +614,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
} }
if (!be_quiet) { ACTF("Using AUTODICT feature."); } if (!be_quiet) { ACTF("Using AUTODICT feature."); }
if (fsrv->use_shmem_fuzz)
status = (FS_OPT_ENABLED | FS_OPT_AUTODICT | FS_OPT_SHDMEM_FUZZ);
else
status = (FS_OPT_ENABLED | FS_OPT_AUTODICT); status = (FS_OPT_ENABLED | FS_OPT_AUTODICT);
if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) { if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) {
FATAL("Writing to forkserver failed."); FATAL("Writing to forkserver failed.");
@ -862,7 +871,9 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) {
*fsrv->shmem_fuzz_len = len; *fsrv->shmem_fuzz_len = len;
memcpy(fsrv->shmem_fuzz, buf, len); memcpy(fsrv->shmem_fuzz, buf, len);
#ifdef _DEBUG #ifdef _DEBUG
fprintf(stderr, "FS crc: %08x len: %u\n", if (getenv("AFL_DEBUG")) {
fprintf(stderr, "FS crc: %016llx len: %u\n",
hash64(fsrv->shmem_fuzz, *fsrv->shmem_fuzz_len, 0xa5b35705), hash64(fsrv->shmem_fuzz, *fsrv->shmem_fuzz_len, 0xa5b35705),
*fsrv->shmem_fuzz_len); *fsrv->shmem_fuzz_len);
fprintf(stderr, "SHM :"); fprintf(stderr, "SHM :");
@ -872,6 +883,9 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) {
for (int i = 0; i < *fsrv->shmem_fuzz_len; i++) for (int i = 0; i < *fsrv->shmem_fuzz_len; i++)
fprintf(stderr, "%02x", buf[i]); fprintf(stderr, "%02x", buf[i]);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
}
#endif #endif
} else { } else {

View File

@ -559,7 +559,7 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
if (q->exec_cksum == cksum) { if (q->exec_cksum == cksum) {
q->n_fuzz = q->n_fuzz + 1; ++q->n_fuzz;
break; break;
} }

View File

@ -2128,6 +2128,7 @@ void check_binary(afl_state_t *afl, u8 *fname) {
/* Check for blatant user errors. */ /* Check for blatant user errors. */
/* disabled. not a real-worl scenario where this is a problem.
if ((!strncmp(afl->fsrv.target_path, "/tmp/", 5) && if ((!strncmp(afl->fsrv.target_path, "/tmp/", 5) &&
!strchr(afl->fsrv.target_path + 5, '/')) || !strchr(afl->fsrv.target_path + 5, '/')) ||
(!strncmp(afl->fsrv.target_path, "/var/tmp/", 9) && (!strncmp(afl->fsrv.target_path, "/var/tmp/", 9) &&
@ -2137,6 +2138,8 @@ void check_binary(afl_state_t *afl, u8 *fname) {
} }
*/
fd = open(afl->fsrv.target_path, O_RDONLY); fd = open(afl->fsrv.target_path, O_RDONLY);
if (fd < 0) { PFATAL("Unable to open '%s'", afl->fsrv.target_path); } if (fd < 0) { PFATAL("Unable to open '%s'", afl->fsrv.target_path); }

View File

@ -44,7 +44,7 @@ void setup_custom_mutators(afl_state_t *afl) {
FATAL( FATAL(
"MOpt and custom mutator are mutually exclusive. We accept pull " "MOpt and custom mutator are mutually exclusive. We accept pull "
"requests that integrates MOpt with the optional mutators " "requests that integrates MOpt with the optional mutators "
"(custom/radamsa/redqueen/...)."); "(custom/redqueen/...).");
u8 *fn_token = (u8 *)strsep((char **)&fn, ";:,"); u8 *fn_token = (u8 *)strsep((char **)&fn, ";:,");
@ -89,7 +89,7 @@ void setup_custom_mutators(afl_state_t *afl) {
FATAL( FATAL(
"MOpt and Python mutator are mutually exclusive. We accept pull " "MOpt and Python mutator are mutually exclusive. We accept pull "
"requests that integrates MOpt with the optional mutators " "requests that integrates MOpt with the optional mutators "
"(custom/radamsa/redqueen/...)."); "(custom/redqueen/...).");
} }

View File

@ -953,6 +953,8 @@ u8 fuzz_one_original(afl_state_t *afl) {
if (afl->queue_cur->cal_failed < CAL_CHANCES) { if (afl->queue_cur->cal_failed < CAL_CHANCES) {
afl->queue_cur->exec_cksum = 0;
res = res =
calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, 0); calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, 0);
@ -1013,8 +1015,6 @@ u8 fuzz_one_original(afl_state_t *afl) {
if (unlikely(perf_score == 0)) { goto abandon_entry; } if (unlikely(perf_score == 0)) { goto abandon_entry; }
if (unlikely(afl->use_radamsa > 1)) { goto radamsa_stage; }
if (afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized) { if (afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized) {
if (input_to_state_stage(afl, in_buf, out_buf, len, if (input_to_state_stage(afl, in_buf, out_buf, len,
@ -2144,6 +2144,7 @@ custom_mutator_stage:
retry_external_pick: retry_external_pick:
/* Pick a random other queue entry for passing to external API */ /* Pick a random other queue entry for passing to external API */
do { do {
tid = rand_below(afl, afl->queued_paths); tid = rand_below(afl, afl->queued_paths);
@ -2168,7 +2169,7 @@ custom_mutator_stage:
/* Make sure that the target has a reasonable length. */ /* Make sure that the target has a reasonable length. */
while (target && (target->len < 2 || target == afl->queue_cur) && while (target && (target->len < 2 || target == afl->queue_cur) &&
afl->queued_paths > 1) { afl->queued_paths > 3) {
target = target->next; target = target->next;
++afl->splicing_with; ++afl->splicing_with;
@ -2900,63 +2901,6 @@ retry_splicing:
#endif /* !IGNORE_FINDS */ #endif /* !IGNORE_FINDS */
ret_val = 0; ret_val = 0;
goto radamsa_stage;
radamsa_stage:
if (likely(!afl->use_radamsa || !afl->radamsa_mutate_ptr)) {
goto abandon_entry;
}
afl->stage_name = "radamsa";
afl->stage_short = "radamsa";
afl->stage_max = (HAVOC_CYCLES * perf_score / afl->havoc_div / 100)
<< afl->use_radamsa;
if (afl->stage_max < HAVOC_MIN) { afl->stage_max = HAVOC_MIN; }
orig_hit_cnt = afl->queued_paths + afl->unique_crashes;
/* Read the additional testcase.
We'll reuse in_scratch, as it is free at this point.
*/
u8 *save_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), len);
memcpy(save_buf, out_buf, len);
u32 max_len = len + choose_block_len(afl, HAVOC_BLK_XL);
u8 *new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), max_len);
u8 *tmp_buf;
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
u32 new_len = afl->radamsa_mutate_ptr(save_buf, len, new_buf, max_len,
get_rand_seed(afl));
if (new_len) {
temp_len = new_len;
tmp_buf = new_buf;
} else {
tmp_buf = save_buf; // nope but I dont care
temp_len = len;
}
if (common_fuzz_stuff(afl, tmp_buf, temp_len)) { goto abandon_entry; }
}
new_hit_cnt = afl->queued_paths + afl->unique_crashes;
afl->stage_finds[STAGE_RADAMSA] += new_hit_cnt - orig_hit_cnt;
afl->stage_cycles[STAGE_RADAMSA] += afl->stage_max;
ret_val = 0;
goto abandon_entry;
/* we are through with this queue entry - for this iteration */ /* we are through with this queue entry - for this iteration */
abandon_entry: abandon_entry:
@ -3099,6 +3043,8 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
if (afl->queue_cur->cal_failed < CAL_CHANCES) { if (afl->queue_cur->cal_failed < CAL_CHANCES) {
afl->queue_cur->exec_cksum = 0;
res = res =
calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, 0); calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, 0);

View File

@ -312,13 +312,12 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
u64 fav_factor; u64 fav_factor;
u64 fuzz_p2; u64 fuzz_p2;
if (unlikely(afl->schedule >= FAST)) if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE))
fuzz_p2 = next_pow2(q->n_fuzz); fuzz_p2 = next_pow2(q->n_fuzz);
else else
fuzz_p2 = q->fuzz_level; fuzz_p2 = q->fuzz_level;
if (unlikely(afl->schedule == MMOPT || afl->schedule == RARE) || if (unlikely(afl->schedule >= RARE) || unlikely(afl->fixed_seed)) {
unlikely(afl->fixed_seed)) {
fav_factor = q->len << 2; fav_factor = q->len << 2;
@ -339,13 +338,12 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
/* Faster-executing or smaller test cases are favored. */ /* Faster-executing or smaller test cases are favored. */
u64 top_rated_fav_factor; u64 top_rated_fav_factor;
u64 top_rated_fuzz_p2; u64 top_rated_fuzz_p2;
if (unlikely(afl->schedule >= FAST)) if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE))
top_rated_fuzz_p2 = next_pow2(afl->top_rated[i]->n_fuzz); top_rated_fuzz_p2 = next_pow2(afl->top_rated[i]->n_fuzz);
else else
top_rated_fuzz_p2 = afl->top_rated[i]->fuzz_level; top_rated_fuzz_p2 = afl->top_rated[i]->fuzz_level;
if (unlikely(afl->schedule == MMOPT || afl->schedule == RARE) || if (unlikely(afl->schedule >= RARE) || unlikely(afl->fixed_seed)) {
unlikely(afl->fixed_seed)) {
top_rated_fav_factor = afl->top_rated[i]->len << 2; top_rated_fav_factor = afl->top_rated[i]->len << 2;
@ -366,8 +364,7 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
} }
if (unlikely(afl->schedule == MMOPT || afl->schedule == RARE) || if (unlikely(afl->schedule >= RARE) || unlikely(afl->fixed_seed)) {
unlikely(afl->fixed_seed)) {
if (fav_factor > afl->top_rated[i]->len << 2) { continue; } if (fav_factor > afl->top_rated[i]->len << 2) { continue; }
@ -512,8 +509,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
// Longer execution time means longer work on the input, the deeper in // Longer execution time means longer work on the input, the deeper in
// coverage, the better the fuzzing, right? -mh // coverage, the better the fuzzing, right? -mh
if (afl->schedule != MMOPT && afl->schedule != RARE && if (afl->schedule >= RARE && likely(!afl->fixed_seed)) {
likely(!afl->fixed_seed)) {
if (q->exec_us * 0.1 > avg_exec_us) { if (q->exec_us * 0.1 > avg_exec_us) {
@ -625,6 +621,9 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
case EXPLORE: case EXPLORE:
break; break;
case SEEK:
break;
case EXPLOIT: case EXPLOIT:
factor = MAX_FACTOR; factor = MAX_FACTOR;
break; break;
@ -718,7 +717,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
} }
if (unlikely(afl->schedule >= FAST)) { if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) {
if (factor > MAX_FACTOR) { factor = MAX_FACTOR; } if (factor > MAX_FACTOR) { factor = MAX_FACTOR; }
perf_score *= factor / POWER_BETA; perf_score *= factor / POWER_BETA;

View File

@ -156,16 +156,22 @@ static void write_with_gap(afl_state_t *afl, void *mem, u32 len, u32 skip_at,
*afl->fsrv.shmem_fuzz_len = len - skip_len; *afl->fsrv.shmem_fuzz_len = len - skip_len;
#ifdef _DEBUG #ifdef _DEBUG
fprintf(stderr, "FS crc: %08x len: %u\n", if (afl->debug) {
hash64(fsrv->shmem_fuzz, *fsrv->shmem_fuzz_len, 0xa5b35705),
*fsrv->shmem_fuzz_len); fprintf(
stderr, "FS crc: %16llx len: %u\n",
hash64(afl->fsrv.shmem_fuzz, *afl->fsrv.shmem_fuzz_len, 0xa5b35705),
*afl->fsrv.shmem_fuzz_len);
fprintf(stderr, "SHM :"); fprintf(stderr, "SHM :");
for (int i = 0; i < *fsrv->shmem_fuzz_len; i++) for (int i = 0; i < *afl->fsrv.shmem_fuzz_len; i++)
fprintf(stderr, "%02x", fsrv->shmem_fuzz[i]); fprintf(stderr, "%02x", afl->fsrv.shmem_fuzz[i]);
fprintf(stderr, "\nORIG:"); fprintf(stderr, "\nORIG:");
for (int i = 0; i < *fsrv->shmem_fuzz_len; i++) for (int i = 0; i < *afl->fsrv.shmem_fuzz_len; i++)
fprintf(stderr, "%02x", buf[i]); fprintf(stderr, "%02x", (u8)((u8 *)mem)[i]);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
}
#endif #endif
return; return;
@ -262,6 +268,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
if (afl->fsrv.support_shmem_fuzz && !afl->fsrv.use_shmem_fuzz) { if (afl->fsrv.support_shmem_fuzz && !afl->fsrv.use_shmem_fuzz) {
unsetenv(SHM_FUZZ_ENV_VAR);
afl_shm_deinit(afl->shm_fuzz); afl_shm_deinit(afl->shm_fuzz);
ck_free(afl->shm_fuzz); ck_free(afl->shm_fuzz);
afl->shm_fuzz = NULL; afl->shm_fuzz = NULL;
@ -286,12 +293,6 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
u64 cksum; u64 cksum;
if (!first_run && !(afl->stage_cur % afl->stats_update_freq)) {
show_stats(afl);
}
write_to_testcase(afl, use_mem, q->len); write_to_testcase(afl, use_mem, q->len);
fault = fuzz_run_target(afl, &afl->fsrv, use_tmout); fault = fuzz_run_target(afl, &afl->fsrv, use_tmout);
@ -413,7 +414,7 @@ void sync_fuzzers(afl_state_t *afl) {
DIR * sd; DIR * sd;
struct dirent *sd_ent; struct dirent *sd_ent;
u32 sync_cnt = 0, synced = 0, entries = 0; u32 sync_cnt = 0, synced = 0, entries = 0;
u8 path[PATH_MAX]; u8 path[PATH_MAX + 256];
sd = opendir(afl->sync_dir); sd = opendir(afl->sync_dir);
if (!sd) { PFATAL("Unable to open '%s'", afl->sync_dir); } if (!sd) { PFATAL("Unable to open '%s'", afl->sync_dir); }
@ -427,7 +428,7 @@ void sync_fuzzers(afl_state_t *afl) {
while ((sd_ent = readdir(sd))) { while ((sd_ent = readdir(sd))) {
u8 qd_synced_path[PATH_MAX], qd_path[PATH_MAX]; u8 qd_synced_path[PATH_MAX], qd_path[PATH_MAX];
u32 min_accept = 0, next_min_accept; u32 min_accept = 0, next_min_accept = 0;
s32 id_fd; s32 id_fd;
@ -466,6 +467,12 @@ void sync_fuzzers(afl_state_t *afl) {
synced++; synced++;
/* document the attempt to sync to this instance */
sprintf(qd_synced_path, "%s/.synced/%s.last", afl->out_dir, sd_ent->d_name);
id_fd = open(qd_synced_path, O_RDWR | O_CREAT | O_TRUNC, 0600);
if (id_fd >= 0) close(id_fd);
/* Skip anything that doesn't have a queue/ subdirectory. */ /* Skip anything that doesn't have a queue/ subdirectory. */
sprintf(qd_path, "%s/%s/queue", afl->sync_dir, sd_ent->d_name); sprintf(qd_path, "%s/%s/queue", afl->sync_dir, sd_ent->d_name);
@ -490,14 +497,13 @@ void sync_fuzzers(afl_state_t *afl) {
if (id_fd < 0) { PFATAL("Unable to create '%s'", qd_synced_path); } if (id_fd < 0) { PFATAL("Unable to create '%s'", qd_synced_path); }
if (read(id_fd, &min_accept, sizeof(u32)) > 0) { if (read(id_fd, &min_accept, sizeof(u32)) == sizeof(u32)) {
next_min_accept = min_accept;
lseek(id_fd, 0, SEEK_SET); lseek(id_fd, 0, SEEK_SET);
} }
next_min_accept = min_accept;
/* Show stats */ /* Show stats */
snprintf(afl->stage_name_buf, STAGE_BUF_SIZE, "sync %u", ++sync_cnt); snprintf(afl->stage_name_buf, STAGE_BUF_SIZE, "sync %u", ++sync_cnt);
@ -533,7 +539,7 @@ void sync_fuzzers(afl_state_t *afl) {
s32 fd; s32 fd;
struct stat st; struct stat st;
sprintf(path, "%s/%s", qd_path, namelist[o]->d_name); snprintf(path, sizeof(path), "%s/%s", qd_path, namelist[o]->d_name);
afl->syncing_case = next_min_accept; afl->syncing_case = next_min_accept;
next_min_accept++; next_min_accept++;
o--; o--;

View File

@ -30,9 +30,9 @@ s8 interesting_8[] = {INTERESTING_8};
s16 interesting_16[] = {INTERESTING_8, INTERESTING_16}; s16 interesting_16[] = {INTERESTING_8, INTERESTING_16};
s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32}; s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32};
char *power_names[POWER_SCHEDULES_NUM] = { char *power_names[POWER_SCHEDULES_NUM] = {"explore", "exploit", "fast",
"coe", "lin", "quad",
"explore", "exploit", "fast", "coe", "lin", "quad", "rare", "mmopt"}; "rare", "mmopt", "seek"};
/* Initialize MOpt "globals" for this afl state */ /* Initialize MOpt "globals" for this afl state */

View File

@ -194,7 +194,8 @@ void maybe_update_plot_file(afl_state_t *afl, double bitmap_cvg, double eps) {
afl->plot_prev_uc == afl->unique_crashes && afl->plot_prev_uc == afl->unique_crashes &&
afl->plot_prev_uh == afl->unique_hangs && afl->plot_prev_uh == afl->unique_hangs &&
afl->plot_prev_md == afl->max_depth) || afl->plot_prev_md == afl->max_depth) ||
unlikely(!afl->queue_cycle)) { unlikely(!afl->queue_cycle) ||
unlikely(get_cur_time() - afl->start_time <= 60)) {
return; return;
@ -745,15 +746,13 @@ void show_stats(afl_state_t *afl) {
afl->sync_id ? u_stringify_int(IB(0), afl->queued_imported) afl->sync_id ? u_stringify_int(IB(0), afl->queued_imported)
: (u8 *)"n/a"); : (u8 *)"n/a");
sprintf(tmp, "%s/%s, %s/%s, %s/%s", sprintf(tmp, "%s/%s, %s/%s",
u_stringify_int(IB(0), afl->stage_finds[STAGE_HAVOC]), u_stringify_int(IB(0), afl->stage_finds[STAGE_HAVOC]),
u_stringify_int(IB(2), afl->stage_cycles[STAGE_HAVOC]), u_stringify_int(IB(2), afl->stage_cycles[STAGE_HAVOC]),
u_stringify_int(IB(3), afl->stage_finds[STAGE_SPLICE]), u_stringify_int(IB(3), afl->stage_finds[STAGE_SPLICE]),
u_stringify_int(IB(4), afl->stage_cycles[STAGE_SPLICE]), u_stringify_int(IB(4), afl->stage_cycles[STAGE_SPLICE]));
u_stringify_int(IB(5), afl->stage_finds[STAGE_RADAMSA]),
u_stringify_int(IB(6), afl->stage_cycles[STAGE_RADAMSA]));
SAYF(bV bSTOP " havoc/rad : " cRST "%-36s " bSTG bV bSTOP, tmp); SAYF(bV bSTOP "havoc/splice : " cRST "%-36s " bSTG bV bSTOP, tmp);
if (t_bytes) { if (t_bytes) {
@ -834,18 +833,19 @@ void show_stats(afl_state_t *afl) {
} }
if (afl->custom_mutators_count) { // if (afl->custom_mutators_count) {
sprintf(tmp, "%s/%s", //
u_stringify_int(IB(0), afl->stage_finds[STAGE_CUSTOM_MUTATOR]), // sprintf(tmp, "%s/%s",
u_stringify_int(IB(1), afl->stage_cycles[STAGE_CUSTOM_MUTATOR])); // u_stringify_int(IB(0), afl->stage_finds[STAGE_CUSTOM_MUTATOR]),
SAYF(bV bSTOP " custom mut. : " cRST "%-36s " bSTG bV RESET_G1, tmp); // u_stringify_int(IB(1), afl->stage_cycles[STAGE_CUSTOM_MUTATOR]));
// SAYF(bV bSTOP " custom mut. : " cRST "%-36s " bSTG bV RESET_G1, tmp);
} else { //
//} else {
SAYF(bV bSTOP " trim : " cRST "%-36s " bSTG bV RESET_G1, tmp); SAYF(bV bSTOP " trim : " cRST "%-36s " bSTG bV RESET_G1, tmp);
} //}
/* Provide some CPU utilization stats. */ /* Provide some CPU utilization stats. */

View File

@ -26,6 +26,13 @@
#include "afl-fuzz.h" #include "afl-fuzz.h"
#include "cmplog.h" #include "cmplog.h"
#include <limits.h> #include <limits.h>
#ifndef USEMMAP
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#endif
#ifdef PROFILING #ifdef PROFILING
extern u64 time_spent_working; extern u64 time_spent_working;
@ -34,6 +41,7 @@ extern u64 time_spent_working;
static void at_exit() { static void at_exit() {
int i; int i;
char *list[4] = {SHM_ENV_VAR, SHM_FUZZ_ENV_VAR, CMPLOG_SHM_ENV_VAR, NULL};
char *ptr = getenv("__AFL_TARGET_PID1"); char *ptr = getenv("__AFL_TARGET_PID1");
if (ptr && *ptr && (i = atoi(ptr)) > 0) kill(i, SIGKILL); if (ptr && *ptr && (i = atoi(ptr)) > 0) kill(i, SIGKILL);
@ -42,65 +50,29 @@ static void at_exit() {
if (ptr && *ptr && (i = atoi(ptr)) > 0) kill(i, SIGKILL); if (ptr && *ptr && (i = atoi(ptr)) > 0) kill(i, SIGKILL);
// anything else? shared memory? i = 0;
while (list[i] != NULL) {
ptr = getenv(list[i]);
if (ptr && *ptr) {
#ifdef USEMMAP
shm_unlink(ptr);
#else
shmctl(atoi(ptr), IPC_RMID, NULL);
#endif
} }
static u8 *get_libradamsa_path(u8 *own_loc) { i++;
u8 *tmp, *cp, *rsl, *own_copy;
tmp = getenv("AFL_PATH");
if (tmp) {
cp = alloc_printf("%s/libradamsa.so", tmp);
if (access(cp, X_OK)) { FATAL("Unable to find '%s'", cp); }
return cp;
} }
own_copy = ck_strdup(own_loc);
rsl = strrchr(own_copy, '/');
if (rsl) {
*rsl = 0;
cp = alloc_printf("%s/libradamsa.so", own_copy);
ck_free(own_copy);
if (!access(cp, X_OK)) { return cp; }
} else {
ck_free(own_copy);
}
if (!access(AFL_PATH "/libradamsa.so", X_OK)) {
return ck_strdup(AFL_PATH "/libradamsa.so");
}
if (!access(BIN_PATH "/libradamsa.so", X_OK)) {
return ck_strdup(BIN_PATH "/libradamsa.so");
}
SAYF(
"\n" cLRD "[-] " cRST
"Oops, unable to find the 'libradamsa.so' binary. The binary must be "
"built\n"
" separately using 'make radamsa'. If you already have the binary "
"installed,\n you may need to specify AFL_PATH in the environment.\n");
FATAL("Failed to locate 'libradamsa.so'.");
} }
/* Display usage hints. */ /* Display usage hints. */
@ -115,12 +87,13 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) {
" -o dir - output directory for fuzzer findings\n\n" " -o dir - output directory for fuzzer findings\n\n"
"Execution control settings:\n" "Execution control settings:\n"
" -p schedule - power schedules recompute a seed's performance " " -p schedule - power schedules compute a seed's performance score. "
"score.\n" "<explore\n"
" <explore(default), fast, coe, lin, quad, exploit, " " (default), fast, coe, lin, quad, exploit, mmopt, "
"mmopt, rare>\n" "rare, seek>\n"
" see docs/power_schedules.md\n" " see docs/power_schedules.md\n"
" -f file - location read by the fuzzed program (stdin)\n" " -f file - location read by the fuzzed program (default: stdin "
"or @@)\n"
" -t msec - timeout for each run (auto-scaled, 50-%d ms)\n" " -t msec - timeout for each run (auto-scaled, 50-%d ms)\n"
" -m megs - memory limit for child process (%d MB)\n" " -m megs - memory limit for child process (%d MB)\n"
" -Q - use binary-only instrumentation (QEMU mode)\n" " -Q - use binary-only instrumentation (QEMU mode)\n"
@ -129,8 +102,6 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) {
"mode)\n\n" "mode)\n\n"
"Mutator settings:\n" "Mutator settings:\n"
" -R[R] - add Radamsa as mutator, add another -R to exclusivly "
"run it\n"
" -L minutes - use MOpt(imize) mode and set the time limit for " " -L minutes - use MOpt(imize) mode and set the time limit for "
"entering the\n" "entering the\n"
" pacemaker mode (minutes of no new paths). 0 = " " pacemaker mode (minutes of no new paths). 0 = "
@ -146,7 +117,7 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) {
"devices etc.!)\n" "devices 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 dir - optional fuzzer dictionary (see README.md, its really " " -x dict_file - optional fuzzer dictionary (see README.md, its really "
"good!)\n\n" "good!)\n\n"
"Testing settings:\n" "Testing settings:\n"
@ -160,13 +131,15 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) {
"Other stuff:\n" "Other stuff:\n"
" -T text - text banner to show on the screen\n" " -T text - text banner to show on the screen\n"
" -M/-S id - distributed mode (see docs/parallel_fuzzing.md)\n" " -M/-S id - distributed mode (see docs/parallel_fuzzing.md)\n"
" use -D to force -S secondary to perform deterministic "
"fuzzing\n"
" -I command - execute this command/script when a new crash is " " -I command - execute this command/script when a new crash is "
"found\n" "found\n"
" -B bitmap.txt - mutate a specific test case, use the out/fuzz_bitmap " //" -B bitmap.txt - mutate a specific test case, use the out/fuzz_bitmap
"file\n" //" "file\n"
" -C - crash exploration mode (the peruvian rabbit thing)\n" " -C - crash exploration mode (the peruvian rabbit thing)\n"
" -e ext - file extension for the temporarily generated test " " -e ext - file extension for the fuzz test input file (if "
"case\n\n", "needed)\n\n",
argv0, EXEC_TIMEOUT, MEM_LIMIT); argv0, EXEC_TIMEOUT, MEM_LIMIT);
if (more_help > 1) { if (more_help > 1) {
@ -289,10 +262,10 @@ int main(int argc, char **argv_orig, char **envp) {
doc_path = access(DOC_PATH, F_OK) != 0 ? (u8 *)"docs" : (u8 *)DOC_PATH; doc_path = access(DOC_PATH, F_OK) != 0 ? (u8 *)"docs" : (u8 *)DOC_PATH;
gettimeofday(&tv, &tz); gettimeofday(&tv, &tz);
afl->init_seed = tv.tv_sec ^ tv.tv_usec ^ getpid(); rand_set_seed(afl, tv.tv_sec ^ tv.tv_usec ^ getpid());
while ((opt = getopt(argc, argv, while ((opt = getopt(argc, argv,
"+c:i:I:o:f:m:t:T:dnCB:S:M:x:QNUWe:p:s:V:E:L:hRP:")) > "+c:i:I:o:f:m:t:T:dDnCB:S:M:x:QNUWe:p:s:V:E:L:hRP:")) >
0) { 0) {
switch (opt) { switch (opt) {
@ -311,7 +284,7 @@ int main(int argc, char **argv_orig, char **envp) {
case 's': { case 's': {
afl->init_seed = strtoul(optarg, 0L, 10); rand_set_seed(afl, strtoul(optarg, 0L, 10));
afl->fixed_seed = 1; afl->fixed_seed = 1;
break; break;
@ -347,6 +320,10 @@ int main(int argc, char **argv_orig, char **envp) {
afl->schedule = RARE; afl->schedule = RARE;
} else if (!stricmp(optarg, "seek")) {
afl->schedule = SEEK;
} else if (!stricmp(optarg, "explore") || !stricmp(optarg, "default") || } else if (!stricmp(optarg, "explore") || !stricmp(optarg, "default") ||
!stricmp(optarg, "normal") || !stricmp(optarg, "afl")) { !stricmp(optarg, "normal") || !stricmp(optarg, "afl")) {
@ -384,7 +361,7 @@ int main(int argc, char **argv_orig, char **envp) {
afl->out_dir = optarg; afl->out_dir = optarg;
break; break;
case 'M': { /* master sync ID */ case 'M': { /* main sync ID */
u8 *c; u8 *c;
@ -413,7 +390,7 @@ int main(int argc, char **argv_orig, char **envp) {
break; break;
case 'S': case 'S': /* secondary sync id */
if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); } if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); }
afl->sync_id = ck_strdup(optarg); afl->sync_id = ck_strdup(optarg);
@ -518,6 +495,11 @@ int main(int argc, char **argv_orig, char **envp) {
break; break;
case 'D': /* enforce deterministic */
afl->skip_deterministic = 0;
break;
case 'd': /* skip deterministic */ case 'd': /* skip deterministic */
afl->skip_deterministic = 1; afl->skip_deterministic = 1;
@ -782,15 +764,9 @@ int main(int argc, char **argv_orig, char **envp) {
case 'R': case 'R':
if (afl->use_radamsa) { FATAL(
"Radamsa is now a custom mutator, please use that "
afl->use_radamsa = 2; "(custom_mutators/radamsa/).");
} else {
afl->use_radamsa = 1;
}
break; break;
@ -823,8 +799,7 @@ int main(int argc, char **argv_orig, char **envp) {
WARNF( WARNF(
"Using -M main node with the AFL_CUSTOM_MUTATOR_ONLY mutator options " "Using -M main node with the AFL_CUSTOM_MUTATOR_ONLY mutator options "
"will " "will result in no deterministic mutations being done!");
"result in no deterministic mutations being done!");
} }
@ -834,59 +809,6 @@ int main(int argc, char **argv_orig, char **envp) {
} }
if (afl->init_seed) {
afl->rand_seed[0] = afl->init_seed;
afl->rand_seed[1] = afl->init_seed ^ 0x1234567890abcdef;
afl->rand_seed[2] = afl->init_seed & 0x0123456789abcdef;
afl->rand_seed[3] = afl->init_seed | 0x01abcde43f567908;
}
// srandom((u32)afl->init_seed);
// srand((u32)afl->init_seed); // in case it is a different implementation
if (afl->use_radamsa) {
if (afl->limit_time_sig > 0) {
FATAL(
"MOpt and Radamsa are mutually exclusive unless you specify -L -1. "
"We accept pull requests that integrates MOpt with the optional "
"mutators (custom/radamsa/redqueen/...).");
}
if (afl->limit_time_sig && afl->use_radamsa > 1) {
FATAL("Radamsa in radamsa-only mode can not run together with -L");
}
OKF("Using Radamsa add-on");
u8 * libradamsa_path = get_libradamsa_path(argv[0]);
void *handle = dlopen(libradamsa_path, RTLD_NOW);
ck_free(libradamsa_path);
if (!handle) { FATAL("Failed to dlopen() libradamsa"); }
void (*radamsa_init_ptr)(void) = dlsym(handle, "radamsa_init");
afl->radamsa_mutate_ptr = dlsym(handle, "radamsa");
if (!radamsa_init_ptr || !afl->radamsa_mutate_ptr) {
FATAL("Failed to dlsym() libradamsa");
}
/* radamsa_init installs some signal handlers, call it before
setup_signal_handlers so that AFL++ can then replace those signal
handlers */
radamsa_init_ptr();
}
#if defined(__SANITIZE_ADDRESS__) #if defined(__SANITIZE_ADDRESS__)
if (afl->fsrv.mem_limit) { if (afl->fsrv.mem_limit) {
@ -960,6 +882,9 @@ int main(int argc, char **argv_orig, char **envp) {
case RARE: case RARE:
OKF("Using rare edge focus power schedule (RARE)"); OKF("Using rare edge focus power schedule (RARE)");
break; break;
case SEEK:
OKF("Using seek power schedule (SEEK)");
break;
case EXPLORE: case EXPLORE:
OKF("Using exploration-based constant power schedule (EXPLORE, default)"); OKF("Using exploration-based constant power schedule (EXPLORE, default)");
break; break;
@ -1095,6 +1020,8 @@ int main(int argc, char **argv_orig, char **envp) {
check_crash_handling(); check_crash_handling();
check_cpu_governor(afl); check_cpu_governor(afl);
atexit(at_exit);
afl->fsrv.trace_bits = afl->fsrv.trace_bits =
afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->non_instrumented_mode); afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->non_instrumented_mode);
@ -1106,7 +1033,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (afl->is_main_node && check_main_node_exists(afl) == 1) { if (afl->is_main_node && check_main_node_exists(afl) == 1) {
WARNF("it is wasteful to run more than one master!"); WARNF("it is wasteful to run more than one main node!");
sleep(1); sleep(1);
} }
@ -1258,8 +1185,6 @@ int main(int argc, char **argv_orig, char **envp) {
} }
atexit(at_exit);
perform_dry_run(afl); perform_dry_run(afl);
cull_queue(afl); cull_queue(afl);
@ -1353,10 +1278,18 @@ int main(int argc, char **argv_orig, char **envp) {
if (!skipped_fuzz && !afl->stop_soon && afl->sync_id) { if (!skipped_fuzz && !afl->stop_soon && afl->sync_id) {
if (unlikely(afl->is_main_node)) {
if (!(sync_interval_cnt++ % (SYNC_INTERVAL / 2))) { sync_fuzzers(afl); }
} else {
if (!(sync_interval_cnt++ % SYNC_INTERVAL)) { sync_fuzzers(afl); } if (!(sync_interval_cnt++ % SYNC_INTERVAL)) { sync_fuzzers(afl); }
} }
}
if (!afl->stop_soon && exit_1) { afl->stop_soon = 2; } if (!afl->stop_soon && exit_1) { afl->stop_soon = 2; }
if (afl->stop_soon) { break; } if (afl->stop_soon) { break; }
@ -1422,10 +1355,13 @@ stop_fuzzing:
destroy_queue(afl); destroy_queue(afl);
destroy_extras(afl); destroy_extras(afl);
destroy_custom_mutators(afl); destroy_custom_mutators(afl);
unsetenv(SHM_ENV_VAR);
unsetenv(CMPLOG_SHM_ENV_VAR);
afl_shm_deinit(&afl->shm); afl_shm_deinit(&afl->shm);
if (afl->shm_fuzz) { if (afl->shm_fuzz) {
unsetenv(SHM_FUZZ_ENV_VAR);
afl_shm_deinit(afl->shm_fuzz); afl_shm_deinit(afl->shm_fuzz);
ck_free(afl->shm_fuzz); ck_free(afl->shm_fuzz);

View File

@ -33,6 +33,17 @@ static inline uint64_t rotl(const uint64_t x, int k) {
} }
void rand_set_seed(afl_state_t *afl, s64 init_seed) {
afl->init_seed = init_seed;
afl->rand_seed[0] =
hash64((u8 *)&afl->init_seed, sizeof(afl->init_seed), HASH_CONST);
afl->rand_seed[1] = afl->rand_seed[0] ^ 0x1234567890abcdef;
afl->rand_seed[2] = afl->rand_seed[0] & 0x0123456789abcdef;
afl->rand_seed[3] = afl->rand_seed[0] | 0x01abcde43f567908;
}
uint32_t rand_next(afl_state_t *afl) { uint32_t rand_next(afl_state_t *afl) {
const uint32_t result = const uint32_t result =
@ -132,13 +143,25 @@ void long_jump(afl_state_t *afl) {
/* we switch from afl's murmur implementation to xxh3 as it is 30% faster - /* we switch from afl's murmur implementation to xxh3 as it is 30% faster -
and get 64 bit hashes instead of just 32 bit. Less collisions! :-) */ and get 64 bit hashes instead of just 32 bit. Less collisions! :-) */
u32 inline hash32(const void *key, u32 len, u32 seed) { #ifdef _DEBUG
u32 hash32(u8 *key, u32 len, u32 seed) {
#else
u32 inline hash32(u8 *key, u32 len, u32 seed) {
#endif
return (u32)XXH64(key, len, seed); return (u32)XXH64(key, len, seed);
} }
u64 inline hash64(const void *key, u32 len, u64 seed) { #ifdef _DEBUG
u64 hash64(u8 *key, u32 len, u64 seed) {
#else
u64 inline hash64(u8 *key, u32 len, u64 seed) {
#endif
return XXH64(key, len, seed); return XXH64(key, len, seed);

View File

@ -66,6 +66,8 @@ static list_t shm_list = {.element_prealloc_count = 0};
void afl_shm_deinit(sharedmem_t *shm) { void afl_shm_deinit(sharedmem_t *shm) {
if (shm == NULL) return;
list_remove(&shm_list, shm); list_remove(&shm_list, shm);
#ifdef USEMMAP #ifdef USEMMAP
@ -83,6 +85,38 @@ void afl_shm_deinit(sharedmem_t *shm) {
} }
if (shm->g_shm_file_path[0]) {
shm_unlink(shm->g_shm_file_path);
shm->g_shm_file_path[0] = 0;
}
if (shm->cmplog_mode) {
if (shm->cmp_map != NULL) {
munmap(shm->cmp_map, shm->map_size);
shm->map = NULL;
}
if (shm->cmplog_g_shm_fd != -1) {
close(shm->cmplog_g_shm_fd);
shm->cmplog_g_shm_fd = -1;
}
if (shm->cmplog_g_shm_file_path[0]) {
shm_unlink(shm->cmplog_g_shm_file_path);
shm->cmplog_g_shm_file_path[0] = 0;
}
}
#else #else
shmctl(shm->shm_id, IPC_RMID, NULL); shmctl(shm->shm_id, IPC_RMID, NULL);
if (shm->cmplog_mode) { shmctl(shm->cmplog_shm_id, IPC_RMID, NULL); } if (shm->cmplog_mode) { shmctl(shm->cmplog_shm_id, IPC_RMID, NULL); }
@ -99,13 +133,15 @@ void afl_shm_deinit(sharedmem_t *shm) {
u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
unsigned char non_instrumented_mode) { unsigned char non_instrumented_mode) {
shm->map_size = map_size; shm->map_size = 0;
shm->map = NULL; shm->map = NULL;
shm->cmp_map = NULL;
#ifdef USEMMAP #ifdef USEMMAP
shm->g_shm_fd = -1; shm->g_shm_fd = -1;
shm->cmplog_g_shm_fd = -1;
/* ====== /* ======
generate random file name for multi instance generate random file name for multi instance
@ -134,6 +170,8 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
close(shm->g_shm_fd); close(shm->g_shm_fd);
shm->g_shm_fd = -1; shm->g_shm_fd = -1;
shm_unlink(shm->g_shm_file_path);
shm->g_shm_file_path[0] = 0;
PFATAL("mmap() failed"); PFATAL("mmap() failed");
} }
@ -147,11 +185,53 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
if (shm->map == (void *)-1 || !shm->map) PFATAL("mmap() failed"); if (shm->map == (void *)-1 || !shm->map) PFATAL("mmap() failed");
if (shm->cmplog_mode) {
snprintf(shm->cmplog_g_shm_file_path, L_tmpnam, "/afl_cmplog_%d_%ld",
getpid(), random());
/* create the shared memory segment as if it was a file */
shm->cmplog_g_shm_fd =
shm_open(shm->cmplog_g_shm_file_path, O_CREAT | O_RDWR | O_EXCL, 0600);
if (shm->cmplog_g_shm_fd == -1) { PFATAL("shm_open() failed"); }
/* configure the size of the shared memory segment */
if (ftruncate(shm->cmplog_g_shm_fd, map_size)) {
PFATAL("setup_shm(): cmplog ftruncate() failed");
}
/* map the shared memory segment to the address space of the process */
shm->cmp_map = mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED,
shm->cmplog_g_shm_fd, 0);
if (shm->map == MAP_FAILED) {
close(shm->cmplog_g_shm_fd);
shm->cmplog_g_shm_fd = -1;
shm_unlink(shm->cmplog_g_shm_file_path);
shm->cmplog_g_shm_file_path[0] = 0;
PFATAL("mmap() failed");
}
/* If somebody is asking us to fuzz instrumented binaries in
non-instrumented mode, we don't want them to detect instrumentation,
since we won't be sending fork server commands. This should be replaced
with better auto-detection later on, perhaps? */
if (!non_instrumented_mode)
setenv(CMPLOG_SHM_ENV_VAR, shm->cmplog_g_shm_file_path, 1);
if (shm->cmp_map == (void *)-1 || !shm->cmp_map)
PFATAL("cmplog mmap() failed");
}
#else #else
u8 *shm_str; u8 *shm_str;
shm->shm_id = shmget(IPC_PRIVATE, map_size, IPC_CREAT | IPC_EXCL | 0600); shm->shm_id = shmget(IPC_PRIVATE, map_size, IPC_CREAT | IPC_EXCL | 0600);
if (shm->shm_id < 0) { PFATAL("shmget() failed"); } if (shm->shm_id < 0) { PFATAL("shmget() failed"); }
if (shm->cmplog_mode) { if (shm->cmplog_mode) {
@ -159,7 +239,12 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
shm->cmplog_shm_id = shmget(IPC_PRIVATE, sizeof(struct cmp_map), shm->cmplog_shm_id = shmget(IPC_PRIVATE, sizeof(struct cmp_map),
IPC_CREAT | IPC_EXCL | 0600); IPC_CREAT | IPC_EXCL | 0600);
if (shm->cmplog_shm_id < 0) { PFATAL("shmget() failed"); } if (shm->cmplog_shm_id < 0) {
shmctl(shm->shm_id, IPC_RMID, NULL); // do not leak shmem
PFATAL("shmget() failed");
}
} }
@ -186,7 +271,18 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
shm->map = shmat(shm->shm_id, NULL, 0); shm->map = shmat(shm->shm_id, NULL, 0);
if (shm->map == (void *)-1 || !shm->map) { PFATAL("shmat() failed"); } if (shm->map == (void *)-1 || !shm->map) {
shmctl(shm->shm_id, IPC_RMID, NULL); // do not leak shmem
if (shm->cmplog_mode) {
shmctl(shm->cmplog_shm_id, IPC_RMID, NULL); // do not leak shmem
}
PFATAL("shmat() failed");
}
if (shm->cmplog_mode) { if (shm->cmplog_mode) {
@ -194,6 +290,13 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
if (shm->cmp_map == (void *)-1 || !shm->cmp_map) { if (shm->cmp_map == (void *)-1 || !shm->cmp_map) {
shmctl(shm->shm_id, IPC_RMID, NULL); // do not leak shmem
if (shm->cmplog_mode) {
shmctl(shm->cmplog_shm_id, IPC_RMID, NULL); // do not leak shmem
}
PFATAL("shmat() failed"); PFATAL("shmat() failed");
} }
@ -202,6 +305,7 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
#endif #endif
shm->map_size = map_size;
list_append(&shm_list, shm); list_append(&shm_list, shm);
return shm->map; return shm->map;

View File

@ -82,11 +82,16 @@ static u8 quiet_mode, /* Hide non-essential messages? */
raw_instr_output, /* Do not apply AFL filters */ raw_instr_output, /* Do not apply AFL filters */
cmin_mode, /* Generate output in afl-cmin mode? */ cmin_mode, /* Generate output in afl-cmin mode? */
binary_mode, /* Write output as a binary map */ binary_mode, /* Write output as a binary map */
keep_cores; /* Allow coredumps? */ keep_cores, /* Allow coredumps? */
remove_shm = 1; /* remove shmem? */
static volatile u8 stop_soon, /* Ctrl-C pressed? */ static volatile u8 stop_soon, /* Ctrl-C pressed? */
child_crashed; /* Child crashed? */ child_crashed; /* Child crashed? */
static sharedmem_t shm;
static afl_forkserver_t *fsrv;
static sharedmem_t * shm_fuzz;
/* Classify tuple counts. Instead of mapping to individual bits, as in /* Classify tuple counts. Instead of mapping to individual bits, as in
afl-fuzz.c, we map to more user-friendly numbers between 1 and 8. */ afl-fuzz.c, we map to more user-friendly numbers between 1 and 8. */
@ -141,12 +146,33 @@ static void classify_counts(afl_forkserver_t *fsrv) {
} }
static sharedmem_t *deinit_shmem(afl_forkserver_t *fsrv,
sharedmem_t * shm_fuzz) {
afl_shm_deinit(shm_fuzz);
fsrv->support_shmem_fuzz = 0;
fsrv->shmem_fuzz_len = NULL;
fsrv->shmem_fuzz = NULL;
ck_free(shm_fuzz);
return NULL;
}
/* Get rid of temp files (atexit handler). */ /* Get rid of temp files (atexit handler). */
static void at_exit_handler(void) { static void at_exit_handler(void) {
if (stdin_file) { unlink(stdin_file); } if (stdin_file) { unlink(stdin_file); }
if (remove_shm) {
if (shm.map) afl_shm_deinit(&shm);
if (fsrv->use_shmem_fuzz) deinit_shmem(fsrv, shm_fuzz);
}
afl_fsrv_killall();
} }
/* Write results. */ /* Write results. */
@ -559,7 +585,7 @@ static void usage(u8 *argv0) {
"size\n" "size\n"
" the target was compiled for\n" " the target was compiled for\n"
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n" "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
"AFL_QUIET: do not print extra informational output", "AFL_QUIET: do not print extra informational output\n",
argv0, MEM_LIMIT, doc_path); argv0, MEM_LIMIT, doc_path);
exit(1); exit(1);
@ -580,7 +606,7 @@ int main(int argc, char **argv_orig, char **envp) {
char **argv = argv_cpy_dup(argc, argv_orig); char **argv = argv_cpy_dup(argc, argv_orig);
afl_forkserver_t fsrv_var = {0}; afl_forkserver_t fsrv_var = {0};
afl_forkserver_t *fsrv = &fsrv_var; fsrv = &fsrv_var;
afl_fsrv_init(fsrv); afl_fsrv_init(fsrv);
map_size = get_map_size(); map_size = get_map_size();
fsrv->map_size = map_size; fsrv->map_size = map_size;
@ -775,7 +801,19 @@ int main(int argc, char **argv_orig, char **envp) {
check_environment_vars(envp); check_environment_vars(envp);
sharedmem_t shm = {0}; if (getenv("AFL_DEBUG")) {
SAYF(cMGN "[D]" cRST);
for (i = 0; i < argc; i++)
SAYF(" %s", argv[i]);
SAYF("\n");
}
// if (afl->shmem_testcase_mode) { setup_testcase_shmem(afl); }
/* initialize cmplog_mode */
shm.cmplog_mode = 0;
fsrv->trace_bits = afl_shm_init(&shm, map_size, 0); fsrv->trace_bits = afl_shm_init(&shm, map_size, 0);
setup_signal_handlers(); setup_signal_handlers();
@ -829,16 +867,36 @@ int main(int argc, char **argv_orig, char **envp) {
} }
shm_fuzz = ck_alloc(sizeof(sharedmem_t));
/* initialize cmplog_mode */
shm_fuzz->cmplog_mode = 0;
u8 *map = afl_shm_init(shm_fuzz, MAX_FILE + sizeof(u32), 1);
if (!map) { FATAL("BUG: Zero return from afl_shm_init."); }
#ifdef USEMMAP
setenv(SHM_FUZZ_ENV_VAR, shm_fuzz->g_shm_file_path, 1);
#else
u8 *shm_str = alloc_printf("%d", shm_fuzz->shm_id);
setenv(SHM_FUZZ_ENV_VAR, shm_str, 1);
ck_free(shm_str);
#endif
fsrv->support_shmem_fuzz = 1;
fsrv->shmem_fuzz_len = (u32 *)map;
fsrv->shmem_fuzz = map + sizeof(u32);
if (in_dir) { if (in_dir) {
DIR * dir_in, *dir_out; DIR * dir_in, *dir_out;
struct dirent *dir_ent; struct dirent *dir_ent;
int done = 0; int done = 0;
u8 infile[PATH_MAX], outfile[PATH_MAX]; u8 infile[PATH_MAX], outfile[PATH_MAX];
u8 wait_for_gdb = 0;
#if !defined(DT_REG) #if !defined(DT_REG)
struct stat statbuf; struct stat statbuf;
#endif #endif
if (getenv("AFL_DEBUG_GDB")) wait_for_gdb = 1;
fsrv->dev_null_fd = open("/dev/null", O_RDWR); fsrv->dev_null_fd = open("/dev/null", O_RDWR);
if (fsrv->dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); } if (fsrv->dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); }
@ -897,6 +955,9 @@ int main(int argc, char **argv_orig, char **envp) {
afl_fsrv_start(fsrv, use_argv, &stop_soon, afl_fsrv_start(fsrv, use_argv, &stop_soon,
get_afl_env("AFL_DEBUG_CHILD_OUTPUT") ? 1 : 0); get_afl_env("AFL_DEBUG_CHILD_OUTPUT") ? 1 : 0);
if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz)
shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
while (done == 0 && (dir_ent = readdir(dir_in))) { while (done == 0 && (dir_ent = readdir(dir_in))) {
if (dir_ent->d_name[0] == '.') { if (dir_ent->d_name[0] == '.') {
@ -924,6 +985,14 @@ int main(int argc, char **argv_orig, char **envp) {
if (read_file(infile)) { if (read_file(infile)) {
if (wait_for_gdb) {
fprintf(stderr, "exec: gdb -p %d\n", fsrv->child_pid);
fprintf(stderr, "exec: kill -CONT %d\n", getpid());
kill(0, SIGSTOP);
}
showmap_run_target_forkserver(fsrv, use_argv, in_data, in_len); showmap_run_target_forkserver(fsrv, use_argv, in_data, in_len);
ck_free(in_data); ck_free(in_data);
tcnt = write_results_to_file(fsrv, outfile); tcnt = write_results_to_file(fsrv, outfile);
@ -939,6 +1008,9 @@ int main(int argc, char **argv_orig, char **envp) {
} else { } else {
if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz)
shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
showmap_run_target(fsrv, use_argv); showmap_run_target(fsrv, use_argv);
tcnt = write_results_to_file(fsrv, out_file); tcnt = write_results_to_file(fsrv, out_file);
@ -960,13 +1032,16 @@ int main(int argc, char **argv_orig, char **envp) {
} }
remove_shm = 0;
afl_shm_deinit(&shm); afl_shm_deinit(&shm);
if (fsrv->use_shmem_fuzz) shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
u32 ret = child_crashed * 2 + fsrv->last_run_timed_out; u32 ret = child_crashed * 2 + fsrv->last_run_timed_out;
if (fsrv->target_path) { ck_free(fsrv->target_path); } if (fsrv->target_path) { ck_free(fsrv->target_path); }
afl_fsrv_deinit(fsrv); afl_fsrv_deinit(fsrv);
if (stdin_file) { ck_free(stdin_file); } if (stdin_file) { ck_free(stdin_file); }
argv_cpy_free(argv); argv_cpy_free(argv);

View File

@ -80,10 +80,16 @@ static u8 crash_mode, /* Crash-centric mode? */
hang_mode, /* Minimize as long as it hangs */ hang_mode, /* Minimize as long as it hangs */
exit_crash, /* Treat non-zero exit as crash? */ exit_crash, /* Treat non-zero exit as crash? */
edges_only, /* Ignore hit counts? */ edges_only, /* Ignore hit counts? */
exact_mode; /* Require path match for crashes? */ exact_mode, /* Require path match for crashes? */
remove_out_file, /* remove out_file on exit? */
remove_shm = 1; /* remove shmem on exit? */
static volatile u8 stop_soon; /* Ctrl-C pressed? */ static volatile u8 stop_soon; /* Ctrl-C pressed? */
static afl_forkserver_t *fsrv;
static sharedmem_t shm;
static sharedmem_t * shm_fuzz;
/* /*
* forkserver section * forkserver section
*/ */
@ -105,6 +111,18 @@ static const u8 count_class_lookup[256] = {
}; };
static sharedmem_t *deinit_shmem(afl_forkserver_t *fsrv,
sharedmem_t * shm_fuzz) {
afl_shm_deinit(shm_fuzz);
fsrv->support_shmem_fuzz = 0;
fsrv->shmem_fuzz_len = NULL;
fsrv->shmem_fuzz = NULL;
ck_free(shm_fuzz);
return NULL;
}
/* Apply mask to classified bitmap (if set). */ /* Apply mask to classified bitmap (if set). */
static void apply_mask(u32 *mem, u32 *mask) { static void apply_mask(u32 *mem, u32 *mask) {
@ -169,7 +187,15 @@ static inline u8 anything_set(afl_forkserver_t *fsrv) {
static void at_exit_handler(void) { static void at_exit_handler(void) {
if (remove_shm) {
if (shm.map) afl_shm_deinit(&shm);
if (fsrv->use_shmem_fuzz) deinit_shmem(fsrv, shm_fuzz);
}
afl_fsrv_killall(); afl_fsrv_killall();
if (remove_out_file) unlink(out_file);
} }
@ -623,6 +649,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
} }
out_file = alloc_printf("%s/.afl-tmin-temp-%u", use_dir, (u32)getpid()); out_file = alloc_printf("%s/.afl-tmin-temp-%u", use_dir, (u32)getpid());
remove_out_file = 1;
} }
@ -813,7 +840,7 @@ int main(int argc, char **argv_orig, char **envp) {
char **argv = argv_cpy_dup(argc, argv_orig); char **argv = argv_cpy_dup(argc, argv_orig);
afl_forkserver_t fsrv_var = {0}; afl_forkserver_t fsrv_var = {0};
afl_forkserver_t *fsrv = &fsrv_var; fsrv = &fsrv_var;
afl_fsrv_init(fsrv); afl_fsrv_init(fsrv);
map_size = get_map_size(); map_size = get_map_size();
fsrv->map_size = map_size; fsrv->map_size = map_size;
@ -1010,7 +1037,8 @@ int main(int argc, char **argv_orig, char **envp) {
check_environment_vars(envp); check_environment_vars(envp);
sharedmem_t shm = {0}; /* initialize cmplog_mode */
shm.cmplog_mode = 0;
fsrv->trace_bits = afl_shm_init(&shm, map_size, 0); fsrv->trace_bits = afl_shm_init(&shm, map_size, 0);
atexit(at_exit_handler); atexit(at_exit_handler);
@ -1052,11 +1080,31 @@ int main(int argc, char **argv_orig, char **envp) {
SAYF("\n"); SAYF("\n");
shm_fuzz = ck_alloc(sizeof(sharedmem_t));
/* initialize cmplog_mode */
shm_fuzz->cmplog_mode = 0;
u8 *map = afl_shm_init(shm_fuzz, MAX_FILE + sizeof(u32), 1);
if (!map) { FATAL("BUG: Zero return from afl_shm_init."); }
#ifdef USEMMAP
setenv(SHM_FUZZ_ENV_VAR, shm_fuzz->g_shm_file_path, 1);
#else
u8 *shm_str = alloc_printf("%d", shm_fuzz->shm_id);
setenv(SHM_FUZZ_ENV_VAR, shm_str, 1);
ck_free(shm_str);
#endif
fsrv->support_shmem_fuzz = 1;
fsrv->shmem_fuzz_len = (u32 *)map;
fsrv->shmem_fuzz = map + sizeof(u32);
read_initial_file(); read_initial_file();
afl_fsrv_start(fsrv, use_argv, &stop_soon, afl_fsrv_start(fsrv, use_argv, &stop_soon,
get_afl_env("AFL_DEBUG_CHILD_OUTPUT") ? 1 : 0); get_afl_env("AFL_DEBUG_CHILD_OUTPUT") ? 1 : 0);
if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz)
shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
ACTF("Performing dry run (mem limit = %llu MB, timeout = %u ms%s)...", ACTF("Performing dry run (mem limit = %llu MB, timeout = %u ms%s)...",
fsrv->mem_limit, fsrv->exec_tmout, edges_only ? ", edges only" : ""); fsrv->mem_limit, fsrv->exec_tmout, edges_only ? ", edges only" : "");
@ -1110,7 +1158,9 @@ int main(int argc, char **argv_orig, char **envp) {
OKF("We're done here. Have a nice day!\n"); OKF("We're done here. Have a nice day!\n");
remove_shm = 0;
afl_shm_deinit(&shm); afl_shm_deinit(&shm);
if (fsrv->use_shmem_fuzz) shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
afl_fsrv_deinit(fsrv); afl_fsrv_deinit(fsrv);
if (fsrv->target_path) { ck_free(fsrv->target_path); } if (fsrv->target_path) { ck_free(fsrv->target_path); }
if (mask_bitmap) { ck_free(mask_bitmap); } if (mask_bitmap) { ck_free(mask_bitmap); }

View File

@ -1,3 +0,0 @@
*.a
*.o
libradamsa-test

View File

@ -1,75 +0,0 @@
#include <radamsa.h>
#include <stdio.h>
#include <inttypes.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
size_t filesize(char* filename) {
struct stat st;
stat(filename, &st);
return st.st_size;
}
#define BUFSIZE 1024*1024
void fail(char *why) {
printf("fail: %s\n", why);
exit(1);
}
void write_output(char *data, size_t len, int num) {
char path[32];
int fd;
int wrote;
sprintf(path, "/tmp/libradamsa-%d.fuzz", num);
fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
printf("Opened %s -> %d\n", path, fd);
if (fd < 0) {
fail("failed to open output file");
}
wrote = write(fd, data, len);
printf("wrote %d of %zu bytes\n", wrote, len);
if (wrote != len) {
fail("failed to write all of output at once");
}
close(fd);
printf("Wrote %zu bytes to %s\n", len, path);
}
int main(int nargs, char **argv) {
char *spath = argv[1];
int fd = open(spath, O_RDONLY, 0);
size_t len;
char *input;
char *output;
int seed = 0;
if (fd < 0) {
fail("cannot open input file");
}
len = filesize(spath);
input = malloc(len);
output = malloc(BUFSIZE);
if (!input || !output) {
fail("failed to allocate buffers\n");
}
radamsa_init();
if (len != read(fd, input, len)) {
fail("failed to read the entire sample at once");
}
while(seed++ < 100) {
size_t n;
n = radamsa((uint8_t *) input, len, (uint8_t *) output, BUFSIZE, seed);
write_output(output, n, seed);
printf("Fuzzed %zu -> %zu bytes\n", len, n);
}
printf("library test passed\n");
free(output);
free(input);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +0,0 @@
#include <inttypes.h>
#include <stddef.h>
void radamsa_init(void);
size_t radamsa(uint8_t *ptr, size_t len,
uint8_t *target, size_t max,
unsigned int seed);
size_t radamsa_inplace(uint8_t *ptr,
size_t len,
size_t max,
unsigned int seed);

View File

@ -23,7 +23,7 @@ else
fi fi
test_compcov_binary_functionality() { test_compcov_binary_functionality() {
RUN="../afl-showmap -o /dev/null -- $1" RUN="../afl-showmap -m ${MEM_LIMIT} -o /dev/null -- $1"
$RUN 'LIBTOKENCAP' | grep 'your string was LIBTOKENCAP' \ $RUN 'LIBTOKENCAP' | grep 'your string was LIBTOKENCAP' \
&& $RUN 'BUGMENOT' | grep 'your string was BUGMENOT' \ && $RUN 'BUGMENOT' | grep 'your string was BUGMENOT' \
&& $RUN 'BANANA' | grep 'your string started with BAN' \ && $RUN 'BANANA' | grep 'your string started with BAN' \
@ -86,7 +86,7 @@ export AFL_LLVM_INSTRUMENT=AFL
# on OpenBSD we need to work with llvm from /usr/local/bin # on OpenBSD we need to work with llvm from /usr/local/bin
test -e /usr/local/bin/opt && { test -e /usr/local/bin/opt && {
export PATH=/usr/local/bin:${PATH} export PATH="/usr/local/bin:${PATH}"
} }
# on MacOS X we prefer afl-clang over afl-gcc, because # on MacOS X we prefer afl-clang over afl-gcc, because
# afl-gcc does not work there # afl-gcc does not work there
@ -108,7 +108,7 @@ RESET="\\033[0m"
MEM_LIMIT=none MEM_LIMIT=none
export PATH=$PATH:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin export PATH="${PATH}:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin"
$ECHO "${RESET}${GREY}[*] starting afl++ test framework ..." $ECHO "${RESET}${GREY}[*] starting afl++ test framework ..."
@ -459,24 +459,23 @@ test -e ../afl-clang-lto -a -e ../afl-llvm-lto-instrumentation.so && {
} }
rm -f test-instr.plain rm -f test-instr.plain
# Disabled whitelist until I have a different solution -mh echo foobar.c > whitelist.txt
# echo foobar.c > whitelist.txt AFL_DEBUG=1 AFL_LLVM_WHITELIST=whitelist.txt ../afl-clang-lto -o test-compcov test-compcov.c > test.out 2>&1
# AFL_LLVM_WHITELIST=whitelist.txt ../afl-clang-lto -o test-compcov test-compcov.c > test.out 2>&1 test -e test-compcov && {
# test -e test-compcov && { grep -q "No instrumentation targets found" test.out && {
# grep -q "No instrumentation targets found" test.out && { $ECHO "$GREEN[+] llvm_mode LTO whitelist feature works correctly"
# $ECHO "$GREEN[+] llvm_mode LTO whitelist feature works correctly" } || {
# } || { $ECHO "$RED[!] llvm_mode LTO whitelist feature failed"
# $ECHO "$RED[!] llvm_mode LTO whitelist feature failed" CODE=1
# CODE=1 }
# } } || {
# } || { $ECHO "$RED[!] llvm_mode LTO whitelist feature compilation failed"
# $ECHO "$RED[!] llvm_mode LTO whitelist feature compilation failed" CODE=1
# CODE=1 }
# } rm -f test-compcov test.out whitelist.txt
# rm -f test-compcov test.out whitelist.txt
../afl-clang-lto -o test-persistent ../examples/persistent_demo/persistent_demo.c > /dev/null 2>&1 ../afl-clang-lto -o test-persistent ../examples/persistent_demo/persistent_demo.c > /dev/null 2>&1
test -e test-persistent && { test -e test-persistent && {
echo foo | ../afl-showmap -o /dev/null -q -r ./test-persistent && { echo foo | ../afl-showmap -m none -o /dev/null -q -r ./test-persistent && {
$ECHO "$GREEN[+] llvm_mode LTO persistent mode feature works correctly" $ECHO "$GREEN[+] llvm_mode LTO persistent mode feature works correctly"
} || { } || {
$ECHO "$RED[!] llvm_mode LTO persistent mode feature failed to work" $ECHO "$RED[!] llvm_mode LTO persistent mode feature failed to work"
@ -638,43 +637,43 @@ test -e ../libdislocator.so && {
INCOMPLETE=1 INCOMPLETE=1
} }
rm -f test-compcov rm -f test-compcov
test -e ../libradamsa.so && { #test -e ../libradamsa.so && {
# on FreeBSD need to set AFL_CC # # on FreeBSD need to set AFL_CC
test `uname -s` = 'FreeBSD' && { # test `uname -s` = 'FreeBSD' && {
if type clang >/dev/null; then # if type clang >/dev/null; then
export AFL_CC=`command -v clang` # export AFL_CC=`command -v clang`
else # else
export AFL_CC=`$LLVM_CONFIG --bindir`/clang # export AFL_CC=`$LLVM_CONFIG --bindir`/clang
fi # fi
} # }
test -e test-instr.plain || ../afl-clang-fast -o test-instr.plain ../test-instr.c > /dev/null 2>&1 # test -e test-instr.plain || ../afl-clang-fast -o test-instr.plain ../test-instr.c > /dev/null 2>&1
test -e test-instr.plain || ../afl-gcc-fast -o test-instr.plain ../test-instr.c > /dev/null 2>&1 # test -e test-instr.plain || ../afl-gcc-fast -o test-instr.plain ../test-instr.c > /dev/null 2>&1
test -e test-instr.plain || ../${AFL_GCC} -o test-instr.plain ../test-instr.c > /dev/null 2>&1 # test -e test-instr.plain || ../${AFL_GCC} -o test-instr.plain ../test-instr.c > /dev/null 2>&1
test -e test-instr.plain && { # test -e test-instr.plain && {
mkdir -p in # mkdir -p in
printf 1 > in/in # printf 1 > in/in
$ECHO "$GREY[*] running afl-fuzz with radamsa, this will take approx 10 seconds" # $ECHO "$GREY[*] running afl-fuzz with radamsa, this will take approx 10 seconds"
{ # {
../afl-fuzz -RR -V10 -m ${MEM_LIMIT} -i in -o out -- ./test-instr.plain # ../afl-fuzz -RR -V10 -m ${MEM_LIMIT} -i in -o out -- ./test-instr.plain
} >>errors 2>&1 # } >>errors 2>&1
test -n "$( ls out/queue/id:000001* 2>/dev/null )" && { # test -n "$( ls out/queue/id:000001* 2>/dev/null )" && {
$ECHO "$GREEN[+] libradamsa performs good - and very slow - mutations" # $ECHO "$GREEN[+] libradamsa performs good - and very slow - mutations"
} || { # } || {
echo CUT------------------------------------------------------------------CUT # echo CUT------------------------------------------------------------------CUT
cat errors # cat errors
echo CUT------------------------------------------------------------------CUT # echo CUT------------------------------------------------------------------CUT
$ECHO "$RED[!] libradamsa failed" # $ECHO "$RED[!] libradamsa failed"
CODE=1 # CODE=1
} # }
rm -rf in out errors test-instr.plain # rm -rf in out errors test-instr.plain
} || { # } || {
$ECHO "$YELLOW[-] compilation of test target failed, cannot test libradamsa" # $ECHO "$YELLOW[-] compilation of test target failed, cannot test libradamsa"
INCOMPLETE=1 # INCOMPLETE=1
} # }
} || { #} || {
$ECHO "$YELLOW[-] libradamsa is not compiled, cannot test" # $ECHO "$YELLOW[-] libradamsa is not compiled, cannot test"
INCOMPLETE=1 # INCOMPLETE=1
} #}
test -z "$AFL_CC" && { test -z "$AFL_CC" && {
if type gcc >/dev/null; then if type gcc >/dev/null; then
@ -902,6 +901,9 @@ $ECHO "$BLUE[*] Testing: unicorn_mode"
test -d ../unicorn_mode/unicornafl && { test -d ../unicorn_mode/unicornafl && {
test -e ../unicorn_mode/samples/simple/simple_target.bin -a -e ../unicorn_mode/samples/compcov_x64/compcov_target.bin && { test -e ../unicorn_mode/samples/simple/simple_target.bin -a -e ../unicorn_mode/samples/compcov_x64/compcov_target.bin && {
{ {
# We want to see python errors etc. in logs, in case something doesn't work
export AFL_DEBUG_CHILD_OUTPUT=1
# some python version should be available now # some python version should be available now
PYTHONS="`command -v python3` `command -v python` `command -v python2`" PYTHONS="`command -v python3` `command -v python` `command -v python2`"
EASY_INSTALL_FOUND=0 EASY_INSTALL_FOUND=0
@ -988,6 +990,9 @@ test -d ../unicorn_mode/unicornafl && {
rm -rf in out errors rm -rf in out errors
} }
fi fi
unset AFL_DEBUG_CHILD_OUTPUT
} }
} || { } || {
$ECHO "$RED[!] missing sample binaries in unicorn_mode/samples/ - what is going on??" $ECHO "$RED[!] missing sample binaries in unicorn_mode/samples/ - what is going on??"

View File

@ -0,0 +1,75 @@
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <assert.h>
#include <cmocka.h>
/* 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-fuzz.h"
#include "hash.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);
void __wrap_exit(int status) {
assert(0);
}
/* ignore all printfs */
#undef printf
extern int printf(const char *format, ...);
extern int __real_printf(const char *format, ...);
int __wrap_printf(const char *format, ...);
int __wrap_printf(const char *format, ...) {
return 1;
}
/* Rand with 0 seed would broke in the past */
static void test_hash(void **state) {
char bitmap[64] = {0};
u64 hash0 = hash64(bitmap, sizeof(bitmap), 0xa5b35705);
bitmap[10] = 1;
u64 hash1 = hash64(bitmap, sizeof(bitmap), 0xa5b35705);
assert_int_not_equal(hash0, hash1);
bitmap[10] = 0;
assert_int_equal(hash0, hash64(bitmap, sizeof(bitmap), 0xa5b35705));
bitmap[10] = 1;
assert_int_equal(hash1, hash64(bitmap, sizeof(bitmap), 0xa5b35705));
}
int main(int argc, char **argv) {
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_hash)
};
//return cmocka_run_group_tests (tests, setup, teardown);
__real_exit( cmocka_run_group_tests (tests, NULL, NULL) );
// fake return for dumb compilers
return 0;
}

View File

@ -0,0 +1,84 @@
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <assert.h>
#include <cmocka.h>
#include <sys/stat.h>
#include <fcntl.h>
/* 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-fuzz.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);
void __wrap_exit(int status) {
assert(0);
}
/* ignore all printfs */
#undef printf
extern int printf(const char *format, ...);
extern int __real_printf(const char *format, ...);
int __wrap_printf(const char *format, ...);
int __wrap_printf(const char *format, ...) {
return 1;
}
/* Rand with 0 seed would broke in the past */
static void test_rand_0(void **state) {
afl_state_t afl = {0};
rand_set_seed(&afl, 0);
/* give this one chance to retry */
assert_int_not_equal(
(rand_next(&afl) != rand_next(&afl)
|| rand_next(&afl) != rand_next(&afl))
, 0);
}
static void test_rand_below(void **state) {
afl_state_t afl = {0};
rand_set_seed(&afl, 1337);
afl.fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY);
assert(!(rand_below(&afl, 9000) > 9000));
assert_int_equal(rand_below(&afl, 1), 0);
}
int main(int argc, char **argv) {
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_rand_0),
cmocka_unit_test(test_rand_below)
};
//return cmocka_run_group_tests (tests, setup, teardown);
__real_exit( cmocka_run_group_tests (tests, NULL, NULL) );
// fake return for dumb compilers
return 0;
}

View File

@ -1 +1 @@
04765d30 0ca7a8f2