mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-08 16:21:32 +00:00
push to stable (#1734)
* afl++ -> AFL++ * update readme * more debug * slightly different weighting algo (#1719) * better seed selection * slightly different weighting calculation * remove unnecessary memset * Add "Hangs saved" to afl-whatsup (#1717) The hangs could show long or infinite loops. This is important. Co-authored-by: van Hauser <vh@thc.org> * nits * afl-showmap: Start a only a single fork server (#1718) A forkserver is started by afl_fsrv_get_mapsize() when dynamically finding the map size. When an input directory option is specified a second fork server was also started. This commit re-arranges the inits for several forkserver struct members so that we can re-use the server started by the get_mapsize() call when not in coresight/qemu/unicorn modes and just start the server otherwise. * Source Code Coverage support for Nyx (Part 1) (#1720) * Additional source code reformatting in afl-compiler-rt * Add source code coverage support to afl-compiler-rt (for use with Nyx) * doc, code format * llvm 17 changes * more llvm 17 * add frida mode tutorial * fix effector map * docs * Should memset EFF_ALEN(len) of eff_map (#1722) * fix reallocs * fix afl-system-config for macos * afl-fuzz.c: Document -i - in --help (#1725) afl-fuzz.c: Document `-i -` in `--help`, to write that `-i` can be passed '-' to resume the prior fuzzing job. Also reference AFL_AUTORESUME so users know they can set that parameter to sidestep the issue entirely. * tritondse custom mutator attempt * tritondse fixes * update libnyx (#1727) * GNUmakefile: Update LLVM instructions (#1728) Update LLVM instructions, because versions higher than 14 are supported and to be explicit that LLD is also required * disable macos in the ci, works fine for me * fix makefile * better tritondse support * next steps for tritondse * qemuafl: Persistent mode for PPC32 targets * update qemu_mode * afl-clang-lto incomptable with -flto=thin * add @responsefile support for afl-cc --------- Co-authored-by: fxlb <devel.fx.lebail@orange.fr> Co-authored-by: Nick Potenski <nick.potenski@garmin.com> Co-authored-by: Christian Holler (:decoder) <choller@mozilla.com> Co-authored-by: lazymio <mio@lazym.io> Co-authored-by: Moshe Kaplan <me@moshekaplan.com> Co-authored-by: Sergej Schumilo <sergej@schumilo.de> Co-authored-by: Dominik Maier <domenukk@gmail.com>
This commit is contained in:
parent
74be9ab5ce
commit
c4b1566ba3
40
.github/workflows/ci.yml
vendored
40
.github/workflows/ci.yml
vendored
@ -36,23 +36,23 @@ jobs:
|
|||||||
run: make distrib ASAN_BUILD=1 NO_NYX=1
|
run: make distrib ASAN_BUILD=1 NO_NYX=1
|
||||||
- name: run tests
|
- name: run tests
|
||||||
run: sudo -E ./afl-system-config; make tests
|
run: sudo -E ./afl-system-config; make tests
|
||||||
macos:
|
# macos:
|
||||||
runs-on: macOS-latest
|
# runs-on: macOS-latest
|
||||||
env:
|
# env:
|
||||||
AFL_MAP_SIZE: 65536
|
# AFL_MAP_SIZE: 65536
|
||||||
AFL_SKIP_CPUFREQ: 1
|
# AFL_SKIP_CPUFREQ: 1
|
||||||
AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1
|
# AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1
|
||||||
steps:
|
# steps:
|
||||||
- uses: actions/checkout@v3
|
# - uses: actions/checkout@v3
|
||||||
- name: install
|
# - name: install
|
||||||
run: brew install make gcc llvm
|
# run: brew install make gcc llvm
|
||||||
- name: fix install
|
# - name: fix install
|
||||||
run: cd /usr/local/bin; ln -s gcc-11 gcc; ln -s g++-11 g++; which gcc; gcc -v
|
# run: cd /usr/local/bin; ln -s gcc-11 gcc; ln -s g++-11 g++; which gcc; gcc -v
|
||||||
- name: build
|
# - name: build
|
||||||
run: export PATH=/usr/local/Cellar/llvm/*/":$PATH"; export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; export LLVM_CONFIG=/usr/local/Cellar/llvm/*/bin/llvm-config; sudo -E ./afl-system-config; gmake ASAN_BUILD=1
|
# run: export PATH=/usr/local/Cellar/llvm/*/":$PATH"; export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; export LLVM_CONFIG=/usr/local/Cellar/llvm/*/bin/llvm-config; sudo -E ./afl-system-config; gmake ASAN_BUILD=1
|
||||||
- name: frida
|
# - name: frida
|
||||||
run: export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; cd frida_mode; gmake
|
# run: export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; cd frida_mode; gmake
|
||||||
- name: run tests
|
# - name: run tests
|
||||||
run: sudo -E ./afl-system-config; export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; export PATH=/usr/local/Cellar/llvm/*/":/usr/local/bin:$PATH"; export LLVM_CONFIG=/usr/local/Cellar/llvm/*/bin/llvm-config; gmake tests
|
# run: sudo -E ./afl-system-config; export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; export PATH=/usr/local/Cellar/llvm/*/":/usr/local/bin:$PATH"; export LLVM_CONFIG=/usr/local/Cellar/llvm/*/bin/llvm-config; gmake tests
|
||||||
- name: force frida test for MacOS
|
# - name: force frida test for MacOS
|
||||||
run: export AFL_PATH=`pwd`; /usr/local/bin/gcc -o test-instr test-instr.c; mkdir in; echo > in/in; AFL_NO_UI=1 ./afl-fuzz -O -i in -o out -V 5 -- ./test-instr
|
# run: export AFL_PATH=`pwd`; /usr/local/bin/gcc -o test-instr test-instr.c; mkdir in; echo > in/in; AFL_NO_UI=1 ./afl-fuzz -O -i in -o out -V 5 -- ./test-instr
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
FROM ubuntu:22.04 AS aflplusplus
|
FROM ubuntu:22.04 AS aflplusplus
|
||||||
LABEL "maintainer"="afl++ team <afl@aflplus.plus>"
|
LABEL "maintainer"="AFL++ team <afl@aflplus.plus>"
|
||||||
LABEL "about"="AFLplusplus container image"
|
LABEL "about"="AFLplusplus container image"
|
||||||
|
|
||||||
### Comment out to enable these features
|
### Comment out to enable these features
|
||||||
@ -94,4 +94,4 @@ RUN sed -i.bak 's/^ -/ /g' GNUmakefile && \
|
|||||||
RUN echo "set encoding=utf-8" > /root/.vimrc && \
|
RUN echo "set encoding=utf-8" > /root/.vimrc && \
|
||||||
echo ". /etc/bash_completion" >> ~/.bashrc && \
|
echo ". /etc/bash_completion" >> ~/.bashrc && \
|
||||||
echo 'alias joe="joe --wordwrap --joe_state -nobackup"' >> ~/.bashrc && \
|
echo 'alias joe="joe --wordwrap --joe_state -nobackup"' >> ~/.bashrc && \
|
||||||
echo "export PS1='"'[afl++ \h] \w \$ '"'" >> ~/.bashrc
|
echo "export PS1='"'[AFL++ \h] \w \$ '"'" >> ~/.bashrc
|
||||||
|
17
GNUmakefile
17
GNUmakefile
@ -39,7 +39,7 @@ ASAN_OPTIONS=detect_leaks=0
|
|||||||
SYS = $(shell uname -s)
|
SYS = $(shell uname -s)
|
||||||
ARCH = $(shell uname -m)
|
ARCH = $(shell uname -m)
|
||||||
|
|
||||||
$(info [*] Compiling afl++ for OS $(SYS) on ARCH $(ARCH))
|
$(info [*] Compiling AFL++ for OS $(SYS) on ARCH $(ARCH))
|
||||||
|
|
||||||
ifdef NO_SPLICING
|
ifdef NO_SPLICING
|
||||||
override CFLAGS_OPT += -DNO_SPLICING
|
override CFLAGS_OPT += -DNO_SPLICING
|
||||||
@ -316,7 +316,7 @@ all: test_x86 test_shm test_python ready $(PROGS) afl-as llvm gcc_plugin test_bu
|
|||||||
@test -e afl-fuzz && echo "[+] afl-fuzz and supporting tools successfully built" || echo "[-] afl-fuzz could not be built, please set CC to a working compiler"
|
@test -e afl-fuzz && echo "[+] afl-fuzz and supporting tools successfully built" || echo "[-] afl-fuzz could not be built, please set CC to a working compiler"
|
||||||
@test -e afl-llvm-pass.so && echo "[+] LLVM basic mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-11 and clang-11 or newer, see docs/INSTALL.md"
|
@test -e afl-llvm-pass.so && echo "[+] LLVM basic mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-11 and clang-11 or newer, see docs/INSTALL.md"
|
||||||
@test -e SanitizerCoveragePCGUARD.so && echo "[+] LLVM mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-11 and clang-11 or newer, see docs/INSTALL.md"
|
@test -e SanitizerCoveragePCGUARD.so && echo "[+] LLVM mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-11 and clang-11 or newer, see docs/INSTALL.md"
|
||||||
@test -e SanitizerCoverageLTO.so && echo "[+] LLVM LTO mode successfully built" || echo "[-] LLVM LTO mode could not be built, it is optional, if you want it, please install LLVM 11-14. More information at instrumentation/README.lto.md on how to build it"
|
@test -e SanitizerCoverageLTO.so && echo "[+] LLVM LTO mode successfully built" || echo "[-] LLVM LTO mode could not be built, it is optional, if you want it, please install LLVM and LLD 11+. More information at instrumentation/README.lto.md on how to build it"
|
||||||
ifneq "$(SYS)" "Darwin"
|
ifneq "$(SYS)" "Darwin"
|
||||||
@test -e afl-gcc-pass.so && echo "[+] gcc_mode successfully built" || echo "[-] gcc_mode could not be built, it is optional, install gcc-VERSION-plugin-dev to enable this"
|
@test -e afl-gcc-pass.so && echo "[+] gcc_mode successfully built" || echo "[-] gcc_mode could not be built, it is optional, install gcc-VERSION-plugin-dev to enable this"
|
||||||
endif
|
endif
|
||||||
@ -359,7 +359,7 @@ performance-test: source-only
|
|||||||
help:
|
help:
|
||||||
@echo "HELP --- the following make targets exist:"
|
@echo "HELP --- the following make targets exist:"
|
||||||
@echo "=========================================="
|
@echo "=========================================="
|
||||||
@echo "all: the main afl++ binaries and llvm/gcc instrumentation"
|
@echo "all: the main AFL++ binaries and llvm/gcc instrumentation"
|
||||||
@echo "binary-only: everything for binary-only fuzzing: frida_mode, nyx_mode, qemu_mode, frida_mode, unicorn_mode, coresight_mode, libdislocator, libtokencap"
|
@echo "binary-only: everything for binary-only fuzzing: frida_mode, nyx_mode, qemu_mode, frida_mode, unicorn_mode, coresight_mode, libdislocator, libtokencap"
|
||||||
@echo "source-only: everything for source code fuzzing: nyx_mode, libdislocator, libtokencap"
|
@echo "source-only: everything for source code fuzzing: nyx_mode, libdislocator, libtokencap"
|
||||||
@echo "distrib: everything (for both binary-only and source code fuzzing)"
|
@echo "distrib: everything (for both binary-only and source code fuzzing)"
|
||||||
@ -367,7 +367,7 @@ help:
|
|||||||
@echo "install: installs everything you have compiled with the build option above"
|
@echo "install: installs everything you have compiled with the build option above"
|
||||||
@echo "clean: cleans everything compiled (not downloads when on a checkout)"
|
@echo "clean: cleans everything compiled (not downloads when on a checkout)"
|
||||||
@echo "deepclean: cleans everything including downloads"
|
@echo "deepclean: cleans everything including downloads"
|
||||||
@echo "uninstall: uninstall afl++ from the system"
|
@echo "uninstall: uninstall AFL++ from the system"
|
||||||
@echo "code-format: format the code, do this before you commit and send a PR please!"
|
@echo "code-format: format the code, do this before you commit and send a PR please!"
|
||||||
@echo "tests: this runs the test framework. It is more catered for the developers, but if you run into problems this helps pinpointing the problem"
|
@echo "tests: this runs the test framework. It is more catered for the developers, but if you run into problems this helps pinpointing the problem"
|
||||||
@echo "unit: perform unit tests (based on cmocka and GNU linker)"
|
@echo "unit: perform unit tests (based on cmocka and GNU linker)"
|
||||||
@ -379,6 +379,7 @@ help:
|
|||||||
@echo Known build environment options:
|
@echo Known build environment options:
|
||||||
@echo "=========================================="
|
@echo "=========================================="
|
||||||
@echo STATIC - compile AFL++ static
|
@echo STATIC - compile AFL++ static
|
||||||
|
@echo "CODE_COVERAGE - compile the target for code coverage (see docs/instrumentation/README.llvm.md)"
|
||||||
@echo ASAN_BUILD - compiles AFL++ with memory sanitizer for debug purposes
|
@echo ASAN_BUILD - compiles AFL++ with memory sanitizer for debug purposes
|
||||||
@echo UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for debug purposes
|
@echo UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for debug purposes
|
||||||
@echo DEBUG - no optimization, -ggdb3, all warnings and -Werror
|
@echo DEBUG - no optimization, -ggdb3, all warnings and -Werror
|
||||||
@ -394,7 +395,7 @@ help:
|
|||||||
@echo AFL_NO_X86 - if compiling on non-intel/amd platforms
|
@echo AFL_NO_X86 - if compiling on non-intel/amd platforms
|
||||||
@echo "LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config (e.g., Debian)"
|
@echo "LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config (e.g., Debian)"
|
||||||
@echo "=========================================="
|
@echo "=========================================="
|
||||||
@echo e.g.: make ASAN_BUILD=1
|
@echo e.g.: make LLVM_CONFIG=llvm-config-16
|
||||||
|
|
||||||
.PHONY: test_x86
|
.PHONY: test_x86
|
||||||
ifndef AFL_NO_X86
|
ifndef AFL_NO_X86
|
||||||
@ -749,7 +750,7 @@ endif
|
|||||||
@echo
|
@echo
|
||||||
|
|
||||||
%.8: %
|
%.8: %
|
||||||
@echo .TH $* 8 $(BUILD_DATE) "afl++" > $@
|
@echo .TH $* 8 $(BUILD_DATE) "AFL++" > $@
|
||||||
@echo .SH NAME >> $@
|
@echo .SH NAME >> $@
|
||||||
@echo .B $* >> $@
|
@echo .B $* >> $@
|
||||||
@echo >> $@
|
@echo >> $@
|
||||||
@ -761,8 +762,8 @@ endif
|
|||||||
@./$* -hh 2>&1 | tail -n +4 >> $@
|
@./$* -hh 2>&1 | tail -n +4 >> $@
|
||||||
@echo >> $@
|
@echo >> $@
|
||||||
@echo .SH AUTHOR >> $@
|
@echo .SH AUTHOR >> $@
|
||||||
@echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse <mh@mh-sec.de>, Heiko \"hexcoder-\" Eissfeldt <heiko.eissfeldt@hexco.de>, Andrea Fioraldi <andreafioraldi@gmail.com> and Dominik Maier <domenukk@gmail.com>" >> $@
|
@echo "AFL++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse <mh@mh-sec.de>, Dominik Maier <domenukk@gmail.com>, Andrea Fioraldi <andreafioraldi@gmail.com> and Heiko \"hexcoder-\" Eissfeldt <heiko.eissfeldt@hexco.de>" >> $@
|
||||||
@echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> $@
|
@echo The homepage of AFL++ is: https://github.com/AFLplusplus/AFLplusplus >> $@
|
||||||
@echo >> $@
|
@echo >> $@
|
||||||
@echo .SH LICENSE >> $@
|
@echo .SH LICENSE >> $@
|
||||||
@echo Apache License Version 2.0, January 2004 >> $@
|
@echo Apache License Version 2.0, January 2004 >> $@
|
||||||
|
@ -175,7 +175,7 @@ all_done: test_build
|
|||||||
.NOTPARALLEL: clean
|
.NOTPARALLEL: clean
|
||||||
|
|
||||||
%.8: %
|
%.8: %
|
||||||
@echo .TH $* 8 `date "+%Y-%m-%d"` "afl++" > ./$@
|
@echo .TH $* 8 `date "+%Y-%m-%d"` "AFL++" > ./$@
|
||||||
@echo .SH NAME >> ./$@
|
@echo .SH NAME >> ./$@
|
||||||
@echo .B $* >> ./$@
|
@echo .B $* >> ./$@
|
||||||
@echo >> ./$@
|
@echo >> ./$@
|
||||||
@ -187,8 +187,8 @@ all_done: test_build
|
|||||||
@./$* -h 2>&1 | tail -n +4 >> ./$@
|
@./$* -h 2>&1 | tail -n +4 >> ./$@
|
||||||
@echo >> ./$@
|
@echo >> ./$@
|
||||||
@echo .SH AUTHOR >> ./$@
|
@echo .SH AUTHOR >> ./$@
|
||||||
@echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse <mh@mh-sec.de>, Heiko \"hexcoder-\" Eissfeldt <heiko.eissfeldt@hexco.de>, Andrea Fioraldi <andreafioraldi@gmail.com> and Dominik Maier <domenukk@gmail.com>" >> ./$@
|
@echo "AFL++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse <mh@mh-sec.de>, Dominik Maier <domenukk@gmail.com>, Andrea Fioraldi <andreafioraldi@gmail.com> and Heiko \"hexcoder-\" Eissfeldt <heiko.eissfeldt@hexco.de>" >> ./$@
|
||||||
@echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> ./$@
|
@echo The homepage of AFL++ is: https://github.com/AFLplusplus/AFLplusplus >> ./$@
|
||||||
@echo >> ./$@
|
@echo >> ./$@
|
||||||
@echo .SH LICENSE >> ./$@
|
@echo .SH LICENSE >> ./$@
|
||||||
@echo Apache License Version 2.0, January 2004 >> ./$@
|
@echo Apache License Version 2.0, January 2004 >> ./$@
|
||||||
|
@ -274,6 +274,11 @@ ifndef LLVM_DEBUG
|
|||||||
CFLAGS_SAFE += -Wno-deprecated
|
CFLAGS_SAFE += -Wno-deprecated
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef CODE_COVERAGE
|
||||||
|
override CFLAGS_SAFE += -D__AFL_CODE_COVERAGE=1
|
||||||
|
override LDFLAGS += -ldl
|
||||||
|
endif
|
||||||
|
|
||||||
override CFLAGS += $(CFLAGS_SAFE)
|
override CFLAGS += $(CFLAGS_SAFE)
|
||||||
|
|
||||||
ifdef AFL_TRACE_PC
|
ifdef AFL_TRACE_PC
|
||||||
@ -510,7 +515,7 @@ install: all
|
|||||||
install -m 644 instrumentation/README.*.md $${DESTDIR}$(DOC_PATH)/
|
install -m 644 instrumentation/README.*.md $${DESTDIR}$(DOC_PATH)/
|
||||||
|
|
||||||
%.8: %
|
%.8: %
|
||||||
@echo .TH $* 8 $(BUILD_DATE) "afl++" > ./$@
|
@echo .TH $* 8 $(BUILD_DATE) "AFL++" > ./$@
|
||||||
@echo .SH NAME >> ./$@
|
@echo .SH NAME >> ./$@
|
||||||
@printf "%s" ".B $* \- " >> ./$@
|
@printf "%s" ".B $* \- " >> ./$@
|
||||||
@./$* -h 2>&1 | head -n 1 | sed -e "s/$$(printf '\e')[^m]*m//g" >> ./$@
|
@./$* -h 2>&1 | head -n 1 | sed -e "s/$$(printf '\e')[^m]*m//g" >> ./$@
|
||||||
@ -524,8 +529,8 @@ install: all
|
|||||||
@./$* -h 2>&1 | tail -n +4 >> ./$@
|
@./$* -h 2>&1 | tail -n +4 >> ./$@
|
||||||
@echo >> ./$@
|
@echo >> ./$@
|
||||||
@echo .SH AUTHOR >> ./$@
|
@echo .SH AUTHOR >> ./$@
|
||||||
@echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse <mh@mh-sec.de>, Heiko \"hexcoder-\" Eissfeldt <heiko.eissfeldt@hexco.de>, Andrea Fioraldi <andreafioraldi@gmail.com> and Dominik Maier <domenukk@gmail.com>" >> ./$@
|
@echo "AFL++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse <mh@mh-sec.de>, Dominik Maier <domenukk@gmail.com>, Andrea Fioraldi <andreafioraldi@gmail.com> and Heiko \"hexcoder-\" Eissfeldt <heiko.eissfeldt@hexco.de>" >> ./$@
|
||||||
@echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> ./$@
|
@echo The homepage of AFL++ is: https://github.com/AFLplusplus/AFLplusplus >> ./$@
|
||||||
@echo >> ./$@
|
@echo >> ./$@
|
||||||
@echo .SH LICENSE >> ./$@
|
@echo .SH LICENSE >> ./$@
|
||||||
@echo Apache License Version 2.0, January 2004 >> ./$@
|
@echo Apache License Version 2.0, January 2004 >> ./$@
|
||||||
|
@ -12,9 +12,9 @@ Repository:
|
|||||||
AFL++ is maintained by:
|
AFL++ is maintained by:
|
||||||
|
|
||||||
* Marc "van Hauser" Heuse <mh@mh-sec.de>
|
* Marc "van Hauser" Heuse <mh@mh-sec.de>
|
||||||
* Heiko "hexcoder-" Eißfeldt <heiko.eissfeldt@hexco.de>
|
|
||||||
* Andrea Fioraldi <andreafioraldi@gmail.com>
|
* Andrea Fioraldi <andreafioraldi@gmail.com>
|
||||||
* Dominik Maier <mail@dmnk.co>
|
* Dominik Maier <mail@dmnk.co>
|
||||||
|
* Heiko "hexcoder-" Eißfeldt <heiko.eissfeldt@hexco.de>
|
||||||
* Documentation: Jana Aydinbas <jana.aydinbas@gmail.com>
|
* Documentation: Jana Aydinbas <jana.aydinbas@gmail.com>
|
||||||
|
|
||||||
Originally developed by Michał "lcamtuf" Zalewski.
|
Originally developed by Michał "lcamtuf" Zalewski.
|
||||||
|
2
afl-cmin
2
afl-cmin
@ -149,7 +149,7 @@ BEGIN {
|
|||||||
redirected = 0
|
redirected = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
print "corpus minimization tool for afl++ (awk version)\n"
|
print "corpus minimization tool for AFL++ (awk version)\n"
|
||||||
|
|
||||||
# defaults
|
# defaults
|
||||||
extra_par = ""
|
extra_par = ""
|
||||||
|
@ -110,7 +110,7 @@ if [ "$PLATFORM" = "Darwin" ] ; then
|
|||||||
sysctl kern.sysv.shmall=131072000
|
sysctl kern.sysv.shmall=131072000
|
||||||
echo Settings applied.
|
echo Settings applied.
|
||||||
echo
|
echo
|
||||||
if [ $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') ] ; then
|
if $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') ; then
|
||||||
echo
|
echo
|
||||||
echo Unloading the default crash reporter
|
echo Unloading the default crash reporter
|
||||||
SL=/System/Library; PL=com.apple.ReportCrash
|
SL=/System/Library; PL=com.apple.ReportCrash
|
||||||
@ -119,6 +119,7 @@ if [ "$PLATFORM" = "Darwin" ] ; then
|
|||||||
echo
|
echo
|
||||||
fi
|
fi
|
||||||
echo It is recommended to disable System Integrity Protection for increased performance.
|
echo It is recommended to disable System Integrity Protection for increased performance.
|
||||||
|
echo See: https://developer.apple.com/documentation/security/disabling_and_enabling_system_integrity_protection
|
||||||
echo
|
echo
|
||||||
DONE=1
|
DONE=1
|
||||||
fi
|
fi
|
||||||
|
@ -88,6 +88,7 @@ TOTAL_TIME=0
|
|||||||
TOTAL_EXECS=0
|
TOTAL_EXECS=0
|
||||||
TOTAL_EPS=0
|
TOTAL_EPS=0
|
||||||
TOTAL_CRASHES=0
|
TOTAL_CRASHES=0
|
||||||
|
TOTAL_HANGS=0
|
||||||
TOTAL_PFAV=0
|
TOTAL_PFAV=0
|
||||||
TOTAL_PENDING=0
|
TOTAL_PENDING=0
|
||||||
|
|
||||||
@ -190,6 +191,7 @@ for i in `find . -maxdepth 2 -iname fuzzer_stats | sort`; do
|
|||||||
TOTAL_EPS=$((TOTAL_EPS + EXEC_SEC))
|
TOTAL_EPS=$((TOTAL_EPS + EXEC_SEC))
|
||||||
TOTAL_EXECS=$((TOTAL_EXECS + execs_done))
|
TOTAL_EXECS=$((TOTAL_EXECS + execs_done))
|
||||||
TOTAL_CRASHES=$((TOTAL_CRASHES + saved_crashes))
|
TOTAL_CRASHES=$((TOTAL_CRASHES + saved_crashes))
|
||||||
|
TOTAL_HANGS=$((TOTAL_HANGS + saved_hangs))
|
||||||
TOTAL_PENDING=$((TOTAL_PENDING + pending_total))
|
TOTAL_PENDING=$((TOTAL_PENDING + pending_total))
|
||||||
TOTAL_PFAV=$((TOTAL_PFAV + pending_favs))
|
TOTAL_PFAV=$((TOTAL_PFAV + pending_favs))
|
||||||
|
|
||||||
@ -301,6 +303,7 @@ if [ "$ALIVE_CNT" -gt "1" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo " Crashes saved : $TOTAL_CRASHES"
|
echo " Crashes saved : $TOTAL_CRASHES"
|
||||||
|
echo " Hangs saved : $TOTAL_HANGS"
|
||||||
echo "Cycles without finds : $TOTAL_WCOP"
|
echo "Cycles without finds : $TOTAL_WCOP"
|
||||||
echo " Time without finds : $TOTAL_LAST_FIND"
|
echo " Time without finds : $TOTAL_LAST_FIND"
|
||||||
echo
|
echo
|
||||||
|
17
custom_mutators/aflpp_tritondse/README.md
Normal file
17
custom_mutators/aflpp_tritondse/README.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# An AFL++ custom mutator using TritonDSE
|
||||||
|
|
||||||
|
## Installing the requirements
|
||||||
|
|
||||||
|
`pip3 install tritondse`
|
||||||
|
|
||||||
|
## How to run with an example
|
||||||
|
|
||||||
|
```
|
||||||
|
../../afl-cc -o ../../test-instr ../../test-instr.c
|
||||||
|
mkdir -p in
|
||||||
|
echo aaaa > in/in
|
||||||
|
TRITON_DSE_TARGET=../../test-instr AFL_CUSTOM_MUTATOR_ONLY=1 AFL_SYNC_TIME=1 AFL_PYTHON_MODULE=aflpp_tritondse PYTHONPATH=. ../../afl-fuzz -i in -o out -- ../../test-instr
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that this custom mutator works differently, new finds are synced
|
||||||
|
after 10-60 seconds to the fuzzing instance.
|
148
custom_mutators/aflpp_tritondse/aflpp_tritondse.py
Normal file
148
custom_mutators/aflpp_tritondse/aflpp_tritondse.py
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
from tritondse import CleLoader
|
||||||
|
from tritondse import CompositeData
|
||||||
|
from tritondse import Config
|
||||||
|
from tritondse import CoverageStrategy
|
||||||
|
from tritondse import ProcessState
|
||||||
|
from tritondse import Program
|
||||||
|
from tritondse import Seed
|
||||||
|
from tritondse import SeedFormat
|
||||||
|
from tritondse import SymbolicExecutor
|
||||||
|
from tritondse import SymbolicExplorator
|
||||||
|
|
||||||
|
is_debug = False
|
||||||
|
out_path = ""
|
||||||
|
input_file = None
|
||||||
|
prog = None
|
||||||
|
config = None
|
||||||
|
dse = None
|
||||||
|
cycle = 0
|
||||||
|
count = 0
|
||||||
|
hashes = set()
|
||||||
|
format = SeedFormat.RAW
|
||||||
|
|
||||||
|
def pre_exec_hook(se: SymbolicExecutor, state: ProcessState):
|
||||||
|
global count
|
||||||
|
global hashes
|
||||||
|
if se.seed.hash not in hashes:
|
||||||
|
hashes.add(se.seed.hash)
|
||||||
|
filename = out_path + "/id:" + f"{count:06}" + "," + se.seed.hash
|
||||||
|
if not os.path.exists(filename):
|
||||||
|
if is_debug:
|
||||||
|
print('Creating queue input ' + filename)
|
||||||
|
with open(filename, 'wb') as file:
|
||||||
|
if input_file:
|
||||||
|
file.write(se.seed.content.files[input_file])
|
||||||
|
else:
|
||||||
|
file.write(se.seed.content)
|
||||||
|
count += 1
|
||||||
|
#if input_file:
|
||||||
|
# if is_debug:
|
||||||
|
# print('Writing to ' + input_file + ' the content: ' + str(se.seed.content))
|
||||||
|
# with open(input_file, 'wb') as file:
|
||||||
|
# file.write(se.seed.content)
|
||||||
|
|
||||||
|
|
||||||
|
def init(seed):
|
||||||
|
global config
|
||||||
|
global dse
|
||||||
|
global format
|
||||||
|
global input_file
|
||||||
|
global is_debug
|
||||||
|
global out_path
|
||||||
|
global prog
|
||||||
|
# Load the program (LIEF-based program loader).
|
||||||
|
prog = CleLoader(os.environ['AFL_CUSTOM_INFO_PROGRAM'])
|
||||||
|
# Process other configuration environment variables.
|
||||||
|
argv = None
|
||||||
|
try:
|
||||||
|
foo = os.environ['AFL_DEBUG']
|
||||||
|
is_debug = True
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
foo = os.environ['AFL_CUSTOM_INFO_OUT']
|
||||||
|
out_path = foo + '/../tritondse/queue'
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
foo = os.environ['AFL_CUSTOM_INFO_PROGRAM_INPUT']
|
||||||
|
input_file = foo
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
argv_list = os.environ['AFL_CUSTOM_INFO_PROGRAM_ARGV']
|
||||||
|
argv_tmp = [ os.environ['AFL_CUSTOM_INFO_PROGRAM'] ]
|
||||||
|
argv_tmp += argv_list.split()
|
||||||
|
argv = []
|
||||||
|
# now check for @@
|
||||||
|
for item in argv_tmp:
|
||||||
|
if "@@" in item:
|
||||||
|
input_file = out_path + '/../.input'
|
||||||
|
argv.append(input_file)
|
||||||
|
else:
|
||||||
|
argv.append(item)
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
# Create the output directory
|
||||||
|
os.makedirs(out_path, exist_ok=True)
|
||||||
|
# Debug
|
||||||
|
if is_debug:
|
||||||
|
print('DEBUG target: ' + os.environ['AFL_CUSTOM_INFO_PROGRAM'])
|
||||||
|
if argv:
|
||||||
|
print('DEBUG argv: ')
|
||||||
|
print(argv)
|
||||||
|
if input_file:
|
||||||
|
print('DEBUG input_file: ' + input_file)
|
||||||
|
print('DEBUG out_path: ' + out_path)
|
||||||
|
print('')
|
||||||
|
if input_file:
|
||||||
|
format = SeedFormat.COMPOSITE
|
||||||
|
# Now set up TritonDSE
|
||||||
|
config = Config(coverage_strategy = CoverageStrategy.PATH,
|
||||||
|
debug = is_debug,
|
||||||
|
pipe_stdout = is_debug,
|
||||||
|
pipe_stderr = is_debug,
|
||||||
|
execution_timeout = 1,
|
||||||
|
program_argv = argv,
|
||||||
|
smt_timeout= 50,
|
||||||
|
seed_format = format)
|
||||||
|
# Create an instance of the Symbolic Explorator
|
||||||
|
dse = SymbolicExplorator(config, prog)
|
||||||
|
# Add callbacks.
|
||||||
|
dse.callback_manager.register_pre_execution_callback(pre_exec_hook)
|
||||||
|
|
||||||
|
|
||||||
|
#def fuzz(buf, add_buf, max_size):
|
||||||
|
# return b""
|
||||||
|
|
||||||
|
|
||||||
|
def queue_new_entry(filename_new_queue, filename_orig_queue):
|
||||||
|
global cycle
|
||||||
|
global dse
|
||||||
|
# Add seed to the worklist.
|
||||||
|
with open(filename_new_queue, "rb") as file:
|
||||||
|
data = file.read()
|
||||||
|
hash = hashlib.md5(data).hexdigest()
|
||||||
|
if hash not in hashes:
|
||||||
|
hashes.add(hash)
|
||||||
|
if is_debug:
|
||||||
|
print("NEW FILE " + filename_new_queue + " hash " + hash + " count " + str(cycle))
|
||||||
|
cycle += 1
|
||||||
|
if input_file:
|
||||||
|
seed = Seed(CompositeData(files={"stdin": b"", # nothing on stdin
|
||||||
|
input_file: data}))
|
||||||
|
else:
|
||||||
|
seed = Seed(data)
|
||||||
|
dse.add_input_seed(seed)
|
||||||
|
# Start exploration!
|
||||||
|
#dse.step()
|
||||||
|
dse.explore()
|
||||||
|
pass
|
||||||
|
|
||||||
|
def splice_optout():
|
||||||
|
pass
|
@ -11,13 +11,17 @@
|
|||||||
- new env `AFL_IGNORE_PROBLEMS_COVERAGE` to ignore coverage from
|
- new env `AFL_IGNORE_PROBLEMS_COVERAGE` to ignore coverage from
|
||||||
loaded libs after forkserver initialization (required by Mozilla)
|
loaded libs after forkserver initialization (required by Mozilla)
|
||||||
- afl-cc:
|
- afl-cc:
|
||||||
|
- added @responsefile support
|
||||||
- new env `AFL_LLVM_LTO_SKIPINIT` to support the AFL++ based WASM
|
- new env `AFL_LLVM_LTO_SKIPINIT` to support the AFL++ based WASM
|
||||||
(https://github.com/fgsect/WAFL) project
|
(https://github.com/fgsect/WAFL) project
|
||||||
|
- error and print help if afl-clan-lto is used with lto=thin
|
||||||
- afl-showmap:
|
- afl-showmap:
|
||||||
- added custom mutator post_process and send support
|
- added custom mutator post_process and send support
|
||||||
- add `-I filelist` option, an alternative to `-i in_dir`
|
- add `-I filelist` option, an alternative to `-i in_dir`
|
||||||
- afl-cmin + afl-cmin.bash:
|
- afl-cmin + afl-cmin.bash:
|
||||||
- `-T threads` parallel task support, can be a huge speedup!
|
- `-T threads` parallel task support, can be a huge speedup!
|
||||||
|
- qemu_mode:
|
||||||
|
- Persistent mode +QASAN support for ppc32 tragets by @worksbutnottested
|
||||||
- a new grammar custom mutator atnwalk was submitted by @voidptr127 !
|
- a new grammar custom mutator atnwalk was submitted by @voidptr127 !
|
||||||
|
|
||||||
|
|
||||||
@ -229,7 +233,7 @@
|
|||||||
afl-showmap and other tools.
|
afl-showmap and other tools.
|
||||||
- afl-cc:
|
- afl-cc:
|
||||||
- detect overflow reads on initial input buffer for asan
|
- detect overflow reads on initial input buffer for asan
|
||||||
- new cmplog mode (incompatible with older afl++ versions)
|
- new cmplog mode (incompatible with older AFL++ versions)
|
||||||
- support llvm IR select instrumentation for default PCGUARD and LTO
|
- support llvm IR select instrumentation for default PCGUARD and LTO
|
||||||
- fix for shared linking on MacOS
|
- fix for shared linking on MacOS
|
||||||
- better selective instrumentation AFL_LLVM_{ALLOW|DENY}LIST
|
- better selective instrumentation AFL_LLVM_{ALLOW|DENY}LIST
|
||||||
|
@ -171,6 +171,14 @@ If you find an interesting or important question missing, submit it via
|
|||||||
The more "unstable" edges there are, the harder it is for AFL++ to identify
|
The more "unstable" edges there are, the harder it is for AFL++ to identify
|
||||||
valid new paths.
|
valid new paths.
|
||||||
|
|
||||||
|
If you fuzz in persistent mode (`AFL_LOOP` or `LLVMFuzzerTestOneInput()`
|
||||||
|
harnesses, a large number of unstable edges can mean that the target keeps
|
||||||
|
internal state and therefore it is possible that crashes cannot be replayed.
|
||||||
|
In such a case do either **not** fuzz in persistent mode (remove `AFL_LOOP()`
|
||||||
|
from your harness or call `LLVMFuzzerTestOneInput()` harnesses with `@@`),
|
||||||
|
or set a low `AFL_LOOP` value, e.g. 100, and enable `AFL_PERSISTENT_RECORD`
|
||||||
|
in `config.h` with the same value.
|
||||||
|
|
||||||
A value above 90% is usually fine and a value above 80% is also still ok, and
|
A value above 90% is usually fine and a value above 80% is also still ok, and
|
||||||
even a value above 20% can still result in successful finds of bugs. However,
|
even a value above 20% can still result in successful finds of bugs. However,
|
||||||
it is recommended that for values below 90% or 80% you should take
|
it is recommended that for values below 90% or 80% you should take
|
||||||
|
@ -51,7 +51,7 @@ make source-only
|
|||||||
|
|
||||||
These build targets exist:
|
These build targets exist:
|
||||||
|
|
||||||
* all: the main afl++ binaries and llvm/gcc instrumentation
|
* all: the main AFL++ binaries and llvm/gcc instrumentation
|
||||||
* binary-only: everything for binary-only fuzzing: frida_mode, nyx_mode,
|
* binary-only: everything for binary-only fuzzing: frida_mode, nyx_mode,
|
||||||
qemu_mode, frida_mode, unicorn_mode, coresight_mode, libdislocator,
|
qemu_mode, frida_mode, unicorn_mode, coresight_mode, libdislocator,
|
||||||
libtokencap
|
libtokencap
|
||||||
@ -79,22 +79,20 @@ make STATIC=1
|
|||||||
These build options exist:
|
These build options exist:
|
||||||
|
|
||||||
* STATIC - compile AFL++ static
|
* STATIC - compile AFL++ static
|
||||||
|
* CODE_COVERAGE - compile the target for code coverage (see docs/instrumentation/README.llvm.md)
|
||||||
* ASAN_BUILD - compiles AFL++ with memory sanitizer for debug purposes
|
* ASAN_BUILD - compiles AFL++ with memory sanitizer for debug purposes
|
||||||
* UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for
|
* UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for debug purposes
|
||||||
debug purposes
|
|
||||||
* DEBUG - no optimization, -ggdb3, all warnings and -Werror
|
* DEBUG - no optimization, -ggdb3, all warnings and -Werror
|
||||||
* LLVM_DEBUG - shows llvm deprecation warnings
|
* LLVM_DEBUG - shows llvm deprecation warnings
|
||||||
* PROFILING - compile afl-fuzz with profiling information
|
* PROFILING - compile afl-fuzz with profiling information
|
||||||
* INTROSPECTION - compile afl-fuzz with mutation introspection
|
* INTROSPECTION - compile afl-fuzz with mutation introspection
|
||||||
* NO_PYTHON - disable python support
|
* NO_PYTHON - disable python support
|
||||||
* NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for
|
* NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for normal fuzzing
|
||||||
normal fuzzing
|
|
||||||
* NO_NYX - disable building nyx mode dependencies
|
* NO_NYX - disable building nyx mode dependencies
|
||||||
* NO_CORESIGHT - disable building coresight (arm64 only)
|
* NO_CORESIGHT - disable building coresight (arm64 only)
|
||||||
* NO_UNICORN_ARM64 - disable building unicorn on arm64
|
* NO_UNICORN_ARM64 - disable building unicorn on arm64
|
||||||
* AFL_NO_X86 - if compiling on non-intel/amd platforms
|
* AFL_NO_X86 - if compiling on non-intel/amd platforms
|
||||||
* LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config
|
* LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config (e.g., Debian)
|
||||||
(e.g., Debian)
|
|
||||||
|
|
||||||
e.g.: `make LLVM_CONFIG=llvm-config-14`
|
e.g.: `make LLVM_CONFIG=llvm-config-14`
|
||||||
|
|
||||||
|
@ -131,6 +131,11 @@ jitter, or is a hash map function etc., then it should not be instrumented.
|
|||||||
To be able to exclude these functions (based on AFL++'s measured stability), the
|
To be able to exclude these functions (based on AFL++'s measured stability), the
|
||||||
following process will allow to identify functions with variable edges.
|
following process will allow to identify functions with variable edges.
|
||||||
|
|
||||||
|
Note that this is only useful for non-persistent targets!
|
||||||
|
If a persistent target is unstable whereas when run non-persistent is fine,
|
||||||
|
then this means that the target is keeping internal state, which is bad for
|
||||||
|
fuzzing. Fuzz such targets **without** persistent mode.
|
||||||
|
|
||||||
Four steps are required to do this and it also requires quite some knowledge of
|
Four steps are required to do this and it also requires quite some knowledge of
|
||||||
coding and/or disassembly and is effectively possible only with `afl-clang-fast`
|
coding and/or disassembly and is effectively possible only with `afl-clang-fast`
|
||||||
`PCGUARD` and `afl-clang-lto` `LTO` instrumentation.
|
`PCGUARD` and `afl-clang-lto` `LTO` instrumentation.
|
||||||
|
@ -304,6 +304,34 @@ Note: for some distributions, you might also need the package `python[3]-apt`.
|
|||||||
In case your setup is different, set the necessary variables like this:
|
In case your setup is different, set the necessary variables like this:
|
||||||
`PYTHON_INCLUDE=/path/to/python/include LDFLAGS=-L/path/to/python/lib make`.
|
`PYTHON_INCLUDE=/path/to/python/include LDFLAGS=-L/path/to/python/lib make`.
|
||||||
|
|
||||||
|
### Helpers
|
||||||
|
|
||||||
|
For C/C++ custom mutators you get a pointer to `afl_state_t *afl` in the
|
||||||
|
`afl_custom_init()` which contains all information that you need.
|
||||||
|
Note that if you access it, you need to recompile your custom mutator if
|
||||||
|
you update AFL++ because the structure might have changed!
|
||||||
|
|
||||||
|
For mutators written in Python, Rust, GO, etc. there are a few environment
|
||||||
|
variables set to help you to get started:
|
||||||
|
|
||||||
|
`AFL_CUSTOM_INFO_PROGRAM` - the program name of the target that is executed.
|
||||||
|
If your custom mutator is used with modes like Qemu (`-Q`), this will still
|
||||||
|
contain the target program, not afl-qemu-trace.
|
||||||
|
|
||||||
|
`AFL_CUSTOM_INFO_PROGRAM_INPUT` - if the `-f` parameter is used with afl-fuzz
|
||||||
|
then this value is found in this environment variable.
|
||||||
|
|
||||||
|
`AFL_CUSTOM_INFO_PROGRAM_ARGV` - this contains the parameters given to the
|
||||||
|
target program and still has the `@@` identifier in there.
|
||||||
|
|
||||||
|
Note: If `AFL_CUSTOM_INFO_PROGRAM_INPUT` is empty and `AFL_CUSTOM_INFO_PROGRAM_ARGV`
|
||||||
|
is either empty or does not contain `@@` then the target gets the input via
|
||||||
|
`stdin`.
|
||||||
|
|
||||||
|
`AFL_CUSTOM_INFO_OUT` - This is the output directory for this fuzzer instance,
|
||||||
|
so if `afl-fuzz` was called with `-o out -S foobar`, then this will be set to
|
||||||
|
`out/foobar`.
|
||||||
|
|
||||||
### Custom Mutator Preparation
|
### Custom Mutator Preparation
|
||||||
|
|
||||||
For C/C++ mutators, the source code must be compiled as a shared object:
|
For C/C++ mutators, the source code must be compiled as a shared object:
|
||||||
|
@ -20,6 +20,10 @@ training, then we can highly recommend the following:
|
|||||||
|
|
||||||
* [https://github.com/antonio-morales/Fuzzing101](https://github.com/antonio-morales/Fuzzing101)
|
* [https://github.com/antonio-morales/Fuzzing101](https://github.com/antonio-morales/Fuzzing101)
|
||||||
|
|
||||||
|
Here is good workflow description for frida_mode:
|
||||||
|
|
||||||
|
* [https://blog.quarkslab.com/android-greybox-fuzzing-with-afl-frida-mode.html](https://blog.quarkslab.com/android-greybox-fuzzing-with-afl-frida-mode.html)
|
||||||
|
|
||||||
If you are interested in fuzzing structured data (where you define what the
|
If you are interested in fuzzing structured data (where you define what the
|
||||||
structure is), these links have you covered (some are outdated though):
|
structure is), these links have you covered (some are outdated though):
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ variables.
|
|||||||
|
|
||||||
In FRIDA mode, binary programs are instrumented, similarly to QEMU mode.
|
In FRIDA mode, binary programs are instrumented, similarly to QEMU mode.
|
||||||
|
|
||||||
|
A tutorial can be found at [https://blog.quarkslab.com/android-greybox-fuzzing-with-afl-frida-mode.html](https://blog.quarkslab.com/android-greybox-fuzzing-with-afl-frida-mode.html)
|
||||||
|
|
||||||
## Current progress
|
## Current progress
|
||||||
|
|
||||||
As FRIDA mode is new, it is missing a lot of features. The design is such that
|
As FRIDA mode is new, it is missing a lot of features. The design is such that
|
||||||
|
@ -1223,7 +1223,7 @@ double rand_next_percent(afl_state_t *afl);
|
|||||||
|
|
||||||
static inline u32 rand_below(afl_state_t *afl, u32 limit) {
|
static inline u32 rand_below(afl_state_t *afl, u32 limit) {
|
||||||
|
|
||||||
if (limit <= 1) return 0;
|
if (unlikely(limit <= 1)) return 0;
|
||||||
|
|
||||||
/* 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. */
|
||||||
@ -1256,7 +1256,7 @@ static inline u32 rand_below(afl_state_t *afl, u32 limit) {
|
|||||||
expand havoc mode */
|
expand havoc mode */
|
||||||
static inline u32 rand_below_datalen(afl_state_t *afl, u32 limit) {
|
static inline u32 rand_below_datalen(afl_state_t *afl, u32 limit) {
|
||||||
|
|
||||||
if (limit <= 1) return 0;
|
if (unlikely(limit <= 1)) return 0;
|
||||||
|
|
||||||
switch (rand_below(afl, 3)) {
|
switch (rand_below(afl, 3)) {
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
// Be careful! _WANT_ORIGINAL_AFL_ALLOC is not compatible with custom mutators
|
// Be careful! _WANT_ORIGINAL_AFL_ALLOC is not compatible with custom mutators
|
||||||
|
|
||||||
#ifndef _WANT_ORIGINAL_AFL_ALLOC
|
#ifndef _WANT_ORIGINAL_AFL_ALLOC
|
||||||
// afl++ stuff without memory corruption checks - for speed
|
// AFL++ stuff without memory corruption checks - for speed
|
||||||
|
|
||||||
/* User-facing macro to sprintf() to a dynamically allocated buffer. */
|
/* User-facing macro to sprintf() to a dynamically allocated buffer. */
|
||||||
|
|
||||||
@ -704,12 +704,11 @@ static inline void *afl_realloc(void **buf, size_t size_needed) {
|
|||||||
*buf = NULL;
|
*buf = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
new_buf = newer_buf;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new_buf = newer_buf;
|
||||||
|
memset(((u8 *)new_buf) + current_size, 0, next_size - current_size);
|
||||||
|
|
||||||
new_buf->complete_size = next_size;
|
new_buf->complete_size = next_size;
|
||||||
*buf = (void *)(new_buf->buf);
|
*buf = (void *)(new_buf->buf);
|
||||||
return *buf;
|
return *buf;
|
||||||
|
@ -37,6 +37,10 @@ static char *afl_environment_variables[] = {
|
|||||||
"AFL_CRASH_EXITCODE",
|
"AFL_CRASH_EXITCODE",
|
||||||
"AFL_CUSTOM_MUTATOR_LIBRARY",
|
"AFL_CUSTOM_MUTATOR_LIBRARY",
|
||||||
"AFL_CUSTOM_MUTATOR_ONLY",
|
"AFL_CUSTOM_MUTATOR_ONLY",
|
||||||
|
"AFL_CUSTOM_INFO_PROGRAM",
|
||||||
|
"AFL_CUSTOM_INFO_PROGRAM_ARGV",
|
||||||
|
"AFL_CUSTOM_INFO_PROGRAM_INPUT",
|
||||||
|
"AFL_CUSTOM_INFO_OUT",
|
||||||
"AFL_CXX",
|
"AFL_CXX",
|
||||||
"AFL_CYCLE_SCHEDULES",
|
"AFL_CYCLE_SCHEDULES",
|
||||||
"AFL_DEBUG",
|
"AFL_DEBUG",
|
||||||
|
@ -280,3 +280,27 @@ Please note that the default counter implementations are not thread safe!
|
|||||||
|
|
||||||
Support for thread safe counters in mode LLVM CLASSIC can be activated with
|
Support for thread safe counters in mode LLVM CLASSIC can be activated with
|
||||||
setting `AFL_LLVM_THREADSAFE_INST=1`.
|
setting `AFL_LLVM_THREADSAFE_INST=1`.
|
||||||
|
|
||||||
|
## 8) Source code coverage through instrumentation
|
||||||
|
|
||||||
|
Measuring source code coverage is a common task in fuzzing, but it is very
|
||||||
|
difficut to do in some situations (e.g. when using snapshot fuzzing).
|
||||||
|
|
||||||
|
When using the `AFL_LLVM_INSTRUMENT=llvm-codecov` option, afl-cc will use
|
||||||
|
native trace-pc-guard instrumentation but additionally select options that
|
||||||
|
are required to utilize the instrumentation for source code coverage.
|
||||||
|
|
||||||
|
In particular, it will switch the instrumentation to be per basic block
|
||||||
|
instead of instrumenting edges, disable all guard pruning and enable the
|
||||||
|
experimental pc-table support that allows the runtime to gather 100% of
|
||||||
|
instrumented basic blocks at start, including their locations.
|
||||||
|
|
||||||
|
Note: You must compile AFL with the `CODE_COVERAGE=1` option to enable the
|
||||||
|
respective parts in the AFL compiler runtime. Support is currently only
|
||||||
|
implemented for Nyx, but can in theory also work without Nyx.
|
||||||
|
|
||||||
|
Note: You might have to adjust `MAP_SIZE_POW2` in include/config.h to ensure
|
||||||
|
that your coverage map is large enough to hold all basic blocks of your
|
||||||
|
target program without any collisions.
|
||||||
|
|
||||||
|
More documentation on how to utilize this with Nyx will follow.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* SanitizeCoverage.cpp ported to afl++ LTO :-) */
|
/* SanitizeCoverage.cpp ported to AFL++ LTO :-) */
|
||||||
|
|
||||||
#define AFL_LLVM_PASS
|
#define AFL_LLVM_PASS
|
||||||
|
|
||||||
@ -20,6 +20,8 @@
|
|||||||
#if LLVM_VERSION_MAJOR < 17
|
#if LLVM_VERSION_MAJOR < 17
|
||||||
#include "llvm/ADT/Triple.h"
|
#include "llvm/ADT/Triple.h"
|
||||||
#include "llvm/Analysis/EHPersonalities.h"
|
#include "llvm/Analysis/EHPersonalities.h"
|
||||||
|
#else
|
||||||
|
#include "llvm/IR/EHPersonalities.h"
|
||||||
#endif
|
#endif
|
||||||
#include "llvm/Analysis/PostDominators.h"
|
#include "llvm/Analysis/PostDominators.h"
|
||||||
#include "llvm/Analysis/ValueTracking.h"
|
#include "llvm/Analysis/ValueTracking.h"
|
||||||
@ -236,7 +238,7 @@ class ModuleSanitizerCoverageLTO
|
|||||||
|
|
||||||
SanitizerCoverageOptions Options;
|
SanitizerCoverageOptions Options;
|
||||||
|
|
||||||
// afl++ START
|
// AFL++ START
|
||||||
// const SpecialCaseList * Allowlist;
|
// const SpecialCaseList * Allowlist;
|
||||||
// const SpecialCaseList * Blocklist;
|
// const SpecialCaseList * Blocklist;
|
||||||
uint32_t autodictionary = 1;
|
uint32_t autodictionary = 1;
|
||||||
@ -262,7 +264,7 @@ class ModuleSanitizerCoverageLTO
|
|||||||
Value *MapPtrFixed = NULL;
|
Value *MapPtrFixed = NULL;
|
||||||
std::ofstream dFile;
|
std::ofstream dFile;
|
||||||
size_t found = 0;
|
size_t found = 0;
|
||||||
// afl++ END
|
// AFL++ END
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -406,7 +408,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
|
|||||||
Int8Ty = IRB.getInt8Ty();
|
Int8Ty = IRB.getInt8Ty();
|
||||||
Int1Ty = IRB.getInt1Ty();
|
Int1Ty = IRB.getInt1Ty();
|
||||||
|
|
||||||
/* afl++ START */
|
/* AFL++ START */
|
||||||
char *ptr;
|
char *ptr;
|
||||||
LLVMContext &Ctx = M.getContext();
|
LLVMContext &Ctx = M.getContext();
|
||||||
Ct = &Ctx;
|
Ct = &Ctx;
|
||||||
@ -980,7 +982,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// afl++ END
|
// AFL++ END
|
||||||
|
|
||||||
SanCovTracePCIndir =
|
SanCovTracePCIndir =
|
||||||
M.getOrInsertFunction(SanCovTracePCIndirName, VoidTy, IntptrTy);
|
M.getOrInsertFunction(SanCovTracePCIndirName, VoidTy, IntptrTy);
|
||||||
@ -1004,7 +1006,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
|
|||||||
for (auto &F : M)
|
for (auto &F : M)
|
||||||
instrumentFunction(F, DTCallback, PDTCallback);
|
instrumentFunction(F, DTCallback, PDTCallback);
|
||||||
|
|
||||||
// afl++ START
|
// AFL++ START
|
||||||
if (dFile.is_open()) dFile.close();
|
if (dFile.is_open()) dFile.close();
|
||||||
|
|
||||||
if (!getenv("AFL_LLVM_LTO_SKIPINIT") &&
|
if (!getenv("AFL_LLVM_LTO_SKIPINIT") &&
|
||||||
@ -1158,7 +1160,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// afl++ END
|
// AFL++ END
|
||||||
|
|
||||||
// We don't reference these arrays directly in any of our runtime functions,
|
// We don't reference these arrays directly in any of our runtime functions,
|
||||||
// so we need to prevent them from being dead stripped.
|
// so we need to prevent them from being dead stripped.
|
||||||
@ -1215,10 +1217,10 @@ static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
|
|||||||
// (catchswitch blocks).
|
// (catchswitch blocks).
|
||||||
if (BB->getFirstInsertionPt() == BB->end()) return false;
|
if (BB->getFirstInsertionPt() == BB->end()) return false;
|
||||||
|
|
||||||
// afl++ START
|
// AFL++ START
|
||||||
if (!Options.NoPrune && &F.getEntryBlock() == BB && F.size() > 1)
|
if (!Options.NoPrune && &F.getEntryBlock() == BB && F.size() > 1)
|
||||||
return false;
|
return false;
|
||||||
// afl++ END
|
// AFL++ END
|
||||||
|
|
||||||
if (Options.NoPrune || &F.getEntryBlock() == BB) return true;
|
if (Options.NoPrune || &F.getEntryBlock() == BB) return true;
|
||||||
|
|
||||||
@ -1260,10 +1262,10 @@ void ModuleSanitizerCoverageLTO::instrumentFunction(
|
|||||||
// if (Blocklist && Blocklist->inSection("coverage", "fun", F.getName()))
|
// if (Blocklist && Blocklist->inSection("coverage", "fun", F.getName()))
|
||||||
// return;
|
// return;
|
||||||
|
|
||||||
// afl++ START
|
// AFL++ START
|
||||||
if (!F.size()) return;
|
if (!F.size()) return;
|
||||||
if (!isInInstrumentList(&F, FMNAME)) return;
|
if (!isInInstrumentList(&F, FMNAME)) return;
|
||||||
// afl++ END
|
// AFL++ END
|
||||||
|
|
||||||
if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge)
|
if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge)
|
||||||
SplitAllCriticalEdges(
|
SplitAllCriticalEdges(
|
||||||
@ -1561,7 +1563,7 @@ bool ModuleSanitizerCoverageLTO::InjectCoverage(
|
|||||||
|
|
||||||
for (size_t i = 0, N = AllBlocks.size(); i < N; i++) {
|
for (size_t i = 0, N = AllBlocks.size(); i < N; i++) {
|
||||||
|
|
||||||
// afl++ START
|
// AFL++ START
|
||||||
if (BlockList.size()) {
|
if (BlockList.size()) {
|
||||||
|
|
||||||
int skip = 0;
|
int skip = 0;
|
||||||
@ -1583,7 +1585,7 @@ bool ModuleSanitizerCoverageLTO::InjectCoverage(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// afl++ END
|
// AFL++ END
|
||||||
|
|
||||||
InjectCoverageAtBlock(F, *AllBlocks[i], i, IsLeafFunc);
|
InjectCoverageAtBlock(F, *AllBlocks[i], i, IsLeafFunc);
|
||||||
|
|
||||||
@ -1649,7 +1651,7 @@ void ModuleSanitizerCoverageLTO::InjectCoverageAtBlock(Function &F,
|
|||||||
|
|
||||||
if (Options.TracePCGuard) {
|
if (Options.TracePCGuard) {
|
||||||
|
|
||||||
// afl++ START
|
// AFL++ START
|
||||||
++afl_global_id;
|
++afl_global_id;
|
||||||
|
|
||||||
if (dFile.is_open()) {
|
if (dFile.is_open()) {
|
||||||
@ -1713,7 +1715,7 @@ void ModuleSanitizerCoverageLTO::InjectCoverageAtBlock(Function &F,
|
|||||||
// done :)
|
// done :)
|
||||||
|
|
||||||
inst++;
|
inst++;
|
||||||
// afl++ END
|
// AFL++ END
|
||||||
|
|
||||||
/*
|
/*
|
||||||
XXXXXXXXXXXXXXXXXXX
|
XXXXXXXXXXXXXXXXXXX
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
#if LLVM_VERSION_MAJOR < 17
|
#if LLVM_VERSION_MAJOR < 17
|
||||||
#include "llvm/ADT/Triple.h"
|
#include "llvm/ADT/Triple.h"
|
||||||
#include "llvm/Analysis/EHPersonalities.h"
|
#include "llvm/Analysis/EHPersonalities.h"
|
||||||
|
#else
|
||||||
|
#include "llvm/IR/EHPersonalities.h"
|
||||||
#endif
|
#endif
|
||||||
#include "llvm/Analysis/PostDominators.h"
|
#include "llvm/Analysis/PostDominators.h"
|
||||||
#include "llvm/IR/CFG.h"
|
#include "llvm/IR/CFG.h"
|
||||||
|
@ -14,6 +14,16 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef __AFL_CODE_COVERAGE
|
||||||
|
#ifndef _GNU_SOURCE
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#endif
|
||||||
|
#ifndef __USE_GNU
|
||||||
|
#define __USE_GNU
|
||||||
|
#endif
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
#include "android-ashmem.h"
|
#include "android-ashmem.h"
|
||||||
#endif
|
#endif
|
||||||
@ -105,6 +115,44 @@ u32 __afl_dictionary_len;
|
|||||||
u64 __afl_map_addr;
|
u64 __afl_map_addr;
|
||||||
u32 __afl_first_final_loc;
|
u32 __afl_first_final_loc;
|
||||||
|
|
||||||
|
#ifdef __AFL_CODE_COVERAGE
|
||||||
|
typedef struct afl_module_info_t afl_module_info_t;
|
||||||
|
|
||||||
|
struct afl_module_info_t {
|
||||||
|
|
||||||
|
// A unique id starting with 0
|
||||||
|
u32 id;
|
||||||
|
|
||||||
|
// Name and base address of the module
|
||||||
|
char *name;
|
||||||
|
uintptr_t base_address;
|
||||||
|
|
||||||
|
// PC Guard start/stop
|
||||||
|
u32 start;
|
||||||
|
u32 stop;
|
||||||
|
|
||||||
|
// PC Table begin/end
|
||||||
|
const uintptr_t *pcs_beg;
|
||||||
|
const uintptr_t *pcs_end;
|
||||||
|
|
||||||
|
u8 mapped;
|
||||||
|
|
||||||
|
afl_module_info_t *next;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
|
||||||
|
uintptr_t PC, PCFlags;
|
||||||
|
|
||||||
|
} PCTableEntry;
|
||||||
|
|
||||||
|
afl_module_info_t *__afl_module_info = NULL;
|
||||||
|
|
||||||
|
u32 __afl_pcmap_size = 0;
|
||||||
|
uintptr_t *__afl_pcmap_ptr = NULL;
|
||||||
|
#endif // __AFL_CODE_COVERAGE
|
||||||
|
|
||||||
/* 1 if we are running in afl, and the forkserver was started, else 0 */
|
/* 1 if we are running in afl, and the forkserver was started, else 0 */
|
||||||
u32 __afl_connected = 0;
|
u32 __afl_connected = 0;
|
||||||
|
|
||||||
@ -499,6 +547,7 @@ static void __afl_map_shm(void) {
|
|||||||
u8 *map_env = (u8 *)getenv("AFL_MAP_SIZE");
|
u8 *map_env = (u8 *)getenv("AFL_MAP_SIZE");
|
||||||
if (!map_env || atoi((char *)map_env) < MAP_SIZE) {
|
if (!map_env || atoi((char *)map_env) < MAP_SIZE) {
|
||||||
|
|
||||||
|
fprintf(stderr, "FS_ERROR_MAP_SIZE\n");
|
||||||
send_forkserver_error(FS_ERROR_MAP_SIZE);
|
send_forkserver_error(FS_ERROR_MAP_SIZE);
|
||||||
_exit(1);
|
_exit(1);
|
||||||
|
|
||||||
@ -678,6 +727,27 @@ static void __afl_map_shm(void) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __AFL_CODE_COVERAGE
|
||||||
|
char *pcmap_id_str = getenv("__AFL_PCMAP_SHM_ID");
|
||||||
|
|
||||||
|
if (pcmap_id_str) {
|
||||||
|
|
||||||
|
__afl_pcmap_size = __afl_map_size * sizeof(void *);
|
||||||
|
u32 shm_id = atoi(pcmap_id_str);
|
||||||
|
|
||||||
|
__afl_pcmap_ptr = (uintptr_t *)shmat(shm_id, NULL, 0);
|
||||||
|
|
||||||
|
if (__afl_debug) {
|
||||||
|
|
||||||
|
fprintf(stderr, "DEBUG: Received %p via shmat for pcmap\n",
|
||||||
|
__afl_pcmap_ptr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __AFL_CODE_COVERAGE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unmap SHM. */
|
/* unmap SHM. */
|
||||||
@ -686,6 +756,17 @@ static void __afl_unmap_shm(void) {
|
|||||||
|
|
||||||
if (!__afl_already_initialized_shm) return;
|
if (!__afl_already_initialized_shm) return;
|
||||||
|
|
||||||
|
#ifdef __AFL_CODE_COVERAGE
|
||||||
|
if (__afl_pcmap_size) {
|
||||||
|
|
||||||
|
shmdt((void *)__afl_pcmap_ptr);
|
||||||
|
__afl_pcmap_ptr = NULL;
|
||||||
|
__afl_pcmap_size = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __AFL_CODE_COVERAGE
|
||||||
|
|
||||||
char *id_str = getenv(SHM_ENV_VAR);
|
char *id_str = getenv(SHM_ENV_VAR);
|
||||||
|
|
||||||
if (id_str) {
|
if (id_str) {
|
||||||
@ -1507,6 +1588,102 @@ void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __AFL_CODE_COVERAGE
|
||||||
|
void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg,
|
||||||
|
const uintptr_t *pcs_end) {
|
||||||
|
|
||||||
|
if (__afl_debug) {
|
||||||
|
|
||||||
|
fprintf(stderr, "DEBUG: __sanitizer_cov_pcs_init called\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// If for whatever reason, we cannot get dlinfo here, then pc_guard_init also
|
||||||
|
// couldn't get it and we'd end up attributing to the wrong module.
|
||||||
|
Dl_info dlinfo;
|
||||||
|
if (!dladdr(__builtin_return_address(0), &dlinfo)) {
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
"WARNING: Ignoring __sanitizer_cov_pcs_init callback due to "
|
||||||
|
"missing module info\n");
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
afl_module_info_t *last_module_info = __afl_module_info;
|
||||||
|
while (last_module_info && last_module_info->next) {
|
||||||
|
|
||||||
|
last_module_info = last_module_info->next;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!last_module_info) {
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
"ERROR: __sanitizer_cov_pcs_init called with no module info?!\n");
|
||||||
|
abort();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
last_module_info->pcs_beg = pcs_beg;
|
||||||
|
last_module_info->pcs_end = pcs_end;
|
||||||
|
|
||||||
|
// Now update the pcmap. If this is the last module coming in, after all
|
||||||
|
// pre-loaded code, then this will also map all of our delayed previous
|
||||||
|
// modules.
|
||||||
|
|
||||||
|
if (!__afl_pcmap_ptr) { return; }
|
||||||
|
|
||||||
|
for (afl_module_info_t *mod_info = __afl_module_info; mod_info;
|
||||||
|
mod_info = mod_info->next) {
|
||||||
|
|
||||||
|
if (mod_info->mapped) { continue; }
|
||||||
|
|
||||||
|
PCTableEntry *start = (PCTableEntry *)(mod_info->pcs_beg);
|
||||||
|
PCTableEntry *end = (PCTableEntry *)(mod_info->pcs_end);
|
||||||
|
|
||||||
|
u32 in_module_index = 0;
|
||||||
|
|
||||||
|
while (start < end) {
|
||||||
|
|
||||||
|
if (mod_info->start + in_module_index >= __afl_map_size) {
|
||||||
|
|
||||||
|
fprintf(stderr, "ERROR: __sanitizer_cov_pcs_init out of bounds?!\n");
|
||||||
|
abort();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t PC = start->PC;
|
||||||
|
|
||||||
|
// This is what `GetPreviousInstructionPc` in sanitizer runtime does
|
||||||
|
// for x86/x86-64. Needs more work for ARM and other archs.
|
||||||
|
PC = PC - 1;
|
||||||
|
|
||||||
|
// Calculate relative offset in module
|
||||||
|
PC = PC - mod_info->base_address;
|
||||||
|
|
||||||
|
__afl_pcmap_ptr[mod_info->start + in_module_index] = PC;
|
||||||
|
|
||||||
|
start++;
|
||||||
|
in_module_index++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
mod_info->mapped = 1;
|
||||||
|
|
||||||
|
if (__afl_debug) {
|
||||||
|
|
||||||
|
fprintf(stderr, "DEBUG: __sanitizer_cov_pcs_init initialized %u PCs\n",
|
||||||
|
in_module_index);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __AFL_CODE_COVERAGE
|
||||||
|
|
||||||
/* Init callback. Populates instrumentation IDs. Note that we're using
|
/* Init callback. Populates instrumentation IDs. Note that we're using
|
||||||
ID of 0 as a special value to indicate non-instrumented bits. That may
|
ID of 0 as a special value to indicate non-instrumented bits. That may
|
||||||
still touch the bitmap, but in a fairly harmless way. */
|
still touch the bitmap, but in a fairly harmless way. */
|
||||||
@ -1538,6 +1715,62 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
|
|||||||
|
|
||||||
if (start == stop || *start) { return; }
|
if (start == stop || *start) { return; }
|
||||||
|
|
||||||
|
#ifdef __AFL_CODE_COVERAGE
|
||||||
|
u32 *orig_start = start;
|
||||||
|
afl_module_info_t *mod_info = NULL;
|
||||||
|
|
||||||
|
Dl_info dlinfo;
|
||||||
|
if (dladdr(__builtin_return_address(0), &dlinfo)) {
|
||||||
|
|
||||||
|
if (__afl_already_initialized_forkserver) {
|
||||||
|
|
||||||
|
fprintf(stderr, "[pcmap] Error: Module was not preloaded: %s\n",
|
||||||
|
dlinfo.dli_fname);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
afl_module_info_t *last_module_info = __afl_module_info;
|
||||||
|
while (last_module_info && last_module_info->next) {
|
||||||
|
|
||||||
|
last_module_info = last_module_info->next;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
mod_info = malloc(sizeof(afl_module_info_t));
|
||||||
|
|
||||||
|
mod_info->id = last_module_info ? last_module_info->id + 1 : 0;
|
||||||
|
mod_info->name = strdup(dlinfo.dli_fname);
|
||||||
|
mod_info->base_address = (uintptr_t)dlinfo.dli_fbase;
|
||||||
|
mod_info->start = 0;
|
||||||
|
mod_info->stop = 0;
|
||||||
|
mod_info->pcs_beg = NULL;
|
||||||
|
mod_info->pcs_end = NULL;
|
||||||
|
mod_info->mapped = 0;
|
||||||
|
mod_info->next = NULL;
|
||||||
|
|
||||||
|
if (last_module_info) {
|
||||||
|
|
||||||
|
last_module_info->next = mod_info;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
__afl_module_info = mod_info;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "[pcmap] Module: %s Base Address: %p\n", dlinfo.dli_fname,
|
||||||
|
dlinfo.dli_fbase);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
fprintf(stderr, "[pcmap] dladdr call failed\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __AFL_CODE_COVERAGE
|
||||||
|
|
||||||
x = getenv("AFL_INST_RATIO");
|
x = getenv("AFL_INST_RATIO");
|
||||||
if (x) {
|
if (x) {
|
||||||
|
|
||||||
@ -1625,6 +1858,22 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __AFL_CODE_COVERAGE
|
||||||
|
if (mod_info) {
|
||||||
|
|
||||||
|
mod_info->start = *orig_start;
|
||||||
|
mod_info->stop = *(stop - 1);
|
||||||
|
if (__afl_debug) {
|
||||||
|
|
||||||
|
fprintf(stderr, "DEBUG: [pcmap] Start Index: %u Stop Index: %u\n",
|
||||||
|
mod_info->start, mod_info->stop);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __AFL_CODE_COVERAGE
|
||||||
|
|
||||||
if (__afl_debug) {
|
if (__afl_debug) {
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
|
@ -584,7 +584,7 @@ bool isInInstrumentList(llvm::Function *F, std::string Filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the number of average collisions that would occur if all
|
// Calculate the number of average collisions that would occur if all
|
||||||
// location IDs would be assigned randomly (like normal afl/afl++).
|
// location IDs would be assigned randomly (like normal afl/AFL++).
|
||||||
// This uses the "balls in bins" algorithm.
|
// This uses the "balls in bins" algorithm.
|
||||||
unsigned long long int calculateCollisions(uint32_t edges) {
|
unsigned long long int calculateCollisions(uint32_t edges) {
|
||||||
|
|
||||||
|
@ -746,7 +746,7 @@ static void registerAFLdict2filePass(const PassManagerBuilder &,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPass<AFLdict2filePass> X("afl-dict2file",
|
static RegisterPass<AFLdict2filePass> X("afl-dict2file",
|
||||||
"afl++ dict2file instrumentation pass",
|
"AFL++ dict2file instrumentation pass",
|
||||||
false, false);
|
false, false);
|
||||||
|
|
||||||
static RegisterStandardPasses RegisterAFLdict2filePass(
|
static RegisterStandardPasses RegisterAFLdict2filePass(
|
||||||
|
@ -1 +1 @@
|
|||||||
2da7f08
|
c8a72dc
|
||||||
|
@ -1 +1 @@
|
|||||||
0569eff8a1
|
a1321713c7
|
||||||
|
@ -356,7 +356,7 @@ fi
|
|||||||
|
|
||||||
if ! command -v "$CROSS" > /dev/null ; then
|
if ! command -v "$CROSS" > /dev/null ; then
|
||||||
if [ "$CPU_TARGET" = "$(uname -m)" ] ; then
|
if [ "$CPU_TARGET" = "$(uname -m)" ] ; then
|
||||||
echo "[+] Building afl++ qemu support libraries with CC=$CC"
|
echo "[+] Building AFL++ qemu support libraries with CC=$CC"
|
||||||
echo "[+] Building libcompcov ..."
|
echo "[+] Building libcompcov ..."
|
||||||
make -C libcompcov && echo "[+] libcompcov ready"
|
make -C libcompcov && echo "[+] libcompcov ready"
|
||||||
echo "[+] Building unsigaction ..."
|
echo "[+] Building unsigaction ..."
|
||||||
@ -371,7 +371,7 @@ if ! command -v "$CROSS" > /dev/null ; then
|
|||||||
echo "[!] Cross compiler $CROSS could not be found, cannot compile libcompcov libqasan and unsigaction"
|
echo "[!] Cross compiler $CROSS could not be found, cannot compile libcompcov libqasan and unsigaction"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "[+] Building afl++ qemu support libraries with CC=\"$CROSS $CROSS_FLAGS\""
|
echo "[+] Building AFL++ qemu support libraries with CC=\"$CROSS $CROSS_FLAGS\""
|
||||||
echo "[+] Building libcompcov ..."
|
echo "[+] Building libcompcov ..."
|
||||||
make -C libcompcov CC="$CROSS $CROSS_FLAGS" && echo "[+] libcompcov ready"
|
make -C libcompcov CC="$CROSS $CROSS_FLAGS" && echo "[+] libcompcov ready"
|
||||||
echo "[+] Building unsigaction ..."
|
echo "[+] Building unsigaction ..."
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 0569eff8a12dec73642b96757f6b5b51a618a03a
|
Subproject commit a1321713c7502c152dd7527555e0f8a800d55225
|
498
src/afl-cc.c
498
src/afl-cc.c
@ -31,6 +31,8 @@
|
|||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#if (LLVM_MAJOR - 0 == 0)
|
#if (LLVM_MAJOR - 0 == 0)
|
||||||
#undef LLVM_MAJOR
|
#undef LLVM_MAJOR
|
||||||
@ -76,6 +78,7 @@ enum {
|
|||||||
INSTRUMENT_OPT_NGRAM = 16,
|
INSTRUMENT_OPT_NGRAM = 16,
|
||||||
INSTRUMENT_OPT_CALLER = 32,
|
INSTRUMENT_OPT_CALLER = 32,
|
||||||
INSTRUMENT_OPT_CTX_K = 64,
|
INSTRUMENT_OPT_CTX_K = 64,
|
||||||
|
INSTRUMENT_OPT_CODECOV = 128,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -375,15 +378,304 @@ void parse_fsanitize(char *string) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u8 fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0,
|
||||||
|
shared_linking = 0, preprocessor_only = 0, have_unroll = 0,
|
||||||
|
have_o = 0, have_pic = 0, have_c = 0, partial_linking = 0,
|
||||||
|
non_dash = 0;
|
||||||
|
|
||||||
|
static void process_params(u32 argc, char **argv) {
|
||||||
|
|
||||||
|
if (cc_par_cnt + argc >= 1024) { FATAL("Too many command line parameters"); }
|
||||||
|
|
||||||
|
if (lto_mode && argc > 1) {
|
||||||
|
|
||||||
|
u32 idx;
|
||||||
|
for (idx = 1; idx < argc; idx++) {
|
||||||
|
|
||||||
|
if (!strncasecmp(argv[idx], "-fpic", 5)) have_pic = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// for (u32 x = 0; x < argc; ++x) fprintf(stderr, "[%u] %s\n", x, argv[x]);
|
||||||
|
|
||||||
|
/* Process the argument list. */
|
||||||
|
|
||||||
|
u8 skip_next = 0;
|
||||||
|
while (--argc) {
|
||||||
|
|
||||||
|
u8 *cur = *(++argv);
|
||||||
|
|
||||||
|
if (skip_next) {
|
||||||
|
|
||||||
|
skip_next = 0;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cur[0] != '-') { non_dash = 1; }
|
||||||
|
if (!strncmp(cur, "--afl", 5)) continue;
|
||||||
|
|
||||||
|
if (lto_mode && !strncmp(cur, "-flto=thin", 10)) {
|
||||||
|
|
||||||
|
FATAL(
|
||||||
|
"afl-clang-lto cannot work with -flto=thin. Switch to -flto=full or "
|
||||||
|
"use afl-clang-fast!");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lto_mode && !strncmp(cur, "-fuse-ld=", 9)) continue;
|
||||||
|
if (lto_mode && !strncmp(cur, "--ld-path=", 10)) continue;
|
||||||
|
if (!strncmp(cur, "-fno-unroll", 11)) continue;
|
||||||
|
if (strstr(cur, "afl-compiler-rt") || strstr(cur, "afl-llvm-rt")) continue;
|
||||||
|
if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined") ||
|
||||||
|
!strcmp(cur, "--no-undefined")) {
|
||||||
|
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compiler_mode == GCC_PLUGIN && !strcmp(cur, "-pipe")) { continue; }
|
||||||
|
|
||||||
|
if (!strcmp(cur, "-z") || !strcmp(cur, "-Wl,-z")) {
|
||||||
|
|
||||||
|
u8 *param = *(argv + 1);
|
||||||
|
if (!strcmp(param, "defs") || !strcmp(param, "-Wl,defs")) {
|
||||||
|
|
||||||
|
skip_next = 1;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((compiler_mode == GCC || compiler_mode == GCC_PLUGIN) &&
|
||||||
|
!strncmp(cur, "-stdlib=", 8)) {
|
||||||
|
|
||||||
|
if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); }
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strncmp(cur, "-fsanitize-coverage-", 20) && strstr(cur, "list=")) {
|
||||||
|
|
||||||
|
have_instr_list = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strncmp(cur, "-fsanitize=", strlen("-fsanitize=")) &&
|
||||||
|
strchr(cur, ',')) {
|
||||||
|
|
||||||
|
parse_fsanitize(cur);
|
||||||
|
if (!cur || strlen(cur) <= strlen("-fsanitize=")) { continue; }
|
||||||
|
|
||||||
|
} else if ((!strncmp(cur, "-fsanitize=fuzzer-",
|
||||||
|
|
||||||
|
strlen("-fsanitize=fuzzer-")) ||
|
||||||
|
!strncmp(cur, "-fsanitize-coverage",
|
||||||
|
strlen("-fsanitize-coverage"))) &&
|
||||||
|
(strncmp(cur, "sanitize-coverage-allow",
|
||||||
|
strlen("sanitize-coverage-allow")) &&
|
||||||
|
strncmp(cur, "sanitize-coverage-deny",
|
||||||
|
strlen("sanitize-coverage-deny")) &&
|
||||||
|
instrument_mode != INSTRUMENT_LLVMNATIVE)) {
|
||||||
|
|
||||||
|
if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); }
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (need_aflpplib || !strcmp(cur, "-fsanitize=fuzzer")) {
|
||||||
|
|
||||||
|
u8 *afllib = find_object("libAFLDriver.a", argv[0]);
|
||||||
|
|
||||||
|
if (!be_quiet) {
|
||||||
|
|
||||||
|
OKF("Found '-fsanitize=fuzzer', replacing with libAFLDriver.a");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!afllib) {
|
||||||
|
|
||||||
|
if (!be_quiet) {
|
||||||
|
|
||||||
|
WARNF(
|
||||||
|
"Cannot find 'libAFLDriver.a' to replace '-fsanitize=fuzzer' in "
|
||||||
|
"the flags - this will fail!");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
cc_params[cc_par_cnt++] = afllib;
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
cc_params[cc_par_cnt++] = "-undefined";
|
||||||
|
cc_params[cc_par_cnt++] = "dynamic_lookup";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (need_aflpplib) {
|
||||||
|
|
||||||
|
need_aflpplib = 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(cur, "-m32")) bit_mode = 32;
|
||||||
|
if (!strcmp(cur, "armv7a-linux-androideabi")) bit_mode = 32;
|
||||||
|
if (!strcmp(cur, "-m64")) bit_mode = 64;
|
||||||
|
|
||||||
|
if (!strcmp(cur, "-fsanitize=address") || !strcmp(cur, "-fsanitize=memory"))
|
||||||
|
asan_set = 1;
|
||||||
|
|
||||||
|
if (strstr(cur, "FORTIFY_SOURCE")) fortify_set = 1;
|
||||||
|
|
||||||
|
if (!strcmp(cur, "-x")) x_set = 1;
|
||||||
|
if (!strcmp(cur, "-E")) preprocessor_only = 1;
|
||||||
|
if (!strcmp(cur, "-shared")) shared_linking = 1;
|
||||||
|
if (!strcmp(cur, "-dynamiclib")) shared_linking = 1;
|
||||||
|
if (!strcmp(cur, "--target=wasm32-wasi")) passthrough = 1;
|
||||||
|
if (!strcmp(cur, "-Wl,-r")) partial_linking = 1;
|
||||||
|
if (!strcmp(cur, "-Wl,-i")) partial_linking = 1;
|
||||||
|
if (!strcmp(cur, "-Wl,--relocatable")) partial_linking = 1;
|
||||||
|
if (!strcmp(cur, "-r")) partial_linking = 1;
|
||||||
|
if (!strcmp(cur, "--relocatable")) partial_linking = 1;
|
||||||
|
if (!strcmp(cur, "-c")) have_c = 1;
|
||||||
|
|
||||||
|
if (!strncmp(cur, "-O", 2)) have_o = 1;
|
||||||
|
if (!strncmp(cur, "-funroll-loop", 13)) have_unroll = 1;
|
||||||
|
|
||||||
|
if (*cur == '@') {
|
||||||
|
|
||||||
|
// response file support.
|
||||||
|
// we have two choices - move everything to the command line or
|
||||||
|
// rewrite the response files to temporary files and delete them
|
||||||
|
// afterwards. We choose the first for easiness.
|
||||||
|
// We do *not* support quotes in the rsp files to cope with spaces in
|
||||||
|
// filenames etc! If you need that then send a patch!
|
||||||
|
u8 *filename = cur + 1;
|
||||||
|
if (debug) { DEBUGF("response file=%s\n", filename); }
|
||||||
|
FILE *f = fopen(filename, "r");
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
// Check not found or empty? let the compiler complain if so.
|
||||||
|
if (!f || fstat(fileno(f), &st) < 0 || st.st_size < 1) {
|
||||||
|
|
||||||
|
cc_params[cc_par_cnt++] = cur;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 *tmpbuf = malloc(st.st_size + 1), *ptr;
|
||||||
|
char **args = malloc(sizeof(char *) * (st.st_size >> 1));
|
||||||
|
int count = 1, cont = 0, cont_act = 0;
|
||||||
|
|
||||||
|
while (fgets(tmpbuf, st.st_size, f)) {
|
||||||
|
|
||||||
|
ptr = tmpbuf;
|
||||||
|
// no leading whitespace
|
||||||
|
while (isspace(*ptr)) {
|
||||||
|
|
||||||
|
++ptr;
|
||||||
|
cont_act = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// no comments, no empty lines
|
||||||
|
if (*ptr == '#' || *ptr == '\n' || !*ptr) { continue; }
|
||||||
|
// remove LF
|
||||||
|
if (ptr[strlen(ptr) - 1] == '\n') { ptr[strlen(ptr) - 1] = 0; }
|
||||||
|
// remove CR
|
||||||
|
if (*ptr && ptr[strlen(ptr) - 1] == '\r') { ptr[strlen(ptr) - 1] = 0; }
|
||||||
|
// handle \ at end of line
|
||||||
|
if (*ptr && ptr[strlen(ptr) - 1] == '\\') {
|
||||||
|
|
||||||
|
cont = 1;
|
||||||
|
ptr[strlen(ptr) - 1] = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove whitespace at end
|
||||||
|
while (*ptr && isspace(ptr[strlen(ptr) - 1])) {
|
||||||
|
|
||||||
|
ptr[strlen(ptr) - 1] = 0;
|
||||||
|
cont = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*ptr) {
|
||||||
|
|
||||||
|
do {
|
||||||
|
|
||||||
|
u8 *value = ptr;
|
||||||
|
while (*ptr && !isspace(*ptr)) {
|
||||||
|
|
||||||
|
++ptr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*ptr && isspace(*ptr)) {
|
||||||
|
|
||||||
|
*ptr++ = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cont_act) {
|
||||||
|
|
||||||
|
u32 len = strlen(args[count - 1]) + strlen(value) + 1;
|
||||||
|
u8 *tmp = malloc(len);
|
||||||
|
snprintf(tmp, len, "%s%s", args[count - 1], value);
|
||||||
|
free(args[count - 1]);
|
||||||
|
args[count - 1] = tmp;
|
||||||
|
cont_act = 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
args[count++] = strdup(value);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (*ptr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cont) {
|
||||||
|
|
||||||
|
cont_act = 1;
|
||||||
|
cont = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count) { process_params(count, args); }
|
||||||
|
|
||||||
|
// we cannot free args[]
|
||||||
|
free(tmpbuf);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_params[cc_par_cnt++] = cur;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Copy argv to cc_params, making the necessary edits. */
|
/* Copy argv to cc_params, making the necessary edits. */
|
||||||
|
|
||||||
static void edit_params(u32 argc, char **argv, char **envp) {
|
static void edit_params(u32 argc, char **argv, char **envp) {
|
||||||
|
|
||||||
u8 fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0, shared_linking = 0,
|
cc_params = ck_alloc(1024 * sizeof(u8 *));
|
||||||
preprocessor_only = 0, have_unroll = 0, have_o = 0, have_pic = 0,
|
|
||||||
have_c = 0, partial_linking = 0;
|
|
||||||
|
|
||||||
cc_params = ck_alloc((argc + 128) * sizeof(u8 *));
|
|
||||||
|
|
||||||
if (lto_mode) {
|
if (lto_mode) {
|
||||||
|
|
||||||
@ -642,7 +934,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//#if LLVM_MAJOR >= 13
|
//#if LLVM_MAJOR >= 13
|
||||||
// // Use the old pass manager in LLVM 14 which the afl++ passes still
|
// // Use the old pass manager in LLVM 14 which the AFL++ passes still
|
||||||
// use. cc_params[cc_par_cnt++] = "-flegacy-pass-manager";
|
// use. cc_params[cc_par_cnt++] = "-flegacy-pass-manager";
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
@ -751,7 +1043,21 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
|||||||
} else if (instrument_mode == INSTRUMENT_LLVMNATIVE) {
|
} else if (instrument_mode == INSTRUMENT_LLVMNATIVE) {
|
||||||
|
|
||||||
#if LLVM_MAJOR >= 4
|
#if LLVM_MAJOR >= 4
|
||||||
cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
|
if (instrument_opt_mode & INSTRUMENT_OPT_CODECOV) {
|
||||||
|
|
||||||
|
#if LLVM_MAJOR >= 6
|
||||||
|
cc_params[cc_par_cnt++] =
|
||||||
|
"-fsanitize-coverage=trace-pc-guard,bb,no-prune,pc-table";
|
||||||
|
#else
|
||||||
|
FATAL("pcguard instrumentation with pc-table requires llvm 6.0.1+");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
FATAL("pcguard instrumentation requires llvm 4.0.1+");
|
FATAL("pcguard instrumentation requires llvm 4.0.1+");
|
||||||
#endif
|
#endif
|
||||||
@ -816,159 +1122,15 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!have_pic) cc_params[cc_par_cnt++] = "-fPIC";
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Detect stray -v calls from ./configure scripts. */
|
/* Inspect the command line parameters. */
|
||||||
|
|
||||||
u8 skip_next = 0, non_dash = 0;
|
process_params(argc, argv);
|
||||||
while (--argc) {
|
|
||||||
|
|
||||||
u8 *cur = *(++argv);
|
if (!have_pic) { cc_params[cc_par_cnt++] = "-fPIC"; }
|
||||||
|
|
||||||
if (skip_next) {
|
|
||||||
|
|
||||||
skip_next = 0;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cur[0] != '-') { non_dash = 1; }
|
|
||||||
if (!strncmp(cur, "--afl", 5)) continue;
|
|
||||||
if (lto_mode && !strncmp(cur, "-fuse-ld=", 9)) continue;
|
|
||||||
if (lto_mode && !strncmp(cur, "--ld-path=", 10)) continue;
|
|
||||||
if (!strncmp(cur, "-fno-unroll", 11)) continue;
|
|
||||||
if (strstr(cur, "afl-compiler-rt") || strstr(cur, "afl-llvm-rt")) continue;
|
|
||||||
if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined") ||
|
|
||||||
!strcmp(cur, "--no-undefined")) {
|
|
||||||
|
|
||||||
continue;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (compiler_mode == GCC_PLUGIN && !strcmp(cur, "-pipe")) { continue; }
|
|
||||||
|
|
||||||
if (!strcmp(cur, "-z") || !strcmp(cur, "-Wl,-z")) {
|
|
||||||
|
|
||||||
u8 *param = *(argv + 1);
|
|
||||||
if (!strcmp(param, "defs") || !strcmp(param, "-Wl,defs")) {
|
|
||||||
|
|
||||||
skip_next = 1;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((compiler_mode == GCC || compiler_mode == GCC_PLUGIN) &&
|
|
||||||
!strncmp(cur, "-stdlib=", 8)) {
|
|
||||||
|
|
||||||
if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); }
|
|
||||||
continue;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strncmp(cur, "-fsanitize-coverage-", 20) && strstr(cur, "list=")) {
|
|
||||||
|
|
||||||
have_instr_list = 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strncmp(cur, "-fsanitize=", strlen("-fsanitize=")) &&
|
|
||||||
strchr(cur, ',')) {
|
|
||||||
|
|
||||||
parse_fsanitize(cur);
|
|
||||||
if (!cur || strlen(cur) <= strlen("-fsanitize=")) { continue; }
|
|
||||||
|
|
||||||
} else if ((!strncmp(cur, "-fsanitize=fuzzer-",
|
|
||||||
|
|
||||||
strlen("-fsanitize=fuzzer-")) ||
|
|
||||||
!strncmp(cur, "-fsanitize-coverage",
|
|
||||||
strlen("-fsanitize-coverage"))) &&
|
|
||||||
(strncmp(cur, "sanitize-coverage-allow",
|
|
||||||
strlen("sanitize-coverage-allow")) &&
|
|
||||||
strncmp(cur, "sanitize-coverage-deny",
|
|
||||||
strlen("sanitize-coverage-deny")) &&
|
|
||||||
instrument_mode != INSTRUMENT_LLVMNATIVE)) {
|
|
||||||
|
|
||||||
if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); }
|
|
||||||
continue;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (need_aflpplib || !strcmp(cur, "-fsanitize=fuzzer")) {
|
|
||||||
|
|
||||||
u8 *afllib = find_object("libAFLDriver.a", argv[0]);
|
|
||||||
|
|
||||||
if (!be_quiet) {
|
|
||||||
|
|
||||||
OKF("Found '-fsanitize=fuzzer', replacing with libAFLDriver.a");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!afllib) {
|
|
||||||
|
|
||||||
if (!be_quiet) {
|
|
||||||
|
|
||||||
WARNF(
|
|
||||||
"Cannot find 'libAFLDriver.a' to replace '-fsanitize=fuzzer' in "
|
|
||||||
"the flags - this will fail!");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
cc_params[cc_par_cnt++] = afllib;
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
cc_params[cc_par_cnt++] = "-undefined";
|
|
||||||
cc_params[cc_par_cnt++] = "dynamic_lookup";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (need_aflpplib) {
|
|
||||||
|
|
||||||
need_aflpplib = 0;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
continue;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strcmp(cur, "-m32")) bit_mode = 32;
|
|
||||||
if (!strcmp(cur, "armv7a-linux-androideabi")) bit_mode = 32;
|
|
||||||
if (!strcmp(cur, "-m64")) bit_mode = 64;
|
|
||||||
|
|
||||||
if (!strcmp(cur, "-fsanitize=address") || !strcmp(cur, "-fsanitize=memory"))
|
|
||||||
asan_set = 1;
|
|
||||||
|
|
||||||
if (strstr(cur, "FORTIFY_SOURCE")) fortify_set = 1;
|
|
||||||
|
|
||||||
if (!strcmp(cur, "-x")) x_set = 1;
|
|
||||||
if (!strcmp(cur, "-E")) preprocessor_only = 1;
|
|
||||||
if (!strcmp(cur, "-shared")) shared_linking = 1;
|
|
||||||
if (!strcmp(cur, "-dynamiclib")) shared_linking = 1;
|
|
||||||
if (!strcmp(cur, "--target=wasm32-wasi")) passthrough = 1;
|
|
||||||
if (!strcmp(cur, "-Wl,-r")) partial_linking = 1;
|
|
||||||
if (!strcmp(cur, "-Wl,-i")) partial_linking = 1;
|
|
||||||
if (!strcmp(cur, "-Wl,--relocatable")) partial_linking = 1;
|
|
||||||
if (!strcmp(cur, "-r")) partial_linking = 1;
|
|
||||||
if (!strcmp(cur, "--relocatable")) partial_linking = 1;
|
|
||||||
if (!strcmp(cur, "-c")) have_c = 1;
|
|
||||||
|
|
||||||
if (!strncmp(cur, "-O", 2)) have_o = 1;
|
|
||||||
if (!strncmp(cur, "-funroll-loop", 13)) have_unroll = 1;
|
|
||||||
|
|
||||||
cc_params[cc_par_cnt++] = cur;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// in case LLVM is installed not via a package manager or "make install"
|
// in case LLVM is installed not via a package manager or "make install"
|
||||||
// e.g. compiled download or compiled from github then its ./lib directory
|
// e.g. compiled download or compiled from github then its ./lib directory
|
||||||
@ -1651,13 +1813,17 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
instrument_mode = INSTRUMENT_CLASSIC;
|
instrument_mode = INSTRUMENT_CLASSIC;
|
||||||
lto_mode = 1;
|
lto_mode = 1;
|
||||||
|
|
||||||
} else if (!instrument_mode || instrument_mode == INSTRUMENT_AFL)
|
} else if (!instrument_mode || instrument_mode == INSTRUMENT_AFL) {
|
||||||
|
|
||||||
instrument_mode = INSTRUMENT_AFL;
|
instrument_mode = INSTRUMENT_AFL;
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
FATAL("main instrumentation mode already set with %s",
|
FATAL("main instrumentation mode already set with %s",
|
||||||
instrument_mode_string[instrument_mode]);
|
instrument_mode_string[instrument_mode]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strncasecmp(ptr2, "pc-guard", strlen("pc-guard")) == 0 ||
|
if (strncasecmp(ptr2, "pc-guard", strlen("pc-guard")) == 0 ||
|
||||||
@ -1682,6 +1848,23 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strncasecmp(ptr2, "llvmcodecov", strlen("llvmcodecov")) == 0 ||
|
||||||
|
strncasecmp(ptr2, "llvm-codecov", strlen("llvm-codecov")) == 0) {
|
||||||
|
|
||||||
|
if (!instrument_mode || instrument_mode == INSTRUMENT_LLVMNATIVE) {
|
||||||
|
|
||||||
|
instrument_mode = INSTRUMENT_LLVMNATIVE;
|
||||||
|
instrument_opt_mode |= INSTRUMENT_OPT_CODECOV;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
FATAL("main instrumentation mode already set with %s",
|
||||||
|
instrument_mode_string[instrument_mode]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (strncasecmp(ptr2, "cfg", strlen("cfg")) == 0 ||
|
if (strncasecmp(ptr2, "cfg", strlen("cfg")) == 0 ||
|
||||||
strncasecmp(ptr2, "instrim", strlen("instrim")) == 0) {
|
strncasecmp(ptr2, "instrim", strlen("instrim")) == 0) {
|
||||||
|
|
||||||
@ -2241,7 +2424,8 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
"(requires LLVM 11 or higher)");
|
"(requires LLVM 11 or higher)");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (instrument_opt_mode && instrument_mode != INSTRUMENT_CLASSIC)
|
if (instrument_opt_mode && instrument_opt_mode != INSTRUMENT_OPT_CODECOV &&
|
||||||
|
instrument_mode != INSTRUMENT_CLASSIC)
|
||||||
FATAL(
|
FATAL(
|
||||||
"CALLER, CTX and NGRAM instrumentation options can only be used with "
|
"CALLER, CTX and NGRAM instrumentation options can only be used with "
|
||||||
"the LLVM CLASSIC instrumentation mode.");
|
"the LLVM CLASSIC instrumentation mode.");
|
||||||
|
@ -489,7 +489,7 @@ static void report_error_and_exit(int error) {
|
|||||||
break;
|
break;
|
||||||
case FS_ERROR_OLD_CMPLOG:
|
case FS_ERROR_OLD_CMPLOG:
|
||||||
FATAL(
|
FATAL(
|
||||||
"the -c cmplog target was instrumented with an too old afl++ "
|
"the -c cmplog target was instrumented with an too old AFL++ "
|
||||||
"version, you need to recompile it.");
|
"version, you need to recompile it.");
|
||||||
break;
|
break;
|
||||||
case FS_ERROR_OLD_CMPLOG_QEMU:
|
case FS_ERROR_OLD_CMPLOG_QEMU:
|
||||||
@ -987,7 +987,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
|||||||
|
|
||||||
if ((status & FS_OPT_ENABLED) == FS_OPT_ENABLED) {
|
if ((status & FS_OPT_ENABLED) == FS_OPT_ENABLED) {
|
||||||
|
|
||||||
// workaround for recent afl++ versions
|
// workaround for recent AFL++ versions
|
||||||
if ((status & FS_OPT_OLD_AFLPP_WORKAROUND) == FS_OPT_OLD_AFLPP_WORKAROUND)
|
if ((status & FS_OPT_OLD_AFLPP_WORKAROUND) == FS_OPT_OLD_AFLPP_WORKAROUND)
|
||||||
status = (status & 0xf0ffffff);
|
status = (status & 0xf0ffffff);
|
||||||
|
|
||||||
@ -1059,7 +1059,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
|||||||
|
|
||||||
FATAL(
|
FATAL(
|
||||||
"Target's coverage map size of %u is larger than the one this "
|
"Target's coverage map size of %u is larger than the one this "
|
||||||
"afl++ is set with (%u). Either set AFL_MAP_SIZE=%u and restart "
|
"AFL++ is set with (%u). Either set AFL_MAP_SIZE=%u and restart "
|
||||||
" afl-fuzz, or change MAP_SIZE_POW2 in config.h and recompile "
|
" afl-fuzz, or change MAP_SIZE_POW2 in config.h and recompile "
|
||||||
"afl-fuzz",
|
"afl-fuzz",
|
||||||
tmp_map_size, fsrv->map_size, tmp_map_size);
|
tmp_map_size, fsrv->map_size, tmp_map_size);
|
||||||
|
@ -716,6 +716,8 @@ void read_testcases(afl_state_t *afl, u8 *directory) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if (getenv("MYTEST")) afl->in_place_resume = 1;
|
||||||
|
|
||||||
if (nl_cnt) {
|
if (nl_cnt) {
|
||||||
|
|
||||||
u32 done = 0;
|
u32 done = 0;
|
||||||
@ -827,6 +829,8 @@ void read_testcases(afl_state_t *afl, u8 *directory) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if (getenv("MYTEST")) afl->in_place_resume = 0;
|
||||||
|
|
||||||
free(nl); /* not tracked */
|
free(nl); /* not tracked */
|
||||||
|
|
||||||
if (!afl->queued_items && directory == NULL) {
|
if (!afl->queued_items && directory == NULL) {
|
||||||
@ -908,8 +912,10 @@ void perform_dry_run(afl_state_t *afl) {
|
|||||||
|
|
||||||
if (res == afl->crash_mode || res == FSRV_RUN_NOBITS) {
|
if (res == afl->crash_mode || res == FSRV_RUN_NOBITS) {
|
||||||
|
|
||||||
SAYF(cGRA " len = %u, map size = %u, exec speed = %llu us\n" cRST,
|
SAYF(cGRA
|
||||||
q->len, q->bitmap_size, q->exec_us);
|
" len = %u, map size = %u, exec speed = %llu us, hash = "
|
||||||
|
"%016llx\n" cRST,
|
||||||
|
q->len, q->bitmap_size, q->exec_us, q->exec_cksum);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1164,14 +1170,14 @@ void perform_dry_run(afl_state_t *afl) {
|
|||||||
|
|
||||||
u32 duplicates = 0, i;
|
u32 duplicates = 0, i;
|
||||||
|
|
||||||
for (idx = 0; idx < afl->queued_items; idx++) {
|
for (idx = 0; idx < afl->queued_items - 1; idx++) {
|
||||||
|
|
||||||
q = afl->queue_buf[idx];
|
q = afl->queue_buf[idx];
|
||||||
if (!q || q->disabled || q->cal_failed || !q->exec_cksum) { continue; }
|
if (!q || q->disabled || q->cal_failed || !q->exec_cksum) { continue; }
|
||||||
|
|
||||||
u32 done = 0;
|
u32 done = 0;
|
||||||
|
|
||||||
for (i = idx + 1;
|
for (i = idx + 1;
|
||||||
i < afl->queued_items && !done && likely(afl->queue_buf[i]); i++) {
|
likely(i < afl->queued_items && afl->queue_buf[i] && !done); ++i) {
|
||||||
|
|
||||||
struct queue_entry *p = afl->queue_buf[i];
|
struct queue_entry *p = afl->queue_buf[i];
|
||||||
if (p->disabled || p->cal_failed || !p->exec_cksum) { continue; }
|
if (p->disabled || p->cal_failed || !p->exec_cksum) { continue; }
|
||||||
@ -1194,6 +1200,13 @@ void perform_dry_run(afl_state_t *afl) {
|
|||||||
p->disabled = 1;
|
p->disabled = 1;
|
||||||
p->perf_score = 0;
|
p->perf_score = 0;
|
||||||
|
|
||||||
|
if (afl->debug) {
|
||||||
|
|
||||||
|
WARNF("Same coverage - %s is kept active, %s is disabled.",
|
||||||
|
q->fname, p->fname);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (!q->was_fuzzed) {
|
if (!q->was_fuzzed) {
|
||||||
@ -1207,7 +1220,14 @@ void perform_dry_run(afl_state_t *afl) {
|
|||||||
q->disabled = 1;
|
q->disabled = 1;
|
||||||
q->perf_score = 0;
|
q->perf_score = 0;
|
||||||
|
|
||||||
done = 1;
|
if (afl->debug) {
|
||||||
|
|
||||||
|
WARNF("Same coverage - %s is kept active, %s is disabled.",
|
||||||
|
p->fname, q->fname);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
done = 1; // end inner loop because outer loop entry is disabled now
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -842,6 +842,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
|||||||
|
|
||||||
eff_map = afl_realloc(AFL_BUF_PARAM(eff), EFF_ALEN(len));
|
eff_map = afl_realloc(AFL_BUF_PARAM(eff), EFF_ALEN(len));
|
||||||
if (unlikely(!eff_map)) { PFATAL("alloc"); }
|
if (unlikely(!eff_map)) { PFATAL("alloc"); }
|
||||||
|
memset(eff_map, 0, EFF_ALEN(len));
|
||||||
eff_map[0] = 1;
|
eff_map[0] = 1;
|
||||||
|
|
||||||
if (EFF_APOS(len - 1) != 0) {
|
if (EFF_APOS(len - 1) != 0) {
|
||||||
@ -2047,20 +2048,22 @@ custom_mutator_stage:
|
|||||||
afl->queue_cur->stats_mutated += afl->stage_max;
|
afl->queue_cur->stats_mutated += afl->stage_max;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (likely(afl->custom_only)) {
|
|
||||||
|
|
||||||
/* Skip other stages */
|
|
||||||
ret_val = 0;
|
|
||||||
goto abandon_entry;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* RANDOM HAVOC *
|
* RANDOM HAVOC *
|
||||||
****************/
|
****************/
|
||||||
|
|
||||||
havoc_stage:
|
havoc_stage:
|
||||||
|
|
||||||
|
if (unlikely(afl->custom_only)) {
|
||||||
|
|
||||||
|
/* Force UI update */
|
||||||
|
show_stats(afl);
|
||||||
|
/* Skip other stages */
|
||||||
|
ret_val = 0;
|
||||||
|
goto abandon_entry;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
afl->stage_cur_byte = -1;
|
afl->stage_cur_byte = -1;
|
||||||
|
|
||||||
/* The havoc stage mutation code is also invoked when splicing files; if the
|
/* The havoc stage mutation code is also invoked when splicing files; if the
|
||||||
@ -3570,6 +3573,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
|
|||||||
|
|
||||||
eff_map = afl_realloc(AFL_BUF_PARAM(eff), EFF_ALEN(len));
|
eff_map = afl_realloc(AFL_BUF_PARAM(eff), EFF_ALEN(len));
|
||||||
if (unlikely(!eff_map)) { PFATAL("alloc"); }
|
if (unlikely(!eff_map)) { PFATAL("alloc"); }
|
||||||
|
memset(eff_map, 0, EFF_ALEN(len));
|
||||||
eff_map[0] = 1;
|
eff_map[0] = 1;
|
||||||
|
|
||||||
if (EFF_APOS(len - 1) != 0) {
|
if (EFF_APOS(len - 1) != 0) {
|
||||||
|
@ -49,11 +49,13 @@ inline u32 select_next_queue_entry(afl_state_t *afl) {
|
|||||||
|
|
||||||
u32 s = rand_below(afl, afl->queued_items);
|
u32 s = rand_below(afl, afl->queued_items);
|
||||||
double p = rand_next_percent(afl);
|
double p = rand_next_percent(afl);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
fprintf(stderr, "select: p=%f s=%u ... p < prob[s]=%f ? s=%u : alias[%u]=%u"
|
fprintf(stderr, "select: p=%f s=%u ... p < prob[s]=%f ? s=%u : alias[%u]=%u"
|
||||||
" ==> %u\n", p, s, afl->alias_probability[s], s, s, afl->alias_table[s], p <
|
" ==> %u\n", p, s, afl->alias_probability[s], s, s, afl->alias_table[s], p <
|
||||||
afl->alias_probability[s] ? s : afl->alias_table[s]);
|
afl->alias_probability[s] ? s : afl->alias_table[s]);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return (p < afl->alias_probability[s] ? s : afl->alias_table[s]);
|
return (p < afl->alias_probability[s] ? s : afl->alias_table[s]);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -87,25 +89,28 @@ double compute_weight(afl_state_t *afl, struct queue_entry *q,
|
|||||||
|
|
||||||
void create_alias_table(afl_state_t *afl) {
|
void create_alias_table(afl_state_t *afl) {
|
||||||
|
|
||||||
u32 n = afl->queued_items, i = 0, a, g;
|
u32 n = afl->queued_items, i = 0, nSmall = 0, nLarge = n - 1;
|
||||||
double sum = 0;
|
double sum = 0;
|
||||||
|
|
||||||
|
double *P = (double *)afl_realloc(AFL_BUF_PARAM(out), n * sizeof(double));
|
||||||
|
u32 *Small = (int *)afl_realloc(AFL_BUF_PARAM(out_scratch), n * sizeof(u32));
|
||||||
|
u32 *Large = (int *)afl_realloc(AFL_BUF_PARAM(in_scratch), n * sizeof(u32));
|
||||||
|
|
||||||
afl->alias_table =
|
afl->alias_table =
|
||||||
(u32 *)afl_realloc((void **)&afl->alias_table, n * sizeof(u32));
|
(u32 *)afl_realloc((void **)&afl->alias_table, n * sizeof(u32));
|
||||||
afl->alias_probability = (double *)afl_realloc(
|
afl->alias_probability = (double *)afl_realloc(
|
||||||
(void **)&afl->alias_probability, n * sizeof(double));
|
(void **)&afl->alias_probability, n * sizeof(double));
|
||||||
double *P = (double *)afl_realloc(AFL_BUF_PARAM(out), n * sizeof(double));
|
|
||||||
int *S = (int *)afl_realloc(AFL_BUF_PARAM(out_scratch), n * sizeof(u32));
|
|
||||||
int *L = (int *)afl_realloc(AFL_BUF_PARAM(in_scratch), n * sizeof(u32));
|
|
||||||
|
|
||||||
if (!P || !S || !L || !afl->alias_table || !afl->alias_probability) {
|
if (!P || !Small || !Large || !afl->alias_table || !afl->alias_probability) {
|
||||||
|
|
||||||
FATAL("could not acquire memory for alias table");
|
FATAL("could not acquire memory for alias table");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memset((void *)afl->alias_table, 0, n * sizeof(u32));
|
|
||||||
memset((void *)afl->alias_probability, 0, n * sizeof(double));
|
memset((void *)afl->alias_probability, 0, n * sizeof(double));
|
||||||
|
memset((void *)afl->alias_table, 0, n * sizeof(u32));
|
||||||
|
memset((void *)Small, 0, n * sizeof(u32));
|
||||||
|
memset((void *)Large, 0, n * sizeof(u32));
|
||||||
|
|
||||||
if (likely(afl->schedule < RARE)) {
|
if (likely(afl->schedule < RARE)) {
|
||||||
|
|
||||||
@ -166,7 +171,15 @@ void create_alias_table(afl_state_t *afl) {
|
|||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
|
|
||||||
// weight is always 0 for disabled entries
|
// weight is always 0 for disabled entries
|
||||||
P[i] = (afl->queue_buf[i]->weight * n) / sum;
|
if (unlikely(afl->queue_buf[i]->disabled)) {
|
||||||
|
|
||||||
|
P[i] = 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
P[i] = (afl->queue_buf[i]->weight * n) / sum;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,60 +189,81 @@ void create_alias_table(afl_state_t *afl) {
|
|||||||
|
|
||||||
struct queue_entry *q = afl->queue_buf[i];
|
struct queue_entry *q = afl->queue_buf[i];
|
||||||
|
|
||||||
if (likely(!q->disabled)) { q->perf_score = calculate_score(afl, q); }
|
if (likely(!q->disabled)) {
|
||||||
|
|
||||||
sum += q->perf_score;
|
q->perf_score = calculate_score(afl, q);
|
||||||
|
sum += q->perf_score;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
|
|
||||||
// perf_score is always 0 for disabled entries
|
// perf_score is always 0 for disabled entries
|
||||||
P[i] = (afl->queue_buf[i]->perf_score * n) / sum;
|
if (unlikely(afl->queue_buf[i]->disabled)) {
|
||||||
|
|
||||||
|
P[i] = 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
P[i] = (afl->queue_buf[i]->perf_score * n) / sum;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int nS = 0, nL = 0, s;
|
// Done collecting weightings in P, now create the arrays.
|
||||||
for (s = (s32)n - 1; s >= 0; --s) {
|
|
||||||
|
|
||||||
if (P[s] < 1) {
|
for (s32 j = (s32)(n - 1); j >= 0; j--) {
|
||||||
|
|
||||||
S[nS++] = s;
|
if (P[j] < 1) {
|
||||||
|
|
||||||
|
Small[nSmall++] = (u32)j;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
L[nL++] = s;
|
Large[nLarge--] = (u32)j;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (nS && nL) {
|
while (nSmall && nLarge != n - 1) {
|
||||||
|
|
||||||
a = S[--nS];
|
u32 small = Small[--nSmall];
|
||||||
g = L[--nL];
|
u32 large = Large[++nLarge];
|
||||||
afl->alias_probability[a] = P[a];
|
|
||||||
afl->alias_table[a] = g;
|
|
||||||
P[g] = P[g] + P[a] - 1;
|
|
||||||
if (P[g] < 1) {
|
|
||||||
|
|
||||||
S[nS++] = g;
|
afl->alias_probability[small] = P[small];
|
||||||
|
afl->alias_table[small] = large;
|
||||||
|
|
||||||
|
P[large] = P[large] - (1 - P[small]);
|
||||||
|
|
||||||
|
if (P[large] < 1) {
|
||||||
|
|
||||||
|
Small[nSmall++] = large;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
L[nL++] = g;
|
Large[nLarge--] = large;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (nL)
|
while (nSmall) {
|
||||||
afl->alias_probability[L[--nL]] = 1;
|
|
||||||
|
|
||||||
while (nS)
|
afl->alias_probability[Small[--nSmall]] = 1;
|
||||||
afl->alias_probability[S[--nS]] = 1;
|
|
||||||
|
}
|
||||||
|
|
||||||
|
while (nLarge != n - 1) {
|
||||||
|
|
||||||
|
afl->alias_probability[Large[++nLarge]] = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
afl->reinit_table = 0;
|
afl->reinit_table = 0;
|
||||||
|
|
||||||
@ -264,7 +298,7 @@ void create_alias_table(afl_state_t *afl) {
|
|||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
fprintf(stderr, " entry alias probability perf_score weight
|
fprintf(stderr, " entry alias probability perf_score weight
|
||||||
filename\n"); for (u32 i = 0; i < n; ++i) fprintf(stderr, " %5u %5u %11u
|
filename\n"); for (i = 0; i < n; ++i) fprintf(stderr, " %5u %5u %11u
|
||||||
%0.9f %0.9f %s\n", i, afl->alias_table[i], afl->alias_probability[i],
|
%0.9f %0.9f %s\n", i, afl->alias_table[i], afl->alias_probability[i],
|
||||||
afl->queue_buf[i]->perf_score, afl->queue_buf[i]->weight,
|
afl->queue_buf[i]->perf_score, afl->queue_buf[i]->weight,
|
||||||
afl->queue_buf[i]->fname);
|
afl->queue_buf[i]->fname);
|
||||||
|
143
src/afl-fuzz.c
143
src/afl-fuzz.c
@ -124,7 +124,8 @@ static void usage(u8 *argv0, int more_help) {
|
|||||||
"\n%s [ options ] -- /path/to/fuzzed_app [ ... ]\n\n"
|
"\n%s [ options ] -- /path/to/fuzzed_app [ ... ]\n\n"
|
||||||
|
|
||||||
"Required parameters:\n"
|
"Required parameters:\n"
|
||||||
" -i dir - input directory with test cases\n"
|
" -i dir - input directory with test cases (or '-' to resume, "
|
||||||
|
"also see AFL_AUTORESUME)\n"
|
||||||
" -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"
|
||||||
@ -1280,16 +1281,16 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
if (afl->fsrv.mem_limit && afl->shm.cmplog_mode) afl->fsrv.mem_limit += 260;
|
if (afl->fsrv.mem_limit && afl->shm.cmplog_mode) afl->fsrv.mem_limit += 260;
|
||||||
|
|
||||||
OKF("afl++ is maintained by Marc \"van Hauser\" Heuse, Heiko \"hexcoder\" "
|
OKF("AFL++ is maintained by Marc \"van Hauser\" Heuse, Dominik Maier, Andrea "
|
||||||
"Eißfeldt, Andrea Fioraldi and Dominik Maier");
|
"Fioraldi and Heiko \"hexcoder\" Eißfeldt");
|
||||||
OKF("afl++ is open source, get it at "
|
OKF("AFL++ is open source, get it at "
|
||||||
"https://github.com/AFLplusplus/AFLplusplus");
|
"https://github.com/AFLplusplus/AFLplusplus");
|
||||||
OKF("NOTE: afl++ >= v3 has changed defaults and behaviours - see README.md");
|
OKF("NOTE: AFL++ >= v3 has changed defaults and behaviours - see README.md");
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
if (afl->fsrv.nyx_mode) {
|
if (afl->fsrv.nyx_mode) {
|
||||||
|
|
||||||
OKF("afl++ Nyx mode is enabled (developed and mainted by Sergej Schumilo)");
|
OKF("AFL++ Nyx mode is enabled (developed and mainted by Sergej Schumilo)");
|
||||||
OKF("Nyx is open source, get it at https://github.com/Nyx-Fuzz");
|
OKF("Nyx is open source, get it at https://github.com/Nyx-Fuzz");
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1529,29 +1530,6 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (afl->limit_time_sig > 0 && afl->custom_mutators_count) {
|
|
||||||
|
|
||||||
if (afl->custom_only) {
|
|
||||||
|
|
||||||
FATAL("Custom mutators are incompatible with MOpt (-L)");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 custom_fuzz = 0;
|
|
||||||
LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
|
|
||||||
|
|
||||||
if (el->afl_custom_fuzz) { custom_fuzz = 1; }
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
if (custom_fuzz) {
|
|
||||||
|
|
||||||
WARNF("afl_custom_fuzz is incompatible with MOpt (-L)");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (afl->afl_env.afl_max_det_extras) {
|
if (afl->afl_env.afl_max_det_extras) {
|
||||||
|
|
||||||
s32 max_det_extras = atoi(afl->afl_env.afl_max_det_extras);
|
s32 max_det_extras = atoi(afl->afl_env.afl_max_det_extras);
|
||||||
@ -1826,8 +1804,76 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
printf("DEBUG: rand %06d is %u\n", counter, rand_below(afl, 65536));
|
printf("DEBUG: rand %06d is %u\n", counter, rand_below(afl, 65536));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (!getenv("AFL_CUSTOM_INFO_PROGRAM")) {
|
||||||
|
|
||||||
|
setenv("AFL_CUSTOM_INFO_PROGRAM", argv[optind], 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!getenv("AFL_CUSTOM_INFO_PROGRAM_INPUT") && afl->fsrv.out_file) {
|
||||||
|
|
||||||
|
setenv("AFL_CUSTOM_INFO_PROGRAM_INPUT", afl->fsrv.out_file, 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
u8 envbuf[8096] = "", tmpbuf[8096] = "";
|
||||||
|
for (s32 i = optind + 1; i < argc; ++i) {
|
||||||
|
|
||||||
|
strcpy(tmpbuf, envbuf);
|
||||||
|
if (strchr(argv[i], ' ') && !strchr(argv[i], '"') &&
|
||||||
|
!strchr(argv[i], '\'')) {
|
||||||
|
|
||||||
|
if (!strchr(argv[i], '\'')) {
|
||||||
|
|
||||||
|
snprintf(envbuf, sizeof(tmpbuf), "%s '%s'", tmpbuf, argv[i]);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
snprintf(envbuf, sizeof(tmpbuf), "%s \"%s\"", tmpbuf, argv[i]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
snprintf(envbuf, sizeof(tmpbuf), "%s %s", tmpbuf, argv[i]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
setenv("AFL_CUSTOM_INFO_PROGRAM_ARGV", envbuf + 1, 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
setenv("AFL_CUSTOM_INFO_OUT", afl->out_dir, 1); // same as __AFL_OUT_DIR
|
||||||
|
|
||||||
setup_custom_mutators(afl);
|
setup_custom_mutators(afl);
|
||||||
|
|
||||||
|
if (afl->limit_time_sig > 0 && afl->custom_mutators_count) {
|
||||||
|
|
||||||
|
if (afl->custom_only) {
|
||||||
|
|
||||||
|
FATAL("Custom mutators are incompatible with MOpt (-L)");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 custom_fuzz = 0;
|
||||||
|
LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
|
||||||
|
|
||||||
|
if (el->afl_custom_fuzz) { custom_fuzz = 1; }
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
if (custom_fuzz) {
|
||||||
|
|
||||||
|
WARNF("afl_custom_fuzz is incompatible with MOpt (-L)");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
write_setup_file(afl, argc, argv);
|
write_setup_file(afl, argc, argv);
|
||||||
|
|
||||||
setup_cmdline_file(afl, argv + optind);
|
setup_cmdline_file(afl, argv + optind);
|
||||||
@ -1979,6 +2025,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
if (afl->non_instrumented_mode || afl->fsrv.qemu_mode ||
|
if (afl->non_instrumented_mode || afl->fsrv.qemu_mode ||
|
||||||
afl->fsrv.frida_mode || afl->fsrv.cs_mode || afl->unicorn_mode) {
|
afl->fsrv.frida_mode || afl->fsrv.cs_mode || afl->unicorn_mode) {
|
||||||
|
|
||||||
|
u32 old_map_size = map_size;
|
||||||
map_size = afl->fsrv.real_map_size = afl->fsrv.map_size = MAP_SIZE;
|
map_size = afl->fsrv.real_map_size = afl->fsrv.map_size = MAP_SIZE;
|
||||||
afl->virgin_bits = ck_realloc(afl->virgin_bits, map_size);
|
afl->virgin_bits = ck_realloc(afl->virgin_bits, map_size);
|
||||||
afl->virgin_tmout = ck_realloc(afl->virgin_tmout, map_size);
|
afl->virgin_tmout = ck_realloc(afl->virgin_tmout, map_size);
|
||||||
@ -1990,6 +2037,18 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
afl->first_trace = ck_realloc(afl->first_trace, map_size);
|
afl->first_trace = ck_realloc(afl->first_trace, map_size);
|
||||||
afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, map_size);
|
afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, map_size);
|
||||||
|
|
||||||
|
if (old_map_size < map_size) {
|
||||||
|
|
||||||
|
memset(afl->var_bytes + old_map_size, 0, map_size - old_map_size);
|
||||||
|
memset(afl->top_rated + old_map_size, 0, map_size - old_map_size);
|
||||||
|
memset(afl->clean_trace + old_map_size, 0, map_size - old_map_size);
|
||||||
|
memset(afl->clean_trace_custom + old_map_size, 0,
|
||||||
|
map_size - old_map_size);
|
||||||
|
memset(afl->first_trace + old_map_size, 0, map_size - old_map_size);
|
||||||
|
memset(afl->map_tmp_buf + old_map_size, 0, map_size - old_map_size);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
afl->argv = use_argv;
|
afl->argv = use_argv;
|
||||||
@ -2017,6 +2076,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
OKF("Re-initializing maps to %u bytes", new_map_size);
|
OKF("Re-initializing maps to %u bytes", new_map_size);
|
||||||
|
|
||||||
|
u32 old_map_size = map_size;
|
||||||
afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size);
|
afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size);
|
||||||
afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size);
|
afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size);
|
||||||
afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size);
|
afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size);
|
||||||
@ -2029,6 +2089,18 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
afl->first_trace = ck_realloc(afl->first_trace, new_map_size);
|
afl->first_trace = ck_realloc(afl->first_trace, new_map_size);
|
||||||
afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size);
|
afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size);
|
||||||
|
|
||||||
|
if (old_map_size < new_map_size) {
|
||||||
|
|
||||||
|
memset(afl->var_bytes + old_map_size, 0, new_map_size - old_map_size);
|
||||||
|
memset(afl->top_rated + old_map_size, 0, new_map_size - old_map_size);
|
||||||
|
memset(afl->clean_trace + old_map_size, 0, new_map_size - old_map_size);
|
||||||
|
memset(afl->clean_trace_custom + old_map_size, 0,
|
||||||
|
new_map_size - old_map_size);
|
||||||
|
memset(afl->first_trace + old_map_size, 0, new_map_size - old_map_size);
|
||||||
|
memset(afl->map_tmp_buf + old_map_size, 0, new_map_size - old_map_size);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
afl_fsrv_kill(&afl->fsrv);
|
afl_fsrv_kill(&afl->fsrv);
|
||||||
afl_shm_deinit(&afl->shm);
|
afl_shm_deinit(&afl->shm);
|
||||||
afl->fsrv.map_size = new_map_size;
|
afl->fsrv.map_size = new_map_size;
|
||||||
@ -2079,6 +2151,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
OKF("Re-initializing maps to %u bytes due cmplog", new_map_size);
|
OKF("Re-initializing maps to %u bytes due cmplog", new_map_size);
|
||||||
|
|
||||||
|
u32 old_map_size = map_size;
|
||||||
afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size);
|
afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size);
|
||||||
afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size);
|
afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size);
|
||||||
afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size);
|
afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size);
|
||||||
@ -2091,6 +2164,18 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
afl->first_trace = ck_realloc(afl->first_trace, new_map_size);
|
afl->first_trace = ck_realloc(afl->first_trace, new_map_size);
|
||||||
afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size);
|
afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size);
|
||||||
|
|
||||||
|
if (old_map_size < new_map_size) {
|
||||||
|
|
||||||
|
memset(afl->var_bytes + old_map_size, 0, new_map_size - old_map_size);
|
||||||
|
memset(afl->top_rated + old_map_size, 0, new_map_size - old_map_size);
|
||||||
|
memset(afl->clean_trace + old_map_size, 0, new_map_size - old_map_size);
|
||||||
|
memset(afl->clean_trace_custom + old_map_size, 0,
|
||||||
|
new_map_size - old_map_size);
|
||||||
|
memset(afl->first_trace + old_map_size, 0, new_map_size - old_map_size);
|
||||||
|
memset(afl->map_tmp_buf + old_map_size, 0, new_map_size - old_map_size);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
afl_fsrv_kill(&afl->fsrv);
|
afl_fsrv_kill(&afl->fsrv);
|
||||||
afl_fsrv_kill(&afl->cmplog_fsrv);
|
afl_fsrv_kill(&afl->cmplog_fsrv);
|
||||||
afl_shm_deinit(&afl->shm);
|
afl_shm_deinit(&afl->shm);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
american fuzzy lop++ - wrapper for llvm 11+ lld
|
american fuzzy lop++ - wrapper for llvm 11+ lld
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
|
|
||||||
Written by Marc Heuse <mh@mh-sec.de> for afl++
|
Written by Marc Heuse <mh@mh-sec.de> for AFL++
|
||||||
|
|
||||||
Maintained by Marc Heuse <mh@mh-sec.de>,
|
Maintained by Marc Heuse <mh@mh-sec.de>,
|
||||||
Heiko Eißfeldt <heiko.eissfeldt@hexco.de>
|
Heiko Eißfeldt <heiko.eissfeldt@hexco.de>
|
||||||
@ -210,7 +210,7 @@ static void edit_params(int argc, char **argv) {
|
|||||||
|
|
||||||
if (strcmp(argv[i], "--afl") == 0) {
|
if (strcmp(argv[i], "--afl") == 0) {
|
||||||
|
|
||||||
if (!be_quiet) OKF("afl++ test command line flag detected, exiting.");
|
if (!be_quiet) OKF("AFL++ test command line flag detected, exiting.");
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1287,7 +1287,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'Y': // fallthough
|
case 'Y': // fallthrough
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
case 'X': /* NYX mode */
|
case 'X': /* NYX mode */
|
||||||
|
|
||||||
@ -1421,6 +1421,14 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
// If @@ are in the target args, replace them and also set use_stdin=false.
|
// If @@ are in the target args, replace them and also set use_stdin=false.
|
||||||
detect_file_args(argv + optind, stdin_file, &fsrv->use_stdin);
|
detect_file_args(argv + optind, stdin_file, &fsrv->use_stdin);
|
||||||
|
|
||||||
|
fsrv->dev_null_fd = open("/dev/null", O_RDWR);
|
||||||
|
if (fsrv->dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); }
|
||||||
|
|
||||||
|
fsrv->out_file = stdin_file;
|
||||||
|
fsrv->out_fd =
|
||||||
|
open(stdin_file, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
|
||||||
|
if (fsrv->out_fd < 0) { PFATAL("Unable to create '%s'", stdin_file); }
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// If @@ are in the target args, replace them and also set use_stdin=false.
|
// If @@ are in the target args, replace them and also set use_stdin=false.
|
||||||
@ -1588,6 +1596,14 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
fsrv->map_size = map_size;
|
fsrv->map_size = map_size;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
afl_fsrv_start(fsrv, use_argv, &stop_soon,
|
||||||
|
(get_afl_env("AFL_DEBUG_CHILD") ||
|
||||||
|
get_afl_env("AFL_DEBUG_CHILD_OUTPUT"))
|
||||||
|
? 1
|
||||||
|
: 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_dir || in_filelist) {
|
if (in_dir || in_filelist) {
|
||||||
@ -1617,9 +1633,6 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
if (getenv("AFL_DEBUG_GDB")) wait_for_gdb = true;
|
if (getenv("AFL_DEBUG_GDB")) wait_for_gdb = true;
|
||||||
|
|
||||||
fsrv->dev_null_fd = open("/dev/null", O_RDWR);
|
|
||||||
if (fsrv->dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); }
|
|
||||||
|
|
||||||
if (in_filelist) {
|
if (in_filelist) {
|
||||||
|
|
||||||
if (!be_quiet) ACTF("Reading from file list '%s'...", in_filelist);
|
if (!be_quiet) ACTF("Reading from file list '%s'...", in_filelist);
|
||||||
@ -1666,10 +1679,6 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
atexit(at_exit_handler);
|
atexit(at_exit_handler);
|
||||||
fsrv->out_file = stdin_file;
|
|
||||||
fsrv->out_fd =
|
|
||||||
open(stdin_file, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
|
|
||||||
if (fsrv->out_fd < 0) { PFATAL("Unable to create '%s'", out_file); }
|
|
||||||
|
|
||||||
if (get_afl_env("AFL_DEBUG")) {
|
if (get_afl_env("AFL_DEBUG")) {
|
||||||
|
|
||||||
@ -1685,12 +1694,6 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
afl_fsrv_start(fsrv, use_argv, &stop_soon,
|
|
||||||
(get_afl_env("AFL_DEBUG_CHILD") ||
|
|
||||||
get_afl_env("AFL_DEBUG_CHILD_OUTPUT"))
|
|
||||||
? 1
|
|
||||||
: 0);
|
|
||||||
|
|
||||||
map_size = fsrv->map_size;
|
map_size = fsrv->map_size;
|
||||||
|
|
||||||
if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz)
|
if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz)
|
||||||
|
@ -28,7 +28,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// must use deferred forkserver as otherwise afl++ instrumentation aborts
|
// must use deferred forkserver as otherwise AFL++ instrumentation aborts
|
||||||
// because all dlopen() of instrumented libs must be before the forkserver
|
// because all dlopen() of instrumented libs must be before the forkserver
|
||||||
__AFL_INIT();
|
__AFL_INIT();
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ test -e ../afl-gcc-fast -a -e ../afl-compiler-rt.o && {
|
|||||||
$ECHO "$GREEN[+] gcc_plugin run reported $TUPLES instrumented locations which is fine"
|
$ECHO "$GREEN[+] gcc_plugin run reported $TUPLES instrumented locations which is fine"
|
||||||
} || {
|
} || {
|
||||||
$ECHO "$RED[!] gcc_plugin instrumentation produces a weird numbers: $TUPLES"
|
$ECHO "$RED[!] gcc_plugin instrumentation produces a weird numbers: $TUPLES"
|
||||||
$ECHO "$YELLOW[-] this is a known issue in gcc, not afl++. It is not flagged as an error because travis builds would all fail otherwise :-("
|
$ECHO "$YELLOW[-] this is a known issue in gcc, not AFL++. It is not flagged as an error because travis builds would all fail otherwise :-("
|
||||||
#CODE=1
|
#CODE=1
|
||||||
}
|
}
|
||||||
test "$TUPLES" -lt 2 && SKIP=1
|
test "$TUPLES" -lt 2 && SKIP=1
|
||||||
|
@ -263,7 +263,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
|
|||||||
{
|
{
|
||||||
mkdir -p in
|
mkdir -p in
|
||||||
echo 00000000000000000000000000000000 > in/in
|
echo 00000000000000000000000000000000 > in/in
|
||||||
AFL_BENCH_UNTIL_CRASH=1 ../afl-fuzz -m none -V15 -i in -o out -c./test-cmplog -- ./test-c >>errors 2>&1
|
AFL_BENCH_UNTIL_CRASH=1 ../afl-fuzz -m none -V30 -i in -o out -c./test-cmplog -- ./test-c >>errors 2>&1
|
||||||
} >>errors 2>&1
|
} >>errors 2>&1
|
||||||
test -n "$( ls out/default/crashes/id:000000* out/default/hangs/id:000000* 2>/dev/null )" && {
|
test -n "$( ls out/default/crashes/id:000000* out/default/hangs/id:000000* 2>/dev/null )" && {
|
||||||
$ECHO "$GREEN[+] afl-fuzz is working correctly with llvm_mode cmplog"
|
$ECHO "$GREEN[+] afl-fuzz is working correctly with llvm_mode cmplog"
|
||||||
|
@ -7,7 +7,7 @@ FILE=$AFL_PERFORMANCE_FILE
|
|||||||
test -z "$FILE" && FILE=.afl_performance
|
test -z "$FILE" && FILE=.afl_performance
|
||||||
|
|
||||||
test -e $FILE || {
|
test -e $FILE || {
|
||||||
echo Warning: This script measure the performance of afl++ and saves the result for future comparisons into $FILE
|
echo Warning: This script measure the performance of AFL++ and saves the result for future comparisons into $FILE
|
||||||
echo Press ENTER to continue or CONTROL-C to abort
|
echo Press ENTER to continue or CONTROL-C to abort
|
||||||
read IN
|
read IN
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ afl-system-config > /dev/null 2>&1
|
|||||||
echo Performance settings applied.
|
echo Performance settings applied.
|
||||||
echo
|
echo
|
||||||
|
|
||||||
$ECHO "${RESET}${GREY}[*] starting afl++ performance test framework ..."
|
$ECHO "${RESET}${GREY}[*] starting AFL++ performance test framework ..."
|
||||||
|
|
||||||
$ECHO "$BLUE[*] Testing: ${AFL_GCC}"
|
$ECHO "$BLUE[*] Testing: ${AFL_GCC}"
|
||||||
GCC=x
|
GCC=x
|
||||||
|
@ -133,7 +133,7 @@ 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 ..."
|
||||||
|
|
||||||
test -z "$SYS" && $ECHO "$YELLOW[-] uname -m did not succeed"
|
test -z "$SYS" && $ECHO "$YELLOW[-] uname -m did not succeed"
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ git pull
|
|||||||
sh -c 'git stash && git stash drop' 1>/dev/null 2>/dev/null
|
sh -c 'git stash && git stash drop' 1>/dev/null 2>/dev/null
|
||||||
git checkout "$UNICORNAFL_VERSION" || exit 1
|
git checkout "$UNICORNAFL_VERSION" || exit 1
|
||||||
|
|
||||||
echo "[*] making sure afl++ header files match"
|
echo "[*] making sure AFL++ header files match"
|
||||||
cp "../../include/config.h" "./include" || exit 1
|
cp "../../include/config.h" "./include" || exit 1
|
||||||
|
|
||||||
echo "[*] Configuring Unicorn build..."
|
echo "[*] Configuring Unicorn build..."
|
||||||
|
Loading…
x
Reference in New Issue
Block a user