From c4b1566ba35c697cda7822bd0cf30e2e3eeee0c7 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 15 May 2023 11:51:37 +0300 Subject: 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 * 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 Co-authored-by: Nick Potenski Co-authored-by: Christian Holler (:decoder) Co-authored-by: lazymio Co-authored-by: Moshe Kaplan Co-authored-by: Sergej Schumilo Co-authored-by: Dominik Maier --- .github/workflows/ci.yml | 40 +- Dockerfile | 4 +- GNUmakefile | 17 +- GNUmakefile.gcc_plugin | 6 +- GNUmakefile.llvm | 11 +- README.md | 2 +- afl-cmin | 2 +- afl-system-config | 3 +- afl-whatsup | 3 + custom_mutators/aflpp_tritondse/README.md | 17 + custom_mutators/aflpp_tritondse/aflpp_tritondse.py | 148 ++++++ docs/Changelog.md | 6 +- docs/FAQ.md | 8 + docs/INSTALL.md | 12 +- docs/best_practices.md | 5 + docs/custom_mutators.md | 28 ++ docs/tutorials.md | 4 + frida_mode/README.md | 2 + include/afl-fuzz.h | 4 +- include/alloc-inl.h | 9 +- include/envs.h | 4 + instrumentation/README.llvm.md | 24 + instrumentation/SanitizerCoverageLTO.so.cc | 32 +- instrumentation/SanitizerCoveragePCGUARD.so.cc | 2 + instrumentation/afl-compiler-rt.o.c | 249 +++++++++++ instrumentation/afl-llvm-common.cc | 2 +- instrumentation/afl-llvm-dict2file.so.cc | 2 +- nyx_mode/LIBNYX_VERSION | 2 +- qemu_mode/QEMUAFL_VERSION | 2 +- qemu_mode/build_qemu_support.sh | 4 +- qemu_mode/qemuafl | 2 +- src/afl-cc.c | 498 ++++++++++++++------- src/afl-forkserver.c | 6 +- src/afl-fuzz-init.c | 32 +- src/afl-fuzz-one.c | 18 +- src/afl-fuzz-queue.c | 92 ++-- src/afl-fuzz.c | 143 ++++-- src/afl-ld-lto.c | 4 +- src/afl-showmap.c | 31 +- test/test-dlopen.c | 2 +- test/test-gcc-plugin.sh | 2 +- test/test-llvm.sh | 2 +- test/test-performance.sh | 4 +- test/test-pre.sh | 2 +- unicorn_mode/build_unicorn_support.sh | 2 +- 45 files changed, 1164 insertions(+), 330 deletions(-) create mode 100644 custom_mutators/aflpp_tritondse/README.md create mode 100644 custom_mutators/aflpp_tritondse/aflpp_tritondse.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 03e4151d..fdf618b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,23 +36,23 @@ jobs: run: make distrib ASAN_BUILD=1 NO_NYX=1 - name: run tests run: sudo -E ./afl-system-config; make tests - macos: - runs-on: macOS-latest - env: - AFL_MAP_SIZE: 65536 - AFL_SKIP_CPUFREQ: 1 - AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1 - steps: - - uses: actions/checkout@v3 - - name: install - run: brew install make gcc llvm - - name: fix install - run: cd /usr/local/bin; ln -s gcc-11 gcc; ln -s g++-11 g++; which gcc; gcc -v - - 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 - - name: frida - run: export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; cd frida_mode; gmake - - 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 - - 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 + # macos: + # runs-on: macOS-latest + # env: + # AFL_MAP_SIZE: 65536 + # AFL_SKIP_CPUFREQ: 1 + # AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1 + # steps: + # - uses: actions/checkout@v3 + # - name: install + # run: brew install make gcc llvm + # - name: fix install + # run: cd /usr/local/bin; ln -s gcc-11 gcc; ln -s g++-11 g++; which gcc; gcc -v + # - 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 + # - name: frida + # run: export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; cd frida_mode; gmake + # - 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 + # - 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 diff --git a/Dockerfile b/Dockerfile index 4e53de40..1b5ffd28 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,7 @@ # FROM ubuntu:22.04 AS aflplusplus -LABEL "maintainer"="afl++ team " +LABEL "maintainer"="AFL++ team " LABEL "about"="AFLplusplus container image" ### 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 && \ echo ". /etc/bash_completion" >> ~/.bashrc && \ echo 'alias joe="joe --wordwrap --joe_state -nobackup"' >> ~/.bashrc && \ - echo "export PS1='"'[afl++ \h] \w \$ '"'" >> ~/.bashrc + echo "export PS1='"'[AFL++ \h] \w \$ '"'" >> ~/.bashrc diff --git a/GNUmakefile b/GNUmakefile index 23cae65d..31374c10 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -39,7 +39,7 @@ ASAN_OPTIONS=detect_leaks=0 SYS = $(shell uname -s) 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 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-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 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" @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 @@ -359,7 +359,7 @@ performance-test: source-only help: @echo "HELP --- the following make targets exist:" @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 "source-only: everything for source code fuzzing: nyx_mode, libdislocator, libtokencap" @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 "clean: cleans everything compiled (not downloads when on a checkout)" @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 "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)" @@ -379,6 +379,7 @@ help: @echo Known build environment options: @echo "==========================================" @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 UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for debug purposes @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 "LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config (e.g., Debian)" @echo "==========================================" - @echo e.g.: make ASAN_BUILD=1 + @echo e.g.: make LLVM_CONFIG=llvm-config-16 .PHONY: test_x86 ifndef AFL_NO_X86 @@ -749,7 +750,7 @@ endif @echo %.8: % - @echo .TH $* 8 $(BUILD_DATE) "afl++" > $@ + @echo .TH $* 8 $(BUILD_DATE) "AFL++" > $@ @echo .SH NAME >> $@ @echo .B $* >> $@ @echo >> $@ @@ -761,8 +762,8 @@ endif @./$* -hh 2>&1 | tail -n +4 >> $@ @echo >> $@ @echo .SH AUTHOR >> $@ - @echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Heiko \"hexcoder-\" Eissfeldt , Andrea Fioraldi and Dominik Maier " >> $@ - @echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> $@ + @echo "AFL++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Dominik Maier , Andrea Fioraldi and Heiko \"hexcoder-\" Eissfeldt " >> $@ + @echo The homepage of AFL++ is: https://github.com/AFLplusplus/AFLplusplus >> $@ @echo >> $@ @echo .SH LICENSE >> $@ @echo Apache License Version 2.0, January 2004 >> $@ diff --git a/GNUmakefile.gcc_plugin b/GNUmakefile.gcc_plugin index 4c4e10c4..41face4c 100644 --- a/GNUmakefile.gcc_plugin +++ b/GNUmakefile.gcc_plugin @@ -175,7 +175,7 @@ all_done: test_build .NOTPARALLEL: clean %.8: % - @echo .TH $* 8 `date "+%Y-%m-%d"` "afl++" > ./$@ + @echo .TH $* 8 `date "+%Y-%m-%d"` "AFL++" > ./$@ @echo .SH NAME >> ./$@ @echo .B $* >> ./$@ @echo >> ./$@ @@ -187,8 +187,8 @@ all_done: test_build @./$* -h 2>&1 | tail -n +4 >> ./$@ @echo >> ./$@ @echo .SH AUTHOR >> ./$@ - @echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Heiko \"hexcoder-\" Eissfeldt , Andrea Fioraldi and Dominik Maier " >> ./$@ - @echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> ./$@ + @echo "AFL++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Dominik Maier , Andrea Fioraldi and Heiko \"hexcoder-\" Eissfeldt " >> ./$@ + @echo The homepage of AFL++ is: https://github.com/AFLplusplus/AFLplusplus >> ./$@ @echo >> ./$@ @echo .SH LICENSE >> ./$@ @echo Apache License Version 2.0, January 2004 >> ./$@ diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm index a053403b..2bb4e7f8 100644 --- a/GNUmakefile.llvm +++ b/GNUmakefile.llvm @@ -274,6 +274,11 @@ ifndef LLVM_DEBUG CFLAGS_SAFE += -Wno-deprecated endif +ifdef CODE_COVERAGE + override CFLAGS_SAFE += -D__AFL_CODE_COVERAGE=1 + override LDFLAGS += -ldl +endif + override CFLAGS += $(CFLAGS_SAFE) ifdef AFL_TRACE_PC @@ -510,7 +515,7 @@ install: all install -m 644 instrumentation/README.*.md $${DESTDIR}$(DOC_PATH)/ %.8: % - @echo .TH $* 8 $(BUILD_DATE) "afl++" > ./$@ + @echo .TH $* 8 $(BUILD_DATE) "AFL++" > ./$@ @echo .SH NAME >> ./$@ @printf "%s" ".B $* \- " >> ./$@ @./$* -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 >> ./$@ @echo >> ./$@ @echo .SH AUTHOR >> ./$@ - @echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Heiko \"hexcoder-\" Eissfeldt , Andrea Fioraldi and Dominik Maier " >> ./$@ - @echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> ./$@ + @echo "AFL++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Dominik Maier , Andrea Fioraldi and Heiko \"hexcoder-\" Eissfeldt " >> ./$@ + @echo The homepage of AFL++ is: https://github.com/AFLplusplus/AFLplusplus >> ./$@ @echo >> ./$@ @echo .SH LICENSE >> ./$@ @echo Apache License Version 2.0, January 2004 >> ./$@ diff --git a/README.md b/README.md index c012c400..863c2fce 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,9 @@ Repository: AFL++ is maintained by: * Marc "van Hauser" Heuse -* Heiko "hexcoder-" Eißfeldt * Andrea Fioraldi * Dominik Maier +* Heiko "hexcoder-" Eißfeldt * Documentation: Jana Aydinbas Originally developed by Michał "lcamtuf" Zalewski. diff --git a/afl-cmin b/afl-cmin index 63cfdd7e..ae723c1b 100755 --- a/afl-cmin +++ b/afl-cmin @@ -149,7 +149,7 @@ BEGIN { redirected = 0 } - print "corpus minimization tool for afl++ (awk version)\n" + print "corpus minimization tool for AFL++ (awk version)\n" # defaults extra_par = "" diff --git a/afl-system-config b/afl-system-config index bf6397fa..b50bb06e 100755 --- a/afl-system-config +++ b/afl-system-config @@ -110,7 +110,7 @@ if [ "$PLATFORM" = "Darwin" ] ; then sysctl kern.sysv.shmall=131072000 echo Settings applied. echo - if [ $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') ] ; then + if $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') ; then echo echo Unloading the default crash reporter SL=/System/Library; PL=com.apple.ReportCrash @@ -119,6 +119,7 @@ if [ "$PLATFORM" = "Darwin" ] ; then echo fi 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 DONE=1 fi diff --git a/afl-whatsup b/afl-whatsup index cec1ae28..6f29ab24 100755 --- a/afl-whatsup +++ b/afl-whatsup @@ -88,6 +88,7 @@ TOTAL_TIME=0 TOTAL_EXECS=0 TOTAL_EPS=0 TOTAL_CRASHES=0 +TOTAL_HANGS=0 TOTAL_PFAV=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_EXECS=$((TOTAL_EXECS + execs_done)) TOTAL_CRASHES=$((TOTAL_CRASHES + saved_crashes)) + TOTAL_HANGS=$((TOTAL_HANGS + saved_hangs)) TOTAL_PENDING=$((TOTAL_PENDING + pending_total)) TOTAL_PFAV=$((TOTAL_PFAV + pending_favs)) @@ -301,6 +303,7 @@ if [ "$ALIVE_CNT" -gt "1" ]; then fi echo " Crashes saved : $TOTAL_CRASHES" +echo " Hangs saved : $TOTAL_HANGS" echo "Cycles without finds : $TOTAL_WCOP" echo " Time without finds : $TOTAL_LAST_FIND" echo diff --git a/custom_mutators/aflpp_tritondse/README.md b/custom_mutators/aflpp_tritondse/README.md new file mode 100644 index 00000000..8a5dd02b --- /dev/null +++ b/custom_mutators/aflpp_tritondse/README.md @@ -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. diff --git a/custom_mutators/aflpp_tritondse/aflpp_tritondse.py b/custom_mutators/aflpp_tritondse/aflpp_tritondse.py new file mode 100644 index 00000000..e0219f0b --- /dev/null +++ b/custom_mutators/aflpp_tritondse/aflpp_tritondse.py @@ -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 diff --git a/docs/Changelog.md b/docs/Changelog.md index 20b915fa..3602af50 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -11,13 +11,17 @@ - new env `AFL_IGNORE_PROBLEMS_COVERAGE` to ignore coverage from loaded libs after forkserver initialization (required by Mozilla) - afl-cc: + - added @responsefile support - new env `AFL_LLVM_LTO_SKIPINIT` to support the AFL++ based WASM (https://github.com/fgsect/WAFL) project + - error and print help if afl-clan-lto is used with lto=thin - afl-showmap: - added custom mutator post_process and send support - add `-I filelist` option, an alternative to `-i in_dir` - afl-cmin + afl-cmin.bash: - `-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 ! @@ -229,7 +233,7 @@ afl-showmap and other tools. - afl-cc: - 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 - fix for shared linking on MacOS - better selective instrumentation AFL_LLVM_{ALLOW|DENY}LIST diff --git a/docs/FAQ.md b/docs/FAQ.md index 76350c79..8178db46 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -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 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 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 diff --git a/docs/INSTALL.md b/docs/INSTALL.md index 591b7ded..637e8658 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -51,7 +51,7 @@ make source-only 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, qemu_mode, frida_mode, unicorn_mode, coresight_mode, libdislocator, libtokencap @@ -79,22 +79,20 @@ make STATIC=1 These build options exist: * 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 -* UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for - debug purposes +* UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for debug purposes * DEBUG - no optimization, -ggdb3, all warnings and -Werror * LLVM_DEBUG - shows llvm deprecation warnings * PROFILING - compile afl-fuzz with profiling information * INTROSPECTION - compile afl-fuzz with mutation introspection * NO_PYTHON - disable python support -* NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for - normal fuzzing +* NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for normal fuzzing * NO_NYX - disable building nyx mode dependencies * NO_CORESIGHT - disable building coresight (arm64 only) * NO_UNICORN_ARM64 - disable building unicorn on arm64 * AFL_NO_X86 - if compiling on non-intel/amd platforms -* LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config - (e.g., Debian) +* LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config (e.g., Debian) e.g.: `make LLVM_CONFIG=llvm-config-14` diff --git a/docs/best_practices.md b/docs/best_practices.md index 133c645e..459fcaf7 100644 --- a/docs/best_practices.md +++ b/docs/best_practices.md @@ -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 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 coding and/or disassembly and is effectively possible only with `afl-clang-fast` `PCGUARD` and `afl-clang-lto` `LTO` instrumentation. diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index a1de479e..3f7e9e6e 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -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: `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 For C/C++ mutators, the source code must be compiled as a shared object: diff --git a/docs/tutorials.md b/docs/tutorials.md index 758fddab..342080fd 100644 --- a/docs/tutorials.md +++ b/docs/tutorials.md @@ -20,6 +20,10 @@ training, then we can highly recommend the following: * [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 structure is), these links have you covered (some are outdated though): diff --git a/frida_mode/README.md b/frida_mode/README.md index 49a1fe38..bfca443c 100644 --- a/frida_mode/README.md +++ b/frida_mode/README.md @@ -7,6 +7,8 @@ variables. 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 As FRIDA mode is new, it is missing a lot of features. The design is such that diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 831a0dbc..8fb7ecb1 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -1223,7 +1223,7 @@ double rand_next_percent(afl_state_t *afl); 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, 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 */ 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)) { diff --git a/include/alloc-inl.h b/include/alloc-inl.h index ae37028e..1e9a192b 100644 --- a/include/alloc-inl.h +++ b/include/alloc-inl.h @@ -42,7 +42,7 @@ // Be careful! _WANT_ORIGINAL_AFL_ALLOC is not compatible with custom mutators #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. */ @@ -704,12 +704,11 @@ static inline void *afl_realloc(void **buf, size_t size_needed) { *buf = 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; *buf = (void *)(new_buf->buf); return *buf; diff --git a/include/envs.h b/include/envs.h index fe5ee0e3..edfd06e4 100644 --- a/include/envs.h +++ b/include/envs.h @@ -37,6 +37,10 @@ static char *afl_environment_variables[] = { "AFL_CRASH_EXITCODE", "AFL_CUSTOM_MUTATOR_LIBRARY", "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_CYCLE_SCHEDULES", "AFL_DEBUG", diff --git a/instrumentation/README.llvm.md b/instrumentation/README.llvm.md index c0677474..126cf1a2 100644 --- a/instrumentation/README.llvm.md +++ b/instrumentation/README.llvm.md @@ -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 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. diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index e779bb79..b3b0d2cd 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -1,4 +1,4 @@ -/* SanitizeCoverage.cpp ported to afl++ LTO :-) */ +/* SanitizeCoverage.cpp ported to AFL++ LTO :-) */ #define AFL_LLVM_PASS @@ -20,6 +20,8 @@ #if LLVM_VERSION_MAJOR < 17 #include "llvm/ADT/Triple.h" #include "llvm/Analysis/EHPersonalities.h" +#else + #include "llvm/IR/EHPersonalities.h" #endif #include "llvm/Analysis/PostDominators.h" #include "llvm/Analysis/ValueTracking.h" @@ -236,7 +238,7 @@ class ModuleSanitizerCoverageLTO SanitizerCoverageOptions Options; - // afl++ START + // AFL++ START // const SpecialCaseList * Allowlist; // const SpecialCaseList * Blocklist; uint32_t autodictionary = 1; @@ -262,7 +264,7 @@ class ModuleSanitizerCoverageLTO Value *MapPtrFixed = NULL; std::ofstream dFile; size_t found = 0; - // afl++ END + // AFL++ END }; @@ -406,7 +408,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule( Int8Ty = IRB.getInt8Ty(); Int1Ty = IRB.getInt1Ty(); - /* afl++ START */ + /* AFL++ START */ char *ptr; LLVMContext &Ctx = M.getContext(); Ct = &Ctx; @@ -980,7 +982,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule( } - // afl++ END + // AFL++ END SanCovTracePCIndir = M.getOrInsertFunction(SanCovTracePCIndirName, VoidTy, IntptrTy); @@ -1004,7 +1006,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule( for (auto &F : M) instrumentFunction(F, DTCallback, PDTCallback); - // afl++ START + // AFL++ START if (dFile.is_open()) dFile.close(); 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, // 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). if (BB->getFirstInsertionPt() == BB->end()) return false; - // afl++ START + // AFL++ START if (!Options.NoPrune && &F.getEntryBlock() == BB && F.size() > 1) return false; - // afl++ END + // AFL++ END if (Options.NoPrune || &F.getEntryBlock() == BB) return true; @@ -1260,10 +1262,10 @@ void ModuleSanitizerCoverageLTO::instrumentFunction( // if (Blocklist && Blocklist->inSection("coverage", "fun", F.getName())) // return; - // afl++ START + // AFL++ START if (!F.size()) return; if (!isInInstrumentList(&F, FMNAME)) return; - // afl++ END + // AFL++ END if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge) SplitAllCriticalEdges( @@ -1561,7 +1563,7 @@ bool ModuleSanitizerCoverageLTO::InjectCoverage( for (size_t i = 0, N = AllBlocks.size(); i < N; i++) { - // afl++ START + // AFL++ START if (BlockList.size()) { int skip = 0; @@ -1583,7 +1585,7 @@ bool ModuleSanitizerCoverageLTO::InjectCoverage( } - // afl++ END + // AFL++ END InjectCoverageAtBlock(F, *AllBlocks[i], i, IsLeafFunc); @@ -1649,7 +1651,7 @@ void ModuleSanitizerCoverageLTO::InjectCoverageAtBlock(Function &F, if (Options.TracePCGuard) { - // afl++ START + // AFL++ START ++afl_global_id; if (dFile.is_open()) { @@ -1713,7 +1715,7 @@ void ModuleSanitizerCoverageLTO::InjectCoverageAtBlock(Function &F, // done :) inst++; - // afl++ END + // AFL++ END /* XXXXXXXXXXXXXXXXXXX diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index 8be9e329..41c38283 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -16,6 +16,8 @@ #if LLVM_VERSION_MAJOR < 17 #include "llvm/ADT/Triple.h" #include "llvm/Analysis/EHPersonalities.h" +#else + #include "llvm/IR/EHPersonalities.h" #endif #include "llvm/Analysis/PostDominators.h" #include "llvm/IR/CFG.h" diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 0912e52b..5372fae0 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -14,6 +14,16 @@ */ +#ifdef __AFL_CODE_COVERAGE + #ifndef _GNU_SOURCE + #define _GNU_SOURCE + #endif + #ifndef __USE_GNU + #define __USE_GNU + #endif + #include +#endif + #ifdef __ANDROID__ #include "android-ashmem.h" #endif @@ -105,6 +115,44 @@ u32 __afl_dictionary_len; u64 __afl_map_addr; 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 */ u32 __afl_connected = 0; @@ -499,6 +547,7 @@ static void __afl_map_shm(void) { u8 *map_env = (u8 *)getenv("AFL_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); _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. */ @@ -686,6 +756,17 @@ static void __afl_unmap_shm(void) { 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); 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 ID of 0 as a special value to indicate non-instrumented bits. That may 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; } +#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"); 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) { fprintf(stderr, diff --git a/instrumentation/afl-llvm-common.cc b/instrumentation/afl-llvm-common.cc index 5d82aa25..7f17b02d 100644 --- a/instrumentation/afl-llvm-common.cc +++ b/instrumentation/afl-llvm-common.cc @@ -584,7 +584,7 @@ bool isInInstrumentList(llvm::Function *F, std::string Filename) { } // 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. unsigned long long int calculateCollisions(uint32_t edges) { diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc index 97155cd6..8ee13010 100644 --- a/instrumentation/afl-llvm-dict2file.so.cc +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -746,7 +746,7 @@ static void registerAFLdict2filePass(const PassManagerBuilder &, } static RegisterPass X("afl-dict2file", - "afl++ dict2file instrumentation pass", + "AFL++ dict2file instrumentation pass", false, false); static RegisterStandardPasses RegisterAFLdict2filePass( diff --git a/nyx_mode/LIBNYX_VERSION b/nyx_mode/LIBNYX_VERSION index 86b32eec..ed88ec10 100644 --- a/nyx_mode/LIBNYX_VERSION +++ b/nyx_mode/LIBNYX_VERSION @@ -1 +1 @@ -2da7f08 +c8a72dc diff --git a/qemu_mode/QEMUAFL_VERSION b/qemu_mode/QEMUAFL_VERSION index fa44d173..44ea5345 100644 --- a/qemu_mode/QEMUAFL_VERSION +++ b/qemu_mode/QEMUAFL_VERSION @@ -1 +1 @@ -0569eff8a1 +a1321713c7 diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh index a064fe58..f59cba78 100755 --- a/qemu_mode/build_qemu_support.sh +++ b/qemu_mode/build_qemu_support.sh @@ -356,7 +356,7 @@ fi if ! command -v "$CROSS" > /dev/null ; 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 ..." make -C libcompcov && echo "[+] libcompcov ready" 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" fi 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 ..." make -C libcompcov CC="$CROSS $CROSS_FLAGS" && echo "[+] libcompcov ready" echo "[+] Building unsigaction ..." diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl index 0569eff8..a1321713 160000 --- a/qemu_mode/qemuafl +++ b/qemu_mode/qemuafl @@ -1 +1 @@ -Subproject commit 0569eff8a12dec73642b96757f6b5b51a618a03a +Subproject commit a1321713c7502c152dd7527555e0f8a800d55225 diff --git a/src/afl-cc.c b/src/afl-cc.c index d1001187..972ac8cd 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -31,6 +31,8 @@ #include #include #include +#include +#include #if (LLVM_MAJOR - 0 == 0) #undef LLVM_MAJOR @@ -76,6 +78,7 @@ enum { INSTRUMENT_OPT_NGRAM = 16, INSTRUMENT_OPT_CALLER = 32, 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. */ 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, - 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 *)); + cc_params = ck_alloc(1024 * sizeof(u8 *)); if (lto_mode) { @@ -642,7 +934,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { } //#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"; //#endif @@ -751,7 +1043,21 @@ static void edit_params(u32 argc, char **argv, char **envp) { } else if (instrument_mode == INSTRUMENT_LLVMNATIVE) { #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 FATAL("pcguard instrumentation requires llvm 4.0.1+"); #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. */ - - u8 skip_next = 0, non_dash = 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, "-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; - - } + /* Inspect the command line parameters. */ - } + process_params(argc, argv); - 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; - - } + if (!have_pic) { cc_params[cc_par_cnt++] = "-fPIC"; } // 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 @@ -1651,13 +1813,17 @@ int main(int argc, char **argv, char **envp) { instrument_mode = INSTRUMENT_CLASSIC; lto_mode = 1; - } else if (!instrument_mode || instrument_mode == INSTRUMENT_AFL) + } else if (!instrument_mode || instrument_mode == INSTRUMENT_AFL) { instrument_mode = INSTRUMENT_AFL; - else + + } else { + FATAL("main instrumentation mode already set with %s", instrument_mode_string[instrument_mode]); + } + } 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 || strncasecmp(ptr2, "instrim", strlen("instrim")) == 0) { @@ -2241,7 +2424,8 @@ int main(int argc, char **argv, char **envp) { "(requires LLVM 11 or higher)"); #endif - if (instrument_opt_mode && instrument_mode != INSTRUMENT_CLASSIC) + if (instrument_opt_mode && instrument_opt_mode != INSTRUMENT_OPT_CODECOV && + instrument_mode != INSTRUMENT_CLASSIC) FATAL( "CALLER, CTX and NGRAM instrumentation options can only be used with " "the LLVM CLASSIC instrumentation mode."); diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index aa8c8622..30c8901c 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -489,7 +489,7 @@ static void report_error_and_exit(int error) { break; case FS_ERROR_OLD_CMPLOG: 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."); break; 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) { - // workaround for recent afl++ versions + // workaround for recent AFL++ versions if ((status & FS_OPT_OLD_AFLPP_WORKAROUND) == FS_OPT_OLD_AFLPP_WORKAROUND) status = (status & 0xf0ffffff); @@ -1059,7 +1059,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, FATAL( "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", tmp_map_size, fsrv->map_size, tmp_map_size); diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index bd591c8f..baf56a5f 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -716,6 +716,8 @@ void read_testcases(afl_state_t *afl, u8 *directory) { } + // if (getenv("MYTEST")) afl->in_place_resume = 1; + if (nl_cnt) { 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 */ 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) { - SAYF(cGRA " len = %u, map size = %u, exec speed = %llu us\n" cRST, - q->len, q->bitmap_size, q->exec_us); + SAYF(cGRA + " 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; - for (idx = 0; idx < afl->queued_items; idx++) { + for (idx = 0; idx < afl->queued_items - 1; idx++) { q = afl->queue_buf[idx]; if (!q || q->disabled || q->cal_failed || !q->exec_cksum) { continue; } - u32 done = 0; + 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]; 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->perf_score = 0; + if (afl->debug) { + + WARNF("Same coverage - %s is kept active, %s is disabled.", + q->fname, p->fname); + + } + } else { if (!q->was_fuzzed) { @@ -1207,7 +1220,14 @@ void perform_dry_run(afl_state_t *afl) { q->disabled = 1; 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 } diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index ee562f96..c6e9a295 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -842,6 +842,7 @@ u8 fuzz_one_original(afl_state_t *afl) { eff_map = afl_realloc(AFL_BUF_PARAM(eff), EFF_ALEN(len)); if (unlikely(!eff_map)) { PFATAL("alloc"); } + memset(eff_map, 0, EFF_ALEN(len)); eff_map[0] = 1; if (EFF_APOS(len - 1) != 0) { @@ -2047,20 +2048,22 @@ custom_mutator_stage: afl->queue_cur->stats_mutated += afl->stage_max; #endif - if (likely(afl->custom_only)) { + /**************** + * RANDOM HAVOC * + ****************/ + +havoc_stage: + + if (unlikely(afl->custom_only)) { + /* Force UI update */ + show_stats(afl); /* Skip other stages */ ret_val = 0; goto abandon_entry; } - /**************** - * RANDOM HAVOC * - ****************/ - -havoc_stage: - afl->stage_cur_byte = -1; /* 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)); if (unlikely(!eff_map)) { PFATAL("alloc"); } + memset(eff_map, 0, EFF_ALEN(len)); eff_map[0] = 1; if (EFF_APOS(len - 1) != 0) { diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 8ad7cd97..b10bf749 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -49,11 +49,13 @@ inline u32 select_next_queue_entry(afl_state_t *afl) { u32 s = rand_below(afl, afl->queued_items); double p = rand_next_percent(afl); + /* 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 < 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) { - 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 *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 = (u32 *)afl_realloc((void **)&afl->alias_table, n * sizeof(u32)); afl->alias_probability = (double *)afl_realloc( (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"); } - memset((void *)afl->alias_table, 0, n * sizeof(u32)); 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)) { @@ -166,7 +171,15 @@ void create_alias_table(afl_state_t *afl) { for (i = 0; i < n; i++) { // 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]; - if (likely(!q->disabled)) { q->perf_score = calculate_score(afl, q); } + if (likely(!q->disabled)) { + + q->perf_score = calculate_score(afl, q); + sum += q->perf_score; - sum += q->perf_score; + } } for (i = 0; i < n; i++) { // 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; - for (s = (s32)n - 1; s >= 0; --s) { + // Done collecting weightings in P, now create the arrays. + + for (s32 j = (s32)(n - 1); j >= 0; j--) { - if (P[s] < 1) { + if (P[j] < 1) { - S[nS++] = s; + Small[nSmall++] = (u32)j; } else { - L[nL++] = s; + Large[nLarge--] = (u32)j; } } - while (nS && nL) { + while (nSmall && nLarge != n - 1) { + + u32 small = Small[--nSmall]; + u32 large = Large[++nLarge]; + + afl->alias_probability[small] = P[small]; + afl->alias_table[small] = large; - a = S[--nS]; - g = L[--nL]; - afl->alias_probability[a] = P[a]; - afl->alias_table[a] = g; - P[g] = P[g] + P[a] - 1; - if (P[g] < 1) { + P[large] = P[large] - (1 - P[small]); - S[nS++] = g; + if (P[large] < 1) { + + Small[nSmall++] = large; } else { - L[nL++] = g; + Large[nLarge--] = large; } } - while (nL) - afl->alias_probability[L[--nL]] = 1; + while (nSmall) { + + afl->alias_probability[Small[--nSmall]] = 1; + + } - while (nS) - afl->alias_probability[S[--nS]] = 1; + while (nLarge != n - 1) { + + afl->alias_probability[Large[++nLarge]] = 1; + + } afl->reinit_table = 0; @@ -264,7 +298,7 @@ void create_alias_table(afl_state_t *afl) { */ /* 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], afl->queue_buf[i]->perf_score, afl->queue_buf[i]->weight, afl->queue_buf[i]->fname); diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 71d2afd8..4339ddd2 100644 --- a/src/afl-fuzz.c +++ b/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" "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" "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; - OKF("afl++ is maintained by Marc \"van Hauser\" Heuse, Heiko \"hexcoder\" " - "Eißfeldt, Andrea Fioraldi and Dominik Maier"); - OKF("afl++ is open source, get it at " + OKF("AFL++ is maintained by Marc \"van Hauser\" Heuse, Dominik Maier, Andrea " + "Fioraldi and Heiko \"hexcoder\" Eißfeldt"); + OKF("AFL++ is open source, get it at " "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__ 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"); } @@ -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) { 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)); #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); + 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); 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 || 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; afl->virgin_bits = ck_realloc(afl->virgin_bits, 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->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; @@ -2017,6 +2076,7 @@ int main(int argc, char **argv_orig, char **envp) { 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_tmout = ck_realloc(afl->virgin_tmout, 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->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_shm_deinit(&afl->shm); 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); + u32 old_map_size = 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_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->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->cmplog_fsrv); afl_shm_deinit(&afl->shm); diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c index 5438bd9f..420dd817 100644 --- a/src/afl-ld-lto.c +++ b/src/afl-ld-lto.c @@ -2,7 +2,7 @@ american fuzzy lop++ - wrapper for llvm 11+ lld ----------------------------------------------- - Written by Marc Heuse for afl++ + Written by Marc Heuse for AFL++ Maintained by Marc Heuse , Heiko Eißfeldt @@ -210,7 +210,7 @@ static void edit_params(int argc, char **argv) { 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); } diff --git a/src/afl-showmap.c b/src/afl-showmap.c index d0e01cb1..9c029035 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -1287,7 +1287,7 @@ int main(int argc, char **argv_orig, char **envp) { break; - case 'Y': // fallthough + case 'Y': // fallthrough #ifdef __linux__ 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. 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 { // 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; + } 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) { @@ -1617,9 +1633,6 @@ int main(int argc, char **argv_orig, char **envp) { 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 (!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); - 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")) { @@ -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; if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz) diff --git a/test/test-dlopen.c b/test/test-dlopen.c index b81bab13..39442f93 100644 --- a/test/test-dlopen.c +++ b/test/test-dlopen.c @@ -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 __AFL_INIT(); diff --git a/test/test-gcc-plugin.sh b/test/test-gcc-plugin.sh index 54e6987f..3690a80a 100755 --- a/test/test-gcc-plugin.sh +++ b/test/test-gcc-plugin.sh @@ -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 "$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 } test "$TUPLES" -lt 2 && SKIP=1 diff --git a/test/test-llvm.sh b/test/test-llvm.sh index 0e66cc97..714bda93 100755 --- a/test/test-llvm.sh +++ b/test/test-llvm.sh @@ -263,7 +263,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { { mkdir -p 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 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" diff --git a/test/test-performance.sh b/test/test-performance.sh index d61e2f2a..50957141 100755 --- a/test/test-performance.sh +++ b/test/test-performance.sh @@ -7,7 +7,7 @@ FILE=$AFL_PERFORMANCE_FILE test -z "$FILE" && FILE=.afl_performance 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 read IN } @@ -74,7 +74,7 @@ afl-system-config > /dev/null 2>&1 echo Performance settings applied. echo -$ECHO "${RESET}${GREY}[*] starting afl++ performance test framework ..." +$ECHO "${RESET}${GREY}[*] starting AFL++ performance test framework ..." $ECHO "$BLUE[*] Testing: ${AFL_GCC}" GCC=x diff --git a/test/test-pre.sh b/test/test-pre.sh index b8b286e5..1ca9dfb5 100755 --- a/test/test-pre.sh +++ b/test/test-pre.sh @@ -133,7 +133,7 @@ MEM_LIMIT=none 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" diff --git a/unicorn_mode/build_unicorn_support.sh b/unicorn_mode/build_unicorn_support.sh index 53ec2481..d3d16ad5 100755 --- a/unicorn_mode/build_unicorn_support.sh +++ b/unicorn_mode/build_unicorn_support.sh @@ -182,7 +182,7 @@ git pull sh -c 'git stash && git stash drop' 1>/dev/null 2>/dev/null 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 echo "[*] Configuring Unicorn build..." -- cgit v1.2.3