diff options
-rw-r--r-- | GNUmakefile | 2 | ||||
-rw-r--r-- | README.md | 4 | ||||
-rw-r--r-- | docs/Changelog.md | 17 | ||||
-rw-r--r-- | docs/afl-fuzz_approach.md | 4 | ||||
-rw-r--r-- | docs/custom_mutators.md | 4 | ||||
-rw-r--r-- | docs/fuzzing_binary-only_targets.md | 8 | ||||
-rw-r--r-- | docs/tutorials.md | 5 | ||||
-rw-r--r-- | frida_mode/src/main.c | 4 | ||||
-rw-r--r-- | frida_mode/src/ranges.c | 2 | ||||
-rw-r--r-- | include/afl-mutations.h | 35 | ||||
-rw-r--r-- | include/config.h | 2 | ||||
-rw-r--r-- | include/envs.h | 1 | ||||
-rw-r--r-- | instrumentation/SanitizerCoverageLTO.so.cc | 54 | ||||
-rw-r--r-- | instrumentation/SanitizerCoveragePCGUARD.so.cc | 4 | ||||
-rw-r--r-- | instrumentation/afl-llvm-common.cc | 8 | ||||
-rw-r--r-- | instrumentation/afl-llvm-dict2file.so.cc | 33 | ||||
-rw-r--r-- | instrumentation/cmplog-routines-pass.cc | 15 | ||||
-rw-r--r-- | instrumentation/compare-transform-pass.so.cc | 30 | ||||
m--------- | nyx_mode/QEMU-Nyx | 0 | ||||
m--------- | nyx_mode/libnyx | 0 | ||||
m--------- | nyx_mode/packer | 0 | ||||
-rw-r--r-- | src/afl-cc.c | 2 | ||||
-rw-r--r-- | src/afl-fuzz-bitmap.c | 11 | ||||
-rw-r--r-- | src/afl-fuzz-state.c | 3 | ||||
-rw-r--r-- | src/afl-fuzz.c | 2 | ||||
-rw-r--r-- | utils/aflpp_driver/aflpp_driver.c | 7 |
26 files changed, 163 insertions, 94 deletions
diff --git a/GNUmakefile b/GNUmakefile index 5fd37147..364cdde1 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -816,7 +816,7 @@ endif .PHONY: uninstall uninstall: - -cd $${DESTDIR}$(BIN_PATH) && rm -f $(PROGS) $(SH_PROGS) afl-cs-proxy afl-qemu-trace afl-plot-ui afl-fuzz-document afl-network-server afl-g* afl-plot.sh afl-as afl-ld-lto afl-c* afl-lto* + -cd $${DESTDIR}$(BIN_PATH) && rm -f $(PROGS) $(SH_PROGS) afl-cs-proxy afl-qemu-trace afl-plot-ui afl-fuzz-document afl-network-client afl-network-server afl-g* afl-plot.sh afl-as afl-ld-lto afl-c* afl-lto* -cd $${DESTDIR}$(HELPER_PATH) && rm -f afl-g*.*o afl-llvm-*.*o afl-compiler-*.*o libdislocator.so libtokencap.so libcompcov.so libqasan.so afl-frida-trace.so libnyx.so socketfuzz*.so argvfuzz*.so libAFLDriver.a libAFLQemuDriver.a as afl-as SanitizerCoverage*.so compare-transform-pass.so cmplog-*-pass.so split-*-pass.so dynamic_list.txt -rm -rf $${DESTDIR}$(MISC_PATH)/testcases $${DESTDIR}$(MISC_PATH)/dictionaries -sh -c "ls docs/*.md | sed 's|^docs/|$${DESTDIR}$(DOC_PATH)/|' | xargs rm -f" diff --git a/README.md b/README.md index 322ebcf2..fd48cb14 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ <img align="right" src="https://raw.githubusercontent.com/AFLplusplus/Website/main/static/aflpp_bg.svg" alt="AFL++ logo" width="250" heigh="250"> -Release version: [4.08c](https://github.com/AFLplusplus/AFLplusplus/releases) +Release version: [4.09c](https://github.com/AFLplusplus/AFLplusplus/releases) -GitHub version: 4.09a +GitHub version: 4.10a Repository: [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus) diff --git a/docs/Changelog.md b/docs/Changelog.md index b2e9fbf6..c8f04217 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -3,8 +3,19 @@ This is the list of all noteworthy changes made in every public release of the tool. See README.md for the general instruction manual. -### Version ++4.09a (dev) +### Version ++4.10a (dev) - afl-fuzz: + - default power schedule is now EXPLORE, due a fix in fast schedules + explore is slightly better now. + - fixed minor issues in the mutation engine, thanks to @futhewo for + reporting! + - instrumentation: + - LLVM 18 support, thanks to @devnexen! + + +### Version ++4.09c (release) + - afl-fuzz: + - fixed the new mutation implementation for two bugs - added `AFL_FINAL_SYNC` which forces a final fuzzer sync (also for `-F`) before terminating. - added AFL_IGNORE_SEED_PROBLEMS to skip over seeds that time out instead @@ -23,14 +34,16 @@ - option -n will not use color in the output - instrumentation: - fix for a few string compare transform functions for LAF + - we are instrumenting __cxx internal functions again. this might break + a few targets, please report if so. - frida_mode: - fixes support for large map offsets + - support for AFL_FUZZER_LOOPCOUNT for afl.rs and LLVMFuzzerTestOneInput - afl-cmin/afl-cmin.bash: prevent unneeded file errors - added new tool afl-addseeds that adds new seeds to a running campaign - added benchmark/benchmark.py if you want to see how good your fuzzing speed is in comparison to other setups. - ### Version ++4.08c (release) - afl-fuzz: - new mutation engine: mutations that favor discovery more paths are diff --git a/docs/afl-fuzz_approach.md b/docs/afl-fuzz_approach.md index 7d18b178..9ea06325 100644 --- a/docs/afl-fuzz_approach.md +++ b/docs/afl-fuzz_approach.md @@ -5,6 +5,10 @@ instrumentation-guided genetic algorithm. It uses a modified form of edge coverage to effortlessly pick up subtle, local-scale changes to program control flow. +Note: If you are interested in a more current up-to-date deep dive how AFL++ +works then we commend this blog post: +[https://blog.ritsec.club/posts/afl-under-hood/](https://blog.ritsec.club/posts/afl-under-hood/) + Simplifying a bit, the overall algorithm can be summed up as: 1) Load user-supplied initial test cases into the queue. diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index 1c4ab2cf..ce0a42dc 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -198,7 +198,7 @@ def deinit(): # optional for Python This method can be used if you want to send data to the target yourself, e.g. via IPC. This replaces some usage of utils/afl_proxy but requires that you start the target with afl-fuzz. - Example: [custom_mutators/examples/custom_send.c](custom_mutators/examples/custom_send.c) + Example: [custom_mutators/examples/custom_send.c](../custom_mutators/examples/custom_send.c) - `queue_new_entry` (optional): @@ -377,4 +377,4 @@ See [example.c](../custom_mutators/examples/example.c) and - [bruce30262/libprotobuf-mutator_fuzzing_learning](https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator) - [thebabush/afl-libprotobuf-mutator](https://github.com/thebabush/afl-libprotobuf-mutator) - [XML Fuzzing@NullCon 2017](https://www.agarri.fr/docs/XML_Fuzzing-NullCon2017-PUBLIC.pdf) - - [A bug detected by AFL + XML-aware mutators](https://bugs.chromium.org/p/chromium/issues/detail?id=930663) \ No newline at end of file + - [A bug detected by AFL + XML-aware mutators](https://bugs.chromium.org/p/chromium/issues/detail?id=930663) diff --git a/docs/fuzzing_binary-only_targets.md b/docs/fuzzing_binary-only_targets.md index 9d9d6bb6..a151bce4 100644 --- a/docs/fuzzing_binary-only_targets.md +++ b/docs/fuzzing_binary-only_targets.md @@ -94,8 +94,7 @@ For more information, see In FRIDA mode, you can fuzz binary-only targets as easily as with QEMU mode. FRIDA mode is most of the times slightly faster than QEMU mode. It is also -newer, lacks COMPCOV, and has the advantage that it works on MacOS (both intel -and M1). +newer, and has the advantage that it works on MacOS (both intel and M1). To build FRIDA mode: @@ -113,10 +112,6 @@ The mode is approximately 2-5x slower than compile-time instrumentation, and is less conducive to parallelization. But for binary-only fuzzing, it gives a huge speed improvement if it is possible to use. -If you want to fuzz a binary-only library, then you can fuzz it with frida-gum -via frida_mode/. You will have to write a harness to call the target function in -the library, use afl-frida.c as a template. - You can also perform remote fuzzing with frida, e.g., if you want to fuzz on iPhone or Android devices, for this you can use [https://github.com/ttdennis/fpicker/](https://github.com/ttdennis/fpicker/) as @@ -302,7 +297,6 @@ some are very hard to set up... * S2E: [https://github.com/S2E](https://github.com/S2E) * TinyInst: [https://github.com/googleprojectzero/TinyInst](https://github.com/googleprojectzero/TinyInst) - (Mac/Windows only) * ... please send me any missing that are good ## Closing words diff --git a/docs/tutorials.md b/docs/tutorials.md index a5ee3322..0a09f6dc 100644 --- a/docs/tutorials.md +++ b/docs/tutorials.md @@ -21,7 +21,7 @@ training, then we can highly recommend the following: * [https://github.com/antonio-morales/Fuzzing101](https://github.com/antonio-morales/Fuzzing101) -Here is a good forkflow description (and tutorial) for qemu_mode: +Here is a good workflow description (and tutorial) for qemu_mode: * [https://airbus-seclab.github.io/AFLplusplus-blogpost/](https://airbus-seclab.github.io/AFLplusplus-blogpost/) @@ -41,6 +41,9 @@ structure is), these links have you covered (some are outdated though): * Superion for AFL++: [https://github.com/adrian-rt/superion-mutator](https://github.com/adrian-rt/superion-mutator) +For a very in-depth explanation on how AFL++ works check out: +[https://blog.ritsec.club/posts/afl-under-hood/](https://blog.ritsec.club/posts/afl-under-hood/) + ## Video Tutorials * [Install AFL++ Ubuntu](https://www.youtube.com/watch?v=5dCvhkbi3RA) diff --git a/frida_mode/src/main.c b/frida_mode/src/main.c index bd7b1351..9daf067b 100644 --- a/frida_mode/src/main.c +++ b/frida_mode/src/main.c @@ -166,7 +166,7 @@ static void afl_print_env(void) { if (fd < 0) { - FWARNF("Failed to open /proc/self/cmdline, errno: (%d)", errno); + FWARNF("Failed to open /proc/self/environ, errno: (%d)", errno); return; } @@ -174,7 +174,7 @@ static void afl_print_env(void) { ssize_t bytes_read = read(fd, buffer, PROC_MAX - 1); if (bytes_read < 0) { - FFATAL("Failed to read /proc/self/cmdline, errno: (%d)", errno); + FFATAL("Failed to read /proc/self/environ, errno: (%d)", errno); } diff --git a/frida_mode/src/ranges.c b/frida_mode/src/ranges.c index e9fc3b4e..269ba59b 100644 --- a/frida_mode/src/ranges.c +++ b/frida_mode/src/ranges.c @@ -653,7 +653,7 @@ void ranges_init(void) { /* * After step 4 we have the total ranges to be instrumented, we now subtract * that either from the original ranges of the modules or from the whole - * memory if AFL_INST_NO_DYNAMIC_LOAD to configure the stalker. + * memory if AFL_FRIDA_INST_NO_DYNAMIC_LOAD to configure the stalker. */ if (ranges_inst_dynamic_load) { diff --git a/include/afl-mutations.h b/include/afl-mutations.h index d709b90d..75e66484 100644 --- a/include/afl-mutations.h +++ b/include/afl-mutations.h @@ -1082,6 +1082,7 @@ u32 mutation_strategy_exploration_binary[MUT_STRATEGY_ARRAY_SIZE] = { MUT_CLONE_COPY, MUT_CLONE_COPY, MUT_CLONE_COPY, + MUT_CLONE_COPY, MUT_CLONE_FIXED, MUT_CLONE_FIXED, MUT_CLONE_FIXED, @@ -2456,14 +2457,14 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps, } - char buf[20]; - snprintf(buf, sizeof(buf), "%" PRId64, val); + char numbuf[32]; + snprintf(numbuf, sizeof(buf), "%" PRId64, val); u32 old_len = off2 - off; - u32 new_len = strlen(buf); + u32 new_len = strlen(numbuf); if (old_len == new_len) { - memcpy(buf + off, buf, new_len); + memcpy(buf + off, numbuf, new_len); } else { @@ -2473,7 +2474,7 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps, /* Inserted part */ - memcpy(tmp_buf + off, buf, new_len); + memcpy(tmp_buf + off, numbuf, new_len); /* Tail */ memcpy(tmp_buf + off + new_len, buf + off2, len - off2); @@ -2490,12 +2491,13 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps, case MUT_INSERTASCIINUM: { - u32 len = 1 + rand_below(afl, 8); + u32 ins_len = 1 + rand_below(afl, 8); u32 pos = rand_below(afl, len); /* Insert ascii number. */ - if (unlikely(len < pos + len)) { + if (unlikely(len < pos + ins_len)) { + // no retry if we have a small input if (unlikely(len < 8)) { break; @@ -2509,9 +2511,22 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps, } u64 val = rand_next(afl); - char buf[20]; - snprintf(buf, sizeof(buf), "%llu", val); - memcpy(buf + pos, buf, len); + char numbuf[32]; + snprintf(numbuf, sizeof(numbuf), "%llu", val); + size_t val_len = strlen(numbuf), off; + + if (ins_len > val_len) { + + ins_len = val_len; + off = 0; + + } else { + + off = val_len - ins_len; + + } + + memcpy(buf + pos, numbuf + off, ins_len); break; diff --git a/include/config.h b/include/config.h index 988e536e..63340650 100644 --- a/include/config.h +++ b/include/config.h @@ -26,7 +26,7 @@ /* Version string: */ // c = release, a = volatile github dev, e = experimental branch -#define VERSION "++4.09a" +#define VERSION "++4.10a" /****************************************************** * * diff --git a/include/envs.h b/include/envs.h index 93e49e34..560092d9 100644 --- a/include/envs.h +++ b/include/envs.h @@ -172,6 +172,7 @@ static char *afl_environment_variables[] = { "AFL_LLVM_LTO_DONTWRITEID", "AFL_LLVM_LTO_SKIPINIT" "AFL_LLVM_LTO_STARTID", + "AFL_FUZZER_LOOPCOUNT", "AFL_NO_ARITH", "AFL_NO_AUTODICT", "AFL_NO_BUILTIN", diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index c70fbd4f..68423029 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -692,33 +692,37 @@ bool ModuleSanitizerCoverageLTO::instrumentModule( * 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()); + isStrcmp &= + FT->getNumParams() == 2 && + FT->getReturnType()->isIntegerTy(32) && + FT->getParamType(0) == FT->getParamType(1) && + FT->getParamType(0) == + IntegerType::getInt8Ty(M.getContext())->getPointerTo(0); + isStrcasecmp &= + FT->getNumParams() == 2 && + FT->getReturnType()->isIntegerTy(32) && + FT->getParamType(0) == FT->getParamType(1) && + FT->getParamType(0) == + IntegerType::getInt8Ty(M.getContext())->getPointerTo(0); 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(); + isStrncmp &= + FT->getNumParams() == 3 && + FT->getReturnType()->isIntegerTy(32) && + FT->getParamType(0) == FT->getParamType(1) && + FT->getParamType(0) == + IntegerType::getInt8Ty(M.getContext())->getPointerTo(0) && + FT->getParamType(2)->isIntegerTy(); + isStrncasecmp &= + FT->getNumParams() == 3 && + FT->getReturnType()->isIntegerTy(32) && + FT->getParamType(0) == FT->getParamType(1) && + FT->getParamType(0) == + IntegerType::getInt8Ty(M.getContext())->getPointerTo(0) && + FT->getParamType(2)->isIntegerTy(); isStdString &= FT->getNumParams() >= 2 && FT->getParamType(0)->isPointerTy() && FT->getParamType(1)->isPointerTy(); @@ -1241,7 +1245,11 @@ void ModuleSanitizerCoverageLTO::instrumentFunction( if (F.empty()) return; if (F.getName().find(".module_ctor") != std::string::npos) return; // Should not instrument sanitizer init functions. +#if LLVM_VERSION_MAJOR >= 18 + if (F.getName().starts_with("__sanitizer_")) +#else if (F.getName().startswith("__sanitizer_")) +#endif return; // Don't instrument __sanitizer_* callbacks. // Don't touch available_externally functions, their actual body is elsewhere. if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) return; @@ -1493,7 +1501,7 @@ GlobalVariable *ModuleSanitizerCoverageLTO::CreateFunctionLocalArrayInSection( Array->setComdat(Comdat); #endif Array->setSection(getSectionName(Section)); - Array->setAlignment(Align(DL->getTypeStoreSize(Ty).getFixedSize())); + Array->setAlignment(Align(DL->getTypeStoreSize(Ty).getFixedValue())); GlobalsToAppendToUsed.push_back(Array); GlobalsToAppendToCompilerUsed.push_back(Array); MDNode *MD = MDNode::get(F.getContext(), ValueAsMetadata::get(&F)); diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index 588eb950..1c019d26 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -572,7 +572,11 @@ void ModuleSanitizerCoverageAFL::instrumentFunction( if (!isInInstrumentList(&F, FMNAME)) return; if (F.getName().find(".module_ctor") != std::string::npos) return; // Should not instrument sanitizer init functions. +#if LLVM_VERSION_MAJOR >= 18 + if (F.getName().starts_with("__sanitizer_")) +#else if (F.getName().startswith("__sanitizer_")) +#endif return; // Don't instrument __sanitizer_* callbacks. // Don't touch available_externally functions, their actual body is elewhere. if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) return; diff --git a/instrumentation/afl-llvm-common.cc b/instrumentation/afl-llvm-common.cc index 7f17b02d..96952bd6 100644 --- a/instrumentation/afl-llvm-common.cc +++ b/instrumentation/afl-llvm-common.cc @@ -97,11 +97,15 @@ bool isIgnoreFunction(const llvm::Function *F) { static constexpr const char *ignoreSubstringList[] = { - "__asan", "__msan", "__ubsan", "__lsan", "__san", "__sanitize", - "__cxx", "DebugCounter", "DwarfDebug", "DebugLoc" + "__asan", "__msan", "__ubsan", "__lsan", "__san", + "__sanitize", "DebugCounter", "DwarfDebug", "DebugLoc" }; + // This check is very sensitive, we must be sure to not include patterns + // that are part of user-written C++ functions like the ones including + // std::string as parameter (see #1927) as the mangled type is inserted in the + // mangled name of the user-written function for (auto const &ignoreListFunc : ignoreSubstringList) { // hexcoder: F->getName().contains() not avaiilable in llvm 3.8.0 diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc index 59b16ca0..c60f3e06 100644 --- a/instrumentation/afl-llvm-dict2file.so.cc +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -433,32 +433,35 @@ bool AFLdict2filePass::runOnModule(Module &M) { isStrstr &= FT->getNumParams() == 2 && FT->getParamType(0) == FT->getParamType(1) && - FT->getParamType(0) == IntegerType::getInt8PtrTy(M.getContext()); + FT->getParamType(0) == + IntegerType::getInt8Ty(M.getContext())->getPointerTo(0); isStrcmp &= FT->getNumParams() == 2 && FT->getReturnType()->isIntegerTy(32) && FT->getParamType(0) == FT->getParamType(1) && - FT->getParamType(0) == IntegerType::getInt8PtrTy(M.getContext()); + FT->getParamType(0) == + IntegerType::getInt8Ty(M.getContext())->getPointerTo(0); isStrcasecmp &= FT->getNumParams() == 2 && FT->getReturnType()->isIntegerTy(32) && FT->getParamType(0) == FT->getParamType(1) && - FT->getParamType(0) == IntegerType::getInt8PtrTy(M.getContext()); + FT->getParamType(0) == + IntegerType::getInt8Ty(M.getContext())->getPointerTo(0); 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(); + isStrncmp &= + FT->getNumParams() == 3 && FT->getReturnType()->isIntegerTy(32) && + FT->getParamType(0) == FT->getParamType(1) && + FT->getParamType(0) == + IntegerType::getInt8Ty(M.getContext())->getPointerTo(0) && + FT->getParamType(2)->isIntegerTy(); + isStrncasecmp &= + FT->getNumParams() == 3 && FT->getReturnType()->isIntegerTy(32) && + FT->getParamType(0) == FT->getParamType(1) && + FT->getParamType(0) == + IntegerType::getInt8Ty(M.getContext())->getPointerTo(0) && + FT->getParamType(2)->isIntegerTy(); isStdString &= FT->getNumParams() >= 2 && FT->getParamType(0)->isPointerTy() && FT->getParamType(1)->isPointerTy(); diff --git a/instrumentation/cmplog-routines-pass.cc b/instrumentation/cmplog-routines-pass.cc index 54e9ddf3..b27e06e0 100644 --- a/instrumentation/cmplog-routines-pass.cc +++ b/instrumentation/cmplog-routines-pass.cc @@ -385,7 +385,8 @@ bool CmpLogRoutines::hookRtns(Module &M) { isStrcmp &= FT->getNumParams() == 2 && FT->getReturnType()->isIntegerTy(32) && FT->getParamType(0) == FT->getParamType(1) && - FT->getParamType(0) == IntegerType::getInt8PtrTy(M.getContext()); + FT->getParamType(0) == + IntegerType::getInt8Ty(M.getContext())->getPointerTo(0); bool isStrncmp = (!FuncName.compare("strncmp") || !FuncName.compare("xmlStrncmp") || @@ -398,12 +399,12 @@ bool CmpLogRoutines::hookRtns(Module &M) { !FuncName.compare("g_ascii_strncasecmp") || !FuncName.compare("Curl_strncasecompare") || !FuncName.compare("g_strncasecmp")); - 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(); + isStrncmp &= + FT->getNumParams() == 3 && FT->getReturnType()->isIntegerTy(32) && + FT->getParamType(0) == FT->getParamType(1) && + FT->getParamType(0) == + IntegerType::getInt8Ty(M.getContext())->getPointerTo(0) && + FT->getParamType(2)->isIntegerTy(); bool isGccStdStringStdString = Callee->getName().find("__is_charIT_EE7__value") != diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc index 5a5415d7..b0d6355a 100644 --- a/instrumentation/compare-transform-pass.so.cc +++ b/instrumentation/compare-transform-pass.so.cc @@ -271,28 +271,30 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, isStrcmp &= FT->getNumParams() == 2 && FT->getReturnType()->isIntegerTy(32) && FT->getParamType(0) == FT->getParamType(1) && - FT->getParamType(0) == IntegerType::getInt8PtrTy(M.getContext()); + FT->getParamType(0) == + IntegerType::getInt8Ty(M.getContext())->getPointerTo(0); isStrcasecmp &= FT->getNumParams() == 2 && FT->getReturnType()->isIntegerTy(32) && FT->getParamType(0) == FT->getParamType(1) && - FT->getParamType(0) == IntegerType::getInt8PtrTy(M.getContext()); + FT->getParamType(0) == + IntegerType::getInt8Ty(M.getContext())->getPointerTo(0); 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(); + isStrncmp &= + FT->getNumParams() == 3 && FT->getReturnType()->isIntegerTy(32) && + FT->getParamType(0) == FT->getParamType(1) && + FT->getParamType(0) == + IntegerType::getInt8Ty(M.getContext())->getPointerTo(0) && + FT->getParamType(2)->isIntegerTy(); + isStrncasecmp &= + FT->getNumParams() == 3 && FT->getReturnType()->isIntegerTy(32) && + FT->getParamType(0) == FT->getParamType(1) && + FT->getParamType(0) == + IntegerType::getInt8Ty(M.getContext())->getPointerTo(0) && + FT->getParamType(2)->isIntegerTy(); if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp && !isStrncasecmp && !isIntMemcpy) diff --git a/nyx_mode/QEMU-Nyx b/nyx_mode/QEMU-Nyx -Subproject 60c216bc9e4c79834716d4099993d8397a3a8fd +Subproject 02a6f2aed360cfe76bb3d788dafe517c350d74e diff --git a/nyx_mode/libnyx b/nyx_mode/libnyx -Subproject 2da7f08b6e0267ccfe64e1320b24cdb29223459 +Subproject 512058a68d58b1a90a4e3971b526a955559735b diff --git a/nyx_mode/packer b/nyx_mode/packer -Subproject 202bace888d237e4e8f4507d0eba6791a811554 +Subproject bcf3e248b660764f48af54232a3388389a2dfc2 diff --git a/src/afl-cc.c b/src/afl-cc.c index 6242ece0..22cce2cd 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -2313,7 +2313,7 @@ int main(int argc, char **argv, char **envp) { "0x10000\n" " AFL_LLVM_DOCUMENT_IDS: write all edge IDs and the corresponding " "functions\n" - " into this file\n" + " into this file (LTO mode)\n" " AFL_LLVM_LTO_DONTWRITEID: don't write the highest ID used to a " "global var\n" " AFL_LLVM_LTO_STARTID: from which ID to start counting from for " diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 568c5274..5f67347c 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -459,6 +459,17 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { if (unlikely(fault == FSRV_RUN_TMOUT && afl->afl_env.afl_ignore_timeouts)) { + if (likely(afl->schedule >= FAST && afl->schedule <= RARE)) { + + classify_counts(&afl->fsrv); + u64 cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); + + // Saturated increment + if (likely(afl->n_fuzz[cksum % N_FUZZ_SIZE] < 0xFFFFFFFF)) + afl->n_fuzz[cksum % N_FUZZ_SIZE]++; + + } + return 0; } diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index db82536d..7d6fdfb9 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -89,9 +89,8 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->w_end = 0.3; afl->g_max = 5000; afl->period_pilot_tmp = 5000.0; - afl->schedule = FAST; /* Power schedule (default: FAST) */ + afl->schedule = EXPLORE; /* Power schedule (default: EXPLORE)*/ afl->havoc_max_mult = HAVOC_MAX_MULT; - afl->clear_screen = 1; /* Window resized? */ afl->havoc_div = 1; /* Cycle count divisor for havoc */ afl->stage_name = "init"; /* Name of the current fuzz stage */ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index becad351..dd990e71 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -138,7 +138,7 @@ static void usage(u8 *argv0, int more_help) { "to\n" " exploit mode, and back on new coverage (default: %u)\n" " -p schedule - power schedules compute a seed's performance score:\n" - " fast(default), explore, exploit, seek, rare, mmopt, " + " explore(default), fast, exploit, seek, rare, mmopt, " "coe, lin\n" " quad -- see docs/FAQ.md for more information\n" " -f file - location read by the fuzzed program (default: stdin " diff --git a/utils/aflpp_driver/aflpp_driver.c b/utils/aflpp_driver/aflpp_driver.c index dab7fd95..9ffb2383 100644 --- a/utils/aflpp_driver/aflpp_driver.c +++ b/utils/aflpp_driver/aflpp_driver.c @@ -292,6 +292,7 @@ __attribute__((weak)) int main(int argc, char **argv) { "afl-fuzz will run N iterations before re-spawning the process " "(default: " "INT_MAX)\n" + "You can also use AFL_FUZZER_LOOPCOUNT to set N\n" "For stdin input processing, pass '-' as single command line option.\n" "For file input processing, pass '@@' as single command line option.\n" "To use with afl-cmin or afl-cmin.bash pass '-' as single command line " @@ -379,6 +380,12 @@ __attribute__((weak)) int LLVMFuzzerRunDriver( } + if (getenv("AFL_FUZZER_LOOPCOUNT")) { + + N = atoi(getenv("AFL_FUZZER_LOOPCOUNT")); + + } + assert(N > 0); __afl_manual_init(); |