diff options
author | van Hauser <vh@thc.org> | 2020-03-10 07:14:42 +0100 |
---|---|---|
committer | van Hauser <vh@thc.org> | 2020-03-10 07:14:42 +0100 |
commit | 1148a2d0d1ce43ab89e14eefb70bc410726838c4 (patch) | |
tree | 4c2a69940d07cb2fadd8b8a5cbbfdb7f902c8d36 | |
parent | 38d9aedb26d6c4530763a29fe7695155a21ffbbc (diff) | |
download | afl++-1148a2d0d1ce43ab89e14eefb70bc410726838c4.tar.gz |
document new environment variables and code format
-rw-r--r-- | docs/Changelog.md | 4 | ||||
-rw-r--r-- | docs/custom_mutators.md | 2 | ||||
-rw-r--r-- | docs/env_variables.md | 23 | ||||
-rw-r--r-- | include/afl-fuzz.h | 2 | ||||
-rw-r--r-- | include/common.h | 6 | ||||
-rw-r--r-- | include/envs.h | 13 | ||||
-rw-r--r-- | llvm_mode/LLVMInsTrim.so.cc | 13 | ||||
-rw-r--r-- | llvm_mode/MarkNodes.cc | 13 | ||||
-rw-r--r-- | llvm_mode/README.instrim.md | 9 |
9 files changed, 61 insertions, 24 deletions
diff --git a/docs/Changelog.md b/docs/Changelog.md index 2a5e36d8..177054e2 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -25,8 +25,8 @@ sending a mail to <afl-users+subscribe@googlegroups.com>. - llvm_mode InsTrim mode: - removed workaround for bug where paths were not instrumented and imported fix by author - - made skipping 1 block functions an option and is disable by default --> TODO: document this! + - made skipping 1 block functions an option and is disable by default, + set AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK=1 to renable this - qemu_mode: - qemu_mode now uses solely the internal capstone version to fix builds on modern Linux distributions diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index 7f95b4af..14d8f518 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -15,7 +15,7 @@ cases beyond those available in AFL. For example, to enable structure-aware fuzzing by using libraries that perform mutations according to a given grammar. The custom mutator is passed to `afl-fuzz` via the `AFL_CUSTOM_MUTATOR_LIBRARY` -or `AFL_PYTHON_MODULE` environment variable., and must export a fuzz function. +or `AFL_PYTHON_MODULE` environment variable, and must export a fuzz function. Please see [APIs](#2-apis) and [Usage](#3-usage) for detail. The custom mutation stage is set to be the first non-deterministic stage (right before the havoc stage). diff --git a/docs/env_variables.md b/docs/env_variables.md index d1cf6977..8c7510cd 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -91,6 +91,25 @@ of the settings discussed in section #1, with the exception of: Then there are a few specific features that are only available in llvm_mode: +### LTO + +This is a different kind way of instrumentation: first it compiles all +code in LTO (link time optimization) and then performs an edge inserting +instrumentation which is 100% collision free (collisions are a big issue +in afl and afl-like instrumentations). This is performed by using +afl-clang-lto/afl-clang-lto++ instead of afl-clang-fast, but is only +built if LLVM 9 or newer is used. + +None of these options are necessary to be used and are rather for manual +use (which only ever the author of this LTO implementation will use ;-) +These are used if several seperated instrumentation are performed which +are then later combined. + + - AFL_LLVM_LTO_STARTID sets the starting location ID for the instrumentation. + This defaults to 1 + - AFL_LLVM_LTO_DONTWRITEID prevents that the highest location ID written + into the instrumentation is set in a global variable + ### LAF-INTEL This great feature will split compares to series of single byte comparisons @@ -126,6 +145,10 @@ Then there are a few specific features that are only available in llvm_mode: afl-fuzz will only be able to see the path the loop took, but not how many times it was called (unless it is a complex loop). + - Setting AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK=1 will skip instrumenting + functions with a single basic block. This is useful for most C and + some C++ targets. + See llvm_mode/README.instrim.md ### NOT_ZERO diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index b83d224b..a28608ce 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -516,7 +516,7 @@ typedef struct afl_state { /* CmpLog */ char* cmplog_binary; - s32 cmplog_child_pid, cmplog_fsrv_pid; + s32 cmplog_child_pid, cmplog_fsrv_pid; /* Custom mutators */ struct custom_mutator* mutator; diff --git a/include/common.h b/include/common.h index 5d0e7266..504783ba 100644 --- a/include/common.h +++ b/include/common.h @@ -31,11 +31,11 @@ #include "types.h" #include "stdbool.h" -void detect_file_args(char** argv, u8* prog_in, u8 *use_stdin); +void detect_file_args(char** argv, u8* prog_in, u8* use_stdin); void check_environment_vars(char** env); -char **argv_cpy_dup(int argc, char **argv); -void argv_cpy_free(char **argv); +char** argv_cpy_dup(int argc, char** argv); +void argv_cpy_free(char** argv); char** get_qemu_argv(u8* own_loc, u8** target_path_p, int argc, char** argv); char** get_wine_argv(u8* own_loc, u8** target_path_p, int argc, char** argv); diff --git a/include/envs.h b/include/envs.h index b131f406..82eaf456 100644 --- a/include/envs.h +++ b/include/envs.h @@ -14,12 +14,13 @@ const char *afl_environment_variables[] = { "AFL_INST_LIBS", "AFL_INST_RATIO", "AFL_KEEP_TRACES", "AFL_KEEP_ASSEMBLY", "AFL_LD_HARD_FAIL", "AFL_LD_LIMIT_MB", "AFL_LD_NO_CALLOC_OVER", "AFL_LD_PRELOAD", "AFL_LD_VERBOSE", "AFL_LLVM_CMPLOG", "AFL_LLVM_INSTRIM", - "AFL_LLVM_INSTRIM_LOOPHEAD", "AFL_LLVM_LAF_SPLIT_COMPARES", - "AFL_LLVM_LAF_SPLIT_COMPARES_BITW", "AFL_LLVM_LAF_SPLIT_FLOATS", - "AFL_LLVM_LAF_SPLIT_SWITCHES", "AFL_LLVM_LAF_TRANSFORM_COMPARES", - "AFL_LLVM_NOT_ZERO", "AFL_LLVM_WHITELIST", "AFL_NO_AFFINITY", - "AFL_LLVM_LTO_STARTID", "AFL_LLVM_LTO_DONTWRITEID", "AFL_NO_ARITH", - "AFL_NO_BUILTIN", "AFL_NO_CPU_RED", "AFL_NO_FORKSRV", "AFL_NO_UI", + "AFL_LLVM_INSTRIM_LOOPHEAD", "AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK", + "AFL_LLVM_LAF_SPLIT_COMPARES", "AFL_LLVM_LAF_SPLIT_COMPARES_BITW", + "AFL_LLVM_LAF_SPLIT_FLOATS", "AFL_LLVM_LAF_SPLIT_SWITCHES", + "AFL_LLVM_LAF_TRANSFORM_COMPARES", "AFL_LLVM_NOT_ZERO", + "AFL_LLVM_WHITELIST", "AFL_NO_AFFINITY", "AFL_LLVM_LTO_STARTID", + "AFL_LLVM_LTO_DONTWRITEID", "AFL_NO_ARITH", "AFL_NO_BUILTIN", + "AFL_NO_CPU_RED", "AFL_NO_FORKSRV", "AFL_NO_UI", "AFL_NO_X86", // not really an env but we dont want to warn on it "AFL_PATH", "AFL_PERFORMANCE_FILE", //"AFL_PERSISTENT", // not implemented anymore, so warn additionally diff --git a/llvm_mode/LLVMInsTrim.so.cc b/llvm_mode/LLVMInsTrim.so.cc index 0fddad24..229d7d24 100644 --- a/llvm_mode/LLVMInsTrim.so.cc +++ b/llvm_mode/LLVMInsTrim.so.cc @@ -54,7 +54,7 @@ struct InsTrim : public ModulePass { protected: std::list<std::string> myWhitelist; - uint32_t function_minimum_size = 1; + uint32_t function_minimum_size = 1; private: std::mt19937 generator; @@ -387,15 +387,18 @@ struct InsTrim : public ModulePass { } - if (function_minimum_size < 2) { + if (function_minimum_size < 2) { + for (BasicBlock &BB : F) { - if (MS.find(&BB) == MS.end()) { - continue; - } + + if (MS.find(&BB) == MS.end()) { continue; } IRBuilder<> IRB(&*BB.getFirstInsertionPt()); IRB.CreateStore(ConstantInt::get(Int32Ty, genLabel()), OldPrev); + } + } + } for (BasicBlock &BB : F) { diff --git a/llvm_mode/MarkNodes.cc b/llvm_mode/MarkNodes.cc index b8587826..cff6c90a 100644 --- a/llvm_mode/MarkNodes.cc +++ b/llvm_mode/MarkNodes.cc @@ -393,10 +393,9 @@ bool MarkSubGraph(uint32_t ss, uint32_t tt) { MakeUniq(TopoOrder[i]); } - - // Check if there is an empty path. - if (NextMarked[tt].count(TopoOrder[0]) > 0) - return true; + + // Check if there is an empty path. + if (NextMarked[tt].count(TopoOrder[0]) > 0) return true; return false; } @@ -422,7 +421,7 @@ void MarkVertice() { timeStamp = 0; uint32_t t = 0; - bool emptyPathExists = true; + bool emptyPathExists = true; while (s != t) { @@ -430,10 +429,12 @@ void MarkVertice() { t = DominatorTree::idom[t]; } - + if (emptyPathExists) { + // Mark all exit blocks to catch the empty path. Marked.insert(t_Pred[0].begin(), t_Pred[0].end()); + } } diff --git a/llvm_mode/README.instrim.md b/llvm_mode/README.instrim.md index b40dbb18..5c3f32c8 100644 --- a/llvm_mode/README.instrim.md +++ b/llvm_mode/README.instrim.md @@ -19,6 +19,15 @@ see how often the loop has been rerun. This again is a tradeoff for speed for less path information. To enable this mode set `AFL_LLVM_INSTRIM_LOOPHEAD=1`. +There is an additional optimization option that skips single block +functions. In 95% of the C targets and (guess) 50% of the C++ targets +it is good to enable this, as otherwise pointless instrumentation occurs. +The corner case where we want this instrumentation is when vtable/call table +is used and the index to that vtable/call table is not set in specific +basic blocks. +To enable skipping these (most of the time) unnecessary instrumentations set +`AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK=1` + ## Background The paper: [InsTrim: Lightweight Instrumentation for Coverage-guided Fuzzing] |