diff options
Diffstat (limited to 'llvm_mode/afl-llvm-lto-instrumentation.so.cc')
-rw-r--r-- | llvm_mode/afl-llvm-lto-instrumentation.so.cc | 107 |
1 files changed, 85 insertions, 22 deletions
diff --git a/llvm_mode/afl-llvm-lto-instrumentation.so.cc b/llvm_mode/afl-llvm-lto-instrumentation.so.cc index 38c3f202..10482705 100644 --- a/llvm_mode/afl-llvm-lto-instrumentation.so.cc +++ b/llvm_mode/afl-llvm-lto-instrumentation.so.cc @@ -49,6 +49,7 @@ #include "llvm/Analysis/MemorySSAUpdater.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Pass.h" +#include "llvm/IR/Constants.h" #include "afl-llvm-common.h" @@ -102,6 +103,7 @@ bool AFLLTOPass::runOnModule(Module &M) { std::vector<std::string> dictionary; std::vector<CallInst *> calls; DenseMap<Value *, std::string *> valueMap; + std::vector<BasicBlock *> BlockList; char * ptr; FILE * documentFile = NULL; @@ -135,7 +137,10 @@ bool AFLLTOPass::runOnModule(Module &M) { if (getenv("AFL_LLVM_LTO_AUTODICTIONARY")) autodictionary = 1; - if (getenv("AFL_LLVM_MAP_DYNAMIC")) map_addr = 0; + // we make this the default as the fixed map has problems with + // defered forkserver, early constructors, ifuncs and maybe more + /*if (getenv("AFL_LLVM_MAP_DYNAMIC"))*/ + map_addr = 0; if (getenv("AFL_LLVM_SKIPSINGLEBLOCK")) function_minimum_size = 2; @@ -146,7 +151,7 @@ bool AFLLTOPass::runOnModule(Module &M) { map_addr = 0; - } else if (map_addr == 0) { + } else if (getenv("AFL_LLVM_MAP_DYNAMIC")) { FATAL( "AFL_LLVM_MAP_ADDR and AFL_LLVM_MAP_DYNAMIC cannot be used together"); @@ -196,7 +201,8 @@ bool AFLLTOPass::runOnModule(Module &M) { ConstantInt *Zero = ConstantInt::get(Int8Ty, 0); ConstantInt *One = ConstantInt::get(Int8Ty, 1); - /* This dumps all inialized global strings - might be useful in the future + // This dumps all inialized global strings - might be useful in the future + /* for (auto G=M.getGlobalList().begin(); G!=M.getGlobalList().end(); G++) { GlobalVariable &GV=*G; @@ -214,14 +220,20 @@ bool AFLLTOPass::runOnModule(Module &M) { */ + scanForDangerousFunctions(&M); + /* Instrument all the things! */ int inst_blocks = 0; for (auto &F : M) { - // fprintf(stderr, "DEBUG: Module %s Function %s\n", - // M.getName().str().c_str(), F.getName().str().c_str()); + /*For debugging + AttributeSet X = F.getAttributes().getFnAttributes(); + fprintf(stderr, "DEBUG: Module %s Function %s attributes %u\n", + M.getName().str().c_str(), F.getName().str().c_str(), + X.getNumAttributes()); + */ if (F.size() < function_minimum_size) continue; if (isIgnoreFunction(&F)) continue; @@ -279,14 +291,14 @@ bool AFLLTOPass::runOnModule(Module &M) { if ((callInst = dyn_cast<CallInst>(&IN))) { - bool isStrcmp = true; - bool isMemcmp = true; - bool isStrncmp = true; - bool isStrcasecmp = true; - bool isStrncasecmp = true; - bool isIntMemcpy = true; - bool addedNull = false; - uint8_t optLen = 0; + 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; @@ -299,6 +311,24 @@ bool AFLLTOPass::runOnModule(Module &M) { isStrncasecmp &= !FuncName.compare("strncasecmp"); isIntMemcpy &= !FuncName.compare("llvm.memcpy.p0i8.p0i8.i64"); + /* we do something different here, putting this BB and the + successors in a block map */ + if (!FuncName.compare("__afl_persistent_loop")) { + + BlockList.push_back(&BB); + /* + for (succ_iterator SI = succ_begin(&BB), SE = + succ_end(&BB); SI != SE; ++SI) { + + BasicBlock *succ = *SI; + BlockList.push_back(succ); + + } + + */ + + } + if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp && !isStrncasecmp && !isIntMemcpy) continue; @@ -516,18 +546,27 @@ bool AFLLTOPass::runOnModule(Module &M) { // add null byte if this is a string compare function and a null // was not already added - if (addedNull == false && !isMemcmp) { + if (!isMemcmp) { - thestring.append("\0", 1); // add null byte - optLen++; + 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); } if (!be_quiet) { std::string outstring; - fprintf(stderr, "%s: length %u/%u \"", FuncName.c_str(), optLen, - (unsigned int)thestring.length()); + fprintf(stderr, "%s: length %zu/%zu \"", FuncName.c_str(), optLen, + thestring.length()); for (uint8_t i = 0; i < thestring.length(); i++) { uint8_t c = thestring[i]; @@ -563,17 +602,41 @@ bool AFLLTOPass::runOnModule(Module &M) { for (auto &BB : F) { - uint32_t succ = 0; + if (F.size() == 1) { + + InsBlocks.push_back(&BB); + continue; - if (F.size() == 1) InsBlocks.push_back(&BB); + } + uint32_t succ = 0; for (succ_iterator SI = succ_begin(&BB), SE = succ_end(&BB); SI != SE; ++SI) if ((*SI)->size() > 0) succ++; - if (succ < 2) // no need to instrument continue; + if (BlockList.size()) { + + int skip = 0; + for (uint32_t k = 0; k < BlockList.size(); k++) { + + if (origBB == BlockList[k]) { + + if (debug) + fprintf(stderr, + "DEBUG: Function %s skipping BB with/after __afl_loop\n", + F.getName().str().c_str()); + skip = 1; + + } + + } + + if (skip) continue; + + } + InsBlocks.push_back(&BB); } @@ -585,7 +648,7 @@ bool AFLLTOPass::runOnModule(Module &M) { do { --i; - BasicBlock * newBB; + BasicBlock * newBB = NULL; BasicBlock * origBB = &(*InsBlocks[i]); std::vector<BasicBlock *> Successors; Instruction * TI = origBB->getTerminator(); |