mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-14 02:58:08 +00:00
document new environment variables and code format
This commit is contained in:
@ -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
|
||||
|
@ -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).
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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]
|
||||
|
Reference in New Issue
Block a user