From 378573ab8b2f9b150429503c649e86e0fed4e946 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sat, 2 May 2020 00:39:13 +0200 Subject: AFL_LLVM_SKIP_NEVERZERO added --- llvm_mode/afl-llvm-pass.so.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'llvm_mode/afl-llvm-pass.so.cc') diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc index 9314c3d1..3e9026c8 100644 --- a/llvm_mode/afl-llvm-pass.so.cc +++ b/llvm_mode/afl-llvm-pass.so.cc @@ -84,7 +84,7 @@ class AFLCoverage : public ModulePass { uint32_t ngram_size = 0; uint32_t debug = 0; uint32_t map_size = MAP_SIZE; - char * ctx_str = NULL; + char * ctx_str = NULL, *skip_nozero = NULL; }; @@ -180,6 +180,7 @@ bool AFLCoverage::runOnModule(Module &M) { #if LLVM_VERSION_MAJOR < 9 char *neverZero_counters_str = getenv("AFL_LLVM_NOT_ZERO"); #endif + skip_nozero = getenv("AFL_LLVM_SKIP_NEVERZERO"); unsigned PrevLocSize; @@ -467,6 +468,9 @@ bool AFLCoverage::runOnModule(Module &M) { if (neverZero_counters_str != NULL) { // with llvm 9 we make this the default as the bug in llvm is // then fixed +#else + if (!skip_nozero) { + #endif /* hexcoder: Realize a counter that skips zero during overflow. * Once this counter reaches its maximum value, it next increments to 1 @@ -482,12 +486,8 @@ bool AFLCoverage::runOnModule(Module &M) { auto carry = IRB.CreateZExt(cf, Int8Ty); Incr = IRB.CreateAdd(Incr, carry); -#if LLVM_VERSION_MAJOR < 9 - } -#endif - IRB.CreateStore(Incr, MapPtrIdx) ->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); -- cgit 1.4.1 From 16c16b3e6e0cd678f5da76f757761fb821f1011f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 4 May 2020 18:01:47 +0200 Subject: ctx and ngram can be used together now --- docs/Changelog.md | 1 + docs/env_variables.md | 6 +- examples/afl_network_proxy/afl-network-client.c | 26 +-- llvm_mode/afl-clang-fast.c | 202 +++++++++++++++--------- llvm_mode/afl-llvm-pass.so.cc | 15 +- 5 files changed, 150 insertions(+), 100 deletions(-) (limited to 'llvm_mode/afl-llvm-pass.so.cc') diff --git a/docs/Changelog.md b/docs/Changelog.md index cae99681..8c0624b6 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -20,6 +20,7 @@ sending a mail to . address for the shared memory map is used as this increases the fuzzing speed - fixes to LTO mode if instrumented edges > MAP_SIZE + - CTX and NGRAM can now be used together - added AFL_LLVM_SKIP_NEVERZERO to skip the never zero coverage counter implmentation. For targets with little or no loops or heavy called functions. Gives a small performance boost. diff --git a/docs/env_variables.md b/docs/env_variables.md index bdbb8520..ab5808ec 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -97,12 +97,14 @@ Then there are a few specific features that are only available in llvm_mode: - AFL_LLVM_INSTRUMENT - this configures the instrumentation mode. Available options: - DEFAULT - classic AFL (map[cur_loc ^ prev_loc >> 1]++) + CLASSIC - classic AFL (map[cur_loc ^ prev_loc >> 1]++) (default) CFG - InsTrim instrumentation (see below) LTO - LTO instrumentation (see below) CTX - context sensitive instrumentation (see below) NGRAM-x - deeper previous location coverage (from NGRAM-2 up to NGRAM-16) - Only one can be used. + In CLASSIC (default) can can also specify CTX and/nor NGRAM, seperate + the options with a comma "," then, e.g.: + AFL_LLVM_INSTRUMENT=CLASSIC,CTX,NGRAM-4 ### LTO diff --git a/examples/afl_network_proxy/afl-network-client.c b/examples/afl_network_proxy/afl-network-client.c index 781ea328..cf09b2ad 100644 --- a/examples/afl_network_proxy/afl-network-client.c +++ b/examples/afl_network_proxy/afl-network-client.c @@ -321,7 +321,7 @@ int main(int argc, char *argv[]) { // fprintf(stderr, "Sending testcase with len %u\n", *lenptr); #ifdef USE_DEFLATE - #ifdef COMPRESS_TESTCASES +#ifdef COMPRESS_TESTCASES // we only compress the testcase if it does not fit in the TCP packet if (*lenptr > 1500 - 20 - 32 - 4) { @@ -331,25 +331,27 @@ int main(int argc, char *argv[]) { buf2 + 8, buf2_len); if (send(s, buf2, *lenptr2 + 8, 0) != *lenptr2 + 8) PFATAL("sending test data failed"); - //fprintf(stderr, "COMPRESS (%u->%u):\n", *lenptr, *lenptr2); - //for (u32 i = 0; i < *lenptr; i++) + // fprintf(stderr, "COMPRESS (%u->%u):\n", *lenptr, *lenptr2); + // for (u32 i = 0; i < *lenptr; i++) // fprintf(stderr, "%02x", buf[i + 4]); - //fprintf(stderr, "\n"); - //for (u32 i = 0; i < *lenptr2; i++) + // fprintf(stderr, "\n"); + // for (u32 i = 0; i < *lenptr2; i++) // fprintf(stderr, "%02x", buf2[i + 8]); - //fprintf(stderr, "\n"); + // fprintf(stderr, "\n"); } else { - #endif + +#endif #endif if (send(s, buf, *lenptr + 4, 0) != *lenptr + 4) PFATAL("sending test data failed"); #ifdef USE_DEFLATE - #ifdef COMPRESS_TESTCASES +#ifdef COMPRESS_TESTCASES // fprintf(stderr, "unCOMPRESS (%u)\n", *lenptr); } - #endif + +#endif #endif received = 0; @@ -381,9 +383,9 @@ int main(int argc, char *argv[]) { &decompress_len) != LIBDEFLATE_SUCCESS || decompress_len != __afl_map_size) FATAL("decompression failed"); - // fprintf(stderr, "DECOMPRESS (%u->%u): ", compress_len, decompress_len); - // for (u32 i = 0; i < __afl_map_size; i++) fprintf(stderr, "%02x", - // __afl_area_ptr[i]); fprintf(stderr, "\n"); + // fprintf(stderr, "DECOMPRESS (%u->%u): ", compress_len, decompress_len); + // for (u32 i = 0; i < __afl_map_size; i++) fprintf(stderr, "%02x", + // __afl_area_ptr[i]); fprintf(stderr, "\n"); #else while (received < __afl_map_size && (ret = recv(s, __afl_area_ptr + received, __afl_map_size - received, diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index c59b814d..9f85e5c6 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -43,7 +43,7 @@ static u8 * obj_path; /* Path to runtime libraries */ static u8 **cc_params; /* Parameters passed to the real CC */ static u32 cc_par_cnt = 1; /* Param count, including argv0 */ static u8 llvm_fullpath[PATH_MAX]; -static u8 instrument_mode; +static u8 instrument_mode, instrument_opt_mode, ngram_size; static u8 * lto_flag = AFL_CLANG_FLTO; static u8 * march_opt = CFLAGS_OPT; static u8 debug; @@ -60,14 +60,15 @@ enum { INSTRUMENT_INSTRIM = 2, INSTRUMENT_CFG = 2, INSTRUMENT_LTO = 3, - INSTRUMENT_CTX = 4, - INSTRUMENT_NGRAM = 5 // + ngram value of 2-16 = 7 - 21 + INSTRUMENT_OPT_CTX = 4, + INSTRUMENT_OPT_NGRAM = 8 }; -char instrument_mode_string[6][16] = { +char instrument_mode_string[10][16] = { - "DEFAULT", "PCGUARD", "CFG", "LTO", "CTX", + "CLASSIC", "PCGUARD", "CFG", "LTO", "CTX", "", + "", "", "NGRAM", "" }; @@ -562,59 +563,6 @@ int main(int argc, char **argv, char **envp) { instrument_mode = INSTRUMENT_PCGUARD; #endif - if (getenv("AFL_LLVM_SKIP_NEVERZERO") && getenv("AFL_LLVM_NOT_ZERO")) - FATAL( - "AFL_LLVM_NOT_ZERO and AFL_LLVM_SKIP_NEVERZERO can not be set " - "together"); - - if ((ptr = getenv("AFL_LLVM_INSTRUMENT")) != NULL) { - - if (strncasecmp(ptr, "default", strlen("default")) == 0 || - strncasecmp(ptr, "afl", strlen("afl")) == 0 || - strncasecmp(ptr, "classic", strlen("classic")) == 0) - instrument_mode = INSTRUMENT_DEFAULT; - if (strncasecmp(ptr, "cfg", strlen("cfg")) == 0 || - strncasecmp(ptr, "instrim", strlen("instrim")) == 0) - instrument_mode = INSTRUMENT_CFG; - else if (strncasecmp(ptr, "pc-guard", strlen("pc-guard")) == 0 || - strncasecmp(ptr, "pcguard", strlen("pcgard")) == 0) - instrument_mode = INSTRUMENT_PCGUARD; - else if (strncasecmp(ptr, "lto", strlen("lto")) == 0) - instrument_mode = INSTRUMENT_LTO; - else if (strncasecmp(ptr, "ctx", strlen("ctx")) == 0) { - - instrument_mode = INSTRUMENT_CTX; - setenv("AFL_LLVM_CTX", "1", 1); - - } else if (strncasecmp(ptr, "ngram", strlen("ngram")) == 0) { - - ptr += strlen("ngram"); - while (*ptr && (*ptr < '0' || *ptr > '9')) - ptr++; - if (!*ptr) - if ((ptr = getenv("AFL_LLVM_NGRAM_SIZE")) != NULL) - FATAL( - "you must set the NGRAM size with (e.g. for value 2) " - "AFL_LLVM_INSTRUMENT=ngram-2"); - instrument_mode = INSTRUMENT_NGRAM + atoi(ptr); - if (instrument_mode < INSTRUMENT_NGRAM + 2 || - instrument_mode > INSTRUMENT_NGRAM + NGRAM_SIZE_MAX) - FATAL( - "NGRAM instrumentation mode must be between 2 and NGRAM_SIZE_MAX " - "(%u)", - NGRAM_SIZE_MAX); - - ptr = alloc_printf("%u", instrument_mode - INSTRUMENT_NGRAM); - setenv("AFL_LLVM_NGRAM_SIZE", ptr, 1); - - } else if (strncasecmp(ptr, "classic", strlen("classic")) != 0 || - - strncasecmp(ptr, "default", strlen("default")) != 0 || - strncasecmp(ptr, "afl", strlen("afl")) != 0) - FATAL("unknown AFL_LLVM_INSTRUMENT value: %s", ptr); - - } - if (getenv("USE_TRACE_PC") || getenv("AFL_USE_TRACE_PC") || getenv("AFL_LLVM_USE_TRACE_PC") || getenv("AFL_TRACE_PC")) { @@ -636,39 +584,116 @@ int main(int argc, char **argv, char **envp) { } - if (getenv("AFL_LLVM_CTX")) { + if (getenv("AFL_LLVM_CTX")) instrument_opt_mode |= INSTRUMENT_OPT_CTX; - if (instrument_mode == 0) - instrument_mode = INSTRUMENT_CTX; - else if (instrument_mode != INSTRUMENT_CTX) - FATAL("you can not set AFL_LLVM_INSTRUMENT and AFL_LLVM_CTX together"); + if (getenv("AFL_LLVM_NGRAM_SIZE")) { + + instrument_opt_mode |= INSTRUMENT_OPT_NGRAM; + ngram_size = atoi(getenv("AFL_LLVM_NGRAM_SIZE")); + if (ngram_size < 2 || ngram_size > NGRAM_SIZE_MAX) + FATAL( + "NGRAM instrumentation mode must be between 2 and NGRAM_SIZE_MAX " + "(%u)", + NGRAM_SIZE_MAX); } - if (getenv("AFL_LLVM_NGRAM_SIZE")) { + if (getenv("AFL_LLVM_INSTRUMENT")) { - if (instrument_mode == 0) { + u8 *ptr = strtok(getenv("AFL_LLVM_INSTRUMENT"), ":,;"); - instrument_mode = INSTRUMENT_NGRAM + atoi(getenv("AFL_LLVM_NGRAM_SIZE")); - if (instrument_mode < INSTRUMENT_NGRAM + 2 || - instrument_mode > INSTRUMENT_NGRAM + NGRAM_SIZE_MAX) - FATAL( - "NGRAM instrumentation mode must be between 2 and NGRAM_SIZE_MAX " - "(%u)", - NGRAM_SIZE_MAX); + while (ptr) { - } else if (instrument_mode != INSTRUMENT_NGRAM) + if (strncasecmp(ptr, "default", strlen("default")) == 0 || + strncasecmp(ptr, "afl", strlen("afl")) == 0 || + strncasecmp(ptr, "classic", strlen("classic")) == 0) { - FATAL( - "you can not set AFL_LLVM_INSTRUMENT and AFL_LLVM_NGRAM_SIZE " - "together"); + if (!instrument_mode || instrument_mode == INSTRUMENT_DEFAULT) + instrument_mode = INSTRUMENT_DEFAULT; + else + FATAL("main instrumentation mode already set with %s", + instrument_mode_string[instrument_mode]); + + } + + if (strncasecmp(ptr, "pc-guard", strlen("pc-guard")) == 0 || + strncasecmp(ptr, "pcguard", strlen("pcgard")) == 0) { + + if (!instrument_mode || instrument_mode == INSTRUMENT_PCGUARD) + instrument_mode = INSTRUMENT_PCGUARD; + else + FATAL("main instrumentation mode already set with %s", + instrument_mode_string[instrument_mode]); + + } + + if (strncasecmp(ptr, "cfg", strlen("cfg")) == 0 || + strncasecmp(ptr, "instrim", strlen("instrim")) == 0) { + + if (!instrument_mode || instrument_mode == INSTRUMENT_CFG) + instrument_mode = INSTRUMENT_CFG; + else + FATAL("main instrumentation mode already set with %s", + instrument_mode_string[instrument_mode]); + + } + + if (strncasecmp(ptr, "lto", strlen("lto")) == 0) { + + if (!instrument_mode || instrument_mode == INSTRUMENT_LTO) + instrument_mode = INSTRUMENT_LTO; + else + FATAL("main instrumentation mode already set with %s", + instrument_mode_string[instrument_mode]); + + } + + if (strncasecmp(ptr, "ctx", strlen("ctx")) == 0) { + + instrument_opt_mode |= INSTRUMENT_OPT_CTX; + setenv("AFL_LLVM_CTX", "1", 1); + + } + + if (strncasecmp(ptr, "ngram", strlen("ngram")) == 0) { + + ptr += strlen("ngram"); + while (*ptr && (*ptr < '0' || *ptr > '9')) + ptr++; + if (!*ptr) + if ((ptr = getenv("AFL_LLVM_NGRAM_SIZE")) != NULL) + FATAL( + "you must set the NGRAM size with (e.g. for value 2) " + "AFL_LLVM_INSTRUMENT=ngram-2"); + ngram_size = atoi(ptr); + if (ngram_size < 2 || ngram_size > NGRAM_SIZE_MAX) + FATAL( + "NGRAM instrumentation option must be between 2 and " + "NGRAM_SIZE_MAX " + "(%u)", + NGRAM_SIZE_MAX); + instrument_opt_mode |= (INSTRUMENT_OPT_NGRAM); + ptr = alloc_printf("%u", ngram_size); + setenv("AFL_LLVM_NGRAM_SIZE", ptr, 1); + + } + + ptr = strtok(NULL, ":,;"); + + } } - if (instrument_mode < INSTRUMENT_NGRAM) + if (!instrument_opt_mode) ptr = instrument_mode_string[instrument_mode]; + else if (instrument_opt_mode == INSTRUMENT_OPT_CTX) + ptr = alloc_printf("%s + CTX", instrument_mode_string[instrument_mode]); + else if (instrument_opt_mode == INSTRUMENT_OPT_NGRAM) + ptr = alloc_printf("%s + NGRAM-%u", instrument_mode_string[instrument_mode], + ngram_size); else - ptr = alloc_printf("NGRAM-%u", instrument_mode - INSTRUMENT_NGRAM); + ptr = alloc_printf("%s + CTX + NGRAM-%u", + instrument_mode_string[instrument_mode], ngram_size); if (strstr(argv[0], "afl-clang-lto") != NULL) { @@ -690,9 +715,28 @@ int main(int argc, char **argv, char **envp) { #ifndef AFL_CLANG_FLTO if (instrument_mode == INSTRUMENT_LTO) - FATAL("instrumentation mode LTO specified but LLVM support not available"); + FATAL( + "instrumentation mode LTO specified but LLVM support not available " + "(requires LLVM 11)"); #endif + if (instrument_opt_mode && instrument_mode != INSTRUMENT_CLASSIC) + /*&& instrument_mode != INSTRUMENT_CFG*/ + FATAL( + "CTX and NGRAM instrumentation options can only be used with the " + "CLASSIC instrumentation mode!"); + + if (getenv("AFL_LLVM_SKIP_NEVERZERO") && getenv("AFL_LLVM_NOT_ZERO")) + FATAL( + "AFL_LLVM_NOT_ZERO and AFL_LLVM_SKIP_NEVERZERO can not be set " + "together"); + + if (instrument_mode == INSTRUMENT_CFG && + getenv("AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK") == NULL && ngram_size) + FATAL( + "NGRAM option together with CFG/INSTRIM instrumentation mode can only " + "be used if AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK is set"); + if (argc < 2 || strcmp(argv[1], "-h") == 0) { if (instrument_mode != INSTRUMENT_LTO) diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc index 3e9026c8..42a2f3af 100644 --- a/llvm_mode/afl-llvm-pass.so.cc +++ b/llvm_mode/afl-llvm-pass.so.cc @@ -182,7 +182,7 @@ bool AFLCoverage::runOnModule(Module &M) { #endif skip_nozero = getenv("AFL_LLVM_SKIP_NEVERZERO"); - unsigned PrevLocSize; + unsigned PrevLocSize = 0; char *ngram_size_str = getenv("AFL_LLVM_NGRAM_SIZE"); if (!ngram_size_str) ngram_size_str = getenv("AFL_NGRAM_SIZE"); @@ -216,9 +216,6 @@ bool AFLCoverage::runOnModule(Module &M) { if (ngram_size) PrevLocTy = VectorType::get(IntLocTy, PrevLocVecSize); #endif - if (ctx_str && ngram_size_str) - FATAL("you must decide between NGRAM and CTX instrumentation"); - /* Get globals for the SHM region and the previous location. Note that __afl_prev_loc is thread-local. */ @@ -437,8 +434,10 @@ bool AFLCoverage::runOnModule(Module &M) { PrevLocTrans = IRB.CreateXorReduce(PrevLoc); else #endif - if (ctx_str) - PrevLocTrans = IRB.CreateZExt(IRB.CreateXor(PrevLoc, PrevCtx), Int32Ty); + PrevLocTrans = PrevLoc; + if (ctx_str) + PrevLocTrans = + IRB.CreateZExt(IRB.CreateXor(PrevLocTrans, PrevCtx), Int32Ty); else PrevLocTrans = IRB.CreateZExt(PrevLoc, IRB.getInt32Ty()); @@ -452,7 +451,9 @@ bool AFLCoverage::runOnModule(Module &M) { if (ngram_size) MapPtrIdx = IRB.CreateGEP( MapPtr, - IRB.CreateZExt(IRB.CreateXor(PrevLocTrans, CurLoc), Int32Ty)); + IRB.CreateZExt( + IRB.CreateXor(PrevLocTrans, IRB.CreateZExt(CurLoc, Int32Ty)), + Int32Ty)); else #endif MapPtrIdx = IRB.CreateGEP(MapPtr, IRB.CreateXor(PrevLocTrans, CurLoc)); -- cgit 1.4.1 From 9d384b4e383e2b216847e2ed3aee432a25cd37d8 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 5 May 2020 12:46:49 +0200 Subject: ctx and ngram fix --- llvm_mode/afl-llvm-pass.so.cc | 128 +++++++++++++++++++++++++----------------- 1 file changed, 75 insertions(+), 53 deletions(-) (limited to 'llvm_mode/afl-llvm-pass.so.cc') diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc index 42a2f3af..c0391b04 100644 --- a/llvm_mode/afl-llvm-pass.so.cc +++ b/llvm_mode/afl-llvm-pass.so.cc @@ -294,70 +294,52 @@ bool AFLCoverage::runOnModule(Module &M) { if (!isInWhitelist(&F)) continue; - if (ctx_str && F.size() > 1) { // Context sensitive coverage - // load the context ID of the previous function and write to to a local - // variable on the stack - auto bb = &F.getEntryBlock(); - BasicBlock::iterator IP = bb->getFirstInsertionPt(); - IRBuilder<> IRB(&(*IP)); - PrevCtx = IRB.CreateLoad(AFLContext); - PrevCtx->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); - - // does the function have calls? and is any of the calls larger than one - // basic block? - has_calls = 0; - for (auto &BB : F) { - - if (has_calls) break; - for (auto &IN : BB) { - - CallInst *callInst = nullptr; - if ((callInst = dyn_cast(&IN))) { - - Function *Callee = callInst->getCalledFunction(); - if (!Callee || Callee->size() < 2) - continue; - else { + for (auto &BB : F) { - has_calls = 1; - break; + BasicBlock::iterator IP = BB.getFirstInsertionPt(); + IRBuilder<> IRB(&(*IP)); - } + // Context sensitive coverage + if (ctx_str && &BB == &F.getEntryBlock() && F.size() > 1) { - } + // load the context ID of the previous function and write to to a local + // variable on the stack + PrevCtx = IRB.CreateLoad(AFLContext); + PrevCtx->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); - } + // does the function have calls? and is any of the calls larger than one + // basic block? + for (auto &BB : F) { - } + if (has_calls) break; + for (auto &IN : BB) { - // if yes we store a context ID for this function in the global var - if (has_calls) { + CallInst *callInst = nullptr; + if ((callInst = dyn_cast(&IN))) { - ConstantInt *NewCtx = ConstantInt::get(Int32Ty, AFL_R(map_size)); - StoreInst * StoreCtx = IRB.CreateStore(NewCtx, AFLContext); - StoreCtx->setMetadata(M.getMDKindID("nosanitize"), - MDNode::get(C, None)); + Function *Callee = callInst->getCalledFunction(); + if (!Callee || Callee->size() < 2) + continue; + else { - } + has_calls = 1; + break; - } + } - for (auto &BB : F) { + } - BasicBlock::iterator IP = BB.getFirstInsertionPt(); - IRBuilder<> IRB(&(*IP)); + } - // in CTX mode we have to restore the original context for the caller - - // she might be calling other functions which need the correct CTX - if (ctx_str && has_calls) { + } - Instruction *Inst = BB.getTerminator(); - if (isa(Inst) || isa(Inst)) { + // if yes we store a context ID for this function in the global var + if (has_calls) { - IRBuilder<> Post_IRB(Inst); - StoreInst * RestoreCtx = Post_IRB.CreateStore(PrevCtx, AFLContext); - RestoreCtx->setMetadata(M.getMDKindID("nosanitize"), - MDNode::get(C, None)); + ConstantInt *NewCtx = ConstantInt::get(Int32Ty, AFL_R(map_size)); + StoreInst * StoreCtx = IRB.CreateStore(NewCtx, AFLContext); + StoreCtx->setMetadata(M.getMDKindID("nosanitize"), + MDNode::get(C, None)); } @@ -407,7 +389,28 @@ bool AFLCoverage::runOnModule(Module &M) { } // fprintf(stderr, " == %d\n", more_than_one); - if (more_than_one != 1) continue; + if (more_than_one != 1) { + + // in CTX mode we have to restore the original context for the caller - + // she might be calling other functions which need the correct CTX + if (ctx_str && has_calls && F.size() > 1) { + + Instruction *Inst = BB.getTerminator(); + if (isa(Inst) || isa(Inst)) { + + IRBuilder<> Post_IRB(Inst); + StoreInst * RestoreCtx = Post_IRB.CreateStore(PrevCtx, AFLContext); + RestoreCtx->setMetadata(M.getMDKindID("nosanitize"), + MDNode::get(C, None)); + + } + + } + + continue; + + } + #endif ConstantInt *CurLoc; @@ -431,15 +434,17 @@ bool AFLCoverage::runOnModule(Module &M) { prev_block_trans = (block_trans_1 ^ ... ^ block_trans_(n-1)" */ if (ngram_size) - PrevLocTrans = IRB.CreateXorReduce(PrevLoc); + PrevLocTrans = + IRB.CreateZExt(IRB.CreateXorReduce(PrevLoc), IRB.getInt32Ty()); else #endif PrevLocTrans = PrevLoc; + if (ctx_str) PrevLocTrans = IRB.CreateZExt(IRB.CreateXor(PrevLocTrans, PrevCtx), Int32Ty); else - PrevLocTrans = IRB.CreateZExt(PrevLoc, IRB.getInt32Ty()); + PrevLocTrans = IRB.CreateZExt(PrevLocTrans, IRB.getInt32Ty()); /* Load SHM pointer */ @@ -518,6 +523,23 @@ bool AFLCoverage::runOnModule(Module &M) { } + // in CTX mode we have to restore the original context for the caller - + // she might be calling other functions which need the correct CTX. + // Currently this is only needed for the Ubuntu clang-6.0 bug + if (ctx_str && has_calls && F.size() > 1) { + + Instruction *Inst = BB.getTerminator(); + if (isa(Inst) || isa(Inst)) { + + IRBuilder<> Post_IRB(Inst); + StoreInst * RestoreCtx = Post_IRB.CreateStore(PrevCtx, AFLContext); + RestoreCtx->setMetadata(M.getMDKindID("nosanitize"), + MDNode::get(C, None)); + + } + + } + inst_blocks++; } -- cgit 1.4.1 From 00683d06c2dc4a021929f25c86b8b426542c4e40 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 5 May 2020 20:10:54 +0200 Subject: fix LTO mode --- TODO.md | 3 ++- llvm_mode/afl-llvm-lto-instrumentation.so.cc | 16 ++++++---------- llvm_mode/afl-llvm-pass.so.cc | 3 +-- 3 files changed, 9 insertions(+), 13 deletions(-) (limited to 'llvm_mode/afl-llvm-pass.so.cc') diff --git a/TODO.md b/TODO.md index f326b6c7..dd88dcc2 100644 --- a/TODO.md +++ b/TODO.md @@ -2,7 +2,8 @@ ## Roadmap 2.65+ - - AFL_MAP_SIZE for afl-llvm-pass, qemu_mode and unicorn_mode + - InsTrim mode for LTO solution + - AFL_MAP_SIZE for qemu_mode and unicorn_mode - random crc32 HASH_CONST per run? because with 65536 paths we have collisions - namespace for targets? e.g. network - libradamsa as a custom module? diff --git a/llvm_mode/afl-llvm-lto-instrumentation.so.cc b/llvm_mode/afl-llvm-lto-instrumentation.so.cc index 2811d98e..838e45af 100644 --- a/llvm_mode/afl-llvm-lto-instrumentation.so.cc +++ b/llvm_mode/afl-llvm-lto-instrumentation.so.cc @@ -690,8 +690,7 @@ bool AFLLTOPass::runOnModule(Module &M) { if (map_addr) { GlobalVariable *AFLMapAddrFixed = new GlobalVariable( - M, Int64Ty, true, GlobalValue::ExternalLinkage, 0, "__afl_map_addr", - 0, GlobalVariable::GeneralDynamicTLSModel, 0, false); + M, Int64Ty, true, GlobalValue::ExternalLinkage, 0, "__afl_map_addr"); ConstantInt *MapAddr = ConstantInt::get(Int64Ty, map_addr); StoreInst * StoreMapAddr = IRB.CreateStore(MapAddr, AFLMapAddrFixed); StoreMapAddr->setMetadata(M.getMDKindID("nosanitize"), @@ -706,8 +705,7 @@ bool AFLLTOPass::runOnModule(Module &M) { if (afl_global_id % 8) write_loc = (((afl_global_id + 8) >> 3) << 3); GlobalVariable *AFLFinalLoc = new GlobalVariable( - M, Int32Ty, true, GlobalValue::ExternalLinkage, 0, "__afl_final_loc", - 0, GlobalVariable::GeneralDynamicTLSModel, 0, false); + M, Int32Ty, true, GlobalValue::ExternalLinkage, 0, "__afl_final_loc"); ConstantInt *const_loc = ConstantInt::get(Int32Ty, write_loc); StoreInst * StoreFinalLoc = IRB.CreateStore(const_loc, AFLFinalLoc); StoreFinalLoc->setMetadata(M.getMDKindID("nosanitize"), @@ -756,10 +754,9 @@ bool AFLLTOPass::runOnModule(Module &M) { } - GlobalVariable *AFLDictionaryLen = new GlobalVariable( - M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, - "__afl_dictionary_len", 0, GlobalVariable::GeneralDynamicTLSModel, - 0, false); + GlobalVariable *AFLDictionaryLen = + new GlobalVariable(M, Int32Ty, false, GlobalValue::ExternalLinkage, + 0, "__afl_dictionary_len"); ConstantInt *const_len = ConstantInt::get(Int32Ty, offset); StoreInst *StoreDictLen = IRB.CreateStore(const_len, AFLDictionaryLen); StoreDictLen->setMetadata(M.getMDKindID("nosanitize"), @@ -770,8 +767,7 @@ bool AFLLTOPass::runOnModule(Module &M) { M, ArrayTy, true, GlobalValue::ExternalLinkage, ConstantDataArray::get(C, *(new ArrayRef((char *)ptr, offset))), - "__afl_internal_dictionary", 0, - GlobalVariable::GeneralDynamicTLSModel, 0, false); + "__afl_internal_dictionary"); AFLInternalDictionary->setInitializer(ConstantDataArray::get( C, *(new ArrayRef((char *)ptr, offset)))); AFLInternalDictionary->setConstant(true); diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc index c0391b04..0d9e0aba 100644 --- a/llvm_mode/afl-llvm-pass.so.cc +++ b/llvm_mode/afl-llvm-pass.so.cc @@ -583,8 +583,7 @@ bool AFLCoverage::runOnModule(Module &M) { GlobalVariable *AFLFinalLoc = new GlobalVariable( M, Int32Ty, true, GlobalValue::ExternalLinkage, 0, - "__afl_final_loc", 0, GlobalVariable::GeneralDynamicTLSModel, 0, - false); + "__afl_final_loc"); ConstantInt *const_loc = ConstantInt::get(Int32Ty, map_size); StoreInst * StoreFinalLoc = IRB.CreateStore(const_loc, AFLFinalLoc); StoreFinalLoc->setMetadata(M.getMDKindID("nosanitize"), -- cgit 1.4.1