1# Fast LLVM-based instrumentation for afl-fuzz 2 3 (See [../README.md](../README.md) for the general instruction manual.) 4 5 (See [README.gcc_plugin.md](../README.gcc_plugin.md) for the GCC-based instrumentation.) 6 7## 1) Introduction 8 9! llvm_mode works with llvm versions 3.8 up to 12 ! 10 11The code in this directory allows you to instrument programs for AFL using 12true compiler-level instrumentation, instead of the more crude 13assembly-level rewriting approach taken by afl-gcc and afl-clang. This has 14several interesting properties: 15 16 - The compiler can make many optimizations that are hard to pull off when 17 manually inserting assembly. As a result, some slow, CPU-bound programs will 18 run up to around 2x faster. 19 20 The gains are less pronounced for fast binaries, where the speed is limited 21 chiefly by the cost of creating new processes. In such cases, the gain will 22 probably stay within 10%. 23 24 - The instrumentation is CPU-independent. At least in principle, you should 25 be able to rely on it to fuzz programs on non-x86 architectures (after 26 building afl-fuzz with AFL_NO_X86=1). 27 28 - The instrumentation can cope a bit better with multi-threaded targets. 29 30 - Because the feature relies on the internals of LLVM, it is clang-specific 31 and will *not* work with GCC (see ../gcc_plugin/ for an alternative once 32 it is available). 33 34Once this implementation is shown to be sufficiently robust and portable, it 35will probably replace afl-clang. For now, it can be built separately and 36co-exists with the original code. 37 38The idea and much of the intial implementation came from Laszlo Szekeres. 39 40## 2a) How to use this - short 41 42Set the `LLVM_CONFIG` variable to the clang version you want to use, e.g. 43``` 44LLVM_CONFIG=llvm-config-9 make 45``` 46In case you have your own compiled llvm version specify the full path: 47``` 48LLVM_CONFIG=~/llvm-project/build/bin/llvm-config make 49``` 50If you try to use a new llvm version on an old Linux this can fail because of 51old c++ libraries. In this case usually switching to gcc/g++ to compile 52llvm_mode will work: 53``` 54LLVM_CONFIG=llvm-config-7 REAL_CC=gcc REAL_CXX=g++ make 55``` 56It is highly recommended to use the newest clang version you can put your 57hands on :) 58 59Then look at [README.persistent_mode.md](README.persistent_mode.md). 60 61## 2b) How to use this - long 62 63In order to leverage this mechanism, you need to have clang installed on your 64system. You should also make sure that the llvm-config tool is in your path 65(or pointed to via LLVM_CONFIG in the environment). 66 67Note that if you have several LLVM versions installed, pointing LLVM_CONFIG 68to the version you want to use will switch compiling to this specific 69version - if you installation is set up correctly :-) 70 71Unfortunately, some systems that do have clang come without llvm-config or the 72LLVM development headers; one example of this is FreeBSD. FreeBSD users will 73also run into problems with clang being built statically and not being able to 74load modules (you'll see "Service unavailable" when loading afl-llvm-pass.so). 75 76To solve all your problems, you can grab pre-built binaries for your OS from: 77 78 http://llvm.org/releases/download.html 79 80...and then put the bin/ directory from the tarball at the beginning of your 81$PATH when compiling the feature and building packages later on. You don't need 82to be root for that. 83 84To build the instrumentation itself, type 'make'. This will generate binaries 85called afl-clang-fast and afl-clang-fast++ in the parent directory. Once this 86is done, you can instrument third-party code in a way similar to the standard 87operating mode of AFL, e.g.: 88 89``` 90 CC=/path/to/afl/afl-clang-fast ./configure [...options...] 91 make 92``` 93 94Be sure to also include CXX set to afl-clang-fast++ for C++ code. 95 96Note that afl-clang-fast/afl-clang-fast++ are just pointers to afl-cc. 97You can also use afl-cc/afl-c++ and instead direct it to use LLVM 98instrumentation by either setting `AFL_CC_COMPILER=LLVM` or pass the parameter 99`--afl-llvm` via CFLAGS/CXXFLAGS/CPPFLAGS. 100 101The tool honors roughly the same environmental variables as afl-gcc (see 102[docs/env_variables.md](../docs/env_variables.md)). This includes AFL_USE_ASAN, 103AFL_HARDEN, and AFL_DONT_OPTIMIZE. However AFL_INST_RATIO is not honored 104as it does not serve a good purpose with the more effective PCGUARD analysis. 105 106## 3) Options 107 108Several options are present to make llvm_mode faster or help it rearrange 109the code to make afl-fuzz path discovery easier. 110 111If you need just to instrument specific parts of the code, you can the instrument file list 112which C/C++ files to actually instrument. See [README.instrument_list.md](README.instrument_list.md) 113 114For splitting memcmp, strncmp, etc. please see [README.laf-intel.md](README.laf-intel.md) 115 116Then there are different ways of instrumenting the target: 117 1181. An better instrumentation strategy uses LTO and link time 119instrumentation. Note that not all targets can compile in this mode, however 120if it works it is the best option you can use. 121Simply use afl-clang-lto/afl-clang-lto++ to use this option. 122See [README.lto.md](README.lto.md) 123 1242. Alternativly you can choose a completely different coverage method: 125 1262a. N-GRAM coverage - which combines the previous visited edges with the 127current one. This explodes the map but on the other hand has proven to be 128effective for fuzzing. 129See [README.ngram.md](README.ngram.md) 130 1312b. Context sensitive coverage - which combines the visited edges with an 132individual caller ID (the function that called the current one) 133[README.ctx.md](README.ctx.md) 134 135Then - additionally to one of the instrumentation options above - there is 136a very effective new instrumentation option called CmpLog as an alternative to 137laf-intel that allow AFL++ to apply mutations similar to Redqueen. 138See [README.cmplog.md](README.cmplog.md) 139 140Finally if your llvm version is 8 or lower, you can activate a mode that 141prevents that a counter overflow result in a 0 value. This is good for 142path discovery, but the llvm implementation for x86 for this functionality 143is not optimal and was only fixed in llvm 9. 144You can set this with AFL_LLVM_NOT_ZERO=1 145See [README.neverzero.md](README.neverzero.md) 146 147Support for thread safe counters has been added for all modes. 148Activate it with `AFL_LLVM_THREADSAFE_INST=1`. The tradeoff is better precision 149in multi threaded apps for a slightly higher instrumentation overhead. 150This also disables the nozero counter default for performance reasons. 151 152## 4) Snapshot feature 153 154To speed up fuzzing you can use a linux loadable kernel module which enables 155a snapshot feature. 156See [README.snapshot.md](README.snapshot.md) 157 158## 5) Gotchas, feedback, bugs 159 160This is an early-stage mechanism, so field reports are welcome. You can send bug 161reports to <afl-users@googlegroups.com>. 162 163## 6) deferred initialization, persistent mode, shared memory fuzzing 164 165This is the most powerful and effective fuzzing you can do. 166Please see [README.persistent_mode.md](README.persistent_mode.md) for a 167full explanation. 168 169## 7) Bonus feature: 'dict2file' pass 170 171Just specify `AFL_LLVM_DICT2FILE=/absolute/path/file.txt` and during compilation 172all constant string compare parameters will be written to this file to be 173used with afl-fuzz' `-x` option. 174