From 6069cac313f4f8f4e696e815d4fe2f8bcaccccf4 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Wed, 14 Apr 2021 18:24:55 +0200 Subject: qemu driver new api --- utils/aflpp_driver/aflpp_qemu_driver_hook.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'utils/aflpp_driver') diff --git a/utils/aflpp_driver/aflpp_qemu_driver_hook.c b/utils/aflpp_driver/aflpp_qemu_driver_hook.c index 823cc42d..d3dd98b0 100644 --- a/utils/aflpp_driver/aflpp_qemu_driver_hook.c +++ b/utils/aflpp_driver/aflpp_qemu_driver_hook.c @@ -1,21 +1,30 @@ +#include "../../qemu_mode/qemuafl/qemuafl/api.h" + #include #include +void afl_persistent_hook(struct x86_64_regs *regs, uint64_t guest_base, + uint8_t *input_buf, uint32_t input_buf_len) { + #define g2h(x) ((void *)((unsigned long)(x) + guest_base)) +#define h2g(x) ((uint64_t)(x)-guest_base) -#define REGS_RDI 7 -#define REGS_RSI 6 + // In this example the register RDI is pointing to the memory location + // of the target buffer, and the length of the input is in RSI. + // This can be seen with a debugger, e.g. gdb (and "disass main") -void afl_persistent_hook(uint64_t *regs, uint64_t guest_base, - uint8_t *input_buf, uint32_t input_len) { + memcpy(g2h(regs->rdi), input_buf, input_buf_len); + regs->rsi = input_buf_len; - memcpy(g2h(regs[REGS_RDI]), input_buf, input_len); - regs[REGS_RSI] = input_len; +#undef g2h +#undef h2g } int afl_persistent_hook_init(void) { + // 1 for shared memory input (faster), 0 for normal input (you have to use + // read(), input_buf will be NULL) return 1; } -- cgit 1.4.1 From f0d300b32a8a5b3adccc8209c151382244135082 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 14 Apr 2021 18:36:22 +0200 Subject: add readme --- utils/aflpp_driver/README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 utils/aflpp_driver/README.md (limited to 'utils/aflpp_driver') diff --git a/utils/aflpp_driver/README.md b/utils/aflpp_driver/README.md new file mode 100644 index 00000000..2c339d12 --- /dev/null +++ b/utils/aflpp_driver/README.md @@ -0,0 +1,25 @@ +# afl++ drivers + +## aflpp_driver + +aflpp_driver is used to compile directly libfuzzer `LLVMFuzzerTestOneInput()` +targets. + +Just do `afl-clang-fast++ -o fuzz fuzzer_harness.cc libAFLDriver.a [plus required linking]`. + +You can also sneakily do this little trick: +If this is the clang compile command to build for libfuzzer: + `clang++ -o fuzz -fsanitize=fuzzer fuzzer_harness.cc -lfoo` +then just switch `clang++` with `afl-clang-fast++` and our compiler will +magically insert libAFLDriver.a :) + + +## aflpp_qemu_driver + +aflpp_qemu_driver is used for libfuzzer `LLVMFuzzerTestOneInput()` targets that +are to be fuzzed in qemu_mode. So we compile them with clang/clang++, without +-fsantize=fuzzer or afl-clang-fast, and link in libAFLQemuDriver.a: + +`clang++ -o fuzz fuzzer_harness.cc libAFLQemuDriver.a [plus required linking]`. + +Then just do `AFL_PRELOAD=/path/to/aflpp_qemu_driver_hook.so afl-fuzz -Q ... -- ./fuzz` -- cgit 1.4.1 From fd8dc1455278bca16e852eb08ddac9a3e466b5c7 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 14 Apr 2021 18:49:02 +0200 Subject: update readme --- utils/aflpp_driver/README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'utils/aflpp_driver') diff --git a/utils/aflpp_driver/README.md b/utils/aflpp_driver/README.md index 2c339d12..01bd10c0 100644 --- a/utils/aflpp_driver/README.md +++ b/utils/aflpp_driver/README.md @@ -22,4 +22,9 @@ are to be fuzzed in qemu_mode. So we compile them with clang/clang++, without `clang++ -o fuzz fuzzer_harness.cc libAFLQemuDriver.a [plus required linking]`. -Then just do `AFL_PRELOAD=/path/to/aflpp_qemu_driver_hook.so afl-fuzz -Q ... -- ./fuzz` + +Then just do (where the name of the binary is `fuzz`): +``` +AFL_QEMU_PERSISTENT_ADDR=0x$(nm fuzz | grep "T LLVMFuzzerTestOneInput" | awk '{print $1}') +AFL_QEMU_PERSISTENT_HOOK=/path/to/aflpp_qemu_driver_hook.so afl-fuzz -Q ... -- ./fuzz` +``` -- cgit 1.4.1 From 4a0e0270adafbc583d491dfad74d9378a4c06bf7 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 14 Apr 2021 22:23:16 +0200 Subject: allow aflpp_qemu_driver_hook.o to fail --- utils/aflpp_driver/GNUmakefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'utils/aflpp_driver') diff --git a/utils/aflpp_driver/GNUmakefile b/utils/aflpp_driver/GNUmakefile index c1a087d7..8ac054a6 100644 --- a/utils/aflpp_driver/GNUmakefile +++ b/utils/aflpp_driver/GNUmakefile @@ -26,17 +26,17 @@ debug: ar ru libAFLDriver.a afl-performance.o aflpp_driver.o aflpp_qemu_driver.o: aflpp_qemu_driver.c - $(LLVM_BINDIR)clang $(CFLAGS) -O0 -funroll-loops -c aflpp_qemu_driver.c + -$(LLVM_BINDIR)clang $(CFLAGS) -O0 -funroll-loops -c aflpp_qemu_driver.c libAFLQemuDriver.a: aflpp_qemu_driver.o - ar ru libAFLQemuDriver.a aflpp_qemu_driver.o - cp -vf libAFLQemuDriver.a ../../ + -ar ru libAFLQemuDriver.a aflpp_qemu_driver.o + -cp -vf libAFLQemuDriver.a ../../ aflpp_qemu_driver_hook.so: aflpp_qemu_driver_hook.o - $(LLVM_BINDIR)clang -shared aflpp_qemu_driver_hook.o -o aflpp_qemu_driver_hook.so + -$(LLVM_BINDIR)clang -shared aflpp_qemu_driver_hook.o -o aflpp_qemu_driver_hook.so aflpp_qemu_driver_hook.o: aflpp_qemu_driver_hook.c - $(LLVM_BINDIR)clang -fPIC $(CFLAGS) -funroll-loops -c aflpp_qemu_driver_hook.c + -$(LLVM_BINDIR)clang -fPIC $(CFLAGS) -funroll-loops -c aflpp_qemu_driver_hook.c test: debug #clang -S -emit-llvm -D_DEBUG=\"1\" -I../../include -Wl,--allow-multiple-definition -funroll-loops -o aflpp_driver_test.ll aflpp_driver_test.c -- cgit 1.4.1 From dde0538b484df627dac14ff030dd09f55c78558e Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 28 Apr 2021 10:59:34 +0200 Subject: nits --- docs/Changelog.md | 1 + qemu_mode/qemuafl | 2 +- utils/aflpp_driver/aflpp_qemu_driver_hook.c | 10 +++++----- utils/qbdi_mode/template.cpp | 2 +- utils/qemu_persistent_hook/read_into_rdi.c | 10 +++++----- 5 files changed, 13 insertions(+), 12 deletions(-) (limited to 'utils/aflpp_driver') diff --git a/docs/Changelog.md b/docs/Changelog.md index 520b13b1..90a1d140 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -10,6 +10,7 @@ sending a mail to . ### Version ++3.13a (development) - frida_mode - new mode that uses frida to fuzz binary-only targets, + it currently supports persistent mode and cmplog. thanks to @WorksButNotTested! - create a fuzzing dictionary with the help of CodeQL thanks to @microsvuln! see utils/autodict_ql diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl index d1ca56b8..d73b0336 160000 --- a/qemu_mode/qemuafl +++ b/qemu_mode/qemuafl @@ -1 +1 @@ -Subproject commit d1ca56b84e78f821406eef28d836918edfc8d610 +Subproject commit d73b0336b451fd034e5f469089fb7ee96c80adf2 diff --git a/utils/aflpp_driver/aflpp_qemu_driver_hook.c b/utils/aflpp_driver/aflpp_qemu_driver_hook.c index d3dd98b0..2979fadc 100644 --- a/utils/aflpp_driver/aflpp_qemu_driver_hook.c +++ b/utils/aflpp_driver/aflpp_qemu_driver_hook.c @@ -3,12 +3,12 @@ #include #include -void afl_persistent_hook(struct x86_64_regs *regs, uint64_t guest_base, - uint8_t *input_buf, uint32_t input_buf_len) { - #define g2h(x) ((void *)((unsigned long)(x) + guest_base)) #define h2g(x) ((uint64_t)(x)-guest_base) +void afl_persistent_hook(struct x86_64_regs *regs, uint64_t guest_base, + uint8_t *input_buf, uint32_t input_buf_len) { + // In this example the register RDI is pointing to the memory location // of the target buffer, and the length of the input is in RSI. // This can be seen with a debugger, e.g. gdb (and "disass main") @@ -16,11 +16,11 @@ void afl_persistent_hook(struct x86_64_regs *regs, uint64_t guest_base, memcpy(g2h(regs->rdi), input_buf, input_buf_len); regs->rsi = input_buf_len; +} + #undef g2h #undef h2g -} - int afl_persistent_hook_init(void) { // 1 for shared memory input (faster), 0 for normal input (you have to use diff --git a/utils/qbdi_mode/template.cpp b/utils/qbdi_mode/template.cpp index 888ecb58..182a014b 100755 --- a/utils/qbdi_mode/template.cpp +++ b/utils/qbdi_mode/template.cpp @@ -25,7 +25,7 @@ #if (defined(__x86_64__) || defined(__i386__)) && defined(AFL_QEMU_NOT_ZERO) #define INC_AFL_AREA(loc) \ asm volatile( \ - "addb $1, (%0, %1, 1)\n" \ + "addb $1, (%0, %1, 1)\n" \ "adcb $0, (%0, %1, 1)\n" \ : /* no out */ \ : "r"(afl_area_ptr), "r"(loc) \ diff --git a/utils/qemu_persistent_hook/read_into_rdi.c b/utils/qemu_persistent_hook/read_into_rdi.c index c1c6642f..14b2ed85 100644 --- a/utils/qemu_persistent_hook/read_into_rdi.c +++ b/utils/qemu_persistent_hook/read_into_rdi.c @@ -3,12 +3,12 @@ #include #include -void afl_persistent_hook(struct x86_64_regs *regs, uint64_t guest_base, - uint8_t *input_buf, uint32_t input_buf_len) { - #define g2h(x) ((void *)((unsigned long)(x) + guest_base)) #define h2g(x) ((uint64_t)(x)-guest_base) +void afl_persistent_hook(struct x86_64_regs *regs, uint64_t guest_base, + uint8_t *input_buf, uint32_t input_buf_len) { + // In this example the register RDI is pointing to the memory location // of the target buffer, and the length of the input is in RSI. // This can be seen with a debugger, e.g. gdb (and "disass main") @@ -19,11 +19,11 @@ void afl_persistent_hook(struct x86_64_regs *regs, uint64_t guest_base, memcpy(g2h(regs->rdi), input_buf, input_buf_len); regs->rsi = input_buf_len; +} + #undef g2h #undef h2g -} - int afl_persistent_hook_init(void) { // 1 for shared memory input (faster), 0 for normal input (you have to use -- cgit 1.4.1 From c9d066038fe0bbf8e0ab0a481ca320ca1c31b1bf Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 30 Apr 2021 10:27:43 +0200 Subject: fix PCGUARD, build aflpp_driver with fPIC --- docs/Changelog.md | 5 +- instrumentation/SanitizerCoverageLTO.so.cc | 15 ++-- instrumentation/SanitizerCoveragePCGUARD.so.cc | 102 +++++++++++-------------- utils/afl_proxy/afl-proxy.c | 6 ++ utils/aflpp_driver/GNUmakefile | 4 +- 5 files changed, 64 insertions(+), 68 deletions(-) (limited to 'utils/aflpp_driver') diff --git a/docs/Changelog.md b/docs/Changelog.md index 90a1d140..5c0f2a9e 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -32,10 +32,13 @@ sending a mail to . afl++ ignores these and uses them for splicing instead. - afl-cc: - We do not support llvm versions prior 6.0 anymore + - Fix for -pie compiled binaries with default afl-clang-fast PCGUARD - Leak Sanitizer (AFL_USE_LSAN) added by Joshua Rogers, thanks! - Removed InsTrim instrumentation as it is not as good as PCGUARD - Removed automatic linking with -lc++ for LTO mode - - utils/aflpp_driver/aflpp_qemu_driver_hook fixed to work with qemu mode + - utils/aflpp_driver: + - aflpp_qemu_driver_hook fixed to work with qemu_mode + - aflpp_driver now compiled with -fPIC - add -d (add dead fuzzer stats) to afl-whatsup ### Version ++3.12c (release) diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index 6dd390e6..2f4337eb 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -60,15 +60,14 @@ using namespace llvm; #define DEBUG_TYPE "sancov" -static const char *const SanCovTracePCIndirName = - "__sanitizer_cov_trace_pc_indir"; -static const char *const SanCovTracePCName = "__sanitizer_cov_trace_pc"; -// static const char *const SanCovTracePCGuardName = +const char SanCovTracePCIndirName[] = "__sanitizer_cov_trace_pc_indir"; +const char SanCovTracePCName[] = "__sanitizer_cov_trace_pc"; +// const char SanCovTracePCGuardName = // "__sanitizer_cov_trace_pc_guard"; -static const char *const SanCovGuardsSectionName = "sancov_guards"; -static const char *const SanCovCountersSectionName = "sancov_cntrs"; -static const char *const SanCovBoolFlagSectionName = "sancov_bools"; -static const char *const SanCovPCsSectionName = "sancov_pcs"; +const char SanCovGuardsSectionName[] = "sancov_guards"; +const char SanCovCountersSectionName[] = "sancov_cntrs"; +const char SanCovBoolFlagSectionName[] = "sancov_bools"; +const char SanCovPCsSectionName[] = "sancov_pcs"; static cl::opt ClCoverageLevel( "lto-coverage-level", diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index 09cda9e2..8878d3b1 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -52,49 +52,39 @@ using namespace llvm; #define DEBUG_TYPE "sancov" -static const char *const SanCovTracePCIndirName = - "__sanitizer_cov_trace_pc_indir"; -static const char *const SanCovTracePCName = "__sanitizer_cov_trace_pc"; -static const char *const SanCovTraceCmp1 = "__sanitizer_cov_trace_cmp1"; -static const char *const SanCovTraceCmp2 = "__sanitizer_cov_trace_cmp2"; -static const char *const SanCovTraceCmp4 = "__sanitizer_cov_trace_cmp4"; -static const char *const SanCovTraceCmp8 = "__sanitizer_cov_trace_cmp8"; -static const char *const SanCovTraceConstCmp1 = - "__sanitizer_cov_trace_const_cmp1"; -static const char *const SanCovTraceConstCmp2 = - "__sanitizer_cov_trace_const_cmp2"; -static const char *const SanCovTraceConstCmp4 = - "__sanitizer_cov_trace_const_cmp4"; -static const char *const SanCovTraceConstCmp8 = - "__sanitizer_cov_trace_const_cmp8"; -static const char *const SanCovTraceDiv4 = "__sanitizer_cov_trace_div4"; -static const char *const SanCovTraceDiv8 = "__sanitizer_cov_trace_div8"; -static const char *const SanCovTraceGep = "__sanitizer_cov_trace_gep"; -static const char *const SanCovTraceSwitchName = "__sanitizer_cov_trace_switch"; -static const char *const SanCovModuleCtorTracePcGuardName = +const char SanCovTracePCIndirName[] = "__sanitizer_cov_trace_pc_indir"; +const char SanCovTracePCName[] = "__sanitizer_cov_trace_pc"; +const char SanCovTraceCmp1[] = "__sanitizer_cov_trace_cmp1"; +const char SanCovTraceCmp2[] = "__sanitizer_cov_trace_cmp2"; +const char SanCovTraceCmp4[] = "__sanitizer_cov_trace_cmp4"; +const char SanCovTraceCmp8[] = "__sanitizer_cov_trace_cmp8"; +const char SanCovTraceConstCmp1[] = "__sanitizer_cov_trace_const_cmp1"; +const char SanCovTraceConstCmp2[] = "__sanitizer_cov_trace_const_cmp2"; +const char SanCovTraceConstCmp4[] = "__sanitizer_cov_trace_const_cmp4"; +const char SanCovTraceConstCmp8[] = "__sanitizer_cov_trace_const_cmp8"; +const char SanCovTraceDiv4[] = "__sanitizer_cov_trace_div4"; +const char SanCovTraceDiv8[] = "__sanitizer_cov_trace_div8"; +const char SanCovTraceGep[] = "__sanitizer_cov_trace_gep"; +const char SanCovTraceSwitchName[] = "__sanitizer_cov_trace_switch"; +const char SanCovModuleCtorTracePcGuardName[] = "sancov.module_ctor_trace_pc_guard"; -static const char *const SanCovModuleCtor8bitCountersName = +const char SanCovModuleCtor8bitCountersName[] = "sancov.module_ctor_8bit_counters"; -static const char *const SanCovModuleCtorBoolFlagName = - "sancov.module_ctor_bool_flag"; +const char SanCovModuleCtorBoolFlagName[] = "sancov.module_ctor_bool_flag"; static const uint64_t SanCtorAndDtorPriority = 2; -static const char *const SanCovTracePCGuardName = - "__sanitizer_cov_trace_pc_guard"; -static const char *const SanCovTracePCGuardInitName = - "__sanitizer_cov_trace_pc_guard_init"; -static const char *const SanCov8bitCountersInitName = - "__sanitizer_cov_8bit_counters_init"; -static const char *const SanCovBoolFlagInitName = - "__sanitizer_cov_bool_flag_init"; -static const char *const SanCovPCsInitName = "__sanitizer_cov_pcs_init"; +const char SanCovTracePCGuardName[] = "__sanitizer_cov_trace_pc_guard"; +const char SanCovTracePCGuardInitName[] = "__sanitizer_cov_trace_pc_guard_init"; +const char SanCov8bitCountersInitName[] = "__sanitizer_cov_8bit_counters_init"; +const char SanCovBoolFlagInitName[] = "__sanitizer_cov_bool_flag_init"; +const char SanCovPCsInitName[] = "__sanitizer_cov_pcs_init"; -static const char *const SanCovGuardsSectionName = "sancov_guards"; -static const char *const SanCovCountersSectionName = "sancov_cntrs"; -static const char *const SanCovBoolFlagSectionName = "sancov_bools"; -static const char *const SanCovPCsSectionName = "sancov_pcs"; +const char SanCovGuardsSectionName[] = "sancov_guards"; +const char SanCovCountersSectionName[] = "sancov_cntrs"; +const char SanCovBoolFlagSectionName[] = "sancov_bools"; +const char SanCovPCsSectionName[] = "sancov_pcs"; -static const char *const SanCovLowestStackName = "__sancov_lowest_stack"; +const char SanCovLowestStackName[] = "__sancov_lowest_stack"; static char *skip_nozero; @@ -320,12 +310,12 @@ std::pair ModuleSanitizerCoverage::CreateSecStartEnd( Module &M, const char *Section, Type *Ty) { GlobalVariable *SecStart = new GlobalVariable( - M, Ty->getPointerElementType(), false, GlobalVariable::ExternalLinkage, - nullptr, getSectionStart(Section)); + M, Ty->getPointerElementType(), false, + GlobalVariable::ExternalWeakLinkage, nullptr, getSectionStart(Section)); SecStart->setVisibility(GlobalValue::HiddenVisibility); GlobalVariable *SecEnd = new GlobalVariable( - M, Ty->getPointerElementType(), false, GlobalVariable::ExternalLinkage, - nullptr, getSectionEnd(Section)); + M, Ty->getPointerElementType(), false, + GlobalVariable::ExternalWeakLinkage, nullptr, getSectionEnd(Section)); SecEnd->setVisibility(GlobalValue::HiddenVisibility); IRBuilder<> IRB(M.getContext()); if (!TargetTriple.isOSBinFormatCOFF()) @@ -573,7 +563,7 @@ bool ModuleSanitizerCoverage::instrumentModule( } // True if block has successors and it dominates all of them. -static bool isFullDominator(const BasicBlock *BB, const DominatorTree *DT) { +bool isFullDominator(const BasicBlock *BB, const DominatorTree *DT) { if (succ_begin(BB) == succ_end(BB)) return false; @@ -588,8 +578,7 @@ static bool isFullDominator(const BasicBlock *BB, const DominatorTree *DT) { } // True if block has predecessors and it postdominates all of them. -static bool isFullPostDominator(const BasicBlock * BB, - const PostDominatorTree *PDT) { +bool isFullPostDominator(const BasicBlock *BB, const PostDominatorTree *PDT) { if (pred_begin(BB) == pred_end(BB)) return false; @@ -603,10 +592,10 @@ static bool isFullPostDominator(const BasicBlock * BB, } -static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB, - const DominatorTree * DT, - const PostDominatorTree * PDT, - const SanitizerCoverageOptions &Options) { +bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB, + const DominatorTree * DT, + const PostDominatorTree * PDT, + const SanitizerCoverageOptions &Options) { // Don't insert coverage for blocks containing nothing but unreachable: we // will never call __sanitizer_cov() for them, so counting them in @@ -636,8 +625,7 @@ static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB, // A twist here is that we treat From->To as a backedge if // * To dominates From or // * To->UniqueSuccessor dominates From -static bool IsBackEdge(BasicBlock *From, BasicBlock *To, - const DominatorTree *DT) { +bool IsBackEdge(BasicBlock *From, BasicBlock *To, const DominatorTree *DT) { if (DT->dominates(To, From)) return true; if (auto Next = To->getUniqueSuccessor()) @@ -651,8 +639,8 @@ static bool IsBackEdge(BasicBlock *From, BasicBlock *To, // // Note that Cmp pruning is controlled by the same flag as the // BB pruning. -static bool IsInterestingCmp(ICmpInst *CMP, const DominatorTree *DT, - const SanitizerCoverageOptions &Options) { +bool IsInterestingCmp(ICmpInst *CMP, const DominatorTree *DT, + const SanitizerCoverageOptions &Options) { if (!Options.NoPrune) if (CMP->hasOneUse()) @@ -1046,7 +1034,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, if (IsEntryBB) { - // Keep static allocas and llvm.localescape calls in the entry block. Even + // Keep allocas and llvm.localescape calls in the entry block. Even // if we aren't splitting the block, it's nice for allocas to be before // calls. IP = PrepareToSplitEntryBlock(BB, IP); @@ -1221,17 +1209,17 @@ ModulePass *llvm::createModuleSanitizerCoverageLegacyPassPass( } -static void registerPCGUARDPass(const PassManagerBuilder &, - legacy::PassManagerBase &PM) { +void registerPCGUARDPass(const PassManagerBuilder &, + legacy::PassManagerBase &PM) { auto p = new ModuleSanitizerCoverageLegacyPass(); PM.add(p); } -static RegisterStandardPasses RegisterCompTransPass( +RegisterStandardPasses RegisterCompTransPass( PassManagerBuilder::EP_OptimizerLast, registerPCGUARDPass); -static RegisterStandardPasses RegisterCompTransPass0( +RegisterStandardPasses RegisterCompTransPass0( PassManagerBuilder::EP_EnabledOnOptLevel0, registerPCGUARDPass); diff --git a/utils/afl_proxy/afl-proxy.c b/utils/afl_proxy/afl-proxy.c index aa7a361a..a80d8a0b 100644 --- a/utils/afl_proxy/afl-proxy.c +++ b/utils/afl_proxy/afl-proxy.c @@ -70,12 +70,18 @@ static void __afl_map_shm(void) { char *id_str = getenv(SHM_ENV_VAR); char *ptr; + + /* NOTE TODO BUG FIXME: if you want to supply a variable sized map then + uncomment the following: */ + + /* if ((ptr = getenv("AFL_MAP_SIZE")) != NULL) { u32 val = atoi(ptr); if (val > 0) __afl_map_size = val; } + */ if (__afl_map_size > MAP_SIZE) { diff --git a/utils/aflpp_driver/GNUmakefile b/utils/aflpp_driver/GNUmakefile index 8ac054a6..556f6420 100644 --- a/utils/aflpp_driver/GNUmakefile +++ b/utils/aflpp_driver/GNUmakefile @@ -7,7 +7,7 @@ ifneq "" "$(LLVM_BINDIR)" LLVM_BINDIR := $(LLVM_BINDIR)/ endif -CFLAGS := -O3 -funroll-loops -g +CFLAGS := -O3 -funroll-loops -g -fPIC all: libAFLDriver.a libAFLQemuDriver.a aflpp_qemu_driver_hook.so @@ -36,7 +36,7 @@ aflpp_qemu_driver_hook.so: aflpp_qemu_driver_hook.o -$(LLVM_BINDIR)clang -shared aflpp_qemu_driver_hook.o -o aflpp_qemu_driver_hook.so aflpp_qemu_driver_hook.o: aflpp_qemu_driver_hook.c - -$(LLVM_BINDIR)clang -fPIC $(CFLAGS) -funroll-loops -c aflpp_qemu_driver_hook.c + -$(LLVM_BINDIR)clang $(CFLAGS) -funroll-loops -c aflpp_qemu_driver_hook.c test: debug #clang -S -emit-llvm -D_DEBUG=\"1\" -I../../include -Wl,--allow-multiple-definition -funroll-loops -o aflpp_driver_test.ll aflpp_driver_test.c -- cgit 1.4.1 From f4cc718fdc4571f56280a1efad3645125bee2154 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 30 Apr 2021 13:56:23 +0200 Subject: let aflpp_qemu_driver_hook.so build fail gracefully --- utils/aflpp_driver/GNUmakefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'utils/aflpp_driver') diff --git a/utils/aflpp_driver/GNUmakefile b/utils/aflpp_driver/GNUmakefile index 556f6420..ad99b893 100644 --- a/utils/aflpp_driver/GNUmakefile +++ b/utils/aflpp_driver/GNUmakefile @@ -33,10 +33,10 @@ libAFLQemuDriver.a: aflpp_qemu_driver.o -cp -vf libAFLQemuDriver.a ../../ aflpp_qemu_driver_hook.so: aflpp_qemu_driver_hook.o - -$(LLVM_BINDIR)clang -shared aflpp_qemu_driver_hook.o -o aflpp_qemu_driver_hook.so + -test -e aflpp_qemu_driver_hook.o && $(LLVM_BINDIR)clang -shared aflpp_qemu_driver_hook.o -o aflpp_qemu_driver_hook.so || echo "Note: Optional aflpp_qemu_driver_hook.so not built." aflpp_qemu_driver_hook.o: aflpp_qemu_driver_hook.c - -$(LLVM_BINDIR)clang $(CFLAGS) -funroll-loops -c aflpp_qemu_driver_hook.c + -test -e ../../qemu_mode/qemuafl/qemuafl/api.h && $(LLVM_BINDIR)clang $(CFLAGS) -funroll-loops -c aflpp_qemu_driver_hook.c || echo "Note: Optional aflpp_qemu_driver_hook.o not built." test: debug #clang -S -emit-llvm -D_DEBUG=\"1\" -I../../include -Wl,--allow-multiple-definition -funroll-loops -o aflpp_driver_test.ll aflpp_driver_test.c -- cgit 1.4.1 From d2e85cce5048f36aef27a26d907670dda61837e4 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 30 May 2021 00:36:56 +0200 Subject: afl-cmin help fix, aflpp_driver - + @@ support --- afl-cmin | 8 ++--- frida_mode/src/instrument/instrument_debug.c | 1 - utils/aflpp_driver/README.md | 6 ++++ utils/aflpp_driver/aflpp_driver.c | 44 +++++++++++++++++++++------- 4 files changed, 44 insertions(+), 15 deletions(-) (limited to 'utils/aflpp_driver') diff --git a/afl-cmin b/afl-cmin index adcbb221..9fa63ec6 100755 --- a/afl-cmin +++ b/afl-cmin @@ -119,13 +119,13 @@ function usage() { "Environment variables used:\n" \ "AFL_ALLOW_TMP: allow unsafe use of input/output directories under {/var}/tmp\n" \ "AFL_CRASH_EXITCODE: optional child exit code to be interpreted as crash\n" \ -"AFL_FORKSRV_INIT_TMOUT: time the fuzzer waits for the target to come up, initially\n" \ +"AFL_FORKSRV_INIT_TMOUT: time the fuzzer waits for the forkserver to come up\n" \ "AFL_KEEP_TRACES: leave the temporary /.traces directory\n" \ -"AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc. (default: SIGKILL)\n" -"AFL_PATH: path for the afl-showmap binary if not found anywhere else\n" \ +"AFL_KILL_SIGNAL: Signal delivered to child processes on timeout (default: SIGKILL)\n" \ +"AFL_PATH: path for the afl-showmap binary if not found anywhere in PATH\n" \ "AFL_PRINT_FILENAMES: If set, the filename currently processed will be " \ "printed to stdout\n" \ -"AFL_SKIP_BIN_CHECK: skip check for target binary\n" +"AFL_SKIP_BIN_CHECK: skip afl instrumentation checks for target binary\n" exit 1 } diff --git a/frida_mode/src/instrument/instrument_debug.c b/frida_mode/src/instrument/instrument_debug.c index 124843d8..be72ef89 100644 --- a/frida_mode/src/instrument/instrument_debug.c +++ b/frida_mode/src/instrument/instrument_debug.c @@ -20,7 +20,6 @@ static void instrument_debug(char *format, ...) { int len; va_start(ap, format); - ret = vsnprintf(buffer, sizeof(buffer) - 1, format, ap); va_end(ap); diff --git a/utils/aflpp_driver/README.md b/utils/aflpp_driver/README.md index 01bd10c0..f03c2fe3 100644 --- a/utils/aflpp_driver/README.md +++ b/utils/aflpp_driver/README.md @@ -13,6 +13,12 @@ If this is the clang compile command to build for libfuzzer: then just switch `clang++` with `afl-clang-fast++` and our compiler will magically insert libAFLDriver.a :) +To use shared-memory testcases, you need nothing to do. +To use stdin testcases give `-` as the only command line parameter. +To use file input testcases give `@@` as the only command line parameter. + +IMPORTANT: if you use `afl-cmin` or `afl-cmin.bash` then either pass `-` +or `@@` as command line parameters. ## aflpp_qemu_driver diff --git a/utils/aflpp_driver/aflpp_driver.c b/utils/aflpp_driver/aflpp_driver.c index ad781e64..c094c425 100644 --- a/utils/aflpp_driver/aflpp_driver.c +++ b/utils/aflpp_driver/aflpp_driver.c @@ -174,11 +174,17 @@ size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize) { static int ExecuteFilesOnyByOne(int argc, char **argv) { unsigned char *buf = (unsigned char *)malloc(MAX_FILE); + for (int i = 1; i < argc; i++) { - int fd = open(argv[i], O_RDONLY); - if (fd == -1) continue; + int fd = 0; + + if (strcmp(argv[i], "-") != 0) { fd = open(argv[i], O_RDONLY); } + + if (fd == -1) { continue; } + ssize_t length = read(fd, buf, MAX_FILE); + if (length > 0) { printf("Reading %zu bytes from %s\n", length, argv[i]); @@ -187,7 +193,7 @@ static int ExecuteFilesOnyByOne(int argc, char **argv) { } - close(fd); + if (fd > 0) { close(fd); } } @@ -199,15 +205,19 @@ static int ExecuteFilesOnyByOne(int argc, char **argv) { int main(int argc, char **argv) { printf( - "======================= INFO =========================\n" + "============================== INFO ================================\n" "This binary is built for afl++.\n" + "To use with afl-cmin or afl-cmin.bash pass '-' as single command line " + "option\n" "To run the target function on individual input(s) execute this:\n" " %s INPUT_FILE1 [INPUT_FILE2 ... ]\n" "To fuzz with afl-fuzz execute this:\n" " afl-fuzz [afl-flags] -- %s [-N]\n" "afl-fuzz will run N iterations before re-spawning the process (default: " "INT_MAX)\n" - "======================================================\n", + "For stdin input processing, pass '-' as single command line option.\n" + "For file input processing, pass '@@' as single command line option.\n" + "===================================================================\n", argv[0], argv[0]); if (getenv("AFL_GDB")) { @@ -237,22 +247,35 @@ int main(int argc, char **argv) { memcpy(dummy_input, (void *)AFL_PERSISTENT, sizeof(AFL_PERSISTENT)); memcpy(dummy_input + 32, (void *)AFL_DEFER_FORKSVR, sizeof(AFL_DEFER_FORKSVR)); + int N = INT_MAX; - if (argc == 2 && argv[1][0] == '-') + + if (argc == 2 && !strcmp(argv[1], "-")) { + + __afl_sharedmem_fuzzing = 0; + __afl_manual_init(); + return ExecuteFilesOnyByOne(argc, argv); + + } else if (argc == 2 && argv[1][0] == '-') { + N = atoi(argv[1] + 1); - else if (argc == 2 && (N = atoi(argv[1])) > 0) + + } else if (argc == 2 && (N = atoi(argv[1])) > 0) { + printf("WARNING: using the deprecated call style `%s %d`\n", argv[0], N); - else if (argc > 1) { + + } else if (argc > 1) { __afl_sharedmem_fuzzing = 0; - __afl_manual_init(); + + if (argc == 2) { __afl_manual_init(); } + return ExecuteFilesOnyByOne(argc, argv); } assert(N > 0); - // if (!getenv("AFL_DRIVER_DONT_DEFER")) __afl_manual_init(); // Call LLVMFuzzerTestOneInput here so that coverage caused by initialization @@ -271,6 +294,7 @@ int main(int argc, char **argv) { fprintf(stderr, "%02x", __afl_fuzz_ptr[i]); fprintf(stderr, "\n"); #endif + if (*__afl_fuzz_len) { num_runs++; -- cgit 1.4.1 From 0c3feba3f6b3a517b21f9e96fa5e0758e959dec1 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 14 Jun 2021 22:58:08 +0200 Subject: aflppdriver help output --- utils/aflpp_driver/aflpp_driver.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'utils/aflpp_driver') diff --git a/utils/aflpp_driver/aflpp_driver.c b/utils/aflpp_driver/aflpp_driver.c index c094c425..ff42f3b9 100644 --- a/utils/aflpp_driver/aflpp_driver.c +++ b/utils/aflpp_driver/aflpp_driver.c @@ -204,21 +204,23 @@ static int ExecuteFilesOnyByOne(int argc, char **argv) { int main(int argc, char **argv) { - printf( - "============================== INFO ================================\n" - "This binary is built for afl++.\n" - "To use with afl-cmin or afl-cmin.bash pass '-' as single command line " - "option\n" - "To run the target function on individual input(s) execute this:\n" - " %s INPUT_FILE1 [INPUT_FILE2 ... ]\n" - "To fuzz with afl-fuzz execute this:\n" - " afl-fuzz [afl-flags] -- %s [-N]\n" - "afl-fuzz will run N iterations before re-spawning the process (default: " - "INT_MAX)\n" - "For stdin input processing, pass '-' as single command line option.\n" - "For file input processing, pass '@@' as single command line option.\n" - "===================================================================\n", - argv[0], argv[0]); + if (argc < 2 || strncmp(argv[1], "-h", 2) == 0) + printf( + "============================== INFO ================================\n" + "This binary is built for afl++.\n" + "To use with afl-cmin or afl-cmin.bash pass '-' as single command line " + "option\n" + "To run the target function on individual input(s) execute this:\n" + " %s INPUT_FILE1 [INPUT_FILE2 ... ]\n" + "To fuzz with afl-fuzz execute this:\n" + " afl-fuzz [afl-flags] -- %s [-N]\n" + "afl-fuzz will run N iterations before re-spawning the process " + "(default: " + "INT_MAX)\n" + "For stdin input processing, pass '-' as single command line option.\n" + "For file input processing, pass '@@' as single command line option.\n" + "===================================================================\n", + argv[0], argv[0]); if (getenv("AFL_GDB")) { -- cgit 1.4.1 From 8dbe87bdf6c848088cd51923e445b92b9f839956 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 7 Jul 2021 16:22:57 +0200 Subject: print warning for libfuzzer qemu driver --- utils/aflpp_driver/aflpp_qemu_driver.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'utils/aflpp_driver') diff --git a/utils/aflpp_driver/aflpp_qemu_driver.c b/utils/aflpp_driver/aflpp_qemu_driver.c index 79de5af6..efa80bca 100644 --- a/utils/aflpp_driver/aflpp_qemu_driver.c +++ b/utils/aflpp_driver/aflpp_qemu_driver.c @@ -27,6 +27,9 @@ int main(int argc, char **argv) { } else { + fprintf(stderr + "Using shared-memory testcases. To read via stdin, set " + "AFL_QEMU_DRIVER_NO_HOOK=1.\n"); uint8_t dummy_input[1024000] = {0}; LLVMFuzzerTestOneInput(dummy_input, 1); -- cgit 1.4.1 From f4b975d6ad6f7e55c5c4e290ab85e18957cad0c3 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 7 Jul 2021 22:22:06 +0200 Subject: update doc --- utils/aflpp_driver/README.md | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'utils/aflpp_driver') diff --git a/utils/aflpp_driver/README.md b/utils/aflpp_driver/README.md index f03c2fe3..4ca59776 100644 --- a/utils/aflpp_driver/README.md +++ b/utils/aflpp_driver/README.md @@ -22,6 +22,8 @@ or `@@` as command line parameters. ## aflpp_qemu_driver +Note that you can use the driver too for frida_mode (`-O`). + aflpp_qemu_driver is used for libfuzzer `LLVMFuzzerTestOneInput()` targets that are to be fuzzed in qemu_mode. So we compile them with clang/clang++, without -fsantize=fuzzer or afl-clang-fast, and link in libAFLQemuDriver.a: @@ -34,3 +36,8 @@ Then just do (where the name of the binary is `fuzz`): AFL_QEMU_PERSISTENT_ADDR=0x$(nm fuzz | grep "T LLVMFuzzerTestOneInput" | awk '{print $1}') AFL_QEMU_PERSISTENT_HOOK=/path/to/aflpp_qemu_driver_hook.so afl-fuzz -Q ... -- ./fuzz` ``` + +if you use afl-cmin or `afl-showmap -C` with the aflpp_qemu_driver you need to +set the set same AFL_QEMU_... (or AFL_FRIDA_...) environment variables. +If you want to use afl-showmap (without -C) or afl-cmin.bash then you may not +set these environment variables and rather set `AFL_QEMU_DRIVER_NO_HOOK=1`. -- cgit 1.4.1 From 6d878a375d91003fb57d7f82a79acfbaa226abb5 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 8 Jul 2021 12:29:05 +0200 Subject: fix qemu driver --- utils/aflpp_driver/aflpp_qemu_driver.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'utils/aflpp_driver') diff --git a/utils/aflpp_driver/aflpp_qemu_driver.c b/utils/aflpp_driver/aflpp_qemu_driver.c index efa80bca..99a4c9a8 100644 --- a/utils/aflpp_driver/aflpp_qemu_driver.c +++ b/utils/aflpp_driver/aflpp_qemu_driver.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -27,7 +28,7 @@ int main(int argc, char **argv) { } else { - fprintf(stderr + fprintf(stderr, "Using shared-memory testcases. To read via stdin, set " "AFL_QEMU_DRIVER_NO_HOOK=1.\n"); uint8_t dummy_input[1024000] = {0}; -- cgit 1.4.1 From 4fe572b80f76ff0b0e916b639d1e04d5af48b157 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 14 Jul 2021 12:24:29 +0200 Subject: always build aflpp driver --- GNUmakefile | 3 +-- docs/Changelog.md | 1 + utils/aflpp_driver/GNUmakefile | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'utils/aflpp_driver') diff --git a/GNUmakefile b/GNUmakefile index 53cc0537..7a1ba88a 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -306,6 +306,7 @@ endif .PHONY: all all: test_x86 test_shm test_python ready $(PROGS) afl-as llvm gcc_plugin test_build all_done + -$(MAKE) -C utils/aflpp_driver .PHONY: llvm llvm: @@ -597,7 +598,6 @@ distrib: all -$(MAKE) -f GNUmakefile.gcc_plugin $(MAKE) -C utils/libdislocator $(MAKE) -C utils/libtokencap - -$(MAKE) -C utils/aflpp_driver $(MAKE) -C utils/afl_network_proxy $(MAKE) -C utils/socket_fuzzing $(MAKE) -C utils/argv_fuzzing @@ -622,7 +622,6 @@ source-only: all -$(MAKE) -f GNUmakefile.gcc_plugin $(MAKE) -C utils/libdislocator $(MAKE) -C utils/libtokencap - -$(MAKE) -C utils/aflpp_driver %.8: % @echo .TH $* 8 $(BUILD_DATE) "afl++" > $@ diff --git a/docs/Changelog.md b/docs/Changelog.md index 705daa40..29af44ab 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -36,6 +36,7 @@ sending a mail to . - fix timeout handling - add forkserver support for better performance - ensure afl-compiler-rt is built for gcc_module + - always build aflpp_driver for libfuzzer harnesses - added `AFL_NO_FORKSRV` env variable support to afl-cmin, afl-tmin, and afl-showmap, by @jhertz - removed outdated documents, improved existing documentation diff --git a/utils/aflpp_driver/GNUmakefile b/utils/aflpp_driver/GNUmakefile index ad99b893..c282a9f3 100644 --- a/utils/aflpp_driver/GNUmakefile +++ b/utils/aflpp_driver/GNUmakefile @@ -15,28 +15,28 @@ aflpp_driver.o: aflpp_driver.c -$(LLVM_BINDIR)clang -I. -I../../include $(CFLAGS) -c aflpp_driver.c libAFLDriver.a: aflpp_driver.o - ar ru libAFLDriver.a aflpp_driver.o - cp -vf libAFLDriver.a ../../ + @ar rc libAFLDriver.a aflpp_driver.o + @cp -vf libAFLDriver.a ../../ debug: $(LLVM_BINDIR)clang -Wno-deprecated -I../../include $(CFLAGS) -D_DEBUG=\"1\" -c -o afl-performance.o ../../src/afl-performance.c $(LLVM_BINDIR)clang -I../../include -D_DEBUG=\"1\" -g -funroll-loops -c aflpp_driver.c #$(LLVM_BINDIR)clang -S -emit-llvm -Wno-deprecated -I../../include $(CFLAGS) -D_DEBUG=\"1\" -c -o afl-performance.ll ../../src/afl-performance.c #$(LLVM_BINDIR)clang -S -emit-llvm -I../../include -D_DEBUG=\"1\" -g -funroll-loops -c aflpp_driver.c - ar ru libAFLDriver.a afl-performance.o aflpp_driver.o + ar rc libAFLDriver.a afl-performance.o aflpp_driver.o aflpp_qemu_driver.o: aflpp_qemu_driver.c -$(LLVM_BINDIR)clang $(CFLAGS) -O0 -funroll-loops -c aflpp_qemu_driver.c libAFLQemuDriver.a: aflpp_qemu_driver.o - -ar ru libAFLQemuDriver.a aflpp_qemu_driver.o - -cp -vf libAFLQemuDriver.a ../../ + @-ar rc libAFLQemuDriver.a aflpp_qemu_driver.o + @-cp -vf libAFLQemuDriver.a ../../ aflpp_qemu_driver_hook.so: aflpp_qemu_driver_hook.o - -test -e aflpp_qemu_driver_hook.o && $(LLVM_BINDIR)clang -shared aflpp_qemu_driver_hook.o -o aflpp_qemu_driver_hook.so || echo "Note: Optional aflpp_qemu_driver_hook.so not built." + @-test -e aflpp_qemu_driver_hook.o && $(LLVM_BINDIR)clang -shared aflpp_qemu_driver_hook.o -o aflpp_qemu_driver_hook.so || echo "Note: Optional aflpp_qemu_driver_hook.so not built." aflpp_qemu_driver_hook.o: aflpp_qemu_driver_hook.c - -test -e ../../qemu_mode/qemuafl/qemuafl/api.h && $(LLVM_BINDIR)clang $(CFLAGS) -funroll-loops -c aflpp_qemu_driver_hook.c || echo "Note: Optional aflpp_qemu_driver_hook.o not built." + @-test -e ../../qemu_mode/qemuafl/qemuafl/api.h && $(LLVM_BINDIR)clang $(CFLAGS) -funroll-loops -c aflpp_qemu_driver_hook.c || echo "Note: Optional aflpp_qemu_driver_hook.o not built." test: debug #clang -S -emit-llvm -D_DEBUG=\"1\" -I../../include -Wl,--allow-multiple-definition -funroll-loops -o aflpp_driver_test.ll aflpp_driver_test.c -- cgit 1.4.1