diff options
Diffstat (limited to 'llvm_mode')
-rw-r--r-- | llvm_mode/afl-llvm-lto-instrumentation.so.cc | 95 | ||||
-rw-r--r-- | llvm_mode/afl-llvm-rt.o.c | 45 |
2 files changed, 124 insertions, 16 deletions
diff --git a/llvm_mode/afl-llvm-lto-instrumentation.so.cc b/llvm_mode/afl-llvm-lto-instrumentation.so.cc index eae60ccd..dbd4a26e 100644 --- a/llvm_mode/afl-llvm-lto-instrumentation.so.cc +++ b/llvm_mode/afl-llvm-lto-instrumentation.so.cc @@ -31,6 +31,7 @@ #include <stdio.h> #include <stdlib.h> #include <unistd.h> +#include <string.h> #include <list> #include <string> @@ -154,6 +155,7 @@ class AFLLTOPass : public ModulePass { protected: int afl_global_id = 1, debug = 0, autodictionary = 0; uint32_t be_quiet = 0, inst_blocks = 0, inst_funcs = 0, total_instr = 0; + uint64_t map_addr = 0x10000; }; @@ -165,9 +167,11 @@ bool AFLLTOPass::runOnModule(Module &M) { std::vector<std::string> dictionary; std::vector<CallInst *> calls; DenseMap<Value *, std::string *> valueMap; + char * ptr; IntegerType *Int8Ty = IntegerType::getInt8Ty(C); IntegerType *Int32Ty = IntegerType::getInt32Ty(C); + IntegerType *Int64Ty = IntegerType::getInt64Ty(C); if (getenv("AFL_DEBUG")) debug = 1; @@ -186,12 +190,63 @@ bool AFLLTOPass::runOnModule(Module &M) { getenv("AFL_LLVM_LTO_AUTODICTIONARY")) autodictionary = 1; + if (getenv("AFL_LLVM_MAP_DYNAMIC")) map_addr = 0; + + if ((ptr = getenv("AFL_LLVM_MAP_ADDR"))) { + + uint64_t val; + if (!*ptr || !strcmp(ptr, "0") || !strcmp(ptr, "0x0")) { + + map_addr = 0; + + } else if (map_addr == 0) { + + FATAL( + "AFL_LLVM_MAP_ADDR and AFL_LLVM_MAP_DYNAMIC cannot be used together"); + + } else if (strncmp(ptr, "0x", 2) != 0) { + + map_addr = 0x10000; // the default + + } else { + + val = strtoull(ptr, NULL, 16); + if (val < 0x100 || val > 0xffffffff00000000) { + + FATAL( + "AFL_LLVM_MAP_ADDR must be a value between 0x100 and " + "0xffffffff00000000"); + + } + + map_addr = val; + + } + + } + + if (debug) { fprintf(stderr, "map address is %lu\n", map_addr); } + /* Get globals for the SHM region and the previous location. Note that __afl_prev_loc is thread-local. */ - GlobalVariable *AFLMapPtr = - new GlobalVariable(M, PointerType::get(Int8Ty, 0), false, - GlobalValue::ExternalLinkage, 0, "__afl_area_ptr"); + GlobalVariable *AFLMapPtr = NULL; + ; + Value *MapPtrFixed = NULL; + + if (!map_addr) { + + AFLMapPtr = + new GlobalVariable(M, PointerType::get(Int8Ty, 0), false, + GlobalValue::ExternalLinkage, 0, "__afl_area_ptr"); + + } else { + + ConstantInt *MapAddr = ConstantInt::get(Int64Ty, map_addr); + MapPtrFixed = + ConstantExpr::getIntToPtr(MapAddr, PointerType::getUnqual(Int8Ty)); + + } ConstantInt *Zero = ConstantInt::get(Int8Ty, 0); ConstantInt *One = ConstantInt::get(Int8Ty, 1); @@ -202,7 +257,7 @@ bool AFLLTOPass::runOnModule(Module &M) { for (auto &F : M) { - //fprintf(stderr, "DEBUG: Function %s\n", F.getName().str().c_str()); + // fprintf(stderr, "DEBUG: Function %s\n", F.getName().str().c_str()); if (F.size() < 2) continue; if (isBlacklisted(&F)) continue; @@ -581,10 +636,20 @@ bool AFLLTOPass::runOnModule(Module &M) { /* Load SHM pointer */ - LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr); - MapPtr->setMetadata(M.getMDKindID("nosanitize"), - MDNode::get(C, None)); - Value *MapPtrIdx = IRB.CreateGEP(MapPtr, CurLoc); + Value *MapPtrIdx; + + if (map_addr) { + + MapPtrIdx = IRB.CreateGEP(MapPtrFixed, CurLoc); + + } else { + + LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr); + MapPtr->setMetadata(M.getMDKindID("nosanitize"), + MDNode::get(C, None)); + MapPtrIdx = IRB.CreateGEP(MapPtr, CurLoc); + + } /* Update bitmap */ @@ -629,7 +694,7 @@ bool AFLLTOPass::runOnModule(Module &M) { } - if (getenv("AFL_LLVM_LTO_DONTWRITEID") == NULL || dictionary.size()) { + if (!getenv("AFL_LLVM_LTO_DONTWRITEID") || dictionary.size() || map_addr) { // yes we could create our own function, insert it into ctors ... // but this would be a pain in the butt ... so we use afl-llvm-rt-lto.o @@ -658,6 +723,18 @@ bool AFLLTOPass::runOnModule(Module &M) { BasicBlock::iterator IP = bb->getFirstInsertionPt(); IRBuilder<> IRB(&(*IP)); + if (map_addr) { + + GlobalVariable *AFLMapAddrFixed = new GlobalVariable( + M, Int64Ty, true, GlobalValue::ExternalLinkage, 0, "__afl_map_addr", + 0, GlobalVariable::GeneralDynamicTLSModel, 0, false); + ConstantInt *MapAddr = ConstantInt::get(Int64Ty, map_addr); + StoreInst * StoreMapAddr = IRB.CreateStore(MapAddr, AFLMapAddrFixed); + StoreMapAddr->setMetadata(M.getMDKindID("nosanitize"), + MDNode::get(C, None)); + + } + if (getenv("AFL_LLVM_LTO_DONTWRITEID") == NULL) { uint32_t write_loc = afl_global_id; diff --git a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c index f286e66a..6da41192 100644 --- a/llvm_mode/afl-llvm-rt.o.c +++ b/llvm_mode/afl-llvm-rt.o.c @@ -52,6 +52,10 @@ #define CONST_PRIO 5 +//#ifndef MAP_FIXED_NOREPLACE +//#define MAP_FIXED_NOREPLACE MAP_FIXED +//#endif + #include <sys/mman.h> #include <fcntl.h> @@ -69,12 +73,14 @@ u32 __afl_final_loc; u32 __afl_prev_ctx; u32 __afl_cmp_counter; u32 __afl_dictionary_len; +u64 __afl_map_addr; #else __thread PREV_LOC_T __afl_prev_loc[NGRAM_SIZE_MAX]; __thread u32 __afl_final_loc; __thread u32 __afl_prev_ctx; __thread u32 __afl_cmp_counter; __thread u32 __afl_dictionary_len; +__thread u64 __afl_map_addr; #endif struct cmp_map *__afl_cmp_map; @@ -87,7 +93,11 @@ static u8 is_persistent; static void __afl_map_shm(void) { - u8 *id_str = getenv(SHM_ENV_VAR); + u8 * id_str = getenv(SHM_ENV_VAR); + unsigned int map_size = MAP_SIZE; + + if (__afl_final_loc > 1 && __afl_final_loc < MAP_SIZE) + map_size = __afl_final_loc; /* If we're running under AFL, attach to the appropriate region, replacing the early-stage __afl_area_initial region that is needed to allow some really @@ -99,10 +109,6 @@ static void __afl_map_shm(void) { const char * shm_file_path = id_str; int shm_fd = -1; unsigned char *shm_base = NULL; - unsigned int map_size = MAP_SIZE - - if (__afl_final_loc > 1 && __afl_final_loc < MAP_SIZE) map_size = - __afl_final_loc; /* create the shared memory segment as if it was a file */ shm_fd = shm_open(shm_file_path, O_RDWR, 0600); @@ -114,7 +120,18 @@ static void __afl_map_shm(void) { } /* map the shared memory segment to the address space of the process */ - shm_base = mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); + if (__afl_map_addr) { + + shm_base = mmap((void *)__afl_map_addr, map_size, PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_SHARED, shm_fd, 0); + + } else { + + shm_base = + mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); + + } + if (shm_base == MAP_FAILED) { close(shm_fd); @@ -129,7 +146,8 @@ static void __afl_map_shm(void) { #else u32 shm_id = atoi(id_str); - __afl_area_ptr = shmat(shm_id, NULL, 0); + __afl_area_ptr = shmat(shm_id, (void *)__afl_map_addr, 0); + #endif /* Whooooops. */ @@ -141,6 +159,19 @@ static void __afl_map_shm(void) { __afl_area_ptr[0] = 1; + } else if (__afl_map_addr) { + + __afl_area_ptr = + mmap((void *)__afl_map_addr, map_size, PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_SHARED | MAP_ANONYMOUS, -1, 0); + if (__afl_area_ptr == MAP_FAILED) { + + fprintf(stderr, "can not aquire mmap for address %p\n", + (void *)__afl_map_addr); + exit(1); + + } + } id_str = getenv(CMPLOG_SHM_ENV_VAR); |