mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-12 10:08:07 +00:00
4
.gitignore
vendored
4
.gitignore
vendored
@ -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
|
||||||
|
@ -9,9 +9,9 @@ branches:
|
|||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- os: linux
|
# - os: linux # focal errors every run with a timeout while installing packages
|
||||||
dist: focal
|
# dist: focal
|
||||||
env: NAME="focal-amd64" MODERN="yes" GCC="9"
|
# env: NAME="focal-amd64" MODERN="yes" GCC="9"
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: bionic
|
dist: bionic
|
||||||
env: NAME="bionic-amd64" MODERN="yes" GCC="7"
|
env: NAME="bionic-amd64" MODERN="yes" GCC="7"
|
||||||
|
112
GNUmakefile
112
GNUmakefile
@ -50,19 +50,30 @@ else
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -fno-move-loop-invariants -fdisable-tree-cunrolli -x c - -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||||
|
SPECIAL_PERFORMANCE += -fno-move-loop-invariants -fdisable-tree-cunrolli
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq "$(shell uname)" "Darwin"
|
ifneq "$(shell uname)" "Darwin"
|
||||||
#ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -march=native -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -march=native -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||||
# CFLAGS_OPT += -march=native
|
#CFLAGS_OPT += -march=native
|
||||||
#endif
|
SPECIAL_PERFORMANCE += -march=native
|
||||||
|
endif
|
||||||
# OS X does not like _FORTIFY_SOURCE=2
|
# OS X does not like _FORTIFY_SOURCE=2
|
||||||
CFLAGS_OPT += -D_FORTIFY_SOURCE=2
|
CFLAGS_OPT += -D_FORTIFY_SOURCE=2
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq "$(shell uname)" "SunOS"
|
||||||
|
CFLAGS_OPT += -Wno-format-truncation
|
||||||
|
LDFLAGS=-lkstat
|
||||||
|
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
|
||||||
@ -86,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"
|
||||||
@ -109,6 +120,13 @@ ifeq "$(shell uname -s)" "NetBSD"
|
|||||||
LDFLAGS += -L /usr/pkg/lib/
|
LDFLAGS += -L /usr/pkg/lib/
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq "$(shell uname -s)" "Haiku"
|
||||||
|
SHMAT_OK=0
|
||||||
|
override CFLAGS += -DUSEMMAP=1 -Wno-error=format -fPIC
|
||||||
|
LDFLAGS += -Wno-deprecated-declarations -lgnu
|
||||||
|
SPECIAL_PERFORMANCE += -DUSEMMAP=1
|
||||||
|
endif
|
||||||
|
|
||||||
AFL_FUZZ_FILES = $(wildcard src/afl-fuzz*.c)
|
AFL_FUZZ_FILES = $(wildcard src/afl-fuzz*.c)
|
||||||
|
|
||||||
ifneq "$(shell command -v python3m 2>/dev/null)" ""
|
ifneq "$(shell command -v python3m 2>/dev/null)" ""
|
||||||
@ -182,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
|
||||||
|
|
||||||
@ -227,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
|
||||||
|
|
||||||
@ -235,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
|
||||||
@ -265,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"
|
||||||
@ -294,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
|
||||||
@ -345,6 +365,9 @@ afl-as: src/afl-as.c include/afl-as.h $(COMM_HDR) | test_x86
|
|||||||
$(CC) $(CFLAGS) src/$@.c -o $@ $(LDFLAGS)
|
$(CC) $(CFLAGS) src/$@.c -o $@ $(LDFLAGS)
|
||||||
ln -sf afl-as as
|
ln -sf afl-as as
|
||||||
|
|
||||||
|
src/afl-performance.o : $(COMM_HDR) src/afl-performance.c include/hash.h
|
||||||
|
$(CC) -Iinclude $(SPECIAL_PERFORMANCE) -O3 -fno-unroll-loops -c src/afl-performance.c -o src/afl-performance.o
|
||||||
|
|
||||||
src/afl-common.o : $(COMM_HDR) src/afl-common.c include/common.h
|
src/afl-common.o : $(COMM_HDR) src/afl-common.c include/common.h
|
||||||
$(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-common.c -o src/afl-common.o
|
$(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-common.c -o src/afl-common.o
|
||||||
|
|
||||||
@ -354,42 +377,47 @@ 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
|
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
|
||||||
cp src/third_party/libradamsa/libradamsa.so .
|
$(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)
|
||||||
|
|
||||||
src/third_party/libradamsa/libradamsa.so: src/third_party/libradamsa/libradamsa.c src/third_party/libradamsa/radamsa.h
|
|
||||||
$(MAKE) -C src/third_party/libradamsa/ CFLAGS="$(CFLAGS)"
|
|
||||||
|
|
||||||
afl-fuzz: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o | test_x86
|
|
||||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(PYFLAGS) $(LDFLAGS)
|
|
||||||
|
|
||||||
afl-showmap: src/afl-showmap.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o $(COMM_HDR) | test_x86
|
afl-showmap: src/afl-showmap.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o $(COMM_HDR) | test_x86
|
||||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(LDFLAGS)
|
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
afl-tmin: src/afl-tmin.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o $(COMM_HDR) | test_x86
|
afl-tmin: src/afl-tmin.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o $(COMM_HDR) | test_x86
|
||||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(LDFLAGS)
|
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
afl-analyze: src/afl-analyze.c src/afl-common.o src/afl-sharedmem.o $(COMM_HDR) | test_x86
|
afl-analyze: src/afl-analyze.c src/afl-common.o src/afl-sharedmem.o src/afl-performance.o $(COMM_HDR) | test_x86
|
||||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o -o $@ $(LDFLAGS)
|
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-performance.o -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
afl-gotcpu: src/afl-gotcpu.c src/afl-common.o $(COMM_HDR) | test_x86
|
afl-gotcpu: src/afl-gotcpu.c src/afl-common.o $(COMM_HDR) | test_x86
|
||||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o -o $@ $(LDFLAGS)
|
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
|
|
||||||
# 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 | 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) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o afl-fuzz-document $(PYFLAGS) $(LDFLAGS)
|
$(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
|
||||||
|
|
||||||
@ -397,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
|
||||||
@ -409,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
|
||||||
|
|
||||||
@ -429,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
|
||||||
@ -481,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
|
||||||
@ -495,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
|
||||||
@ -504,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
|
||||||
@ -554,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
|
||||||
|
23
README.md
23
README.md
@ -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
|
||||||
|
11
TODO.md
11
TODO.md
@ -3,13 +3,9 @@
|
|||||||
## Roadmap 2.65+
|
## Roadmap 2.65+
|
||||||
|
|
||||||
- AFL_MAP_SIZE for qemu_mode and unicorn_mode
|
- AFL_MAP_SIZE for qemu_mode and unicorn_mode
|
||||||
- random crc32 HASH_CONST per run? because with 65536 paths we have collisions
|
|
||||||
- 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
|
- CPU affinity for many cores? There seems to be an issue > 96 cores
|
||||||
- for persistent mode, have a functionality that transports the test case
|
|
||||||
via shared memory (and the int write to the FD from afl-fuzz is the size)
|
|
||||||
- CPU affinity for many cores?
|
|
||||||
|
|
||||||
## Further down the road
|
## Further down the road
|
||||||
|
|
||||||
@ -18,9 +14,10 @@ afl-fuzz:
|
|||||||
- 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:
|
llvm_mode:
|
||||||
- better whitelist solution for LTO
|
- LTO - imitate sancov
|
||||||
|
|
||||||
gcc_plugin:
|
gcc_plugin:
|
||||||
|
- (wait for submission then decide)
|
||||||
- laf-intel
|
- laf-intel
|
||||||
- better instrumentation (seems to be better with gcc-9+)
|
- better instrumentation (seems to be better with gcc-9+)
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
76
afl-plot
76
afl-plot
@ -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
12
custom_mutators/README.md
Normal 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.
|
@ -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
|
@ -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.
|
||||||
|
|
342
custom_mutators/radamsa/custom_mutator_helpers.h
Normal file
342
custom_mutators/radamsa/custom_mutator_helpers.h
Normal 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
|
||||||
|
|
81
custom_mutators/radamsa/libradamsa-test.c
Normal file
81
custom_mutators/radamsa/libradamsa-test.c
Normal 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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
61880
custom_mutators/radamsa/libradamsa.c
Normal file
61880
custom_mutators/radamsa/libradamsa.c
Normal file
File diff suppressed because it is too large
Load Diff
70
custom_mutators/radamsa/radamsa-mutator.c
Normal file
70
custom_mutators/radamsa/radamsa-mutator.c
Normal 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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
10
custom_mutators/radamsa/radamsa.h
Normal file
10
custom_mutators/radamsa/radamsa.h
Normal 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);
|
||||||
|
|
124
dictionaries/ftp.dict
Normal file
124
dictionaries/ftp.dict
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
# from https://github.com/antonio-morales/Fuzzing/Dictionaries/FTP/Example.dict.txt
|
||||||
|
#Parameters
|
||||||
|
#tls = {0,1,2,3}
|
||||||
|
|
||||||
|
#Input1
|
||||||
|
"user"
|
||||||
|
"pass"
|
||||||
|
"syst"
|
||||||
|
"acct"
|
||||||
|
"feat"
|
||||||
|
"noop"
|
||||||
|
"help"
|
||||||
|
"stat"
|
||||||
|
"stru"
|
||||||
|
"adat"
|
||||||
|
"site"
|
||||||
|
|
||||||
|
#Input2
|
||||||
|
"mkd"
|
||||||
|
"cwd"
|
||||||
|
"pwd"
|
||||||
|
"cdup"
|
||||||
|
|
||||||
|
#Input3
|
||||||
|
"port"
|
||||||
|
"list"
|
||||||
|
"mlst"
|
||||||
|
"nlst"
|
||||||
|
"mlsd"
|
||||||
|
|
||||||
|
#Input4
|
||||||
|
"rmd"
|
||||||
|
|
||||||
|
#Input5
|
||||||
|
"stor"
|
||||||
|
|
||||||
|
#Input6
|
||||||
|
"retr"
|
||||||
|
|
||||||
|
#Input7
|
||||||
|
"dele"
|
||||||
|
|
||||||
|
#Input8
|
||||||
|
"pasv"
|
||||||
|
|
||||||
|
#Input9
|
||||||
|
"epsv"
|
||||||
|
|
||||||
|
#Input10
|
||||||
|
"type"
|
||||||
|
"size"
|
||||||
|
|
||||||
|
#Input11
|
||||||
|
"mode"
|
||||||
|
|
||||||
|
#Input12
|
||||||
|
"rnfr"
|
||||||
|
"rnto"
|
||||||
|
|
||||||
|
#Input13
|
||||||
|
"appe"
|
||||||
|
|
||||||
|
#Input14
|
||||||
|
"allo"
|
||||||
|
"quit"
|
||||||
|
|
||||||
|
#Input15
|
||||||
|
"connect"
|
||||||
|
|
||||||
|
#Input16
|
||||||
|
"esta"
|
||||||
|
"estp"
|
||||||
|
|
||||||
|
#Input17
|
||||||
|
"mdtm"
|
||||||
|
"opts"
|
||||||
|
"eprt"
|
||||||
|
|
||||||
|
#Input18
|
||||||
|
"mfmt"
|
||||||
|
"pret"
|
||||||
|
"stou"
|
||||||
|
"rest"
|
||||||
|
|
||||||
|
|
||||||
|
#-------------------------------------
|
||||||
|
"\x00"
|
||||||
|
"\x0d\x0a"
|
||||||
|
"\x0d"
|
||||||
|
"\x0a"
|
||||||
|
"-"
|
||||||
|
"-a "
|
||||||
|
"-C "
|
||||||
|
"-d "
|
||||||
|
"-F "
|
||||||
|
"-l "
|
||||||
|
"-r "
|
||||||
|
"-R "
|
||||||
|
"-S "
|
||||||
|
"-t"
|
||||||
|
" "
|
||||||
|
"fuzzing"
|
||||||
|
"test"
|
||||||
|
"teste"
|
||||||
|
".txt"
|
||||||
|
"test.txt"
|
||||||
|
" UTC"
|
||||||
|
"C"
|
||||||
|
"E"
|
||||||
|
"P"
|
||||||
|
"S"
|
||||||
|
"abor"
|
||||||
|
|
||||||
|
#ifdef WITH_TLS
|
||||||
|
"pbsz"
|
||||||
|
"auth"
|
||||||
|
"prot"
|
||||||
|
"ccc"
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
"xdbg"
|
||||||
|
|
||||||
|
# ifdef WITH_DIRALIASES
|
||||||
|
"alias"
|
@ -71,7 +71,7 @@
|
|||||||
"Location"
|
"Location"
|
||||||
"Max-Forwards"
|
"Max-Forwards"
|
||||||
"Origin"
|
"Origin"
|
||||||
"P3P "
|
"P3P"
|
||||||
"Pragma"
|
"Pragma"
|
||||||
"Proxy-Authenticate"
|
"Proxy-Authenticate"
|
||||||
"Proxy-Authorization"
|
"Proxy-Authorization"
|
||||||
|
@ -373,7 +373,7 @@
|
|||||||
"ALT "
|
"ALT "
|
||||||
"AMH "
|
"AMH "
|
||||||
"ANG "
|
"ANG "
|
||||||
"APPH"
|
"APPH"
|
||||||
"ARA "
|
"ARA "
|
||||||
"ARG "
|
"ARG "
|
||||||
"ARI "
|
"ARI "
|
||||||
@ -394,9 +394,9 @@
|
|||||||
"BAR "
|
"BAR "
|
||||||
"BAU "
|
"BAU "
|
||||||
"BBC "
|
"BBC "
|
||||||
"BBR "
|
"BBR "
|
||||||
"BCH "
|
"BCH "
|
||||||
"BCR "
|
"BCR "
|
||||||
"BDY "
|
"BDY "
|
||||||
"BEL "
|
"BEL "
|
||||||
"BEM "
|
"BEM "
|
||||||
@ -416,7 +416,7 @@
|
|||||||
"BLN "
|
"BLN "
|
||||||
"BLT "
|
"BLT "
|
||||||
"BMB "
|
"BMB "
|
||||||
"BML "
|
"BML "
|
||||||
"BOS "
|
"BOS "
|
||||||
"BPY "
|
"BPY "
|
||||||
"BRE "
|
"BRE "
|
||||||
@ -521,7 +521,7 @@
|
|||||||
"GAE "
|
"GAE "
|
||||||
"GAG "
|
"GAG "
|
||||||
"GAL "
|
"GAL "
|
||||||
"GAR "
|
"GAR "
|
||||||
"GAW "
|
"GAW "
|
||||||
"GEZ "
|
"GEZ "
|
||||||
"GIH "
|
"GIH "
|
||||||
@ -725,7 +725,7 @@
|
|||||||
"MOK "
|
"MOK "
|
||||||
"MOL "
|
"MOL "
|
||||||
"MON "
|
"MON "
|
||||||
"MOR "
|
"MOR "
|
||||||
"MOS "
|
"MOS "
|
||||||
"MRI "
|
"MRI "
|
||||||
"MTH "
|
"MTH "
|
||||||
@ -751,7 +751,7 @@
|
|||||||
"NEP "
|
"NEP "
|
||||||
"NEW "
|
"NEW "
|
||||||
"NGA "
|
"NGA "
|
||||||
"NGR "
|
"NGR "
|
||||||
"NHC "
|
"NHC "
|
||||||
"NIS "
|
"NIS "
|
||||||
"NIU "
|
"NIU "
|
||||||
@ -930,7 +930,7 @@
|
|||||||
"VIT "
|
"VIT "
|
||||||
"VOL "
|
"VOL "
|
||||||
"VRO "
|
"VRO "
|
||||||
"WA "
|
"WA "
|
||||||
"WAG "
|
"WAG "
|
||||||
"WAR "
|
"WAR "
|
||||||
"WCR "
|
"WCR "
|
||||||
@ -949,7 +949,7 @@
|
|||||||
"YAP "
|
"YAP "
|
||||||
"YBA "
|
"YBA "
|
||||||
"YCR "
|
"YCR "
|
||||||
"YIC "
|
"YIC "
|
||||||
"YIM "
|
"YIM "
|
||||||
"ZEA "
|
"ZEA "
|
||||||
"ZGH "
|
"ZGH "
|
||||||
|
@ -11,21 +11,32 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
|
|||||||
|
|
||||||
### Version ++2.65d (dev)
|
### Version ++2.65d (dev)
|
||||||
- afl-fuzz:
|
- afl-fuzz:
|
||||||
- -S secondary nodes now only sync from the main node to increase performance,
|
- -S secondary nodes now only sync from the main node to increase
|
||||||
the -M main node still syncs from everyone. Added checks that ensure
|
performance, the -M main node still syncs from everyone. Added checks
|
||||||
exactly one main node is present and warn otherwise
|
that ensure exactly one main node is present and warn otherwise
|
||||||
- If no main node is present at a sync one secondary node automatically becomes
|
- Add -D after -S to force a secondary to perform deterministic fuzzing
|
||||||
a temporary main node until a real main nodes shows up
|
- 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
|
||||||
|
- Fixed a mayor performance issue we inherited from AFLfast
|
||||||
|
- switched murmur2 hashing and random() for xxh3 and xoshiro256**,
|
||||||
|
resulting in an up to 5.5% speed increase
|
||||||
|
- Resizing the window does not crash afl-fuzz anymore
|
||||||
|
- 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 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, as it is faster and provides
|
- the default instrumentation is now PCGUARD if the llvm version is >= 7,
|
||||||
better coverage. The original afl instrumentation can be set via
|
as it is faster and provides better coverage. The original afl
|
||||||
AFL_LLVM_INSTRUMENT=AFL. This is automatically done when the WHITELIST
|
instrumentation can be set via AFL_LLVM_INSTRUMENT=AFL. This is
|
||||||
feature is used.
|
automatically done when the WHITELIST feature is used.
|
||||||
- some targets want a ld variant for LD that is not gcc/clang but ld, added
|
- PCGUARD mode is now even better because we made it collision free - plus
|
||||||
afl-ld-lto to solve this
|
it has a fixed map size, so it is also faster! :)
|
||||||
- lowered minimum required llvm version to 3.4 (except LLVMInsTrim,
|
- some targets want a ld variant for LD that is not gcc/clang but ld,
|
||||||
which needs 3.8.0)
|
added afl-ld-lto to solve this
|
||||||
|
- lowered minimum required llvm version to 3.4 (except LLVMInsTrim, which
|
||||||
|
needs 3.8.0)
|
||||||
- WHITELIST feature now supports wildcards (thanks to sirmc)
|
- WHITELIST feature now supports wildcards (thanks to sirmc)
|
||||||
- small change to cmplog to make it work with current llvm 11-dev
|
- small change to cmplog to make it work with current llvm 11-dev
|
||||||
- added AFL_LLVM_LAF_ALL, sets all laf-intel settings
|
- added AFL_LLVM_LAF_ALL, sets all laf-intel settings
|
||||||
@ -37,16 +48,23 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
|
|||||||
- enable snapshot lkm also for persistent mode
|
- enable snapshot lkm also for persistent mode
|
||||||
- Unicornafl
|
- Unicornafl
|
||||||
- Added powerPC support from unicorn/next
|
- Added powerPC support from unicorn/next
|
||||||
|
- 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
|
||||||
- added lots of dictionaries from oss-fuzz, go-fuzz and Jakub Wilk
|
- added lots of dictionaries from oss-fuzz, go-fuzz and Jakub Wilk
|
||||||
- added former post_library examples to examples/custom_mutators/
|
- added former post_library examples to examples/custom_mutators/
|
||||||
- Dockerfile upgraded to Ubuntu 20.04 Focal and installing llvm 11 and gcc 10
|
- Dockerfile upgraded to Ubuntu 20.04 Focal and installing llvm 11 and
|
||||||
so afl-clang-lto can be build
|
gcc 10 so afl-clang-lto can be build
|
||||||
|
|
||||||
|
|
||||||
### Version ++2.65c (release):
|
### Version ++2.65c (release):
|
||||||
|
@ -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
|
|
@ -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
|
||||||
|
@ -21,6 +21,7 @@ We find that AFL's exploitation-based constant schedule assigns **too much energ
|
|||||||
| `-p exploit` (AFL) |  |
|
| `-p exploit` (AFL) |  |
|
||||||
| `-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/).
|
||||||
|
@ -7,20 +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++ -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
|
||||||
@ -34,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++ -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
|
||||||
|
@ -54,6 +54,10 @@ If 1, close stdout at startup. If 2 close stderr; if 3 close both.
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#include "hash.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// Platform detection. Copied from FuzzerInternal.h
|
// Platform detection. Copied from FuzzerInternal.h
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#define LIBFUZZER_LINUX 1
|
#define LIBFUZZER_LINUX 1
|
||||||
@ -273,7 +277,11 @@ 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, "len: %u\n", *__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:");
|
||||||
|
for (int i = 0; i < *__afl_fuzz_len; i++)
|
||||||
|
fprintf(stderr, "%02x", __afl_fuzz_ptr[i]);
|
||||||
|
fprintf(stderr,"\n");
|
||||||
#endif
|
#endif
|
||||||
if (*__afl_fuzz_len) {
|
if (*__afl_fuzz_len) {
|
||||||
num_runs++;
|
num_runs++;
|
||||||
|
@ -1,19 +1,21 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "hash.h"
|
||||||
|
|
||||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||||
|
|
||||||
fprintf(stderr, "Received size %lu\n", Size);
|
fprintf(stderr, "FUNC crc: %016llx len: %lu\n", hash64((u8*)Data, (unsigned int) Size, (unsigned long long int) 0xa5b35705), Size);
|
||||||
|
|
||||||
if (Size < 4)
|
if (Size < 5)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (Data[0] == 'F')
|
if (Data[0] == 'F')
|
||||||
if (Data[1] == 'A')
|
if (Data[1] == 'A')
|
||||||
if (Data[2] == '$')
|
if (Data[2] == '$')
|
||||||
if (Data[3] == '$')
|
if (Data[3] == '$')
|
||||||
abort();
|
if (Data[4] == '$')
|
||||||
|
abort();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -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");
|
||||||
|
@ -28,11 +28,12 @@ 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,13 +61,15 @@ 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 += -lrt
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq "$(TEST_MMAP)" "1"
|
ifeq "$(TEST_MMAP)" "1"
|
||||||
SHMAT_OK=0
|
SHMAT_OK=0
|
||||||
CFLAGS+=-DUSEMMAP=1
|
override CFLAGS += -DUSEMMAP=1
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq "$(shell uname -s)" "Haiku"
|
||||||
LDFLAGS += -lrt
|
LDFLAGS += -lrt
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -111,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..."
|
||||||
|
@ -231,7 +231,7 @@ static void edit_params(u32 argc, char **argv) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USEMMAP
|
#if defined(USEMMAP) && !defined(__HAIKU__)
|
||||||
cc_params[cc_par_cnt++] = "-lrt";
|
cc_params[cc_par_cnt++] = "-lrt";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -35,7 +35,9 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/shm.h>
|
#ifndef USEMMAP
|
||||||
|
#include <sys/shm.h>
|
||||||
|
#endif
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
@ -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>
|
||||||
@ -66,7 +67,9 @@
|
|||||||
|
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/shm.h>
|
#ifndef USEMMAP
|
||||||
|
#include <sys/shm.h>
|
||||||
|
#endif
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
@ -83,7 +86,7 @@
|
|||||||
can hope... */
|
can hope... */
|
||||||
|
|
||||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
|
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
|
||||||
defined(__DragonFly__)
|
defined(__DragonFly__) || defined(__sun)
|
||||||
#define HAVE_AFFINITY 1
|
#define HAVE_AFFINITY 1
|
||||||
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -96,6 +99,11 @@
|
|||||||
#define cpu_set_t cpuset_t
|
#define cpu_set_t cpuset_t
|
||||||
#elif defined(__NetBSD__)
|
#elif defined(__NetBSD__)
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#elif defined(__sun)
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <kstat.h>
|
||||||
|
#include <sys/sysinfo.h>
|
||||||
|
#include <sys/pset.h>
|
||||||
#endif
|
#endif
|
||||||
#endif /* __linux__ */
|
#endif /* __linux__ */
|
||||||
|
|
||||||
@ -134,13 +142,13 @@ struct queue_entry {
|
|||||||
fully_colorized; /* Do not run redqueen stage again */
|
fully_colorized; /* Do not run redqueen stage again */
|
||||||
|
|
||||||
u32 bitmap_size, /* Number of bits set in bitmap */
|
u32 bitmap_size, /* Number of bits set in bitmap */
|
||||||
fuzz_level, /* Number of fuzzing iterations */
|
fuzz_level; /* Number of fuzzing iterations */
|
||||||
exec_cksum; /* Checksum of the execution trace */
|
|
||||||
|
|
||||||
u64 exec_us, /* Execution time (us) */
|
u64 exec_us, /* Execution time (us) */
|
||||||
handicap, /* Number of queue cycles behind */
|
handicap, /* Number of queue cycles behind */
|
||||||
n_fuzz, /* Number of fuzz, does not overflow */
|
n_fuzz, /* Number of fuzz, does not overflow*/
|
||||||
depth; /* Path depth */
|
depth, /* Path depth */
|
||||||
|
exec_cksum; /* Checksum of the execution trace */
|
||||||
|
|
||||||
u8 *trace_mini; /* Trace bytes, if kept */
|
u8 *trace_mini; /* Trace bytes, if kept */
|
||||||
u32 tc_ref; /* Trace bytes ref count */
|
u32 tc_ref; /* Trace bytes ref count */
|
||||||
@ -180,10 +188,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
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -197,7 +206,7 @@ enum {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define operator_num 16
|
#define operator_num 18
|
||||||
#define swarm_num 5
|
#define swarm_num 5
|
||||||
#define period_core 500000
|
#define period_core 500000
|
||||||
|
|
||||||
@ -211,18 +220,21 @@ enum {
|
|||||||
#define STAGE_DELETEBYTE 13
|
#define STAGE_DELETEBYTE 13
|
||||||
#define STAGE_Clone75 14
|
#define STAGE_Clone75 14
|
||||||
#define STAGE_OverWrite75 15
|
#define STAGE_OverWrite75 15
|
||||||
|
#define STAGE_OverWriteExtra 16
|
||||||
|
#define STAGE_InsertExtra 17
|
||||||
#define period_pilot 50000
|
#define period_pilot 50000
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
||||||
/* 00 */ EXPLORE, /* AFL default, Exploration-based constant schedule */
|
/* 00 */ EXPLORE, /* AFL default, Exploration-based constant schedule */
|
||||||
/* 01 */ FAST, /* Exponential schedule */
|
/* 01 */ EXPLOIT, /* AFL's exploitation-based const. */
|
||||||
/* 02 */ COE, /* Cut-Off Exponential schedule */
|
/* 02 */ FAST, /* Exponential schedule */
|
||||||
/* 03 */ LIN, /* Linear schedule */
|
/* 03 */ COE, /* Cut-Off Exponential schedule */
|
||||||
/* 04 */ QUAD, /* Quadratic schedule */
|
/* 04 */ LIN, /* Linear schedule */
|
||||||
/* 05 */ EXPLOIT, /* AFL's exploitation-based const. */
|
/* 05 */ QUAD, /* Quadratic schedule */
|
||||||
/* 06 */ MMOPT, /* Modified MOPT schedule */
|
/* 06 */ RARE, /* Rare edges */
|
||||||
/* 07 */ RARE, /* Rare edges */
|
/* 07 */ MMOPT, /* Modified MOPT schedule */
|
||||||
|
/* 08 */ SEEK, /* EXPLORE that ignores timings */
|
||||||
|
|
||||||
POWER_SCHEDULES_NUM
|
POWER_SCHEDULES_NUM
|
||||||
|
|
||||||
@ -416,9 +428,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? */
|
||||||
@ -515,11 +524,9 @@ typedef struct afl_state {
|
|||||||
u64 stage_finds[32], /* Patterns found per fuzz stage */
|
u64 stage_finds[32], /* Patterns found per fuzz stage */
|
||||||
stage_cycles[32]; /* Execs per fuzz stage */
|
stage_cycles[32]; /* Execs per fuzz stage */
|
||||||
|
|
||||||
#ifndef HAVE_ARC4RANDOM
|
|
||||||
u32 rand_cnt; /* Random number counter */
|
u32 rand_cnt; /* Random number counter */
|
||||||
#endif
|
|
||||||
|
|
||||||
u32 rand_seed[2];
|
u64 rand_seed[4];
|
||||||
s64 init_seed;
|
s64 init_seed;
|
||||||
|
|
||||||
u64 total_cal_us, /* Total calibration time (us) */
|
u64 total_cal_us, /* Total calibration time (us) */
|
||||||
@ -937,7 +944,10 @@ u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len);
|
|||||||
|
|
||||||
/* RedQueen */
|
/* RedQueen */
|
||||||
u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len,
|
u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len,
|
||||||
u32 exec_cksum);
|
u64 exec_cksum);
|
||||||
|
|
||||||
|
/* xoshiro256** */
|
||||||
|
uint64_t rand_next(afl_state_t *afl);
|
||||||
|
|
||||||
/**** Inline routines ****/
|
/**** Inline routines ****/
|
||||||
|
|
||||||
@ -946,34 +956,31 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len,
|
|||||||
|
|
||||||
static inline u32 rand_below(afl_state_t *afl, u32 limit) {
|
static inline u32 rand_below(afl_state_t *afl, u32 limit) {
|
||||||
|
|
||||||
#ifdef HAVE_ARC4RANDOM
|
|
||||||
if (unlikely(afl->fixed_seed)) { return random() % limit; }
|
|
||||||
|
|
||||||
/* The boundary not being necessarily a power of 2,
|
/* The boundary not being necessarily a power of 2,
|
||||||
we need to ensure the result uniformity. */
|
we need to ensure the result uniformity. */
|
||||||
return arc4random_uniform(limit);
|
|
||||||
#else
|
|
||||||
if (unlikely(!afl->rand_cnt--) && likely(!afl->fixed_seed)) {
|
if (unlikely(!afl->rand_cnt--) && likely(!afl->fixed_seed)) {
|
||||||
|
|
||||||
ck_read(afl->fsrv.dev_urandom_fd, &afl->rand_seed, sizeof(afl->rand_seed),
|
ck_read(afl->fsrv.dev_urandom_fd, &afl->rand_seed, sizeof(afl->rand_seed),
|
||||||
"/dev/urandom");
|
"/dev/urandom");
|
||||||
srandom(afl->rand_seed[0]);
|
// srandom(afl->rand_seed[0]);
|
||||||
afl->rand_cnt = (RESEED_RNG / 2) + (afl->rand_seed[1] % RESEED_RNG);
|
afl->rand_cnt = (RESEED_RNG / 2) + (afl->rand_seed[1] % RESEED_RNG);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return random() % limit;
|
return rand_next(afl) % limit;
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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). */
|
||||||
|
|
||||||
|
@ -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; \
|
||||||
\
|
\
|
||||||
|
@ -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);
|
||||||
|
@ -293,7 +293,7 @@
|
|||||||
|
|
||||||
/* Call count interval between reseeding the libc PRNG from /dev/urandom: */
|
/* Call count interval between reseeding the libc PRNG from /dev/urandom: */
|
||||||
|
|
||||||
#define RESEED_RNG 10000
|
#define RESEED_RNG 100000
|
||||||
|
|
||||||
/* Maximum line length passed from GCC to 'as' and used for parsing
|
/* Maximum line length passed from GCC to 'as' and used for parsing
|
||||||
configuration files: */
|
configuration files: */
|
||||||
@ -397,12 +397,5 @@
|
|||||||
|
|
||||||
// #define IGNORE_FINDS
|
// #define IGNORE_FINDS
|
||||||
|
|
||||||
/* for *BSD: use ARC4RANDOM and save a file descriptor */
|
|
||||||
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
|
||||||
#ifndef HAVE_ARC4RANDOM
|
|
||||||
#define HAVE_ARC4RANDOM 1
|
|
||||||
#endif
|
|
||||||
#endif /* __APPLE__ || __FreeBSD__ || __OpenBSD__ */
|
|
||||||
|
|
||||||
#endif /* ! _HAVE_CONFIG_H */
|
#endif /* ! _HAVE_CONFIG_H */
|
||||||
|
|
||||||
|
@ -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...) \
|
||||||
|
@ -47,9 +47,8 @@ typedef struct afl_forkserver {
|
|||||||
out_dir_fd; /* FD of the lock file */
|
out_dir_fd; /* FD of the lock file */
|
||||||
|
|
||||||
s32 out_fd, /* Persistent fd for fsrv->out_file */
|
s32 out_fd, /* Persistent fd for fsrv->out_file */
|
||||||
#ifndef HAVE_ARC4RANDOM
|
|
||||||
dev_urandom_fd, /* Persistent fd for /dev/urandom */
|
dev_urandom_fd, /* Persistent fd for /dev/urandom */
|
||||||
#endif
|
|
||||||
dev_null_fd, /* Persistent fd for /dev/null */
|
dev_null_fd, /* Persistent fd for /dev/null */
|
||||||
fsrv_ctl_fd, /* Fork server control pipe (write) */
|
fsrv_ctl_fd, /* Fork server control pipe (write) */
|
||||||
fsrv_st_fd; /* Fork server status pipe (read) */
|
fsrv_st_fd; /* Fork server status pipe (read) */
|
||||||
|
@ -30,11 +30,18 @@
|
|||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
#ifdef __x86_64__
|
u32 hash32(u8 *key, u32 len, u32 seed);
|
||||||
|
u64 hash64(u8 *key, u32 len, u64 seed);
|
||||||
|
|
||||||
#define ROL64(_x, _r) ((((u64)(_x)) << (_r)) | (((u64)(_x)) >> (64 - (_r))))
|
#if 0
|
||||||
|
|
||||||
static inline u32 hash32(const void *key, u32 len, u32 seed) {
|
The following code is disabled because xxh3 is 30% faster
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
|
||||||
|
#define ROL64(_x, _r) ((((u64)(_x)) << (_r)) | (((u64)(_x)) >> (64 - (_r))))
|
||||||
|
|
||||||
|
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;
|
||||||
@ -65,9 +72,9 @@ static inline u32 hash32(const void *key, u32 len, u32 seed) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define ROL32(_x, _r) ((((u32)(_x)) << (_r)) | (((u32)(_x)) >> (32 - (_r))))
|
#define ROL32(_x, _r) ((((u32)(_x)) << (_r)) | (((u32)(_x)) >> (32 - (_r))))
|
||||||
|
|
||||||
static inline u32 hash32(const void *key, u32 len, u32 seed) {
|
static inline u32 hash32(const void *key, u32 len, u32 seed) {
|
||||||
|
|
||||||
@ -100,7 +107,8 @@ static inline u32 hash32(const void *key, u32 len, u32 seed) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* ^__x86_64__ */
|
#endif /* ^__x86_64__ */
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* !_HAVE_HASH_H */
|
#endif /* !_HAVE_HASH_H */
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
3187
include/xxh3.h
Normal file
3187
include/xxh3.h
Normal file
File diff suppressed because it is too large
Load Diff
2442
include/xxhash.h
Normal file
2442
include/xxhash.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -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>
|
||||||
#include <sys/syscall.h>
|
#ifdef __linux__
|
||||||
|
#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 { \
|
||||||
|
@ -35,10 +35,11 @@ _UNIQ=_QINU_
|
|||||||
_____OS_DL = $(____OS_DL:$(_UNIQ)$(UNAME_S)=)
|
_____OS_DL = $(____OS_DL:$(_UNIQ)$(UNAME_S)=)
|
||||||
______OS_DL = $(_____OS_DL:$(_UNIQ)="-ldl")
|
______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)
|
||||||
|
|
||||||
|
@ -33,8 +33,9 @@
|
|||||||
#include "../types.h"
|
#include "../types.h"
|
||||||
#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
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -357,7 +373,7 @@ int strcasecmp(const char *str1, const char *str2) {
|
|||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
const unsigned char c1 = tolower(*str1), c2 = tolower(*str2);
|
const unsigned char c1 = tolower((int)*str1), c2 = tolower((int)*str2);
|
||||||
|
|
||||||
if (c1 != c2) return (c1 > c2) ? 1 : -1;
|
if (c1 != c2) return (c1 > c2) ? 1 : -1;
|
||||||
if (!c1) return 0;
|
if (!c1) return 0;
|
||||||
@ -381,7 +397,7 @@ int strncasecmp(const char *str1, const char *str2, size_t len) {
|
|||||||
|
|
||||||
while (len--) {
|
while (len--) {
|
||||||
|
|
||||||
const unsigned char c1 = tolower(*str1), c2 = tolower(*str2);
|
const unsigned char c1 = tolower((int)*str1), c2 = tolower((int)*str2);
|
||||||
|
|
||||||
if (c1 != c2) return (c1 > c2) ? 1 : -1;
|
if (c1 != c2) return (c1 > c2) ? 1 : -1;
|
||||||
if (!c1) return 0;
|
if (!c1) return 0;
|
||||||
@ -495,7 +511,7 @@ char *strcasestr(const char *haystack, const char *needle) {
|
|||||||
const char *n = needle;
|
const char *n = needle;
|
||||||
const char *h = haystack;
|
const char *h = haystack;
|
||||||
|
|
||||||
while (*n && *h && tolower(*n) == tolower(*h))
|
while (*n && *h && tolower((int)*n) == tolower((int)*h))
|
||||||
n++, h++;
|
n++, h++;
|
||||||
|
|
||||||
if (!*n) return (char *)haystack;
|
if (!*n) return (char *)haystack;
|
||||||
|
@ -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 -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 -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..."
|
||||||
|
@ -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) {
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
@ -464,7 +466,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USEMMAP
|
#if defined(USEMMAP) && !defined(__HAIKU__)
|
||||||
cc_params[cc_par_cnt++] = "-lrt";
|
cc_params[cc_par_cnt++] = "-lrt";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -500,7 +502,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
|||||||
"unsigned char *__afl_fuzz_alt_ptr;";
|
"unsigned char *__afl_fuzz_alt_ptr;";
|
||||||
cc_params[cc_par_cnt++] =
|
cc_params[cc_par_cnt++] =
|
||||||
"-D__AFL_FUZZ_TESTCASE_BUF=(__afl_fuzz_ptr ? __afl_fuzz_ptr : "
|
"-D__AFL_FUZZ_TESTCASE_BUF=(__afl_fuzz_ptr ? __afl_fuzz_ptr : "
|
||||||
"(__afl_fuzz_alt_ptr = malloc(1 * 1024 * 1024)))";
|
"(__afl_fuzz_alt_ptr = (unsigned char *) malloc(1 * 1024 * 1024)))";
|
||||||
cc_params[cc_par_cnt++] =
|
cc_params[cc_par_cnt++] =
|
||||||
"-D__AFL_FUZZ_TESTCASE_LEN=(__afl_fuzz_ptr ? *__afl_fuzz_len : read(0, "
|
"-D__AFL_FUZZ_TESTCASE_LEN=(__afl_fuzz_ptr ? *__afl_fuzz_len : read(0, "
|
||||||
"__afl_fuzz_alt_ptr, 1 * 1024 * 1024))";
|
"__afl_fuzz_alt_ptr, 1 * 1024 * 1024))";
|
||||||
@ -757,12 +759,14 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
|
|
||||||
if (instrument_mode == 0) {
|
if (instrument_mode == 0) {
|
||||||
|
|
||||||
#ifndef USE_TRACE_PC
|
#if LLVM_VERSION_MAJOR <= 6
|
||||||
|
instrument_mode = INSTRUMENT_AFL;
|
||||||
|
#else
|
||||||
if (getenv("AFL_LLVM_WHITELIST"))
|
if (getenv("AFL_LLVM_WHITELIST"))
|
||||||
instrument_mode = INSTRUMENT_AFL;
|
instrument_mode = INSTRUMENT_AFL;
|
||||||
else
|
else
|
||||||
#endif
|
|
||||||
instrument_mode = INSTRUMENT_PCGUARD;
|
instrument_mode = INSTRUMENT_PCGUARD;
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,8 +110,11 @@ struct InsTrimLTO : public ModulePass {
|
|||||||
|
|
||||||
bool runOnModule(Module &M) override {
|
bool runOnModule(Module &M) override {
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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. */
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -139,7 +139,8 @@ static void __afl_map_shm_fuzz() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
map = (u8 *)mmap(0, MAX_FILE, PROT_READ, MAP_SHARED, shm_fd, 0);
|
map =
|
||||||
|
(u8 *)mmap(0, MAX_FILE + sizeof(u32), PROT_READ, MAP_SHARED, shm_fd, 0);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
u32 shm_id = atoi(id_str);
|
u32 shm_id = atoi(id_str);
|
||||||
@ -157,7 +158,7 @@ static void __afl_map_shm_fuzz() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
__afl_fuzz_len = (u32 *)map;
|
__afl_fuzz_len = (u32 *)map;
|
||||||
__afl_fuzz_ptr = (u8 *)(map + sizeof(u32));
|
__afl_fuzz_ptr = map + sizeof(u32);
|
||||||
|
|
||||||
if (getenv("AFL_DEBUG")) {
|
if (getenv("AFL_DEBUG")) {
|
||||||
|
|
||||||
@ -182,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) {
|
||||||
|
|
||||||
@ -391,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();
|
||||||
@ -590,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)) {
|
||||||
|
|
||||||
@ -870,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;
|
||||||
|
|
||||||
|
@ -237,16 +237,16 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
|
|||||||
switch (max_size) {
|
switch (max_size) {
|
||||||
|
|
||||||
case 8:
|
case 8:
|
||||||
IRB.CreateCall(cmplogHookIns1, args, "tmp");
|
IRB.CreateCall(cmplogHookIns1, args);
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
IRB.CreateCall(cmplogHookIns2, args, "tmp");
|
IRB.CreateCall(cmplogHookIns2, args);
|
||||||
break;
|
break;
|
||||||
case 32:
|
case 32:
|
||||||
IRB.CreateCall(cmplogHookIns4, args, "tmp");
|
IRB.CreateCall(cmplogHookIns4, args);
|
||||||
break;
|
break;
|
||||||
case 64:
|
case 64:
|
||||||
IRB.CreateCall(cmplogHookIns8, args, "tmp");
|
IRB.CreateCall(cmplogHookIns8, args);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -169,7 +169,7 @@ bool CmpLogRoutines::hookRtns(Module &M) {
|
|||||||
args.push_back(v1Pcasted);
|
args.push_back(v1Pcasted);
|
||||||
args.push_back(v2Pcasted);
|
args.push_back(v2Pcasted);
|
||||||
|
|
||||||
IRB.CreateCall(cmplogHookFn, args, "tmp");
|
IRB.CreateCall(cmplogHookFn, args);
|
||||||
|
|
||||||
// errs() << callInst->getCalledFunction()->getName() << "\n";
|
// errs() << callInst->getCalledFunction()->getName() << "\n";
|
||||||
|
|
||||||
|
@ -500,7 +500,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
|
|||||||
load = cur_cmp_IRB.CreateZExt(load, Int32Ty);
|
load = cur_cmp_IRB.CreateZExt(load, Int32Ty);
|
||||||
std::vector<Value *> args;
|
std::vector<Value *> args;
|
||||||
args.push_back(load);
|
args.push_back(load);
|
||||||
load = cur_cmp_IRB.CreateCall(tolowerFn, args, "tmp");
|
load = cur_cmp_IRB.CreateCall(tolowerFn, args);
|
||||||
load = cur_cmp_IRB.CreateTrunc(load, Int8Ty);
|
load = cur_cmp_IRB.CreateTrunc(load, Int8Ty);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -51,7 +51,9 @@
|
|||||||
|
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/shm.h>
|
#ifndef USEMMAP
|
||||||
|
#include <sys/shm.h>
|
||||||
|
#endif
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
@ -66,11 +68,12 @@ static u8 *in_file, /* Analyzer input test case */
|
|||||||
static u8 *in_data; /* Input data for analysis */
|
static u8 *in_data; /* Input data for analysis */
|
||||||
|
|
||||||
static u32 in_len, /* Input data length */
|
static u32 in_len, /* Input data length */
|
||||||
orig_cksum, /* Original checksum */
|
|
||||||
total_execs, /* Total number of execs */
|
total_execs, /* Total number of execs */
|
||||||
exec_hangs, /* Total number of hangs */
|
exec_hangs, /* Total number of hangs */
|
||||||
exec_tmout = EXEC_TIMEOUT; /* Exec timeout (ms) */
|
exec_tmout = EXEC_TIMEOUT; /* Exec timeout (ms) */
|
||||||
|
|
||||||
|
static u64 orig_cksum; /* Original checksum */
|
||||||
|
|
||||||
static u64 mem_limit = MEM_LIMIT; /* Memory limit (MB) */
|
static u64 mem_limit = MEM_LIMIT; /* Memory limit (MB) */
|
||||||
|
|
||||||
static s32 dev_null_fd = -1; /* FD to /dev/null */
|
static s32 dev_null_fd = -1; /* FD to /dev/null */
|
||||||
@ -222,7 +225,7 @@ static u32 analyze_run_target(char **argv, u8 *mem, u32 len, u8 first_run) {
|
|||||||
int status = 0;
|
int status = 0;
|
||||||
|
|
||||||
s32 prog_in_fd;
|
s32 prog_in_fd;
|
||||||
u32 cksum;
|
u64 cksum;
|
||||||
|
|
||||||
memset(trace_bits, 0, map_size);
|
memset(trace_bits, 0, map_size);
|
||||||
MEM_BARRIER();
|
MEM_BARRIER();
|
||||||
@ -321,7 +324,7 @@ static u32 analyze_run_target(char **argv, u8 *mem, u32 len, u8 first_run) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cksum = hash32(trace_bits, map_size, HASH_CONST);
|
cksum = hash64(trace_bits, map_size, HASH_CONST);
|
||||||
|
|
||||||
/* We don't actually care if the target is crashing or not,
|
/* We don't actually care if the target is crashing or not,
|
||||||
except that when it does, the checksum should be different. */
|
except that when it does, the checksum should be different. */
|
||||||
@ -1046,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();
|
||||||
|
@ -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",
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "forkserver.h"
|
#include "forkserver.h"
|
||||||
|
#include "hash.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -70,9 +71,8 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) {
|
|||||||
fsrv->out_fd = -1;
|
fsrv->out_fd = -1;
|
||||||
fsrv->out_dir_fd = -1;
|
fsrv->out_dir_fd = -1;
|
||||||
fsrv->dev_null_fd = -1;
|
fsrv->dev_null_fd = -1;
|
||||||
#ifndef HAVE_ARC4RANDOM
|
|
||||||
fsrv->dev_urandom_fd = -1;
|
fsrv->dev_urandom_fd = -1;
|
||||||
#endif
|
|
||||||
/* Settings */
|
/* Settings */
|
||||||
fsrv->use_stdin = 1;
|
fsrv->use_stdin = 1;
|
||||||
fsrv->no_unlink = 0;
|
fsrv->no_unlink = 0;
|
||||||
@ -103,9 +103,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) {
|
|||||||
fsrv_to->map_size = from->map_size;
|
fsrv_to->map_size = from->map_size;
|
||||||
fsrv_to->support_shmem_fuzz = from->support_shmem_fuzz;
|
fsrv_to->support_shmem_fuzz = from->support_shmem_fuzz;
|
||||||
|
|
||||||
#ifndef HAVE_ARC4RANDOM
|
|
||||||
fsrv_to->dev_urandom_fd = from->dev_urandom_fd;
|
fsrv_to->dev_urandom_fd = from->dev_urandom_fd;
|
||||||
#endif
|
|
||||||
|
|
||||||
// These are forkserver specific.
|
// These are forkserver specific.
|
||||||
fsrv_to->out_dir_fd = -1;
|
fsrv_to->out_dir_fd = -1;
|
||||||
@ -131,7 +129,8 @@ static u32 read_s32_timed(s32 fd, s32 *buf, u32 timeout_ms,
|
|||||||
FD_ZERO(&readfds);
|
FD_ZERO(&readfds);
|
||||||
FD_SET(fd, &readfds);
|
FD_SET(fd, &readfds);
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
size_t len = 4;
|
int sret;
|
||||||
|
ssize_t len_read;
|
||||||
|
|
||||||
timeout.tv_sec = (timeout_ms / 1000);
|
timeout.tv_sec = (timeout_ms / 1000);
|
||||||
timeout.tv_usec = (timeout_ms % 1000) * 1000;
|
timeout.tv_usec = (timeout_ms % 1000) * 1000;
|
||||||
@ -140,33 +139,52 @@ static u32 read_s32_timed(s32 fd, s32 *buf, u32 timeout_ms,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* set exceptfds as well to return when a child exited/closed the pipe. */
|
/* set exceptfds as well to return when a child exited/closed the pipe. */
|
||||||
int sret = select(fd + 1, &readfds, NULL, NULL, &timeout);
|
restart_select:
|
||||||
|
sret = select(fd + 1, &readfds, NULL, NULL, &timeout);
|
||||||
|
|
||||||
if (!sret) {
|
if (likely(sret > 0)) {
|
||||||
|
|
||||||
|
restart_read:
|
||||||
|
len_read = read(fd, (u8 *)buf, 4);
|
||||||
|
|
||||||
|
if (likely(len_read == 4)) { // for speed we put this first
|
||||||
|
|
||||||
|
#if defined(__linux__)
|
||||||
|
u32 exec_ms = MIN(
|
||||||
|
timeout_ms,
|
||||||
|
((u64)timeout_ms - (timeout.tv_sec * 1000 + timeout.tv_usec / 1000)));
|
||||||
|
#else
|
||||||
|
u32 exec_ms = MIN(timeout_ms, get_cur_time_us() - read_start);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ensure to report 1 ms has passed (0 is an error)
|
||||||
|
return exec_ms > 0 ? exec_ms : 1;
|
||||||
|
|
||||||
|
} else if (unlikely(len_read == -1 && errno == EINTR)) {
|
||||||
|
|
||||||
|
goto restart_read;
|
||||||
|
|
||||||
|
} else if (unlikely(len_read < 4)) {
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (unlikely(!sret)) {
|
||||||
|
|
||||||
*buf = -1;
|
*buf = -1;
|
||||||
return timeout_ms + 1;
|
return timeout_ms + 1;
|
||||||
|
|
||||||
} else if (sret < 0) {
|
} else if (unlikely(sret < 0)) {
|
||||||
|
|
||||||
|
if (likely(errno == EINTR)) goto restart_select;
|
||||||
|
|
||||||
*buf = -1;
|
*buf = -1;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t len_read = read(fd, ((u8 *)buf), len);
|
return 0; // not reached
|
||||||
if (len_read < len) { return 0; }
|
|
||||||
|
|
||||||
#if defined(__linux__)
|
|
||||||
u32 exec_ms =
|
|
||||||
MIN(timeout_ms,
|
|
||||||
((u64)timeout_ms - (timeout.tv_sec * 1000 + timeout.tv_usec / 1000)));
|
|
||||||
#else
|
|
||||||
u32 exec_ms = MIN(timeout_ms, get_cur_time_us() - read_start);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ensure to report 1 ms has passed (0 is an error)
|
|
||||||
return exec_ms > 0 ? exec_ms : 1;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -400,9 +418,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
|||||||
|
|
||||||
close(fsrv->out_dir_fd);
|
close(fsrv->out_dir_fd);
|
||||||
close(fsrv->dev_null_fd);
|
close(fsrv->dev_null_fd);
|
||||||
#ifndef HAVE_ARC4RANDOM
|
|
||||||
close(fsrv->dev_urandom_fd);
|
close(fsrv->dev_urandom_fd);
|
||||||
#endif
|
|
||||||
if (fsrv->plot_file != NULL) { fclose(fsrv->plot_file); }
|
if (fsrv->plot_file != NULL) { fclose(fsrv->plot_file); }
|
||||||
|
|
||||||
/* This should improve performance a bit, since it stops the linker from
|
/* This should improve performance a bit, since it stops the linker from
|
||||||
@ -445,6 +462,13 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
|||||||
|
|
||||||
/* PARENT PROCESS */
|
/* PARENT PROCESS */
|
||||||
|
|
||||||
|
char pid_buf[16];
|
||||||
|
sprintf(pid_buf, "%d", fsrv->fsrv_pid);
|
||||||
|
if (fsrv->cmplog_binary)
|
||||||
|
setenv("__AFL_TARGET_PID2", pid_buf, 1);
|
||||||
|
else
|
||||||
|
setenv("__AFL_TARGET_PID1", pid_buf, 1);
|
||||||
|
|
||||||
/* Close the unneeded endpoints. */
|
/* Close the unneeded endpoints. */
|
||||||
|
|
||||||
close(ctl_pipe[0]);
|
close(ctl_pipe[0]);
|
||||||
@ -545,7 +569,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);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -572,9 +596,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.");
|
||||||
@ -586,7 +610,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."); }
|
||||||
status = (FS_OPT_ENABLED | FS_OPT_AUTODICT);
|
|
||||||
|
if (fsrv->use_shmem_fuzz)
|
||||||
|
status = (FS_OPT_ENABLED | FS_OPT_AUTODICT | FS_OPT_SHDMEM_FUZZ);
|
||||||
|
else
|
||||||
|
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.");
|
||||||
@ -837,8 +866,23 @@ 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);
|
||||||
// printf("test case len: %u [0]:0x%02x\n", *fsrv->shmem_fuzz_len, buf[0]);
|
#ifdef _DEBUG
|
||||||
// fflush(stdout);
|
if (getenv("AFL_DEBUG")) {
|
||||||
|
|
||||||
|
fprintf(stderr, "FS crc: %016llx len: %u\n",
|
||||||
|
hash64(fsrv->shmem_fuzz, *fsrv->shmem_fuzz_len, 0xa5b35705),
|
||||||
|
*fsrv->shmem_fuzz_len);
|
||||||
|
fprintf(stderr, "SHM :");
|
||||||
|
for (int i = 0; i < *fsrv->shmem_fuzz_len; i++)
|
||||||
|
fprintf(stderr, "%02x", fsrv->shmem_fuzz[i]);
|
||||||
|
fprintf(stderr, "\nORIG:");
|
||||||
|
for (int i = 0; i < *fsrv->shmem_fuzz_len; i++)
|
||||||
|
fprintf(stderr, "%02x", buf[i]);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
@ -542,27 +542,35 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
|
|||||||
u8 hnb = '\0';
|
u8 hnb = '\0';
|
||||||
s32 fd;
|
s32 fd;
|
||||||
u8 keeping = 0, res;
|
u8 keeping = 0, res;
|
||||||
|
u64 cksum = 0;
|
||||||
|
|
||||||
u8 fn[PATH_MAX];
|
u8 fn[PATH_MAX];
|
||||||
|
|
||||||
/* Update path frequency. */
|
/* Update path frequency. */
|
||||||
u32 cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
|
||||||
|
|
||||||
struct queue_entry *q = afl->queue;
|
/* Generating a hash on every input is super expensive. Bad idea and should
|
||||||
while (q) {
|
only be used for special schedules */
|
||||||
|
if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) {
|
||||||
|
|
||||||
if (q->exec_cksum == cksum) {
|
cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||||
|
|
||||||
q->n_fuzz = q->n_fuzz + 1;
|
struct queue_entry *q = afl->queue;
|
||||||
break;
|
while (q) {
|
||||||
|
|
||||||
|
if (q->exec_cksum == cksum) {
|
||||||
|
|
||||||
|
++q->n_fuzz;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
q = q->next;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
q = q->next;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(fault == afl->crash_mode)) {
|
if (likely(fault == afl->crash_mode)) {
|
||||||
|
|
||||||
/* Keep only if there are new bits in the map, add to queue for
|
/* Keep only if there are new bits in the map, add to queue for
|
||||||
future fuzzing, etc. */
|
future fuzzing, etc. */
|
||||||
@ -595,7 +603,11 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
afl->queue_top->exec_cksum = cksum;
|
if (cksum)
|
||||||
|
afl->queue_top->exec_cksum = cksum;
|
||||||
|
else
|
||||||
|
afl->queue_top->exec_cksum =
|
||||||
|
hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||||
|
|
||||||
/* Try to calibrate inline; this also calls update_bitmap_score() when
|
/* Try to calibrate inline; this also calls update_bitmap_score() when
|
||||||
successful. */
|
successful. */
|
||||||
|
@ -37,6 +37,8 @@ void bind_to_free_cpu(afl_state_t *afl) {
|
|||||||
cpu_set_t c;
|
cpu_set_t c;
|
||||||
#elif defined(__NetBSD__)
|
#elif defined(__NetBSD__)
|
||||||
cpuset_t * c;
|
cpuset_t * c;
|
||||||
|
#elif defined(__sun)
|
||||||
|
psetid_t c;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
u8 cpu_used[4096] = {0};
|
u8 cpu_used[4096] = {0};
|
||||||
@ -181,6 +183,56 @@ void bind_to_free_cpu(afl_state_t *afl) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ck_free(procs);
|
ck_free(procs);
|
||||||
|
#elif defined(__sun)
|
||||||
|
kstat_named_t *n;
|
||||||
|
kstat_ctl_t * m;
|
||||||
|
kstat_t * k;
|
||||||
|
cpu_stat_t cs;
|
||||||
|
u32 ncpus;
|
||||||
|
|
||||||
|
m = kstat_open();
|
||||||
|
|
||||||
|
if (!m) FATAL("kstat_open failed");
|
||||||
|
|
||||||
|
k = kstat_lookup(m, "unix", 0, "system_misc");
|
||||||
|
|
||||||
|
if (!k) {
|
||||||
|
|
||||||
|
kstat_close(m);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kstat_read(m, k, NULL)) {
|
||||||
|
|
||||||
|
kstat_close(m);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
n = kstat_data_lookup(k, "ncpus");
|
||||||
|
ncpus = n->value.i32;
|
||||||
|
|
||||||
|
if (ncpus > sizeof(cpu_used)) ncpus = sizeof(cpu_used);
|
||||||
|
|
||||||
|
for (i = 0; i < ncpus; i++) {
|
||||||
|
|
||||||
|
k = kstat_lookup(m, "cpu_stat", i, NULL);
|
||||||
|
if (kstat_read(m, k, &cs)) {
|
||||||
|
|
||||||
|
kstat_close(m);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cs.cpu_sysinfo.cpu[CPU_IDLE] > 0) continue;
|
||||||
|
|
||||||
|
if (cs.cpu_sysinfo.cpu[CPU_USER] > 0 || cs.cpu_sysinfo.cpu[CPU_KERNEL] > 0)
|
||||||
|
cpu_used[i] = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
kstat_close(m);
|
||||||
#else
|
#else
|
||||||
#warning \
|
#warning \
|
||||||
"For this platform we do not have free CPU binding code yet. If possible, please supply a PR to https://github.com/AFLplusplus/AFLplusplus"
|
"For this platform we do not have free CPU binding code yet. If possible, please supply a PR to https://github.com/AFLplusplus/AFLplusplus"
|
||||||
@ -189,7 +241,7 @@ void bind_to_free_cpu(afl_state_t *afl) {
|
|||||||
size_t cpu_start = 0;
|
size_t cpu_start = 0;
|
||||||
|
|
||||||
try:
|
try:
|
||||||
#ifndef __ANDROID__
|
#if !defined(__ANDROID__)
|
||||||
for (i = cpu_start; i < afl->cpu_core_count; i++) {
|
for (i = cpu_start; i < afl->cpu_core_count; i++) {
|
||||||
|
|
||||||
if (!cpu_used[i]) { break; }
|
if (!cpu_used[i]) { break; }
|
||||||
@ -228,6 +280,9 @@ void bind_to_free_cpu(afl_state_t *afl) {
|
|||||||
c = cpuset_create();
|
c = cpuset_create();
|
||||||
if (c == NULL) PFATAL("cpuset_create failed");
|
if (c == NULL) PFATAL("cpuset_create failed");
|
||||||
cpuset_set(i, c);
|
cpuset_set(i, c);
|
||||||
|
#elif defined(__sun)
|
||||||
|
pset_create(&c);
|
||||||
|
if (pset_assign(c, i, NULL)) PFATAL("pset_assign failed");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
@ -271,6 +326,19 @@ if (pthread_setaffinity_np(pthread_self(), cpuset_size(c), c)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cpuset_destroy(c);
|
cpuset_destroy(c);
|
||||||
|
#elif defined(__sun)
|
||||||
|
if (pset_bind(c, P_PID, getpid(), NULL)) {
|
||||||
|
|
||||||
|
if (cpu_start == afl->cpu_core_count)
|
||||||
|
PFATAL("pset_bind failed for cpu %d, exit", i);
|
||||||
|
WARNF("pthread_setaffinity failed to CPU %d, trying next CPU", i);
|
||||||
|
cpu_start++;
|
||||||
|
goto try
|
||||||
|
;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pset_destroy(c);
|
||||||
#else
|
#else
|
||||||
// this will need something for other platforms
|
// this will need something for other platforms
|
||||||
// TODO: Solaris/Illumos has processor_bind ... might worth a try
|
// TODO: Solaris/Illumos has processor_bind ... might worth a try
|
||||||
@ -1473,10 +1541,8 @@ void setup_dirs_fds(afl_state_t *afl) {
|
|||||||
afl->fsrv.dev_null_fd = open("/dev/null", O_RDWR);
|
afl->fsrv.dev_null_fd = open("/dev/null", O_RDWR);
|
||||||
if (afl->fsrv.dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); }
|
if (afl->fsrv.dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); }
|
||||||
|
|
||||||
#ifndef HAVE_ARC4RANDOM
|
|
||||||
afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY);
|
afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY);
|
||||||
if (afl->fsrv.dev_urandom_fd < 0) { PFATAL("Unable to open /dev/urandom"); }
|
if (afl->fsrv.dev_urandom_fd < 0) { PFATAL("Unable to open /dev/urandom"); }
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Gnuplot output file. */
|
/* Gnuplot output file. */
|
||||||
|
|
||||||
@ -2062,14 +2128,17 @@ void check_binary(afl_state_t *afl, u8 *fname) {
|
|||||||
|
|
||||||
/* Check for blatant user errors. */
|
/* Check for blatant user errors. */
|
||||||
|
|
||||||
if ((!strncmp(afl->fsrv.target_path, "/tmp/", 5) &&
|
/* disabled. not a real-worl scenario where this is a problem.
|
||||||
!strchr(afl->fsrv.target_path + 5, '/')) ||
|
if ((!strncmp(afl->fsrv.target_path, "/tmp/", 5) &&
|
||||||
(!strncmp(afl->fsrv.target_path, "/var/tmp/", 9) &&
|
!strchr(afl->fsrv.target_path + 5, '/')) ||
|
||||||
!strchr(afl->fsrv.target_path + 9, '/'))) {
|
(!strncmp(afl->fsrv.target_path, "/var/tmp/", 9) &&
|
||||||
|
!strchr(afl->fsrv.target_path + 9, '/'))) {
|
||||||
|
|
||||||
FATAL("Please don't keep binaries in /tmp or /var/tmp");
|
FATAL("Please don't keep binaries in /tmp or /var/tmp");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
fd = open(afl->fsrv.target_path, O_RDONLY);
|
fd = open(afl->fsrv.target_path, O_RDONLY);
|
||||||
|
|
||||||
|
@ -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/...).");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,7 +272,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
|
|||||||
sprintf(afl->stage_name_buf, "ptrim %s",
|
sprintf(afl->stage_name_buf, "ptrim %s",
|
||||||
u_stringify_int(val_buf, trim_exec));
|
u_stringify_int(val_buf, trim_exec));
|
||||||
|
|
||||||
u32 cksum;
|
u64 cksum;
|
||||||
|
|
||||||
size_t retlen = mutator->afl_custom_trim(mutator->data, &retbuf);
|
size_t retlen = mutator->afl_custom_trim(mutator->data, &retbuf);
|
||||||
|
|
||||||
@ -295,7 +295,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
|
|||||||
|
|
||||||
if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; }
|
if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; }
|
||||||
|
|
||||||
cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||||
|
|
||||||
if (cksum == q->exec_cksum) {
|
if (cksum == q->exec_cksum) {
|
||||||
|
|
||||||
|
@ -29,10 +29,14 @@
|
|||||||
|
|
||||||
static int select_algorithm(afl_state_t *afl) {
|
static int select_algorithm(afl_state_t *afl) {
|
||||||
|
|
||||||
int i_puppet, j_puppet;
|
int i_puppet, j_puppet = 0, operator_number = operator_num;
|
||||||
|
|
||||||
|
if (!afl->extras_cnt && !afl->a_extras_cnt) operator_number -= 2;
|
||||||
|
|
||||||
|
double range_sele =
|
||||||
|
(double)afl->probability_now[afl->swarm_now][operator_number - 1];
|
||||||
|
double sele = ((double)(rand_below(afl, 10000) * 0.0001 * range_sele));
|
||||||
|
|
||||||
double sele = ((double)(rand_below(afl, 10000)) * 0.0001);
|
|
||||||
j_puppet = 0;
|
|
||||||
for (i_puppet = 0; i_puppet < operator_num; ++i_puppet) {
|
for (i_puppet = 0; i_puppet < operator_num; ++i_puppet) {
|
||||||
|
|
||||||
if (unlikely(i_puppet == 0)) {
|
if (unlikely(i_puppet == 0)) {
|
||||||
@ -52,8 +56,10 @@ static int select_algorithm(afl_state_t *afl) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (j_puppet == 1 &&
|
if ((j_puppet == 1 &&
|
||||||
sele < afl->probability_now[afl->swarm_now][i_puppet - 1]) {
|
sele < afl->probability_now[afl->swarm_now][i_puppet - 1]) ||
|
||||||
|
(i_puppet + 1 < operator_num &&
|
||||||
|
sele > afl->probability_now[afl->swarm_now][i_puppet + 1])) {
|
||||||
|
|
||||||
FATAL("error select_algorithm");
|
FATAL("error select_algorithm");
|
||||||
|
|
||||||
@ -364,8 +370,8 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
|||||||
|
|
||||||
s32 len, fd, temp_len, i, j;
|
s32 len, fd, temp_len, i, j;
|
||||||
u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0;
|
u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0;
|
||||||
u64 havoc_queued = 0, orig_hit_cnt, new_hit_cnt;
|
u64 havoc_queued = 0, orig_hit_cnt, new_hit_cnt = 0, prev_cksum;
|
||||||
u32 splice_cycle = 0, perf_score = 100, orig_perf, prev_cksum, eff_cnt = 1;
|
u32 splice_cycle = 0, perf_score = 100, orig_perf, eff_cnt = 1;
|
||||||
|
|
||||||
u8 ret_val = 1, doing_det = 0;
|
u8 ret_val = 1, doing_det = 0;
|
||||||
|
|
||||||
@ -488,6 +494,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);
|
||||||
|
|
||||||
@ -548,8 +556,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,
|
||||||
@ -566,12 +572,11 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
|||||||
if it has gone through deterministic testing in earlier, resumed runs
|
if it has gone through deterministic testing in earlier, resumed runs
|
||||||
(passed_det). */
|
(passed_det). */
|
||||||
|
|
||||||
if (afl->skip_deterministic ||
|
if (likely(afl->queue_cur->passed_det) || likely(afl->skip_deterministic) ||
|
||||||
((!afl->queue_cur->passed_det) &&
|
likely(perf_score <
|
||||||
perf_score < (afl->queue_cur->depth * 30 <= afl->havoc_max_mult * 100
|
(afl->queue_cur->depth * 30 <= afl->havoc_max_mult * 100
|
||||||
? afl->queue_cur->depth * 30
|
? afl->queue_cur->depth * 30
|
||||||
: afl->havoc_max_mult * 100)) ||
|
: afl->havoc_max_mult * 100))) {
|
||||||
afl->queue_cur->passed_det) {
|
|
||||||
|
|
||||||
goto custom_mutator_stage;
|
goto custom_mutator_stage;
|
||||||
|
|
||||||
@ -653,7 +658,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
|||||||
|
|
||||||
if (!afl->non_instrumented_mode && (afl->stage_cur & 7) == 7) {
|
if (!afl->non_instrumented_mode && (afl->stage_cur & 7) == 7) {
|
||||||
|
|
||||||
u32 cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
u64 cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||||
|
|
||||||
if (afl->stage_cur == afl->stage_max - 1 && cksum == prev_cksum) {
|
if (afl->stage_cur == afl->stage_max - 1 && cksum == prev_cksum) {
|
||||||
|
|
||||||
@ -821,14 +826,14 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
|||||||
|
|
||||||
if (!eff_map[EFF_APOS(afl->stage_cur)]) {
|
if (!eff_map[EFF_APOS(afl->stage_cur)]) {
|
||||||
|
|
||||||
u32 cksum;
|
u64 cksum;
|
||||||
|
|
||||||
/* If in non-instrumented mode or if the file is very short, just flag
|
/* If in non-instrumented mode or if the file is very short, just flag
|
||||||
everything without wasting time on checksums. */
|
everything without wasting time on checksums. */
|
||||||
|
|
||||||
if (!afl->non_instrumented_mode && len >= EFF_MIN_LEN) {
|
if (!afl->non_instrumented_mode && len >= EFF_MIN_LEN) {
|
||||||
|
|
||||||
cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -1680,6 +1685,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);
|
||||||
@ -1704,7 +1710,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;
|
||||||
@ -2230,7 +2236,7 @@ havoc_stage:
|
|||||||
case 16: {
|
case 16: {
|
||||||
|
|
||||||
u32 use_extra, extra_len, insert_at = rand_below(afl, temp_len + 1);
|
u32 use_extra, extra_len, insert_at = rand_below(afl, temp_len + 1);
|
||||||
u8 *new_buf;
|
u8 *ptr;
|
||||||
|
|
||||||
/* Insert an extra. Do the same dice-rolling stuff as for the
|
/* Insert an extra. Do the same dice-rolling stuff as for the
|
||||||
previous case. */
|
previous case. */
|
||||||
@ -2239,44 +2245,27 @@ havoc_stage:
|
|||||||
|
|
||||||
use_extra = rand_below(afl, afl->a_extras_cnt);
|
use_extra = rand_below(afl, afl->a_extras_cnt);
|
||||||
extra_len = afl->a_extras[use_extra].len;
|
extra_len = afl->a_extras[use_extra].len;
|
||||||
|
ptr = afl->a_extras[use_extra].data;
|
||||||
if (temp_len + extra_len >= MAX_FILE) { break; }
|
|
||||||
|
|
||||||
new_buf =
|
|
||||||
ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + extra_len);
|
|
||||||
|
|
||||||
/* Head */
|
|
||||||
memcpy(new_buf, out_buf, insert_at);
|
|
||||||
|
|
||||||
/* Inserted part */
|
|
||||||
memcpy(new_buf + insert_at, afl->a_extras[use_extra].data,
|
|
||||||
extra_len);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
use_extra = rand_below(afl, afl->extras_cnt);
|
use_extra = rand_below(afl, afl->extras_cnt);
|
||||||
extra_len = afl->extras[use_extra].len;
|
extra_len = afl->extras[use_extra].len;
|
||||||
|
ptr = afl->extras[use_extra].data;
|
||||||
if (temp_len + extra_len >= MAX_FILE) { break; }
|
|
||||||
|
|
||||||
new_buf =
|
|
||||||
ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + extra_len);
|
|
||||||
|
|
||||||
/* Head */
|
|
||||||
memcpy(new_buf, out_buf, insert_at);
|
|
||||||
|
|
||||||
/* Inserted part */
|
|
||||||
memcpy(new_buf + insert_at, afl->extras[use_extra].data, extra_len);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tail */
|
if (temp_len + extra_len >= MAX_FILE) { break; }
|
||||||
memcpy(new_buf + insert_at + extra_len, out_buf + insert_at,
|
|
||||||
temp_len - insert_at);
|
out_buf = ck_maybe_grow(BUF_PARAMS(out), temp_len + extra_len);
|
||||||
|
|
||||||
|
/* Tail */
|
||||||
|
memmove(out_buf + insert_at + extra_len, out_buf + insert_at,
|
||||||
|
temp_len - insert_at);
|
||||||
|
|
||||||
|
/* Inserted part */
|
||||||
|
memcpy(out_buf + insert_at, ptr, extra_len);
|
||||||
|
|
||||||
swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch));
|
|
||||||
out_buf = new_buf;
|
|
||||||
new_buf = NULL;
|
|
||||||
temp_len += extra_len;
|
temp_len += extra_len;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -2438,63 +2427,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:
|
||||||
@ -2539,8 +2471,8 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
|
|||||||
|
|
||||||
s32 len, fd, temp_len, i, j;
|
s32 len, fd, temp_len, i, j;
|
||||||
u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0;
|
u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0;
|
||||||
u64 havoc_queued, orig_hit_cnt, new_hit_cnt, cur_ms_lv;
|
u64 havoc_queued = 0, orig_hit_cnt, new_hit_cnt = 0, cur_ms_lv, prev_cksum;
|
||||||
u32 splice_cycle = 0, perf_score = 100, orig_perf, prev_cksum, eff_cnt = 1;
|
u32 splice_cycle = 0, perf_score = 100, orig_perf, eff_cnt = 1;
|
||||||
|
|
||||||
u8 ret_val = 1, doing_det = 0;
|
u8 ret_val = 1, doing_det = 0;
|
||||||
|
|
||||||
@ -2637,6 +2569,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);
|
||||||
|
|
||||||
@ -2806,7 +2740,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
|
|||||||
|
|
||||||
if (!afl->non_instrumented_mode && (afl->stage_cur & 7) == 7) {
|
if (!afl->non_instrumented_mode && (afl->stage_cur & 7) == 7) {
|
||||||
|
|
||||||
u32 cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
u64 cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||||
|
|
||||||
if (afl->stage_cur == afl->stage_max - 1 && cksum == prev_cksum) {
|
if (afl->stage_cur == afl->stage_max - 1 && cksum == prev_cksum) {
|
||||||
|
|
||||||
@ -2974,14 +2908,14 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
|
|||||||
|
|
||||||
if (!eff_map[EFF_APOS(afl->stage_cur)]) {
|
if (!eff_map[EFF_APOS(afl->stage_cur)]) {
|
||||||
|
|
||||||
u32 cksum;
|
u64 cksum;
|
||||||
|
|
||||||
/* If in non-instrumented mode or if the file is very short, just flag
|
/* If in non-instrumented mode or if the file is very short, just flag
|
||||||
everything without wasting time on checksums. */
|
everything without wasting time on checksums. */
|
||||||
|
|
||||||
if (!afl->non_instrumented_mode && len >= EFF_MIN_LEN) {
|
if (!afl->non_instrumented_mode && len >= EFF_MIN_LEN) {
|
||||||
|
|
||||||
cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -4208,6 +4142,94 @@ pacemaker_fuzzing:
|
|||||||
|
|
||||||
} /* case 15 */
|
} /* case 15 */
|
||||||
|
|
||||||
|
/* Values 16 and 17 can be selected only if there are any extras
|
||||||
|
present in the dictionaries. */
|
||||||
|
|
||||||
|
case 16: {
|
||||||
|
|
||||||
|
/* Overwrite bytes with an extra. */
|
||||||
|
|
||||||
|
if (!afl->extras_cnt ||
|
||||||
|
(afl->a_extras_cnt && rand_below(afl, 2))) {
|
||||||
|
|
||||||
|
/* No user-specified extras or odds in our favor. Let's use an
|
||||||
|
auto-detected one. */
|
||||||
|
|
||||||
|
u32 use_extra = rand_below(afl, afl->a_extras_cnt);
|
||||||
|
u32 extra_len = afl->a_extras[use_extra].len;
|
||||||
|
|
||||||
|
if (extra_len > temp_len) break;
|
||||||
|
|
||||||
|
u32 insert_at = rand_below(afl, temp_len - extra_len + 1);
|
||||||
|
memcpy(out_buf + insert_at, afl->a_extras[use_extra].data,
|
||||||
|
extra_len);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* No auto extras or odds in our favor. Use the dictionary. */
|
||||||
|
|
||||||
|
u32 use_extra = rand_below(afl, afl->extras_cnt);
|
||||||
|
u32 extra_len = afl->extras[use_extra].len;
|
||||||
|
|
||||||
|
if (extra_len > temp_len) break;
|
||||||
|
|
||||||
|
u32 insert_at = rand_below(afl, temp_len - extra_len + 1);
|
||||||
|
memcpy(out_buf + insert_at, afl->extras[use_extra].data,
|
||||||
|
extra_len);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
afl->stage_cycles_puppet_v2[afl->swarm_now]
|
||||||
|
[STAGE_OverWriteExtra] += 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Insert an extra. */
|
||||||
|
|
||||||
|
case 17: {
|
||||||
|
|
||||||
|
u32 use_extra, extra_len,
|
||||||
|
insert_at = rand_below(afl, temp_len + 1);
|
||||||
|
u8 *ptr;
|
||||||
|
|
||||||
|
/* Insert an extra. Do the same dice-rolling stuff as for the
|
||||||
|
previous case. */
|
||||||
|
|
||||||
|
if (!afl->extras_cnt ||
|
||||||
|
(afl->a_extras_cnt && rand_below(afl, 2))) {
|
||||||
|
|
||||||
|
use_extra = rand_below(afl, afl->a_extras_cnt);
|
||||||
|
extra_len = afl->a_extras[use_extra].len;
|
||||||
|
ptr = afl->a_extras[use_extra].data;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
use_extra = rand_below(afl, afl->extras_cnt);
|
||||||
|
extra_len = afl->extras[use_extra].len;
|
||||||
|
ptr = afl->extras[use_extra].data;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (temp_len + extra_len >= MAX_FILE) break;
|
||||||
|
|
||||||
|
out_buf = ck_maybe_grow(BUF_PARAMS(out), temp_len + extra_len);
|
||||||
|
|
||||||
|
/* Tail */
|
||||||
|
memmove(out_buf + insert_at + extra_len, out_buf + insert_at,
|
||||||
|
temp_len - insert_at);
|
||||||
|
|
||||||
|
/* Inserted part */
|
||||||
|
memcpy(out_buf + insert_at, ptr, extra_len);
|
||||||
|
|
||||||
|
temp_len += extra_len;
|
||||||
|
afl->stage_cycles_puppet_v2[afl->swarm_now][STAGE_InsertExtra] +=
|
||||||
|
1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} /* switch select_algorithm() */
|
} /* switch select_algorithm() */
|
||||||
|
|
||||||
} /* for i=0; i < use_stacking */
|
} /* for i=0; i < use_stacking */
|
||||||
|
@ -194,10 +194,14 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
|
|
||||||
u32 i;
|
u32 i;
|
||||||
u64 fav_factor;
|
u64 fav_factor;
|
||||||
u64 fuzz_p2 = next_pow2(q->n_fuzz);
|
u64 fuzz_p2;
|
||||||
|
|
||||||
if (afl->schedule == MMOPT || afl->schedule == RARE ||
|
if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE))
|
||||||
unlikely(afl->fixed_seed)) {
|
fuzz_p2 = next_pow2(q->n_fuzz);
|
||||||
|
else
|
||||||
|
fuzz_p2 = q->fuzz_level;
|
||||||
|
|
||||||
|
if (unlikely(afl->schedule >= RARE) || unlikely(afl->fixed_seed)) {
|
||||||
|
|
||||||
fav_factor = q->len << 2;
|
fav_factor = q->len << 2;
|
||||||
|
|
||||||
@ -217,10 +221,13 @@ 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 = next_pow2(afl->top_rated[i]->n_fuzz);
|
u64 top_rated_fuzz_p2;
|
||||||
|
if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE))
|
||||||
|
top_rated_fuzz_p2 = next_pow2(afl->top_rated[i]->n_fuzz);
|
||||||
|
else
|
||||||
|
top_rated_fuzz_p2 = afl->top_rated[i]->fuzz_level;
|
||||||
|
|
||||||
if (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;
|
||||||
|
|
||||||
@ -241,8 +248,7 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (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; }
|
||||||
|
|
||||||
@ -387,8 +393,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) {
|
||||||
|
|
||||||
@ -500,6 +505,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;
|
||||||
@ -593,9 +601,12 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (factor > MAX_FACTOR) { factor = MAX_FACTOR; }
|
if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) {
|
||||||
|
|
||||||
perf_score *= factor / POWER_BETA;
|
if (factor > MAX_FACTOR) { factor = MAX_FACTOR; }
|
||||||
|
perf_score *= factor / POWER_BETA;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// MOpt mode
|
// MOpt mode
|
||||||
if (afl->limit_time_sig != 0 && afl->max_depth - q->depth < 3) {
|
if (afl->limit_time_sig != 0 && afl->max_depth - q->depth < 3) {
|
||||||
|
@ -89,11 +89,11 @@ static struct range *pop_biggest_range(struct range **ranges) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8 get_exec_checksum(afl_state_t *afl, u8 *buf, u32 len, u32 *cksum) {
|
static u8 get_exec_checksum(afl_state_t *afl, u8 *buf, u32 len, u64 *cksum) {
|
||||||
|
|
||||||
if (unlikely(common_fuzz_stuff(afl, buf, len))) { return 1; }
|
if (unlikely(common_fuzz_stuff(afl, buf, len))) { return 1; }
|
||||||
|
|
||||||
*cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
*cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -109,7 +109,7 @@ static void rand_replace(afl_state_t *afl, u8 *buf, u32 len) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u32 exec_cksum) {
|
static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u64 exec_cksum) {
|
||||||
|
|
||||||
struct range *ranges = add_range(NULL, 0, len);
|
struct range *ranges = add_range(NULL, 0, len);
|
||||||
u8 * backup = ck_alloc_nozero(len);
|
u8 * backup = ck_alloc_nozero(len);
|
||||||
@ -137,7 +137,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u32 exec_cksum) {
|
|||||||
memcpy(backup, buf + rng->start, s);
|
memcpy(backup, buf + rng->start, s);
|
||||||
rand_replace(afl, buf + rng->start, s);
|
rand_replace(afl, buf + rng->start, s);
|
||||||
|
|
||||||
u32 cksum;
|
u64 cksum;
|
||||||
u64 start_us = get_cur_time_us();
|
u64 start_us = get_cur_time_us();
|
||||||
if (unlikely(get_exec_checksum(afl, buf, len, &cksum))) {
|
if (unlikely(get_exec_checksum(afl, buf, len, &cksum))) {
|
||||||
|
|
||||||
@ -180,7 +180,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u32 exec_cksum) {
|
|||||||
while (ranges) {
|
while (ranges) {
|
||||||
|
|
||||||
rng = ranges;
|
rng = ranges;
|
||||||
ranges = ranges->next;
|
ranges = rng->next;
|
||||||
ck_free(rng);
|
ck_free(rng);
|
||||||
rng = NULL;
|
rng = NULL;
|
||||||
|
|
||||||
@ -224,7 +224,7 @@ checksum_fail:
|
|||||||
while (ranges) {
|
while (ranges) {
|
||||||
|
|
||||||
rng = ranges;
|
rng = ranges;
|
||||||
ranges = ranges->next;
|
ranges = rng->next;
|
||||||
ck_free(rng);
|
ck_free(rng);
|
||||||
rng = NULL;
|
rng = NULL;
|
||||||
|
|
||||||
@ -695,7 +695,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) {
|
|||||||
|
|
||||||
// afl->queue_cur->exec_cksum
|
// afl->queue_cur->exec_cksum
|
||||||
u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len,
|
u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len,
|
||||||
u32 exec_cksum) {
|
u64 exec_cksum) {
|
||||||
|
|
||||||
u8 r = 1;
|
u8 r = 1;
|
||||||
if (afl->orig_cmp_map == NULL) {
|
if (afl->orig_cmp_map == NULL) {
|
||||||
|
@ -142,7 +142,41 @@ static void write_with_gap(afl_state_t *afl, void *mem, u32 len, u32 skip_at,
|
|||||||
s32 fd = afl->fsrv.out_fd;
|
s32 fd = afl->fsrv.out_fd;
|
||||||
u32 tail_len = len - skip_at - skip_len;
|
u32 tail_len = len - skip_at - skip_len;
|
||||||
|
|
||||||
if (afl->fsrv.out_file) {
|
if (afl->fsrv.shmem_fuzz) {
|
||||||
|
|
||||||
|
if (skip_at) { memcpy(afl->fsrv.shmem_fuzz, mem, skip_at); }
|
||||||
|
|
||||||
|
if (tail_len) {
|
||||||
|
|
||||||
|
memcpy(afl->fsrv.shmem_fuzz + skip_at, (u8 *)mem + skip_at + skip_len,
|
||||||
|
tail_len);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
*afl->fsrv.shmem_fuzz_len = len - skip_len;
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
if (afl->debug) {
|
||||||
|
|
||||||
|
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 :");
|
||||||
|
for (int i = 0; i < *afl->fsrv.shmem_fuzz_len; i++)
|
||||||
|
fprintf(stderr, "%02x", afl->fsrv.shmem_fuzz[i]);
|
||||||
|
fprintf(stderr, "\nORIG:");
|
||||||
|
for (int i = 0; i < *afl->fsrv.shmem_fuzz_len; i++)
|
||||||
|
fprintf(stderr, "%02x", (u8)((u8 *)mem)[i]);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
} else if (afl->fsrv.out_file) {
|
||||||
|
|
||||||
if (afl->no_unlink) {
|
if (afl->no_unlink) {
|
||||||
|
|
||||||
@ -234,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;
|
||||||
@ -256,13 +291,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
|
|||||||
|
|
||||||
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
|
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
|
||||||
|
|
||||||
u32 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);
|
||||||
|
|
||||||
@ -281,7 +310,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||||
if (q->exec_cksum != cksum) {
|
if (q->exec_cksum != cksum) {
|
||||||
|
|
||||||
hnb = has_new_bits(afl, afl->virgin_bits);
|
hnb = has_new_bits(afl, afl->virgin_bits);
|
||||||
@ -385,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); }
|
||||||
@ -399,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;
|
||||||
|
|
||||||
@ -438,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);
|
||||||
@ -462,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);
|
||||||
@ -505,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--;
|
||||||
@ -646,7 +680,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
|||||||
while (remove_pos < q->len) {
|
while (remove_pos < q->len) {
|
||||||
|
|
||||||
u32 trim_avail = MIN(remove_len, q->len - remove_pos);
|
u32 trim_avail = MIN(remove_len, q->len - remove_pos);
|
||||||
u32 cksum;
|
u64 cksum;
|
||||||
|
|
||||||
write_with_gap(afl, in_buf, q->len, remove_pos, trim_avail);
|
write_with_gap(afl, in_buf, q->len, remove_pos, trim_avail);
|
||||||
|
|
||||||
@ -658,7 +692,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
|||||||
/* Note that we don't keep track of crashes or hangs here; maybe TODO?
|
/* Note that we don't keep track of crashes or hangs here; maybe TODO?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||||
|
|
||||||
/* If the deletion had no impact on the trace, make it permanent. This
|
/* If the deletion had no impact on the trace, make it permanent. This
|
||||||
isn't perfect for variable-path inputs, but we're just making a
|
isn't perfect for variable-path inputs, but we're just making a
|
||||||
|
@ -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", "fast", "coe", "lin", "quad", "exploit", "mmopt", "rare"};
|
"rare", "mmopt", "seek"};
|
||||||
|
|
||||||
/* Initialize MOpt "globals" for this afl state */
|
/* Initialize MOpt "globals" for this afl state */
|
||||||
|
|
||||||
@ -124,9 +124,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) {
|
|||||||
|
|
||||||
afl->stats_update_freq = 1;
|
afl->stats_update_freq = 1;
|
||||||
|
|
||||||
#ifndef HAVE_ARC4RANDOM
|
|
||||||
afl->fsrv.dev_urandom_fd = -1;
|
afl->fsrv.dev_urandom_fd = -1;
|
||||||
#endif
|
|
||||||
afl->fsrv.dev_null_fd = -1;
|
afl->fsrv.dev_null_fd = -1;
|
||||||
|
|
||||||
afl->fsrv.child_pid = -1;
|
afl->fsrv.child_pid = -1;
|
||||||
|
@ -31,7 +31,9 @@
|
|||||||
void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
|
void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
|
||||||
double eps) {
|
double eps) {
|
||||||
|
|
||||||
|
#ifndef __HAIKU__
|
||||||
struct rusage rus;
|
struct rusage rus;
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned long long int cur_time = get_cur_time();
|
unsigned long long int cur_time = get_cur_time();
|
||||||
u8 fn[PATH_MAX];
|
u8 fn[PATH_MAX];
|
||||||
@ -65,7 +67,9 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __HAIKU__
|
||||||
if (getrusage(RUSAGE_CHILDREN, &rus)) { rus.ru_maxrss = 0; }
|
if (getrusage(RUSAGE_CHILDREN, &rus)) { rus.ru_maxrss = 0; }
|
||||||
|
#endif
|
||||||
|
|
||||||
fprintf(
|
fprintf(
|
||||||
f,
|
f,
|
||||||
@ -119,12 +123,21 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
|
|||||||
afl->last_path_time / 1000, afl->last_crash_time / 1000,
|
afl->last_path_time / 1000, afl->last_crash_time / 1000,
|
||||||
afl->last_hang_time / 1000, afl->fsrv.total_execs - afl->last_crash_execs,
|
afl->last_hang_time / 1000, afl->fsrv.total_execs - afl->last_crash_execs,
|
||||||
afl->fsrv.exec_tmout, afl->slowest_exec_ms,
|
afl->fsrv.exec_tmout, afl->slowest_exec_ms,
|
||||||
#ifdef __APPLE__
|
#ifndef __HAIKU__
|
||||||
|
#ifdef __APPLE__
|
||||||
(unsigned long int)(rus.ru_maxrss >> 20),
|
(unsigned long int)(rus.ru_maxrss >> 20),
|
||||||
#else
|
#else
|
||||||
(unsigned long int)(rus.ru_maxrss >> 10),
|
(unsigned long int)(rus.ru_maxrss >> 10),
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
-1UL,
|
||||||
#endif
|
#endif
|
||||||
afl->cpu_aff, t_bytes, afl->var_byte_count, afl->use_banner,
|
#ifdef HAVE_AFFINITY
|
||||||
|
afl->cpu_aff,
|
||||||
|
#else
|
||||||
|
-1,
|
||||||
|
#endif
|
||||||
|
t_bytes, afl->var_byte_count, afl->use_banner,
|
||||||
afl->unicorn_mode ? "unicorn" : "", afl->fsrv.qemu_mode ? "qemu " : "",
|
afl->unicorn_mode ? "unicorn" : "", afl->fsrv.qemu_mode ? "qemu " : "",
|
||||||
afl->non_instrumented_mode ? " non_instrumented " : "",
|
afl->non_instrumented_mode ? " non_instrumented " : "",
|
||||||
afl->no_forkserver ? "no_fsrv " : "", afl->crash_mode ? "crash " : "",
|
afl->no_forkserver ? "no_fsrv " : "", afl->crash_mode ? "crash " : "",
|
||||||
@ -181,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;
|
||||||
|
|
||||||
@ -732,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) {
|
||||||
|
|
||||||
@ -821,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. */
|
||||||
|
|
||||||
|
206
src/afl-fuzz.c
206
src/afl-fuzz.c
@ -26,66 +26,53 @@
|
|||||||
#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;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static u8 *get_libradamsa_path(u8 *own_loc) {
|
static void at_exit() {
|
||||||
|
|
||||||
u8 *tmp, *cp, *rsl, *own_copy;
|
int i;
|
||||||
|
char *list[4] = {SHM_ENV_VAR, SHM_FUZZ_ENV_VAR, CMPLOG_SHM_ENV_VAR, NULL};
|
||||||
|
char *ptr = getenv("__AFL_TARGET_PID1");
|
||||||
|
|
||||||
tmp = getenv("AFL_PATH");
|
if (ptr && *ptr && (i = atoi(ptr)) > 0) kill(i, SIGKILL);
|
||||||
|
|
||||||
if (tmp) {
|
ptr = getenv("__AFL_TARGET_PID2");
|
||||||
|
|
||||||
cp = alloc_printf("%s/libradamsa.so", tmp);
|
if (ptr && *ptr && (i = atoi(ptr)) > 0) kill(i, SIGKILL);
|
||||||
|
|
||||||
if (access(cp, X_OK)) { FATAL("Unable to find '%s'", cp); }
|
i = 0;
|
||||||
|
while (list[i] != NULL) {
|
||||||
|
|
||||||
return cp;
|
ptr = getenv(list[i]);
|
||||||
|
|
||||||
|
if (ptr && *ptr) {
|
||||||
|
|
||||||
|
#ifdef USEMMAP
|
||||||
|
|
||||||
|
shm_unlink(ptr);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
shmctl(atoi(ptr), IPC_RMID, NULL);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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. */
|
||||||
@ -100,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"
|
||||||
@ -114,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 = "
|
||||||
@ -131,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"
|
||||||
@ -144,14 +130,16 @@ 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) {
|
||||||
@ -231,7 +219,7 @@ static int stricmp(char const *a, char const *b) {
|
|||||||
for (;; ++a, ++b) {
|
for (;; ++a, ++b) {
|
||||||
|
|
||||||
int d;
|
int d;
|
||||||
d = tolower(*a) - tolower(*b);
|
d = tolower((int)*a) - tolower((int)*b);
|
||||||
if (d != 0 || !*a) { return d; }
|
if (d != 0 || !*a) { return d; }
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -274,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) {
|
||||||
@ -296,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;
|
||||||
|
|
||||||
@ -332,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")) {
|
||||||
@ -369,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;
|
||||||
|
|
||||||
@ -398,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);
|
||||||
@ -503,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;
|
||||||
@ -767,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;
|
||||||
|
|
||||||
@ -808,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!");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -819,50 +809,6 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
|
||||||
@ -936,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;
|
||||||
@ -1071,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);
|
||||||
|
|
||||||
@ -1082,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);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1327,7 +1278,15 @@ 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 (!(sync_interval_cnt++ % SYNC_INTERVAL)) { sync_fuzzers(afl); }
|
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); }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1396,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);
|
||||||
|
|
||||||
|
@ -335,7 +335,7 @@ static void edit_params(u32 argc, char **argv) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USEMMAP
|
#if defined(USEMMAP) && !defined(__HAIKU__)
|
||||||
cc_params[cc_par_cnt++] = "-lrt";
|
cc_params[cc_par_cnt++] = "-lrt";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
|
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
|
||||||
defined(__APPLE__) || defined(__DragonFly__)
|
defined(__APPLE__) || defined(__DragonFly__) || defined(__sun)
|
||||||
#define HAVE_AFFINITY 1
|
#define HAVE_AFFINITY 1
|
||||||
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
@ -70,6 +70,8 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <mach/thread_act.h>
|
#include <mach/thread_act.h>
|
||||||
#include <mach/thread_policy.h>
|
#include <mach/thread_policy.h>
|
||||||
|
#elif defined(__sun)
|
||||||
|
#include <sys/pset.h>
|
||||||
#endif
|
#endif
|
||||||
#endif /* __linux__ || __FreeBSD__ || __NetBSD__ || __APPLE__ */
|
#endif /* __linux__ || __FreeBSD__ || __NetBSD__ || __APPLE__ */
|
||||||
|
|
||||||
@ -181,6 +183,12 @@ int main(int argc, char **argv) {
|
|||||||
if (thread_policy_set(native_thread, THREAD_AFFINITY_POLICY,
|
if (thread_policy_set(native_thread, THREAD_AFFINITY_POLICY,
|
||||||
(thread_policy_t)&c, 1) != KERN_SUCCESS)
|
(thread_policy_t)&c, 1) != KERN_SUCCESS)
|
||||||
PFATAL("thread_policy_set failed");
|
PFATAL("thread_policy_set failed");
|
||||||
|
#elif defined(__sun)
|
||||||
|
psetid_t c;
|
||||||
|
|
||||||
|
if (pset_create(&c)) PFATAL("pset_create failed");
|
||||||
|
|
||||||
|
if (pset_assign(c, i, NULL)) PFATAL("pset_assign failed");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
||||||
@ -195,6 +203,12 @@ int main(int argc, char **argv) {
|
|||||||
cpuset_destroy(c);
|
cpuset_destroy(c);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__sun)
|
||||||
|
if (pset_bind(c, P_PID, getpid(), NULL)) PFATAL("pset_bind failed");
|
||||||
|
|
||||||
|
pset_destroy(c);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
if (sched_setaffinity(0, sizeof(c), &c)) {
|
if (sched_setaffinity(0, sizeof(c), &c)) {
|
||||||
|
|
||||||
|
167
src/afl-performance.c
Normal file
167
src/afl-performance.c
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
/*
|
||||||
|
Written in 2019 by David Blackman and Sebastiano Vigna (vigna@acm.org)
|
||||||
|
|
||||||
|
To the extent possible under law, the author has dedicated all copyright
|
||||||
|
and related and neighboring rights to this software to the public domain
|
||||||
|
worldwide. This software is distributed without any warranty.
|
||||||
|
|
||||||
|
See <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||||
|
|
||||||
|
This is xoshiro256++ 1.0, one of our all-purpose, rock-solid generators.
|
||||||
|
It has excellent (sub-ns) speed, a state (256 bits) that is large
|
||||||
|
enough for any parallel application, and it passes all tests we are
|
||||||
|
aware of.
|
||||||
|
|
||||||
|
For generating just floating-point numbers, xoshiro256+ is even faster.
|
||||||
|
|
||||||
|
The state must be seeded so that it is not everywhere zero. If you have
|
||||||
|
a 64-bit seed, we suggest to seed a splitmix64 generator and use its
|
||||||
|
output to fill s[].
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "afl-fuzz.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "xxh3.h"
|
||||||
|
|
||||||
|
/* we use xoshiro256** instead of rand/random because it is 10x faster and has
|
||||||
|
better randomness properties. */
|
||||||
|
|
||||||
|
static inline uint64_t rotl(const uint64_t x, int k) {
|
||||||
|
|
||||||
|
return (x << k) | (x >> (64 - 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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t rand_next(afl_state_t *afl) {
|
||||||
|
|
||||||
|
const uint64_t result =
|
||||||
|
rotl(afl->rand_seed[0] + afl->rand_seed[3], 23) + afl->rand_seed[0];
|
||||||
|
|
||||||
|
const uint64_t t = afl->rand_seed[1] << 17;
|
||||||
|
|
||||||
|
afl->rand_seed[2] ^= afl->rand_seed[0];
|
||||||
|
afl->rand_seed[3] ^= afl->rand_seed[1];
|
||||||
|
afl->rand_seed[1] ^= afl->rand_seed[2];
|
||||||
|
afl->rand_seed[0] ^= afl->rand_seed[3];
|
||||||
|
|
||||||
|
afl->rand_seed[2] ^= t;
|
||||||
|
|
||||||
|
afl->rand_seed[3] = rotl(afl->rand_seed[3], 45);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is the jump function for the generator. It is equivalent
|
||||||
|
to 2^128 calls to rand_next(); it can be used to generate 2^128
|
||||||
|
non-overlapping subsequences for parallel computations. */
|
||||||
|
|
||||||
|
void jump(afl_state_t *afl) {
|
||||||
|
|
||||||
|
static const uint64_t JUMP[] = {0x180ec6d33cfd0aba, 0xd5a61266f0c9392c,
|
||||||
|
0xa9582618e03fc9aa, 0x39abdc4529b1661c};
|
||||||
|
int i, b;
|
||||||
|
uint64_t s0 = 0;
|
||||||
|
uint64_t s1 = 0;
|
||||||
|
uint64_t s2 = 0;
|
||||||
|
uint64_t s3 = 0;
|
||||||
|
for (i = 0; i < sizeof JUMP / sizeof *JUMP; i++)
|
||||||
|
for (b = 0; b < 64; b++) {
|
||||||
|
|
||||||
|
if (JUMP[i] & UINT64_C(1) << b) {
|
||||||
|
|
||||||
|
s0 ^= afl->rand_seed[0];
|
||||||
|
s1 ^= afl->rand_seed[1];
|
||||||
|
s2 ^= afl->rand_seed[2];
|
||||||
|
s3 ^= afl->rand_seed[3];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
rand_next(afl);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
afl->rand_seed[0] = s0;
|
||||||
|
afl->rand_seed[1] = s1;
|
||||||
|
afl->rand_seed[2] = s2;
|
||||||
|
afl->rand_seed[3] = s3;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is the long-jump function for the generator. It is equivalent to
|
||||||
|
2^192 calls to rand_next(); it can be used to generate 2^64 starting points,
|
||||||
|
from each of which jump() will generate 2^64 non-overlapping
|
||||||
|
subsequences for parallel distributed computations. */
|
||||||
|
|
||||||
|
void long_jump(afl_state_t *afl) {
|
||||||
|
|
||||||
|
static const uint64_t LONG_JUMP[] = {0x76e15d3efefdcbbf, 0xc5004e441c522fb3,
|
||||||
|
0x77710069854ee241, 0x39109bb02acbe635};
|
||||||
|
|
||||||
|
int i, b;
|
||||||
|
uint64_t s0 = 0;
|
||||||
|
uint64_t s1 = 0;
|
||||||
|
uint64_t s2 = 0;
|
||||||
|
uint64_t s3 = 0;
|
||||||
|
for (i = 0; i < sizeof LONG_JUMP / sizeof *LONG_JUMP; i++)
|
||||||
|
for (b = 0; b < 64; b++) {
|
||||||
|
|
||||||
|
if (LONG_JUMP[i] & UINT64_C(1) << b) {
|
||||||
|
|
||||||
|
s0 ^= afl->rand_seed[0];
|
||||||
|
s1 ^= afl->rand_seed[1];
|
||||||
|
s2 ^= afl->rand_seed[2];
|
||||||
|
s3 ^= afl->rand_seed[3];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
rand_next(afl);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
afl->rand_seed[0] = s0;
|
||||||
|
afl->rand_seed[1] = s1;
|
||||||
|
afl->rand_seed[2] = s2;
|
||||||
|
afl->rand_seed[3] = s3;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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! :-) */
|
||||||
|
|
||||||
|
#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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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");
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -145,13 +183,55 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
|
|||||||
|
|
||||||
if (!non_instrumented_mode) setenv(SHM_ENV_VAR, shm->g_shm_file_path, 1);
|
if (!non_instrumented_mode) setenv(SHM_ENV_VAR, shm->g_shm_file_path, 1);
|
||||||
|
|
||||||
if (shm->map == -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;
|
||||||
|
@ -56,7 +56,9 @@
|
|||||||
|
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/shm.h>
|
#ifndef USEMMAP
|
||||||
|
#include <sys/shm.h>
|
||||||
|
#endif
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
@ -80,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. */
|
||||||
|
|
||||||
@ -139,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. */
|
||||||
@ -557,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);
|
||||||
@ -577,8 +605,8 @@ 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;
|
||||||
@ -773,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();
|
||||||
|
|
||||||
@ -827,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"); }
|
||||||
|
|
||||||
@ -895,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] == '.') {
|
||||||
@ -922,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);
|
||||||
@ -937,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);
|
||||||
|
|
||||||
@ -958,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);
|
||||||
|
@ -54,7 +54,9 @@
|
|||||||
|
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/shm.h>
|
#ifndef USEMMAP
|
||||||
|
#include <sys/shm.h>
|
||||||
|
#endif
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
@ -67,20 +69,27 @@ static u8 *in_file, /* Minimizer input test case */
|
|||||||
static u8 *in_data; /* Input data for trimming */
|
static u8 *in_data; /* Input data for trimming */
|
||||||
|
|
||||||
static u32 in_len, /* Input data length */
|
static u32 in_len, /* Input data length */
|
||||||
orig_cksum, /* Original checksum */
|
|
||||||
missed_hangs, /* Misses due to hangs */
|
missed_hangs, /* Misses due to hangs */
|
||||||
missed_crashes, /* Misses due to crashes */
|
missed_crashes, /* Misses due to crashes */
|
||||||
missed_paths, /* Misses due to exec path diffs */
|
missed_paths, /* Misses due to exec path diffs */
|
||||||
map_size = MAP_SIZE;
|
map_size = MAP_SIZE;
|
||||||
|
|
||||||
|
static u64 orig_cksum; /* Original checksum */
|
||||||
|
|
||||||
static u8 crash_mode, /* Crash-centric mode? */
|
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
|
||||||
*/
|
*/
|
||||||
@ -102,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) {
|
||||||
@ -166,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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,7 +329,7 @@ static u8 tmin_run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len,
|
|||||||
|
|
||||||
if (ret == FSRV_RUN_NOINST) { FATAL("Binary not instrumented?"); }
|
if (ret == FSRV_RUN_NOINST) { FATAL("Binary not instrumented?"); }
|
||||||
|
|
||||||
u32 cksum = hash32(fsrv->trace_bits, fsrv->map_size, HASH_CONST);
|
u64 cksum = hash64(fsrv->trace_bits, fsrv->map_size, HASH_CONST);
|
||||||
|
|
||||||
if (first_run) { orig_cksum = cksum; }
|
if (first_run) { orig_cksum = cksum; }
|
||||||
|
|
||||||
@ -620,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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -809,8 +839,8 @@ 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;
|
||||||
@ -1007,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);
|
||||||
@ -1049,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" : "");
|
||||||
|
|
||||||
@ -1107,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); }
|
||||||
|
3
src/third_party/libradamsa/.gitignore
vendored
3
src/third_party/libradamsa/.gitignore
vendored
@ -1,3 +0,0 @@
|
|||||||
*.a
|
|
||||||
*.o
|
|
||||||
libradamsa-test
|
|
75
src/third_party/libradamsa/libradamsa-test.c
vendored
75
src/third_party/libradamsa/libradamsa-test.c
vendored
@ -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;
|
|
||||||
}
|
|
||||||
|
|
30850
src/third_party/libradamsa/libradamsa.c
vendored
30850
src/third_party/libradamsa/libradamsa.c
vendored
File diff suppressed because it is too large
Load Diff
13
src/third_party/libradamsa/radamsa.h
vendored
13
src/third_party/libradamsa/radamsa.h
vendored
@ -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);
|
|
119
test/test.sh
119
test/test.sh
@ -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??"
|
||||||
@ -1121,7 +1126,7 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && {
|
|||||||
|
|
||||||
$ECHO "$BLUE[*] Execution cmocka Unit-Tests $GREY"
|
$ECHO "$BLUE[*] Execution cmocka Unit-Tests $GREY"
|
||||||
unset AFL_CC
|
unset AFL_CC
|
||||||
make -C .. unit || "$CODE" = "1"
|
make -C .. unit || CODE=1 INCOMPLETE=1 :
|
||||||
|
|
||||||
$ECHO "$GREY[*] all test cases completed.$RESET"
|
$ECHO "$GREY[*] all test cases completed.$RESET"
|
||||||
test "$INCOMPLETE" = "0" && $ECHO "$GREEN[+] all test cases executed"
|
test "$INCOMPLETE" = "0" && $ECHO "$GREEN[+] all test cases executed"
|
||||||
|
75
test/unittests/unit_hash.c
Normal file
75
test/unittests/unit_hash.c
Normal 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;
|
||||||
|
}
|
@ -126,6 +126,8 @@ int main(int argc, char **argv) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
//return cmocka_run_group_tests (tests, setup, teardown);
|
//return cmocka_run_group_tests (tests, setup, teardown);
|
||||||
return cmocka_run_group_tests (tests, NULL, NULL);
|
__real_exit( cmocka_run_group_tests (tests, NULL, NULL) );
|
||||||
|
|
||||||
|
// fake return for dumb compilers
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -156,6 +156,8 @@ int main(int argc, char **argv) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
//return cmocka_run_group_tests (tests, setup, teardown);
|
//return cmocka_run_group_tests (tests, setup, teardown);
|
||||||
return cmocka_run_group_tests (tests, NULL, NULL);
|
__real_exit( cmocka_run_group_tests (tests, NULL, NULL) );
|
||||||
|
|
||||||
|
// fake return for dumb compilers
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -109,6 +109,8 @@ int main(int argc, char **argv) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
//return cmocka_run_group_tests (tests, setup, teardown);
|
//return cmocka_run_group_tests (tests, setup, teardown);
|
||||||
return cmocka_run_group_tests (tests, NULL, NULL);
|
__real_exit( cmocka_run_group_tests (tests, NULL, NULL) );
|
||||||
|
|
||||||
|
// fake return for dumb compilers
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
84
test/unittests/unit_rand.c
Normal file
84
test/unittests/unit_rand.c
Normal 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;
|
||||||
|
}
|
@ -1 +1 @@
|
|||||||
a6e943c
|
0ca7a8f2
|
||||||
|
Submodule unicorn_mode/unicornafl updated: a6e943c683...0ca7a8f22b
Reference in New Issue
Block a user