mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-14 11:08:06 +00:00
Merge branch 'dev' of https://github.com/AFLplusplus/AFLplusplus into dev
This commit is contained in:
@ -55,6 +55,7 @@ behaviours and defaults:
|
|||||||
* a caching of testcases can now be performed and can be modified by
|
* a caching of testcases can now be performed and can be modified by
|
||||||
editing config.h for TESTCASE_CACHE or by specifying the env variable
|
editing config.h for TESTCASE_CACHE or by specifying the env variable
|
||||||
`AFL_TESTCACHE_SIZE` (in MB). Good values are between 50-500 (default: 50).
|
`AFL_TESTCACHE_SIZE` (in MB). Good values are between 50-500 (default: 50).
|
||||||
|
* -M mains do not perform trimming
|
||||||
* examples/ got renamed to utils/
|
* examples/ got renamed to utils/
|
||||||
* libtokencap/ libdislocator/ and qdbi_mode/ were moved to utils/
|
* libtokencap/ libdislocator/ and qdbi_mode/ were moved to utils/
|
||||||
* afl-cmin/afl-cmin.bash now search first in PATH and last in AFL_PATH
|
* afl-cmin/afl-cmin.bash now search first in PATH and last in AFL_PATH
|
||||||
|
@ -36,6 +36,9 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
|
|||||||
- cmplog/redqueen now also tracks floating point, _ExtInt() + 128bit
|
- cmplog/redqueen now also tracks floating point, _ExtInt() + 128bit
|
||||||
- cmplog/redqueen can now process basic libc++ and libstdc++
|
- cmplog/redqueen can now process basic libc++ and libstdc++
|
||||||
std::string comparisons (though no position or length type variants)
|
std::string comparisons (though no position or length type variants)
|
||||||
|
- added support for __afl_coverage_interesting() for LTO and
|
||||||
|
and our own PCGUARD (llvm 10.0.1+), read more about this function
|
||||||
|
and selective coverage in instrumentation/README.instrument_list.md
|
||||||
- added AFL_LLVM_INSTRUMENT option NATIVE for native clang pc-guard
|
- added AFL_LLVM_INSTRUMENT option NATIVE for native clang pc-guard
|
||||||
support (less performant than our own), GCC for old afl-gcc and
|
support (less performant than our own), GCC for old afl-gcc and
|
||||||
CLANG for old afl-clang
|
CLANG for old afl-clang
|
||||||
|
@ -16,6 +16,8 @@ test cases executed.
|
|||||||
It should be clickable which value is X and Y axis, zoom factor, log scaling
|
It should be clickable which value is X and Y axis, zoom factor, log scaling
|
||||||
on-off, etc.
|
on-off, etc.
|
||||||
|
|
||||||
|
Mentor: vanhauser-thc
|
||||||
|
|
||||||
## WASM Instrumentation
|
## WASM Instrumentation
|
||||||
|
|
||||||
Currently, AFL++ can be used for source code fuzzing and traditional binaries.
|
Currently, AFL++ can be used for source code fuzzing and traditional binaries.
|
||||||
@ -36,19 +38,6 @@ Either improve a single mutator thorugh learning of many different bugs
|
|||||||
|
|
||||||
Mentor: domenukk
|
Mentor: domenukk
|
||||||
|
|
||||||
## Collision-free Binary-Only Maps
|
|
||||||
|
|
||||||
AFL++ supports collison-free maps using an LTO (link-time-optimization) pass.
|
|
||||||
This should be possible to implement for QEMU and Unicorn instrumentations.
|
|
||||||
As the forkserver parent caches just in time translated translation blocks,
|
|
||||||
adding a simple counter between jumps should be doable.
|
|
||||||
|
|
||||||
Note: this is already in development for qemu by Andrea, so for people who
|
|
||||||
want to contribute it might make more sense to port his solution to unicorn.
|
|
||||||
|
|
||||||
Mentor: andreafioraldi or domenukk
|
|
||||||
Issue/idea tracker: [https://github.com/AFLplusplus/AFLplusplus/issues/237](https://github.com/AFLplusplus/AFLplusplus/issues/237)
|
|
||||||
|
|
||||||
## Your idea!
|
## Your idea!
|
||||||
|
|
||||||
Finally, we are open to proposals!
|
Finally, we are open to proposals!
|
||||||
|
@ -43,6 +43,13 @@ in any function where you want:
|
|||||||
* `__AFL_COVERAGE_DISCARD();` - reset all coverage gathered until this point
|
* `__AFL_COVERAGE_DISCARD();` - reset all coverage gathered until this point
|
||||||
* `__AFL_COVERAGE_SKIP();` - mark this test case as unimportant. Whatever happens, afl-fuzz will ignore it.
|
* `__AFL_COVERAGE_SKIP();` - mark this test case as unimportant. Whatever happens, afl-fuzz will ignore it.
|
||||||
|
|
||||||
|
A special function is `__afl_coverage_interesting`.
|
||||||
|
To use this, you must define `void __afl_coverage_interesting(u8 val, u32 id);`.
|
||||||
|
Then you can use this function globally, where the `val` parameter can be set
|
||||||
|
by you, the `id` parameter is for afl-fuzz and will be overwritten.
|
||||||
|
Note that useful parameters are for `val` are: 1, 2, 3, 4, 8, 16, 32, 64, 128.
|
||||||
|
A value of e.g. 33 will be seen as 32 for coverage purposes.
|
||||||
|
|
||||||
## 3) Selective instrumenation with AFL_LLVM_ALLOWLIST/AFL_LLVM_DENYLIST
|
## 3) Selective instrumenation with AFL_LLVM_ALLOWLIST/AFL_LLVM_DENYLIST
|
||||||
|
|
||||||
This feature is equivalent to llvm 12 sancov feature and allows to specify
|
This feature is equivalent to llvm 12 sancov feature and allows to specify
|
||||||
|
@ -1237,6 +1237,25 @@ void ModuleSanitizerCoverage::instrumentFunction(
|
|||||||
|
|
||||||
for (auto &BB : F) {
|
for (auto &BB : F) {
|
||||||
|
|
||||||
|
for (auto &IN : BB) {
|
||||||
|
|
||||||
|
CallInst *callInst = nullptr;
|
||||||
|
|
||||||
|
if ((callInst = dyn_cast<CallInst>(&IN))) {
|
||||||
|
|
||||||
|
Function *Callee = callInst->getCalledFunction();
|
||||||
|
if (!Callee) continue;
|
||||||
|
if (callInst->getCallingConv() != llvm::CallingConv::C) continue;
|
||||||
|
StringRef FuncName = Callee->getName();
|
||||||
|
if (FuncName.compare(StringRef("__afl_coverage_interesting"))) continue;
|
||||||
|
|
||||||
|
Value *val = ConstantInt::get(Int32Ty, ++afl_global_id);
|
||||||
|
callInst->setOperand(1, val);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (shouldInstrumentBlock(F, &BB, DT, PDT, Options))
|
if (shouldInstrumentBlock(F, &BB, DT, PDT, Options))
|
||||||
BlocksToInstrument.push_back(&BB);
|
BlocksToInstrument.push_back(&BB);
|
||||||
for (auto &Inst : BB) {
|
for (auto &Inst : BB) {
|
||||||
@ -1338,6 +1357,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
|
|||||||
|
|
||||||
if (AllBlocks.empty()) return false;
|
if (AllBlocks.empty()) return false;
|
||||||
CreateFunctionLocalArrays(F, AllBlocks);
|
CreateFunctionLocalArrays(F, AllBlocks);
|
||||||
|
|
||||||
for (size_t i = 0, N = AllBlocks.size(); i < N; i++) {
|
for (size_t i = 0, N = AllBlocks.size(); i < N; i++) {
|
||||||
|
|
||||||
// afl++ START
|
// afl++ START
|
||||||
|
@ -311,7 +311,8 @@ class ModuleSanitizerCoverage {
|
|||||||
Function &F, Type *Ty,
|
Function &F, Type *Ty,
|
||||||
const char *Section);
|
const char *Section);
|
||||||
GlobalVariable *CreatePCArray(Function &F, ArrayRef<BasicBlock *> AllBlocks);
|
GlobalVariable *CreatePCArray(Function &F, ArrayRef<BasicBlock *> AllBlocks);
|
||||||
void CreateFunctionLocalArrays(Function &F, ArrayRef<BasicBlock *> AllBlocks);
|
void CreateFunctionLocalArrays(Function &F, ArrayRef<BasicBlock *> AllBlocks,
|
||||||
|
uint32_t special);
|
||||||
void InjectCoverageAtBlock(Function &F, BasicBlock &BB, size_t Idx,
|
void InjectCoverageAtBlock(Function &F, BasicBlock &BB, size_t Idx,
|
||||||
bool IsLeafFunc = true);
|
bool IsLeafFunc = true);
|
||||||
Function *CreateInitCallsForSections(Module &M, const char *CtorName,
|
Function *CreateInitCallsForSections(Module &M, const char *CtorName,
|
||||||
@ -970,11 +971,11 @@ GlobalVariable *ModuleSanitizerCoverage::CreatePCArray(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ModuleSanitizerCoverage::CreateFunctionLocalArrays(
|
void ModuleSanitizerCoverage::CreateFunctionLocalArrays(
|
||||||
Function &F, ArrayRef<BasicBlock *> AllBlocks) {
|
Function &F, ArrayRef<BasicBlock *> AllBlocks, uint32_t special) {
|
||||||
|
|
||||||
if (Options.TracePCGuard)
|
if (Options.TracePCGuard)
|
||||||
FunctionGuardArray = CreateFunctionLocalArrayInSection(
|
FunctionGuardArray = CreateFunctionLocalArrayInSection(
|
||||||
AllBlocks.size(), F, Int32Ty, SanCovGuardsSectionName);
|
AllBlocks.size() + special, F, Int32Ty, SanCovGuardsSectionName);
|
||||||
|
|
||||||
if (Options.Inline8bitCounters)
|
if (Options.Inline8bitCounters)
|
||||||
Function8bitCounterArray = CreateFunctionLocalArrayInSection(
|
Function8bitCounterArray = CreateFunctionLocalArrayInSection(
|
||||||
@ -993,9 +994,38 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
|
|||||||
bool IsLeafFunc) {
|
bool IsLeafFunc) {
|
||||||
|
|
||||||
if (AllBlocks.empty()) return false;
|
if (AllBlocks.empty()) return false;
|
||||||
CreateFunctionLocalArrays(F, AllBlocks);
|
|
||||||
|
uint32_t special = 0;
|
||||||
|
for (auto &BB : F) {
|
||||||
|
|
||||||
|
for (auto &IN : BB) {
|
||||||
|
|
||||||
|
CallInst *callInst = nullptr;
|
||||||
|
|
||||||
|
if ((callInst = dyn_cast<CallInst>(&IN))) {
|
||||||
|
|
||||||
|
Function *Callee = callInst->getCalledFunction();
|
||||||
|
StringRef FuncName = Callee->getName();
|
||||||
|
if (!Callee) continue;
|
||||||
|
if (callInst->getCallingConv() != llvm::CallingConv::C) continue;
|
||||||
|
if (FuncName.compare(StringRef("__afl_coverage_interesting"))) continue;
|
||||||
|
|
||||||
|
uint32_t id = 1 + instr + (uint32_t)AllBlocks.size() + special++;
|
||||||
|
Value * val = ConstantInt::get(Int32Ty, id);
|
||||||
|
callInst->setOperand(1, val);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateFunctionLocalArrays(F, AllBlocks, special);
|
||||||
for (size_t i = 0, N = AllBlocks.size(); i < N; i++)
|
for (size_t i = 0, N = AllBlocks.size(); i < N; i++)
|
||||||
InjectCoverageAtBlock(F, *AllBlocks[i], i, IsLeafFunc);
|
InjectCoverageAtBlock(F, *AllBlocks[i], i, IsLeafFunc);
|
||||||
|
|
||||||
|
instr += special;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
14
src/afl-cc.c
14
src/afl-cc.c
@ -572,7 +572,8 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
|||||||
|
|
||||||
cc_params[cc_par_cnt++] = "-Wl,--allow-multiple-definition";
|
cc_params[cc_par_cnt++] = "-Wl,--allow-multiple-definition";
|
||||||
|
|
||||||
if (instrument_mode == INSTRUMENT_CFG)
|
if (instrument_mode == INSTRUMENT_CFG ||
|
||||||
|
instrument_mode == INSTRUMENT_PCGUARD)
|
||||||
cc_params[cc_par_cnt++] = alloc_printf(
|
cc_params[cc_par_cnt++] = alloc_printf(
|
||||||
"-Wl,-mllvm=-load=%s/SanitizerCoverageLTO.so", obj_path);
|
"-Wl,-mllvm=-load=%s/SanitizerCoverageLTO.so", obj_path);
|
||||||
else
|
else
|
||||||
@ -1670,15 +1671,16 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
if (compiler_mode == LTO) {
|
if (compiler_mode == LTO) {
|
||||||
|
|
||||||
if (instrument_mode == 0 || instrument_mode == INSTRUMENT_LTO ||
|
if (instrument_mode == 0 || instrument_mode == INSTRUMENT_LTO ||
|
||||||
instrument_mode == INSTRUMENT_CFG) {
|
instrument_mode == INSTRUMENT_CFG ||
|
||||||
|
instrument_mode == INSTRUMENT_PCGUARD) {
|
||||||
|
|
||||||
lto_mode = 1;
|
lto_mode = 1;
|
||||||
if (!instrument_mode) {
|
// force CFG
|
||||||
|
// if (!instrument_mode) {
|
||||||
|
|
||||||
instrument_mode = INSTRUMENT_CFG;
|
instrument_mode = INSTRUMENT_PCGUARD;
|
||||||
// ptr = instrument_mode_string[instrument_mode];
|
// ptr = instrument_mode_string[instrument_mode];
|
||||||
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
} else if (instrument_mode == INSTRUMENT_LTO ||
|
} else if (instrument_mode == INSTRUMENT_LTO ||
|
||||||
|
|
||||||
|
@ -145,7 +145,8 @@ static void usage(u8 *argv0, int more_help) {
|
|||||||
|
|
||||||
"Other stuff:\n"
|
"Other stuff:\n"
|
||||||
" -M/-S id - distributed mode (see docs/parallel_fuzzing.md)\n"
|
" -M/-S id - distributed mode (see docs/parallel_fuzzing.md)\n"
|
||||||
" -M auto-sets -D and -Z (use -d to disable -D)\n"
|
" -M auto-sets -D, -Z (use -d to disable -D) and no "
|
||||||
|
"trimming\n"
|
||||||
" -F path - sync to a foreign fuzzer queue directory (requires "
|
" -F path - sync to a foreign fuzzer queue directory (requires "
|
||||||
"-M, can\n"
|
"-M, can\n"
|
||||||
" be specified up to %u times)\n"
|
" be specified up to %u times)\n"
|
||||||
@ -502,6 +503,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
afl->sync_id = ck_strdup(optarg);
|
afl->sync_id = ck_strdup(optarg);
|
||||||
afl->skip_deterministic = 0; // force deterministic fuzzing
|
afl->skip_deterministic = 0; // force deterministic fuzzing
|
||||||
afl->old_seed_selection = 1; // force old queue walking seed selection
|
afl->old_seed_selection = 1; // force old queue walking seed selection
|
||||||
|
afl->disable_trim = 1; // disable trimming
|
||||||
|
|
||||||
if ((c = strchr(afl->sync_id, ':'))) {
|
if ((c = strchr(afl->sync_id, ':'))) {
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user