diff options
Diffstat (limited to 'instrumentation')
-rw-r--r-- | instrumentation/README.instrument_list.md | 6 | ||||
-rw-r--r-- | instrumentation/README.laf-intel.md | 2 | ||||
-rw-r--r-- | instrumentation/README.lto.md | 2 | ||||
-rw-r--r-- | instrumentation/README.out_of_line.md | 2 | ||||
-rw-r--r-- | instrumentation/README.persistent_mode.md | 13 | ||||
-rw-r--r-- | instrumentation/SanitizerCoverageLTO.so.cc | 39 | ||||
-rw-r--r-- | instrumentation/afl-compiler-rt.o.c | 4 | ||||
-rw-r--r-- | instrumentation/afl-llvm-dict2file.so.cc | 55 | ||||
-rw-r--r-- | instrumentation/afl-llvm-lto-instrumentation.so.cc | 38 | ||||
-rw-r--r-- | instrumentation/compare-transform-pass.so.cc | 39 |
10 files changed, 163 insertions, 37 deletions
diff --git a/instrumentation/README.instrument_list.md b/instrumentation/README.instrument_list.md index 2116d24c..7db9c055 100644 --- a/instrumentation/README.instrument_list.md +++ b/instrumentation/README.instrument_list.md @@ -1,4 +1,4 @@ -# Using afl++ with partial instrumentation +# Using AFL++ with partial instrumentation This file describes two different mechanisms to selectively instrument only specific parts in the target. @@ -13,7 +13,7 @@ the program, leaving the rest uninstrumented. This helps to focus the fuzzer on the important parts of the program, avoiding undesired noise and disturbance by uninteresting code being exercised. -For this purpose, "partial instrumentation" support is provided by afl++ that +For this purpose, "partial instrumentation" support is provided by AFL++ that allows to specify what should be instrumented and what not. Both mechanisms can be used together. @@ -100,7 +100,7 @@ exists somewhere else in the project directories. You can also specify function names. Note that for C++ the function names must be mangled to match! `nm` can print these names. -afl++ is able to identify whether an entry is a filename or a function. +AFL++ is able to identify whether an entry is a filename or a function. However if you want to be sure (and compliant to the sancov allow/blocklist format), you can specify source file entries like this: ``` diff --git a/instrumentation/README.laf-intel.md b/instrumentation/README.laf-intel.md index c50a6979..229807e8 100644 --- a/instrumentation/README.laf-intel.md +++ b/instrumentation/README.laf-intel.md @@ -7,7 +7,7 @@ His blog [Circumventing Fuzzing Roadblocks with Compiler Transformations] (https://lafintel.wordpress.com/) and gitlab repo [laf-llvm-pass] (https://gitlab.com/laf-intel/laf-llvm-pass/) describe some code transformations that -help afl++ to enter conditional blocks, where conditions consist of +help AFL++ to enter conditional blocks, where conditions consist of comparisons of large values. ## Usage diff --git a/instrumentation/README.lto.md b/instrumentation/README.lto.md index 39f6465a..626bc9cb 100644 --- a/instrumentation/README.lto.md +++ b/instrumentation/README.lto.md @@ -19,7 +19,7 @@ This version requires a current llvm 11+ compiled from the github master. ## Introduction and problem description -A big issue with how afl/afl++ works is that the basic block IDs that are +A big issue with how AFL/AFL++ works is that the basic block IDs that are set during compilation are random - and hence naturally the larger the number of instrumented locations, the higher the number of edge collisions are in the map. This can result in not discovering new paths and therefore degrade the diff --git a/instrumentation/README.out_of_line.md b/instrumentation/README.out_of_line.md index 2264f91f..346fe98d 100644 --- a/instrumentation/README.out_of_line.md +++ b/instrumentation/README.out_of_line.md @@ -1,4 +1,4 @@ -## Using afl++ without inlined instrumentation +## Using AFL++ without inlined instrumentation This file describes how you can disable inlining of instrumentation. diff --git a/instrumentation/README.persistent_mode.md b/instrumentation/README.persistent_mode.md index 24f81ea0..0517886b 100644 --- a/instrumentation/README.persistent_mode.md +++ b/instrumentation/README.persistent_mode.md @@ -2,13 +2,16 @@ ## 1) Introduction -The most effective way is to fuzz in persistent mode, as the speed can easily +In persistent mode, AFL++ fuzzes a target multiple times +in a single process, instead of forking a new process for each fuzz execution. +This is the most effective way to fuzz, as the speed can easily be x10 or x20 times faster without any disadvanges. -*All professional fuzzing is using this mode.* +*All professional fuzzing uses this mode.* -This requires that the target can be called in a (or several) function(s), -and that its state can be resetted so that multiple calls can be performed -without resource leaks and former runs having no impact on following runs + +Persistent mode requires that the target can be called in one or more functions, +and that its state can be reset so that multiple calls can be performed +without resource leaks and earlier runs will have no impact on future runs (this can be seen by the `stability` indicator in the `afl-fuzz` UI). Examples can be found in [utils/persistent_mode](../utils/persistent_mode). diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index 91b81910..e06f8b93 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -626,12 +626,41 @@ bool ModuleSanitizerCoverage::instrumentModule( if (!Callee) continue; if (callInst->getCallingConv() != llvm::CallingConv::C) continue; std::string FuncName = Callee->getName().str(); - isStrcmp &= !FuncName.compare("strcmp"); + + isStrcmp &= (!FuncName.compare("strcmp") || + !FuncName.compare("xmlStrcmp") || + !FuncName.compare("xmlStrEqual") || + !FuncName.compare("g_strcmp0") || + !FuncName.compare("curl_strequal") || + !FuncName.compare("strcsequal")); isMemcmp &= - (!FuncName.compare("memcmp") || !FuncName.compare("bcmp")); - isStrncmp &= !FuncName.compare("strncmp"); - isStrcasecmp &= !FuncName.compare("strcasecmp"); - isStrncasecmp &= !FuncName.compare("strncasecmp"); + (!FuncName.compare("memcmp") || !FuncName.compare("bcmp") || + !FuncName.compare("CRYPTO_memcmp") || + !FuncName.compare("OPENSSL_memcmp") || + !FuncName.compare("memcmp_const_time") || + !FuncName.compare("memcmpct")); + isStrncmp &= (!FuncName.compare("strncmp") || + !FuncName.compare("xmlStrncmp") || + !FuncName.compare("curl_strnequal")); + isStrcasecmp &= (!FuncName.compare("strcasecmp") || + !FuncName.compare("stricmp") || + !FuncName.compare("ap_cstr_casecmp") || + !FuncName.compare("OPENSSL_strcasecmp") || + !FuncName.compare("xmlStrcasecmp") || + !FuncName.compare("g_strcasecmp") || + !FuncName.compare("g_ascii_strcasecmp") || + !FuncName.compare("Curl_strcasecompare") || + !FuncName.compare("Curl_safe_strcasecompare") || + !FuncName.compare("cmsstrcasecmp")); + isStrncasecmp &= (!FuncName.compare("strncasecmp") || + !FuncName.compare("strnicmp") || + !FuncName.compare("ap_cstr_casecmpn") || + !FuncName.compare("OPENSSL_strncasecmp") || + !FuncName.compare("xmlStrncasecmp") || + !FuncName.compare("g_ascii_strncasecmp") || + !FuncName.compare("Curl_strncasecompare") || + !FuncName.compare("g_strncasecmp")); + isIntMemcpy &= !FuncName.compare("llvm.memcpy.p0i8.p0i8.i64"); isStdString &= ((FuncName.find("basic_string") != std::string::npos && diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index b01ea987..18b0a55b 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -320,7 +320,7 @@ static void __afl_map_shm(void) { fprintf(stderr, "DEBUG: (1) id_str %s, __afl_area_ptr %p, __afl_area_initial %p, " - "__afl_area_ptr_dummy 0x%p, __afl_map_addr 0x%llx, MAP_SIZE %u, " + "__afl_area_ptr_dummy %p, __afl_map_addr 0x%llx, MAP_SIZE %u, " "__afl_final_loc %u, " "max_size_forkserver %u/0x%x\n", id_str == NULL ? "<null>" : id_str, __afl_area_ptr, @@ -471,7 +471,7 @@ static void __afl_map_shm(void) { fprintf(stderr, "DEBUG: (2) id_str %s, __afl_area_ptr %p, __afl_area_initial %p, " - "__afl_area_ptr_dummy 0x%p, __afl_map_addr 0x%llx, MAP_SIZE " + "__afl_area_ptr_dummy %p, __afl_map_addr 0x%llx, MAP_SIZE " "%u, __afl_final_loc %u, " "max_size_forkserver %u/0x%x\n", id_str == NULL ? "<null>" : id_str, __afl_area_ptr, diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc index 9daa75a8..4622e488 100644 --- a/instrumentation/afl-llvm-dict2file.so.cc +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -288,6 +288,7 @@ bool AFLdict2filePass::runOnModule(Module &M) { bool isStrncasecmp = true; bool isIntMemcpy = true; bool isStdString = true; + bool isStrstr = true; bool addedNull = false; size_t optLen = 0; @@ -295,12 +296,46 @@ bool AFLdict2filePass::runOnModule(Module &M) { if (!Callee) continue; if (callInst->getCallingConv() != llvm::CallingConv::C) continue; std::string FuncName = Callee->getName().str(); - isStrcmp &= !FuncName.compare("strcmp"); + isStrcmp &= + (!FuncName.compare("strcmp") || !FuncName.compare("xmlStrcmp") || + !FuncName.compare("xmlStrEqual") || + !FuncName.compare("g_strcmp0") || + !FuncName.compare("curl_strequal") || + !FuncName.compare("strcsequal")); isMemcmp &= - (!FuncName.compare("memcmp") || !FuncName.compare("bcmp")); - isStrncmp &= !FuncName.compare("strncmp"); - isStrcasecmp &= !FuncName.compare("strcasecmp"); - isStrncasecmp &= !FuncName.compare("strncasecmp"); + (!FuncName.compare("memcmp") || !FuncName.compare("bcmp") || + !FuncName.compare("CRYPTO_memcmp") || + !FuncName.compare("OPENSSL_memcmp") || + !FuncName.compare("memcmp_const_time") || + !FuncName.compare("memcmpct")); + isStrncmp &= (!FuncName.compare("strncmp") || + !FuncName.compare("xmlStrncmp") || + !FuncName.compare("curl_strnequal")); + isStrcasecmp &= (!FuncName.compare("strcasecmp") || + !FuncName.compare("stricmp") || + !FuncName.compare("ap_cstr_casecmp") || + !FuncName.compare("OPENSSL_strcasecmp") || + !FuncName.compare("xmlStrcasecmp") || + !FuncName.compare("g_strcasecmp") || + !FuncName.compare("g_ascii_strcasecmp") || + !FuncName.compare("Curl_strcasecompare") || + !FuncName.compare("Curl_safe_strcasecompare") || + !FuncName.compare("cmsstrcasecmp")); + isStrncasecmp &= (!FuncName.compare("strncasecmp") || + !FuncName.compare("strnicmp") || + !FuncName.compare("ap_cstr_casecmpn") || + !FuncName.compare("OPENSSL_strncasecmp") || + !FuncName.compare("xmlStrncasecmp") || + !FuncName.compare("g_ascii_strncasecmp") || + !FuncName.compare("Curl_strncasecompare") || + !FuncName.compare("g_strncasecmp")); + isStrstr &= (!FuncName.compare("strstr") || + !FuncName.compare("g_strstr_len") || + !FuncName.compare("ap_strcasestr") || + !FuncName.compare("xmlStrstr") || + !FuncName.compare("xmlStrcasestr") || + !FuncName.compare("g_str_has_prefix") || + !FuncName.compare("g_str_has_suffix")); isIntMemcpy &= !FuncName.compare("llvm.memcpy.p0i8.p0i8.i64"); isStdString &= ((FuncName.find("basic_string") != std::string::npos && FuncName.find("compare") != std::string::npos) || @@ -308,13 +343,17 @@ bool AFLdict2filePass::runOnModule(Module &M) { FuncName.find("find") != std::string::npos)); if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp && - !isStrncasecmp && !isIntMemcpy && !isStdString) + !isStrncasecmp && !isIntMemcpy && !isStdString && !isStrstr) continue; /* Verify the strcmp/memcmp/strncmp/strcasecmp/strncasecmp function * prototype */ FunctionType *FT = Callee->getFunctionType(); + isStrstr &= + FT->getNumParams() == 2 && + FT->getParamType(0) == FT->getParamType(1) && + FT->getParamType(0) == IntegerType::getInt8PtrTy(M.getContext()); isStrcmp &= FT->getNumParams() == 2 && FT->getReturnType()->isIntegerTy(32) && FT->getParamType(0) == FT->getParamType(1) && @@ -345,7 +384,7 @@ bool AFLdict2filePass::runOnModule(Module &M) { FT->getParamType(1)->isPointerTy(); if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp && - !isStrncasecmp && !isIntMemcpy && !isStdString) + !isStrncasecmp && !isIntMemcpy && !isStdString && !isStrstr) continue; /* is a str{n,}{case,}cmp/memcmp, check if we have @@ -359,7 +398,7 @@ bool AFLdict2filePass::runOnModule(Module &M) { bool HasStr1; getConstantStringInfo(Str1P, TmpStr); - if (TmpStr.empty()) { + if (isStrstr || TmpStr.empty()) { HasStr1 = false; diff --git a/instrumentation/afl-llvm-lto-instrumentation.so.cc b/instrumentation/afl-llvm-lto-instrumentation.so.cc index 263d947d..e300044c 100644 --- a/instrumentation/afl-llvm-lto-instrumentation.so.cc +++ b/instrumentation/afl-llvm-lto-instrumentation.so.cc @@ -393,12 +393,40 @@ bool AFLLTOPass::runOnModule(Module &M) { if (!Callee) continue; if (callInst->getCallingConv() != llvm::CallingConv::C) continue; std::string FuncName = Callee->getName().str(); - isStrcmp &= !FuncName.compare("strcmp"); + + isStrcmp &= (!FuncName.compare("strcmp") || + !FuncName.compare("xmlStrcmp") || + !FuncName.compare("xmlStrEqual") || + !FuncName.compare("g_strcmp0") || + !FuncName.compare("curl_strequal") || + !FuncName.compare("strcsequal")); isMemcmp &= - (!FuncName.compare("memcmp") || !FuncName.compare("bcmp")); - isStrncmp &= !FuncName.compare("strncmp"); - isStrcasecmp &= !FuncName.compare("strcasecmp"); - isStrncasecmp &= !FuncName.compare("strncasecmp"); + (!FuncName.compare("memcmp") || !FuncName.compare("bcmp") || + !FuncName.compare("CRYPTO_memcmp") || + !FuncName.compare("OPENSSL_memcmp") || + !FuncName.compare("memcmp_const_time") || + !FuncName.compare("memcmpct")); + isStrncmp &= (!FuncName.compare("strncmp") || + !FuncName.compare("xmlStrncmp") || + !FuncName.compare("curl_strnequal")); + isStrcasecmp &= (!FuncName.compare("strcasecmp") || + !FuncName.compare("stricmp") || + !FuncName.compare("ap_cstr_casecmp") || + !FuncName.compare("OPENSSL_strcasecmp") || + !FuncName.compare("xmlStrcasecmp") || + !FuncName.compare("g_strcasecmp") || + !FuncName.compare("g_ascii_strcasecmp") || + !FuncName.compare("Curl_strcasecompare") || + !FuncName.compare("Curl_safe_strcasecompare") || + !FuncName.compare("cmsstrcasecmp")); + isStrncasecmp &= (!FuncName.compare("strncasecmp") || + !FuncName.compare("strnicmp") || + !FuncName.compare("ap_cstr_casecmpn") || + !FuncName.compare("OPENSSL_strncasecmp") || + !FuncName.compare("xmlStrncasecmp") || + !FuncName.compare("g_ascii_strncasecmp") || + !FuncName.compare("Curl_strncasecompare") || + !FuncName.compare("g_strncasecmp")); isIntMemcpy &= !FuncName.compare("llvm.memcpy.p0i8.p0i8.i64"); isStdString &= ((FuncName.find("basic_string") != std::string::npos && diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc index f5dd4a53..288e8282 100644 --- a/instrumentation/compare-transform-pass.so.cc +++ b/instrumentation/compare-transform-pass.so.cc @@ -151,12 +151,39 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, if (!Callee) continue; if (callInst->getCallingConv() != llvm::CallingConv::C) continue; StringRef FuncName = Callee->getName(); - isStrcmp &= !FuncName.compare(StringRef("strcmp")); - isMemcmp &= (!FuncName.compare(StringRef("memcmp")) || - !FuncName.compare(StringRef("bcmp"))); - isStrncmp &= !FuncName.compare(StringRef("strncmp")); - isStrcasecmp &= !FuncName.compare(StringRef("strcasecmp")); - isStrncasecmp &= !FuncName.compare(StringRef("strncasecmp")); + isStrcmp &= + (!FuncName.compare("strcmp") || !FuncName.compare("xmlStrcmp") || + !FuncName.compare("xmlStrEqual") || + !FuncName.compare("g_strcmp0") || + !FuncName.compare("curl_strequal") || + !FuncName.compare("strcsequal")); + isMemcmp &= + (!FuncName.compare("memcmp") || !FuncName.compare("bcmp") || + !FuncName.compare("CRYPTO_memcmp") || + !FuncName.compare("OPENSSL_memcmp") || + !FuncName.compare("memcmp_const_time") || + !FuncName.compare("memcmpct")); + isStrncmp &= (!FuncName.compare("strncmp") || + !FuncName.compare("xmlStrncmp") || + !FuncName.compare("curl_strnequal")); + isStrcasecmp &= (!FuncName.compare("strcasecmp") || + !FuncName.compare("stricmp") || + !FuncName.compare("ap_cstr_casecmp") || + !FuncName.compare("OPENSSL_strcasecmp") || + !FuncName.compare("xmlStrcasecmp") || + !FuncName.compare("g_strcasecmp") || + !FuncName.compare("g_ascii_strcasecmp") || + !FuncName.compare("Curl_strcasecompare") || + !FuncName.compare("Curl_safe_strcasecompare") || + !FuncName.compare("cmsstrcasecmp")); + isStrncasecmp &= (!FuncName.compare("strncasecmp") || + !FuncName.compare("strnicmp") || + !FuncName.compare("ap_cstr_casecmpn") || + !FuncName.compare("OPENSSL_strncasecmp") || + !FuncName.compare("xmlStrncasecmp") || + !FuncName.compare("g_ascii_strncasecmp") || + !FuncName.compare("Curl_strncasecompare") || + !FuncName.compare("g_strncasecmp")); isIntMemcpy &= !FuncName.compare("llvm.memcpy.p0i8.p0i8.i64"); if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp && |