├── 24-hour-runs-2.40b.png ├── FairFuzz-logo.png ├── LICENSE ├── Makefile ├── QuickStartGuide.txt ├── README ├── README.md ├── afl-analyze.c ├── afl-as.c ├── afl-as.h ├── afl-cmin ├── afl-fuzz.c ├── afl-gcc.c ├── afl-gotcpu.c ├── afl-plot ├── afl-showmap.c ├── afl-tmin.c ├── afl-whatsup ├── alloc-inl.h ├── config.h ├── debug.h ├── dictionaries ├── README.dictionaries ├── gif.dict ├── html_tags.dict ├── jpeg.dict ├── js.dict ├── json.dict ├── pdf.dict ├── png.dict ├── sql.dict ├── tiff.dict ├── webp.dict └── xml.dict ├── docs ├── COPYING ├── ChangeLog ├── INSTALL ├── QuickStartGuide.txt ├── README ├── env_variables.txt ├── historical_notes.txt ├── life_pro_tips.txt ├── notes_for_asan.txt ├── parallel_fuzzing.txt ├── perf_tips.txt ├── sister_projects.txt ├── status_screen.txt ├── technical_details.txt ├── visualization │ └── afl_gzip.png └── vuln_samples │ ├── bash-cmd-exec.var │ ├── bash-uninit-mem.var │ ├── ffmpeg-h264-bad-ptr-800m.mp4 │ ├── ffmpeg-h264-bad-read.mp4 │ ├── ffmpeg-h264-call-stack-overflow.mp4 │ ├── file-fpu-exception.elf │ ├── firefox-bmp-leak.bmp │ ├── firefox-chrome-leak.jpg │ ├── firefox-gif-leak.gif │ ├── firefox-gif-leak2.gif │ ├── jxrlib-crash.jxr │ ├── jxrlib-crash2.jxr │ ├── jxrlib-crash3.jxr │ ├── jxrlib-crash4.jxr │ ├── lesspipe-cpio-bad-write.cpio │ ├── libjpeg-sos-leak.jpg │ ├── libjpeg-turbo-dht-leak.jpg │ ├── libtiff-bad-write.tif │ ├── libtiff-uninit-mem.tif │ ├── libtiff-uninit-mem2.tif │ ├── libtiff-uninit-mem3.tif │ ├── libtiff-uninit-mem4.tif │ ├── libxml2-bad-read.xml │ ├── msie-dht-leak.jpg │ ├── msie-jxr-mem-leak.jxr │ ├── msie-png-mem-leak.png │ ├── msie-tiff-mem-leak.tif │ ├── msie-zlib-dos.png │ ├── openssl-null-ptr.der │ ├── openssl-null-ptr2.der │ ├── photoshop-mem-leak.jpg │ ├── sqlite-bad-free.sql │ ├── sqlite-bad-ptr.sql │ ├── sqlite-bad-ptr2.sql │ ├── sqlite-bad-ptr3.sql │ ├── sqlite-heap-overflow.sql │ ├── sqlite-heap-overwrite.sql │ ├── sqlite-negative-memset.sql │ ├── sqlite-null-ptr1.sql │ ├── sqlite-null-ptr10.sql │ ├── sqlite-null-ptr11.sql │ ├── sqlite-null-ptr12.sql │ ├── sqlite-null-ptr13.sql │ ├── sqlite-null-ptr14.sql │ ├── sqlite-null-ptr15.sql │ ├── sqlite-null-ptr2.sql │ ├── sqlite-null-ptr3.sql │ ├── sqlite-null-ptr4.sql │ ├── sqlite-null-ptr5.sql │ ├── sqlite-null-ptr6.sql │ ├── sqlite-null-ptr7.sql │ ├── sqlite-null-ptr8.sql │ ├── sqlite-null-ptr9.sql │ ├── sqlite-oob-read.sql │ ├── sqlite-oob-write.sql │ ├── sqlite-stack-buf-overflow.sql │ ├── sqlite-stack-exhaustion.sql │ ├── sqlite-unint-mem.sql │ ├── sqlite-use-after-free.sql │ ├── strings-bfd-badptr.elf │ ├── strings-bfd-badptr2.elf │ ├── strings-stack-overflow │ ├── strings-unchecked-ctr.elf │ ├── tcpdump-arp-crash.pcap │ ├── tcpdump-ppp-crash.pcap │ ├── unrtf-arbitrary-read.rtf │ └── unzip-t-mem-corruption.zip ├── experimental ├── README.experiments ├── argv_fuzzing │ └── argv-fuzz-inl.h ├── asan_cgroups │ └── limit_memory.sh ├── bash_shellshock │ └── shellshock-fuzz.diff ├── canvas_harness │ └── canvas_harness.html ├── clang_asm_normalize │ └── as ├── crash_triage │ └── triage_crashes.sh ├── distributed_fuzzing │ └── sync_script.sh ├── libpng_no_checksum │ └── libpng-nocrc.patch ├── persistent_demo │ └── persistent_demo.c └── post_library │ ├── post_library.so.c │ └── post_library_png.so.c ├── hash.h ├── libdislocator ├── Makefile ├── README.dislocator └── libdislocator.so.c ├── libtokencap ├── Makefile ├── README.tokencap └── libtokencap.so.c ├── llvm_mode ├── Makefile ├── README.llvm ├── afl-clang-fast.c ├── afl-llvm-pass.so.cc └── afl-llvm-rt.o.c ├── qemu_mode ├── README.qemu ├── build_qemu_support.sh └── patches │ ├── afl-qemu-cpu-inl.h │ ├── cpu-exec.diff │ ├── elfload.diff │ ├── syscall.diff │ └── translate-all.diff ├── test-instr.c ├── testcases ├── README.testcases ├── archives │ ├── common │ │ ├── ar │ │ │ └── small_archive.a │ │ ├── bzip2 │ │ │ └── small_archive.bz2 │ │ ├── cab │ │ │ └── small_archive.cab │ │ ├── compress │ │ │ └── small_archive.Z │ │ ├── cpio │ │ │ └── small_archive.cpio │ │ ├── gzip │ │ │ └── small_archive.gz │ │ ├── lzo │ │ │ └── small_archive.lzo │ │ ├── rar │ │ │ └── small_archive.rar │ │ ├── tar │ │ │ └── small_archive.tar │ │ ├── xz │ │ │ └── small_archive.xz │ │ └── zip │ │ │ └── small_archive.zip │ └── exotic │ │ ├── arj │ │ └── small_archive.arj │ │ ├── lha │ │ └── small_archive.lha │ │ ├── lrzip │ │ └── small_archive.lrz │ │ ├── lzip │ │ └── small_archive.lz │ │ ├── lzma │ │ └── small_archive.lzma │ │ ├── rzip │ │ └── small_archive.rz │ │ └── zoo │ │ └── small_archive.zoo ├── images │ ├── bmp │ │ └── not_kitty.bmp │ ├── gif │ │ └── not_kitty.gif │ ├── ico │ │ └── not_kitty.ico │ ├── jp2 │ │ └── not_kitty.jp2 │ ├── jpeg │ │ └── not_kitty.jpg │ ├── jxr │ │ └── not_kitty.jxr │ ├── png │ │ ├── not_kitty.png │ │ ├── not_kitty_alpha.png │ │ ├── not_kitty_gamma.png │ │ └── not_kitty_icc.png │ ├── tiff │ │ └── not_kitty.tiff │ └── webp │ │ └── not_kitty.webp ├── multimedia │ └── h264 │ │ └── small_movie.mp4 └── others │ ├── elf │ └── small_exec.elf │ ├── js │ └── small_script.js │ ├── pcap │ └── small_capture.pcap │ ├── pdf │ └── small.pdf │ ├── rtf │ └── small_document.rtf │ ├── sql │ └── simple_queries.sql │ ├── text │ └── hello_world.txt │ └── xml │ └── small_document.xml └── types.h /24-hour-runs-2.40b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/carolemieux/afl-rb/e529c1f1b3666ad94e4d6e7ef24ea648aff39ae2/24-hour-runs-2.40b.png -------------------------------------------------------------------------------- /FairFuzz-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/carolemieux/afl-rb/e529c1f1b3666ad94e4d6e7ef24ea648aff39ae2/FairFuzz-logo.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2018 Regents of the Univeristy of California 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # american fuzzy lop - makefile 3 | # ----------------------------- 4 | # 5 | # Written and maintained by Michal Zalewski 6 | # 7 | # Copyright 2013, 2014, 2015, 2016, 2017 Google Inc. All rights reserved. 8 | # 9 | # Licensed under the Apache License, Version 2.0 (the "License"); 10 | # you may not use this file except in compliance with the License. 11 | # You may obtain a copy of the License at: 12 | # 13 | # http://www.apache.org/licenses/LICENSE-2.0 14 | # 15 | 16 | PROGNAME = afl 17 | VERSION = $(shell grep '^\#define VERSION ' config.h | cut -d '"' -f2) 18 | 19 | PREFIX ?= /usr/local 20 | BIN_PATH = $(PREFIX)/bin 21 | HELPER_PATH = $(PREFIX)/lib/afl 22 | DOC_PATH = $(PREFIX)/share/doc/afl 23 | MISC_PATH = $(PREFIX)/share/afl 24 | 25 | # PROGS intentionally omit afl-as, which gets installed elsewhere. 26 | 27 | PROGS = afl-gcc afl-fuzz afl-showmap afl-tmin afl-gotcpu afl-analyze 28 | SH_PROGS = afl-plot afl-cmin afl-whatsup 29 | 30 | CFLAGS ?= -O3 -funroll-loops 31 | CFLAGS += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign \ 32 | -DAFL_PATH=\"$(HELPER_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\" \ 33 | -DBIN_PATH=\"$(BIN_PATH)\" 34 | 35 | ifneq "$(filter Linux GNU%,$(shell uname))" "" 36 | LDFLAGS += -ldl 37 | endif 38 | 39 | ifeq "$(findstring clang, $(shell $(CC) --version 2>/dev/null))" "" 40 | TEST_CC = afl-gcc 41 | else 42 | TEST_CC = afl-clang 43 | endif 44 | 45 | COMM_HDR = alloc-inl.h config.h debug.h types.h 46 | 47 | all: test_x86 $(PROGS) afl-as test_build all_done 48 | 49 | ifndef AFL_NO_X86 50 | 51 | test_x86: 52 | @echo "[*] Checking for the ability to compile x86 code..." 53 | @echo 'main() { __asm__("xorb %al, %al"); }' | $(CC) -w -x c - -o .test || ( echo; echo "Oops, looks like your compiler can't generate x86 code."; echo; echo "Don't panic! You can use the LLVM or QEMU mode, but see docs/INSTALL first."; echo "(To ignore this error, set AFL_NO_X86=1 and try again.)"; echo; exit 1 ) 54 | @rm -f .test 55 | @echo "[+] Everything seems to be working, ready to compile." 56 | 57 | else 58 | 59 | test_x86: 60 | @echo "[!] Note: skipping x86 compilation checks (AFL_NO_X86 set)." 61 | 62 | endif 63 | 64 | afl-gcc: afl-gcc.c $(COMM_HDR) | test_x86 65 | $(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS) 66 | set -e; for i in afl-g++ afl-clang afl-clang++; do ln -sf afl-gcc $$i; done 67 | 68 | afl-as: afl-as.c afl-as.h $(COMM_HDR) | test_x86 69 | $(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS) 70 | ln -sf afl-as as 71 | 72 | afl-fuzz: afl-fuzz.c $(COMM_HDR) | test_x86 73 | $(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS) 74 | 75 | afl-showmap: afl-showmap.c $(COMM_HDR) | test_x86 76 | $(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS) 77 | 78 | afl-tmin: afl-tmin.c $(COMM_HDR) | test_x86 79 | $(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS) 80 | 81 | afl-analyze: afl-analyze.c $(COMM_HDR) | test_x86 82 | $(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS) 83 | 84 | afl-gotcpu: afl-gotcpu.c $(COMM_HDR) | test_x86 85 | $(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS) 86 | 87 | ifndef AFL_NO_X86 88 | 89 | test_build: afl-gcc afl-as afl-showmap 90 | @echo "[*] Testing the CC wrapper and instrumentation output..." 91 | unset AFL_USE_ASAN AFL_USE_MSAN; AFL_QUIET=1 AFL_INST_RATIO=100 AFL_PATH=. ./$(TEST_CC) $(CFLAGS) test-instr.c -o test-instr $(LDFLAGS) 92 | echo 0 | ./afl-showmap -m none -q -o .test-instr0 ./test-instr 93 | echo 1 | ./afl-showmap -m none -q -o .test-instr1 ./test-instr 94 | @rm -f test-instr 95 | @cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation does not seem to be behaving correctly!"; echo; echo "Please ping to troubleshoot the issue."; echo; exit 1; fi 96 | @echo "[+] All right, the instrumentation seems to be working!" 97 | 98 | else 99 | 100 | test_build: afl-gcc afl-as afl-showmap 101 | @echo "[!] Note: skipping build tests (you may need to use LLVM or QEMU mode)." 102 | 103 | endif 104 | 105 | all_done: test_build 106 | @if [ ! "`which clang 2>/dev/null`" = "" ]; then echo "[+] LLVM users: see llvm_mode/README.llvm for a faster alternative to afl-gcc."; fi 107 | @echo "[+] All done! Be sure to review README - it's pretty short and useful." 108 | @if [ "`uname`" = "Darwin" ]; then printf "\nWARNING: Fuzzing on MacOS X is slow because of the unusually high overhead of\nfork() on this OS. Consider using Linux or *BSD. You can also use VirtualBox\n(virtualbox.org) to put AFL inside a Linux or *BSD VM.\n\n"; fi 109 | @! tty <&1 >/dev/null || printf "\033[0;30mNOTE: If you can read this, your terminal probably uses white background.\nThis will make the UI hard to read. See docs/status_screen.txt for advice.\033[0m\n" 2>/dev/null 110 | 111 | .NOTPARALLEL: clean 112 | 113 | clean: 114 | rm -f $(PROGS) afl-as as afl-g++ afl-clang afl-clang++ *.o *~ a.out core core.[1-9][0-9]* *.stackdump test .test test-instr .test-instr0 .test-instr1 qemu_mode/qemu-2.10.0.tar.bz2 afl-qemu-trace 115 | rm -rf out_dir qemu_mode/qemu-2.10.0 116 | $(MAKE) -C llvm_mode clean 117 | $(MAKE) -C libdislocator clean 118 | $(MAKE) -C libtokencap clean 119 | 120 | install: all 121 | mkdir -p -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH) 122 | rm -f $${DESTDIR}$(BIN_PATH)/afl-plot.sh 123 | install -m 755 $(PROGS) $(SH_PROGS) $${DESTDIR}$(BIN_PATH) 124 | rm -f $${DESTDIR}$(BIN_PATH)/afl-as 125 | if [ -f afl-qemu-trace ]; then install -m 755 afl-qemu-trace $${DESTDIR}$(BIN_PATH); fi 126 | ifndef AFL_TRACE_PC 127 | if [ -f afl-clang-fast -a -f afl-llvm-pass.so -a -f afl-llvm-rt.o ]; then set -e; install -m 755 afl-clang-fast $${DESTDIR}$(BIN_PATH); ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-fast++; install -m 755 afl-llvm-pass.so afl-llvm-rt.o $${DESTDIR}$(HELPER_PATH); fi 128 | else 129 | if [ -f afl-clang-fast -a -f afl-llvm-rt.o ]; then set -e; install -m 755 afl-clang-fast $${DESTDIR}$(BIN_PATH); ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-fast++; install -m 755 afl-llvm-rt.o $${DESTDIR}$(HELPER_PATH); fi 130 | endif 131 | if [ -f afl-llvm-rt-32.o ]; then set -e; install -m 755 afl-llvm-rt-32.o $${DESTDIR}$(HELPER_PATH); fi 132 | if [ -f afl-llvm-rt-64.o ]; then set -e; install -m 755 afl-llvm-rt-64.o $${DESTDIR}$(HELPER_PATH); fi 133 | set -e; for i in afl-g++ afl-clang afl-clang++; do ln -sf afl-gcc $${DESTDIR}$(BIN_PATH)/$$i; done 134 | install -m 755 afl-as $${DESTDIR}$(HELPER_PATH) 135 | ln -sf afl-as $${DESTDIR}$(HELPER_PATH)/as 136 | install -m 644 docs/README docs/ChangeLog docs/*.txt $${DESTDIR}$(DOC_PATH) 137 | cp -r testcases/ $${DESTDIR}$(MISC_PATH) 138 | cp -r dictionaries/ $${DESTDIR}$(MISC_PATH) 139 | 140 | publish: clean 141 | test "`basename $$PWD`" = "afl" || exit 1 142 | test -f ~/www/afl/releases/$(PROGNAME)-$(VERSION).tgz; if [ "$$?" = "0" ]; then echo; echo "Change program version in config.h, mmkay?"; echo; exit 1; fi 143 | cd ..; rm -rf $(PROGNAME)-$(VERSION); cp -pr $(PROGNAME) $(PROGNAME)-$(VERSION); \ 144 | tar -cvz -f ~/www/afl/releases/$(PROGNAME)-$(VERSION).tgz $(PROGNAME)-$(VERSION) 145 | chmod 644 ~/www/afl/releases/$(PROGNAME)-$(VERSION).tgz 146 | ( cd ~/www/afl/releases/; ln -s -f $(PROGNAME)-$(VERSION).tgz $(PROGNAME)-latest.tgz ) 147 | cat docs/README >~/www/afl/README.txt 148 | cat docs/status_screen.txt >~/www/afl/status_screen.txt 149 | cat docs/historical_notes.txt >~/www/afl/historical_notes.txt 150 | cat docs/technical_details.txt >~/www/afl/technical_details.txt 151 | cat docs/ChangeLog >~/www/afl/ChangeLog.txt 152 | cat docs/QuickStartGuide.txt >~/www/afl/QuickStartGuide.txt 153 | echo -n "$(VERSION)" >~/www/afl/version.txt 154 | -------------------------------------------------------------------------------- /QuickStartGuide.txt: -------------------------------------------------------------------------------- 1 | docs/QuickStartGuide.txt -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | docs/README -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FairFuzz 2 | 3 | 4 | 5 | 6 | An AFL extension to increase code coverage by targeting rare branches. FairFuzz has a particular advantage on programs with highly nested structure (packet analyzers, xmllint, programs compiled with [laf-inte](https://lafintel.wordpress.com/), etc). AFL is written and maintained by Michal Zalewski ; FairFuzz extension by Caroline Lemieux . 7 | 8 | Our paper on FairFuzz was [published in ASE 2018](http://www.carolemieux.com/fairfuzz-ase18.pdf). 9 | 10 | 11 | ## Summary 12 | 13 | This is a modified version of [AFL](http://lcamtuf.coredump.cx/afl/) which changes (1) the way in which AFL selects input for mutation and (2) the way in which AFL mutates inputs to target rare "branches" in the program under test. AFL keeps track of program coverage an input achieves by counting the number of times the input hits a _Basic Block Transition_ (see [AFL technical details](http://lcamtuf.coredump.cx/afl/technical_details.txt) for more detail). This basic block transition can be loosely associated with a branch in the control flow graph, thus we call refer to these transitions as _branches_. 14 | 15 | On many benchmarks, this modification achieves faster branch coverage than AFL or AFLFast. The advantage seems particularly strong on programs structured with many nested conditional statements. The graphs below show the number of basic block transitions covered over 24 hours on 9 different benchmarks. Each run was repeated 20 times (one fuzzer only): the dark middle line is the average coverage achieved, and the bands represent 95% confidence intervals. 16 | 17 | ![24 hour runs on benchmarks](https://github.com/carolemieux/afl-rb/raw/master/24-hour-runs-2.40b.png) 18 | 19 | Evaluation was conducted on on AFL 2.40b. All runs were done with no AFL dictionary: the emphasis on rare branches appears to yield better automated discovery of special sequences. On the `tcpdump` and `xmllint` benchmarks, FairFuzz was able to discover rare sequences over the 20 runs, which the other techniques did not discover. Over these 20 techniques each different technique, the number of runs finding portions of the sequence `[1](#footnote1), a mutation is only performed at a location if the branch mask designates the position as overwritable (or insertable, for dictionary element insert). For multi-byte modifications, a modification is only performed if all bytes are overwritable. The mask is used in conjunction with the effector map when the effector map is used. 52 | 2. In the havoc stage, positions for mutations are randomly selected _within the modifiable positions of the branch mask_. For example, if bytes 5-10 and 13-20 in a 20-byte input can be overwritten without failing to hit the target branch, when randomly selecting a byte to randomly mutate, FairFuzz will randomly select a position in [5,6,7,8,9,10,13,...,20] to mutate. After a havoc mutation that deletes (resp. adds) a sequence of bytes in the input, FairFuzz deletes the sequence (resp. adds an "all modifiable" sequence) at the corresponding location in the branch mask.[2](#footnote2) The branch mask becomes approximate after this point. 53 | 54 | 55 | 1 The mask is not used in the bitflipping stage since this would interfere with AFL's automatic detection of dictionary elements. 56 | 57 | 2 The mask is not used to determine where to splice inputs in the splicing stage: during splicing, the first part of the branch mask is kept, but the spliced half of the input is marked as all modifiable. 58 | 59 | 60 | ## Usage summary 61 | 62 | For basic AFL usage, see the [README](https://github.com/carolemieux/afl-rb/blob/master/docs/README) in `docs/` (the one with no .md extension). There are four FairFuzz Rare Branches-specific options: 63 | 64 | *Running options* (may be useful for functionality): 65 | - `-r` adds an additional trimming stage before mutating inputs. This trimming is more aggressive than AFL's, trimming the input down only according to the target branch -- the resulting trimmed input may have a different path than the original input, but will still hit the target branch. Recommended for use if there are very large seed files and deterministic mutations are being run. 66 | - `-q num` bootstraps the rare branch input selection from the queue with the regular AFL input selection mechanism. If after an entire cycle through the queue, no new branches are discovered, bootstrap according to `num` as follows: 67 | - `-q 1` go back to regular AFL queueing + no branch mask on mutations until a new branch is found 68 | - `-q 2` go back to regular AFL queueing + no branch mask on mutations + no deterministic mutations until a new branch is found 69 | - `-q 3` go back to regular AFL queueing + no branch mask on mutations for a single queueing cycle 70 | 71 | *Evaluation options* (mostly useful for comparing AFL versions): 72 | - `-b` disables the branch mask. (sets every position in the mask as modifiable -- will incur unnecessary slowdown compared to AFL) 73 | - `-s` runs a "shadow" mutation run before the branch-mask enabled run. Side effects are disabled in this run. This allows for direct comparison of the effect of the branch mask on new coverage discovered/number of inputs hitting the target branch. See `min-branch-fuzzing.log` produced in the AFL output directory for details. 74 | -------------------------------------------------------------------------------- /afl-gotcpu.c: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop - free CPU gizmo 3 | ----------------------------------- 4 | 5 | Written and maintained by Michal Zalewski 6 | 7 | Copyright 2015, 2016 Google Inc. All rights reserved. 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at: 12 | 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | This tool provides a fairly accurate measurement of CPU preemption rate. 16 | It is meant to complement the quick-and-dirty load average widget shown 17 | in the afl-fuzz UI. See docs/parallel_fuzzing.txt for more info. 18 | 19 | For some work loads, the tool may actually suggest running more instances 20 | than you have CPU cores. This can happen if the tested program is spending 21 | a portion of its run time waiting for I/O, rather than being 100% 22 | CPU-bound. 23 | 24 | The idea for the getrusage()-based approach comes from Jakub Wilk. 25 | 26 | */ 27 | 28 | #define AFL_MAIN 29 | #define _GNU_SOURCE 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include "types.h" 43 | #include "debug.h" 44 | 45 | #ifdef __linux__ 46 | # define HAVE_AFFINITY 1 47 | #endif /* __linux__ */ 48 | 49 | 50 | /* Get unix time in microseconds. */ 51 | 52 | static u64 get_cur_time_us(void) { 53 | 54 | struct timeval tv; 55 | struct timezone tz; 56 | 57 | gettimeofday(&tv, &tz); 58 | 59 | return (tv.tv_sec * 1000000ULL) + tv.tv_usec; 60 | 61 | } 62 | 63 | 64 | /* Get CPU usage in microseconds. */ 65 | 66 | static u64 get_cpu_usage_us(void) { 67 | 68 | struct rusage u; 69 | 70 | getrusage(RUSAGE_SELF, &u); 71 | 72 | return (u.ru_utime.tv_sec * 1000000ULL) + u.ru_utime.tv_usec + 73 | (u.ru_stime.tv_sec * 1000000ULL) + u.ru_stime.tv_usec; 74 | 75 | } 76 | 77 | 78 | /* Measure preemption rate. */ 79 | 80 | static u32 measure_preemption(u32 target_ms) { 81 | 82 | static volatile u32 v1, v2; 83 | 84 | u64 st_t, en_t, st_c, en_c, real_delta, slice_delta; 85 | s32 loop_repeats = 0; 86 | 87 | st_t = get_cur_time_us(); 88 | st_c = get_cpu_usage_us(); 89 | 90 | repeat_loop: 91 | 92 | v1 = CTEST_BUSY_CYCLES; 93 | 94 | while (v1--) v2++; 95 | sched_yield(); 96 | 97 | en_t = get_cur_time_us(); 98 | 99 | if (en_t - st_t < target_ms * 1000) { 100 | loop_repeats++; 101 | goto repeat_loop; 102 | } 103 | 104 | /* Let's see what percentage of this time we actually had a chance to 105 | run, and how much time was spent in the penalty box. */ 106 | 107 | en_c = get_cpu_usage_us(); 108 | 109 | real_delta = (en_t - st_t) / 1000; 110 | slice_delta = (en_c - st_c) / 1000; 111 | 112 | return real_delta * 100 / slice_delta; 113 | 114 | } 115 | 116 | 117 | /* Do the benchmark thing. */ 118 | 119 | int main(int argc, char** argv) { 120 | 121 | #ifdef HAVE_AFFINITY 122 | 123 | u32 cpu_cnt = sysconf(_SC_NPROCESSORS_ONLN), 124 | idle_cpus = 0, maybe_cpus = 0, i; 125 | 126 | SAYF(cCYA "afl-gotcpu " cBRI VERSION cRST " by \n"); 127 | 128 | ACTF("Measuring per-core preemption rate (this will take %0.02f sec)...", 129 | ((double)CTEST_CORE_TRG_MS) / 1000); 130 | 131 | for (i = 0; i < cpu_cnt; i++) { 132 | 133 | s32 fr = fork(); 134 | 135 | if (fr < 0) PFATAL("fork failed"); 136 | 137 | if (!fr) { 138 | 139 | cpu_set_t c; 140 | u32 util_perc; 141 | 142 | CPU_ZERO(&c); 143 | CPU_SET(i, &c); 144 | 145 | if (sched_setaffinity(0, sizeof(c), &c)) 146 | PFATAL("sched_setaffinity failed"); 147 | 148 | util_perc = measure_preemption(CTEST_CORE_TRG_MS); 149 | 150 | if (util_perc < 110) { 151 | 152 | SAYF(" Core #%u: " cLGN "AVAILABLE\n" cRST, i); 153 | exit(0); 154 | 155 | } else if (util_perc < 250) { 156 | 157 | SAYF(" Core #%u: " cYEL "CAUTION " cRST "(%u%%)\n", i, util_perc); 158 | exit(1); 159 | 160 | } 161 | 162 | SAYF(" Core #%u: " cLRD "OVERBOOKED " cRST "(%u%%)\n" cRST, i, 163 | util_perc); 164 | exit(2); 165 | 166 | } 167 | 168 | } 169 | 170 | for (i = 0; i < cpu_cnt; i++) { 171 | 172 | int ret; 173 | if (waitpid(-1, &ret, 0) < 0) PFATAL("waitpid failed"); 174 | 175 | if (WEXITSTATUS(ret) == 0) idle_cpus++; 176 | if (WEXITSTATUS(ret) <= 1) maybe_cpus++; 177 | 178 | } 179 | 180 | SAYF(cGRA "\n>>> "); 181 | 182 | if (idle_cpus) { 183 | 184 | if (maybe_cpus == idle_cpus) { 185 | 186 | SAYF(cLGN "PASS: " cRST "You can run more processes on %u core%s.", 187 | idle_cpus, idle_cpus > 1 ? "s" : ""); 188 | 189 | } else { 190 | 191 | SAYF(cLGN "PASS: " cRST "You can run more processes on %u to %u core%s.", 192 | idle_cpus, maybe_cpus, maybe_cpus > 1 ? "s" : ""); 193 | 194 | } 195 | 196 | SAYF(cGRA " <<<" cRST "\n\n"); 197 | return 0; 198 | 199 | } 200 | 201 | if (maybe_cpus) { 202 | 203 | SAYF(cYEL "CAUTION: " cRST "You may still have %u core%s available.", 204 | maybe_cpus, maybe_cpus > 1 ? "s" : ""); 205 | SAYF(cGRA " <<<" cRST "\n\n"); 206 | return 1; 207 | 208 | } 209 | 210 | SAYF(cLRD "FAIL: " cRST "All cores are overbooked."); 211 | SAYF(cGRA " <<<" cRST "\n\n"); 212 | return 2; 213 | 214 | #else 215 | 216 | u32 util_perc; 217 | 218 | SAYF(cCYA "afl-gotcpu " cBRI VERSION cRST " by \n"); 219 | 220 | /* Run a busy loop for CTEST_TARGET_MS. */ 221 | 222 | ACTF("Measuring gross preemption rate (this will take %0.02f sec)...", 223 | ((double)CTEST_TARGET_MS) / 1000); 224 | 225 | util_perc = measure_preemption(CTEST_TARGET_MS); 226 | 227 | /* Deliver the final verdict. */ 228 | 229 | SAYF(cGRA "\n>>> "); 230 | 231 | if (util_perc < 105) { 232 | 233 | SAYF(cLGN "PASS: " cRST "You can probably run additional processes."); 234 | 235 | } else if (util_perc < 130) { 236 | 237 | SAYF(cYEL "CAUTION: " cRST "Your CPU may be somewhat overbooked (%u%%).", 238 | util_perc); 239 | 240 | } else { 241 | 242 | SAYF(cLRD "FAIL: " cRST "Your CPU is overbooked (%u%%).", util_perc); 243 | 244 | } 245 | 246 | SAYF(cGRA " <<<" cRST "\n\n"); 247 | 248 | return (util_perc > 105) + (util_perc > 130); 249 | 250 | #endif /* ^HAVE_AFFINITY */ 251 | 252 | } 253 | -------------------------------------------------------------------------------- /afl-plot: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # american fuzzy lop - Advanced Persistent Graphing 4 | # ------------------------------------------------- 5 | # 6 | # Written and maintained by Michal Zalewski 7 | # Based on a design & prototype by Michael Rash. 8 | # 9 | # Copyright 2014, 2015 Google Inc. All rights reserved. 10 | # 11 | # Licensed under the Apache License, Version 2.0 (the "License"); 12 | # you may not use this file except in compliance with the License. 13 | # You may obtain a copy of the License at: 14 | # 15 | # http://www.apache.org/licenses/LICENSE-2.0 16 | # 17 | 18 | echo "progress plotting utility for afl-fuzz by " 19 | echo 20 | 21 | if [ ! "$#" = "2" ]; then 22 | 23 | cat 1>&2 <<_EOF_ 24 | This program generates gnuplot images from afl-fuzz output data. Usage: 25 | 26 | $0 afl_state_dir graph_output_dir 27 | 28 | The afl_state_dir parameter should point to an existing state directory for any 29 | active or stopped instance of afl-fuzz; while graph_output_dir should point to 30 | an empty directory where this tool can write the resulting plots to. 31 | 32 | The program will put index.html and three PNG images in the output directory; 33 | you should be able to view it with any web browser of your choice. 34 | 35 | _EOF_ 36 | 37 | exit 1 38 | 39 | fi 40 | 41 | if [ "$AFL_ALLOW_TMP" = "" ]; then 42 | 43 | echo "$1" | grep -qE '^(/var)?/tmp/' 44 | T1="$?" 45 | 46 | echo "$2" | grep -qE '^(/var)?/tmp/' 47 | T2="$?" 48 | 49 | if [ "$T1" = "0" -o "$T2" = "0" ]; then 50 | 51 | echo "[-] Error: this script shouldn't be used with shared /tmp directories." 1>&2 52 | exit 1 53 | 54 | fi 55 | 56 | fi 57 | 58 | if [ ! -f "$1/plot_data" ]; then 59 | 60 | echo "[-] Error: input directory is not valid (missing 'plot_data')." 1>&2 61 | exit 1 62 | 63 | fi 64 | 65 | BANNER="`cat "$1/fuzzer_stats" | grep '^afl_banner ' | cut -d: -f2- | cut -b2-`" 66 | 67 | test "$BANNER" = "" && BANNER="(none)" 68 | 69 | GNUPLOT=`which gnuplot 2>/dev/null` 70 | 71 | if [ "$GNUPLOT" = "" ]; then 72 | 73 | echo "[-] Error: can't find 'gnuplot' in your \$PATH." 1>&2 74 | exit 1 75 | 76 | fi 77 | 78 | mkdir "$2" 2>/dev/null 79 | 80 | if [ ! -d "$2" ]; then 81 | 82 | echo "[-] Error: unable to create the output directory - pick another location." 1>&2 83 | exit 1 84 | 85 | fi 86 | 87 | rm -f "$2/high_freq.png" "$2/low_freq.png" "$2/exec_speed.png" 88 | mv -f "$2/index.html" "$2/index.html.orig" 2>/dev/null 89 | 90 | echo "[*] Generating plots..." 91 | 92 | ( 93 | 94 | cat <<_EOF_ 95 | set terminal png truecolor enhanced size 1000,300 butt 96 | 97 | set output '$2/high_freq.png' 98 | 99 | set xdata time 100 | set timefmt '%s' 101 | set format x "%b %d\n%H:%M" 102 | set tics font 'small' 103 | unset mxtics 104 | unset mytics 105 | 106 | set grid xtics linetype 0 linecolor rgb '#e0e0e0' 107 | set grid ytics linetype 0 linecolor rgb '#e0e0e0' 108 | set border linecolor rgb '#50c0f0' 109 | set tics textcolor rgb '#000000' 110 | set key outside 111 | 112 | set autoscale xfixmin 113 | set autoscale xfixmax 114 | 115 | plot '$1/plot_data' using 1:4 with filledcurve x1 title 'total paths' linecolor rgb '#000000' fillstyle transparent solid 0.2 noborder, \\ 116 | '' using 1:3 with filledcurve x1 title 'current path' linecolor rgb '#f0f0f0' fillstyle transparent solid 0.5 noborder, \\ 117 | '' using 1:5 with lines title 'pending paths' linecolor rgb '#0090ff' linewidth 3, \\ 118 | '' using 1:6 with lines title 'pending favs' linecolor rgb '#c00080' linewidth 3, \\ 119 | '' using 1:2 with lines title 'cycles done' linecolor rgb '#c000f0' linewidth 3 120 | 121 | set terminal png truecolor enhanced size 1000,200 butt 122 | set output '$2/low_freq.png' 123 | 124 | plot '$1/plot_data' using 1:8 with filledcurve x1 title '' linecolor rgb '#c00080' fillstyle transparent solid 0.2 noborder, \\ 125 | '' using 1:8 with lines title ' uniq crashes' linecolor rgb '#c00080' linewidth 3, \\ 126 | '' using 1:9 with lines title 'uniq hangs' linecolor rgb '#c000f0' linewidth 3, \\ 127 | '' using 1:10 with lines title 'levels' linecolor rgb '#0090ff' linewidth 3 128 | 129 | set terminal png truecolor enhanced size 1000,200 butt 130 | set output '$2/exec_speed.png' 131 | 132 | plot '$1/plot_data' using 1:11 with filledcurve x1 title '' linecolor rgb '#0090ff' fillstyle transparent solid 0.2 noborder, \\ 133 | '$1/plot_data' using 1:11 with lines title ' execs/sec' linecolor rgb '#0090ff' linewidth 3 smooth bezier; 134 | 135 | _EOF_ 136 | 137 | ) | gnuplot 138 | 139 | if [ ! -s "$2/exec_speed.png" ]; then 140 | 141 | echo "[-] Error: something went wrong! Perhaps you have an ancient version of gnuplot?" 1>&2 142 | exit 1 143 | 144 | fi 145 | 146 | echo "[*] Generating index.html..." 147 | 148 | cat >"$2/index.html" <<_EOF_ 149 | 150 | 151 | 152 | 153 |
Banner:$BANNER
Directory:$1
Generated on:`date`
154 |

155 |

156 |

157 | 158 | 159 | _EOF_ 160 | 161 | # Make it easy to remotely view results when outputting directly to a directory 162 | # served by Apache or other HTTP daemon. Since the plots aren't horribly 163 | # sensitive, this seems like a reasonable trade-off. 164 | 165 | chmod 755 "$2" 166 | chmod 644 "$2/high_freq.png" "$2/low_freq.png" "$2/exec_speed.png" "$2/index.html" 167 | 168 | echo "[+] All done - enjoy your charts!" 169 | 170 | exit 0 171 | -------------------------------------------------------------------------------- /afl-whatsup: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # american fuzzy lop - status check tool 4 | # -------------------------------------- 5 | # 6 | # Written and maintained by Michal Zalewski 7 | # 8 | # Copyright 2015 Google Inc. All rights reserved. 9 | # 10 | # Licensed under the Apache License, Version 2.0 (the "License"); 11 | # you may not use this file except in compliance with the License. 12 | # You may obtain a copy of the License at: 13 | # 14 | # http://www.apache.org/licenses/LICENSE-2.0 15 | # 16 | # This tool summarizes the status of any locally-running synchronized 17 | # instances of afl-fuzz. 18 | # 19 | 20 | echo "status check tool for afl-fuzz by " 21 | echo 22 | 23 | if [ "$1" = "-s" ]; then 24 | 25 | SUMMARY_ONLY=1 26 | DIR="$2" 27 | 28 | else 29 | 30 | unset SUMMARY_ONLY 31 | DIR="$1" 32 | 33 | fi 34 | 35 | if [ "$DIR" = "" ]; then 36 | 37 | echo "Usage: $0 [ -s ] afl_sync_dir" 1>&2 38 | echo 1>&2 39 | echo "The -s option causes the tool to skip all the per-fuzzer trivia and show" 1>&2 40 | echo "just the summary results. See docs/parallel_fuzzing.txt for additional tips." 1>&2 41 | echo 1>&2 42 | exit 1 43 | 44 | fi 45 | 46 | cd "$DIR" || exit 1 47 | 48 | if [ -d queue ]; then 49 | 50 | echo "[-] Error: parameter is an individual output directory, not a sync dir." 1>&2 51 | exit 1 52 | 53 | fi 54 | 55 | CUR_TIME=`date +%s` 56 | 57 | TMP=`mktemp -t .afl-whatsup-XXXXXXXX` || exit 1 58 | 59 | ALIVE_CNT=0 60 | DEAD_CNT=0 61 | 62 | TOTAL_TIME=0 63 | TOTAL_EXECS=0 64 | TOTAL_EPS=0 65 | TOTAL_CRASHES=0 66 | TOTAL_PFAV=0 67 | TOTAL_PENDING=0 68 | 69 | if [ "$SUMMARY_ONLY" = "" ]; then 70 | 71 | echo "Individual fuzzers" 72 | echo "==================" 73 | echo 74 | 75 | fi 76 | 77 | for i in `find . -maxdepth 2 -iname fuzzer_stats | sort`; do 78 | 79 | sed 's/^command_line.*$/_skip:1/;s/[ ]*:[ ]*/="/;s/$/"/' "$i" >"$TMP" 80 | . "$TMP" 81 | 82 | RUN_UNIX=$((CUR_TIME - start_time)) 83 | RUN_DAYS=$((RUN_UNIX / 60 / 60 / 24)) 84 | RUN_HRS=$(((RUN_UNIX / 60 / 60) % 24)) 85 | 86 | if [ "$SUMMARY_ONLY" = "" ]; then 87 | 88 | echo ">>> $afl_banner ($RUN_DAYS days, $RUN_HRS hrs) <<<" 89 | echo 90 | 91 | fi 92 | 93 | if ! kill -0 "$fuzzer_pid" 2>/dev/null; then 94 | 95 | if [ "$SUMMARY_ONLY" = "" ]; then 96 | 97 | echo " Instance is dead or running remotely, skipping." 98 | echo 99 | 100 | fi 101 | 102 | DEAD_CNT=$((DEAD_CNT + 1)) 103 | continue 104 | 105 | fi 106 | 107 | ALIVE_CNT=$((ALIVE_CNT + 1)) 108 | 109 | EXEC_SEC=$((execs_done / RUN_UNIX)) 110 | PATH_PERC=$((cur_path * 100 / paths_total)) 111 | 112 | TOTAL_TIME=$((TOTAL_TIME + RUN_UNIX)) 113 | TOTAL_EPS=$((TOTAL_EPS + EXEC_SEC)) 114 | TOTAL_EXECS=$((TOTAL_EXECS + execs_done)) 115 | TOTAL_CRASHES=$((TOTAL_CRASHES + unique_crashes)) 116 | TOTAL_PENDING=$((TOTAL_PENDING + pending_total)) 117 | TOTAL_PFAV=$((TOTAL_PFAV + pending_favs)) 118 | 119 | if [ "$SUMMARY_ONLY" = "" ]; then 120 | 121 | echo " cycle $((cycles_done + 1)), lifetime speed $EXEC_SEC execs/sec, path $cur_path/$paths_total (${PATH_PERC}%)" 122 | 123 | if [ "$unique_crashes" = "0" ]; then 124 | echo " pending $pending_favs/$pending_total, coverage $bitmap_cvg, no crashes yet" 125 | else 126 | echo " pending $pending_favs/$pending_total, coverage $bitmap_cvg, crash count $unique_crashes (!)" 127 | fi 128 | 129 | echo 130 | 131 | fi 132 | 133 | done 134 | 135 | rm -f "$TMP" 136 | 137 | TOTAL_DAYS=$((TOTAL_TIME / 60 / 60 / 24)) 138 | TOTAL_HRS=$(((TOTAL_TIME / 60 / 60) % 24)) 139 | 140 | test "$TOTAL_TIME" = "0" && TOTAL_TIME=1 141 | 142 | echo "Summary stats" 143 | echo "=============" 144 | echo 145 | echo " Fuzzers alive : $ALIVE_CNT" 146 | 147 | if [ ! "$DEAD_CNT" = "0" ]; then 148 | echo " Dead or remote : $DEAD_CNT (excluded from stats)" 149 | fi 150 | 151 | echo " Total run time : $TOTAL_DAYS days, $TOTAL_HRS hours" 152 | echo " Total execs : $((TOTAL_EXECS / 1000 / 1000)) million" 153 | echo " Cumulative speed : $TOTAL_EPS execs/sec" 154 | echo " Pending paths : $TOTAL_PFAV faves, $TOTAL_PENDING total" 155 | 156 | if [ "$ALIVE_CNT" -gt "1" ]; then 157 | echo " Pending per fuzzer : $((TOTAL_PFAV/ALIVE_CNT)) faves, $((TOTAL_PENDING/ALIVE_CNT)) total (on average)" 158 | fi 159 | 160 | echo " Crashes found : $TOTAL_CRASHES locally unique" 161 | echo 162 | 163 | exit 0 164 | -------------------------------------------------------------------------------- /debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop - debug / error handling macros 3 | -------------------------------------------------- 4 | 5 | Written and maintained by Michal Zalewski 6 | 7 | Copyright 2013, 2014, 2015, 2016 Google Inc. All rights reserved. 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at: 12 | 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | */ 16 | 17 | #ifndef _HAVE_DEBUG_H 18 | #define _HAVE_DEBUG_H 19 | 20 | #include 21 | 22 | #include "types.h" 23 | #include "config.h" 24 | 25 | /******************* 26 | * Terminal colors * 27 | *******************/ 28 | 29 | #ifdef USE_COLOR 30 | 31 | # define cBLK "\x1b[0;30m" 32 | # define cRED "\x1b[0;31m" 33 | # define cGRN "\x1b[0;32m" 34 | # define cBRN "\x1b[0;33m" 35 | # define cBLU "\x1b[0;34m" 36 | # define cMGN "\x1b[0;35m" 37 | # define cCYA "\x1b[0;36m" 38 | # define cLGR "\x1b[0;37m" 39 | # define cGRA "\x1b[1;90m" 40 | # define cLRD "\x1b[1;91m" 41 | # define cLGN "\x1b[1;92m" 42 | # define cYEL "\x1b[1;93m" 43 | # define cLBL "\x1b[1;94m" 44 | # define cPIN "\x1b[1;95m" 45 | # define cLCY "\x1b[1;96m" 46 | # define cBRI "\x1b[1;97m" 47 | # define cRST "\x1b[0m" 48 | 49 | # define bgBLK "\x1b[40m" 50 | # define bgRED "\x1b[41m" 51 | # define bgGRN "\x1b[42m" 52 | # define bgBRN "\x1b[43m" 53 | # define bgBLU "\x1b[44m" 54 | # define bgMGN "\x1b[45m" 55 | # define bgCYA "\x1b[46m" 56 | # define bgLGR "\x1b[47m" 57 | # define bgGRA "\x1b[100m" 58 | # define bgLRD "\x1b[101m" 59 | # define bgLGN "\x1b[102m" 60 | # define bgYEL "\x1b[103m" 61 | # define bgLBL "\x1b[104m" 62 | # define bgPIN "\x1b[105m" 63 | # define bgLCY "\x1b[106m" 64 | # define bgBRI "\x1b[107m" 65 | 66 | #else 67 | 68 | # define cBLK "" 69 | # define cRED "" 70 | # define cGRN "" 71 | # define cBRN "" 72 | # define cBLU "" 73 | # define cMGN "" 74 | # define cCYA "" 75 | # define cLGR "" 76 | # define cGRA "" 77 | # define cLRD "" 78 | # define cLGN "" 79 | # define cYEL "" 80 | # define cLBL "" 81 | # define cPIN "" 82 | # define cLCY "" 83 | # define cBRI "" 84 | # define cRST "" 85 | 86 | # define bgBLK "" 87 | # define bgRED "" 88 | # define bgGRN "" 89 | # define bgBRN "" 90 | # define bgBLU "" 91 | # define bgMGN "" 92 | # define bgCYA "" 93 | # define bgLGR "" 94 | # define bgGRA "" 95 | # define bgLRD "" 96 | # define bgLGN "" 97 | # define bgYEL "" 98 | # define bgLBL "" 99 | # define bgPIN "" 100 | # define bgLCY "" 101 | # define bgBRI "" 102 | 103 | #endif /* ^USE_COLOR */ 104 | 105 | /************************* 106 | * Box drawing sequences * 107 | *************************/ 108 | 109 | #ifdef FANCY_BOXES 110 | 111 | # define SET_G1 "\x1b)0" /* Set G1 for box drawing */ 112 | # define RESET_G1 "\x1b)B" /* Reset G1 to ASCII */ 113 | # define bSTART "\x0e" /* Enter G1 drawing mode */ 114 | # define bSTOP "\x0f" /* Leave G1 drawing mode */ 115 | # define bH "q" /* Horizontal line */ 116 | # define bV "x" /* Vertical line */ 117 | # define bLT "l" /* Left top corner */ 118 | # define bRT "k" /* Right top corner */ 119 | # define bLB "m" /* Left bottom corner */ 120 | # define bRB "j" /* Right bottom corner */ 121 | # define bX "n" /* Cross */ 122 | # define bVR "t" /* Vertical, branch right */ 123 | # define bVL "u" /* Vertical, branch left */ 124 | # define bHT "v" /* Horizontal, branch top */ 125 | # define bHB "w" /* Horizontal, branch bottom */ 126 | 127 | #else 128 | 129 | # define SET_G1 "" 130 | # define RESET_G1 "" 131 | # define bSTART "" 132 | # define bSTOP "" 133 | # define bH "-" 134 | # define bV "|" 135 | # define bLT "+" 136 | # define bRT "+" 137 | # define bLB "+" 138 | # define bRB "+" 139 | # define bX "+" 140 | # define bVR "+" 141 | # define bVL "+" 142 | # define bHT "+" 143 | # define bHB "+" 144 | 145 | #endif /* ^FANCY_BOXES */ 146 | 147 | /*********************** 148 | * Misc terminal codes * 149 | ***********************/ 150 | 151 | #define TERM_HOME "\x1b[H" 152 | #define TERM_CLEAR TERM_HOME "\x1b[2J" 153 | #define cEOL "\x1b[0K" 154 | #define CURSOR_HIDE "\x1b[?25l" 155 | #define CURSOR_SHOW "\x1b[?25h" 156 | 157 | /************************ 158 | * Debug & error macros * 159 | ************************/ 160 | 161 | /* Just print stuff to the appropriate stream. */ 162 | 163 | #ifdef MESSAGES_TO_STDOUT 164 | # define SAYF(x...) printf(x) 165 | #else 166 | # define SAYF(x...) fprintf(stderr, x) 167 | #endif /* ^MESSAGES_TO_STDOUT */ 168 | 169 | /* Show a prefixed warning. */ 170 | 171 | #define WARNF(x...) do { \ 172 | SAYF(cYEL "[!] " cBRI "WARNING: " cRST x); \ 173 | SAYF(cRST "\n"); \ 174 | } while (0) 175 | 176 | /* Show a prefixed "doing something" message. */ 177 | 178 | #define ACTF(x...) do { \ 179 | SAYF(cLBL "[*] " cRST x); \ 180 | SAYF(cRST "\n"); \ 181 | } while (0) 182 | 183 | /* Show a prefixed "success" message. */ 184 | 185 | #define OKF(x...) do { \ 186 | SAYF(cLGN "[+] " cRST x); \ 187 | SAYF(cRST "\n"); \ 188 | } while (0) 189 | 190 | /* Show a prefixed fatal error message (not used in afl). */ 191 | 192 | #define BADF(x...) do { \ 193 | SAYF(cLRD "\n[-] " cRST x); \ 194 | SAYF(cRST "\n"); \ 195 | } while (0) 196 | 197 | /* Die with a verbose non-OS fatal error message. */ 198 | 199 | #define FATAL(x...) do { \ 200 | SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD "\n[-] PROGRAM ABORT : " \ 201 | cBRI x); \ 202 | SAYF(cLRD "\n Location : " cRST "%s(), %s:%u\n\n", \ 203 | __FUNCTION__, __FILE__, __LINE__); \ 204 | exit(1); \ 205 | } while (0) 206 | 207 | /* Die by calling abort() to provide a core dump. */ 208 | 209 | #define ABORT(x...) do { \ 210 | SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD "\n[-] PROGRAM ABORT : " \ 211 | cBRI x); \ 212 | SAYF(cLRD "\n Stop location : " cRST "%s(), %s:%u\n\n", \ 213 | __FUNCTION__, __FILE__, __LINE__); \ 214 | abort(); \ 215 | } while (0) 216 | 217 | /* Die while also including the output of perror(). */ 218 | 219 | #define PFATAL(x...) do { \ 220 | fflush(stdout); \ 221 | SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD "\n[-] SYSTEM ERROR : " \ 222 | cBRI x); \ 223 | SAYF(cLRD "\n Stop location : " cRST "%s(), %s:%u\n", \ 224 | __FUNCTION__, __FILE__, __LINE__); \ 225 | SAYF(cLRD " OS message : " cRST "%s\n", strerror(errno)); \ 226 | exit(1); \ 227 | } while (0) 228 | 229 | /* Die with FAULT() or PFAULT() depending on the value of res (used to 230 | interpret different failure modes for read(), write(), etc). */ 231 | 232 | #define RPFATAL(res, x...) do { \ 233 | if (res < 0) PFATAL(x); else FATAL(x); \ 234 | } while (0) 235 | 236 | /* Error-checking versions of read() and write() that call RPFATAL() as 237 | appropriate. */ 238 | 239 | #define ck_write(fd, buf, len, fn) do { \ 240 | u32 _len = (len); \ 241 | s32 _res = write(fd, buf, _len); \ 242 | if (_res != _len) RPFATAL(_res, "Short write to %s", fn); \ 243 | } while (0) 244 | 245 | #define ck_read(fd, buf, len, fn) do { \ 246 | u32 _len = (len); \ 247 | s32 _res = read(fd, buf, _len); \ 248 | if (_res != _len) RPFATAL(_res, "Short read from %s", fn); \ 249 | } while (0) 250 | 251 | #endif /* ! _HAVE_DEBUG_H */ 252 | -------------------------------------------------------------------------------- /dictionaries/README.dictionaries: -------------------------------------------------------------------------------- 1 | ================ 2 | AFL dictionaries 3 | ================ 4 | 5 | (See ../docs/README for the general instruction manual.) 6 | 7 | This subdirectory contains a set of dictionaries that can be used in 8 | conjunction with the -x option to allow the fuzzer to effortlessly explore the 9 | grammar of some of the more verbose data formats or languages. The basic 10 | principle behind the operation of fuzzer dictionaries is outlined in section 9 11 | of the "main" README for the project. 12 | 13 | Custom dictionaries can be added at will. They should consist of a 14 | reasonably-sized set of rudimentary syntax units that the fuzzer will then try 15 | to clobber together in various ways. Snippets between 2 and 16 bytes are usually 16 | the sweet spot. 17 | 18 | Custom dictionaries can be created in two ways: 19 | 20 | - By creating a new directory and placing each token in a separate file, in 21 | which case, there is no need to escape or otherwise format the data. 22 | 23 | - By creating a flat text file where tokens are listed one per line in the 24 | format of name="value". The alphanumeric name is ignored and can be omitted, 25 | although it is a convenient way to document the meaning of a particular 26 | token. The value must appear in quotes, with hex escaping (\xNN) applied to 27 | all non-printable, high-bit, or otherwise problematic characters (\\ and \" 28 | shorthands are recognized, too). 29 | 30 | The fuzzer auto-selects the appropriate mode depending on whether the -x 31 | parameter is a file or a directory. 32 | 33 | In the file mode, every name field can be optionally followed by @, e.g.: 34 | 35 | keyword_foo@1 = "foo" 36 | 37 | Such entries will be loaded only if the requested dictionary level is equal or 38 | higher than this number. The default level is zero; a higher value can be set 39 | by appending @ to the dictionary file name, like so: 40 | 41 | -x path/to/dictionary.dct@2 42 | 43 | Good examples of dictionaries can be found in xml.dict and png.dict. 44 | -------------------------------------------------------------------------------- /dictionaries/gif.dict: -------------------------------------------------------------------------------- 1 | # 2 | # AFL dictionary for GIF images 3 | # ----------------------------- 4 | # 5 | # Created by Michal Zalewski 6 | # 7 | 8 | header_87a="87a" 9 | header_89a="89a" 10 | header_gif="GIF" 11 | 12 | marker_2c="," 13 | marker_3b=";" 14 | 15 | section_2101="!\x01\x12" 16 | section_21f9="!\xf9\x04" 17 | section_21fe="!\xfe" 18 | section_21ff="!\xff\x11" 19 | -------------------------------------------------------------------------------- /dictionaries/html_tags.dict: -------------------------------------------------------------------------------- 1 | # 2 | # AFL dictionary for HTML parsers (tags only) 3 | # ------------------------------------------- 4 | # 5 | # A basic collection of HTML tags likely to matter to HTML parsers. Does *not* 6 | # include any attributes or attribute values. 7 | # 8 | # Created by Michal Zalewski 9 | # 10 | 11 | tag_a="" 12 | tag_abbr="" 13 | tag_acronym="" 14 | tag_address="

" 15 | tag_annotation_xml="" 16 | tag_applet="" 17 | tag_area="" 18 | tag_article="
" 19 | tag_aside="