From 996986bed5f2dd97a3d76f584d8eddc1203f8396 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sat, 5 Sep 2020 12:11:48 +0200 Subject: first batch of changes --- instrumentation/afl-llvm-dict2file.so.cc | 599 +++++++++++++++++++++++++++++++ 1 file changed, 599 insertions(+) create mode 100644 instrumentation/afl-llvm-dict2file.so.cc (limited to 'instrumentation/afl-llvm-dict2file.so.cc') diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc new file mode 100644 index 00000000..e87ecce8 --- /dev/null +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -0,0 +1,599 @@ +/* + american fuzzy lop++ - LLVM LTO instrumentation pass + ---------------------------------------------------- + + Written by Marc Heuse + + Copyright 2019-2020 AFLplusplus Project. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at: + + http://www.apache.org/licenses/LICENSE-2.0 + + This library is plugged into LLVM when invoking clang through afl-clang-lto. + + */ + +#define AFL_LLVM_PASS + +#include "config.h" +#include "debug.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "llvm/Config/llvm-config.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/LegacyPassManager.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/DebugInfo.h" +#include "llvm/IR/CFG.h" +#include "llvm/IR/Verifier.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Transforms/IPO/PassManagerBuilder.h" +#include "llvm/Transforms/Utils/BasicBlockUtils.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/MemorySSAUpdater.h" +#include "llvm/Analysis/ValueTracking.h" +#include "llvm/Pass.h" +#include "llvm/IR/Constants.h" + +#include "afl-llvm-common.h" + +#ifndef O_DSYNC + #define O_DSYNC O_SYNC +#endif + +using namespace llvm; + +namespace { + +class AFLdict2filePass : public ModulePass { + + public: + static char ID; + + AFLdict2filePass() : ModulePass(ID) { + + if (getenv("AFL_DEBUG")) debug = 1; + + } + + bool runOnModule(Module &M) override; + +}; + +} // namespace + +void dict2file(int fd, u8 *mem, u32 len) { + + int i, j, binary = 0; + char line[MAX_AUTO_EXTRA * 8], tmp[8]; + + strcpy(line, "\""); + j = 1; + for (i = 0; i < len; i++) { + + if (isprint(mem[i])) { + + line[j++] = mem[i]; + + } else { + + if (i + 1 != len || mem[i] != 0 || binary || len == 4 || len == 8) { + + line[j] = 0; + sprintf(tmp, "\\x%02x", (u8)mem[i]); + strcat(line, tmp); + j = strlen(line); + + } + + binary = 1; + + } + + } + + line[j] = 0; + strcat(line, "\"\n"); + if (write(fd, line, strlen(line)) <= 0) + PFATAL("Could not write to dictionary file"); + fsync(fd); + + if (!be_quiet) fprintf(stderr, "Found dictionary token: %s", line); + +} + +bool AFLdict2filePass::runOnModule(Module &M) { + + DenseMap valueMap; + char * ptr; + int fd, found = 0; + + /* Show a banner */ + setvbuf(stdout, NULL, _IONBF, 0); + + if ((isatty(2) && !getenv("AFL_QUIET")) || debug) { + + SAYF(cCYA "afl-llvm-dict2file" VERSION cRST + " by Marc \"vanHauser\" Heuse \n"); + + } else + + be_quiet = 1; + + scanForDangerousFunctions(&M); + + ptr = getenv("AFL_LLVM_DICT2FILE"); + + if (!ptr || *ptr != '/') + FATAL("AFL_LLVM_DICT2FILE is not set to an absolute path: %s", ptr); + + if ((fd = open(ptr, O_WRONLY | O_APPEND | O_CREAT | O_DSYNC, 0644)) < 0) + PFATAL("Could not open/create %s.", ptr); + + /* Instrument all the things! */ + + for (auto &F : M) { + + if (isIgnoreFunction(&F)) continue; + + /* Some implementation notes. + * + * We try to handle 3 cases: + * - memcmp("foo", arg, 3) <- literal string + * - static char globalvar[] = "foo"; + * memcmp(globalvar, arg, 3) <- global variable + * - char localvar[] = "foo"; + * memcmp(locallvar, arg, 3) <- local variable + * + * The local variable case is the hardest. We can only detect that + * case if there is no reassignment or change in the variable. + * And it might not work across llvm version. + * What we do is hooking the initializer function for local variables + * (llvm.memcpy.p0i8.p0i8.i64) and note the string and the assigned + * variable. And if that variable is then used in a compare function + * we use that noted string. + * This seems not to work for tokens that have a size <= 4 :-( + * + * - if the compared length is smaller than the string length we + * save the full string. This is likely better for fuzzing but + * might be wrong in a few cases depending on optimizers + * + * - not using StringRef because there is a bug in the llvm 11 + * checkout I am using which sometimes points to wrong strings + * + * Over and out. Took me a full day. damn. mh/vh + */ + + for (auto &BB : F) { + + for (auto &IN : BB) { + + CallInst *callInst = nullptr; + CmpInst * cmpInst = nullptr; + + if ((cmpInst = dyn_cast(&IN))) { + + Value * op = cmpInst->getOperand(1); + ConstantInt *ilen = dyn_cast(op); + + if (ilen) { + + u64 val2 = 0, val = ilen->getZExtValue(); + u32 len = 0; + if (val > 0x10000 && val < 0xffffffff) len = 4; + if (val > 0x100000001 && val < 0xffffffffffffffff) len = 8; + + if (len) { + + auto c = cmpInst->getPredicate(); + + switch (c) { + + case CmpInst::FCMP_OGT: // fall through + case CmpInst::FCMP_OLE: // fall through + case CmpInst::ICMP_SLE: // fall through + case CmpInst::ICMP_SGT: + + // signed comparison and it is a negative constant + if ((len == 4 && (val & 80000000)) || + (len == 8 && (val & 8000000000000000))) { + + if ((val & 0xffff) != 1) val2 = val - 1; + break; + + } + + // fall through + + case CmpInst::FCMP_UGT: // fall through + case CmpInst::FCMP_ULE: // fall through + case CmpInst::ICMP_UGT: // fall through + case CmpInst::ICMP_ULE: + if ((val & 0xffff) != 0xfffe) val2 = val + 1; + break; + + case CmpInst::FCMP_OLT: // fall through + case CmpInst::FCMP_OGE: // fall through + case CmpInst::ICMP_SLT: // fall through + case CmpInst::ICMP_SGE: + + // signed comparison and it is a negative constant + if ((len == 4 && (val & 80000000)) || + (len == 8 && (val & 8000000000000000))) { + + if ((val & 0xffff) != 1) val2 = val - 1; + break; + + } + + // fall through + + case CmpInst::FCMP_ULT: // fall through + case CmpInst::FCMP_UGE: // fall through + case CmpInst::ICMP_ULT: // fall through + case CmpInst::ICMP_UGE: + if ((val & 0xffff) != 1) val2 = val - 1; + break; + + default: + val2 = 0; + + } + + dict2file(fd, (u8 *)&val, len); + found++; + if (val2) { + + dict2file(fd, (u8 *)&val2, len); + found++; + + } + + } + + } + + } + + if ((callInst = dyn_cast(&IN))) { + + bool isStrcmp = true; + bool isMemcmp = true; + bool isStrncmp = true; + bool isStrcasecmp = true; + bool isStrncasecmp = true; + bool isIntMemcpy = true; + bool addedNull = false; + size_t optLen = 0; + + Function *Callee = callInst->getCalledFunction(); + if (!Callee) continue; + if (callInst->getCallingConv() != llvm::CallingConv::C) continue; + std::string FuncName = Callee->getName().str(); + isStrcmp &= !FuncName.compare("strcmp"); + isMemcmp &= !FuncName.compare("memcmp"); + isStrncmp &= !FuncName.compare("strncmp"); + isStrcasecmp &= !FuncName.compare("strcasecmp"); + isStrncasecmp &= !FuncName.compare("strncasecmp"); + isIntMemcpy &= !FuncName.compare("llvm.memcpy.p0i8.p0i8.i64"); + + if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp && + !isStrncasecmp && !isIntMemcpy) + continue; + + /* Verify the strcmp/memcmp/strncmp/strcasecmp/strncasecmp function + * prototype */ + FunctionType *FT = Callee->getFunctionType(); + + isStrcmp &= + FT->getNumParams() == 2 && FT->getReturnType()->isIntegerTy(32) && + FT->getParamType(0) == FT->getParamType(1) && + FT->getParamType(0) == IntegerType::getInt8PtrTy(M.getContext()); + isStrcasecmp &= + FT->getNumParams() == 2 && FT->getReturnType()->isIntegerTy(32) && + FT->getParamType(0) == FT->getParamType(1) && + FT->getParamType(0) == IntegerType::getInt8PtrTy(M.getContext()); + isMemcmp &= FT->getNumParams() == 3 && + FT->getReturnType()->isIntegerTy(32) && + FT->getParamType(0)->isPointerTy() && + FT->getParamType(1)->isPointerTy() && + FT->getParamType(2)->isIntegerTy(); + isStrncmp &= FT->getNumParams() == 3 && + FT->getReturnType()->isIntegerTy(32) && + FT->getParamType(0) == FT->getParamType(1) && + FT->getParamType(0) == + IntegerType::getInt8PtrTy(M.getContext()) && + FT->getParamType(2)->isIntegerTy(); + isStrncasecmp &= FT->getNumParams() == 3 && + FT->getReturnType()->isIntegerTy(32) && + FT->getParamType(0) == FT->getParamType(1) && + FT->getParamType(0) == + IntegerType::getInt8PtrTy(M.getContext()) && + FT->getParamType(2)->isIntegerTy(); + + if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp && + !isStrncasecmp && !isIntMemcpy) + continue; + + /* is a str{n,}{case,}cmp/memcmp, check if we have + * str{case,}cmp(x, "const") or str{case,}cmp("const", x) + * strn{case,}cmp(x, "const", ..) or strn{case,}cmp("const", x, ..) + * memcmp(x, "const", ..) or memcmp("const", x, ..) */ + Value *Str1P = callInst->getArgOperand(0), + *Str2P = callInst->getArgOperand(1); + std::string Str1, Str2; + StringRef TmpStr; + bool HasStr1 = getConstantStringInfo(Str1P, TmpStr); + if (TmpStr.empty()) { + + HasStr1 = false; + + } else { + + HasStr1 = true; + Str1 = TmpStr.str(); + + } + + bool HasStr2 = getConstantStringInfo(Str2P, TmpStr); + if (TmpStr.empty()) { + + HasStr2 = false; + + } else { + + HasStr2 = true; + Str2 = TmpStr.str(); + + } + + if (debug) + fprintf(stderr, "F:%s %p(%s)->\"%s\"(%s) %p(%s)->\"%s\"(%s)\n", + FuncName.c_str(), Str1P, Str1P->getName().str().c_str(), + Str1.c_str(), HasStr1 == true ? "true" : "false", Str2P, + Str2P->getName().str().c_str(), Str2.c_str(), + HasStr2 == true ? "true" : "false"); + + // we handle the 2nd parameter first because of llvm memcpy + if (!HasStr2) { + + auto *Ptr = dyn_cast(Str2P); + if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) { + + if (auto *Var = dyn_cast(Ptr->getOperand(0))) { + + if (Var->hasInitializer()) { + + if (auto *Array = + dyn_cast(Var->getInitializer())) { + + HasStr2 = true; + Str2 = Array->getAsString().str(); + + } + + } + + } + + } + + } + + // for the internal memcpy routine we only care for the second + // parameter and are not reporting anything. + if (isIntMemcpy == true) { + + if (HasStr2 == true) { + + Value * op2 = callInst->getArgOperand(2); + ConstantInt *ilen = dyn_cast(op2); + if (ilen) { + + uint64_t literalLength = Str2.size(); + uint64_t optLength = ilen->getZExtValue(); + if (literalLength + 1 == optLength) { + + Str2.append("\0", 1); // add null byte + addedNull = true; + + } + + } + + valueMap[Str1P] = new std::string(Str2); + + if (debug) + fprintf(stderr, "Saved: %s for %p\n", Str2.c_str(), Str1P); + continue; + + } + + continue; + + } + + // Neither a literal nor a global variable? + // maybe it is a local variable that we saved + if (!HasStr2) { + + std::string *strng = valueMap[Str2P]; + if (strng && !strng->empty()) { + + Str2 = *strng; + HasStr2 = true; + if (debug) + fprintf(stderr, "Filled2: %s for %p\n", strng->c_str(), Str2P); + + } + + } + + if (!HasStr1) { + + auto Ptr = dyn_cast(Str1P); + + if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) { + + if (auto *Var = dyn_cast(Ptr->getOperand(0))) { + + if (Var->hasInitializer()) { + + if (auto *Array = + dyn_cast(Var->getInitializer())) { + + HasStr1 = true; + Str1 = Array->getAsString().str(); + + } + + } + + } + + } + + } + + // Neither a literal nor a global variable? + // maybe it is a local variable that we saved + if (!HasStr1) { + + std::string *strng = valueMap[Str1P]; + if (strng && !strng->empty()) { + + Str1 = *strng; + HasStr1 = true; + if (debug) + fprintf(stderr, "Filled1: %s for %p\n", strng->c_str(), Str1P); + + } + + } + + /* handle cases of one string is const, one string is variable */ + if (!(HasStr1 ^ HasStr2)) continue; + + std::string thestring; + + if (HasStr1) + thestring = Str1; + else + thestring = Str2; + + optLen = thestring.length(); + + if (isMemcmp || isStrncmp || isStrncasecmp) { + + Value * op2 = callInst->getArgOperand(2); + ConstantInt *ilen = dyn_cast(op2); + if (ilen) { + + uint64_t literalLength = optLen; + optLen = ilen->getZExtValue(); + if (literalLength + 1 == optLen) { // add null byte + thestring.append("\0", 1); + addedNull = true; + + } + + } + + } + + // add null byte if this is a string compare function and a null + // was not already added + if (!isMemcmp) { + + if (addedNull == false) { + + thestring.append("\0", 1); // add null byte + optLen++; + + } + + // ensure we do not have garbage + size_t offset = thestring.find('\0', 0); + if (offset + 1 < optLen) optLen = offset + 1; + thestring = thestring.substr(0, optLen); + + } + + // we take the longer string, even if the compare was to a + // shorter part. Note that depending on the optimizer of the + // compiler this can be wrong, but it is more likely that this + // is helping the fuzzer + if (optLen != thestring.length()) optLen = thestring.length(); + if (optLen > MAX_AUTO_EXTRA) optLen = MAX_AUTO_EXTRA; + if (optLen < 3) // too short? skip + continue; + + ptr = (char *)thestring.c_str(); + + dict2file(fd, (u8 *)ptr, optLen); + found++; + + } + + } + + } + + } + + close(fd); + + /* Say something nice. */ + + if (!be_quiet) { + + if (!found) + OKF("No entries for a dictionary found."); + else + OKF("Wrote %d entries to the dictionary file.\n", found); + + } + + return true; + +} + +char AFLdict2filePass::ID = 0; + +static void registerAFLdict2filePass(const PassManagerBuilder &, + legacy::PassManagerBase &PM) { + + PM.add(new AFLdict2filePass()); + +} + +static RegisterPass X("afl-dict2file", + "afl++ dict2file instrumentation pass", + false, false); + +static RegisterStandardPasses RegisterAFLdict2filePass( + PassManagerBuilder::EP_OptimizerLast, registerAFLdict2filePass); + +static RegisterStandardPasses RegisterAFLdict2filePass0( + PassManagerBuilder::EP_EnabledOnOptLevel0, registerAFLdict2filePass); + -- cgit 1.4.1 From 8ec41b2585390c54256dd823e1beafd6246d9976 Mon Sep 17 00:00:00 2001 From: aflpp Date: Sun, 6 Sep 2020 11:40:41 +0200 Subject: fix various warnings --- GNUmakefile.llvm | 6 ++---- instrumentation/SanitizerCoverageLTO.so.cc | 12 ++++++++---- instrumentation/afl-llvm-dict2file.so.cc | 2 +- src/afl-cc.c | 6 +----- 4 files changed, 12 insertions(+), 14 deletions(-) (limited to 'instrumentation/afl-llvm-dict2file.so.cc') diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm index 1bb3d265..d432021b 100644 --- a/GNUmakefile.llvm +++ b/GNUmakefile.llvm @@ -422,13 +422,11 @@ document: ./afl-compiler-rt-32.o: instrumentation/afl-compiler-rt.o.c | test_deps @printf "[*] Building 32-bit variant of the runtime (-m32)... " - @$(CLANG_BIN) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi - @test -e afl-compiler-rt-32.o && ln -sf afl-compiler-rt-32.o afl-llvm-rt-64.o + @$(CLANG_BIN) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; ln -sf afl-compiler-rt-32.o afl-llvm-rt-32.o; else echo "failed (that's fine)"; fi ./afl-compiler-rt-64.o: instrumentation/afl-compiler-rt.o.c | test_deps @printf "[*] Building 64-bit variant of the runtime (-m64)... " - @$(CLANG_BIN) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi - @test -e afl-compiler-rt-64.o && ln -sf afl-compiler-rt-64.o afl-llvm-rt-64.o + @$(CLANG_BIN) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; ln -sf afl-compiler-rt-64.o afl-llvm-rt-64.o; else echo "failed (that's fine)"; fi .PHONY: test_build test_build: $(PROGS) diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index f4958d80..0a136d6f 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -197,8 +197,8 @@ class ModuleSanitizerCoverage { void CreateFunctionLocalArrays(Function &F, ArrayRef AllBlocks); void InjectCoverageAtBlock(Function &F, BasicBlock &BB, size_t Idx, bool IsLeafFunc = true); - std::pair CreateSecStartEnd(Module &M, const char *Section, - Type *Ty); +// std::pair CreateSecStartEnd(Module &M, const char *Section, +// Type *Ty); void SetNoSanitizeMetadata(Instruction *I) { @@ -208,8 +208,8 @@ class ModuleSanitizerCoverage { } std::string getSectionName(const std::string &Section) const; - std::string getSectionStart(const std::string &Section) const; - std::string getSectionEnd(const std::string &Section) const; +// std::string getSectionStart(const std::string &Section) const; +// std::string getSectionEnd(const std::string &Section) const; FunctionCallee SanCovTracePCIndir; FunctionCallee SanCovTracePC /*, SanCovTracePCGuard*/; Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy, @@ -349,6 +349,7 @@ PreservedAnalyses ModuleSanitizerCoveragePass::run(Module & M, } +/* std::pair ModuleSanitizerCoverage::CreateSecStartEnd( Module &M, const char *Section, Type *Ty) { @@ -373,6 +374,7 @@ std::pair ModuleSanitizerCoverage::CreateSecStartEnd( return std::make_pair(IRB.CreatePointerCast(GEP, Ty), SecEndPtr); } +*/ bool ModuleSanitizerCoverage::instrumentModule( Module &M, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) { @@ -1536,6 +1538,7 @@ std::string ModuleSanitizerCoverage::getSectionName( } +/* std::string ModuleSanitizerCoverage::getSectionStart( const std::string &Section) const { @@ -1553,6 +1556,7 @@ std::string ModuleSanitizerCoverage::getSectionEnd( return "__stop___" + Section; } +*/ char ModuleSanitizerCoverageLegacyPass::ID = 0; diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc index e87ecce8..ef42756e 100644 --- a/instrumentation/afl-llvm-dict2file.so.cc +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -84,7 +84,7 @@ class AFLdict2filePass : public ModulePass { void dict2file(int fd, u8 *mem, u32 len) { - int i, j, binary = 0; + u32 i, j, binary = 0; char line[MAX_AUTO_EXTRA * 8], tmp[8]; strcpy(line, "\""); diff --git a/src/afl-cc.c b/src/afl-cc.c index e11ce40a..ddda3845 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1153,9 +1153,6 @@ int main(int argc, char **argv, char **envp) { if (argc < 2 || strncmp(argv[1], "-h", 2) == 0) { - char *fp; - fp = realpath(argv[0], NULL); - printf("afl-cc" VERSION " by Michal Zalewski, Laszlo Szekeres, Marc Heuse\n"); @@ -1302,8 +1299,7 @@ int main(int argc, char **argv, char **envp) { " AFL_USE_ASAN: activate address sanitizer\n" " AFL_USE_CFISAN: activate control flow sanitizer\n" " AFL_USE_MSAN: activate memory sanitizer\n" - " AFL_USE_UBSAN: activate undefined behaviour sanitizer\n", - BIN_PATH, BIN_PATH); + " AFL_USE_UBSAN: activate undefined behaviour sanitizer\n"); SAYF( "\nLLVM/LTO/afl-clang-fast/afl-clang-lto specific environment " -- cgit 1.4.1 From 6114a48b89528ff3f24d91832d588aa8c05b672e Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 6 Sep 2020 13:29:32 +0200 Subject: add std::string and bcmp to dictionary functions --- docs/Changelog.md | 3 ++- instrumentation/SanitizerCoverageLTO.so.cc | 29 ++++++++++++++++------ instrumentation/afl-llvm-dict2file.so.cc | 15 ++++++++--- instrumentation/afl-llvm-lto-instrumentation.so.cc | 16 +++++++++--- 4 files changed, 48 insertions(+), 15 deletions(-) (limited to 'instrumentation/afl-llvm-dict2file.so.cc') diff --git a/docs/Changelog.md b/docs/Changelog.md index b4c575a6..73613452 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -28,7 +28,8 @@ sending a mail to . - not overriding -Ox or -fno-unroll-loops anymore - new llvm pass: dict2file via AFL_LLVM_DICT2FILE, create afl-fuzz -x dictionary of string comparisons found during compilation - - LTO autodict now also collects interesting cmp comparisons + - LTO autodict now also collects interesting cmp comparisons, + std::string compare + find + ==, bcmp ### Version ++2.68c (release) diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index 0a136d6f..b75776b8 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -197,8 +197,9 @@ class ModuleSanitizerCoverage { void CreateFunctionLocalArrays(Function &F, ArrayRef AllBlocks); void InjectCoverageAtBlock(Function &F, BasicBlock &BB, size_t Idx, bool IsLeafFunc = true); -// std::pair CreateSecStartEnd(Module &M, const char *Section, -// Type *Ty); + // std::pair CreateSecStartEnd(Module &M, const char + // *Section, + // Type *Ty); void SetNoSanitizeMetadata(Instruction *I) { @@ -207,9 +208,9 @@ class ModuleSanitizerCoverage { } - std::string getSectionName(const std::string &Section) const; -// std::string getSectionStart(const std::string &Section) const; -// std::string getSectionEnd(const std::string &Section) const; + std::string getSectionName(const std::string &Section) const; + // std::string getSectionStart(const std::string &Section) const; + // std::string getSectionEnd(const std::string &Section) const; FunctionCallee SanCovTracePCIndir; FunctionCallee SanCovTracePC /*, SanCovTracePCGuard*/; Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy, @@ -374,6 +375,7 @@ std::pair ModuleSanitizerCoverage::CreateSecStartEnd( return std::make_pair(IRB.CreatePointerCast(GEP, Ty), SecEndPtr); } + */ bool ModuleSanitizerCoverage::instrumentModule( @@ -612,6 +614,7 @@ bool ModuleSanitizerCoverage::instrumentModule( bool isStrcasecmp = true; bool isStrncasecmp = true; bool isIntMemcpy = true; + bool isStdString = true; bool addedNull = false; size_t optLen = 0; @@ -624,7 +627,13 @@ bool ModuleSanitizerCoverage::instrumentModule( isStrncmp &= !FuncName.compare("strncmp"); isStrcasecmp &= !FuncName.compare("strcasecmp"); isStrncasecmp &= !FuncName.compare("strncasecmp"); - isIntMemcpy &= !FuncName.compare("llvm.memcpy.p0i8.p0i8.i64"); + isIntMemcpy &= (!FuncName.compare("llvm.memcpy.p0i8.p0i8.i64") || + !FuncName.compare("bcmp")); + isStdString &= + ((FuncName.find("basic_string") != std::string::npos && + FuncName.find("compare") != std::string::npos) || + (FuncName.find("basic_string") != std::string::npos && + FuncName.find("find") != std::string::npos)); /* we do something different here, putting this BB and the successors in a block map */ @@ -642,7 +651,7 @@ bool ModuleSanitizerCoverage::instrumentModule( } if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp && - !isStrncasecmp && !isIntMemcpy) + !isStrncasecmp && !isIntMemcpy && !isStdString) continue; /* Verify the strcmp/memcmp/strncmp/strcasecmp/strncasecmp function @@ -676,9 +685,12 @@ bool ModuleSanitizerCoverage::instrumentModule( FT->getParamType(0) == IntegerType::getInt8PtrTy(M.getContext()) && FT->getParamType(2)->isIntegerTy(); + isStdString &= FT->getNumParams() >= 2 && + FT->getParamType(0)->isPointerTy() && + FT->getParamType(1)->isPointerTy(); if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp && - !isStrncasecmp && !isIntMemcpy) + !isStrncasecmp && !isIntMemcpy && !isStdString) continue; /* is a str{n,}{case,}cmp/memcmp, check if we have @@ -1556,6 +1568,7 @@ std::string ModuleSanitizerCoverage::getSectionEnd( return "__stop___" + Section; } + */ char ModuleSanitizerCoverageLegacyPass::ID = 0; diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc index ef42756e..0ab97d5b 100644 --- a/instrumentation/afl-llvm-dict2file.so.cc +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -283,6 +283,7 @@ bool AFLdict2filePass::runOnModule(Module &M) { bool isStrcasecmp = true; bool isStrncasecmp = true; bool isIntMemcpy = true; + bool isStdString = true; bool addedNull = false; size_t optLen = 0; @@ -295,10 +296,15 @@ bool AFLdict2filePass::runOnModule(Module &M) { isStrncmp &= !FuncName.compare("strncmp"); isStrcasecmp &= !FuncName.compare("strcasecmp"); isStrncasecmp &= !FuncName.compare("strncasecmp"); - isIntMemcpy &= !FuncName.compare("llvm.memcpy.p0i8.p0i8.i64"); + isIntMemcpy &= (!FuncName.compare("llvm.memcpy.p0i8.p0i8.i64") || + !FuncName.compare("bcmp")); + isStdString &= ((FuncName.find("basic_string") != std::string::npos && + FuncName.find("compare") != std::string::npos) || + (FuncName.find("basic_string") != std::string::npos && + FuncName.find("find") != std::string::npos)); if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp && - !isStrncasecmp && !isIntMemcpy) + !isStrncasecmp && !isIntMemcpy && !isStdString) continue; /* Verify the strcmp/memcmp/strncmp/strcasecmp/strncasecmp function @@ -330,9 +336,12 @@ bool AFLdict2filePass::runOnModule(Module &M) { FT->getParamType(0) == IntegerType::getInt8PtrTy(M.getContext()) && FT->getParamType(2)->isIntegerTy(); + isStdString &= FT->getNumParams() >= 2 && + FT->getParamType(0)->isPointerTy() && + FT->getParamType(1)->isPointerTy(); if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp && - !isStrncasecmp && !isIntMemcpy) + !isStrncasecmp && !isIntMemcpy && !isStdString) continue; /* is a str{n,}{case,}cmp/memcmp, check if we have diff --git a/instrumentation/afl-llvm-lto-instrumentation.so.cc b/instrumentation/afl-llvm-lto-instrumentation.so.cc index 9632c319..4f032ca0 100644 --- a/instrumentation/afl-llvm-lto-instrumentation.so.cc +++ b/instrumentation/afl-llvm-lto-instrumentation.so.cc @@ -381,6 +381,7 @@ bool AFLLTOPass::runOnModule(Module &M) { bool isStrcasecmp = true; bool isStrncasecmp = true; bool isIntMemcpy = true; + bool isStdString = true; bool addedNull = false; size_t optLen = 0; @@ -393,7 +394,13 @@ bool AFLLTOPass::runOnModule(Module &M) { isStrncmp &= !FuncName.compare("strncmp"); isStrcasecmp &= !FuncName.compare("strcasecmp"); isStrncasecmp &= !FuncName.compare("strncasecmp"); - isIntMemcpy &= !FuncName.compare("llvm.memcpy.p0i8.p0i8.i64"); + isIntMemcpy &= (!FuncName.compare("llvm.memcpy.p0i8.p0i8.i64") || + !FuncName.compare("bcmp")); + isStdString &= + ((FuncName.find("basic_string") != std::string::npos && + FuncName.find("compare") != std::string::npos) || + (FuncName.find("basic_string") != std::string::npos && + FuncName.find("find") != std::string::npos)); /* we do something different here, putting this BB and the successors in a block map */ @@ -414,7 +421,7 @@ bool AFLLTOPass::runOnModule(Module &M) { } if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp && - !isStrncasecmp && !isIntMemcpy) + !isStrncasecmp && !isIntMemcpy && !isStdString) continue; /* Verify the strcmp/memcmp/strncmp/strcasecmp/strncasecmp function @@ -448,9 +455,12 @@ bool AFLLTOPass::runOnModule(Module &M) { FT->getParamType(0) == IntegerType::getInt8PtrTy(M.getContext()) && FT->getParamType(2)->isIntegerTy(); + isStdString &= FT->getNumParams() >= 2 && + FT->getParamType(0)->isPointerTy() && + FT->getParamType(1)->isPointerTy(); if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp && - !isStrncasecmp && !isIntMemcpy) + !isStrncasecmp && !isIntMemcpy && !isStdString) continue; /* is a str{n,}{case,}cmp/memcmp, check if we have -- cgit 1.4.1 From 06ac2850c54412ee8897361f8ff05a649a716b30 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 6 Sep 2020 13:53:40 +0200 Subject: bcmp for compare-transform-pass --- instrumentation/SanitizerCoverageLTO.so.cc | 6 +++--- instrumentation/afl-llvm-dict2file.so.cc | 6 +++--- instrumentation/afl-llvm-lto-instrumentation.so.cc | 6 +++--- instrumentation/compare-transform-pass.so.cc | 3 ++- 4 files changed, 11 insertions(+), 10 deletions(-) (limited to 'instrumentation/afl-llvm-dict2file.so.cc') diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index b75776b8..64162145 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -623,12 +623,12 @@ bool ModuleSanitizerCoverage::instrumentModule( if (callInst->getCallingConv() != llvm::CallingConv::C) continue; std::string FuncName = Callee->getName().str(); isStrcmp &= !FuncName.compare("strcmp"); - isMemcmp &= !FuncName.compare("memcmp"); + isMemcmp &= + (!FuncName.compare("memcmp") || !FuncName.compare("bcmp")); isStrncmp &= !FuncName.compare("strncmp"); isStrcasecmp &= !FuncName.compare("strcasecmp"); isStrncasecmp &= !FuncName.compare("strncasecmp"); - isIntMemcpy &= (!FuncName.compare("llvm.memcpy.p0i8.p0i8.i64") || - !FuncName.compare("bcmp")); + isIntMemcpy &= !FuncName.compare("llvm.memcpy.p0i8.p0i8.i64"); isStdString &= ((FuncName.find("basic_string") != std::string::npos && FuncName.find("compare") != std::string::npos) || diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc index 0ab97d5b..2f9f44ca 100644 --- a/instrumentation/afl-llvm-dict2file.so.cc +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -292,12 +292,12 @@ bool AFLdict2filePass::runOnModule(Module &M) { if (callInst->getCallingConv() != llvm::CallingConv::C) continue; std::string FuncName = Callee->getName().str(); isStrcmp &= !FuncName.compare("strcmp"); - isMemcmp &= !FuncName.compare("memcmp"); + isMemcmp &= + (!FuncName.compare("memcmp") || !FuncName.compare("bcmp")); isStrncmp &= !FuncName.compare("strncmp"); isStrcasecmp &= !FuncName.compare("strcasecmp"); isStrncasecmp &= !FuncName.compare("strncasecmp"); - isIntMemcpy &= (!FuncName.compare("llvm.memcpy.p0i8.p0i8.i64") || - !FuncName.compare("bcmp")); + isIntMemcpy &= !FuncName.compare("llvm.memcpy.p0i8.p0i8.i64"); isStdString &= ((FuncName.find("basic_string") != std::string::npos && FuncName.find("compare") != std::string::npos) || (FuncName.find("basic_string") != std::string::npos && diff --git a/instrumentation/afl-llvm-lto-instrumentation.so.cc b/instrumentation/afl-llvm-lto-instrumentation.so.cc index 4f032ca0..2f936c29 100644 --- a/instrumentation/afl-llvm-lto-instrumentation.so.cc +++ b/instrumentation/afl-llvm-lto-instrumentation.so.cc @@ -390,12 +390,12 @@ bool AFLLTOPass::runOnModule(Module &M) { if (callInst->getCallingConv() != llvm::CallingConv::C) continue; std::string FuncName = Callee->getName().str(); isStrcmp &= !FuncName.compare("strcmp"); - isMemcmp &= !FuncName.compare("memcmp"); + isMemcmp &= + (!FuncName.compare("memcmp") || !FuncName.compare("bcmp")); isStrncmp &= !FuncName.compare("strncmp"); isStrcasecmp &= !FuncName.compare("strcasecmp"); isStrncasecmp &= !FuncName.compare("strncasecmp"); - isIntMemcpy &= (!FuncName.compare("llvm.memcpy.p0i8.p0i8.i64") || - !FuncName.compare("bcmp")); + isIntMemcpy &= !FuncName.compare("llvm.memcpy.p0i8.p0i8.i64"); isStdString &= ((FuncName.find("basic_string") != std::string::npos && FuncName.find("compare") != std::string::npos) || diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc index acdd0f3b..9d2f4a92 100644 --- a/instrumentation/compare-transform-pass.so.cc +++ b/instrumentation/compare-transform-pass.so.cc @@ -143,7 +143,8 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, if (callInst->getCallingConv() != llvm::CallingConv::C) continue; StringRef FuncName = Callee->getName(); isStrcmp &= !FuncName.compare(StringRef("strcmp")); - isMemcmp &= !FuncName.compare(StringRef("memcmp")); + isMemcmp &= (!FuncName.compare(StringRef("memcmp")) || + !FuncName.compare(StringRef("bcmp"))); isStrncmp &= !FuncName.compare(StringRef("strncmp")); isStrcasecmp &= !FuncName.compare(StringRef("strcasecmp")); isStrncasecmp &= !FuncName.compare(StringRef("strncasecmp")); -- cgit 1.4.1 From 688e2c87df90cc63032aa4d1961493f52ebbd3c5 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Fri, 11 Sep 2020 22:13:42 +0200 Subject: portability: make llvm-dict2file compilable under Ubuntu xenial (llvm 3.8.0) --- instrumentation/afl-llvm-dict2file.so.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'instrumentation/afl-llvm-dict2file.so.cc') diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc index 2f9f44ca..15accc88 100644 --- a/instrumentation/afl-llvm-dict2file.so.cc +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -50,7 +50,6 @@ #include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Analysis/LoopInfo.h" -#include "llvm/Analysis/MemorySSAUpdater.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Pass.h" #include "llvm/IR/Constants.h" -- cgit 1.4.1 From 093754f6bfaaaac0ace8f223ff37cdd30b658b9e Mon Sep 17 00:00:00 2001 From: aflpp Date: Tue, 22 Sep 2020 02:04:23 +0200 Subject: dict2file fix for integers > 64 bit --- instrumentation/afl-llvm-dict2file.so.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'instrumentation/afl-llvm-dict2file.so.cc') diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc index 15accc88..abf8e868 100644 --- a/instrumentation/afl-llvm-dict2file.so.cc +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -195,7 +195,7 @@ bool AFLdict2filePass::runOnModule(Module &M) { Value * op = cmpInst->getOperand(1); ConstantInt *ilen = dyn_cast(op); - if (ilen) { + if (ilen && ilen->uge(0xffffffffffffffff) == false) { u64 val2 = 0, val = ilen->getZExtValue(); u32 len = 0; -- cgit 1.4.1 From f4a0407270fa9a928c7954f1a74bb63f8f24fd63 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 22 Sep 2020 20:06:39 +0200 Subject: add comment for future --- instrumentation/afl-llvm-dict2file.so.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'instrumentation/afl-llvm-dict2file.so.cc') diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc index abf8e868..aab20661 100644 --- a/instrumentation/afl-llvm-dict2file.so.cc +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -195,6 +195,10 @@ bool AFLdict2filePass::runOnModule(Module &M) { Value * op = cmpInst->getOperand(1); ConstantInt *ilen = dyn_cast(op); + /* We skip > 64 bit integers. why? first because their value is + difficult to obtain, and second because clang does not support + literals > 64 bit (as of llvm 12) */ + if (ilen && ilen->uge(0xffffffffffffffff) == false) { u64 val2 = 0, val = ilen->getZExtValue(); -- cgit 1.4.1 From fc75d2b1818432e744c6e6057aa75cebb1870b8e Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 25 Sep 2020 13:14:54 +0200 Subject: remove warnings --- GNUmakefile.llvm | 2 +- instrumentation/afl-llvm-dict2file.so.cc | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'instrumentation/afl-llvm-dict2file.so.cc') diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm index 11ed0bd6..ef2a1f68 100644 --- a/GNUmakefile.llvm +++ b/GNUmakefile.llvm @@ -237,7 +237,7 @@ else endif CFLAGS ?= -O3 -funroll-loops -fPIC -D_FORTIFY_SOURCE=2 -CFLAGS_SAFE := -Wall -g -Wno-pointer-sign -I ./include/ -I ./instrumentation/ \ +CFLAGS_SAFE := -Wall -g -Wno-cast-qual -Wno-variadic-macros -Wno-pointer-sign -I ./include/ -I ./instrumentation/ \ -DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \ -DLLVM_BINDIR=\"$(LLVM_BINDIR)\" -DVERSION=\"$(VERSION)\" \ -DLLVM_LIBDIR=\"$(LLVM_LIBDIR)\" -DLLVM_VERSION=\"$(LLVMVER)\" \ diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc index aab20661..e04ebda8 100644 --- a/instrumentation/afl-llvm-dict2file.so.cc +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -381,8 +381,8 @@ bool AFLdict2filePass::runOnModule(Module &M) { if (debug) fprintf(stderr, "F:%s %p(%s)->\"%s\"(%s) %p(%s)->\"%s\"(%s)\n", - FuncName.c_str(), Str1P, Str1P->getName().str().c_str(), - Str1.c_str(), HasStr1 == true ? "true" : "false", Str2P, + FuncName.c_str(), (void*)Str1P, Str1P->getName().str().c_str(), + Str1.c_str(), HasStr1 == true ? "true" : "false", (void*)Str2P, Str2P->getName().str().c_str(), Str2.c_str(), HasStr2 == true ? "true" : "false"); @@ -436,7 +436,7 @@ bool AFLdict2filePass::runOnModule(Module &M) { valueMap[Str1P] = new std::string(Str2); if (debug) - fprintf(stderr, "Saved: %s for %p\n", Str2.c_str(), Str1P); + fprintf(stderr, "Saved: %s for %p\n", Str2.c_str(), (void*)Str1P); continue; } @@ -455,7 +455,7 @@ bool AFLdict2filePass::runOnModule(Module &M) { Str2 = *strng; HasStr2 = true; if (debug) - fprintf(stderr, "Filled2: %s for %p\n", strng->c_str(), Str2P); + fprintf(stderr, "Filled2: %s for %p\n", strng->c_str(), (void*)Str2P); } @@ -497,7 +497,7 @@ bool AFLdict2filePass::runOnModule(Module &M) { Str1 = *strng; HasStr1 = true; if (debug) - fprintf(stderr, "Filled1: %s for %p\n", strng->c_str(), Str1P); + fprintf(stderr, "Filled1: %s for %p\n", strng->c_str(), (void*)Str1P); } -- cgit 1.4.1 From 383cd487a2c28012c80341f8517e473120af4d19 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 29 Sep 2020 15:02:57 +0200 Subject: small improvements to Marcel's patch, fix laf-intel + redqueen crashes --- docs/Changelog.md | 1 + include/afl-fuzz.h | 5 +-- instrumentation/afl-llvm-dict2file.so.cc | 14 ++++++--- instrumentation/cmplog-instructions-pass.cc | 6 ++-- instrumentation/cmplog-routines-pass.cc | 11 ++++--- instrumentation/compare-transform-pass.so.cc | 24 ++++++++------ instrumentation/split-compares-pass.so.cc | 47 +++++++++++++++++----------- instrumentation/split-switches-pass.so.cc | 21 +++++++------ src/afl-fuzz-bitmap.c | 13 +++++--- src/afl-fuzz-init.c | 4 +-- src/afl-fuzz-queue.c | 30 +++++++++--------- src/afl-fuzz.c | 2 +- 12 files changed, 104 insertions(+), 74 deletions(-) (limited to 'instrumentation/afl-llvm-dict2file.so.cc') diff --git a/docs/Changelog.md b/docs/Changelog.md index 789b1f74..0f923423 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -14,6 +14,7 @@ sending a mail to . - all compilers combined to afl-cc which emulates the previous ones - afl-llvm/gcc-rt.o merged into afl-compiler-rt.o - afl-fuzz + - Marcel Boehme submitted a patch that improves all AFFast schedules :) - reading testcases from -i now descends into subdirectories - allow up to 4 -x command line options - loaded extras now have a duplicate protection diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index f65fc40f..fb661ce5 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -151,7 +151,8 @@ struct queue_entry { is_ascii; /* Is the input just ascii text? */ u32 bitmap_size, /* Number of bits set in bitmap */ - fuzz_level; /* Number of fuzzing iterations */ + fuzz_level, /* Number of fuzzing iterations */ + n_fuzz_entry; /* offset in n_fuzz */ u64 exec_us, /* Execution time (us) */ handicap, /* Number of queue cycles behind */ @@ -491,7 +492,7 @@ typedef struct afl_state { u8 *var_bytes; /* Bytes that appear to be variable */ - #define n_fuzz_size (1 << 21) +#define N_FUZZ_SIZE (1 << 21) u32 *n_fuzz; volatile u8 stop_soon, /* Ctrl-C pressed? */ diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc index e04ebda8..bd8eb27a 100644 --- a/instrumentation/afl-llvm-dict2file.so.cc +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -381,8 +381,9 @@ bool AFLdict2filePass::runOnModule(Module &M) { if (debug) fprintf(stderr, "F:%s %p(%s)->\"%s\"(%s) %p(%s)->\"%s\"(%s)\n", - FuncName.c_str(), (void*)Str1P, Str1P->getName().str().c_str(), - Str1.c_str(), HasStr1 == true ? "true" : "false", (void*)Str2P, + FuncName.c_str(), (void *)Str1P, + Str1P->getName().str().c_str(), Str1.c_str(), + HasStr1 == true ? "true" : "false", (void *)Str2P, Str2P->getName().str().c_str(), Str2.c_str(), HasStr2 == true ? "true" : "false"); @@ -436,7 +437,8 @@ bool AFLdict2filePass::runOnModule(Module &M) { valueMap[Str1P] = new std::string(Str2); if (debug) - fprintf(stderr, "Saved: %s for %p\n", Str2.c_str(), (void*)Str1P); + fprintf(stderr, "Saved: %s for %p\n", Str2.c_str(), + (void *)Str1P); continue; } @@ -455,7 +457,8 @@ bool AFLdict2filePass::runOnModule(Module &M) { Str2 = *strng; HasStr2 = true; if (debug) - fprintf(stderr, "Filled2: %s for %p\n", strng->c_str(), (void*)Str2P); + fprintf(stderr, "Filled2: %s for %p\n", strng->c_str(), + (void *)Str2P); } @@ -497,7 +500,8 @@ bool AFLdict2filePass::runOnModule(Module &M) { Str1 = *strng; HasStr1 = true; if (debug) - fprintf(stderr, "Filled1: %s for %p\n", strng->c_str(), (void*)Str1P); + fprintf(stderr, "Filled1: %s for %p\n", strng->c_str(), + (void *)Str1P); } diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc index d5de3dbb..9921de0c 100644 --- a/instrumentation/cmplog-instructions-pass.cc +++ b/instrumentation/cmplog-instructions-pass.cc @@ -210,7 +210,8 @@ bool CmpLogInstructions::hookInstrs(Module &M) { } if (!icomps.size()) return false; - if (!be_quiet) errs() << "Hooking " << icomps.size() << " cmp instructions\n"; + // if (!be_quiet) errs() << "Hooking " << icomps.size() << " cmp + // instructions\n"; for (auto &selectcmpInst : icomps) { @@ -259,8 +260,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) { bool CmpLogInstructions::runOnModule(Module &M) { if (getenv("AFL_QUIET") == NULL) - llvm::errs() - << "Running cmplog-instructions-pass by andreafioraldi@gmail.com\n"; + printf("Running cmplog-instructions-pass by andreafioraldi@gmail.com\n"); else be_quiet = 1; hookInstrs(M); diff --git a/instrumentation/cmplog-routines-pass.cc b/instrumentation/cmplog-routines-pass.cc index c44f38c4..e92883ae 100644 --- a/instrumentation/cmplog-routines-pass.cc +++ b/instrumentation/cmplog-routines-pass.cc @@ -149,9 +149,11 @@ bool CmpLogRoutines::hookRtns(Module &M) { } if (!calls.size()) return false; - if (!be_quiet) - errs() << "Hooking " << calls.size() - << " calls with pointers as arguments\n"; + /* + if (!be_quiet) + errs() << "Hooking " << calls.size() + << " calls with pointers as arguments\n"; + */ for (auto &callInst : calls) { @@ -179,8 +181,7 @@ bool CmpLogRoutines::hookRtns(Module &M) { bool CmpLogRoutines::runOnModule(Module &M) { if (getenv("AFL_QUIET") == NULL) - llvm::errs() - << "Running cmplog-routines-pass by andreafioraldi@gmail.com\n"; + printf("Running cmplog-routines-pass by andreafioraldi@gmail.com\n"); else be_quiet = 1; hookRtns(M); diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc index 9d2f4a92..3a4abd6e 100644 --- a/instrumentation/compare-transform-pass.so.cc +++ b/instrumentation/compare-transform-pass.so.cc @@ -339,8 +339,9 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, if (!calls.size()) return false; if (!be_quiet) - errs() << "Replacing " << calls.size() - << " calls to strcmp/memcmp/strncmp/strcasecmp/strncasecmp\n"; + printf( + "Replacing %lu calls to strcmp/memcmp/strncmp/strcasecmp/strncasecmp\n", + calls.size()); for (auto &callInst : calls) { @@ -426,11 +427,14 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, else unrollLen = constStrLen; - if (!be_quiet) - errs() << callInst->getCalledFunction()->getName() << ": unroll len " - << unrollLen - << ((isSizedcmp && !isConstSized) ? ", variable n" : "") << ": " - << ConstStr << "\n"; + /* + if (!be_quiet) + errs() << callInst->getCalledFunction()->getName() << ": unroll len " + << unrollLen + << ((isSizedcmp && !isConstSized) ? ", variable n" : "") << ": + " + << ConstStr << "\n"; + */ /* split before the call instruction */ BasicBlock *bb = callInst->getParent(); @@ -556,10 +560,12 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, bool CompareTransform::runOnModule(Module &M) { if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL) - llvm::errs() << "Running compare-transform-pass by laf.intel@gmail.com, " - "extended by heiko@hexco.de\n"; + printf( + "Running compare-transform-pass by laf.intel@gmail.com, extended by " + "heiko@hexco.de\n"); else be_quiet = 1; + transformCmps(M, true, true, true, true, true); verifyModule(M); diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc index 2fb90e5e..6d0c52a4 100644 --- a/instrumentation/split-compares-pass.so.cc +++ b/instrumentation/split-compares-pass.so.cc @@ -1262,8 +1262,9 @@ bool SplitComparesTransform::runOnModule(Module &M) { if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL) { - errs() << "Split-compare-pass by laf.intel@gmail.com, extended by " - "heiko@hexco.de\n"; + printf( + "Split-compare-pass by laf.intel@gmail.com, extended by " + "heiko@hexco.de\n"); } else { @@ -1275,13 +1276,15 @@ bool SplitComparesTransform::runOnModule(Module &M) { count = splitFPCompares(M); - if (!be_quiet) { + /* + if (!be_quiet) { - errs() << "Split-floatingpoint-compare-pass: " << count - << " FP comparisons split\n"; + errs() << "Split-floatingpoint-compare-pass: " << count + << " FP comparisons split\n"; - } + } + */ simplifyFPCompares(M); } @@ -1294,10 +1297,12 @@ bool SplitComparesTransform::runOnModule(Module &M) { case 64: count = splitIntCompares(M, bitw); - if (!be_quiet) - errs() << "Split-integer-compare-pass " << bitw << "bit: " << count - << " split\n"; - + /* + if (!be_quiet) + errs() << "Split-integer-compare-pass " << bitw << "bit: " << + count + << " split\n"; + */ bitw >>= 1; #if LLVM_VERSION_MAJOR > 3 || \ (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 7) @@ -1305,10 +1310,12 @@ bool SplitComparesTransform::runOnModule(Module &M) { #endif case 32: count = splitIntCompares(M, bitw); - if (!be_quiet) - errs() << "Split-integer-compare-pass " << bitw << "bit: " << count - << " split\n"; - + /* + if (!be_quiet) + errs() << "Split-integer-compare-pass " << bitw << "bit: " << + count + << " split\n"; + */ bitw >>= 1; #if LLVM_VERSION_MAJOR > 3 || \ (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 7) @@ -1316,15 +1323,17 @@ bool SplitComparesTransform::runOnModule(Module &M) { #endif case 16: count = splitIntCompares(M, bitw); - if (!be_quiet) - errs() << "Split-integer-compare-pass " << bitw << "bit: " << count - << " split\n"; - + /* + if (!be_quiet) + errs() << "Split-integer-compare-pass " << bitw << "bit: " << + count + << " split\n"; + */ bitw >>= 1; break; default: - if (!be_quiet) errs() << "NOT Running split-compare-pass \n"; + // if (!be_quiet) errs() << "NOT Running split-compare-pass \n"; return false; break; diff --git a/instrumentation/split-switches-pass.so.cc b/instrumentation/split-switches-pass.so.cc index a79d4114..97ab04a4 100644 --- a/instrumentation/split-switches-pass.so.cc +++ b/instrumentation/split-switches-pass.so.cc @@ -327,10 +327,11 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) { } if (!switches.size()) return false; - if (!be_quiet) - errs() << "Rewriting " << switches.size() << " switch statements " - << "\n"; - + /* + if (!be_quiet) + errs() << "Rewriting " << switches.size() << " switch statements " + << "\n"; + */ for (auto &SI : switches) { BasicBlock *CurBlock = SI->getParent(); @@ -341,15 +342,17 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) { BasicBlock *Default = SI->getDefaultDest(); unsigned bitw = Val->getType()->getIntegerBitWidth(); - if (!be_quiet) - errs() << "switch: " << SI->getNumCases() << " cases " << bitw - << " bit\n"; + /* + if (!be_quiet) + errs() << "switch: " << SI->getNumCases() << " cases " << bitw + << " bit\n"; + */ /* If there is only the default destination or the condition checks 8 bit or * less, don't bother with the code below. */ if (!SI->getNumCases() || bitw <= 8) { - if (!be_quiet) errs() << "skip trivial switch..\n"; + // if (!be_quiet) errs() << "skip trivial switch..\n"; continue; } @@ -415,7 +418,7 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) { bool SplitSwitchesTransform::runOnModule(Module &M) { if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL) - llvm::errs() << "Running split-switches-pass by laf.intel@gmail.com\n"; + printf("Running split-switches-pass by laf.intel@gmail.com\n"); else be_quiet = 1; splitSwitches(M); diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 64de86a2..a22223b9 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -556,8 +556,8 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); /* Saturated increment */ - if (afl->n_fuzz[cksum % n_fuzz_size] < 0xFFFFFFFF) - afl->n_fuzz[cksum % n_fuzz_size]++; + if (afl->n_fuzz[cksum % N_FUZZ_SIZE] < 0xFFFFFFFF) + afl->n_fuzz[cksum % N_FUZZ_SIZE]++; } @@ -597,10 +597,15 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { if (cksum) afl->queue_top->exec_cksum = cksum; else - afl->queue_top->exec_cksum = + cksum = afl->queue_top->exec_cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); - afl->n_fuzz[cksum % n_fuzz_size] = 1; + if (afl->schedule >= FAST && afl->schedule <= RARE) { + + afl->queue_top->n_fuzz_entry = cksum % N_FUZZ_SIZE; + afl->n_fuzz[afl->queue_top->n_fuzz_entry] = 1; + + } /* Try to calibrate inline; this also calls update_bitmap_score() when successful. */ diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index b825837f..65478a78 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -732,8 +732,8 @@ void read_testcases(afl_state_t *afl, u8 *directory) { if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) { u64 cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); - - afl->n_fuzz[cksum % n_fuzz_size] = 1; + afl->queue_top->n_fuzz_entry = cksum % N_FUZZ_SIZE; + afl->n_fuzz[afl->queue_top->n_fuzz_entry] = 1; } diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index dfabba7b..0d7d0314 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -308,9 +308,9 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { u64 fuzz_p2; if (unlikely(afl->schedule >= FAST && afl->schedule < RARE)) - fuzz_p2 = 0; // Skip the fuzz_p2 comparison + fuzz_p2 = 0; // Skip the fuzz_p2 comparison else if (unlikely(afl->schedule == RARE)) - fuzz_p2 = next_pow2(afl->n_fuzz[q->exec_cksum % n_fuzz_size]); + fuzz_p2 = next_pow2(afl->n_fuzz[q->n_fuzz_entry]); else fuzz_p2 = q->fuzz_level; @@ -336,7 +336,8 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { u64 top_rated_fav_factor; u64 top_rated_fuzz_p2; if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) - top_rated_fuzz_p2 = next_pow2(afl->n_fuzz[afl->top_rated[i]->exec_cksum % n_fuzz_size]); + top_rated_fuzz_p2 = + next_pow2(afl->n_fuzz[afl->top_rated[i]->n_fuzz_entry]); else top_rated_fuzz_p2 = afl->top_rated[i]->fuzz_level; @@ -607,11 +608,10 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { } - u32 n_paths; - double factor = 1.0; + u32 n_paths; + double factor = 1.0; long double fuzz_mu; - switch (afl->schedule) { case EXPLORE: @@ -634,7 +634,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { struct queue_entry *queue_it = afl->queue; while (queue_it) { - fuzz_mu += log2(afl->n_fuzz[q->exec_cksum % n_fuzz_size]); + fuzz_mu += log2(afl->n_fuzz[q->n_fuzz_entry]); n_paths++; queue_it = queue_it->next; @@ -645,7 +645,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { fuzz_mu = fuzz_mu / n_paths; - if (log2(afl->n_fuzz[q->exec_cksum % n_fuzz_size]) > fuzz_mu) { + if (log2(afl->n_fuzz[q->n_fuzz_entry]) > fuzz_mu) { /* Never skip favourites */ if (!q->favored) factor = 0; @@ -660,7 +660,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { // Don't modify unfuzzed seeds if (q->fuzz_level == 0) break; - switch ((u32)log2(afl->n_fuzz[q->exec_cksum % n_fuzz_size])) { + switch ((u32)log2(afl->n_fuzz[q->n_fuzz_entry])) { case 0 ... 1: factor = 4; @@ -691,17 +691,17 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { } - if (q->favored) - factor *= 1.15; + if (q->favored) factor *= 1.15; break; case LIN: - factor = q->fuzz_level / (afl->n_fuzz[q->exec_cksum % n_fuzz_size] + 1); + factor = q->fuzz_level / (afl->n_fuzz[q->n_fuzz_entry] + 1); break; case QUAD: - factor = q->fuzz_level * q->fuzz_level / (afl->n_fuzz[q->exec_cksum % n_fuzz_size] + 1); + factor = + q->fuzz_level * q->fuzz_level / (afl->n_fuzz[q->n_fuzz_entry] + 1); break; case MMOPT: @@ -726,8 +726,8 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { perf_score += (q->tc_ref * 10); // the more often fuzz result paths are equal to this queue entry, // reduce its value - perf_score *= - (1 - (double)((double)afl->n_fuzz[q->exec_cksum % n_fuzz_size] / (double)afl->fsrv.total_execs)); + perf_score *= (1 - (double)((double)afl->n_fuzz[q->n_fuzz_entry] / + (double)afl->fsrv.total_execs)); break; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 889f753d..273d1c14 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -939,7 +939,7 @@ int main(int argc, char **argv_orig, char **envp) { /* Dynamically allocate memory for AFLFast schedules */ if (afl->schedule >= FAST && afl->schedule <= RARE) { - afl->n_fuzz = ck_alloc(n_fuzz_size * sizeof(u32)); + afl->n_fuzz = ck_alloc(N_FUZZ_SIZE * sizeof(u32)); } -- cgit 1.4.1