├── .gitignore ├── .travis.yml ├── .travis └── check_fuzzer_stats.sh ├── Android.bp ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── 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 ├── android-ashmem.h ├── config.h ├── debug.h ├── dictionaries ├── README.dictionaries ├── gif.dict ├── html_tags.dict ├── jpeg.dict ├── js.dict ├── json.dict ├── pdf.dict ├── perl.dict ├── png.dict ├── regexp.dict ├── sql.dict ├── tiff.dict ├── webp.dict └── xml.dict ├── docs ├── COPYING ├── ChangeLog ├── INSTALL ├── QuickStartGuide.txt ├── 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 │ ├── test.c │ └── test.txt ├── 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 │ ├── configure.diff │ ├── cpu-exec.diff │ ├── elfload.diff │ ├── memfd.diff │ └── syscall.diff ├── test-instr.c ├── test-libfuzzer-target.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 │ ├── regexp │ ├── reg1 │ ├── reg2 │ ├── reg3 │ └── reg4 │ ├── rtf │ └── small_document.rtf │ ├── sql │ └── simple_queries.sql │ ├── text │ └── hello_world.txt │ └── xml │ └── small_document.xml └── types.h /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries produced by "make". 2 | afl-analyze 3 | afl-as 4 | afl-clang 5 | afl-clang++ 6 | afl-fuzz 7 | afl-g++ 8 | afl-gcc 9 | afl-gotcpu 10 | afl-showmap 11 | afl-tmin 12 | as 13 | 14 | # Binaries produced by "make -C llvm_mode" 15 | afl-clang-fast 16 | afl-clang-fast++ 17 | afl-llvm-pass.so 18 | afl-llvm-rt-32.o 19 | afl-llvm-rt-64.o 20 | afl-llvm-rt.o 21 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | 3 | env: 4 | - AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 AFL_NO_UI=1 AFL_STOP_MANUALLY=1 5 | - AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 AFL_NO_UI=1 AFL_EXIT_WHEN_DONE=1 6 | # TODO: test AFL_BENCH_UNTIL_CRASH once we have a target that crashes 7 | - AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 AFL_NO_UI=1 AFL_BENCH_JUST_ONE=1 8 | 9 | before_install: 10 | - sudo apt update 11 | - sudo apt install -y libtool libtool-bin automake bison libglib2.0 12 | 13 | # TODO: Look into splitting off some builds using a build matrix. 14 | # TODO: Move this all into a bash script so we don't need to write bash in yaml. 15 | script: 16 | - make 17 | - ./afl-gcc ./test-instr.c -o test-instr-gcc 18 | - mkdir seeds 19 | - echo "" > seeds/nil_seed 20 | - if [ -z "$AFL_STOP_MANUALLY" ]; 21 | then ./afl-fuzz -i seeds -o out/ -- ./test-instr-gcc; 22 | else timeout --preserve-status 5s ./afl-fuzz -i seeds -o out/ -- ./test-instr-gcc; 23 | fi 24 | - .travis/check_fuzzer_stats.sh -o out -k peak_rss_mb -v 1 -p 3 25 | - rm -r out/* 26 | - ./afl-clang ./test-instr.c -o test-instr-clang 27 | - if [ -z "$AFL_STOP_MANUALLY" ]; 28 | then ./afl-fuzz -i seeds -o out/ -- ./test-instr-clang; 29 | else timeout --preserve-status 5s ./afl-fuzz -i seeds -o out/ -- ./test-instr-clang; 30 | fi 31 | - .travis/check_fuzzer_stats.sh -o out -k peak_rss_mb -v 1 -p 2 32 | - make clean 33 | - CC=clang CXX=clang++ make 34 | - cd llvm_mode 35 | # TODO: Build with different versions of clang/LLVM since LLVM passes don't 36 | # have a stable API. 37 | - CC=clang CXX=clang++ LLVM_CONFIG=llvm-config make 38 | - cd .. 39 | - rm -r out/* 40 | - ./afl-clang-fast ./test-instr.c -o test-instr-clang-fast 41 | - if [ -z "$AFL_STOP_MANUALLY" ]; 42 | then ./afl-fuzz -i seeds -o out/ -- ./test-instr-clang-fast; 43 | else timeout --preserve-status 5s ./afl-fuzz -i seeds -o out/ -- ./test-instr-clang-fast; 44 | fi 45 | - .travis/check_fuzzer_stats.sh -o out -k peak_rss_mb -v 1 -p 3 46 | # Test fuzzing libFuzzer targets and trace-pc-guard instrumentation. 47 | - clang -g -fsanitize-coverage=trace-pc-guard ./test-libfuzzer-target.c -c 48 | - clang -c -w llvm_mode/afl-llvm-rt.o.c 49 | - wget https://raw.githubusercontent.com/llvm/llvm-project/main/compiler-rt/lib/fuzzer/afl/afl_driver.cpp 50 | - clang++ afl_driver.cpp afl-llvm-rt.o.o test-libfuzzer-target.o -o test-libfuzzer-target 51 | - timeout --preserve-status 5s ./afl-fuzz -i seeds -o out/ -- ./test-libfuzzer-target 52 | - cd qemu_mode 53 | - ./build_qemu_support.sh 54 | - cd .. 55 | - gcc ./test-instr.c -o test-no-instr 56 | - if [ -z "$AFL_STOP_MANUALLY" ]; 57 | then ./afl-fuzz -Q -i seeds -o out/ -- ./test-no-instr; 58 | else timeout --preserve-status 5s ./afl-fuzz -Q -i seeds -o out/ -- ./test-no-instr; 59 | fi 60 | - .travis/check_fuzzer_stats.sh -o out -k peak_rss_mb -v 12 -p 9 61 | -------------------------------------------------------------------------------- /.travis/check_fuzzer_stats.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | usage() { 3 | echo "Usage: $0 -o -k -v [-p ]" 1>&2; 4 | echo " " 1>&2; 5 | echo "Checks if a key:value appears in the fuzzer_stats report" 1>&2; 6 | echo " " 1>&2; 7 | echo -n "If \"value\" is numeric and \"precision\" is defined, checks if the stat " 1>&2; 8 | echo "printed by afl is value+/-precision." 1>&2; 9 | exit 1; } 10 | 11 | while getopts "o:k:v:p:" opt; do 12 | case "${opt}" in 13 | o) 14 | o=${OPTARG} 15 | ;; 16 | k) 17 | k=${OPTARG} 18 | ;; 19 | v) 20 | v=${OPTARG} 21 | ;; 22 | p) 23 | p=${OPTARG} 24 | ;; 25 | *) 26 | usage 27 | ;; 28 | esac 29 | done 30 | 31 | if [ -z $o ] || [ -z $k ] || [ -z $v ]; then usage; fi 32 | 33 | # xargs to trim the surrounding whitespaces 34 | stat_v=$( grep $k "$o"/fuzzer_stats | cut -d ":" -f 2 | xargs ) 35 | v=$( echo "$v" | xargs ) 36 | 37 | if [ -z stat_v ]; 38 | then echo "ERROR: key $k not found in fuzzer_stats." 1>&2 39 | exit 1 40 | fi 41 | 42 | re_percent='^[0-9]+([.][0-9]+)?\%$' 43 | # if the argument is a number in percentage, get rid of the % 44 | if [[ "$v" =~ $re_percent ]]; then v=${v: :-1}; fi 45 | if [[ "$stat_v" =~ $re_percent ]]; then stat_v=${stat_v: :-1}; fi 46 | 47 | re_numeric='^[0-9]+([.][0-9]+)?$' 48 | # if the argument is not a number, we check for strict equality 49 | if (! [[ "$v" =~ $re_numeric ]]) || (! [[ "$stat_v" =~ $re ]]); 50 | then if [ "$v" != "$stat_v" ]; 51 | then echo "ERROR: \"$k:$stat_v\" (should be $v)." 1>&2 52 | exit 2; 53 | fi 54 | # checks if the stat reported by afl is in the range 55 | elif [ "$stat_v" -lt $(( v - p )) ] || [ "$stat_v" -gt $(( v + p )) ]; 56 | then echo "ERROR: key $k:$stat_v is out of correct range." 1>&2 57 | exit 3; 58 | fi 59 | echo "OK: key $k:$stat_v" 1>&2 60 | 61 | -------------------------------------------------------------------------------- /Android.bp: -------------------------------------------------------------------------------- 1 | cc_defaults { 2 | name: "afl-defaults", 3 | 4 | cflags: [ 5 | "-funroll-loops", 6 | "-Wno-pointer-sign", 7 | "-Wno-pointer-arith", 8 | "-Wno-sign-compare", 9 | "-Wno-unused-parameter", 10 | "-Wno-unused-function", 11 | "-Wno-format", 12 | "-Wno-user-defined-warnings", 13 | "-DUSE_TRACE_PC=1", 14 | "-DBIN_PATH=\"out/host/linux-x86/bin\"", 15 | "-DDOC_PATH=\"out/host/linux-x86/shared/doc/afl\"", 16 | "-D__USE_GNU", 17 | ], 18 | } 19 | 20 | cc_binary { 21 | name: "afl-fuzz", 22 | static_executable: true, 23 | host_supported: true, 24 | 25 | defaults: [ 26 | "afl-defaults", 27 | ], 28 | 29 | srcs: [ 30 | "afl-fuzz.c", 31 | ], 32 | } 33 | 34 | cc_binary { 35 | name: "afl-showmap", 36 | static_executable: true, 37 | host_supported: true, 38 | 39 | defaults: [ 40 | "afl-defaults", 41 | ], 42 | 43 | srcs: [ 44 | "afl-showmap.c", 45 | ], 46 | } 47 | 48 | cc_binary { 49 | name: "afl-tmin", 50 | static_executable: true, 51 | host_supported: true, 52 | 53 | defaults: [ 54 | "afl-defaults", 55 | ], 56 | 57 | srcs: [ 58 | "afl-tmin.c", 59 | ], 60 | } 61 | 62 | cc_binary { 63 | name: "afl-analyze", 64 | static_executable: true, 65 | host_supported: true, 66 | 67 | defaults: [ 68 | "afl-defaults", 69 | ], 70 | 71 | srcs: [ 72 | "afl-analyze.c", 73 | ], 74 | } 75 | 76 | cc_binary { 77 | name: "afl-gotcpu", 78 | static_executable: true, 79 | host_supported: true, 80 | 81 | defaults: [ 82 | "afl-defaults", 83 | ], 84 | 85 | srcs: [ 86 | "afl-gotcpu.c", 87 | ], 88 | } 89 | 90 | cc_binary_host { 91 | name: "afl-clang-fast", 92 | static_executable: true, 93 | 94 | defaults: [ 95 | "afl-defaults", 96 | ], 97 | 98 | cflags: [ 99 | "-D__ANDROID__", 100 | "-DAFL_PATH=\"out/host/linux-x86/lib64\"", 101 | ], 102 | 103 | srcs: [ 104 | "llvm_mode/afl-clang-fast.c", 105 | ], 106 | } 107 | 108 | cc_binary_host { 109 | name: "afl-clang-fast++", 110 | static_executable: true, 111 | 112 | defaults: [ 113 | "afl-defaults", 114 | ], 115 | 116 | cflags: [ 117 | "-D__ANDROID__", 118 | "-DAFL_PATH=\"out/host/linux-x86/lib64\"", 119 | ], 120 | 121 | srcs: [ 122 | "llvm_mode/afl-clang-fast.c", 123 | ], 124 | } 125 | 126 | cc_library_static { 127 | name: "afl-llvm-rt", 128 | compile_multilib: "both", 129 | vendor_available: true, 130 | host_supported: true, 131 | recovery_available: true, 132 | 133 | defaults: [ 134 | "afl-defaults", 135 | ], 136 | 137 | srcs: [ 138 | "llvm_mode/afl-llvm-rt.o.c", 139 | ], 140 | } 141 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to this project must be accompanied by a Contributor License 9 | Agreement. You (or your employer) retain the copyright to your contribution; 10 | this simply gives us permission to use and redistribute your contributions as 11 | part of the project. Head over to to see 12 | your current agreements on file or to sign a new one. 13 | 14 | You generally only need to submit a CLA once, so if you've already submitted one 15 | (even if it was for a different project), you probably don't need to do it 16 | again. 17 | 18 | ## Code reviews 19 | 20 | All submissions, including submissions by project members, require review. We 21 | use GitHub pull requests for this purpose. Consult 22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 23 | information on using pull requests. 24 | 25 | ## Community Guidelines 26 | 27 | This project follows [Google's Open Source Community 28 | Guidelines](https://opensource.google.com/conduct/). 29 | -------------------------------------------------------------------------------- /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 LLC 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 | ./afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null 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 README.md 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 | -------------------------------------------------------------------------------- /afl-gotcpu.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Google LLC All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at: 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | american fuzzy lop - free CPU gizmo 19 | ----------------------------------- 20 | 21 | Written and maintained by Michal Zalewski 22 | 23 | This tool provides a fairly accurate measurement of CPU preemption rate. 24 | It is meant to complement the quick-and-dirty load average widget shown 25 | in the afl-fuzz UI. See docs/parallel_fuzzing.txt for more info. 26 | 27 | For some work loads, the tool may actually suggest running more instances 28 | than you have CPU cores. This can happen if the tested program is spending 29 | a portion of its run time waiting for I/O, rather than being 100% 30 | CPU-bound. 31 | 32 | The idea for the getrusage()-based approach comes from Jakub Wilk. 33 | */ 34 | 35 | #define AFL_MAIN 36 | #include "android-ashmem.h" 37 | #define _GNU_SOURCE 38 | 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include "types.h" 51 | #include "debug.h" 52 | 53 | #ifdef __linux__ 54 | # define HAVE_AFFINITY 1 55 | #endif /* __linux__ */ 56 | 57 | 58 | /* Get unix time in microseconds. */ 59 | 60 | static u64 get_cur_time_us(void) { 61 | 62 | struct timeval tv; 63 | struct timezone tz; 64 | 65 | gettimeofday(&tv, &tz); 66 | 67 | return (tv.tv_sec * 1000000ULL) + tv.tv_usec; 68 | 69 | } 70 | 71 | 72 | /* Get CPU usage in microseconds. */ 73 | 74 | static u64 get_cpu_usage_us(void) { 75 | 76 | struct rusage u; 77 | 78 | getrusage(RUSAGE_SELF, &u); 79 | 80 | return (u.ru_utime.tv_sec * 1000000ULL) + u.ru_utime.tv_usec + 81 | (u.ru_stime.tv_sec * 1000000ULL) + u.ru_stime.tv_usec; 82 | 83 | } 84 | 85 | 86 | /* Measure preemption rate. */ 87 | 88 | static u32 measure_preemption(u32 target_ms) { 89 | 90 | static volatile u32 v1, v2; 91 | 92 | u64 st_t, en_t, st_c, en_c, real_delta, slice_delta; 93 | s32 loop_repeats = 0; 94 | 95 | st_t = get_cur_time_us(); 96 | st_c = get_cpu_usage_us(); 97 | 98 | repeat_loop: 99 | 100 | v1 = CTEST_BUSY_CYCLES; 101 | 102 | while (v1--) v2++; 103 | sched_yield(); 104 | 105 | en_t = get_cur_time_us(); 106 | 107 | if (en_t - st_t < target_ms * 1000) { 108 | loop_repeats++; 109 | goto repeat_loop; 110 | } 111 | 112 | /* Let's see what percentage of this time we actually had a chance to 113 | run, and how much time was spent in the penalty box. */ 114 | 115 | en_c = get_cpu_usage_us(); 116 | 117 | real_delta = (en_t - st_t) / 1000; 118 | slice_delta = (en_c - st_c) / 1000; 119 | 120 | return real_delta * 100 / slice_delta; 121 | 122 | } 123 | 124 | 125 | /* Do the benchmark thing. */ 126 | 127 | int main(int argc, char** argv) { 128 | 129 | #ifdef HAVE_AFFINITY 130 | 131 | u32 cpu_cnt = sysconf(_SC_NPROCESSORS_ONLN), 132 | idle_cpus = 0, maybe_cpus = 0, i; 133 | 134 | SAYF(cCYA "afl-gotcpu " cBRI VERSION cRST " by \n"); 135 | 136 | ACTF("Measuring per-core preemption rate (this will take %0.02f sec)...", 137 | ((double)CTEST_CORE_TRG_MS) / 1000); 138 | 139 | for (i = 0; i < cpu_cnt; i++) { 140 | 141 | s32 fr = fork(); 142 | 143 | if (fr < 0) PFATAL("fork failed"); 144 | 145 | if (!fr) { 146 | 147 | cpu_set_t c; 148 | u32 util_perc; 149 | 150 | CPU_ZERO(&c); 151 | CPU_SET(i, &c); 152 | 153 | if (sched_setaffinity(0, sizeof(c), &c)) 154 | PFATAL("sched_setaffinity failed for cpu %d", i); 155 | 156 | util_perc = measure_preemption(CTEST_CORE_TRG_MS); 157 | 158 | if (util_perc < 110) { 159 | 160 | SAYF(" Core #%u: " cLGN "AVAILABLE " cRST "(%u%%)\n", i, util_perc); 161 | exit(0); 162 | 163 | } else if (util_perc < 250) { 164 | 165 | SAYF(" Core #%u: " cYEL "CAUTION " cRST "(%u%%)\n", i, util_perc); 166 | exit(1); 167 | 168 | } 169 | 170 | SAYF(" Core #%u: " cLRD "OVERBOOKED " cRST "(%u%%)\n" cRST, i, 171 | util_perc); 172 | exit(2); 173 | 174 | } 175 | 176 | } 177 | 178 | for (i = 0; i < cpu_cnt; i++) { 179 | 180 | int ret; 181 | if (waitpid(-1, &ret, 0) < 0) PFATAL("waitpid failed"); 182 | 183 | if (WEXITSTATUS(ret) == 0) idle_cpus++; 184 | if (WEXITSTATUS(ret) <= 1) maybe_cpus++; 185 | 186 | } 187 | 188 | SAYF(cGRA "\n>>> "); 189 | 190 | if (idle_cpus) { 191 | 192 | if (maybe_cpus == idle_cpus) { 193 | 194 | SAYF(cLGN "PASS: " cRST "You can run more processes on %u core%s.", 195 | idle_cpus, idle_cpus > 1 ? "s" : ""); 196 | 197 | } else { 198 | 199 | SAYF(cLGN "PASS: " cRST "You can run more processes on %u to %u core%s.", 200 | idle_cpus, maybe_cpus, maybe_cpus > 1 ? "s" : ""); 201 | 202 | } 203 | 204 | SAYF(cGRA " <<<" cRST "\n\n"); 205 | return 0; 206 | 207 | } 208 | 209 | if (maybe_cpus) { 210 | 211 | SAYF(cYEL "CAUTION: " cRST "You may still have %u core%s available.", 212 | maybe_cpus, maybe_cpus > 1 ? "s" : ""); 213 | SAYF(cGRA " <<<" cRST "\n\n"); 214 | return 1; 215 | 216 | } 217 | 218 | SAYF(cLRD "FAIL: " cRST "All cores are overbooked."); 219 | SAYF(cGRA " <<<" cRST "\n\n"); 220 | return 2; 221 | 222 | #else 223 | 224 | u32 util_perc; 225 | 226 | SAYF(cCYA "afl-gotcpu " cBRI VERSION cRST " by \n"); 227 | 228 | /* Run a busy loop for CTEST_TARGET_MS. */ 229 | 230 | ACTF("Measuring gross preemption rate (this will take %0.02f sec)...", 231 | ((double)CTEST_TARGET_MS) / 1000); 232 | 233 | util_perc = measure_preemption(CTEST_TARGET_MS); 234 | 235 | /* Deliver the final verdict. */ 236 | 237 | SAYF(cGRA "\n>>> "); 238 | 239 | if (util_perc < 105) { 240 | 241 | SAYF(cLGN "PASS: " cRST "You can probably run additional processes."); 242 | 243 | } else if (util_perc < 130) { 244 | 245 | SAYF(cYEL "CAUTION: " cRST "Your CPU may be somewhat overbooked (%u%%).", 246 | util_perc); 247 | 248 | } else { 249 | 250 | SAYF(cLRD "FAIL: " cRST "Your CPU is overbooked (%u%%).", util_perc); 251 | 252 | } 253 | 254 | SAYF(cGRA " <<<" cRST "\n\n"); 255 | 256 | return (util_perc > 105) + (util_perc > 130); 257 | 258 | #endif /* ^HAVE_AFFINITY */ 259 | 260 | } 261 | -------------------------------------------------------------------------------- /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 LLC 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 LLC 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` || TMP=`mktemp -p /data/local/tmp .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 | -------------------------------------------------------------------------------- /android-ashmem.h: -------------------------------------------------------------------------------- 1 | #ifdef __ANDROID__ 2 | #ifndef _ANDROID_ASHMEM_H 3 | #define _ANDROID_ASHMEM_H 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #if __ANDROID_API__ >= 26 12 | #define shmat bionic_shmat 13 | #define shmctl bionic_shmctl 14 | #define shmdt bionic_shmdt 15 | #define shmget bionic_shmget 16 | #endif 17 | #include 18 | #undef shmat 19 | #undef shmctl 20 | #undef shmdt 21 | #undef shmget 22 | #include 23 | 24 | #define ASHMEM_DEVICE "/dev/ashmem" 25 | 26 | static inline int shmctl(int __shmid, int __cmd, struct shmid_ds *__buf) { 27 | int ret = 0; 28 | if (__cmd == IPC_RMID) { 29 | int length = ioctl(__shmid, ASHMEM_GET_SIZE, NULL); 30 | struct ashmem_pin pin = {0, length}; 31 | ret = ioctl(__shmid, ASHMEM_UNPIN, &pin); 32 | close(__shmid); 33 | } 34 | 35 | return ret; 36 | } 37 | 38 | static inline int shmget(key_t __key, size_t __size, int __shmflg) { 39 | (void) __shmflg; 40 | int fd, ret; 41 | char ourkey[11]; 42 | 43 | fd = open(ASHMEM_DEVICE, O_RDWR); 44 | if (fd < 0) 45 | return fd; 46 | 47 | sprintf(ourkey, "%d", __key); 48 | ret = ioctl(fd, ASHMEM_SET_NAME, ourkey); 49 | if (ret < 0) 50 | goto error; 51 | 52 | ret = ioctl(fd, ASHMEM_SET_SIZE, __size); 53 | if (ret < 0) 54 | goto error; 55 | 56 | return fd; 57 | 58 | error: 59 | close(fd); 60 | return ret; 61 | } 62 | 63 | static inline void *shmat(int __shmid, const void *__shmaddr, int __shmflg) { 64 | (void) __shmflg; 65 | int size; 66 | void *ptr; 67 | 68 | size = ioctl(__shmid, ASHMEM_GET_SIZE, NULL); 69 | if (size < 0) { 70 | return NULL; 71 | } 72 | 73 | ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, __shmid, 0); 74 | if (ptr == MAP_FAILED) { 75 | return NULL; 76 | } 77 | 78 | return ptr; 79 | } 80 | 81 | #endif /* !_ANDROID_ASHMEM_H */ 82 | #endif /* !__ANDROID__ */ 83 | -------------------------------------------------------------------------------- /debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2013 Google LLC All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at: 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | american fuzzy lop - debug / error handling macros 19 | -------------------------------------------------- 20 | 21 | Written and maintained by Michal Zalewski 22 | */ 23 | 24 | #ifndef _HAVE_DEBUG_H 25 | #define _HAVE_DEBUG_H 26 | 27 | #include 28 | 29 | #include "types.h" 30 | #include "config.h" 31 | 32 | /******************* 33 | * Terminal colors * 34 | *******************/ 35 | 36 | #ifdef USE_COLOR 37 | 38 | # define cBLK "\x1b[0;30m" 39 | # define cRED "\x1b[0;31m" 40 | # define cGRN "\x1b[0;32m" 41 | # define cBRN "\x1b[0;33m" 42 | # define cBLU "\x1b[0;34m" 43 | # define cMGN "\x1b[0;35m" 44 | # define cCYA "\x1b[0;36m" 45 | # define cLGR "\x1b[0;37m" 46 | # define cGRA "\x1b[1;90m" 47 | # define cLRD "\x1b[1;91m" 48 | # define cLGN "\x1b[1;92m" 49 | # define cYEL "\x1b[1;93m" 50 | # define cLBL "\x1b[1;94m" 51 | # define cPIN "\x1b[1;95m" 52 | # define cLCY "\x1b[1;96m" 53 | # define cBRI "\x1b[1;97m" 54 | # define cRST "\x1b[0m" 55 | 56 | # define bgBLK "\x1b[40m" 57 | # define bgRED "\x1b[41m" 58 | # define bgGRN "\x1b[42m" 59 | # define bgBRN "\x1b[43m" 60 | # define bgBLU "\x1b[44m" 61 | # define bgMGN "\x1b[45m" 62 | # define bgCYA "\x1b[46m" 63 | # define bgLGR "\x1b[47m" 64 | # define bgGRA "\x1b[100m" 65 | # define bgLRD "\x1b[101m" 66 | # define bgLGN "\x1b[102m" 67 | # define bgYEL "\x1b[103m" 68 | # define bgLBL "\x1b[104m" 69 | # define bgPIN "\x1b[105m" 70 | # define bgLCY "\x1b[106m" 71 | # define bgBRI "\x1b[107m" 72 | 73 | #else 74 | 75 | # define cBLK "" 76 | # define cRED "" 77 | # define cGRN "" 78 | # define cBRN "" 79 | # define cBLU "" 80 | # define cMGN "" 81 | # define cCYA "" 82 | # define cLGR "" 83 | # define cGRA "" 84 | # define cLRD "" 85 | # define cLGN "" 86 | # define cYEL "" 87 | # define cLBL "" 88 | # define cPIN "" 89 | # define cLCY "" 90 | # define cBRI "" 91 | # define cRST "" 92 | 93 | # define bgBLK "" 94 | # define bgRED "" 95 | # define bgGRN "" 96 | # define bgBRN "" 97 | # define bgBLU "" 98 | # define bgMGN "" 99 | # define bgCYA "" 100 | # define bgLGR "" 101 | # define bgGRA "" 102 | # define bgLRD "" 103 | # define bgLGN "" 104 | # define bgYEL "" 105 | # define bgLBL "" 106 | # define bgPIN "" 107 | # define bgLCY "" 108 | # define bgBRI "" 109 | 110 | #endif /* ^USE_COLOR */ 111 | 112 | /************************* 113 | * Box drawing sequences * 114 | *************************/ 115 | 116 | #ifdef FANCY_BOXES 117 | 118 | # define SET_G1 "\x1b)0" /* Set G1 for box drawing */ 119 | # define RESET_G1 "\x1b)B" /* Reset G1 to ASCII */ 120 | # define bSTART "\x0e" /* Enter G1 drawing mode */ 121 | # define bSTOP "\x0f" /* Leave G1 drawing mode */ 122 | # define bH "q" /* Horizontal line */ 123 | # define bV "x" /* Vertical line */ 124 | # define bLT "l" /* Left top corner */ 125 | # define bRT "k" /* Right top corner */ 126 | # define bLB "m" /* Left bottom corner */ 127 | # define bRB "j" /* Right bottom corner */ 128 | # define bX "n" /* Cross */ 129 | # define bVR "t" /* Vertical, branch right */ 130 | # define bVL "u" /* Vertical, branch left */ 131 | # define bHT "v" /* Horizontal, branch top */ 132 | # define bHB "w" /* Horizontal, branch bottom */ 133 | 134 | #else 135 | 136 | # define SET_G1 "" 137 | # define RESET_G1 "" 138 | # define bSTART "" 139 | # define bSTOP "" 140 | # define bH "-" 141 | # define bV "|" 142 | # define bLT "+" 143 | # define bRT "+" 144 | # define bLB "+" 145 | # define bRB "+" 146 | # define bX "+" 147 | # define bVR "+" 148 | # define bVL "+" 149 | # define bHT "+" 150 | # define bHB "+" 151 | 152 | #endif /* ^FANCY_BOXES */ 153 | 154 | /*********************** 155 | * Misc terminal codes * 156 | ***********************/ 157 | 158 | #define TERM_HOME "\x1b[H" 159 | #define TERM_CLEAR TERM_HOME "\x1b[2J" 160 | #define cEOL "\x1b[0K" 161 | #define CURSOR_HIDE "\x1b[?25l" 162 | #define CURSOR_SHOW "\x1b[?25h" 163 | 164 | /************************ 165 | * Debug & error macros * 166 | ************************/ 167 | 168 | /* Just print stuff to the appropriate stream. */ 169 | 170 | #ifdef MESSAGES_TO_STDOUT 171 | # define SAYF(x...) printf(x) 172 | #else 173 | # define SAYF(x...) fprintf(stderr, x) 174 | #endif /* ^MESSAGES_TO_STDOUT */ 175 | 176 | /* Show a prefixed warning. */ 177 | 178 | #define WARNF(x...) do { \ 179 | SAYF(cYEL "[!] " cBRI "WARNING: " cRST x); \ 180 | SAYF(cRST "\n"); \ 181 | } while (0) 182 | 183 | /* Show a prefixed "doing something" message. */ 184 | 185 | #define ACTF(x...) do { \ 186 | SAYF(cLBL "[*] " cRST x); \ 187 | SAYF(cRST "\n"); \ 188 | } while (0) 189 | 190 | /* Show a prefixed "success" message. */ 191 | 192 | #define OKF(x...) do { \ 193 | SAYF(cLGN "[+] " cRST x); \ 194 | SAYF(cRST "\n"); \ 195 | } while (0) 196 | 197 | /* Show a prefixed fatal error message (not used in afl). */ 198 | 199 | #define BADF(x...) do { \ 200 | SAYF(cLRD "\n[-] " cRST x); \ 201 | SAYF(cRST "\n"); \ 202 | } while (0) 203 | 204 | /* Die with a verbose non-OS fatal error message. */ 205 | 206 | #define FATAL(x...) do { \ 207 | SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD "\n[-] PROGRAM ABORT : " \ 208 | cBRI x); \ 209 | SAYF(cLRD "\n Location : " cRST "%s(), %s:%u\n\n", \ 210 | __FUNCTION__, __FILE__, __LINE__); \ 211 | exit(1); \ 212 | } while (0) 213 | 214 | /* Die by calling abort() to provide a core dump. */ 215 | 216 | #define ABORT(x...) do { \ 217 | SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD "\n[-] PROGRAM ABORT : " \ 218 | cBRI x); \ 219 | SAYF(cLRD "\n Stop location : " cRST "%s(), %s:%u\n\n", \ 220 | __FUNCTION__, __FILE__, __LINE__); \ 221 | abort(); \ 222 | } while (0) 223 | 224 | /* Die while also including the output of perror(). */ 225 | 226 | #define PFATAL(x...) do { \ 227 | fflush(stdout); \ 228 | SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD "\n[-] SYSTEM ERROR : " \ 229 | cBRI x); \ 230 | SAYF(cLRD "\n Stop location : " cRST "%s(), %s:%u\n", \ 231 | __FUNCTION__, __FILE__, __LINE__); \ 232 | SAYF(cLRD " OS message : " cRST "%s\n", strerror(errno)); \ 233 | exit(1); \ 234 | } while (0) 235 | 236 | /* Die with FAULT() or PFAULT() depending on the value of res (used to 237 | interpret different failure modes for read(), write(), etc). */ 238 | 239 | #define RPFATAL(res, x...) do { \ 240 | if (res < 0) PFATAL(x); else FATAL(x); \ 241 | } while (0) 242 | 243 | /* Error-checking versions of read() and write() that call RPFATAL() as 244 | appropriate. */ 245 | 246 | #define ck_write(fd, buf, len, fn) do { \ 247 | u32 _len = (len); \ 248 | s32 _res = write(fd, buf, _len); \ 249 | if (_res != _len) RPFATAL(_res, "Short write to %s", fn); \ 250 | } while (0) 251 | 252 | #define ck_read(fd, buf, len, fn) do { \ 253 | u32 _len = (len); \ 254 | s32 _res = read(fd, buf, _len); \ 255 | if (_res != _len) RPFATAL(_res, "Short read from %s", fn); \ 256 | } while (0) 257 | 258 | #endif /* ! _HAVE_DEBUG_H */ 259 | -------------------------------------------------------------------------------- /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="