mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-09 08:41:32 +00:00
commit
2dffed1cff
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,8 +1,10 @@
|
||||
.test
|
||||
.test2
|
||||
.sync_tmp
|
||||
.vscode
|
||||
*.o
|
||||
*.so
|
||||
*.swp
|
||||
*.pyc
|
||||
*.dSYM
|
||||
as
|
||||
@ -10,6 +12,7 @@ ld
|
||||
in
|
||||
out
|
||||
core*
|
||||
compile_commands.json
|
||||
afl-analyze
|
||||
afl-as
|
||||
afl-clang
|
||||
@ -39,6 +42,7 @@ afl-cmin.8
|
||||
afl-cmin.bash.8
|
||||
afl-fuzz.8
|
||||
afl-gcc.8
|
||||
afl-g++.8
|
||||
afl-gcc-fast.8
|
||||
afl-g++-fast.8
|
||||
afl-gotcpu.8
|
||||
|
70
GNUmakefile
70
GNUmakefile
@ -24,22 +24,21 @@ BIN_PATH = $(PREFIX)/bin
|
||||
HELPER_PATH = $(PREFIX)/lib/afl
|
||||
DOC_PATH = $(PREFIX)/share/doc/afl
|
||||
MISC_PATH = $(PREFIX)/share/afl
|
||||
MAN_PATH = $(PREFIX)/man/man8
|
||||
MAN_PATH = $(PREFIX)/share/man/man8
|
||||
|
||||
PROGNAME = afl
|
||||
VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2)
|
||||
|
||||
# PROGS intentionally omit afl-as, which gets installed elsewhere.
|
||||
|
||||
PROGS = afl-gcc afl-fuzz afl-showmap afl-tmin afl-gotcpu afl-analyze
|
||||
PROGS = afl-gcc afl-g++ afl-fuzz afl-showmap afl-tmin afl-gotcpu afl-analyze
|
||||
SH_PROGS = afl-plot afl-cmin afl-cmin.bash afl-whatsup afl-system-config
|
||||
MANPAGES=$(foreach p, $(PROGS) $(SH_PROGS), $(p).8) afl-as.8
|
||||
ASAN_OPTIONS=detect_leaks=0
|
||||
|
||||
ifeq "$(findstring android, $(shell $(CC) --version 2>/dev/null))" ""
|
||||
ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -flto=full -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||
ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -flto=full -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||
CFLAGS_FLTO ?= -flto=full
|
||||
else
|
||||
else
|
||||
ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -flto=thin -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||
CFLAGS_FLTO ?= -flto=thin
|
||||
else
|
||||
@ -47,7 +46,7 @@ else
|
||||
CFLAGS_FLTO ?= -flto
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -fno-move-loop-invariants -fdisable-tree-cunrolli -x c - -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||
@ -62,7 +61,10 @@ ifneq "$(shell uname)" "Darwin"
|
||||
endif
|
||||
endif
|
||||
# OS X does not like _FORTIFY_SOURCE=2
|
||||
# _FORTIFY_SOURCE=2 does not like -O0
|
||||
ifndef DEBUG
|
||||
CFLAGS_OPT += -D_FORTIFY_SOURCE=2
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq "$(shell uname)" "SunOS"
|
||||
@ -204,7 +206,10 @@ else
|
||||
endif
|
||||
|
||||
ifneq "$(filter Linux GNU%,$(shell uname))" ""
|
||||
# _FORTIFY_SOURCE=2 does not like -O0
|
||||
ifndef DEBUG
|
||||
override CFLAGS += -D_FORTIFY_SOURCE=2
|
||||
endif
|
||||
LDFLAGS += -ldl -lrt
|
||||
endif
|
||||
|
||||
@ -274,7 +279,7 @@ endif
|
||||
|
||||
all: test_x86 test_shm test_python ready $(PROGS) afl-as test_build all_done
|
||||
|
||||
man: $(MANPAGES)
|
||||
man: afl-gcc all $(MANPAGES)
|
||||
|
||||
tests: source-only
|
||||
@cd test ; ./test-all.sh
|
||||
@ -367,79 +372,81 @@ endif
|
||||
ready:
|
||||
@echo "[+] Everything seems to be working, ready to compile."
|
||||
|
||||
afl-g++: afl-gcc
|
||||
|
||||
afl-gcc: src/afl-gcc.c $(COMM_HDR) | test_x86
|
||||
$(CC) $(CFLAGS) src/$@.c -o $@ $(LDFLAGS)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) src/$@.c -o $@ $(LDFLAGS)
|
||||
set -e; for i in afl-g++ afl-clang afl-clang++; do ln -sf afl-gcc $$i; done
|
||||
|
||||
afl-as: src/afl-as.c include/afl-as.h $(COMM_HDR) | test_x86
|
||||
$(CC) $(CFLAGS) src/$@.c -o $@ $(LDFLAGS)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) src/$@.c -o $@ $(LDFLAGS)
|
||||
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
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -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
|
||||
$(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-common.c -o src/afl-common.o
|
||||
$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(CPPFLAGS) -c src/afl-common.c -o src/afl-common.o
|
||||
|
||||
src/afl-forkserver.o : $(COMM_HDR) src/afl-forkserver.c include/forkserver.h
|
||||
$(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-forkserver.c -o src/afl-forkserver.o
|
||||
$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(CPPFLAGS) -c src/afl-forkserver.c -o src/afl-forkserver.o
|
||||
|
||||
src/afl-sharedmem.o : $(COMM_HDR) src/afl-sharedmem.c include/sharedmem.h
|
||||
$(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-sharedmem.c -o src/afl-sharedmem.o
|
||||
$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(CPPFLAGS) -c src/afl-sharedmem.c -o src/afl-sharedmem.o
|
||||
|
||||
afl-fuzz: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o | test_x86
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(PYFLAGS) $(LDFLAGS)
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) $(CPPFLAGS) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(PYFLAGS) $(LDFLAGS)
|
||||
|
||||
afl-showmap: src/afl-showmap.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o $(COMM_HDR) | test_x86
|
||||
$(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) $(CPPFLAGS) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o -o $@ $(LDFLAGS)
|
||||
|
||||
afl-tmin: src/afl-tmin.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o $(COMM_HDR) | test_x86
|
||||
$(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)
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(CPPFLAGS) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(LDFLAGS)
|
||||
|
||||
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 src/afl-performance.o -o $@ $(LDFLAGS)
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(CPPFLAGS) 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
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o -o $@ $(LDFLAGS)
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(CPPFLAGS) src/$@.c src/afl-common.o -o $@ $(LDFLAGS)
|
||||
|
||||
|
||||
# document all mutations and only do one run (use with only one input file!)
|
||||
document: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-performance.o | test_x86
|
||||
$(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)
|
||||
$(CC) -D_DEBUG=\"1\" -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) $(CPPFLAGS) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.c src/afl-performance.o -o afl-fuzz-document $(PYFLAGS) $(LDFLAGS)
|
||||
|
||||
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) $(CPPFLAGS) -c test/unittests/unit_maybe_alloc.c -o test/unittests/unit_maybe_alloc.o
|
||||
|
||||
unit_maybe_alloc: test/unittests/unit_maybe_alloc.o
|
||||
@$(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_maybe_alloc.o -o test/unittests/unit_maybe_alloc $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||
@$(CC) $(CFLAGS) $(CPPFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_maybe_alloc.o -o test/unittests/unit_maybe_alloc $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||
./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
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(CPPFLAGS) -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
|
||||
@$(CC) $(CFLAGS) $(CPPFLAGS) -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
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(CPPFLAGS) -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
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(CPPFLAGS) -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)
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_list.c -o test/unittests/unit_list.o
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(CPPFLAGS) -c test/unittests/unit_list.c -o test/unittests/unit_list.o
|
||||
|
||||
unit_list: test/unittests/unit_list.o
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_list.o -o test/unittests/unit_list $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(CPPFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_list.o -o test/unittests/unit_list $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||
./test/unittests/unit_list
|
||||
|
||||
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
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(CPPFLAGS) -c test/unittests/unit_preallocable.c -o 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) $(CPPFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_preallocable.o -o test/unittests/unit_preallocable $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||
./test/unittests/unit_preallocable
|
||||
|
||||
unit_clean:
|
||||
@ -486,7 +493,7 @@ ifndef AFL_NO_X86
|
||||
|
||||
test_build: afl-gcc afl-as afl-showmap
|
||||
@echo "[*] Testing the CC wrapper and instrumentation output..."
|
||||
@unset AFL_USE_ASAN AFL_USE_MSAN AFL_CC; AFL_DEBUG=1 AFL_INST_RATIO=100 AFL_PATH=. ./$(TEST_CC) $(CFLAGS) test-instr.c -o test-instr $(LDFLAGS) 2>&1 | grep 'afl-as' >/dev/null || (echo "Oops, afl-as did not get called from "$(TEST_CC)". This is normally achieved by "$(CC)" honoring the -B option."; exit 1 )
|
||||
@unset AFL_USE_ASAN AFL_USE_MSAN AFL_CC; AFL_DEBUG=1 AFL_INST_RATIO=100 AFL_AS_FORCE_INSTRUMENT=1 AFL_PATH=. ./$(TEST_CC) $(CFLAGS) test-instr.c -o test-instr $(LDFLAGS) 2>&1 | grep 'afl-as' >/dev/null || (echo "Oops, afl-as did not get called from "$(TEST_CC)". This is normally achieved by "$(CC)" honoring the -B option."; exit 1 )
|
||||
ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null
|
||||
echo 1 | ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr1 ./test-instr
|
||||
@rm -f test-instr
|
||||
@ -566,7 +573,8 @@ source-only: all
|
||||
%.8: %
|
||||
@echo .TH $* 8 $(BUILD_DATE) "afl++" > $@
|
||||
@echo .SH NAME >> $@
|
||||
@echo .B $* >> $@
|
||||
@echo -n ".B $* \- " >> $@
|
||||
@./$* -h 2>&1 | head -n 1 | sed -e "s/$$(printf '\e')[^m]*m//g" >> $@
|
||||
@echo >> $@
|
||||
@echo .SH SYNOPSIS >> $@
|
||||
@./$* -h 2>&1 | head -n 3 | tail -n 1 | sed 's/^\.\///' >> $@
|
||||
|
5
TODO.md
5
TODO.md
@ -1,10 +1,13 @@
|
||||
# TODO list for AFL++
|
||||
|
||||
## Roadmap 2.67+
|
||||
## Roadmap 2.68+
|
||||
|
||||
- AFL_MAP_SIZE for qemu_mode and unicorn_mode
|
||||
- CPU affinity for many cores? There seems to be an issue > 96 cores
|
||||
- afl-plot to support multiple plot_data
|
||||
- afl_custom_fuzz_splice_optin()
|
||||
- intel-pt tracer
|
||||
- honor -O flags and -fno-unroll-loops in afl-cc
|
||||
|
||||
## Further down the road
|
||||
|
||||
|
1
afl-cmin
1
afl-cmin
@ -120,6 +120,7 @@ function usage() {
|
||||
"AFL_PATH: path for the afl-showmap binary\n" \
|
||||
"AFL_SKIP_BIN_CHECK: skip check for target binary\n" \
|
||||
"AFL_ALLOW_TMP: allow unsafe use of input/output directories under {/var}/tmp\n"
|
||||
"AFL_FORKSRV_INIT_TMOUT: time the fuzzer waits for the target to come up, initially\n"
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
@ -15,14 +15,14 @@ libradamsa.a: libradamsa.c radamsa.h
|
||||
@echo " ***************************************************************"
|
||||
@echo " * Compiling libradamsa, wait some minutes (~3 on modern CPUs) *"
|
||||
@echo " ***************************************************************"
|
||||
$(CC) -fPIC $(CFLAGS) -I $(CUR_DIR) -o libradamsa.a -c libradamsa.c
|
||||
$(CC) -fPIC $(CFLAGS) $(CPPFLAGS) -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
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -g -I. -I../../include -shared -fPIC -c radamsa-mutator.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -shared -fPIC -o radamsa-mutator.so radamsa-mutator.o libradamsa.a
|
||||
|
||||
test: libradamsa.a libradamsa-test.c
|
||||
$(CC) $(CFLAGS) -I $(CUR_DIR) -o libradamsa-test libradamsa-test.c libradamsa.a
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -I $(CUR_DIR) -o libradamsa-test libradamsa-test.c libradamsa.a
|
||||
./libradamsa-test libradamsa-test.c | grep "library test passed"
|
||||
rm /tmp/libradamsa-*.fuzz
|
||||
|
||||
|
@ -10,10 +10,18 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
|
||||
|
||||
|
||||
### Version ++2.67d (develop)
|
||||
- a few QOL changes for Apple and its outdated gmake
|
||||
- afl-fuzz:
|
||||
- Fix for auto dictionary entries found during fuzzing to not throw out
|
||||
a -x dictionary
|
||||
- added total execs done to plot file
|
||||
- AFL_MAX_DET_EXTRAS env variable added to control the amount of deterministic
|
||||
dict entries without recompiling.
|
||||
- AFL_FORKSRV_INIT_TMOUT env variable added to control the time to wait for
|
||||
the forkserver to come up without the need to increase the overall timeout.
|
||||
- custom mutators:
|
||||
- added afl_custom_fuzz_count/fuzz_count function to allow specifying the
|
||||
number of fuzz attempts for custom_fuzz
|
||||
- llvm_mode:
|
||||
- Ported SanCov to LTO, and made it the default for LTO. better
|
||||
instrumentation locations
|
||||
@ -409,7 +417,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
|
||||
- big code refactoring:
|
||||
* all includes are now in include/
|
||||
* all afl sources are now in src/ - see src/README.md
|
||||
* afl-fuzz was splitted up in various individual files for including
|
||||
* afl-fuzz was split up in various individual files for including
|
||||
functionality in other programs (e.g. forkserver, memory map, etc.)
|
||||
for better readability.
|
||||
* new code indention everywhere
|
||||
|
@ -6,14 +6,14 @@
|
||||
However, if there is only the binary program and no source code available,
|
||||
then standard `afl-fuzz -n` (non-instrumented mode) is not effective.
|
||||
|
||||
The following is a description of how these binaries can be fuzzed with afl++
|
||||
The following is a description of how these binaries can be fuzzed with afl++.
|
||||
|
||||
|
||||
## TL;DR:
|
||||
|
||||
qemu_mode in persistent mode is the fastest - if the stability is
|
||||
high enough. Otherwise try retrowrite, afl-dyninst and if these
|
||||
fail too then standard qemu_mode with AFL_ENTRYPOINT to where you need it.
|
||||
fail too then try standard qemu_mode with AFL_ENTRYPOINT to where you need it.
|
||||
|
||||
If your target is a library use examples/afl_frida/.
|
||||
|
||||
@ -29,10 +29,10 @@
|
||||
|
||||
The speed decrease is at about 50%.
|
||||
However various options exist to increase the speed:
|
||||
- using AFL_ENTRYPOINT to move the forkserver to a later basic block in
|
||||
- using AFL_ENTRYPOINT to move the forkserver entry to a later basic block in
|
||||
the binary (+5-10% speed)
|
||||
- using persistent mode [qemu_mode/README.persistent.md](../qemu_mode/README.persistent.md)
|
||||
this will result in 150-300% overall speed - so 3-8x the original
|
||||
this will result in 150-300% overall speed increase - so 3-8x the original
|
||||
qemu_mode speed!
|
||||
- using AFL_CODE_START/AFL_CODE_END to only instrument specific parts
|
||||
|
||||
@ -104,7 +104,7 @@
|
||||
|
||||
## RETROWRITE
|
||||
|
||||
If you have an x86/x86_64 binary that still has it's symbols, is compiled
|
||||
If you have an x86/x86_64 binary that still has its symbols, is compiled
|
||||
with position independant code (PIC/PIE) and does not use most of the C++
|
||||
features then the retrowrite solution might be for you.
|
||||
It decompiles to ASM files which can then be instrumented with afl-gcc.
|
||||
@ -148,7 +148,7 @@
|
||||
## CORESIGHT
|
||||
|
||||
Coresight is ARM's answer to Intel's PT.
|
||||
There is no implementation so far which handle coresight and getting
|
||||
There is no implementation so far which handles coresight and getting
|
||||
it working on an ARM Linux is very difficult due to custom kernel building
|
||||
on embedded systems is difficult. And finding one that has coresight in
|
||||
the ARM chip is difficult too.
|
||||
|
@ -32,6 +32,7 @@ performed with the custom mutator.
|
||||
C/C++:
|
||||
```c
|
||||
void *afl_custom_init(afl_t *afl, unsigned int seed);
|
||||
uint32_t afl_custom_fuzz_count(void *data, const u8 *buf, size_t buf_size);
|
||||
size_t afl_custom_fuzz(void *data, uint8_t *buf, size_t buf_size, u8 **out_buf, uint8_t *add_buf, size_t add_buf_size, size_t max_size);
|
||||
size_t afl_custom_post_process(void *data, uint8_t *buf, size_t buf_size, uint8_t **out_buf);
|
||||
int32_t afl_custom_init_trim(void *data, uint8_t *buf, size_t buf_size);
|
||||
@ -49,6 +50,9 @@ Python:
|
||||
def init(seed):
|
||||
pass
|
||||
|
||||
def fuzz_count(buf, add_buf, max_size):
|
||||
return cnt
|
||||
|
||||
def fuzz(buf, add_buf, max_size):
|
||||
return mutated_out
|
||||
|
||||
@ -88,6 +92,14 @@ def queue_new_entry(filename_new_queue, filename_orig_queue):
|
||||
This method determines whether the custom fuzzer should fuzz the current
|
||||
queue entry or not
|
||||
|
||||
- `fuzz_count` (optional):
|
||||
|
||||
When a queue entry is selected to be fuzzed, afl-fuzz selects the number
|
||||
of fuzzing attempts with this input based on a few factors.
|
||||
If however the custom mutator wants to set this number instead on how often
|
||||
it is called for a specific queue entry, use this function.
|
||||
This function in mostly useful if **not** `AFL_CUSTOM_MUTATOR_ONLY` is used.
|
||||
|
||||
- `fuzz` (optional):
|
||||
|
||||
This method performs custom mutations on a given input. It also accepts an
|
||||
|
@ -10,8 +10,8 @@
|
||||
Because they can't directly accept command-line options, the compile-time
|
||||
tools make fairly broad use of environmental variables:
|
||||
|
||||
- Most afl tools do not print any ouput if stout/stderr are redirected.
|
||||
If you want to have the output into a file then set the AFL_DEBUG
|
||||
- Most afl tools do not print any output if stdout/stderr are redirected.
|
||||
If you want to save the output in a file then set the AFL_DEBUG
|
||||
environment variable.
|
||||
This is sadly necessary for various build processes which fail otherwise.
|
||||
|
||||
@ -44,7 +44,7 @@ tools make fairly broad use of environmental variables:
|
||||
you instrument hand-written assembly when compiling clang code by plugging
|
||||
a normalizer into the chain. (There is no equivalent feature for GCC.)
|
||||
|
||||
- Setting AFL_INST_RATIO to a percentage between 0 and 100% controls the
|
||||
- Setting AFL_INST_RATIO to a percentage between 0% and 100% controls the
|
||||
probability of instrumenting every branch. This is (very rarely) useful
|
||||
when dealing with exceptionally complex programs that saturate the output
|
||||
bitmap. Examples include v8, ffmpeg, and perl.
|
||||
@ -88,7 +88,7 @@ of the settings discussed in section #1, with the exception of:
|
||||
- TMPDIR and AFL_KEEP_ASSEMBLY, since no temporary assembly files are
|
||||
created.
|
||||
|
||||
- AFL_INST_RATIO, as we by default collision free instrumentation is used.
|
||||
- AFL_INST_RATIO, as we by default use collision free instrumentation.
|
||||
|
||||
Then there are a few specific features that are only available in llvm_mode:
|
||||
|
||||
@ -121,7 +121,7 @@ Then there are a few specific features that are only available in llvm_mode:
|
||||
|
||||
None of the following options are necessary to be used and are rather for
|
||||
manual use (which only ever the author of this LTO implementation will use).
|
||||
These are used if several seperated instrumentation are performed which
|
||||
These are used if several seperated instrumentations are performed which
|
||||
are then later combined.
|
||||
|
||||
- AFL_LLVM_DOCUMENT_IDS=file will document to a file which edge ID was given
|
||||
@ -200,7 +200,7 @@ Then there are a few specific features that are only available in llvm_mode:
|
||||
|
||||
### INSTRUMENT LIST (selectively instrument files and functions)
|
||||
|
||||
This feature allows selectively instrumentation of the source
|
||||
This feature allows selective instrumentation of the source
|
||||
|
||||
- Setting AFL_LLVM_ALLOWLIST or AFL_LLVM_DENYLIST with a filenames and/or
|
||||
function will only instrument (or skip) those files that match the names
|
||||
@ -278,6 +278,14 @@ checks or alter some of the more exotic semantics of the tool:
|
||||
don't want AFL to spend too much time classifying that stuff and just
|
||||
rapidly put all timeouts in that bin.
|
||||
|
||||
- Setting AFL_FORKSRV_INIT_TMOUT allows yout to specify a different timeout
|
||||
to wait for the forkserver to spin up. The default is the `-t` value times
|
||||
`FORK_WAIT_MULT` from `config.h` (usually 10), so for a `-t 100`, the
|
||||
default would wait `1000` milis. Setting a different time here is useful
|
||||
if the target has a very slow startup time, for example when doing
|
||||
full-system fuzzing or emulation, but you don't want the actual runs
|
||||
to wait too long for timeouts.
|
||||
|
||||
- AFL_NO_ARITH causes AFL to skip most of the deterministic arithmetics.
|
||||
This can be useful to speed up the fuzzing of text-based file formats.
|
||||
|
||||
@ -370,6 +378,16 @@ checks or alter some of the more exotic semantics of the tool:
|
||||
normally done when starting up the forkserver and causes a pretty
|
||||
significant performance drop.
|
||||
|
||||
- Setting AFL_MAX_DET_EXTRAS changes the count of dictionary entries/extras
|
||||
(default 200), after which the entries will be used probabilistically.
|
||||
So, if the dict/extras file (`-x`) contains more tokens than this threshold,
|
||||
not all of the tokens will be used in each fuzzing step, every time.
|
||||
Instead, there is a chance that the entry will be skipped during fuzzing.
|
||||
This makes sure that the fuzzer doesn't spend all its time only inserting
|
||||
the extras, but will still do other mutations. However, it decreases the
|
||||
likelihood for each token to be inserted, before the next queue entry is fuzzed.
|
||||
Either way, all tokens will be used eventually, in a longer fuzzing campaign.
|
||||
|
||||
- Outdated environment variables that are that not supported anymore:
|
||||
AFL_DEFER_FORKSRV
|
||||
AFL_PERSISTENT
|
||||
|
@ -10,8 +10,8 @@ n-core system, you can almost always run around n concurrent fuzzing jobs with
|
||||
virtually no performance hit (you can use the afl-gotcpu tool to make sure).
|
||||
|
||||
In fact, if you rely on just a single job on a multi-core system, you will
|
||||
be underutilizing the hardware. So, parallelization is usually the right
|
||||
way to go.
|
||||
be underutilizing the hardware. So, parallelization is always the right way to
|
||||
go.
|
||||
|
||||
When targeting multiple unrelated binaries or using the tool in
|
||||
"non-instrumented" (-n) mode, it is perfectly fine to just start up several
|
||||
@ -65,22 +65,7 @@ still perform deterministic checks; while the secondary instances will
|
||||
proceed straight to random tweaks.
|
||||
|
||||
Note that you must always have one -M main instance!
|
||||
|
||||
Note that running multiple -M instances is wasteful, although there is an
|
||||
experimental support for parallelizing the deterministic checks. To leverage
|
||||
that, you need to create -M instances like so:
|
||||
|
||||
```
|
||||
./afl-fuzz -i testcase_dir -o sync_dir -M mainA:1/3 [...]
|
||||
./afl-fuzz -i testcase_dir -o sync_dir -M mainB:2/3 [...]
|
||||
./afl-fuzz -i testcase_dir -o sync_dir -M mainC:3/3 [...]
|
||||
```
|
||||
|
||||
...where the first value after ':' is the sequential ID of a particular main
|
||||
instance (starting at 1), and the second value is the total number of fuzzers to
|
||||
distribute the deterministic fuzzing across. Note that if you boot up fewer
|
||||
fuzzers than indicated by the second number passed to -M, you may end up with
|
||||
poor coverage.
|
||||
Running multiple -M instances is wasteful!
|
||||
|
||||
You can also monitor the progress of your jobs from the command line with the
|
||||
provided afl-whatsup tool. When the instances are no longer finding new paths,
|
||||
@ -99,61 +84,88 @@ example may be:
|
||||
This is not a concern if you use @@ without -f and let afl-fuzz come up with the
|
||||
file name.
|
||||
|
||||
## 3) Syncing with non-afl fuzzers or independant instances
|
||||
## 3) Multiple -M mains
|
||||
|
||||
|
||||
There is support for parallelizing the deterministic checks.
|
||||
This is only needed where
|
||||
|
||||
1. many new paths are found fast over a long time and it looks unlikely that
|
||||
main node will ever catch up, and
|
||||
2. deterministic fuzzing is actively helping path discovery (you can see this
|
||||
in the main node for the first for lines in the "fuzzing strategy yields"
|
||||
section. If the ration `found/attemps` is high, then it is effective. It
|
||||
most commonly isn't.)
|
||||
|
||||
Only if both are true it is beneficial to have more than one main.
|
||||
You can leverage this by creating -M instances like so:
|
||||
|
||||
```
|
||||
./afl-fuzz -i testcase_dir -o sync_dir -M mainA:1/3 [...]
|
||||
./afl-fuzz -i testcase_dir -o sync_dir -M mainB:2/3 [...]
|
||||
./afl-fuzz -i testcase_dir -o sync_dir -M mainC:3/3 [...]
|
||||
```
|
||||
|
||||
... where the first value after ':' is the sequential ID of a particular main
|
||||
instance (starting at 1), and the second value is the total number of fuzzers to
|
||||
distribute the deterministic fuzzing across. Note that if you boot up fewer
|
||||
fuzzers than indicated by the second number passed to -M, you may end up with
|
||||
poor coverage.
|
||||
|
||||
## 4) Syncing with non-afl fuzzers or independant instances
|
||||
|
||||
A -M main node can be told with the `-F other_fuzzer_queue_directory` option
|
||||
to sync results from other fuzzers, e.g. libfuzzer or honggfuzz.
|
||||
|
||||
Only the specified directory will by synced into afl, not subdirectories.
|
||||
The specified directories do not need to exist yet at the start of afl.
|
||||
The specified directory does not need to exist yet at the start of afl.
|
||||
|
||||
## 4) Multi-system parallelization
|
||||
The `-F` option can be passed to the main node several times.
|
||||
|
||||
## 5) Multi-system parallelization
|
||||
|
||||
The basic operating principle for multi-system parallelization is similar to
|
||||
the mechanism explained in section 2. The key difference is that you need to
|
||||
write a simple script that performs two actions:
|
||||
|
||||
- Uses SSH with authorized_keys to connect to every machine and retrieve
|
||||
a tar archive of the /path/to/sync_dir/<fuzzer_id>/queue/ directories for
|
||||
every <fuzzer_id> local to the machine. It's best to use a naming scheme
|
||||
that includes host name in the fuzzer ID, so that you can do something
|
||||
like:
|
||||
a tar archive of the /path/to/sync_dir/<main_node(s)> directory local to
|
||||
the machine.
|
||||
It is best to use a naming scheme that includes host name and it's being
|
||||
a main node (e.g. main1, main2) in the fuzzer ID, so that you can do
|
||||
something like:
|
||||
|
||||
```sh
|
||||
for s in {1..10}; do
|
||||
ssh user@host${s} "tar -czf - sync/host${s}_fuzzid*/[qf]*" >host${s}.tgz
|
||||
for host in `cat HOSTLIST`; do
|
||||
ssh user@$host "tar -czf - sync/$host_main*/" > $host.tgz
|
||||
done
|
||||
```
|
||||
|
||||
- Distributes and unpacks these files on all the remaining machines, e.g.:
|
||||
|
||||
```sh
|
||||
for s in {1..10}; do
|
||||
for d in {1..10}; do
|
||||
test "$s" = "$d" && continue
|
||||
ssh user@host${d} 'tar -kxzf -' <host${s}.tgz
|
||||
for srchost in `cat HOSTLIST`; do
|
||||
for dsthost in `cat HOSTLIST`; do
|
||||
test "$srchost" = "$dsthost" && continue
|
||||
ssh user@$srchost 'tar -kxzf -' < $dsthost.tgz
|
||||
done
|
||||
done
|
||||
```
|
||||
|
||||
There is an example of such a script in examples/distributed_fuzzing/;
|
||||
you can also find a more featured, experimental tool developed by
|
||||
Martijn Bogaard at:
|
||||
There is an example of such a script in examples/distributed_fuzzing/.
|
||||
|
||||
https://github.com/MartijnB/disfuzz-afl
|
||||
There are other (older) more featured, experimental tools:
|
||||
* https://github.com/richo/roving
|
||||
* https://github.com/MartijnB/disfuzz-afl
|
||||
|
||||
Another client-server implementation from Richo Healey is:
|
||||
|
||||
https://github.com/richo/roving
|
||||
|
||||
Note that these third-party tools are unsafe to run on systems exposed to the
|
||||
Internet or to untrusted users.
|
||||
However these do not support syncing just main nodes (yet).
|
||||
|
||||
When developing custom test case sync code, there are several optimizations
|
||||
to keep in mind:
|
||||
|
||||
- The synchronization does not have to happen very often; running the
|
||||
task every 30 minutes or so may be perfectly fine.
|
||||
task every 60 minutes or even less often at later fuzzing stages is
|
||||
fine
|
||||
|
||||
- There is no need to synchronize crashes/ or hangs/; you only need to
|
||||
copy over queue/* (and ideally, also fuzzer_stats).
|
||||
@ -180,18 +192,23 @@ to keep in mind:
|
||||
run them all with -S, and just designate a single process somewhere within
|
||||
the fleet to run with -M.
|
||||
|
||||
- Syncing is only necessary for the main nodes on a system. It is possible
|
||||
to run main-less with only secondaries. However then you need to find out
|
||||
which secondary took over the temporary role to be the main node. Look for
|
||||
the `is_main_node` file in the fuzzer directories, eg. `sync-dir/hostname-*/is_main_node`
|
||||
|
||||
It is *not* advisable to skip the synchronization script and run the fuzzers
|
||||
directly on a network filesystem; unexpected latency and unkillable processes
|
||||
in I/O wait state can mess things up.
|
||||
|
||||
## 5) Remote monitoring and data collection
|
||||
## 6) Remote monitoring and data collection
|
||||
|
||||
You can use screen, nohup, tmux, or something equivalent to run remote
|
||||
instances of afl-fuzz. If you redirect the program's output to a file, it will
|
||||
automatically switch from a fancy UI to more limited status reports. There is
|
||||
also basic machine-readable information always written to the fuzzer_stats file
|
||||
in the output directory. Locally, that information can be interpreted with
|
||||
afl-whatsup.
|
||||
also basic machine-readable information which is always written to the
|
||||
fuzzer_stats file in the output directory. Locally, that information can be
|
||||
interpreted with afl-whatsup.
|
||||
|
||||
In principle, you can use the status screen of the main (-M) instance to
|
||||
monitor the overall fuzzing progress and decide when to stop. In this
|
||||
@ -208,7 +225,7 @@ Keep in mind that crashing inputs are *not* automatically propagated to the
|
||||
main instance, so you may still want to monitor for crashes fleet-wide
|
||||
from within your synchronization or health checking scripts (see afl-whatsup).
|
||||
|
||||
## 6) Asymmetric setups
|
||||
## 7) Asymmetric setups
|
||||
|
||||
It is perhaps worth noting that all of the following is permitted:
|
||||
|
||||
@ -224,7 +241,7 @@ It is perhaps worth noting that all of the following is permitted:
|
||||
the discovered test cases can have synergistic effects and improve the
|
||||
overall coverage.
|
||||
|
||||
(In this case, running one -M instance per each binary is a good plan.)
|
||||
(In this case, running one -M instance per target is necessary.)
|
||||
|
||||
- Having some of the fuzzers invoke the binary in different ways.
|
||||
For example, 'djpeg' supports several DCT modes, configurable with
|
||||
|
@ -74,6 +74,7 @@ static u8 *in_data; /* Input data for trimming */
|
||||
static u8 *buf2;
|
||||
|
||||
static s32 in_len;
|
||||
static s32 buf2_len;
|
||||
static u32 map_size = MAP_SIZE;
|
||||
|
||||
static volatile u8 stop_soon; /* Ctrl-C pressed? */
|
||||
@ -381,6 +382,7 @@ int recv_testcase(int s, void **buf) {
|
||||
if (clen < 1)
|
||||
FATAL("did not receive valid compressed len information: %u", clen);
|
||||
buf2 = afl_realloc((void **)&buf2, clen);
|
||||
buf2_len = clen;
|
||||
if (unlikely(!buf2)) { PFATAL("Alloc"); }
|
||||
received = 0;
|
||||
while (received < clen &&
|
||||
@ -641,6 +643,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
compressor = libdeflate_alloc_compressor(1);
|
||||
decompressor = libdeflate_alloc_decompressor();
|
||||
buf2 = afl_realloc((void **)&buf2, map_size + 16);
|
||||
buf2_len = map_size + 16;
|
||||
if (unlikely(!buf2)) { PFATAL("alloc"); }
|
||||
lenptr = (u32 *)(buf2 + 4);
|
||||
fprintf(stderr, "Compiled with compression support\n");
|
||||
|
@ -39,8 +39,11 @@ FUZZ_USER=bob
|
||||
# Directory to synchronize
|
||||
SYNC_DIR='/home/bob/sync_dir'
|
||||
|
||||
# Interval (seconds) between sync attempts
|
||||
SYNC_INTERVAL=$((30 * 60))
|
||||
# We only capture -M main nodes, set the name to your chosen naming scheme
|
||||
MAIN_NAME='main'
|
||||
|
||||
# Interval (seconds) between sync attempts (eg one hour)
|
||||
SYNC_INTERVAL=$((60 * 60))
|
||||
|
||||
if [ "$AFL_ALLOW_TMP" = "" ]; then
|
||||
|
||||
@ -63,7 +66,7 @@ while :; do
|
||||
echo "[*] Retrieving data from ${host}.${FUZZ_DOMAIN}..."
|
||||
|
||||
ssh -o 'passwordauthentication no' ${FUZZ_USER}@${host}.$FUZZ_DOMAIN \
|
||||
"cd '$SYNC_DIR' && tar -czf - ${host}_*/[qf]*" >".sync_tmp/${host}.tgz"
|
||||
"cd '$SYNC_DIR' && tar -czf - ${host}_${MAIN_NAME}*/" > ".sync_tmp/${host}.tgz"
|
||||
|
||||
done
|
||||
|
||||
@ -80,7 +83,7 @@ while :; do
|
||||
echo " Sending fuzzer data from ${src_host}.${FUZZ_DOMAIN}..."
|
||||
|
||||
ssh -o 'passwordauthentication no' ${FUZZ_USER}@$dst_host \
|
||||
"cd '$SYNC_DIR' && tar -xkzf -" <".sync_tmp/${src_host}.tgz"
|
||||
"cd '$SYNC_DIR' && tar -xkzf - " < ".sync_tmp/${src_host}.tgz"
|
||||
|
||||
done
|
||||
|
||||
|
@ -24,7 +24,7 @@ PREFIX ?= /usr/local
|
||||
HELPER_PATH ?= $(PREFIX)/lib/afl
|
||||
BIN_PATH ?= $(PREFIX)/bin
|
||||
DOC_PATH ?= $(PREFIX)/share/doc/afl
|
||||
MAN_PATH ?= $(PREFIX)/man/man8
|
||||
MAN_PATH ?= $(PREFIX)/share/man/man8
|
||||
|
||||
VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2)
|
||||
|
||||
@ -111,21 +111,21 @@ test_deps:
|
||||
@echo "[+] All set and ready to build."
|
||||
|
||||
afl-common.o: ../src/afl-common.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ $(LDFLAGS)
|
||||
|
||||
../afl-gcc-fast: afl-gcc-fast.c afl-common.o | test_deps
|
||||
$(CC) -DAFL_GCC_CC=\"$(CC)\" -DAFL_GCC_CXX=\"$(CXX)\" $(CFLAGS) $< afl-common.o -o $@ $(LDFLAGS)
|
||||
$(CC) -DAFL_GCC_CC=\"$(CC)\" -DAFL_GCC_CXX=\"$(CXX)\" $(CFLAGS) $(CPPFLAGS) $< afl-common.o -o $@ $(LDFLAGS)
|
||||
ln -sf afl-gcc-fast ../afl-g++-fast
|
||||
|
||||
../afl-gcc-pass.so: afl-gcc-pass.so.cc | test_deps
|
||||
$(CXX) $(CXXEFLAGS) $(PLUGIN_FLAGS) -shared $< -o $@
|
||||
|
||||
../afl-gcc-rt.o: afl-gcc-rt.o.c | test_deps
|
||||
$(CC) $(CFLAGS_SAFE) -fPIC -c $< -o $@
|
||||
$(CC) $(CFLAGS_SAFE) $(CPPFLAGS) -fPIC -c $< -o $@
|
||||
|
||||
test_build: $(PROGS)
|
||||
@echo "[*] Testing the CC wrapper and instrumentation output..."
|
||||
unset AFL_USE_ASAN AFL_USE_MSAN; AFL_QUIET=1 AFL_INST_RATIO=100 AFL_PATH=. AFL_CC=$(CC) ../afl-gcc-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS)
|
||||
unset AFL_USE_ASAN AFL_USE_MSAN; AFL_QUIET=1 AFL_INST_RATIO=100 AFL_PATH=. AFL_CC=$(CC) ../afl-gcc-fast $(CFLAGS) $(CPPFLAGS) ../test-instr.c -o test-instr $(LDFLAGS)
|
||||
# unset AFL_USE_ASAN AFL_USE_MSAN; AFL_INST_RATIO=100 AFL_PATH=. AFL_CC=$(CC) ../afl-gcc-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS)
|
||||
ASAN_OPTIONS=detect_leaks=0 ../afl-showmap -m none -q -o .test-instr0 ./test-instr </dev/null
|
||||
echo 1 | ASAN_OPTIONS=detect_leaks=0 ../afl-showmap -m none -q -o .test-instr1 ./test-instr
|
||||
|
@ -24,7 +24,7 @@ PREFIX ?= /usr/local
|
||||
HELPER_PATH ?= $(PREFIX)/lib/afl
|
||||
BIN_PATH ?= $(PREFIX)/bin
|
||||
DOC_PATH ?= $(PREFIX)/share/doc/afl
|
||||
MAN_PATH ?= $(PREFIX)/man/man8
|
||||
MAN_PATH ?= $(PREFIX)/share/man/man8
|
||||
|
||||
VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2)
|
||||
VERSION:sh= grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2
|
||||
|
@ -288,16 +288,19 @@ enum {
|
||||
enum {
|
||||
|
||||
/* 00 */ PY_FUNC_INIT,
|
||||
/* 01 */ PY_FUNC_FUZZ,
|
||||
/* 02 */ PY_FUNC_POST_PROCESS,
|
||||
/* 03 */ PY_FUNC_INIT_TRIM,
|
||||
/* 04 */ PY_FUNC_POST_TRIM,
|
||||
/* 05 */ PY_FUNC_TRIM,
|
||||
/* 06 */ PY_FUNC_HAVOC_MUTATION,
|
||||
/* 07 */ PY_FUNC_HAVOC_MUTATION_PROBABILITY,
|
||||
/* 08 */ PY_FUNC_QUEUE_GET,
|
||||
/* 09 */ PY_FUNC_QUEUE_NEW_ENTRY,
|
||||
/* 10 */ PY_FUNC_DEINIT,
|
||||
/* 01 */ PY_FUNC_DEINIT,
|
||||
/* FROM HERE ON BELOW ALL ARE OPTIONAL */
|
||||
/* 02 */ PY_OPTIONAL = 2,
|
||||
/* 02 */ PY_FUNC_FUZZ = 2,
|
||||
/* 03 */ PY_FUNC_FUZZ_COUNT,
|
||||
/* 04 */ PY_FUNC_POST_PROCESS,
|
||||
/* 05 */ PY_FUNC_INIT_TRIM,
|
||||
/* 06 */ PY_FUNC_POST_TRIM,
|
||||
/* 07 */ PY_FUNC_TRIM,
|
||||
/* 08 */ PY_FUNC_HAVOC_MUTATION,
|
||||
/* 09 */ PY_FUNC_HAVOC_MUTATION_PROBABILITY,
|
||||
/* 10 */ PY_FUNC_QUEUE_GET,
|
||||
/* 11 */ PY_FUNC_QUEUE_NEW_ENTRY,
|
||||
PY_FUNC_COUNT
|
||||
|
||||
};
|
||||
@ -353,7 +356,8 @@ typedef struct afl_env_vars {
|
||||
afl_cal_fast, afl_cycle_schedules, afl_expand_havoc;
|
||||
|
||||
u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path,
|
||||
*afl_hang_tmout, *afl_skip_crashes, *afl_preload;
|
||||
*afl_hang_tmout, *afl_forksrv_init_tmout, *afl_skip_crashes, *afl_preload,
|
||||
*afl_max_det_extras;
|
||||
|
||||
} afl_env_vars_t;
|
||||
|
||||
@ -506,7 +510,8 @@ typedef struct afl_state {
|
||||
useless_at_start, /* Number of useless starting paths */
|
||||
var_byte_count, /* Bitmap bytes with var behavior */
|
||||
current_entry, /* Current queue entry ID */
|
||||
havoc_div; /* Cycle count divisor for havoc */
|
||||
havoc_div, /* Cycle count divisor for havoc */
|
||||
max_det_extras; /* deterministic extra count (dicts)*/
|
||||
|
||||
u64 total_crashes, /* Total number of crashes */
|
||||
unique_crashes, /* Crashes with unique signatures */
|
||||
@ -677,6 +682,24 @@ struct custom_mutator {
|
||||
*/
|
||||
void *(*afl_custom_init)(afl_state_t *afl, unsigned int seed);
|
||||
|
||||
/**
|
||||
* This method is called just before fuzzing a queue entry with the custom
|
||||
* mutator, and receives the initial buffer. It should return the number of
|
||||
* fuzzes to perform.
|
||||
*
|
||||
* A value of 0 means no fuzzing of this queue entry.
|
||||
*
|
||||
* The function is now allowed to change the data.
|
||||
*
|
||||
* (Optional)
|
||||
*
|
||||
* @param data pointer returned in afl_custom_init for this fuzz case
|
||||
* @param buf Buffer containing the test case
|
||||
* @param buf_size Size of the test case
|
||||
* @return The amount of fuzzes to perform on this queue entry, 0 = skip
|
||||
*/
|
||||
u32 (*afl_custom_fuzz_count)(void *data, const u8 *buf, size_t buf_size);
|
||||
|
||||
/**
|
||||
* Perform custom mutations on a given input
|
||||
*
|
||||
@ -865,6 +888,7 @@ u8 trim_case_custom(afl_state_t *, struct queue_entry *q, u8 *in_buf,
|
||||
struct custom_mutator *load_custom_mutator_py(afl_state_t *, char *);
|
||||
void finalize_py_module(void *);
|
||||
|
||||
u32 fuzz_count_py(void *, const u8 *, size_t);
|
||||
size_t post_process_py(void *, u8 *, size_t, u8 **);
|
||||
s32 init_trim_py(void *, u8 *, size_t);
|
||||
s32 post_trim_py(void *, u8);
|
||||
@ -1003,7 +1027,18 @@ static inline u32 rand_below(afl_state_t *afl, u32 limit) {
|
||||
|
||||
}
|
||||
|
||||
return rand_next(afl) % limit;
|
||||
/* Modulo is biased - we don't want our fuzzing to be biased so let's do it
|
||||
right. See:
|
||||
https://stackoverflow.com/questions/10984974/why-do-people-say-there-is-modulo-bias-when-using-a-random-number-generator
|
||||
*/
|
||||
u64 unbiased_rnd;
|
||||
do {
|
||||
|
||||
unbiased_rnd = rand_next(afl);
|
||||
|
||||
} while (unlikely(unbiased_rnd >= (UINT64_MAX - (UINT64_MAX % limit))));
|
||||
|
||||
return unbiased_rnd % limit;
|
||||
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,7 @@ static char *afl_environment_variables[] = {
|
||||
"AFL_GCC_INSTRUMENT_FILE",
|
||||
"AFL_GCJ",
|
||||
"AFL_HANG_TMOUT",
|
||||
"AFL_FORKSRV_INIT_TMOUT",
|
||||
"AFL_HARDEN",
|
||||
"AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES",
|
||||
"AFL_IMPORT_FIRST",
|
||||
@ -102,6 +103,7 @@ static char *afl_environment_variables[] = {
|
||||
"AFL_NO_X86", // not really an env but we dont want to warn on it
|
||||
"AFL_MAP_SIZE",
|
||||
"AFL_MAPSIZE",
|
||||
"AFL_MAX_DET_EXTRAS",
|
||||
"AFL_PATH",
|
||||
"AFL_PERFORMANCE_FILE",
|
||||
"AFL_PRELOAD",
|
||||
|
@ -56,6 +56,7 @@ typedef struct afl_forkserver {
|
||||
u8 no_unlink; /* do not unlink cur_input */
|
||||
|
||||
u32 exec_tmout; /* Configurable exec timeout (ms) */
|
||||
u32 init_tmout; /* Configurable init timeout (ms) */
|
||||
u32 map_size; /* map size used by the target */
|
||||
u32 snapshot; /* is snapshot feature used */
|
||||
u64 mem_limit; /* Memory cap for child (MB) */
|
||||
|
@ -28,7 +28,7 @@ all: libdislocator.so
|
||||
|
||||
VPATH = ..
|
||||
libdislocator.so: libdislocator.so.c ../config.h
|
||||
$(CC) $(CFLAGS) -shared -fPIC libdislocator.so.c -o ../$@ $(LDFLAGS)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -shared -fPIC libdislocator.so.c -o ../$@ $(LDFLAGS)
|
||||
|
||||
.NOTPARALLEL: clean
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
PREFIX ?= /usr/local
|
||||
HELPER_PATH = $(PREFIX)/lib/afl
|
||||
DOC_PATH ?= $(PREFIX)/share/doc/afl
|
||||
MAN_PATH ?= $(PREFIX)/man/man8
|
||||
MAN_PATH ?= $(PREFIX)/share/man/man8
|
||||
|
||||
VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2)
|
||||
|
||||
@ -70,7 +70,7 @@ all: $(TARGETS)
|
||||
|
||||
VPATH = ..
|
||||
libtokencap.so: libtokencap.so.c ../config.h
|
||||
$(CC) $(CFLAGS) -shared -fPIC $< -o ../$@ $(LDFLAGS)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -shared -fPIC $< -o ../$@ $(LDFLAGS)
|
||||
|
||||
.NOTPARALLEL: clean
|
||||
|
||||
|
@ -275,8 +275,8 @@ static void __tokencap_load_mappings(void) {
|
||||
|
||||
for (c = map; r > 0; c++, r -= sizeof(prmap_t)) {
|
||||
|
||||
__tokencap_ro[__tokencap_ro_cnt].st = c->pr_vaddr;
|
||||
__tokencap_ro[__tokencap_ro_cnt].en = c->pr_vaddr + c->pr_size;
|
||||
__tokencap_ro[__tokencap_ro_cnt].st = (void *)c->pr_vaddr;
|
||||
__tokencap_ro[__tokencap_ro_cnt].en = (void *)(c->pr_vaddr + c->pr_size);
|
||||
|
||||
if (++__tokencap_ro_cnt == MAX_MAPPINGS) break;
|
||||
|
||||
|
@ -24,10 +24,12 @@ HELPER_PATH ?= $(PREFIX)/lib/afl
|
||||
BIN_PATH ?= $(PREFIX)/bin
|
||||
DOC_PATH ?= $(PREFIX)/share/doc/afl
|
||||
MISC_PATH ?= $(PREFIX)/share/afl
|
||||
MAN_PATH ?= $(PREFIX)/man/man8
|
||||
MAN_PATH ?= $(PREFIX)/share/man/man8
|
||||
|
||||
VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2)
|
||||
|
||||
BUILD_DATE ?= $(shell date -u -d "@$(SOURCE_DATE_EPOCH)" "+%Y-%m-%d" 2>/dev/null || date -u -r "$(SOURCE_DATE_EPOCH)" "+%Y-%m-%d" 2>/dev/null || date -u "+%Y-%m-%d")
|
||||
|
||||
ifeq "$(shell uname)" "OpenBSD"
|
||||
LLVM_CONFIG ?= $(BIN_PATH)/llvm-config
|
||||
HAS_OPT = $(shell test -x $(BIN_PATH)/opt && echo 0 || echo 1)
|
||||
@ -224,7 +226,8 @@ CFLAGS_SAFE := -Wall -g -Wno-pointer-sign -I ../include/ \
|
||||
-DAFL_REAL_LD=\"$(AFL_REAL_LD)\" \
|
||||
-DAFL_CLANG_LDPATH=\"$(AFL_CLANG_LDPATH)\" \
|
||||
-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 \
|
||||
-fdebug-prefix-map="$(CURDIR)=llvm_mode"
|
||||
override CFLAGS += $(CFLAGS_SAFE)
|
||||
|
||||
ifdef AFL_TRACE_PC
|
||||
@ -329,10 +332,10 @@ endif
|
||||
@echo "[+] All set and ready to build."
|
||||
|
||||
afl-common.o: ../src/afl-common.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ $(LDFLAGS)
|
||||
|
||||
../afl-clang-fast: afl-clang-fast.c afl-common.o | test_deps
|
||||
$(CC) $(CLANG_CFL) $(CFLAGS) $< afl-common.o -o $@ $(LDFLAGS) -DCFLAGS_OPT=\"$(CFLAGS_OPT)\"
|
||||
$(CC) $(CLANG_CFL) $(CFLAGS) $(CPPFLAGS) $< afl-common.o -o $@ $(LDFLAGS) -DCFLAGS_OPT=\"$(CFLAGS_OPT)\"
|
||||
ln -sf afl-clang-fast ../afl-clang-fast++
|
||||
ifneq "$(AFL_CLANG_FLTO)" ""
|
||||
ifeq "$(LLVM_LTO)" "1"
|
||||
@ -342,7 +345,7 @@ endif
|
||||
endif
|
||||
|
||||
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) $(CPPFLAGS) `$(LLVM_CONFIG) --cxxflags` -fno-rtti -fPIC -std=$(LLVM_STDCXX) -c $< -o $@
|
||||
|
||||
../libLLVMInsTrim.so: LLVMInsTrim.so.cc MarkNodes.cc afl-llvm-common.o | test_deps
|
||||
-$(CXX) $(CLANG_CPPFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) afl-llvm-common.o
|
||||
@ -360,7 +363,7 @@ endif
|
||||
|
||||
../afl-ld-lto: afl-ld-lto.c
|
||||
ifeq "$(LLVM_LTO)" "1"
|
||||
$(CC) $(CFLAGS) $< -o $@
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $< -o $@
|
||||
endif
|
||||
|
||||
../SanitizerCoverageLTO.so: SanitizerCoverageLTO.so.cc
|
||||
@ -371,9 +374,9 @@ endif
|
||||
../afl-llvm-lto-instrumentation.so: afl-llvm-lto-instrumentation.so.cc afl-llvm-common.o
|
||||
ifeq "$(LLVM_LTO)" "1"
|
||||
$(CXX) $(CLANG_CPPFL) -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.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_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_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
|
||||
$(CLANG_BIN) $(CFLAGS_SAFE) $(CPPFLAGS) -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) $(CPPFLAGS) -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) $(CPPFLAGS) -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
|
||||
|
||||
# laf
|
||||
@ -392,20 +395,20 @@ endif
|
||||
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) afl-llvm-common.o
|
||||
|
||||
document:
|
||||
$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS_SAFE) $(CLANG_CFL) -O3 -Wno-unused-result -fPIC -c afl-llvm-rt.o.c -o ../afl-llvm-rt.o
|
||||
@$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS_SAFE) $(CLANG_CFL) -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_SAFE) $(CLANG_CFL) -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
|
||||
$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS_SAFE) $(CPPFLAGS) $(CLANG_CFL) -O3 -Wno-unused-result -fPIC -c afl-llvm-rt.o.c -o ../afl-llvm-rt.o
|
||||
@$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS_SAFE) $(CPPFLAGS) $(CLANG_CFL) -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_SAFE) $(CPPFLAGS) $(CLANG_CFL) -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
|
||||
$(CLANG_BIN) $(CLANG_CFL) $(CFLAGS_SAFE) -O3 -Wno-unused-result -fPIC -c $< -o $@
|
||||
$(CLANG_BIN) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -fPIC -c $< -o $@
|
||||
|
||||
../afl-llvm-rt-32.o: afl-llvm-rt.o.c | test_deps
|
||||
@printf "[*] Building 32-bit variant of the runtime (-m32)... "
|
||||
@$(CLANG_BIN) $(CLANG_CFL) $(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
|
||||
@$(CLANG_BIN) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
|
||||
|
||||
../afl-llvm-rt-64.o: afl-llvm-rt.o.c | test_deps
|
||||
@printf "[*] Building 64-bit variant of the runtime (-m64)... "
|
||||
@$(CLANG_BIN) $(CLANG_CFL) $(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
|
||||
@$(CLANG_BIN) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
|
||||
|
||||
test_build: $(PROGS)
|
||||
@echo "[*] Testing the CC wrapper and instrumentation output..."
|
||||
@ -434,15 +437,16 @@ install: all
|
||||
if [ -f ../cmplog-instructions-pass.so ]; then set -e; install -m 755 ../cmplog-*-pass.so $${DESTDIR}$(HELPER_PATH); fi
|
||||
if [ -f ../SanitizerCoverageLTO.so ]; then set -e; install -m 755 ../SanitizerCoverageLTO.so $${DESTDIR}$(HELPER_PATH); fi
|
||||
set -e; install -m 644 ../dynamic_list.txt $${DESTDIR}$(HELPER_PATH)
|
||||
set -e; if [ -f ../afl-clang-fast ] ; then ln -sf ../afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf ../afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang++ ; else ln -sf ../afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf ../afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang++; fi
|
||||
set -e; if [ -f ../afl-clang-fast ] ; then ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang++ ; else ln -sf afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang++; fi
|
||||
install -m 644 README.*.md $${DESTDIR}$(DOC_PATH)/
|
||||
install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.llvm_mode.md
|
||||
install -m 644 README.md $${DESTDIR}$(DOC_PATH)/README.llvm_mode.md
|
||||
|
||||
vpath % ..
|
||||
%.8: %
|
||||
@echo .TH $* 8 `date "+%Y-%m-%d"` "afl++" > ../$@
|
||||
@echo .TH $* 8 $(BUILD_DATE) "afl++" > ../$@
|
||||
@echo .SH NAME >> ../$@
|
||||
@echo .B $* >> ../$@
|
||||
@echo -n ".B $* \- " >> ../$@
|
||||
@../$* -h 2>&1 | head -n 1 | sed -e "s/$$(printf '\e')[^m]*m//g" >> ../$@
|
||||
@echo >> ../$@
|
||||
@echo .SH SYNOPSIS >> ../$@
|
||||
@../$* -h 2>&1 | head -n 3 | tail -n 1 | sed 's/^\.\///' >> ../$@
|
||||
|
@ -243,7 +243,7 @@ struct InsTrim : public ModulePass {
|
||||
for (unsigned I = 0; I < PrevLocSize - 1; ++I)
|
||||
PrevLocShuffle.push_back(ConstantInt::get(Int32Ty, I));
|
||||
|
||||
for (unsigned I = PrevLocSize; I < PrevLocVecSize; ++I)
|
||||
for (int I = PrevLocSize; I < PrevLocVecSize; ++I)
|
||||
PrevLocShuffle.push_back(ConstantInt::get(Int32Ty, PrevLocSize));
|
||||
|
||||
Constant *PrevLocShuffleMask = ConstantVector::get(PrevLocShuffle);
|
||||
|
@ -437,8 +437,6 @@ bool ModuleSanitizerCoverage::instrumentModule(
|
||||
if ((afl_global_id = atoi(ptr)) < 0)
|
||||
FATAL("AFL_LLVM_LTO_STARTID value of \"%s\" is negative\n", ptr);
|
||||
|
||||
if (getenv("AFL_LLVM_CMPLOG")) autodictionary = 0;
|
||||
|
||||
if ((ptr = getenv("AFL_LLVM_DOCUMENT_IDS")) != NULL) {
|
||||
|
||||
if ((documentFile = fopen(ptr, "a")) == NULL)
|
||||
|
@ -670,9 +670,11 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
||||
|
||||
}
|
||||
|
||||
#ifndef __APPLE__
|
||||
if (!shared_linking)
|
||||
cc_params[cc_par_cnt++] =
|
||||
alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@ -811,13 +813,25 @@ int main(int argc, char **argv, char **envp) {
|
||||
if (strncasecmp(ptr, "ngram", strlen("ngram")) == 0) {
|
||||
|
||||
ptr += strlen("ngram");
|
||||
while (*ptr && (*ptr < '0' || *ptr > '9'))
|
||||
while (*ptr && (*ptr < '0' || *ptr > '9')) {
|
||||
|
||||
ptr++;
|
||||
if (!*ptr)
|
||||
if ((ptr = getenv("AFL_LLVM_NGRAM_SIZE")) != NULL)
|
||||
|
||||
}
|
||||
|
||||
if (!*ptr) {
|
||||
|
||||
ptr = getenv("AFL_LLVM_NGRAM_SIZE");
|
||||
if (!ptr || !*ptr) {
|
||||
|
||||
FATAL(
|
||||
"you must set the NGRAM size with (e.g. for value 2) "
|
||||
"AFL_LLVM_INSTRUMENT=ngram-2");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ngram_size = atoi(ptr);
|
||||
if (ngram_size < 2 || ngram_size > NGRAM_SIZE_MAX)
|
||||
FATAL(
|
||||
|
@ -344,9 +344,10 @@ static std::string getSourceName(llvm::Function *F) {
|
||||
(LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7)
|
||||
if (Loc) {
|
||||
|
||||
StringRef instFilename;
|
||||
DILocation *cDILoc = dyn_cast<DILocation>(Loc.getAsMDNode());
|
||||
|
||||
StringRef instFilename = cDILoc->getFilename();
|
||||
if (cDILoc) { instFilename = cDILoc->getFilename(); }
|
||||
|
||||
if (instFilename.str().empty()) {
|
||||
|
||||
|
@ -87,7 +87,7 @@ class AFLLTOPass : public ModulePass {
|
||||
bool runOnModule(Module &M) override;
|
||||
|
||||
protected:
|
||||
int afl_global_id = 1, autodictionary = 0;
|
||||
int afl_global_id = 1, autodictionary = 1;
|
||||
uint32_t function_minimum_size = 1;
|
||||
uint32_t inst_blocks = 0, inst_funcs = 0, total_instr = 0;
|
||||
uint64_t map_addr = 0x10000;
|
||||
@ -128,8 +128,6 @@ bool AFLLTOPass::runOnModule(Module &M) {
|
||||
|
||||
be_quiet = 1;
|
||||
|
||||
if (getenv("AFL_LLVM_CMPLOG")) autodictionary = 0;
|
||||
|
||||
if ((ptr = getenv("AFL_LLVM_DOCUMENT_IDS")) != NULL) {
|
||||
|
||||
if ((documentFile = fopen(ptr, "a")) == NULL)
|
||||
@ -137,8 +135,6 @@ bool AFLLTOPass::runOnModule(Module &M) {
|
||||
|
||||
}
|
||||
|
||||
if (getenv("AFL_LLVM_LTO_AUTODICTIONARY")) autodictionary = 1;
|
||||
|
||||
// we make this the default as the fixed map has problems with
|
||||
// defered forkserver, early constructors, ifuncs and maybe more
|
||||
/*if (getenv("AFL_LLVM_MAP_DYNAMIC"))*/
|
||||
@ -378,16 +374,29 @@ bool AFLLTOPass::runOnModule(Module &M) {
|
||||
std::string Str1, Str2;
|
||||
StringRef TmpStr;
|
||||
bool HasStr1 = getConstantStringInfo(Str1P, TmpStr);
|
||||
if (TmpStr.empty())
|
||||
if (TmpStr.empty()) {
|
||||
|
||||
HasStr1 = false;
|
||||
else
|
||||
|
||||
} else {
|
||||
|
||||
HasStr1 = true;
|
||||
Str1 = TmpStr.str();
|
||||
|
||||
}
|
||||
|
||||
bool HasStr2 = getConstantStringInfo(Str2P, TmpStr);
|
||||
if (TmpStr.empty())
|
||||
if (TmpStr.empty()) {
|
||||
|
||||
HasStr2 = false;
|
||||
else
|
||||
|
||||
} else {
|
||||
|
||||
HasStr2 = true;
|
||||
Str2 = TmpStr.str();
|
||||
|
||||
}
|
||||
|
||||
if (debug)
|
||||
fprintf(stderr, "F:%s %p(%s)->\"%s\"(%s) %p(%s)->\"%s\"(%s)\n",
|
||||
FuncName.c_str(), Str1P, Str1P->getName().str().c_str(),
|
||||
|
@ -284,7 +284,7 @@ bool AFLCoverage::runOnModule(Module &M) {
|
||||
for (unsigned I = 0; I < PrevLocSize - 1; ++I)
|
||||
PrevLocShuffle.push_back(ConstantInt::get(Int32Ty, I));
|
||||
|
||||
for (unsigned I = PrevLocSize; I < PrevLocVecSize; ++I)
|
||||
for (int I = PrevLocSize; I < PrevLocVecSize; ++I)
|
||||
PrevLocShuffle.push_back(ConstantInt::get(Int32Ty, PrevLocSize));
|
||||
|
||||
Constant *PrevLocShuffleMask = ConstantVector::get(PrevLocShuffle);
|
||||
|
@ -339,7 +339,7 @@ static void __afl_map_shm(void) {
|
||||
|
||||
if (__afl_area_ptr == MAP_FAILED) {
|
||||
|
||||
fprintf(stderr, "can not aquire mmap for address %p\n",
|
||||
fprintf(stderr, "can not acquire mmap for address %p\n",
|
||||
(void *)__afl_map_addr);
|
||||
exit(1);
|
||||
|
||||
|
@ -1272,7 +1272,7 @@ bool SplitComparesTransform::runOnModule(Module &M) {
|
||||
if (!be_quiet) {
|
||||
|
||||
errs() << "Split-floatingpoint-compare-pass: " << count
|
||||
<< " FP comparisons splitted\n";
|
||||
<< " FP comparisons split\n";
|
||||
|
||||
}
|
||||
|
||||
@ -1290,7 +1290,7 @@ bool SplitComparesTransform::runOnModule(Module &M) {
|
||||
count = splitIntCompares(M, bitw);
|
||||
if (!be_quiet)
|
||||
errs() << "Split-integer-compare-pass " << bitw << "bit: " << count
|
||||
<< " splitted\n";
|
||||
<< " split\n";
|
||||
|
||||
bitw >>= 1;
|
||||
#if LLVM_VERSION_MAJOR > 3 || \
|
||||
@ -1301,7 +1301,7 @@ bool SplitComparesTransform::runOnModule(Module &M) {
|
||||
count = splitIntCompares(M, bitw);
|
||||
if (!be_quiet)
|
||||
errs() << "Split-integer-compare-pass " << bitw << "bit: " << count
|
||||
<< " splitted\n";
|
||||
<< " split\n";
|
||||
|
||||
bitw >>= 1;
|
||||
#if LLVM_VERSION_MAJOR > 3 || \
|
||||
@ -1312,7 +1312,7 @@ bool SplitComparesTransform::runOnModule(Module &M) {
|
||||
count = splitIntCompares(M, bitw);
|
||||
if (!be_quiet)
|
||||
errs() << "Split-integer-compare-pass " << bitw << "bit: " << count
|
||||
<< " splitted\n";
|
||||
<< " split\n";
|
||||
|
||||
bitw >>= 1;
|
||||
break;
|
||||
|
@ -16,7 +16,7 @@
|
||||
PREFIX ?= /usr/local
|
||||
HELPER_PATH = $(PREFIX)/lib/afl
|
||||
DOC_PATH ?= $(PREFIX)/share/doc/afl
|
||||
MAN_PATH ?= $(PREFIX)/man/man8
|
||||
MAN_PATH ?= $(PREFIX)/share/man/man8
|
||||
|
||||
VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2)
|
||||
|
||||
|
@ -152,7 +152,7 @@ static void edit_params(int argc, char **argv) {
|
||||
|
||||
/* The Apple case is a bit different... */
|
||||
|
||||
if (!strcmp(argv[i], "-arch") && i + 1 < argc) {
|
||||
if (!strcmp(argv[i], "-arch") && i + 1 < (u32)argc) {
|
||||
|
||||
if (!strcmp(argv[i + 1], "x86_64"))
|
||||
use_64bit = 1;
|
||||
|
@ -79,6 +79,7 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) {
|
||||
fsrv->use_stdin = 1;
|
||||
fsrv->no_unlink = 0;
|
||||
fsrv->exec_tmout = EXEC_TIMEOUT;
|
||||
fsrv->init_tmout = EXEC_TIMEOUT * FORK_WAIT_MULT;
|
||||
fsrv->mem_limit = MEM_LIMIT;
|
||||
fsrv->out_file = NULL;
|
||||
|
||||
@ -101,6 +102,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) {
|
||||
fsrv_to->out_fd = from->out_fd;
|
||||
fsrv_to->dev_null_fd = from->dev_null_fd;
|
||||
fsrv_to->exec_tmout = from->exec_tmout;
|
||||
fsrv_to->init_tmout = from->init_tmout;
|
||||
fsrv_to->mem_limit = from->mem_limit;
|
||||
fsrv_to->map_size = from->map_size;
|
||||
fsrv_to->support_shmem_fuzz = from->support_shmem_fuzz;
|
||||
@ -115,6 +117,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) {
|
||||
fsrv_to->out_file = NULL;
|
||||
|
||||
fsrv_to->init_child_func = fsrv_exec_child;
|
||||
// Note: do not copy ->add_extra_func
|
||||
|
||||
list_append(&fsrv_list, fsrv_to);
|
||||
|
||||
@ -516,15 +519,14 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
||||
rlen = 0;
|
||||
if (fsrv->exec_tmout) {
|
||||
|
||||
u32 time_ms =
|
||||
read_s32_timed(fsrv->fsrv_st_fd, &status,
|
||||
fsrv->exec_tmout * FORK_WAIT_MULT, stop_soon_p);
|
||||
u32 time_ms = read_s32_timed(fsrv->fsrv_st_fd, &status, fsrv->init_tmout,
|
||||
stop_soon_p);
|
||||
|
||||
if (!time_ms) {
|
||||
|
||||
kill(fsrv->fsrv_pid, SIGKILL);
|
||||
|
||||
} else if (time_ms > fsrv->exec_tmout * FORK_WAIT_MULT) {
|
||||
} else if (time_ms > fsrv->init_tmout) {
|
||||
|
||||
fsrv->last_run_timed_out = 1;
|
||||
kill(fsrv->fsrv_pid, SIGKILL);
|
||||
@ -632,7 +634,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
||||
|
||||
if (fsrv->add_extra_func == NULL || fsrv->afl_ptr == NULL) {
|
||||
|
||||
// this is not afl-fuzz - we deny and return
|
||||
// this is not afl-fuzz - or it is cmplog - we deny and return
|
||||
if (fsrv->use_shmem_fuzz) {
|
||||
|
||||
status = (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ);
|
||||
@ -939,7 +941,7 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) {
|
||||
|
||||
s32 fd = fsrv->out_fd;
|
||||
|
||||
if (fsrv->out_file) {
|
||||
if (!fsrv->use_stdin) {
|
||||
|
||||
if (fsrv->no_unlink) {
|
||||
|
||||
@ -962,7 +964,7 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) {
|
||||
|
||||
ck_write(fd, buf, len, fsrv->out_file);
|
||||
|
||||
if (!fsrv->out_file) {
|
||||
if (fsrv->use_stdin) {
|
||||
|
||||
if (ftruncate(fd, len)) { PFATAL("ftruncate() failed"); }
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
|
@ -248,10 +248,10 @@ static void extras_check_and_sort(afl_state_t *afl, u32 min_len, u32 max_len,
|
||||
|
||||
}
|
||||
|
||||
if (afl->extras_cnt > MAX_DET_EXTRAS) {
|
||||
if (afl->extras_cnt > afl->max_det_extras) {
|
||||
|
||||
WARNF("More than %d tokens - will use them probabilistically.",
|
||||
MAX_DET_EXTRAS);
|
||||
OKF("More than %d tokens - will use them probabilistically.",
|
||||
afl->max_det_extras);
|
||||
|
||||
}
|
||||
|
||||
@ -319,8 +319,8 @@ void load_extras(afl_state_t *afl, u8 *dir) {
|
||||
|
||||
if (st.st_size > MAX_DICT_FILE) {
|
||||
|
||||
FATAL(
|
||||
"Extra '%s' is too big (%s, limit is %s)", fn,
|
||||
WARNF(
|
||||
"Extra '%s' is very big (%s, limit is %s)", fn,
|
||||
stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), st.st_size),
|
||||
stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE));
|
||||
|
||||
@ -370,14 +370,14 @@ static inline u8 memcmp_nocase(u8 *m1, u8 *m2, u32 len) {
|
||||
|
||||
}
|
||||
|
||||
/* Adds a new extra / dict entry. */
|
||||
/* Adds a new extra / dict entry. Used for LTO autodict. */
|
||||
void add_extra(afl_state_t *afl, u8 *mem, u32 len) {
|
||||
|
||||
u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX];
|
||||
|
||||
if (len > MAX_DICT_FILE) {
|
||||
|
||||
FATAL("Extra '%.*s' is too big (%s, limit is %s)", (int)len, mem,
|
||||
WARNF("Extra '%.*s' is very big (%s, limit is %s)", (int)len, mem,
|
||||
stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), len),
|
||||
stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE));
|
||||
|
||||
@ -403,10 +403,10 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) {
|
||||
|
||||
/* We only want to print this once */
|
||||
|
||||
if (afl->extras_cnt == MAX_DET_EXTRAS + 1) {
|
||||
if (afl->extras_cnt == afl->max_det_extras + 1) {
|
||||
|
||||
WARNF("More than %d tokens - will use them probabilistically.",
|
||||
MAX_DET_EXTRAS);
|
||||
OKF("More than %d tokens - will use them probabilistically.",
|
||||
afl->max_det_extras);
|
||||
|
||||
}
|
||||
|
||||
|
@ -256,18 +256,18 @@ void bind_to_free_cpu(afl_state_t *afl) {
|
||||
|
||||
}
|
||||
|
||||
for (i = 0; i < proccount; i++) {
|
||||
for (i = 0; i < (s32)proccount; i++) {
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
|
||||
if (!strcmp(procs[i].ki_comm, "idle")) continue;
|
||||
|
||||
// fix when ki_oncpu = -1
|
||||
int oncpu;
|
||||
s32 oncpu;
|
||||
oncpu = procs[i].ki_oncpu;
|
||||
if (oncpu == -1) oncpu = procs[i].ki_lastcpu;
|
||||
|
||||
if (oncpu != -1 && oncpu < sizeof(cpu_used) && procs[i].ki_pctcpu > 60)
|
||||
if (oncpu != -1 && oncpu < (s32)sizeof(cpu_used) && procs[i].ki_pctcpu > 60)
|
||||
cpu_used[oncpu] = 1;
|
||||
|
||||
#elif defined(__DragonFly__)
|
||||
@ -1841,24 +1841,26 @@ void setup_cmdline_file(afl_state_t *afl, char **argv) {
|
||||
|
||||
void setup_stdio_file(afl_state_t *afl) {
|
||||
|
||||
u8 *fn;
|
||||
if (afl->file_extension) {
|
||||
|
||||
fn = alloc_printf("%s/.cur_input.%s", afl->tmp_dir, afl->file_extension);
|
||||
afl->fsrv.out_file =
|
||||
alloc_printf("%s/.cur_input.%s", afl->tmp_dir, afl->file_extension);
|
||||
|
||||
} else {
|
||||
|
||||
fn = alloc_printf("%s/.cur_input", afl->tmp_dir);
|
||||
afl->fsrv.out_file = alloc_printf("%s/.cur_input", afl->tmp_dir);
|
||||
|
||||
}
|
||||
|
||||
unlink(fn); /* Ignore errors */
|
||||
unlink(afl->fsrv.out_file); /* Ignore errors */
|
||||
|
||||
afl->fsrv.out_fd = open(fn, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||
afl->fsrv.out_fd = open(afl->fsrv.out_file, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||
|
||||
if (afl->fsrv.out_fd < 0) { PFATAL("Unable to create '%s'", fn); }
|
||||
if (afl->fsrv.out_fd < 0) {
|
||||
|
||||
ck_free(fn);
|
||||
PFATAL("Unable to create '%s'", afl->fsrv.out_file);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -166,6 +166,11 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) {
|
||||
|
||||
}
|
||||
|
||||
/* "afl_custom_fuzz_count", optional */
|
||||
mutator->afl_custom_fuzz_count = dlsym(dh, "afl_custom_fuzz_count");
|
||||
if (!mutator->afl_custom_fuzz_count)
|
||||
ACTF("optional symbol 'afl_custom_fuzz_count' not found.");
|
||||
|
||||
/* "afl_custom_deinit", optional for backward compatibility */
|
||||
mutator->afl_custom_deinit = dlsym(dh, "afl_custom_deinit");
|
||||
if (!mutator->afl_custom_deinit)
|
||||
|
@ -1509,13 +1509,13 @@ skip_interest:
|
||||
|
||||
for (j = 0; j < afl->extras_cnt; ++j) {
|
||||
|
||||
/* Skip extras probabilistically if afl->extras_cnt > MAX_DET_EXTRAS. Also
|
||||
skip them if there's no room to insert the payload, if the token
|
||||
/* Skip extras probabilistically if afl->extras_cnt > AFL_MAX_DET_EXTRAS.
|
||||
Also skip them if there's no room to insert the payload, if the token
|
||||
is redundant, or if its entire span has no bytes set in the effector
|
||||
map. */
|
||||
|
||||
if ((afl->extras_cnt > MAX_DET_EXTRAS &&
|
||||
rand_below(afl, afl->extras_cnt) >= MAX_DET_EXTRAS) ||
|
||||
if ((afl->extras_cnt > afl->max_det_extras &&
|
||||
rand_below(afl, afl->extras_cnt) >= afl->max_det_extras) ||
|
||||
afl->extras[j].len > len - i ||
|
||||
!memcmp(afl->extras[j].data, out_buf + i, afl->extras[j].len) ||
|
||||
!memchr(eff_map + EFF_APOS(i), 1,
|
||||
@ -1672,7 +1672,7 @@ custom_mutator_stage:
|
||||
|
||||
if (afl->stage_max < HAVOC_MIN) { afl->stage_max = HAVOC_MIN; }
|
||||
|
||||
const u32 max_seed_size = MAX_FILE;
|
||||
const u32 max_seed_size = MAX_FILE, saved_max = afl->stage_max;
|
||||
|
||||
orig_hit_cnt = afl->queued_paths + afl->unique_crashes;
|
||||
|
||||
@ -1680,10 +1680,17 @@ custom_mutator_stage:
|
||||
|
||||
if (el->afl_custom_fuzz) {
|
||||
|
||||
if (el->afl_custom_fuzz_count)
|
||||
afl->stage_max = el->afl_custom_fuzz_count(el->data, out_buf, len);
|
||||
else
|
||||
afl->stage_max = saved_max;
|
||||
|
||||
has_custom_fuzz = true;
|
||||
|
||||
afl->stage_short = el->name_short;
|
||||
|
||||
if (afl->stage_max) {
|
||||
|
||||
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max;
|
||||
++afl->stage_cur) {
|
||||
|
||||
@ -1729,7 +1736,11 @@ custom_mutator_stage:
|
||||
|
||||
/* Read the additional testcase into a new buffer. */
|
||||
fd = open(target->fname, O_RDONLY);
|
||||
if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", target->fname); }
|
||||
if (unlikely(fd < 0)) {
|
||||
|
||||
PFATAL("Unable to open '%s'", target->fname);
|
||||
|
||||
}
|
||||
|
||||
new_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), target->len);
|
||||
if (unlikely(!new_buf)) { PFATAL("alloc"); }
|
||||
@ -1756,6 +1767,8 @@ custom_mutator_stage:
|
||||
|
||||
}
|
||||
|
||||
if (!el->afl_custom_fuzz_count) {
|
||||
|
||||
/* If we're finding new stuff, let's run for a bit longer, limits
|
||||
permitting. */
|
||||
|
||||
@ -1774,8 +1787,12 @@ custom_mutator_stage:
|
||||
|
||||
}
|
||||
|
||||
/* `(afl->)out_buf` may have been changed by the call to custom_fuzz */
|
||||
/* TODO: Only do this when `mutated_buf` == `out_buf`? Branch vs Memcpy.
|
||||
}
|
||||
|
||||
/* `(afl->)out_buf` may have been changed by the call to custom_fuzz
|
||||
*/
|
||||
/* TODO: Only do this when `mutated_buf` == `out_buf`? Branch vs
|
||||
* Memcpy.
|
||||
*/
|
||||
memcpy(out_buf, in_buf, len);
|
||||
|
||||
@ -1783,6 +1800,8 @@ custom_mutator_stage:
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
if (!has_custom_fuzz) goto havoc_stage;
|
||||
@ -3722,13 +3741,13 @@ skip_interest:
|
||||
|
||||
for (j = 0; j < afl->extras_cnt; ++j) {
|
||||
|
||||
/* Skip extras probabilistically if afl->extras_cnt > MAX_DET_EXTRAS. Also
|
||||
skip them if there's no room to insert the payload, if the token
|
||||
/* Skip extras probabilistically if afl->extras_cnt > AFL_MAX_DET_EXTRAS.
|
||||
Also skip them if there's no room to insert the payload, if the token
|
||||
is redundant, or if its entire span has no bytes set in the effector
|
||||
map. */
|
||||
|
||||
if ((afl->extras_cnt > MAX_DET_EXTRAS &&
|
||||
rand_below(afl, afl->extras_cnt) >= MAX_DET_EXTRAS) ||
|
||||
if ((afl->extras_cnt > afl->max_det_extras &&
|
||||
rand_below(afl, afl->extras_cnt) >= afl->max_det_extras) ||
|
||||
afl->extras[j].len > len - i ||
|
||||
!memcmp(afl->extras[j].data, out_buf + i, afl->extras[j].len) ||
|
||||
!memchr(eff_map + EFF_APOS(i), 1,
|
||||
|
@ -144,6 +144,8 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) {
|
||||
py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "fuzz");
|
||||
if (!py_functions[PY_FUNC_FUZZ])
|
||||
py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "mutate");
|
||||
py_functions[PY_FUNC_FUZZ_COUNT] =
|
||||
PyObject_GetAttrString(py_module, "fuzz_count");
|
||||
if (!py_functions[PY_FUNC_FUZZ])
|
||||
WARNF("fuzz function not found in python module");
|
||||
py_functions[PY_FUNC_POST_PROCESS] =
|
||||
@ -169,27 +171,20 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) {
|
||||
|
||||
if (!py_functions[py_idx] || !PyCallable_Check(py_functions[py_idx])) {
|
||||
|
||||
if (py_idx == PY_FUNC_POST_PROCESS) {
|
||||
|
||||
// Implenting the post_process API is optional for now
|
||||
if (PyErr_Occurred()) { PyErr_Print(); }
|
||||
|
||||
} else if (py_idx >= PY_FUNC_INIT_TRIM && py_idx <= PY_FUNC_TRIM) {
|
||||
if (py_idx >= PY_FUNC_INIT_TRIM && py_idx <= PY_FUNC_TRIM) {
|
||||
|
||||
// Implementing the trim API is optional for now
|
||||
if (PyErr_Occurred()) { PyErr_Print(); }
|
||||
py_notrim = 1;
|
||||
|
||||
} else if ((py_idx >= PY_FUNC_HAVOC_MUTATION) &&
|
||||
} else if (py_idx >= PY_OPTIONAL) {
|
||||
|
||||
(py_idx <= PY_FUNC_QUEUE_NEW_ENTRY)) {
|
||||
// Only _init and _deinit are not optional currently
|
||||
|
||||
// Implenting the havoc and queue API is optional for now
|
||||
if (PyErr_Occurred()) { PyErr_Print(); }
|
||||
|
||||
} else {
|
||||
|
||||
if (PyErr_Occurred()) { PyErr_Print(); }
|
||||
fprintf(stderr,
|
||||
"Cannot find/call function with index %d in external "
|
||||
"Python module.\n",
|
||||
@ -347,6 +342,12 @@ struct custom_mutator *load_custom_mutator_py(afl_state_t *afl,
|
||||
|
||||
}
|
||||
|
||||
if (py_functions[PY_FUNC_FUZZ_COUNT]) {
|
||||
|
||||
mutator->afl_custom_fuzz_count = fuzz_count_py;
|
||||
|
||||
}
|
||||
|
||||
if (py_functions[PY_FUNC_POST_TRIM]) {
|
||||
|
||||
mutator->afl_custom_post_trim = post_trim_py;
|
||||
@ -477,6 +478,44 @@ s32 init_trim_py(void *py_mutator, u8 *buf, size_t buf_size) {
|
||||
|
||||
}
|
||||
|
||||
u32 fuzz_count_py(void *py_mutator, const u8 *buf, size_t buf_size) {
|
||||
|
||||
PyObject *py_args, *py_value;
|
||||
|
||||
py_args = PyTuple_New(1);
|
||||
py_value = PyByteArray_FromStringAndSize(buf, buf_size);
|
||||
if (!py_value) {
|
||||
|
||||
Py_DECREF(py_args);
|
||||
FATAL("Failed to convert arguments");
|
||||
|
||||
}
|
||||
|
||||
PyTuple_SetItem(py_args, 0, py_value);
|
||||
|
||||
py_value = PyObject_CallObject(
|
||||
((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_FUZZ_COUNT], py_args);
|
||||
Py_DECREF(py_args);
|
||||
|
||||
if (py_value != NULL) {
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
u32 retcnt = (u32)PyLong_AsLong(py_value);
|
||||
#else
|
||||
u32 retcnt = PyInt_AsLong(py_value);
|
||||
#endif
|
||||
Py_DECREF(py_value);
|
||||
return retcnt;
|
||||
|
||||
} else {
|
||||
|
||||
PyErr_Print();
|
||||
FATAL("Call failed");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
s32 post_trim_py(void *py_mutator, u8 success) {
|
||||
|
||||
PyObject *py_args, *py_value;
|
||||
|
@ -349,6 +349,20 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
|
||||
afl->afl_env.afl_preload =
|
||||
(u8 *)get_afl_env(afl_environment_variables[i]);
|
||||
|
||||
} else if (!strncmp(env, "AFL_MAX_DET_EXTRAS",
|
||||
|
||||
afl_environment_variable_len)) {
|
||||
|
||||
afl->afl_env.afl_max_det_extras =
|
||||
(u8 *)get_afl_env(afl_environment_variables[i]);
|
||||
|
||||
} else if (!strncmp(env, "AFL_FORKSRV_INIT_TMOUT",
|
||||
|
||||
afl_environment_variable_len)) {
|
||||
|
||||
afl->afl_env.afl_forksrv_init_tmout =
|
||||
(u8 *)get_afl_env(afl_environment_variables[i]);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -173,10 +173,14 @@ static void usage(u8 *argv0, int more_help) {
|
||||
"AFL_FAST_CAL: limit the calibration stage to three cycles for speedup\n"
|
||||
"AFL_FORCE_UI: force showing the status screen (for virtual consoles)\n"
|
||||
"AFL_HANG_TMOUT: override timeout value (in milliseconds)\n"
|
||||
"AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in milliseconds)\n"
|
||||
"AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: don't warn about core dump handlers\n"
|
||||
"AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n"
|
||||
"AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n"
|
||||
" the target was compiled for\n"
|
||||
"AFL_MAX_DET_EXTRAS: if more entries are in the dictionary list than this value\n"
|
||||
" then they are randomly selected instead all of them being\n"
|
||||
" used. Defaults to 200.\n"
|
||||
"AFL_NO_AFFINITY: do not check for an unused cpu core to use for fuzzing\n"
|
||||
"AFL_NO_ARITH: skip arithmetic mutations in deterministic stage\n"
|
||||
"AFL_NO_CPU_RED: avoid red color for showing very high cpu usage\n"
|
||||
@ -188,7 +192,7 @@ static void usage(u8 *argv0, int more_help) {
|
||||
"AFL_QUIET: suppress forkserver status messages\n"
|
||||
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
|
||||
"AFL_SHUFFLE_QUEUE: reorder the input queue randomly on startup\n"
|
||||
"AFL_SKIP_BIN_CHECK: skip the check, if the target is an excutable\n"
|
||||
"AFL_SKIP_BIN_CHECK: skip the check, if the target is an executable\n"
|
||||
"AFL_SKIP_CPUFREQ: do not warn about variable cpu clocking\n"
|
||||
"AFL_SKIP_CRASHES: during initial dry run do not terminate for crashing inputs\n"
|
||||
"AFL_TMPDIR: directory to use for input file generation (ramdisk recommended)\n"
|
||||
@ -949,8 +953,36 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
if (afl->afl_env.afl_hang_tmout) {
|
||||
|
||||
afl->hang_tmout = atoi(afl->afl_env.afl_hang_tmout);
|
||||
if (!afl->hang_tmout) { FATAL("Invalid value of AFL_HANG_TMOUT"); }
|
||||
s32 hang_tmout = atoi(afl->afl_env.afl_hang_tmout);
|
||||
if (hang_tmout < 1) { FATAL("Invalid value for AFL_HANG_TMOUT"); }
|
||||
afl->hang_tmout = (u32)hang_tmout;
|
||||
|
||||
}
|
||||
|
||||
if (afl->afl_env.afl_max_det_extras) {
|
||||
|
||||
s32 max_det_extras = atoi(afl->afl_env.afl_max_det_extras);
|
||||
if (max_det_extras < 1) { FATAL("Invalid value for AFL_MAX_DET_EXTRAS"); }
|
||||
afl->max_det_extras = (u32)max_det_extras;
|
||||
|
||||
} else {
|
||||
|
||||
afl->max_det_extras = MAX_DET_EXTRAS;
|
||||
|
||||
}
|
||||
|
||||
if (afl->afl_env.afl_forksrv_init_tmout) {
|
||||
|
||||
afl->fsrv.init_tmout = atoi(afl->afl_env.afl_forksrv_init_tmout);
|
||||
if (!afl->fsrv.init_tmout) {
|
||||
|
||||
FATAL("Invalid value of AFL_FORKSRV_INIT_TMOUT");
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
afl->fsrv.init_tmout = afl->fsrv.exec_tmout * FORK_WAIT_MULT;
|
||||
|
||||
}
|
||||
|
||||
|
@ -415,7 +415,7 @@ int main(int argc, char **argv) {
|
||||
"AFL_KEEP_ASSEMBLY: leave instrumented assembly files\n"
|
||||
"AFL_AS_FORCE_INSTRUMENT: force instrumentation for asm sources\n";
|
||||
|
||||
if (argc == 2 && strcmp(argv[1], "-h") == 0) {
|
||||
if (argc == 2 && strncmp(argv[1], "-h", 2) == 0) {
|
||||
|
||||
printf("afl-cc" VERSION " by Michal Zalewski\n\n");
|
||||
printf("%s \n\n", argv[0]);
|
||||
|
@ -72,12 +72,12 @@ void jump(afl_state_t *afl) {
|
||||
|
||||
static const uint64_t JUMP[] = {0x180ec6d33cfd0aba, 0xd5a61266f0c9392c,
|
||||
0xa9582618e03fc9aa, 0x39abdc4529b1661c};
|
||||
int i, b;
|
||||
size_t 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 (i = 0; i < (sizeof(JUMP) / sizeof(*JUMP)); i++)
|
||||
for (b = 0; b < 64; b++) {
|
||||
|
||||
if (JUMP[i] & UINT64_C(1) << b) {
|
||||
@ -110,12 +110,12 @@ void long_jump(afl_state_t *afl) {
|
||||
static const uint64_t LONG_JUMP[] = {0x76e15d3efefdcbbf, 0xc5004e441c522fb3,
|
||||
0x77710069854ee241, 0x39109bb02acbe635};
|
||||
|
||||
int i, b;
|
||||
size_t 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 (i = 0; i < (sizeof(LONG_JUMP) / sizeof(*LONG_JUMP)); i++)
|
||||
for (b = 0; b < 64; b++) {
|
||||
|
||||
if (LONG_JUMP[i] & UINT64_C(1) << b) {
|
||||
@ -145,7 +145,7 @@ void long_jump(afl_state_t *afl) {
|
||||
u32 hash32(u8 *key, u32 len, u32 seed) {
|
||||
|
||||
#else
|
||||
u32 inline hash32(u8 *key, u32 len, u32 seed) {
|
||||
inline u32 hash32(u8 *key, u32 len, u32 seed) {
|
||||
|
||||
#endif
|
||||
|
||||
@ -157,7 +157,7 @@ u32 inline hash32(u8 *key, u32 len, u32 seed) {
|
||||
u64 hash64(u8 *key, u32 len, u64 seed) {
|
||||
|
||||
#else
|
||||
u64 inline hash64(u8 *key, u32 len, u64 seed) {
|
||||
inline u64 hash64(u8 *key, u32 len, u64 seed) {
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -636,6 +636,8 @@ static void usage(u8 *argv0) {
|
||||
"size\n"
|
||||
" the target was compiled for\n"
|
||||
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
|
||||
"AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during "
|
||||
"startup (in milliseconds)\n"
|
||||
"AFL_QUIET: do not print extra informational output\n",
|
||||
argv0, MEM_LIMIT, doc_path);
|
||||
|
||||
@ -1036,6 +1038,19 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
}
|
||||
|
||||
if (getenv("AFL_FORKSRV_INIT_TMOUT")) {
|
||||
|
||||
s32 forksrv_init_tmout = atoi(getenv("AFL_FORKSRV_INIT_TMOUT"));
|
||||
if (forksrv_init_tmout < 1) {
|
||||
|
||||
FATAL("Bad value specified for AFL_FORKSRV_INIT_TMOUT");
|
||||
|
||||
}
|
||||
|
||||
fsrv->init_tmout = (u32)forksrv_init_tmout;
|
||||
|
||||
}
|
||||
|
||||
afl_fsrv_start(fsrv, use_argv, &stop_soon,
|
||||
get_afl_env("AFL_DEBUG_CHILD_OUTPUT") ? 1 : 0);
|
||||
map_size = fsrv->map_size;
|
||||
|
@ -846,6 +846,7 @@ static void usage(u8 *argv0) {
|
||||
" the target was compiled for\n"
|
||||
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
|
||||
"AFL_TMIN_EXACT: require execution paths to match for crashing inputs\n"
|
||||
"AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in milliseconds)\n"
|
||||
|
||||
, argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);
|
||||
|
||||
@ -1104,6 +1105,19 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
SAYF("\n");
|
||||
|
||||
if (getenv("AFL_FORKSRV_INIT_TMOUT")) {
|
||||
|
||||
s32 forksrv_init_tmout = atoi(getenv("AFL_FORKSRV_INIT_TMOUT"));
|
||||
if (forksrv_init_tmout < 1) {
|
||||
|
||||
FATAL("Bad value specified for AFL_FORKSRV_INIT_TMOUT");
|
||||
|
||||
}
|
||||
|
||||
fsrv->init_tmout = (u32)forksrv_init_tmout;
|
||||
|
||||
}
|
||||
|
||||
shm_fuzz = ck_alloc(sizeof(sharedmem_t));
|
||||
|
||||
/* initialize cmplog_mode */
|
||||
|
@ -70,6 +70,11 @@ MAKECMD=make
|
||||
TARCMD=tar
|
||||
|
||||
if [ "$PLT" = "Linux" ]; then
|
||||
MUSL=`ldd --version 2>&1 | head -n 1 | cut -f 1 -d " "`
|
||||
if [ "musl" = $MUSL ]; then
|
||||
echo "[-] Error: Unicorn instrumentation is unsupported with the musl's libc."
|
||||
exit 1
|
||||
fi
|
||||
CORES=`nproc`
|
||||
fi
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user