├── Makefile ├── README.llvm ├── README.osx ├── afl-clang-fast.c ├── afl-instr ├── Makefile ├── afl-as.h ├── afl-llvm-pass.so.cc ├── alloc-inl.h ├── config.h ├── debug.h ├── hash.h └── types.h ├── afl-llvm-pass.so.cc ├── afl-llvm-rt.o.c └── compile_llvm.sh /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # american fuzzy lop - LLVM instrumentation 3 | # ----------------------------------------- 4 | # 5 | # Written by Laszlo Szekeres and 6 | # Michal Zalewski 7 | # 8 | # LLVM integration design comes from Laszlo Szekeres. 9 | # 10 | # Copyright 2015 Google Inc. All rights reserved. 11 | # 12 | # Licensed under the Apache License, Version 2.0 (the "License"); 13 | # you may not use this file except in compliance with the License. 14 | # You may obtain a copy of the License at: 15 | # 16 | # http://www.apache.org/licenses/LICENSE-2.0 17 | # 18 | 19 | PREFIX ?= /opt/local 20 | #HELPER_PATH = $(PREFIX)/lib/afl 21 | HELPER_PATH = . 22 | 23 | LLVM_SRC_DIR = $(PWD)/llvm-3.5.0 24 | 25 | BIN_PATH = $(PREFIX)/bin 26 | 27 | VERSION = $(shell grep ^VERSION ../Makefile | cut -d= -f2 | sed 's/ //') 28 | 29 | LLVM_CONFIG ?= llvm-config 30 | 31 | CFLAGS ?= -O3 -funroll-loops 32 | CFLAGS += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign \ 33 | -DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \ 34 | -DVERSION=\"$(VERSION)\" 35 | 36 | CXXFLAGS ?= -O3 -funroll-loops 37 | CXXFLAGS += -Wall -D_FORTIFY_SOURCE=2 -g -v -Wno-pointer-sign \ 38 | -DVERSION=\"$(VERSION)\" 39 | 40 | CLANG_CFL = `$(LLVM_CONFIG) --cxxflags` -fno-rtti $(CXXFLAGS) 41 | CLANG_LFL = `$(LLVM_CONFIG) --ldflags --libs --system-libs` $(LDFLAGS) 42 | 43 | # We were using llvm-config --bindir to get the location of clang, but 44 | # this seems to be busted on some distros, so using the one in $PATH is 45 | # probably better. 46 | 47 | ifeq "$(origin CC)" "default" 48 | 49 | CC = /opt/local/bin/clang 50 | CXX = /opt/local/bin/clang++ 51 | 52 | endif 53 | 54 | PROGS = afl-llvm-pass.so afl-llvm-rt.o 55 | 56 | all: test_deps $(PROGS) test_build all_done 57 | 58 | osx: test_deps compile_llvm afl-llvm-rt.o ../afl-clang-fast test_build_osx 59 | 60 | compile_llvm: 61 | ./compile_llvm.sh 62 | 63 | test_build_osx: afl-llvm-rt.o 64 | @echo "[*] Testing the CC wrapper and instrumentation output..." 65 | unset AFL_USE_ASAN AFL_USE_MSAN AFL_DEFER_FORKSRV; AFL_QUIET=1 AFL_INST_RATIO=100 AFL_PATH=. AFL_CC=$(LLVM_SRC_DIR)/build/Release+Asserts/bin/clang ../afl-clang-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS) 66 | echo 0 | ../afl-showmap -m none -q -o .test-instr0 ./test-instr 67 | echo 1 | ../afl-showmap -m none -q -o .test-instr1 ./test-instr 68 | @rm -f test-instr 69 | @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 70 | @echo "[+] All right, the instrumentation seems to be working!" 71 | 72 | test_deps: 73 | @echo "[*] Checking for working 'llvm-config'..." 74 | @which $(LLVM_CONFIG) >/dev/null 2>&1 || ( echo "[-] Oops, can't find 'llvm-config'. Install clang or set \$$LLVM_CONFIG or \$$PATH beforehand."; echo " (Sometimes, the binary will be named llvm-config-3.5 or something like that.)"; exit 1 ) 75 | @echo "[*] Checking for working '$(CC)'..." 76 | @which $(CC) >/dev/null 2>&1 || ( echo "[-] Oops, can't find '$(CC)'. Make sure that it's in your \$$PATH (or set \$$CC and \$$CXX)."; exit 1 ) 77 | @echo "[*] Checking for '../afl-showmap'..." 78 | @test -f ../afl-showmap || ( echo "[-] Oops, can't find '../afl-showmap'. Be sure to compile AFL first."; exit 1 ) 79 | @echo "[+] All set and ready to build." 80 | 81 | ../afl-clang-fast: afl-clang-fast.c | test_deps 82 | $(CC) $(CFLAGS) $< -o $@ $(LDFLAGS) 83 | ln -sf afl-clang-fast ../afl-clang-fast++ 84 | 85 | afl-llvm-pass.so: afl-llvm-pass.so.cc | test_deps 86 | $(CXX) $(CLANG_CFL) -dynamiclib $< -o $@ $(CLANG_LFL) 87 | 88 | afl-llvm-rt.o: afl-llvm-rt.o.c | test_deps 89 | $(CC) $(CFLAGS) -fPIC -c $< -o $@ 90 | 91 | test_build: $(PROGS) 92 | @echo "[*] Testing the CC wrapper and instrumentation output..." 93 | unset AFL_USE_ASAN AFL_USE_MSAN AFL_DEFER_FORKSRV; AFL_QUIET=1 AFL_INST_RATIO=100 AFL_PATH=. AFL_CC=$(CC) ../afl-clang-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS) 94 | echo 0 | ../afl-showmap -m none -q -o .test-instr0 ./test-instr 95 | echo 1 | ../afl-showmap -m none -q -o .test-instr1 ./test-instr 96 | @rm -f test-instr 97 | @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 98 | @echo "[+] All right, the instrumentation seems to be working!" 99 | 100 | all_done: test_build 101 | @echo "[+] All done! You can now use '../afl-clang-fast' to compile programs." 102 | 103 | .NOTPARALLEL: clean 104 | 105 | clean: 106 | rm -f *.o *.so *~ a.out core core.[1-9][0-9]* test-instr .test-instr0 .test-instr1 107 | rm -f $(PROGS) ../afl-clang-fast++ 108 | 109 | superclean: clean 110 | rm -rf $(LLVM_SRC_DIR) *.dSYM *.xz 111 | -------------------------------------------------------------------------------- /README.llvm: -------------------------------------------------------------------------------- 1 | ============================================ 2 | Fast LLVM-based instrumentation for afl-fuzz 3 | ============================================ 4 | 5 | (See ../docs/README for the general instruction manual.) 6 | 7 | 1) Introduction 8 | --------------- 9 | 10 | The code in this directory allows you to instrument programs for AFL using 11 | true compiler-level instrumentation, instead of the more crude 12 | assembly-level rewriting approach taken by afl-gcc and afl-clang. This has 13 | several interesting properties: 14 | 15 | - The compiler can make many optimizations that are hard to pull off when 16 | manually inserting assembly. As a result, some slow, CPU-bound programs will 17 | run up to around 2x faster. 18 | 19 | The gains are less pronounced for fast binaries, where the speed is limited 20 | chiefly by the cost of creating new processes. In such cases, the gain will 21 | probably stay within 10%. 22 | 23 | - The instrumentation is CPU-independent. At least in principle, you should 24 | be able to rely on it to fuzz programs on non-x86 architectures (after 25 | building afl-fuzz with AFL_NOX86=1). 26 | 27 | - Because the features relies on the internals of LLVM, it is clang-specific 28 | and will *not* work with GCC. 29 | 30 | Once this implementation is shown to be sufficiently robust, it will probably 31 | replace afl-clang. For now, it can be built separately and co-exists with the 32 | original code. 33 | 34 | The idea and much of the implementation comes from Laszlo Szekeres. 35 | 36 | 2) How to use 37 | ------------- 38 | 39 | In order to leverage this mechanism, you need to have clang installed on your 40 | system. You should also make sure that the llvm-config tool is in your path; 41 | if not, be sure to set LLVM_CONFIG in the environment beforehand. 42 | 43 | Unfortunately, some systems come without llvm-config or the LLVM development 44 | headers. In such a case, you may have to do a full install on your own, or 45 | download pre-built binaries from: 46 | 47 | http://llvm.org/releases/download.html 48 | 49 | To build the instrumentation, type 'make'. This will generate binaries called 50 | afl-clang-fast and afl-clang-fast++ in the parent directory. Once this is done, 51 | you can instrument third-party code in a way similar to the standard operating 52 | mode of AFL, e.g.: 53 | 54 | CC=/path/to/afl/afl-clang-fast ./configure [...options...] 55 | make 56 | 57 | ...or: 58 | 59 | CXX=/path/to/afl/afl-clang-fast++ ./configure [...options...] 60 | make 61 | 62 | The tool honors roughly the same environmental variables as afl-gcc (see 63 | ../docs/env_variables.txt). This includes AFL_INST_RATIO, AFL_USE_ASAN, 64 | AFL_HARDEN, and AFL_DONT_OPTIMIZE. 65 | 66 | Note: if you want the LLVM helper to be installed on your system for all 67 | users, you need to build it before issuing 'make install' in the parent 68 | directory. 69 | 70 | 3) Gotchas, feedback, bugs 71 | -------------------------- 72 | 73 | This is an early-stage mechanism, so field reports are welcome. You can send 74 | bug reports to . 75 | 76 | 4) Bonus feature: deferred instrumentation 77 | ------------------------------------------ 78 | 79 | AFL tries to optimize performance by executing the targeted binary just once, 80 | stopping it just before main(), and then cloning this "master" process to get 81 | a steady supply of targets to fuzz. 82 | 83 | Although this approach eliminates much of the OS-, linker- and libc-level 84 | costs of executing the program, it does not always help with binaries that 85 | perform other time-consuming initialization steps before getting to the input 86 | file. 87 | 88 | In such cases, it would be beneficial to initialize the forkserver a bit later, 89 | once most of the initialization work is already done, but before the binary 90 | attempts to read the fuzzed input and parse it. You can do this in LLVM mode in 91 | a fairly simple way: 92 | 93 | 1) First, locate a suitable location in the code for the deferred initialization 94 | to take place. This needs to be done with *extreme* care to avoid breaking 95 | the binary. In particular, the program will probably malfunction if the 96 | initialization happens after: 97 | 98 | - The creation of any vital threads or child processes - since the forkserver 99 | can't clone them easily. 100 | 101 | - The creation of temporary files, network sockets, offset-sensitive file 102 | descriptors, and similar shared-state resources - but only provided that 103 | their state meaningfully influences the behavior of the program later on. 104 | 105 | - Any access to the fuzzed input, including the metadata about its size. 106 | 107 | Of course, things will also not work if the forkserver is never initialized 108 | at all; in this case, afl-fuzz will complain about failed handshake and bail 109 | out. 110 | 111 | 2) Next, insert the following global function declaration somewhere in the 112 | source file: 113 | 114 | void __afl_manual_init(void); 115 | 116 | ...and add a call to this function in the desired location before recompiling 117 | the project with afl-clang-fast (afl-gcc and afl-clang will *not* work). 118 | 119 | 3) Finally, be sure to set AFL_DEFER_FORKSRV=1 before invoking afl-fuzz. 120 | 121 | Again, this feature is easy to misuse; be careful and double-test that the 122 | coverage and the number of discovered paths is comparable between normal and 123 | deferred runs. That said, when you do it well, you can see gains up to 10x or 124 | so: 125 | 126 | https://groups.google.com/forum/#!topic/afl-users/fNMJHl7Fhzs 127 | -------------------------------------------------------------------------------- /README.osx: -------------------------------------------------------------------------------- 1 | ============================================ 2 | Fast LLVM-based instrumentation for afl-fuzz 3 | ============================================ 4 | 5 | (See ../docs/README for the general instruction manual.) 6 | (See ./README.llvm for the basic idea) 7 | 8 | 0) Run `make osx` 9 | 10 | === 11 | BUGS 12 | === 13 | 14 | It's awful. Please fix it. -------------------------------------------------------------------------------- /afl-clang-fast.c: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop - LLVM-mode wrapper for clang 3 | ------------------------------------------------ 4 | 5 | Written by Laszlo Szekeres and 6 | Michal Zalewski 7 | 8 | LLVM integration design comes from Laszlo Szekeres. 9 | 10 | Copyright 2015 Google Inc. All rights reserved. 11 | 12 | Licensed under the Apache License, Version 2.0 (the "License"); 13 | you may not use this file except in compliance with the License. 14 | You may obtain a copy of the License at: 15 | 16 | http://www.apache.org/licenses/LICENSE-2.0 17 | 18 | This program is a drop-in replacement for clang, similar in most respects 19 | to ../afl-gcc. It tries to figure out compilation mode, adds a bunch 20 | of flags, and then calls the real compiler. 21 | 22 | */ 23 | 24 | #define AFL_MAIN 25 | 26 | #include "../config.h" 27 | #include "../types.h" 28 | #include "../debug.h" 29 | #include "../alloc-inl.h" 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | static u8* obj_path; /* Path to runtime libraries */ 37 | static u8** cc_params; /* Parameters passed to the real CC */ 38 | static u32 cc_par_cnt = 1; /* Param count, including argv0 */ 39 | 40 | 41 | /* Try to find the runtime libraries. If that fails, abort. */ 42 | 43 | static void find_obj(u8* argv0) { 44 | 45 | u8 *afl_path = getenv("AFL_PATH"); 46 | u8 *slash, *tmp; 47 | 48 | if (afl_path) { 49 | 50 | tmp = alloc_printf("%s/afl-llvm-rt.o", afl_path); 51 | 52 | if (!access(tmp, R_OK)) { 53 | obj_path = afl_path; 54 | ck_free(tmp); 55 | return; 56 | } 57 | 58 | ck_free(tmp); 59 | 60 | } 61 | 62 | slash = strrchr(argv0, '/'); 63 | 64 | if (slash) { 65 | 66 | u8 *dir; 67 | 68 | *slash = 0; 69 | dir = ck_strdup(argv0); 70 | *slash = '/'; 71 | 72 | tmp = alloc_printf("%s/afl-llvm-rt.o", dir); 73 | 74 | if (!access(tmp, R_OK)) { 75 | obj_path = dir; 76 | ck_free(tmp); 77 | return; 78 | } 79 | 80 | ck_free(tmp); 81 | ck_free(dir); 82 | 83 | } 84 | 85 | if (!access(AFL_PATH "/afl-llvm-rt.o", R_OK)) { 86 | obj_path = AFL_PATH; 87 | return; 88 | } 89 | 90 | FATAL("Unable to find 'afl-llvm-rt.o' or 'afl-llvm-pass.so'. Please set AFL_PATH"); 91 | 92 | } 93 | 94 | 95 | /* Copy argv to cc_params, making the necessary edits. */ 96 | 97 | static void edit_params(u32 argc, char** argv) { 98 | 99 | u8 fortify_set = 0, asan_set = 0, x_set = 0, maybe_linking = 1; 100 | u8 *name; 101 | 102 | cc_params = ck_alloc((argc + 32) * sizeof(u8*)); 103 | 104 | name = strrchr(argv[0], '/'); 105 | if (!name) name = argv[0]; else name++; 106 | 107 | if (!strcmp(name, "afl-clang-fast++")) { 108 | u8* alt_cxx = getenv("AFL_CXX"); 109 | cc_params[0] = alt_cxx ? alt_cxx : (u8*)"clang++"; 110 | } else { 111 | u8* alt_cc = getenv("AFL_CC"); 112 | cc_params[0] = alt_cc ? alt_cc : (u8*)"clang"; 113 | } 114 | 115 | cc_params[cc_par_cnt++] = "-Xclang"; 116 | cc_params[cc_par_cnt++] = "-load"; 117 | cc_params[cc_par_cnt++] = "-Xclang"; 118 | cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-pass.so", obj_path); 119 | cc_params[cc_par_cnt++] = "-Qunused-arguments"; 120 | 121 | while (--argc) { 122 | u8* cur = *(++argv); 123 | 124 | #if defined(__x86_64__) 125 | if (!strcmp(cur, "-m32")) FATAL("-m32 is not supported"); 126 | #endif 127 | 128 | if (!strcmp(cur, "-x")) x_set = 1; 129 | 130 | if (!strcmp(cur, "-c") || !strcmp(cur, "-S") || !strcmp(cur, "-E")) 131 | maybe_linking = 0; 132 | 133 | if (!strcmp(cur, "-fsanitize=address") || 134 | !strcmp(cur, "-fsanitize=memory")) asan_set = 1; 135 | 136 | if (strstr(cur, "FORTIFY_SOURCE")) fortify_set = 1; 137 | 138 | cc_params[cc_par_cnt++] = cur; 139 | 140 | } 141 | 142 | if (getenv("AFL_HARDEN")) { 143 | 144 | cc_params[cc_par_cnt++] = "-fstack-protector-all"; 145 | 146 | if (!fortify_set) 147 | cc_params[cc_par_cnt++] = "-D_FORTIFY_SOURCE=2"; 148 | 149 | } 150 | 151 | if (!asan_set) { 152 | 153 | if (getenv("AFL_USE_ASAN")) { 154 | 155 | cc_params[cc_par_cnt++] = "-fsanitize=address"; 156 | 157 | if (getenv("AFL_USE_MSAN")) 158 | FATAL("ASAN and MSAN are mutually exclusive"); 159 | 160 | } else if (getenv("AFL_USE_MSAN")) { 161 | 162 | cc_params[cc_par_cnt++] = "-fsanitize=memory"; 163 | 164 | if (getenv("AFL_USE_ASAN")) 165 | FATAL("ASAN and MSAN are mutually exclusive"); 166 | 167 | } 168 | 169 | } 170 | 171 | if (!getenv("AFL_DONT_OPTIMIZE")) { 172 | 173 | cc_params[cc_par_cnt++] = "-g"; 174 | cc_params[cc_par_cnt++] = "-O3"; 175 | cc_params[cc_par_cnt++] = "-funroll-loops"; 176 | 177 | } 178 | 179 | if (maybe_linking) { 180 | 181 | if (x_set) { 182 | cc_params[cc_par_cnt++] = "-x"; 183 | cc_params[cc_par_cnt++] = "none"; 184 | } 185 | 186 | cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-rt.o", obj_path); 187 | 188 | } 189 | 190 | cc_params[cc_par_cnt] = NULL; 191 | 192 | } 193 | 194 | 195 | /* Main entry point */ 196 | 197 | int main(int argc, char** argv) { 198 | 199 | if (isatty(2) && !getenv("AFL_QUIET")) { 200 | 201 | SAYF(cCYA "afl-clang-fast " cBRI VERSION cRST " by \n"); 202 | 203 | } 204 | 205 | if (argc < 2) { 206 | 207 | SAYF("\n" 208 | "This is a helper application for afl-fuzz. It serves as a drop-in replacement\n" 209 | "for clang, letting you recompile third-party code with the required runtime\n" 210 | "instrumentation. A common use pattern would be one of the following:\n\n" 211 | 212 | " CC=%s/afl-clang-fast ./configure\n" 213 | " CXX=%s/afl-clang-fast++ ./configure\n\n" 214 | 215 | "In contrast to the traditional afl-clang tool, this version is implemented as\n" 216 | "an LLVM pass and tends to offer improved performance with slow programs.\n\n" 217 | 218 | "You can specify custom next-stage toolchain via AFL_CC and AFL_CXX. Setting\n" 219 | "AFL_HARDEN enables hardening optimizations in the compiled code.\n\n", 220 | BIN_PATH, BIN_PATH); 221 | 222 | exit(1); 223 | 224 | } 225 | 226 | 227 | find_obj(argv[0]); 228 | 229 | edit_params(argc, argv); 230 | 231 | execvp(cc_params[0], (char**)cc_params); 232 | 233 | FATAL("Oops, failed to execute '%s' - check your PATH", cc_params[0]); 234 | 235 | return 0; 236 | 237 | } 238 | -------------------------------------------------------------------------------- /afl-instr/Makefile: -------------------------------------------------------------------------------- 1 | LEVEL= ../.. 2 | LIBRARYNAME= afl 3 | SHARED_LIBRARY= 1 4 | LOADABLE_MODULE= 1 5 | LINK_LIBS_IN_SHARED= 1 6 | ENABLE_OPTIMIZED= 1 7 | include $(LEVEL)/Makefile.common 8 | 9 | LDFLAGS += 10 | 11 | CXXFLAGS += -fexceptions -fPIC 12 | CXXFLAGS += -std=c++11 -g -O0 -------------------------------------------------------------------------------- /afl-instr/afl-as.h: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop - injectable parts 3 | ------------------------------------- 4 | 5 | Written and maintained by Michal Zalewski 6 | 7 | Forkserver design by Jann Horn 8 | 9 | Copyright 2013, 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 | This file houses the assembly-level instrumentation injected into fuzzed 18 | programs. The instrumentation stores XORed pairs of data: identifiers of the 19 | currently executing branch and the one that executed immediately before. 20 | 21 | TL;DR: the instrumentation does shm_trace_map[cur_loc ^ prev_loc]++ 22 | 23 | The code is designed for 32-bit and 64-bit x86 systems. Both modes should 24 | work everywhere except for Apple systems. Apple does relocations differently 25 | from everybody else, so since their OSes have been 64-bit for a longer while, 26 | I didn't go through the mental effort of porting the 32-bit code. 27 | 28 | In principle, similar code should be easy to inject into any well-behaved 29 | binary-only code (e.g., using DynamoRIO). Conditional jumps offer natural 30 | targets for instrumentation, and should offer comparable probe density. 31 | 32 | */ 33 | 34 | #ifndef _HAVE_AFL_AS_H 35 | #define _HAVE_AFL_AS_H 36 | 37 | #include "config.h" 38 | #include "types.h" 39 | 40 | /* 41 | ------------------ 42 | Performances notes 43 | ------------------ 44 | 45 | Contributions to make this code faster are appreciated! Here are some 46 | rough notes that may help with the task: 47 | 48 | - Only the trampoline_fmt and the non-setup __afl_maybe_log code paths are 49 | really worth optimizing; the setup / fork server stuff matters a lot less 50 | and should be mostly just kept readable. 51 | 52 | - We're aiming for modern CPUs with out-of-order execution and large 53 | pipelines; the code is mostly follows intuitive, human-readable 54 | instruction ordering, because "textbook" manual reorderings make no 55 | substantial difference. 56 | 57 | - Interestingly, instrumented execution isn't a lot faster if we store a 58 | variable pointer to the setup, log, or return routine and then do a reg 59 | call from within trampoline_fmt. It does speed up non-instrumented 60 | execution quite a bit, though, since that path just becomes 61 | push-call-ret-pop. 62 | 63 | - There is also not a whole lot to be gained by doing SHM attach at a 64 | fixed address instead of retrieving __afl_area_ptr. Although it allows us 65 | to have a shorter log routine inserted for conditional jumps and jump 66 | labels (for a ~10% perf gain), there is a risk of bumping into other 67 | allocations created by the program or by tools such as ASAN. 68 | 69 | - popf is *awfully* slow, which is why we're doing the lahf / sahf + 70 | overflow test trick. Unfortunately, this forces us to taint eax / rax, but 71 | this dependency on a commonly-used register still beats the alternative of 72 | using pushf / popf. 73 | 74 | One possible optimization is to avoid touching flags by using a circular 75 | buffer that stores just a sequence of current locations, with the XOR stuff 76 | happening offline. Alas, this doesn't seem to have a huge impact: 77 | 78 | https://groups.google.com/d/msg/afl-users/MsajVf4fRLo/2u6t88ntUBIJ 79 | 80 | - Preforking one child a bit sooner, and then waiting for the "go" command 81 | from within the child, doesn't offer major performance gains; fork() seems 82 | to be relatively inexpensive these days. Preforking multiple children does 83 | help, but badly breaks the "~1 core per fuzzer" design, making it harder to 84 | scale up. Maybe there is some middle ground. 85 | 86 | Perhaps of note: in the 64-bit version for all platforms except for Apple, 87 | the instrumentation is done slightly differently than on 32-bit, with 88 | __afl_prev_loc and __afl_area_ptr being local to the object file (.lcomm), 89 | rather than global (.comm). This is to avoid GOTRELPC lookups in the critical 90 | code path, which AFAICT, are otherwise unavoidable if we want gcc -shared to 91 | work; simple relocations between .bss and .text won't work on most 64-bit 92 | platforms in such a case. 93 | 94 | (Fun fact: on Apple systems, .lcomm can segfault the linker.) 95 | 96 | The side effect is that state transitions are measured in a somewhat 97 | different way, with previous tuple being recorded separately within the scope 98 | of every .c file. This should have no impact in any practical sense. 99 | 100 | Another side effect of this design is that getenv() will be called once per 101 | every .o file when running in non-instrumented mode; an since getenv() tends 102 | to be optimized in funny ways, we need to be very careful to save every 103 | oddball register it may touch. 104 | 105 | */ 106 | 107 | static const u8* trampoline_fmt_32 = 108 | 109 | "\n" 110 | "/* --- AFL TRAMPOLINE (32-BIT) --- */\n" 111 | "\n" 112 | ".align 4\n" 113 | "\n" 114 | "leal -16(%%esp), %%esp\n" 115 | "movl %%edi, 0(%%esp)\n" 116 | "movl %%edx, 4(%%esp)\n" 117 | "movl %%ecx, 8(%%esp)\n" 118 | "movl %%eax, 12(%%esp)\n" 119 | "movl $0x%08x, %%ecx\n" 120 | "call __afl_maybe_log\n" 121 | "movl 12(%%esp), %%eax\n" 122 | "movl 8(%%esp), %%ecx\n" 123 | "movl 4(%%esp), %%edx\n" 124 | "movl 0(%%esp), %%edi\n" 125 | "leal 16(%%esp), %%esp\n" 126 | "\n" 127 | "/* --- END --- */\n" 128 | "\n"; 129 | 130 | static const u8* trampoline_fmt_64 = 131 | 132 | "\n" 133 | "/* --- AFL TRAMPOLINE (64-BIT) --- */\n" 134 | "\n" 135 | ".align 4\n" 136 | "\n" 137 | "leaq -(128+24)(%%rsp), %%rsp\n" 138 | "movq %%rdx, 0(%%rsp)\n" 139 | "movq %%rcx, 8(%%rsp)\n" 140 | "movq %%rax, 16(%%rsp)\n" 141 | "movq $0x%08x, %%rcx\n" 142 | "call __afl_maybe_log\n" 143 | "movq 16(%%rsp), %%rax\n" 144 | "movq 8(%%rsp), %%rcx\n" 145 | "movq 0(%%rsp), %%rdx\n" 146 | "leaq (128+24)(%%rsp), %%rsp\n" 147 | "\n" 148 | "/* --- END --- */\n" 149 | "\n"; 150 | 151 | static const u8* main_payload_32 = 152 | 153 | "\n" 154 | "/* --- AFL MAIN PAYLOAD (32-BIT) --- */\n" 155 | "\n" 156 | ".text\n" 157 | ".att_syntax\n" 158 | ".code32\n" 159 | ".align 8\n" 160 | "\n" 161 | 162 | "__afl_maybe_log:\n" 163 | "\n" 164 | " lahf\n" 165 | " seto %al\n" 166 | "\n" 167 | " /* Check if SHM region is already mapped. */\n" 168 | "\n" 169 | " movl __afl_area_ptr, %edx\n" 170 | " testl %edx, %edx\n" 171 | " je __afl_setup\n" 172 | "\n" 173 | "__afl_store:\n" 174 | "\n" 175 | " /* Calculate and store hit for the code location specified in ecx. There\n" 176 | " is a double-XOR way of doing this without tainting another register,\n" 177 | " and we use it on 64-bit systems; but it's slower for 32-bit ones. */\n" 178 | "\n" 179 | #ifndef COVERAGE_ONLY 180 | " movl __afl_prev_loc, %edi\n" 181 | " xorl %ecx, %edi\n" 182 | " shrl $1, %ecx\n" 183 | " movl %ecx, __afl_prev_loc\n" 184 | #endif /* !COVERAGE_ONLY */ 185 | "\n" 186 | #ifdef SKIP_COUNTS 187 | " orb $1, (%edx, %edi, 1)\n" 188 | #else 189 | " incb (%edx, %edi, 1)\n" 190 | #endif /* ^SKIP_COUNTS */ 191 | "\n" 192 | "__afl_return:\n" 193 | "\n" 194 | " addb $127, %al\n" 195 | " sahf\n" 196 | " ret\n" 197 | "\n" 198 | ".align 8\n" 199 | "\n" 200 | "__afl_setup:\n" 201 | "\n" 202 | " /* Do not retry setup if we had previous failures. */\n" 203 | "\n" 204 | " cmpb $0, __afl_setup_failure\n" 205 | " jne __afl_return\n" 206 | "\n" 207 | " /* Map SHM, jumping to __afl_setup_abort if something goes wrong.\n" 208 | " We do not save FPU/MMX/SSE registers here, but hopefully, nobody\n" 209 | " will notice this early in the game. */\n" 210 | "\n" 211 | " pushl %eax\n" 212 | " pushl %ecx\n" 213 | "\n" 214 | " pushl $.AFL_SHM_ENV\n" 215 | " call getenv\n" 216 | " addl $4, %esp\n" 217 | "\n" 218 | " testl %eax, %eax\n" 219 | " je __afl_setup_abort\n" 220 | "\n" 221 | " pushl %eax\n" 222 | " call atoi\n" 223 | " addl $4, %esp\n" 224 | "\n" 225 | " pushl $0 /* shmat flags */\n" 226 | " pushl $0 /* requested addr */\n" 227 | " pushl %eax /* SHM ID */\n" 228 | " call shmat\n" 229 | " addl $12, %esp\n" 230 | "\n" 231 | " cmpl $-1, %eax\n" 232 | " je __afl_setup_abort\n" 233 | "\n" 234 | " /* Store the address of the SHM region. */\n" 235 | "\n" 236 | " movl %eax, __afl_area_ptr\n" 237 | " movl %eax, %edx\n" 238 | "\n" 239 | " popl %ecx\n" 240 | " popl %eax\n" 241 | "\n" 242 | "__afl_forkserver:\n" 243 | "\n" 244 | " /* Enter the fork server mode to avoid the overhead of execve() calls. */\n" 245 | "\n" 246 | " pushl %eax\n" 247 | " pushl %ecx\n" 248 | " pushl %edx\n" 249 | "\n" 250 | " /* Phone home and tell the parent that we're OK. (Note that signals with\n" 251 | " no SA_RESTART will mess it up). If this fails, assume that the fd is\n" 252 | " closed because we were execve()d from an instrumented binary, or because\n" 253 | " the parent doesn't want to use the fork server. */\n" 254 | "\n" 255 | " pushl $4 /* length */\n" 256 | " pushl $__afl_temp /* data */\n" 257 | " pushl $" STRINGIFY((FORKSRV_FD + 1)) " /* file desc */\n" 258 | " call write\n" 259 | " addl $12, %esp\n" 260 | "\n" 261 | " cmpl $4, %eax\n" 262 | " jne __afl_fork_resume\n" 263 | "\n" 264 | "__afl_fork_wait_loop:\n" 265 | "\n" 266 | " /* Wait for parent by reading from the pipe. Abort if read fails. */\n" 267 | "\n" 268 | " pushl $4 /* length */\n" 269 | " pushl $__afl_temp /* data */\n" 270 | " pushl $" STRINGIFY(FORKSRV_FD) " /* file desc */\n" 271 | " call read\n" 272 | " addl $12, %esp\n" 273 | "\n" 274 | " cmpl $4, %eax\n" 275 | " jne __afl_die\n" 276 | "\n" 277 | " /* Once woken up, create a clone of our process. This is an excellent use\n" 278 | " case for syscall(__NR_clone, 0, CLONE_PARENT), but glibc boneheadedly\n" 279 | " caches getpid() results and offers no way to update the value, breaking\n" 280 | " abort(), raise(), and a bunch of other things :-( */\n" 281 | "\n" 282 | " call fork\n" 283 | "\n" 284 | " cmpl $0, %eax\n" 285 | " jl __afl_die\n" 286 | " je __afl_fork_resume\n" 287 | "\n" 288 | " /* In parent process: write PID to pipe, then wait for child. */\n" 289 | "\n" 290 | " movl %eax, __afl_fork_pid\n" 291 | "\n" 292 | " pushl $4 /* length */\n" 293 | " pushl $__afl_fork_pid /* data */\n" 294 | " pushl $" STRINGIFY((FORKSRV_FD + 1)) " /* file desc */\n" 295 | " call write\n" 296 | " addl $12, %esp\n" 297 | "\n" 298 | " pushl $2 /* WUNTRACED */\n" 299 | " pushl $__afl_temp /* status */\n" 300 | " pushl __afl_fork_pid /* PID */\n" 301 | " call waitpid\n" 302 | " addl $12, %esp\n" 303 | "\n" 304 | " cmpl $0, %eax\n" 305 | " jle __afl_die\n" 306 | "\n" 307 | " /* Relay wait status to pipe, then loop back. */\n" 308 | "\n" 309 | " pushl $4 /* length */\n" 310 | " pushl $__afl_temp /* data */\n" 311 | " pushl $" STRINGIFY((FORKSRV_FD + 1)) " /* file desc */\n" 312 | " call write\n" 313 | " addl $12, %esp\n" 314 | "\n" 315 | " jmp __afl_fork_wait_loop\n" 316 | "\n" 317 | "__afl_fork_resume:\n" 318 | "\n" 319 | " /* In child process: close fds, resume execution. */\n" 320 | "\n" 321 | " pushl $" STRINGIFY(FORKSRV_FD) "\n" 322 | " call close\n" 323 | "\n" 324 | " pushl $" STRINGIFY((FORKSRV_FD + 1)) "\n" 325 | " call close\n" 326 | "\n" 327 | " addl $8, %esp\n" 328 | "\n" 329 | " popl %edx\n" 330 | " popl %ecx\n" 331 | " popl %eax\n" 332 | " jmp __afl_store\n" 333 | "\n" 334 | "__afl_die:\n" 335 | "\n" 336 | " xorl %eax, %eax\n" 337 | " call exit\n" 338 | "\n" 339 | "__afl_setup_abort:\n" 340 | "\n" 341 | " /* Record setup failure so that we don't keep calling\n" 342 | " shmget() / shmat() over and over again. */\n" 343 | "\n" 344 | " incb __afl_setup_failure\n" 345 | " popl %ecx\n" 346 | " popl %eax\n" 347 | " jmp __afl_return\n" 348 | "\n" 349 | ".AFL_VARS:\n" 350 | "\n" 351 | " .comm __afl_area_ptr, 4, 32\n" 352 | " .comm __afl_setup_failure, 1, 32\n" 353 | #ifndef COVERAGE_ONLY 354 | " .comm __afl_prev_loc, 4, 32\n" 355 | #endif /* !COVERAGE_ONLY */ 356 | " .comm __afl_fork_pid, 4, 32\n" 357 | " .comm __afl_temp, 4, 32\n" 358 | "\n" 359 | ".AFL_SHM_ENV:\n" 360 | " .asciz \"" SHM_ENV_VAR "\"\n" 361 | "\n" 362 | "/* --- END --- */\n" 363 | "\n"; 364 | 365 | /* The OpenBSD hack is due to lahf and sahf not being recognized by some 366 | versions of binutils: http://marc.info/?l=openbsd-cvs&m=141636589924400 367 | 368 | The Apple code is a bit different when calling libc functions because 369 | they are doing relocations differently from everybody else. We also need 370 | to work around the crash issue with .lcomm and the fact that they don't 371 | recognize .string. */ 372 | 373 | #ifdef __APPLE__ 374 | # define CALL_L64(str) "call _" str "\n" 375 | #else 376 | # define CALL_L64(str) "call " str "@PLT\n" 377 | #endif /* ^__APPLE__ */ 378 | 379 | static const u8* main_payload_64 = 380 | 381 | "\n" 382 | "/* --- AFL MAIN PAYLOAD (64-BIT) --- */\n" 383 | "\n" 384 | ".text\n" 385 | ".att_syntax\n" 386 | ".code64\n" 387 | ".align 8\n" 388 | "\n" 389 | "__afl_maybe_log:\n" 390 | "\n" 391 | #ifdef __OpenBSD__ 392 | " .byte 0x9f /* lahf */\n" 393 | #else 394 | " lahf\n" 395 | #endif /* ^__OpenBSD__ */ 396 | " seto %al\n" 397 | "\n" 398 | " /* Check if SHM region is already mapped. */\n" 399 | "\n" 400 | " movq __afl_area_ptr(%rip), %rdx\n" 401 | " testq %rdx, %rdx\n" 402 | " je __afl_setup\n" 403 | "\n" 404 | "__afl_store:\n" 405 | "\n" 406 | " /* Calculate and store hit for the code location specified in rcx. */\n" 407 | "\n" 408 | #ifndef COVERAGE_ONLY 409 | " xorq __afl_prev_loc(%rip), %rcx\n" 410 | " xorq %rcx, __afl_prev_loc(%rip)\n" 411 | " shrq $1, __afl_prev_loc(%rip)\n" 412 | #endif /* ^!COVERAGE_ONLY */ 413 | "\n" 414 | #ifdef SKIP_COUNTS 415 | " orb $1, (%rdx, %rcx, 1)\n" 416 | #else 417 | " incb (%rdx, %rcx, 1)\n" 418 | #endif /* ^SKIP_COUNTS */ 419 | "\n" 420 | "__afl_return:\n" 421 | "\n" 422 | " addb $127, %al\n" 423 | #ifdef __OpenBSD__ 424 | " .byte 0x9e /* sahf */\n" 425 | #else 426 | " sahf\n" 427 | #endif /* ^__OpenBSD__ */ 428 | " ret\n" 429 | "\n" 430 | ".align 8\n" 431 | "\n" 432 | "__afl_setup:\n" 433 | "\n" 434 | " /* Do not retry setup if we had previous failures. */\n" 435 | "\n" 436 | " cmpb $0, __afl_setup_failure(%rip)\n" 437 | " jne __afl_return\n" 438 | "\n" 439 | " /* Check out if we have a global pointer on file. */\n" 440 | "\n" 441 | #ifndef __APPLE__ 442 | " movq __afl_global_area_ptr@GOTPCREL(%rip), %rdx\n" 443 | " movq (%rdx), %rdx\n" 444 | #else 445 | " movq __afl_global_area_ptr(%rip), %rdx\n" 446 | #endif /* !^__APPLE__ */ 447 | " testq %rdx, %rdx\n" 448 | " je __afl_setup_first\n" 449 | "\n" 450 | " movq %rdx, __afl_area_ptr(%rip)\n" 451 | " jmp __afl_store\n" 452 | "\n" 453 | "__afl_setup_first:\n" 454 | "\n" 455 | " /* Save everything that is not yet saved and that may be touched by\n" 456 | " getenv() and several other libcalls we'll be relying on. */\n" 457 | "\n" 458 | " leaq -352(%rsp), %rsp\n" 459 | "\n" 460 | " movq %rax, 0(%rsp)\n" 461 | " movq %rcx, 8(%rsp)\n" 462 | " movq %rdi, 16(%rsp)\n" 463 | " movq %rsi, 32(%rsp)\n" 464 | " movq %r8, 40(%rsp)\n" 465 | " movq %r9, 48(%rsp)\n" 466 | " movq %r10, 56(%rsp)\n" 467 | " movq %r11, 64(%rsp)\n" 468 | "\n" 469 | " movq %xmm0, 96(%rsp)\n" 470 | " movq %xmm1, 112(%rsp)\n" 471 | " movq %xmm2, 128(%rsp)\n" 472 | " movq %xmm3, 144(%rsp)\n" 473 | " movq %xmm4, 160(%rsp)\n" 474 | " movq %xmm5, 176(%rsp)\n" 475 | " movq %xmm6, 192(%rsp)\n" 476 | " movq %xmm7, 208(%rsp)\n" 477 | " movq %xmm8, 224(%rsp)\n" 478 | " movq %xmm9, 240(%rsp)\n" 479 | " movq %xmm10, 256(%rsp)\n" 480 | " movq %xmm11, 272(%rsp)\n" 481 | " movq %xmm12, 288(%rsp)\n" 482 | " movq %xmm13, 304(%rsp)\n" 483 | " movq %xmm14, 320(%rsp)\n" 484 | " movq %xmm15, 336(%rsp)\n" 485 | "\n" 486 | " /* Map SHM, jumping to __afl_setup_abort if something goes wrong. */\n" 487 | "\n" 488 | " /* The 64-bit ABI requires 16-byte stack alignment. We'll keep the\n" 489 | " original stack ptr in the callee-saved r12. */\n" 490 | "\n" 491 | " pushq %r12\n" 492 | " movq %rsp, %r12\n" 493 | " subq $16, %rsp\n" 494 | " andq $0xfffffffffffffff0, %rsp\n" 495 | "\n" 496 | " leaq .AFL_SHM_ENV(%rip), %rdi\n" 497 | CALL_L64("getenv") 498 | "\n" 499 | " testq %rax, %rax\n" 500 | " je __afl_setup_abort\n" 501 | "\n" 502 | " movq %rax, %rdi\n" 503 | CALL_L64("atoi") 504 | "\n" 505 | " xorq %rdx, %rdx /* shmat flags */\n" 506 | " xorq %rsi, %rsi /* requested addr */\n" 507 | " movq %rax, %rdi /* SHM ID */\n" 508 | CALL_L64("shmat") 509 | "\n" 510 | " cmpq $-1, %rax\n" 511 | " je __afl_setup_abort\n" 512 | "\n" 513 | " /* Store the address of the SHM region. */\n" 514 | "\n" 515 | " movq %rax, %rdx\n" 516 | " movq %rax, __afl_area_ptr(%rip)\n" 517 | "\n" 518 | #ifdef __APPLE__ 519 | " movq %rax, __afl_global_area_ptr(%rip)\n" 520 | #else 521 | " movq __afl_global_area_ptr@GOTPCREL(%rip), %rdx\n" 522 | " movq %rax, (%rdx)\n" 523 | #endif /* ^__APPLE__ */ 524 | " movq %rax, %rdx\n" 525 | "\n" 526 | "__afl_forkserver:\n" 527 | "\n" 528 | " /* Enter the fork server mode to avoid the overhead of execve() calls. We\n" 529 | " push rdx (area ptr) twice to keep stack alignment neat. */\n" 530 | "\n" 531 | " pushq %rdx\n" 532 | " pushq %rdx\n" 533 | "\n" 534 | " /* Phone home and tell the parent that we're OK. (Note that signals with\n" 535 | " no SA_RESTART will mess it up). If this fails, assume that the fd is\n" 536 | " closed because we were execve()d from an instrumented binary, or because\n" 537 | " the parent doesn't want to use the fork server. */\n" 538 | "\n" 539 | " movq $4, %rdx /* length */\n" 540 | " leaq __afl_temp(%rip), %rsi /* data */\n" 541 | " movq $" STRINGIFY((FORKSRV_FD + 1)) ", %rdi /* file desc */\n" 542 | CALL_L64("write") 543 | "\n" 544 | " cmpq $4, %rax\n" 545 | " jne __afl_fork_resume\n" 546 | "\n" 547 | "__afl_fork_wait_loop:\n" 548 | "\n" 549 | " /* Wait for parent by reading from the pipe. Abort if read fails. */\n" 550 | "\n" 551 | " movq $4, %rdx /* length */\n" 552 | " leaq __afl_temp(%rip), %rsi /* data */\n" 553 | " movq $" STRINGIFY(FORKSRV_FD) ", %rdi /* file desc */\n" 554 | CALL_L64("read") 555 | " cmpq $4, %rax\n" 556 | " jne __afl_die\n" 557 | "\n" 558 | " /* Once woken up, create a clone of our process. This is an excellent use\n" 559 | " case for syscall(__NR_clone, 0, CLONE_PARENT), but glibc boneheadedly\n" 560 | " caches getpid() results and offers no way to update the value, breaking\n" 561 | " abort(), raise(), and a bunch of other things :-( */\n" 562 | "\n" 563 | CALL_L64("fork") 564 | " cmpq $0, %rax\n" 565 | " jl __afl_die\n" 566 | " je __afl_fork_resume\n" 567 | "\n" 568 | " /* In parent process: write PID to pipe, then wait for child. */\n" 569 | "\n" 570 | " movl %eax, __afl_fork_pid(%rip)\n" 571 | "\n" 572 | " movq $4, %rdx /* length */\n" 573 | " leaq __afl_fork_pid(%rip), %rsi /* data */\n" 574 | " movq $" STRINGIFY((FORKSRV_FD + 1)) ", %rdi /* file desc */\n" 575 | CALL_L64("write") 576 | "\n" 577 | " movq $2, %rdx /* WUNTRACED */\n" 578 | " leaq __afl_temp(%rip), %rsi /* status */\n" 579 | " movq __afl_fork_pid(%rip), %rdi /* PID */\n" 580 | CALL_L64("waitpid") 581 | " cmpq $0, %rax\n" 582 | " jle __afl_die\n" 583 | "\n" 584 | " /* Relay wait status to pipe, then loop back. */\n" 585 | "\n" 586 | " movq $4, %rdx /* length */\n" 587 | " leaq __afl_temp(%rip), %rsi /* data */\n" 588 | " movq $" STRINGIFY((FORKSRV_FD + 1)) ", %rdi /* file desc */\n" 589 | CALL_L64("write") 590 | "\n" 591 | " jmp __afl_fork_wait_loop\n" 592 | "\n" 593 | "__afl_fork_resume:\n" 594 | "\n" 595 | " /* In child process: close fds, resume execution. */\n" 596 | "\n" 597 | " movq $" STRINGIFY(FORKSRV_FD) ", %rdi\n" 598 | CALL_L64("close") 599 | "\n" 600 | " movq $" STRINGIFY((FORKSRV_FD + 1)) ", %rdi\n" 601 | CALL_L64("close") 602 | "\n" 603 | " popq %rdx\n" 604 | " popq %rdx\n" 605 | "\n" 606 | " movq %r12, %rsp\n" 607 | " popq %r12\n" 608 | "\n" 609 | " movq 0(%rsp), %rax\n" 610 | " movq 8(%rsp), %rcx\n" 611 | " movq 16(%rsp), %rdi\n" 612 | " movq 32(%rsp), %rsi\n" 613 | " movq 40(%rsp), %r8\n" 614 | " movq 48(%rsp), %r9\n" 615 | " movq 56(%rsp), %r10\n" 616 | " movq 64(%rsp), %r11\n" 617 | "\n" 618 | " movq 96(%rsp), %xmm0\n" 619 | " movq 112(%rsp), %xmm1\n" 620 | " movq 128(%rsp), %xmm2\n" 621 | " movq 144(%rsp), %xmm3\n" 622 | " movq 160(%rsp), %xmm4\n" 623 | " movq 176(%rsp), %xmm5\n" 624 | " movq 192(%rsp), %xmm6\n" 625 | " movq 208(%rsp), %xmm7\n" 626 | " movq 224(%rsp), %xmm8\n" 627 | " movq 240(%rsp), %xmm9\n" 628 | " movq 256(%rsp), %xmm10\n" 629 | " movq 272(%rsp), %xmm11\n" 630 | " movq 288(%rsp), %xmm12\n" 631 | " movq 304(%rsp), %xmm13\n" 632 | " movq 320(%rsp), %xmm14\n" 633 | " movq 336(%rsp), %xmm15\n" 634 | "\n" 635 | " leaq 352(%rsp), %rsp\n" 636 | "\n" 637 | " jmp __afl_store\n" 638 | "\n" 639 | "__afl_die:\n" 640 | "\n" 641 | " xorq %rax, %rax\n" 642 | CALL_L64("exit") 643 | "\n" 644 | "__afl_setup_abort:\n" 645 | "\n" 646 | " /* Record setup failure so that we don't keep calling\n" 647 | " shmget() / shmat() over and over again. */\n" 648 | "\n" 649 | " incb __afl_setup_failure(%rip)\n" 650 | "\n" 651 | " movq %r12, %rsp\n" 652 | " popq %r12\n" 653 | "\n" 654 | " movq 0(%rsp), %rax\n" 655 | " movq 8(%rsp), %rcx\n" 656 | " movq 16(%rsp), %rdi\n" 657 | " movq 32(%rsp), %rsi\n" 658 | " movq 40(%rsp), %r8\n" 659 | " movq 48(%rsp), %r9\n" 660 | " movq 56(%rsp), %r10\n" 661 | " movq 64(%rsp), %r11\n" 662 | "\n" 663 | " movq 96(%rsp), %xmm0\n" 664 | " movq 112(%rsp), %xmm1\n" 665 | " movq 128(%rsp), %xmm2\n" 666 | " movq 144(%rsp), %xmm3\n" 667 | " movq 160(%rsp), %xmm4\n" 668 | " movq 176(%rsp), %xmm5\n" 669 | " movq 192(%rsp), %xmm6\n" 670 | " movq 208(%rsp), %xmm7\n" 671 | " movq 224(%rsp), %xmm8\n" 672 | " movq 240(%rsp), %xmm9\n" 673 | " movq 256(%rsp), %xmm10\n" 674 | " movq 272(%rsp), %xmm11\n" 675 | " movq 288(%rsp), %xmm12\n" 676 | " movq 304(%rsp), %xmm13\n" 677 | " movq 320(%rsp), %xmm14\n" 678 | " movq 336(%rsp), %xmm15\n" 679 | "\n" 680 | " leaq 352(%rsp), %rsp\n" 681 | "\n" 682 | " jmp __afl_return\n" 683 | "\n" 684 | ".AFL_VARS:\n" 685 | "\n" 686 | 687 | #ifdef __APPLE__ 688 | 689 | " .comm __afl_area_ptr, 8\n" 690 | #ifndef COVERAGE_ONLY 691 | " .comm __afl_prev_loc, 8\n" 692 | #endif /* !COVERAGE_ONLY */ 693 | " .comm __afl_fork_pid, 4\n" 694 | " .comm __afl_temp, 4\n" 695 | " .comm __afl_setup_failure, 1\n" 696 | 697 | #else 698 | 699 | " .lcomm __afl_area_ptr, 8\n" 700 | #ifndef COVERAGE_ONLY 701 | " .lcomm __afl_prev_loc, 8\n" 702 | #endif /* !COVERAGE_ONLY */ 703 | " .lcomm __afl_fork_pid, 4\n" 704 | " .lcomm __afl_temp, 4\n" 705 | " .lcomm __afl_setup_failure, 1\n" 706 | 707 | #endif /* ^__APPLE__ */ 708 | 709 | " .comm __afl_global_area_ptr, 8, 8\n" 710 | "\n" 711 | ".AFL_SHM_ENV:\n" 712 | " .asciz \"" SHM_ENV_VAR "\"\n" 713 | "\n" 714 | "/* --- END --- */\n" 715 | "\n"; 716 | 717 | #endif /* !_HAVE_AFL_AS_H */ 718 | -------------------------------------------------------------------------------- /afl-instr/afl-llvm-pass.so.cc: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop - LLVM-mode instrumentation pass 3 | --------------------------------------------------- 4 | 5 | Written by Laszlo Szekeres and 6 | Michal Zalewski 7 | 8 | LLVM integration design comes from Laszlo Szekeres. C bits copied-and-pasted 9 | from afl-as.c are Michal's fault. 10 | 11 | Copyright 2015 Google Inc. All rights reserved. 12 | 13 | Licensed under the Apache License, Version 2.0 (the "License"); 14 | you may not use this file except in compliance with the License. 15 | You may obtain a copy of the License at: 16 | 17 | http://www.apache.org/licenses/LICENSE-2.0 18 | 19 | This library is plugged into LLVM when invoking clang through afl-clang-fast. 20 | It tells the compiler to add code roughly equivalent to the bits discussed 21 | in ../afl-as.h. 22 | 23 | */ 24 | 25 | // CHANGES (bn) 26 | // Don't use SAYF macro, doesn't compile with clang 27 | // Change imports to config / debug to . from .. 28 | // Add debugging printf to registerAFLPass 29 | // Add module loaded printf 30 | 31 | #include "config.h" 32 | #include "debug.h" 33 | 34 | #include 35 | #include 36 | #include 37 | 38 | #include "llvm/ADT/Statistic.h" 39 | #include "llvm/IR/IRBuilder.h" 40 | #include "llvm/IR/LegacyPassManager.h" 41 | #include "llvm/IR/Module.h" 42 | #include "llvm/Support/Debug.h" 43 | #include "llvm/Transforms/IPO/PassManagerBuilder.h" 44 | 45 | using namespace llvm; 46 | 47 | //#define DEBUG_TYPE "afl" 48 | 49 | namespace 50 | { 51 | 52 | class AFLCoverage : public ModulePass 53 | { 54 | 55 | public: 56 | 57 | static char ID; 58 | AFLCoverage() : ModulePass(ID) { } 59 | 60 | bool runOnModule(Module &M) override; 61 | 62 | const char* getPassName() const override 63 | { 64 | return "American Fuzzy Lop Instrumentation"; 65 | } 66 | 67 | }; 68 | 69 | } 70 | 71 | 72 | char AFLCoverage::ID = 0; 73 | 74 | 75 | bool AFLCoverage::runOnModule(Module &M) 76 | { 77 | 78 | LLVMContext &C = M.getContext(); 79 | 80 | IntegerType* Int8Ty = IntegerType::getInt8Ty(C); 81 | IntegerType* Int16Ty = IntegerType::getInt16Ty(C); 82 | IntegerType* Int64Ty = IntegerType::getInt64Ty(C); 83 | 84 | /* Show a banner */ 85 | 86 | char be_quiet = 0; 87 | 88 | if (isatty(2) && !getenv("AFL_QUIET")) { 89 | 90 | //SAYF(cCYA "afl-llvm-pass " cBRI VERSION cRST " by \n"); 91 | 92 | } else { be_quiet = 1; } 93 | 94 | /* Decide instrumentation ratio */ 95 | 96 | char* inst_ratio_str = getenv("AFL_INST_RATIO"); 97 | int inst_ratio = 100; 98 | 99 | if (inst_ratio_str) { 100 | 101 | if (sscanf(inst_ratio_str, "%u", &inst_ratio) != 1 || !inst_ratio || 102 | inst_ratio > 100) 103 | { FATAL("Bad value of AFL_INST_RATIO (must be between 1 and 100)"); } 104 | 105 | } 106 | 107 | /* Get globals for the SHM region and the previous location. */ 108 | 109 | GlobalVariable* AFLMapPtr = 110 | new GlobalVariable(M, PointerType::get(Int8Ty, 0), false, 111 | GlobalValue::ExternalLinkage, 0, "__afl_area_ptr"); 112 | 113 | GlobalVariable* AFLPrevLoc = new GlobalVariable( 114 | M, Int16Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_loc"); 115 | 116 | /* Instrument all the things! */ 117 | 118 | int inst_blocks = 0; 119 | 120 | for (auto &F : M) 121 | for (auto &BB : F) { 122 | 123 | BasicBlock::iterator IP = BB.getFirstInsertionPt(); 124 | IRBuilder<> IRB(IP); 125 | 126 | if (R(100) >= inst_ratio) { continue; } 127 | 128 | /* Make up cur_loc */ 129 | 130 | unsigned int cur_loc = R(MAP_SIZE); 131 | ConstantInt* CurLoc = ConstantInt::get(Int64Ty, cur_loc); 132 | 133 | /* Load prev_loc */ 134 | 135 | LoadInst* PrevLoc = IRB.CreateLoad(AFLPrevLoc); 136 | PrevLoc->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); 137 | Value* PrevLocCasted = IRB.CreateZExt(PrevLoc, IRB.getInt64Ty()); 138 | 139 | /* Load SHM pointer */ 140 | 141 | LoadInst* MapPtr = IRB.CreateLoad(AFLMapPtr); 142 | MapPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); 143 | Value* MapPtrIdx = 144 | IRB.CreateGEP(MapPtr, IRB.CreateXor(PrevLocCasted, CurLoc)); 145 | 146 | /* Update bitmap */ 147 | 148 | LoadInst* Counter = IRB.CreateLoad(MapPtrIdx); 149 | Counter->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); 150 | Value* Incr = IRB.CreateAdd(Counter, ConstantInt::get(Int8Ty, 1)); 151 | IRB.CreateStore(Incr, MapPtrIdx) 152 | ->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); 153 | 154 | /* Set prev_loc to cur_loc >> 1 */ 155 | 156 | StoreInst* Store = 157 | IRB.CreateStore(ConstantInt::get(Int16Ty, cur_loc >> 1), AFLPrevLoc); 158 | Store->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); 159 | 160 | inst_blocks++; 161 | 162 | } 163 | 164 | /* Say something nice. */ 165 | 166 | if (!be_quiet) { 167 | 168 | if (!inst_blocks) { WARNF("No instrumentation targets found."); } 169 | else OKF("Instrumented %u locations (%s mode, ratio %u%%).", 170 | inst_blocks, 171 | getenv("AFL_HARDEN") ? "hardened" : "non-hardened", 172 | inst_ratio); 173 | 174 | } 175 | 176 | return true; 177 | 178 | } 179 | 180 | 181 | static void registerAFLPass(const PassManagerBuilder &, 182 | legacy::PassManagerBase &PM) 183 | { 184 | printf("Trying to register pass...\n"); 185 | PM.add(new AFLCoverage()); 186 | printf("pass is registered!\n"); 187 | 188 | } 189 | 190 | 191 | static RegisterStandardPasses RegisterAFLPass( 192 | PassManagerBuilder::EP_OptimizerLast, registerAFLPass); 193 | 194 | static struct X { 195 | X() { printf("library is loaded.\n"); } 196 | } X; 197 | -------------------------------------------------------------------------------- /afl-instr/alloc-inl.h: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop - error-checking, memory-zeroing alloc routines 3 | ------------------------------------------------------------------ 4 | 5 | Written and maintained by Michal Zalewski 6 | 7 | Copyright 2013, 2014, 2015 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 allocator is not designed to resist malicious attackers (the canaries 16 | are small and predictable), but provides a robust and portable way to detect 17 | use-after-free, off-by-one writes, stale pointers, and so on. 18 | 19 | */ 20 | 21 | #ifndef _HAVE_ALLOC_INL_H 22 | #define _HAVE_ALLOC_INL_H 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include "config.h" 29 | #include "types.h" 30 | #include "debug.h" 31 | 32 | /* User-facing macro to sprintf() to a dynamically allocated buffer. */ 33 | 34 | #define alloc_printf(_str...) ({ \ 35 | u8* _tmp; \ 36 | s32 _len = snprintf(NULL, 0, _str); \ 37 | if (_len < 0) FATAL("Whoa, snprintf() fails?!"); \ 38 | _tmp = ck_alloc(_len + 1); \ 39 | snprintf((char*)_tmp, _len + 1, _str); \ 40 | _tmp; \ 41 | }) 42 | 43 | /* Macro to enforce allocation limits as a last-resort defense against 44 | integer overflows. */ 45 | 46 | #define ALLOC_CHECK_SIZE(_s) do { \ 47 | if ((_s) > MAX_ALLOC) \ 48 | ABORT("Bad alloc request: %u bytes", (_s)); \ 49 | } while (0) 50 | 51 | /* Macro to check malloc() failures and the like. */ 52 | 53 | #define ALLOC_CHECK_RESULT(_r, _s) do { \ 54 | if (!(_r)) \ 55 | ABORT("Out of memory: can't allocate %u bytes", (_s)); \ 56 | } while (0) 57 | 58 | /* Magic tokens used to mark used / freed chunks. */ 59 | 60 | #define ALLOC_MAGIC_C1 0xFF00 61 | #define ALLOC_MAGIC_F 0xFE00 62 | #define ALLOC_MAGIC_C2 0xF0 63 | 64 | /* Positions of guard tokens in relation to the user-visible pointer. */ 65 | 66 | #define ALLOC_C1(_ptr) (((u16*)(_ptr))[-3]) 67 | #define ALLOC_S(_ptr) (((u32*)(_ptr))[-1]) 68 | #define ALLOC_C2(_ptr) (((u8*)(_ptr))[ALLOC_S(_ptr)]) 69 | 70 | #define ALLOC_OFF_HEAD 6 71 | #define ALLOC_OFF_TOTAL (ALLOC_OFF_HEAD + 1) 72 | 73 | /* Allocator increments for ck_realloc_block(). */ 74 | 75 | #define ALLOC_BLK_INC 256 76 | 77 | /* Sanity-checking macros for pointers. */ 78 | 79 | #define CHECK_PTR(_p) do { \ 80 | if (_p) { \ 81 | if (ALLOC_C1(_p) ^ ALLOC_MAGIC_C1) {\ 82 | if (ALLOC_C1(_p) == ALLOC_MAGIC_F) \ 83 | ABORT("Use after free."); \ 84 | else ABORT("Corrupted head alloc canary."); \ 85 | } \ 86 | if (ALLOC_C2(_p) ^ ALLOC_MAGIC_C2) \ 87 | ABORT("Corrupted tail alloc canary."); \ 88 | } \ 89 | } while (0) 90 | 91 | #define CHECK_PTR_EXPR(_p) ({ \ 92 | typeof (_p) _tmp = (_p); \ 93 | CHECK_PTR(_tmp); \ 94 | _tmp; \ 95 | }) 96 | 97 | 98 | /* Allocate a buffer, explicitly not zeroing it. Returns NULL for zero-sized 99 | requests. */ 100 | 101 | static inline void* DFL_ck_alloc_nozero(u32 size) { 102 | 103 | void* ret; 104 | 105 | if (!size) return NULL; 106 | 107 | ALLOC_CHECK_SIZE(size); 108 | ret = malloc(size + ALLOC_OFF_TOTAL); 109 | ALLOC_CHECK_RESULT(ret, size); 110 | 111 | ret += ALLOC_OFF_HEAD; 112 | 113 | ALLOC_C1(ret) = ALLOC_MAGIC_C1; 114 | ALLOC_S(ret) = size; 115 | ALLOC_C2(ret) = ALLOC_MAGIC_C2; 116 | 117 | return ret; 118 | 119 | } 120 | 121 | 122 | /* Allocate a buffer, returning zeroed memory. */ 123 | 124 | static inline void* DFL_ck_alloc(u32 size) { 125 | 126 | void* mem; 127 | 128 | if (!size) return NULL; 129 | mem = DFL_ck_alloc_nozero(size); 130 | 131 | return memset(mem, 0, size); 132 | 133 | } 134 | 135 | 136 | /* Free memory, checking for double free and corrupted heap. When DEBUG_BUILD 137 | is set, the old memory will be also clobbered with 0xFF. */ 138 | 139 | static inline void DFL_ck_free(void* mem) { 140 | 141 | if (!mem) return; 142 | 143 | CHECK_PTR(mem); 144 | 145 | #ifdef DEBUG_BUILD 146 | 147 | /* Catch pointer issues sooner. */ 148 | memset(mem, 0xFF, ALLOC_S(mem)); 149 | 150 | #endif /* DEBUG_BUILD */ 151 | 152 | ALLOC_C1(mem) = ALLOC_MAGIC_F; 153 | 154 | free(mem - ALLOC_OFF_HEAD); 155 | 156 | } 157 | 158 | 159 | /* Re-allocate a buffer, checking for issues and zeroing any newly-added tail. 160 | With DEBUG_BUILD, the buffer is always reallocated to a new addresses and the 161 | old memory is clobbered with 0xFF. */ 162 | 163 | static inline void* DFL_ck_realloc(void* orig, u32 size) { 164 | 165 | void* ret; 166 | u32 old_size = 0; 167 | 168 | if (!size) { 169 | 170 | DFL_ck_free(orig); 171 | return NULL; 172 | 173 | } 174 | 175 | if (orig) { 176 | 177 | CHECK_PTR(orig); 178 | 179 | #ifndef DEBUG_BUILD 180 | ALLOC_C1(orig) = ALLOC_MAGIC_F; 181 | #endif /* !DEBUG_BUILD */ 182 | 183 | old_size = ALLOC_S(orig); 184 | orig -= ALLOC_OFF_HEAD; 185 | 186 | ALLOC_CHECK_SIZE(old_size); 187 | 188 | } 189 | 190 | ALLOC_CHECK_SIZE(size); 191 | 192 | #ifndef DEBUG_BUILD 193 | 194 | ret = realloc(orig, size + ALLOC_OFF_TOTAL); 195 | ALLOC_CHECK_RESULT(ret, size); 196 | 197 | #else 198 | 199 | /* Catch pointer issues sooner: force relocation and make sure that the 200 | original buffer is wiped. */ 201 | 202 | ret = malloc(size + ALLOC_OFF_TOTAL); 203 | ALLOC_CHECK_RESULT(ret, size); 204 | 205 | if (orig) { 206 | 207 | memcpy(ret + ALLOC_OFF_HEAD, orig + ALLOC_OFF_HEAD, MIN(size, old_size)); 208 | memset(orig + ALLOC_OFF_HEAD, 0xFF, old_size); 209 | 210 | ALLOC_C1(orig + ALLOC_OFF_HEAD) = ALLOC_MAGIC_F; 211 | 212 | free(orig); 213 | 214 | } 215 | 216 | #endif /* ^!DEBUG_BUILD */ 217 | 218 | ret += ALLOC_OFF_HEAD; 219 | 220 | ALLOC_C1(ret) = ALLOC_MAGIC_C1; 221 | ALLOC_S(ret) = size; 222 | ALLOC_C2(ret) = ALLOC_MAGIC_C2; 223 | 224 | if (size > old_size) 225 | memset(ret + old_size, 0, size - old_size); 226 | 227 | return ret; 228 | 229 | } 230 | 231 | 232 | /* Re-allocate a buffer with ALLOC_BLK_INC increments (used to speed up 233 | repeated small reallocs without complicating the user code). */ 234 | 235 | static inline void* DFL_ck_realloc_block(void* orig, u32 size) { 236 | 237 | #ifndef DEBUG_BUILD 238 | 239 | if (orig) { 240 | 241 | CHECK_PTR(orig); 242 | 243 | if (ALLOC_S(orig) >= size) return orig; 244 | 245 | size += ALLOC_BLK_INC; 246 | 247 | } 248 | 249 | #endif /* !DEBUG_BUILD */ 250 | 251 | return DFL_ck_realloc(orig, size); 252 | 253 | } 254 | 255 | 256 | /* Create a buffer with a copy of a string. Returns NULL for NULL inputs. */ 257 | 258 | static inline u8* DFL_ck_strdup(u8* str) { 259 | 260 | void* ret; 261 | u32 size; 262 | 263 | if (!str) return NULL; 264 | 265 | size = strlen((char*)str) + 1; 266 | 267 | ALLOC_CHECK_SIZE(size); 268 | ret = malloc(size + ALLOC_OFF_TOTAL); 269 | ALLOC_CHECK_RESULT(ret, size); 270 | 271 | ret += ALLOC_OFF_HEAD; 272 | 273 | ALLOC_C1(ret) = ALLOC_MAGIC_C1; 274 | ALLOC_S(ret) = size; 275 | ALLOC_C2(ret) = ALLOC_MAGIC_C2; 276 | 277 | return memcpy(ret, str, size); 278 | 279 | } 280 | 281 | 282 | /* Create a buffer with a copy of a memory block. Returns NULL for zero-sized 283 | or NULL inputs. */ 284 | 285 | static inline void* DFL_ck_memdup(void* mem, u32 size) { 286 | 287 | void* ret; 288 | 289 | if (!mem || !size) return NULL; 290 | 291 | ALLOC_CHECK_SIZE(size); 292 | ret = malloc(size + ALLOC_OFF_TOTAL); 293 | ALLOC_CHECK_RESULT(ret, size); 294 | 295 | ret += ALLOC_OFF_HEAD; 296 | 297 | ALLOC_C1(ret) = ALLOC_MAGIC_C1; 298 | ALLOC_S(ret) = size; 299 | ALLOC_C2(ret) = ALLOC_MAGIC_C2; 300 | 301 | return memcpy(ret, mem, size); 302 | 303 | } 304 | 305 | 306 | /* Create a buffer with a block of text, appending a NUL terminator at the end. 307 | Returns NULL for zero-sized or NULL inputs. */ 308 | 309 | static inline u8* DFL_ck_memdup_str(u8* mem, u32 size) { 310 | 311 | u8* ret; 312 | 313 | if (!mem || !size) return NULL; 314 | 315 | ALLOC_CHECK_SIZE(size); 316 | ret = malloc(size + ALLOC_OFF_TOTAL + 1); 317 | ALLOC_CHECK_RESULT(ret, size); 318 | 319 | ret += ALLOC_OFF_HEAD; 320 | 321 | ALLOC_C1(ret) = ALLOC_MAGIC_C1; 322 | ALLOC_S(ret) = size; 323 | ALLOC_C2(ret) = ALLOC_MAGIC_C2; 324 | 325 | memcpy(ret, mem, size); 326 | ret[size] = 0; 327 | 328 | return ret; 329 | 330 | } 331 | 332 | 333 | #ifndef DEBUG_BUILD 334 | 335 | /* In non-debug mode, we just do straightforward aliasing of the above functions 336 | to user-visible names such as ck_alloc(). */ 337 | 338 | #define ck_alloc DFL_ck_alloc 339 | #define ck_alloc_nozero DFL_ck_alloc_nozero 340 | #define ck_realloc DFL_ck_realloc 341 | #define ck_realloc_block DFL_ck_realloc_block 342 | #define ck_strdup DFL_ck_strdup 343 | #define ck_memdup DFL_ck_memdup 344 | #define ck_memdup_str DFL_ck_memdup_str 345 | #define ck_free DFL_ck_free 346 | 347 | #define alloc_report() 348 | 349 | #else 350 | 351 | /* In debugging mode, we also track allocations to detect memory leaks, and the 352 | flow goes through one more layer of indirection. */ 353 | 354 | /* Alloc tracking data structures: */ 355 | 356 | #define ALLOC_BUCKETS 4096 357 | 358 | struct TRK_obj { 359 | void *ptr; 360 | char *file, *func; 361 | u32 line; 362 | }; 363 | 364 | #ifdef AFL_MAIN 365 | 366 | struct TRK_obj* TRK[ALLOC_BUCKETS]; 367 | u32 TRK_cnt[ALLOC_BUCKETS]; 368 | 369 | # define alloc_report() TRK_report() 370 | 371 | #else 372 | 373 | extern struct TRK_obj* TRK[ALLOC_BUCKETS]; 374 | extern u32 TRK_cnt[ALLOC_BUCKETS]; 375 | 376 | # define alloc_report() 377 | 378 | #endif /* ^AFL_MAIN */ 379 | 380 | /* Bucket-assigning function for a given pointer: */ 381 | 382 | #define TRKH(_ptr) (((((u32)(_ptr)) >> 16) ^ ((u32)(_ptr))) % ALLOC_BUCKETS) 383 | 384 | 385 | /* Add a new entry to the list of allocated objects. */ 386 | 387 | static inline void TRK_alloc_buf(void* ptr, const char* file, const char* func, 388 | u32 line) { 389 | 390 | u32 i, bucket; 391 | 392 | if (!ptr) return; 393 | 394 | bucket = TRKH(ptr); 395 | 396 | /* Find a free slot in the list of entries for that bucket. */ 397 | 398 | for (i = 0; i < TRK_cnt[bucket]; i++) 399 | 400 | if (!TRK[bucket][i].ptr) { 401 | 402 | TRK[bucket][i].ptr = ptr; 403 | TRK[bucket][i].file = (char*)file; 404 | TRK[bucket][i].func = (char*)func; 405 | TRK[bucket][i].line = line; 406 | return; 407 | 408 | } 409 | 410 | /* No space available - allocate more. */ 411 | 412 | TRK[bucket] = DFL_ck_realloc_block(TRK[bucket], 413 | (TRK_cnt[bucket] + 1) * sizeof(struct TRK_obj)); 414 | 415 | TRK[bucket][i].ptr = ptr; 416 | TRK[bucket][i].file = (char*)file; 417 | TRK[bucket][i].func = (char*)func; 418 | TRK[bucket][i].line = line; 419 | 420 | TRK_cnt[bucket]++; 421 | 422 | } 423 | 424 | 425 | /* Remove entry from the list of allocated objects. */ 426 | 427 | static inline void TRK_free_buf(void* ptr, const char* file, const char* func, 428 | u32 line) { 429 | 430 | u32 i, bucket; 431 | 432 | if (!ptr) return; 433 | 434 | bucket = TRKH(ptr); 435 | 436 | /* Find the element on the list... */ 437 | 438 | for (i = 0; i < TRK_cnt[bucket]; i++) 439 | 440 | if (TRK[bucket][i].ptr == ptr) { 441 | 442 | TRK[bucket][i].ptr = 0; 443 | return; 444 | 445 | } 446 | 447 | WARNF("ALLOC: Attempt to free non-allocated memory in %s (%s:%u)", 448 | func, file, line); 449 | 450 | } 451 | 452 | 453 | /* Do a final report on all non-deallocated objects. */ 454 | 455 | static inline void TRK_report(void) { 456 | 457 | u32 i, bucket; 458 | 459 | fflush(0); 460 | 461 | for (bucket = 0; bucket < ALLOC_BUCKETS; bucket++) 462 | for (i = 0; i < TRK_cnt[bucket]; i++) 463 | if (TRK[bucket][i].ptr) 464 | WARNF("ALLOC: Memory never freed, created in %s (%s:%u)", 465 | TRK[bucket][i].func, TRK[bucket][i].file, TRK[bucket][i].line); 466 | 467 | } 468 | 469 | 470 | /* Simple wrappers for non-debugging functions: */ 471 | 472 | static inline void* TRK_ck_alloc(u32 size, const char* file, const char* func, 473 | u32 line) { 474 | 475 | void* ret = DFL_ck_alloc(size); 476 | TRK_alloc_buf(ret, file, func, line); 477 | return ret; 478 | 479 | } 480 | 481 | 482 | static inline void* TRK_ck_realloc(void* orig, u32 size, const char* file, 483 | const char* func, u32 line) { 484 | 485 | void* ret = DFL_ck_realloc(orig, size); 486 | TRK_free_buf(orig, file, func, line); 487 | TRK_alloc_buf(ret, file, func, line); 488 | return ret; 489 | 490 | } 491 | 492 | 493 | static inline void* TRK_ck_realloc_block(void* orig, u32 size, const char* file, 494 | const char* func, u32 line) { 495 | 496 | void* ret = DFL_ck_realloc_block(orig, size); 497 | TRK_free_buf(orig, file, func, line); 498 | TRK_alloc_buf(ret, file, func, line); 499 | return ret; 500 | 501 | } 502 | 503 | 504 | static inline void* TRK_ck_strdup(u8* str, const char* file, const char* func, 505 | u32 line) { 506 | 507 | void* ret = DFL_ck_strdup(str); 508 | TRK_alloc_buf(ret, file, func, line); 509 | return ret; 510 | 511 | } 512 | 513 | 514 | static inline void* TRK_ck_memdup(void* mem, u32 size, const char* file, 515 | const char* func, u32 line) { 516 | 517 | void* ret = DFL_ck_memdup(mem, size); 518 | TRK_alloc_buf(ret, file, func, line); 519 | return ret; 520 | 521 | } 522 | 523 | 524 | static inline void* TRK_ck_memdup_str(void* mem, u32 size, const char* file, 525 | const char* func, u32 line) { 526 | 527 | void* ret = DFL_ck_memdup_str(mem, size); 528 | TRK_alloc_buf(ret, file, func, line); 529 | return ret; 530 | 531 | } 532 | 533 | 534 | static inline void TRK_ck_free(void* ptr, const char* file, 535 | const char* func, u32 line) { 536 | 537 | TRK_free_buf(ptr, file, func, line); 538 | DFL_ck_free(ptr); 539 | 540 | } 541 | 542 | /* Aliasing user-facing names to tracking functions: */ 543 | 544 | #define ck_alloc(_p1) \ 545 | TRK_ck_alloc(_p1, __FILE__, __FUNCTION__, __LINE__) 546 | 547 | #define ck_alloc_nozero(_p1) \ 548 | TRK_ck_alloc(_p1, __FILE__, __FUNCTION__, __LINE__) 549 | 550 | #define ck_realloc(_p1, _p2) \ 551 | TRK_ck_realloc(_p1, _p2, __FILE__, __FUNCTION__, __LINE__) 552 | 553 | #define ck_realloc_block(_p1, _p2) \ 554 | TRK_ck_realloc_block(_p1, _p2, __FILE__, __FUNCTION__, __LINE__) 555 | 556 | #define ck_strdup(_p1) \ 557 | TRK_ck_strdup(_p1, __FILE__, __FUNCTION__, __LINE__) 558 | 559 | #define ck_memdup(_p1, _p2) \ 560 | TRK_ck_memdup(_p1, _p2, __FILE__, __FUNCTION__, __LINE__) 561 | 562 | #define ck_memdup_str(_p1, _p2) \ 563 | TRK_ck_memdup_str(_p1, _p2, __FILE__, __FUNCTION__, __LINE__) 564 | 565 | #define ck_free(_p1) \ 566 | TRK_ck_free(_p1, __FILE__, __FUNCTION__, __LINE__) 567 | 568 | #endif /* ^!DEBUG_BUILD */ 569 | 570 | #endif /* ! _HAVE_ALLOC_INL_H */ 571 | -------------------------------------------------------------------------------- /afl-instr/config.h: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop - vaguely configurable bits 3 | ---------------------------------------------- 4 | 5 | Written and maintained by Michal Zalewski 6 | 7 | Copyright 2013, 2014, 2015 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_CONFIG_H 18 | #define _HAVE_CONFIG_H 19 | 20 | #include "types.h" 21 | 22 | /****************************************************** 23 | * * 24 | * Settings that may be of interest to power users: * 25 | * * 26 | ******************************************************/ 27 | 28 | /* Comment out to disable terminal colors: */ 29 | 30 | #define USE_COLOR 31 | 32 | /* Comment out to disable fancy ANSI boxes and use poor man's 7-bit UI: */ 33 | 34 | #define FANCY_BOXES 35 | 36 | /* Default timeout for fuzzed code (milliseconds): */ 37 | 38 | #define EXEC_TIMEOUT 1000 39 | 40 | /* Timeout rounding factor when auto-scaling (milliseconds): */ 41 | 42 | #define EXEC_TM_ROUND 20 43 | 44 | /* Default memory limit for child process (MB): */ 45 | 46 | #ifndef __x86_64__ 47 | # define MEM_LIMIT 25 48 | #else 49 | # define MEM_LIMIT 50 50 | #endif /* ^!__x86_64__ */ 51 | 52 | /* Default memory limit when running in QEMU mode (MB): */ 53 | 54 | #define MEM_LIMIT_QEMU 200 55 | 56 | /* Number of calibration cycles per every new test case (and for test 57 | cases that show variable behavior): */ 58 | 59 | #define CAL_CYCLES 10 60 | #define CAL_CYCLES_LONG 40 61 | 62 | /* The same, but when AFL_NO_VAR_CHECK is set in the environment: */ 63 | 64 | #define CAL_CYCLES_NO_VAR 4 65 | 66 | /* Number of subsequent hangs before abandoning an input file: */ 67 | 68 | #define HANG_LIMIT 250 69 | 70 | /* Maximum number of unique hangs or crashes to record: */ 71 | 72 | #define KEEP_UNIQUE_HANG 500 73 | #define KEEP_UNIQUE_CRASH 5000 74 | 75 | /* Baseline number of random tweaks during a single 'havoc' stage: */ 76 | 77 | #define HAVOC_CYCLES 5000 78 | 79 | /* Maximum multiplier for the above (should be a power of two, beware 80 | of 32-bit int overflows): */ 81 | 82 | #define HAVOC_MAX_MULT 16 83 | 84 | /* Absolute minimum number of havoc cycles (after all adjustments): */ 85 | 86 | #define HAVOC_MIN 10 87 | 88 | /* Maximum stacking for havoc-stage tweaks. The actual value is calculated 89 | like this: 90 | 91 | n = random between 0 and HAVOC_STACK_POW2 92 | stacking = 2^n 93 | 94 | In other words, the default (n = 7) produces 1, 2, 4, 8, 16, 32, 64, or 95 | 128 stacked tweaks: */ 96 | 97 | #define HAVOC_STACK_POW2 7 98 | 99 | /* Caps on block sizes for cloning and deletion operations. Each of these 100 | ranges has a 33% probability of getting picked, except for the first 101 | two cycles where smaller blocks are favored: */ 102 | 103 | #define HAVOC_BLK_SMALL 32 104 | #define HAVOC_BLK_MEDIUM 128 105 | #define HAVOC_BLK_LARGE 1500 106 | 107 | /* Probabilities of skipping non-favored entries in the queue, expressed as 108 | percentages: */ 109 | 110 | #define SKIP_TO_NEW_PROB 99 /* ...when there are new, pending favorites */ 111 | #define SKIP_NFAV_OLD_PROB 95 /* ...no new favs, cur entry already fuzzed */ 112 | #define SKIP_NFAV_NEW_PROB 75 /* ...no new favs, cur entry not fuzzed yet */ 113 | 114 | /* Splicing cycle count: */ 115 | 116 | #define SPLICE_CYCLES 20 117 | 118 | /* Nominal per-splice havoc cycle length: */ 119 | 120 | #define SPLICE_HAVOC 500 121 | 122 | /* Maximum offset for integer addition / subtraction stages: */ 123 | 124 | #define ARITH_MAX 35 125 | 126 | /* Limits for the test case trimmer. The absolute minimum chunk size; and 127 | the starting and ending divisors for chopping up the input file: */ 128 | 129 | #define TRIM_MIN_BYTES 4 130 | #define TRIM_START_STEPS 16 131 | #define TRIM_END_STEPS 1024 132 | 133 | /* Maximum size of input file, in bytes (keep under 100MB): */ 134 | 135 | #define MAX_FILE (1 * 1024 * 1024) 136 | 137 | /* The same, for the test case minimizer: */ 138 | 139 | #define TMIN_MAX_FILE (10 * 1024 * 1024) 140 | 141 | /* Block normalization steps for afl-tmin: */ 142 | 143 | #define TMIN_SET_MIN_SIZE 4 144 | #define TMIN_SET_STEPS 128 145 | 146 | /* Maximum dictionary token size (-x), in bytes: */ 147 | 148 | #define MAX_DICT_FILE 128 149 | 150 | /* Length limits for auto-detected dictionary tokens: */ 151 | 152 | #define MIN_AUTO_EXTRA 3 153 | #define MAX_AUTO_EXTRA 32 154 | 155 | /* Maximum number of user-specified dictionary tokens to use in deterministic 156 | steps; past this point, the "extras/user" step will be still carried out, 157 | but with proportionally lower odds: */ 158 | 159 | #define MAX_DET_EXTRAS 200 160 | 161 | /* Maximum number of auto-extracted dictionary tokens to actually use in fuzzing 162 | (first value), and to keep in memory as candidates. The latter should be much 163 | higher than the former. */ 164 | 165 | #define USE_AUTO_EXTRAS 50 166 | #define MAX_AUTO_EXTRAS (USE_AUTO_EXTRAS * 10) 167 | 168 | /* Scaling factor for the effector map used to skip some of the more 169 | expensive deterministic steps. The actual divisor is set to 170 | 2^EFF_MAP_SCALE2 bytes: */ 171 | 172 | #define EFF_MAP_SCALE2 3 173 | 174 | /* Minimum input file length at which the effector logic kicks in: */ 175 | 176 | #define EFF_MIN_LEN 128 177 | 178 | /* Maximum effector density past which everything is just fuzzed 179 | unconditionally (%): */ 180 | 181 | #define EFF_MAX_PERC 90 182 | 183 | /* UI refresh frequency (Hz): */ 184 | 185 | #define UI_TARGET_HZ 5 186 | 187 | /* Fuzzer stats file and plot update intervals (sec): */ 188 | 189 | #define STATS_UPDATE_SEC 60 190 | #define PLOT_UPDATE_SEC 5 191 | 192 | /* Smoothing divisor for CPU load and exec speed stats (1 - no smoothing). */ 193 | 194 | #define AVG_SMOOTHING 16 195 | 196 | /* Sync interval (every n havoc cycles): */ 197 | 198 | #define SYNC_INTERVAL 5 199 | 200 | /* Output directory reuse grace period (minutes): */ 201 | 202 | #define OUTPUT_GRACE 25 203 | 204 | /* Uncomment to use simple file names (id_NNNNNN): */ 205 | 206 | // #define SIMPLE_FILES 207 | 208 | /* List of interesting values to use in fuzzing. */ 209 | 210 | #define INTERESTING_8 \ 211 | -128, /* Overflow signed 8-bit when decremented */ \ 212 | -1, /* */ \ 213 | 0, /* */ \ 214 | 1, /* */ \ 215 | 16, /* One-off with common buffer size */ \ 216 | 32, /* One-off with common buffer size */ \ 217 | 64, /* One-off with common buffer size */ \ 218 | 100, /* One-off with common buffer size */ \ 219 | 127 /* Overflow signed 8-bit when incremented */ 220 | 221 | #define INTERESTING_16 \ 222 | -32768, /* Overflow signed 16-bit when decremented */ \ 223 | -129, /* Overflow signed 8-bit */ \ 224 | 128, /* Overflow signed 8-bit */ \ 225 | 255, /* Overflow unsig 8-bit when incremented */ \ 226 | 256, /* Overflow unsig 8-bit */ \ 227 | 512, /* One-off with common buffer size */ \ 228 | 1000, /* One-off with common buffer size */ \ 229 | 1024, /* One-off with common buffer size */ \ 230 | 4096, /* One-off with common buffer size */ \ 231 | 32767 /* Overflow signed 16-bit when incremented */ 232 | 233 | #define INTERESTING_32 \ 234 | -2147483648LL, /* Overflow signed 32-bit when decremented */ \ 235 | -100663046, /* Large negative number (endian-agnostic) */ \ 236 | -32769, /* Overflow signed 16-bit */ \ 237 | 32768, /* Overflow signed 16-bit */ \ 238 | 65535, /* Overflow unsig 16-bit when incremented */ \ 239 | 65536, /* Overflow unsig 16 bit */ \ 240 | 100663045, /* Large positive number (endian-agnostic) */ \ 241 | 2147483647 /* Overflow signed 32-bit when incremented */ 242 | 243 | /*********************************************************** 244 | * * 245 | * Really exotic stuff you probably don't want to touch: * 246 | * * 247 | ***********************************************************/ 248 | 249 | /* Call count interval between reseeding the libc PRNG from /dev/urandom: */ 250 | 251 | #define RESEED_RNG 10000 252 | 253 | /* Maximum line length passed from GCC to 'as': */ 254 | 255 | #define MAX_AS_LINE 8192 256 | 257 | /* Environment variable used to pass SHM ID to the called program. */ 258 | 259 | #define SHM_ENV_VAR "__AFL_SHM_ID" 260 | 261 | /* Other less interesting, internal-only variables. */ 262 | 263 | #define CLANG_ENV_VAR "__AFL_CLANG_MODE" 264 | #define AS_LOOP_ENV_VAR "__AFL_AS_LOOPCHECK" 265 | 266 | /* Distinctive bitmap signature used to indicate failed execution: */ 267 | 268 | #define EXEC_FAIL_SIG 0xfee1dead 269 | 270 | /* Distinctive exit code used to indicate MSAN trip condition: */ 271 | 272 | #define MSAN_ERROR 86 273 | 274 | /* Designated file descriptors for forkserver commands (the application will 275 | use FORKSRV_FD and FORKSRV_FD + 1): */ 276 | 277 | #define FORKSRV_FD 198 278 | 279 | /* Fork server init timeout multiplier: we'll wait the user-selected 280 | timeout plus this much for the fork server to spin up. */ 281 | 282 | #define FORK_WAIT_MULT 10 283 | 284 | /* Calibration timeout adjustments, to be a bit more generous when resuming 285 | fuzzing sessions or trying to calibrate already-added internal finds. 286 | The first value is a percentage, the other is in milliseconds: */ 287 | 288 | #define CAL_TMOUT_PERC 125 289 | #define CAL_TMOUT_ADD 50 290 | 291 | /* Number of chances to calibrate a case before giving up: */ 292 | 293 | #define CAL_CHANCES 3 294 | 295 | /* Map size for the traced binary (2^MAP_SIZE_POW2). Must be greater than 296 | 2; you probably want to keep it under 18 or so for performance reasons 297 | (adjusting AFL_INST_RATIO when compiling is probably a better way to solve 298 | problems with complex programs). You need to recompile the target binary 299 | after changing this - otherwise, SEGVs may ensue. */ 300 | 301 | #define MAP_SIZE_POW2 16 302 | #define MAP_SIZE (1 << MAP_SIZE_POW2) 303 | 304 | /* Maximum allocator request size (keep well under INT_MAX): */ 305 | 306 | #define MAX_ALLOC 0x40000000 307 | 308 | /* A made-up hashing seed: */ 309 | 310 | #define HASH_CONST 0xa5b35705 311 | 312 | /* Constants for afl-gotcpu to control busy loop timing: */ 313 | 314 | #define CTEST_TARGET_MS 5000 315 | #define CTEST_BUSY_CYCLES (10 * 1000 * 1000) 316 | 317 | /* Uncomment this to use inferior block-coverage-based instrumentation. Note 318 | that you need to recompile the target binary for this to have any effect: */ 319 | 320 | // #define COVERAGE_ONLY 321 | 322 | /* Uncomment this to ignore hit counts and output just one bit per tuple. 323 | As with the previous setting, you will need to recompile the target 324 | binary: */ 325 | 326 | // #define SKIP_COUNTS 327 | 328 | /* Uncomment this to use instrumentation data to record newly discovered paths, 329 | but do not use them as seeds for fuzzing. This is useful for conveniently 330 | measuring coverage that could be attained by a "dumb" fuzzing algorithm: */ 331 | 332 | // #define IGNORE_FINDS 333 | 334 | #endif /* ! _HAVE_CONFIG_H */ 335 | -------------------------------------------------------------------------------- /afl-instr/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 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 cNOR "\x1b[0;37m" 39 | # define cGRA "\x1b[1;30m" 40 | # define cLRD "\x1b[1;31m" 41 | # define cLGN "\x1b[1;32m" 42 | # define cYEL "\x1b[1;33m" 43 | # define cLBL "\x1b[1;34m" 44 | # define cPIN "\x1b[1;35m" 45 | # define cLCY "\x1b[1;36m" 46 | # define cBRI "\x1b[1;37m" 47 | # define cRST "\x1b[0m" 48 | 49 | #else 50 | 51 | # define cBLK "" 52 | # define cRED "" 53 | # define cGRN "" 54 | # define cBRN "" 55 | # define cBLU "" 56 | # define cMGN "" 57 | # define cCYA "" 58 | # define cNOR "" 59 | # define cGRA "" 60 | # define cLRD "" 61 | # define cLGN "" 62 | # define cYEL "" 63 | # define cLBL "" 64 | # define cPIN "" 65 | # define cLCY "" 66 | # define cBRI "" 67 | # define cRST "" 68 | 69 | #endif /* ^USE_COLOR */ 70 | 71 | /************************* 72 | * Box drawing sequences * 73 | *************************/ 74 | 75 | #ifdef FANCY_BOXES 76 | 77 | # define SET_G1 "\x1b)0" /* Set G1 for box drawing */ 78 | # define RESET_G1 "\x1b)B" /* Reset G1 to ASCII */ 79 | # define bSTART "\x0e" /* Enter G1 drawing mode */ 80 | # define bSTOP "\x0f" /* Leave G1 drawing mode */ 81 | # define bH "q" /* Horizontal line */ 82 | # define bV "x" /* Vertical line */ 83 | # define bLT "l" /* Left top corner */ 84 | # define bRT "k" /* Right top corner */ 85 | # define bLB "m" /* Left bottom corner */ 86 | # define bRB "j" /* Right bottom corner */ 87 | # define bX "n" /* Cross */ 88 | # define bVR "t" /* Vertical, branch right */ 89 | # define bVL "u" /* Vertical, branch left */ 90 | # define bHT "v" /* Horizontal, branch top */ 91 | # define bHB "w" /* Horizontal, branch bottom */ 92 | 93 | #else 94 | 95 | # define SET_G1 "" 96 | # define RESET_G1 "" 97 | # define bSTART "" 98 | # define bSTOP "" 99 | # define bH "-" 100 | # define bV "|" 101 | # define bLT "+" 102 | # define bRT "+" 103 | # define bLB "+" 104 | # define bRB "+" 105 | # define bX "+" 106 | # define bVR "+" 107 | # define bVL "+" 108 | # define bHT "+" 109 | # define bHB "+" 110 | 111 | #endif /* ^FANCY_BOXES */ 112 | 113 | /*********************** 114 | * Misc terminal codes * 115 | ***********************/ 116 | 117 | #define TERM_HOME "\x1b[H" 118 | #define TERM_CLEAR TERM_HOME "\x1b[2J" 119 | #define cEOL "\x1b[0K" 120 | #define CURSOR_HIDE "\x1b[?25l" 121 | #define CURSOR_SHOW "\x1b[?25h" 122 | 123 | /************************ 124 | * Debug & error macros * 125 | ************************/ 126 | 127 | /* Just print stuff to the appropriate stream. */ 128 | 129 | #ifdef MESSAGES_TO_STDOUT 130 | # define SAYF(x...) printf(x) 131 | #else 132 | # define SAYF(x...) fprintf(stderr, x) 133 | #endif /* ^MESSAGES_TO_STDOUT */ 134 | 135 | /* Show a prefixed warning. */ 136 | 137 | #define WARNF(x...) do { \ 138 | SAYF(cYEL "[!] " cBRI "WARNING: " cRST x); \ 139 | SAYF(cRST "\n"); \ 140 | } while (0) 141 | 142 | /* Show a prefixed "doing something" message. */ 143 | 144 | #define ACTF(x...) do { \ 145 | SAYF(cLBL "[*] " cRST x); \ 146 | SAYF(cRST "\n"); \ 147 | } while (0) 148 | 149 | /* Show a prefixed "success" message. */ 150 | 151 | #define OKF(x...) do { \ 152 | SAYF(cLGN "[+] " cRST x); \ 153 | SAYF(cRST "\n"); \ 154 | } while (0) 155 | 156 | /* Show a prefixed fatal error message (not used in afl). */ 157 | 158 | #define BADF(x...) do { \ 159 | SAYF(cLRD "\n[-] " cRST x); \ 160 | SAYF(cRST "\n"); \ 161 | } while (0) 162 | 163 | /* Die with a verbose non-OS fatal error message. */ 164 | 165 | #define FATAL(x...) do { \ 166 | SAYF(bSTOP RESET_G1 CURSOR_SHOW cLRD "\n[-] PROGRAM ABORT : " cBRI x); \ 167 | SAYF(cLRD "\n Location : " cRST "%s(), %s:%u\n\n", \ 168 | __FUNCTION__, __FILE__, __LINE__); \ 169 | exit(1); \ 170 | } while (0) 171 | 172 | /* Die by calling abort() to provide a core dump. */ 173 | 174 | #define ABORT(x...) do { \ 175 | SAYF(bSTOP RESET_G1 CURSOR_SHOW cLRD "\n[-] PROGRAM ABORT : " cBRI x); \ 176 | SAYF(cLRD "\n Stop location : " cRST "%s(), %s:%u\n\n", \ 177 | __FUNCTION__, __FILE__, __LINE__); \ 178 | abort(); \ 179 | } while (0) 180 | 181 | /* Die while also including the output of perror(). */ 182 | 183 | #define PFATAL(x...) do { \ 184 | fflush(stdout); \ 185 | SAYF(bSTOP RESET_G1 CURSOR_SHOW cLRD "\n[-] SYSTEM ERROR : " cBRI x); \ 186 | SAYF(cLRD "\n Stop location : " cRST "%s(), %s:%u\n", \ 187 | __FUNCTION__, __FILE__, __LINE__); \ 188 | SAYF(cLRD " OS message : " cRST "%s\n", strerror(errno)); \ 189 | exit(1); \ 190 | } while (0) 191 | 192 | /* Die with FAULT() or PFAULT() depending on the value of res (used to 193 | interpret different failure modes for read(), write(), etc). */ 194 | 195 | #define RPFATAL(res, x...) do { \ 196 | if (res < 0) PFATAL(x); else FATAL(x); \ 197 | } while (0) 198 | 199 | /* Error-checking versions of read() and write() that call RPFATAL() as 200 | appropriate. */ 201 | 202 | #define ck_write(fd, buf, len, fn) do { \ 203 | u32 _len = (len); \ 204 | s32 _res = write(fd, buf, _len); \ 205 | if (_res != _len) RPFATAL(_res, "Short write to %s", fn); \ 206 | } while (0) 207 | 208 | #define ck_read(fd, buf, len, fn) do { \ 209 | u32 _len = (len); \ 210 | s32 _res = read(fd, buf, _len); \ 211 | if (_res != _len) RPFATAL(_res, "Short read from %s", fn); \ 212 | } while (0) 213 | 214 | #endif /* ! _HAVE_DEBUG_H */ 215 | -------------------------------------------------------------------------------- /afl-instr/hash.h: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop - hashing function 3 | ------------------------------------- 4 | 5 | The hash32() function is a variant of MurmurHash3, a good 6 | non-cryptosafe hashing function developed by Austin Appleby. 7 | 8 | For simplicity, this variant does *NOT* accept buffer lengths 9 | that are not divisible by 8 bytes. The 32-bit version is otherwise 10 | similar to the original; the 64-bit one is a custom hack with 11 | mostly-unproven properties. 12 | 13 | Austin's original code is public domain; so is this variant. 14 | 15 | */ 16 | 17 | #ifndef _HAVE_HASH_H 18 | #define _HAVE_HASH_H 19 | 20 | #include "types.h" 21 | 22 | #ifdef __x86_64__ 23 | 24 | #define ROL64(_x, _r) ((((u64)(_x)) << (_r)) | (((u64)(_x)) >> (64 - (_r)))) 25 | 26 | static inline u32 hash32(const void* key, u32 len, u32 seed) { 27 | 28 | const u64* data = (u64*)key; 29 | u64 h1 = seed ^ len; 30 | 31 | len >>= 3; 32 | 33 | while (len--) { 34 | 35 | u64 k1 = *data++; 36 | 37 | k1 *= 0x87c37b91114253d5ULL; 38 | k1 = ROL64(k1, 31); 39 | k1 *= 0x4cf5ad432745937fULL; 40 | 41 | h1 ^= k1; 42 | h1 = ROL64(h1, 27); 43 | h1 = h1 * 5 + 0x52dce729; 44 | 45 | } 46 | 47 | h1 ^= h1 >> 33; 48 | h1 *= 0xff51afd7ed558ccdULL; 49 | h1 ^= h1 >> 33; 50 | h1 *= 0xc4ceb9fe1a85ec53ULL; 51 | h1 ^= h1 >> 33; 52 | 53 | return h1; 54 | 55 | } 56 | 57 | #else 58 | 59 | #define ROL32(_x, _r) ((((u32)(_x)) << (_r)) | (((u32)(_x)) >> (32 - (_r)))) 60 | 61 | static inline u32 hash32(const void* key, u32 len, u32 seed) { 62 | 63 | const u32* data = (u32*)key; 64 | u32 h1 = seed ^ len; 65 | 66 | len >>= 2; 67 | 68 | while (len--) { 69 | 70 | u32 k1 = *data++; 71 | 72 | k1 *= 0xcc9e2d51; 73 | k1 = ROL32(k1, 15); 74 | k1 *= 0x1b873593; 75 | 76 | h1 ^= k1; 77 | h1 = ROL32(h1, 13); 78 | h1 = h1 * 5 + 0xe6546b64; 79 | 80 | } 81 | 82 | h1 ^= h1 >> 16; 83 | h1 *= 0x85ebca6b; 84 | h1 ^= h1 >> 13; 85 | h1 *= 0xc2b2ae35; 86 | h1 ^= h1 >> 16; 87 | 88 | return h1; 89 | 90 | } 91 | 92 | #endif /* ^__x86_64__ */ 93 | 94 | #endif /* !_HAVE_HASH_H */ 95 | -------------------------------------------------------------------------------- /afl-instr/types.h: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop - type definitions and minor macros 3 | ------------------------------------------------------ 4 | 5 | Written and maintained by Michal Zalewski 6 | 7 | Copyright 2013, 2014, 2015 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_TYPES_H 18 | #define _HAVE_TYPES_H 19 | 20 | #include 21 | #include 22 | 23 | typedef uint8_t u8; 24 | typedef uint16_t u16; 25 | typedef uint32_t u32; 26 | 27 | /* 28 | 29 | Ugh. There is an unintended compiler / glibc #include glitch caused by 30 | combining the u64 type an %llu in format strings, necessitating a workaround. 31 | 32 | In essence, the compiler is always looking for 'unsigned long long' for %llu. 33 | On 32-bit systems, the u64 type (aliased to uint64_t) is expanded to 34 | 'unsigned long long' in , so everything checks out. 35 | 36 | But on 64-bit systems, it is #ifdef'ed in the same file as 'unsigned long'. 37 | Now, it only happens in circumstances where the type happens to have the 38 | expected bit width, *but* the compiler does not know that... and complains 39 | about 'unsigned long' being unsafe to pass to %llu. 40 | 41 | */ 42 | 43 | #ifdef __x86_64__ 44 | typedef unsigned long long u64; 45 | #else 46 | typedef uint64_t u64; 47 | #endif /* ^sizeof(...) */ 48 | 49 | typedef int8_t s8; 50 | typedef int16_t s16; 51 | typedef int32_t s32; 52 | typedef int64_t s64; 53 | 54 | #ifndef MIN 55 | # define MIN(_a,_b) ((_a) > (_b) ? (_b) : (_a)) 56 | # define MAX(_a,_b) ((_a) > (_b) ? (_a) : (_b)) 57 | #endif /* !MIN */ 58 | 59 | #define SWAP16(_x) ({ \ 60 | u16 _ret = (_x); \ 61 | (u16)((_ret << 8) | (_ret >> 8)); \ 62 | }) 63 | 64 | #define SWAP32(_x) ({ \ 65 | u32 _ret = (_x); \ 66 | (u32)((_ret << 24) | (_ret >> 24) | \ 67 | ((_ret << 8) & 0x00FF0000) | \ 68 | ((_ret >> 8) & 0x0000FF00)); \ 69 | }) 70 | 71 | #define R(x) (random() % (x)) 72 | 73 | #define STRINGIFY_INTERNAL(x) #x 74 | #define STRINGIFY(x) STRINGIFY_INTERNAL(x) 75 | 76 | #define MEM_BARRIER() \ 77 | asm volatile("" ::: "memory") 78 | 79 | #endif /* ! _HAVE_TYPES_H */ 80 | -------------------------------------------------------------------------------- /afl-llvm-pass.so.cc: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop - LLVM-mode instrumentation pass 3 | --------------------------------------------------- 4 | 5 | Written by Laszlo Szekeres and 6 | Michal Zalewski 7 | 8 | LLVM integration design comes from Laszlo Szekeres. C bits copied-and-pasted 9 | from afl-as.c are Michal's fault. 10 | 11 | Copyright 2015 Google Inc. All rights reserved. 12 | 13 | Licensed under the Apache License, Version 2.0 (the "License"); 14 | you may not use this file except in compliance with the License. 15 | You may obtain a copy of the License at: 16 | 17 | http://www.apache.org/licenses/LICENSE-2.0 18 | 19 | This library is plugged into LLVM when invoking clang through afl-clang-fast. 20 | It tells the compiler to add code roughly equivalent to the bits discussed 21 | in ../afl-as.h. 22 | 23 | */ 24 | 25 | #include "../config.h" 26 | #include "../debug.h" 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #include "llvm/ADT/Statistic.h" 33 | #include "llvm/IR/IRBuilder.h" 34 | #include "llvm/IR/LegacyPassManager.h" 35 | #include "llvm/IR/Module.h" 36 | #include "llvm/Support/Debug.h" 37 | #include "llvm/Transforms/IPO/PassManagerBuilder.h" 38 | 39 | using namespace llvm; 40 | 41 | //#define DEBUG_TYPE "afl" 42 | 43 | namespace 44 | { 45 | 46 | class AFLCoverage : public ModulePass 47 | { 48 | 49 | public: 50 | 51 | static char ID; 52 | AFLCoverage() : ModulePass(ID) { } 53 | 54 | bool runOnModule(Module &M) override; 55 | 56 | const char* getPassName() const override 57 | { 58 | return "American Fuzzy Lop Instrumentation"; 59 | } 60 | 61 | }; 62 | 63 | } 64 | 65 | 66 | char AFLCoverage::ID = 0; 67 | 68 | 69 | bool AFLCoverage::runOnModule(Module &M) 70 | { 71 | 72 | LLVMContext &C = M.getContext(); 73 | 74 | IntegerType* Int8Ty = IntegerType::getInt8Ty(C); 75 | IntegerType* Int16Ty = IntegerType::getInt16Ty(C); 76 | IntegerType* Int64Ty = IntegerType::getInt64Ty(C); 77 | 78 | /* Show a banner */ 79 | 80 | char be_quiet = 0; 81 | 82 | if (isatty(2) && !getenv("AFL_QUIET")) { 83 | 84 | SAYF(cCYA "afl-llvm-pass " cBRI VERSION cRST " by \n"); 85 | 86 | } else { be_quiet = 1; } 87 | 88 | /* Decide instrumentation ratio */ 89 | 90 | char* inst_ratio_str = getenv("AFL_INST_RATIO"); 91 | int inst_ratio = 100; 92 | 93 | if (inst_ratio_str) { 94 | 95 | if (sscanf(inst_ratio_str, "%u", &inst_ratio) != 1 || !inst_ratio || 96 | inst_ratio > 100) 97 | { FATAL("Bad value of AFL_INST_RATIO (must be between 1 and 100)"); } 98 | 99 | } 100 | 101 | /* Get globals for the SHM region and the previous location. */ 102 | 103 | GlobalVariable* AFLMapPtr = 104 | new GlobalVariable(M, PointerType::get(Int8Ty, 0), false, 105 | GlobalValue::ExternalLinkage, 0, "__afl_area_ptr"); 106 | 107 | GlobalVariable* AFLPrevLoc = new GlobalVariable( 108 | M, Int16Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_loc"); 109 | 110 | /* Instrument all the things! */ 111 | 112 | int inst_blocks = 0; 113 | 114 | for (auto &F : M) 115 | for (auto &BB : F) { 116 | 117 | BasicBlock::iterator IP = BB.getFirstInsertionPt(); 118 | IRBuilder<> IRB(IP); 119 | 120 | if (R(100) >= inst_ratio) { continue; } 121 | 122 | /* Make up cur_loc */ 123 | 124 | unsigned int cur_loc = R(MAP_SIZE); 125 | ConstantInt* CurLoc = ConstantInt::get(Int64Ty, cur_loc); 126 | 127 | /* Load prev_loc */ 128 | 129 | LoadInst* PrevLoc = IRB.CreateLoad(AFLPrevLoc); 130 | PrevLoc->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); 131 | Value* PrevLocCasted = IRB.CreateZExt(PrevLoc, IRB.getInt64Ty()); 132 | 133 | /* Load SHM pointer */ 134 | 135 | LoadInst* MapPtr = IRB.CreateLoad(AFLMapPtr); 136 | MapPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); 137 | Value* MapPtrIdx = 138 | IRB.CreateGEP(MapPtr, IRB.CreateXor(PrevLocCasted, CurLoc)); 139 | 140 | /* Update bitmap */ 141 | 142 | LoadInst* Counter = IRB.CreateLoad(MapPtrIdx); 143 | Counter->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); 144 | Value* Incr = IRB.CreateAdd(Counter, ConstantInt::get(Int8Ty, 1)); 145 | IRB.CreateStore(Incr, MapPtrIdx) 146 | ->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); 147 | 148 | /* Set prev_loc to cur_loc >> 1 */ 149 | 150 | StoreInst* Store = 151 | IRB.CreateStore(ConstantInt::get(Int16Ty, cur_loc >> 1), AFLPrevLoc); 152 | Store->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); 153 | 154 | inst_blocks++; 155 | 156 | } 157 | 158 | /* Say something nice. */ 159 | 160 | if (!be_quiet) { 161 | 162 | if (!inst_blocks) { WARNF("No instrumentation targets found."); } 163 | else OKF("Instrumented %u locations (%s mode, ratio %u%%).", 164 | inst_blocks, 165 | getenv("AFL_HARDEN") ? "hardened" : "non-hardened", 166 | inst_ratio); 167 | 168 | } 169 | 170 | return true; 171 | 172 | } 173 | 174 | 175 | static void registerAFLPass(const PassManagerBuilder &, 176 | legacy::PassManagerBase &PM) 177 | { 178 | printf("Trying to register pass...\n"); 179 | PM.add(new AFLCoverage()); 180 | printf("pass is registered!\n"); 181 | 182 | } 183 | 184 | 185 | static RegisterStandardPasses RegisterAFLPass( 186 | PassManagerBuilder::EP_OptimizerLast, registerAFLPass); 187 | 188 | static struct X { 189 | X() { printf("library is loaded.\n"); } 190 | } X; 191 | -------------------------------------------------------------------------------- /afl-llvm-rt.o.c: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop - LLVM instrumentation bootstrap 3 | --------------------------------------------------- 4 | 5 | Written by Laszlo Szekeres and 6 | Michal Zalewski 7 | 8 | LLVM integration design comes from Laszlo Szekeres. 9 | 10 | Copyright 2015 Google Inc. All rights reserved. 11 | 12 | Licensed under the Apache License, Version 2.0 (the "License"); 13 | you may not use this file except in compliance with the License. 14 | You may obtain a copy of the License at: 15 | 16 | http://www.apache.org/licenses/LICENSE-2.0 17 | 18 | This code is the rewrite of afl-as.h's main_payload. 19 | 20 | */ 21 | 22 | #include "../config.h" 23 | #include "../types.h" 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | 33 | /* Globals needed by the injected instrumentation. The __afl_area_initial region 34 | is used for instrumentation output before __afl_map_shm() has a chance to run. 35 | It will end up as .comm, so it shouldn't be too wasteful. */ 36 | 37 | u8 __afl_area_initial[MAP_SIZE]; 38 | u8* __afl_area_ptr = __afl_area_initial; 39 | u16 __afl_prev_loc; 40 | 41 | /* SHM setup. */ 42 | 43 | static void __afl_map_shm(void) { 44 | 45 | u8 *id_str = getenv(SHM_ENV_VAR); 46 | 47 | /* If we're running under AFL, attach to the appropriate region, replacing the 48 | early-stage __afl_area_initial region that is needed to allow some really 49 | hacky .init code to work correctly in projects such as OpenSSL. */ 50 | 51 | if (id_str) { 52 | 53 | u32 shm_id = atoi(id_str); 54 | 55 | __afl_area_ptr = shmat(shm_id, NULL, 0); 56 | 57 | /* Whooooops. */ 58 | 59 | if (__afl_area_ptr == (void *)-1) exit(1); 60 | 61 | /* Write something into the bitmap so that even with low AFL_INST_RATIO, 62 | our parent doesn't give up on us. */ 63 | 64 | __afl_area_ptr[0] = 1; 65 | 66 | } 67 | 68 | } 69 | 70 | 71 | /* Fork server logic. */ 72 | 73 | static void __afl_start_forkserver(void) { 74 | 75 | static u8 tmp[4]; 76 | 77 | /* Phone home and tell the parent that we're OK. If parent isn't there, 78 | assume we're not running in forkserver mode and just execute program. */ 79 | 80 | if (write(FORKSRV_FD + 1, tmp, 4) != 4) return; 81 | 82 | while (1) { 83 | 84 | s32 child_pid; 85 | int status; 86 | 87 | /* Wait for parent by reading from the pipe. Abort if read fails. */ 88 | 89 | if (read(FORKSRV_FD, tmp, 4) != 4) exit(1); 90 | 91 | /* Once woken up, create a clone of our process. */ 92 | 93 | child_pid = fork(); 94 | if (child_pid < 0) exit(1); 95 | 96 | /* In child process: close fds, resume execution. */ 97 | 98 | if (!child_pid) { 99 | 100 | close(FORKSRV_FD); 101 | close(FORKSRV_FD + 1); 102 | return; 103 | 104 | } 105 | 106 | /* In parent process: write PID to pipe, then wait for child. */ 107 | 108 | if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) exit(1); 109 | if (waitpid(child_pid, &status, WUNTRACED) < 0) exit(1); 110 | 111 | /* Relay wait status to pipe, then loop back. */ 112 | 113 | if (write(FORKSRV_FD + 1, &status, 4) != 4) exit(1); 114 | 115 | } 116 | 117 | } 118 | 119 | 120 | /* This one can be called from user code when AFL_DEFER_FORKSRV is set. */ 121 | 122 | void __afl_manual_init(void) { 123 | 124 | static u8 init_done; 125 | 126 | if (!init_done) { 127 | 128 | __afl_map_shm(); 129 | __afl_start_forkserver(); 130 | init_done = 1; 131 | 132 | } 133 | 134 | } 135 | 136 | 137 | /* Proper initialization routine. */ 138 | 139 | __attribute__((constructor(0))) void __afl_auto_init(void) { 140 | 141 | if (getenv("AFL_DEFER_FORKSRV")) return; 142 | __afl_manual_init(); 143 | 144 | } 145 | 146 | 147 | -------------------------------------------------------------------------------- /compile_llvm.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | LLVM_VERSION="3.5.0" 6 | LLVM_SRC_DIR="${PWD}/llvm-${LLVM_VERSION}" 7 | 8 | if [[ -f "${LLVM_SRC_DIR}/build/Release+Asserts/lib/afl.dylib" ]]; then 9 | cp "${LLVM_SRC_DIR}/build/Release+Asserts/lib/afl.dylib" afl-llvm-pass.so 10 | echo 11 | echo "Looks like the custom LLVM is already built!" 12 | echo "(Delete it manually if you want to rebuild)" 13 | exit 0 14 | fi 15 | 16 | if [[ ! -f "llvm-${LLVM_VERSION}.src.tar.xz" ]]; then 17 | echo 18 | echo "Downloading LLVM" 19 | curl -O "http://releases.llvm.org/${LLVM_VERSION}/llvm-${LLVM_VERSION}.src.tar.xz" 20 | else 21 | echo 22 | echo "Found existing LLVM" 23 | fi 24 | 25 | if [[ ! -f "cfe-${LLVM_VERSION}.src.tar.xz" ]]; then 26 | echo 27 | echo "Downloading Clang" 28 | curl -O "http://releases.llvm.org/${LLVM_VERSION}/cfe-${LLVM_VERSION}.src.tar.xz" 29 | else 30 | echo 31 | echo "Found existing Clang" 32 | fi 33 | 34 | if [[ ! -f "compiler-rt-${LLVM_VERSION}.src.tar.xz" ]]; then 35 | echo 36 | echo "Downloading Compiler-RT" 37 | curl -O "http://releases.llvm.org/${LLVM_VERSION}/compiler-rt-${LLVM_VERSION}.src.tar.xz" 38 | else 39 | echo 40 | echo "Found existing Compiler-RT" 41 | fi 42 | 43 | echo 44 | echo "Unpacking LLVM" 45 | tar xf "llvm-${LLVM_VERSION}.src.tar.xz" 46 | mv "llvm-${LLVM_VERSION}.src" "${LLVM_SRC_DIR}" 47 | 48 | echo 49 | echo "Unpacking Clang into tools" 50 | tar xf "cfe-${LLVM_VERSION}.src.tar.xz" 51 | mv "cfe-${LLVM_VERSION}.src" "${LLVM_SRC_DIR}/tools/clang" 52 | 53 | echo 54 | echo "Unpacking Compiler-RT into projects" 55 | tar xf "compiler-rt-${LLVM_VERSION}.src.tar.xz" 56 | mv "compiler-rt-${LLVM_VERSION}.src" "${LLVM_SRC_DIR}/projects/compiler-rt" 57 | 58 | echo 59 | echo "Copying afl-instr sources into LLVM source tree" 60 | cp -r afl-instr "${LLVM_SRC_DIR}/projects/" 61 | 62 | echo 63 | echo "Installing LLVM" 64 | mkdir "${LLVM_SRC_DIR}/build" 65 | cd "${LLVM_SRC_DIR}/build" 66 | export CC=gcc 67 | export CXX=g++ 68 | ../configure --enable-optimized 69 | REQUIRES_RTTI=1 make -j5 70 | cd ../.. 71 | cp "${LLVM_SRC_DIR}/build/Release+Asserts/lib/afl.dylib" afl-llvm-pass.so 72 | 73 | echo "All done" 74 | --------------------------------------------------------------------------------