diff options
37 files changed, 409 insertions, 127 deletions
diff --git a/.gitmodules b/.gitmodules index 3ad6e10c..7c7613ac 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,4 +7,4 @@ url = https://github.com/AFLplusplus/Grammar-Mutator [submodule "qemu_mode/qemuafl"] path = qemu_mode/qemuafl - url = https://github.com/AFLplusplus/qemuafl.git + url = https://github.com/AFLplusplus/qemuafl diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ccacef5f..c36ed9d8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,9 +16,9 @@ project, or added a file in a directory we already format, otherwise run: ``` Regarding the coding style, please follow the AFL style. -No camel case at all and use the AFL's macros wherever possible +No camel case at all and use AFL's macros wherever possible (e.g. WARNF, FATAL, MAP_SIZE, ...). Remember that AFLplusplus has to build and run on many platforms, so generalize your Makefiles/GNUmakefile (or your patches to our pre-existing -Makefiles) to be as much generic as possible. +Makefiles) to be as generic as possible. diff --git a/README.md b/README.md index d7c5694e..494a6bb7 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,8 @@ afl++ is a superior fork to Google's afl - more speed, more and better mutations, more and better instrumentation, custom module support, etc. - If you want to use afl++ for you academic work, check the [papers page](https://aflplus.plus/papers/) - in the website. + If you want to use afl++ for your academic work, check the [papers page](https://aflplus.plus/papers/) + on the website. ## Major changes in afl++ 3.0 @@ -585,7 +585,10 @@ For every secondary fuzzer there should be a variation, e.g.: activated (`export AFL_USE_ASAN=1 ; export AFL_USE_UBSAN=1 ; export AFL_USE_CFISAN=1 ; ` * one should fuzz the target with CMPLOG/redqueen (see above) - * one to three should fuzz a target compiled with laf-intel/COMPCOV (see above). + * one to three fuzzers should fuzz a target compiled with laf-intel/COMPCOV + (see above). Important note: If you run more than one laf-intel/COMPCOV + fuzzer and you want them to share their intermediate results, the main + fuzzer (`-M`) must be one of the them! All other secondaries should be used like this: * A third to a half with the MOpt mutator enabled: `-L 0` @@ -597,11 +600,11 @@ You can also use different fuzzers. If you are using afl spinoffs or afl conforming fuzzers, then just use the same -o directory and give it a unique `-S` name. Examples are: - * [Angora](https://github.com/AngoraFuzzer/Angora) * [Untracer](https://github.com/FoRTE-Research/UnTracer-AFL) * [AFLsmart](https://github.com/aflsmart/aflsmart) * [FairFuzz](https://github.com/carolemieux/afl-rb) * [Neuzz](https://github.com/Dongdongshe/neuzz) + * [Angora](https://github.com/AngoraFuzzer/Angora) A long list can be found at [https://github.com/Microsvuln/Awesome-AFL](https://github.com/Microsvuln/Awesome-AFL) diff --git a/custom_mutators/honggfuzz/honggfuzz.c b/custom_mutators/honggfuzz/honggfuzz.c index bde922c6..b4f07258 100644 --- a/custom_mutators/honggfuzz/honggfuzz.c +++ b/custom_mutators/honggfuzz/honggfuzz.c @@ -37,6 +37,7 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) { if ((data->mutator_buf = malloc(MAX_FILE)) == NULL) { + free(data); perror("mutator_buf alloc"); return NULL; diff --git a/custom_mutators/libfuzzer/FuzzerIO.cpp b/custom_mutators/libfuzzer/FuzzerIO.cpp index e0c15db4..d8d52b63 100644 --- a/custom_mutators/libfuzzer/FuzzerIO.cpp +++ b/custom_mutators/libfuzzer/FuzzerIO.cpp @@ -83,6 +83,8 @@ void WriteToFile(const std::string &Data, const std::string &Path) { void WriteToFile(const uint8_t *Data, size_t Size, const std::string &Path) { + return; + // Use raw C interface because this function may be called from a sig handler. FILE *Out = fopen(Path.c_str(), "wb"); if (!Out) return; @@ -93,6 +95,8 @@ void WriteToFile(const uint8_t *Data, size_t Size, const std::string &Path) { void AppendToFile(const std::string &Data, const std::string &Path) { + return; + AppendToFile(reinterpret_cast<const uint8_t *>(Data.data()), Data.size(), Path); @@ -100,6 +104,8 @@ void AppendToFile(const std::string &Data, const std::string &Path) { void AppendToFile(const uint8_t *Data, size_t Size, const std::string &Path) { + return; + FILE *Out = fopen(Path.c_str(), "a"); if (!Out) return; fwrite(Data, sizeof(Data[0]), Size, Out); @@ -182,6 +188,7 @@ void Printf(const char *Fmt, ...) { void VPrintf(bool Verbose, const char *Fmt, ...) { + return; if (!Verbose) return; va_list ap; va_start(ap, Fmt); diff --git a/custom_mutators/libfuzzer/FuzzerLoop.cpp b/custom_mutators/libfuzzer/FuzzerLoop.cpp index 201883f0..08fda520 100644 --- a/custom_mutators/libfuzzer/FuzzerLoop.cpp +++ b/custom_mutators/libfuzzer/FuzzerLoop.cpp @@ -206,6 +206,8 @@ void Fuzzer::StaticDeathCallback() { void Fuzzer::DumpCurrentUnit(const char *Prefix) { + return; + if (!CurrentUnitData) return; // Happens when running individual inputs. ScopedDisableMsanInterceptorChecks S; MD.PrintMutationSequence(); @@ -733,6 +735,7 @@ std::string Fuzzer::WriteToOutputCorpus(const Unit &U) { void Fuzzer::WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix) { + return; if (!Options.SaveArtifacts) return; std::string Path = Options.ArtifactPrefix + Prefix + Hash(U); if (!Options.ExactArtifactPath.empty()) @@ -1073,13 +1076,21 @@ void Fuzzer::MinimizeCrashLoop(const Unit &U) { } // namespace fuzzer +#ifdef INTROSPECTION + extern const char *introspection_ptr; +#endif + extern "C" { ATTRIBUTE_INTERFACE size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize) { assert(fuzzer::F); - return fuzzer::F->GetMD().DefaultMutate(Data, Size, MaxSize); + size_t r = fuzzer::F->GetMD().DefaultMutate(Data, Size, MaxSize); +#ifdef INTROSPECTION + introspection_ptr = fuzzer::F->GetMD().WriteMutationSequence(); +#endif + return r; } diff --git a/custom_mutators/libfuzzer/FuzzerMutate.cpp b/custom_mutators/libfuzzer/FuzzerMutate.cpp index eebae39b..edfe0455 100644 --- a/custom_mutators/libfuzzer/FuzzerMutate.cpp +++ b/custom_mutators/libfuzzer/FuzzerMutate.cpp @@ -14,6 +14,8 @@ #include "FuzzerMutate.h" #include "FuzzerOptions.h" #include "FuzzerTracePC.h" +#include <random> +#include <chrono> namespace fuzzer { @@ -100,15 +102,17 @@ size_t MutationDispatcher::Mutate_CustomCrossOver(uint8_t *Data, size_t Size, } + size_t MutationDispatcher::Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize) { - if (Size > MaxSize || Size == 0) return 0; size_t ShuffleAmount = Rand(std::min(Size, (size_t)8)) + 1; // [1,8] and <= Size. size_t ShuffleStart = Rand(Size - ShuffleAmount); assert(ShuffleStart + ShuffleAmount <= Size); - std::shuffle(Data + ShuffleStart, Data + ShuffleStart + ShuffleAmount, Rand); + unsigned num = std::chrono::system_clock::now().time_since_epoch().count(); + std::shuffle(Data + ShuffleStart, Data + ShuffleStart + ShuffleAmount, std::default_random_engine(num)); + //std::shuffle(Data + ShuffleStart, Data + ShuffleStart + ShuffleAmount, Rand); return Size; } @@ -609,8 +613,24 @@ void MutationDispatcher::PrintRecommendedDictionary() { } +const char *MutationDispatcher::WriteMutationSequence() { + + static std::string buf; + buf = ""; + + for (size_t i = 0; i < CurrentMutatorSequence.size(); i++) { + + buf = buf + " " + CurrentMutatorSequence[i].Name; + + } + + return buf.c_str(); + +} + void MutationDispatcher::PrintMutationSequence(bool Verbose) { + return; Printf("MS: %zd ", CurrentMutatorSequence.size()); size_t EntriesToPrint = Verbose ? CurrentMutatorSequence.size() diff --git a/custom_mutators/libfuzzer/FuzzerMutate.h b/custom_mutators/libfuzzer/FuzzerMutate.h index 37fd6100..6252f265 100644 --- a/custom_mutators/libfuzzer/FuzzerMutate.h +++ b/custom_mutators/libfuzzer/FuzzerMutate.h @@ -26,6 +26,7 @@ public: void StartMutationSequence(); /// Print the current sequence of mutations. Only prints the full sequence /// when Verbose is true. + const char *WriteMutationSequence(); void PrintMutationSequence(bool Verbose = true); /// Return the current sequence of mutations. std::string MutationSequence(); diff --git a/custom_mutators/libfuzzer/Makefile b/custom_mutators/libfuzzer/Makefile index 95402f6c..51263b89 100644 --- a/custom_mutators/libfuzzer/Makefile +++ b/custom_mutators/libfuzzer/Makefile @@ -3,6 +3,11 @@ CFLAGS = -g -O3 -funroll-loops -fPIC -fpermissive -std=c++11 #CFLAGS = -g -O0 -fPIC -fpermissive -std=c++11 CXX ?= clang++ +ifdef INTROSPECTION + $(info Compiling with introspection documentation) + CFLAGS += -DINTROSPECTION=1 +endif + all: libfuzzer-mutator.so FuzzerCrossOver.o: FuzzerCrossOver.cpp diff --git a/custom_mutators/libfuzzer/libfuzzer.cpp b/custom_mutators/libfuzzer/libfuzzer.cpp index 5e37df66..dc1fbeb2 100644 --- a/custom_mutators/libfuzzer/libfuzzer.cpp +++ b/custom_mutators/libfuzzer/libfuzzer.cpp @@ -6,6 +6,10 @@ //#include "debug.h" #include "afl-fuzz.h" +#ifdef INTROSPECTION + const char *introspection_ptr; +#endif + afl_state_t *afl_struct; extern "C" size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize); @@ -46,6 +50,7 @@ extern "C" my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) { if ((data->mutator_buf = (u8 *)malloc(MAX_FILE)) == NULL) { + free(data); perror("mutator_buf alloc"); return NULL; @@ -133,6 +138,14 @@ extern "C" size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, } +#ifdef INTROSPECTION +extern "C" const char* afl_custom_introspection(my_mutator_t *data) { + + return introspection_ptr; + +} +#endif + /** * Deinitialize everything * diff --git a/custom_mutators/radamsa/radamsa-mutator.c b/custom_mutators/radamsa/radamsa-mutator.c index 82d28001..624ace3d 100644 --- a/custom_mutators/radamsa/radamsa-mutator.c +++ b/custom_mutators/radamsa/radamsa-mutator.c @@ -33,6 +33,7 @@ my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) { if ((data->mutator_buf = malloc(MAX_FILE)) == NULL) { + free(data); perror("mutator_buf alloc"); return NULL; diff --git a/custom_mutators/symcc/symcc.c b/custom_mutators/symcc/symcc.c index acec29da..9c6c0cb8 100644 --- a/custom_mutators/symcc/symcc.c +++ b/custom_mutators/symcc/symcc.c @@ -45,6 +45,7 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) { if ((data->mutator_buf = malloc(MAX_FILE)) == NULL) { + free(data); perror("mutator_buf alloc"); return NULL; diff --git a/docs/Changelog.md b/docs/Changelog.md index 50c1d48a..baa2667b 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -38,22 +38,26 @@ sending a mail to <afl-users+subscribe@googlegroups.com>. - added INTROSPECTION make target that writes all mutations to out/NAME/introspection.txt - print special compile time options used in help output + - somewhere we broke -n dumb fuzzing, fixed - instrumentation - We received an enhanced gcc_plugin module from AdaCore, thank you very much!! - not overriding -Ox or -fno-unroll-loops anymore - we now have our own trace-pc-guard implementation. It is the same as -fsanitize-coverage=trace-pc-guard from llvm 12, but: it is a) inline - and b) works from llvm 10+ on :) + and b) works from llvm 10.0.1 + onwards :) - new llvm pass: dict2file via AFL_LLVM_DICT2FILE, create afl-fuzz -x dictionary of string comparisons found during compilation - LTO autodict now also collects interesting cmp comparisons, std::string compare + find + ==, bcmp - fix crash in dict2file for integers > 64 bit + - custom mutators + - added a new custom mutator: symcc -> https://github.com/eurecom-s3/symcc/ + - added a new custom mutator: libfuzzer that integrates libfuzzer mutations + - Our afl++ Grammar-Mutator is now better integrated into custom_mutators/ + - added INTROSPECTION support for custom modules + - python fuzz function was not optional, fixed - unicornafl synced with upstream (arm64 fix, better rust bindings) - - added a new custom mutator: symcc -> https://github.com/eurecom-s3/symcc/ - - added a new custom mutator: libfuzzer that integrates libfuzzer mutations - - Our afl++ Grammar-Mutator is now better integrated into custom_mutators/ ### Version ++2.68c (release) diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index 81ee9de4..2516e511 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -42,6 +42,7 @@ size_t afl_custom_havoc_mutation(void *data, unsigned char *buf, size_t buf_size unsigned char afl_custom_havoc_mutation_probability(void *data); unsigned char afl_custom_queue_get(void *data, const unsigned char *filename); void afl_custom_queue_new_entry(void *data, const unsigned char *filename_new_queue, const unsigned int *filename_orig_queue); +const char* afl_custom_introspection(my_mutator_t *data); void afl_custom_deinit(void *data); ``` @@ -81,6 +82,9 @@ def queue_new_entry(filename_new_queue, filename_orig_queue): pass ``` +def introspection(): + return string + ### Custom Mutation - `init`: @@ -130,6 +134,12 @@ def queue_new_entry(filename_new_queue, filename_orig_queue): This methods is called after adding a new test case to the queue. +- `introspection` (optional): + + This method is called after a new queue entry, crash or timeout is + discovered if compiled with INTROSPECTION. The custom mutator can then + return a string (const char *) that reports the exact mutations used. + - `deinit`: The last method to be called, deinitializing the state. diff --git a/examples/afl_frida/afl-frida.c b/examples/afl_frida/afl-frida.c index 2ad5a72a..31bf8f25 100644 --- a/examples/afl_frida/afl-frida.c +++ b/examples/afl_frida/afl-frida.c @@ -6,7 +6,7 @@ Written mostly by meme -> https://github.com/meme/hotwax - Modificationy by Marc Heuse <mh@mh-sec.de> + Modifications by Marc Heuse <mh@mh-sec.de> Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -504,11 +504,12 @@ int main() { previous_pc = 0; // Required! #ifdef _DEBUG - fprintf(stderr, "CLIENT crc: %016llx len: %u\n", hash64(__afl_fuzz_ptr, *__a + fprintf(stderr, "CLIENT crc: %016llx len: %u\n", + hash64(__afl_fuzz_ptr, *__afl_fuzz_len), *__afl_fuzz_len); fprintf(stderr, "RECV:"); for (int i = 0; i < *__afl_fuzz_len; i++) fprintf(stderr, "%02x", __afl_fuzz_ptr[i]); - fprintf(stderr,"\n"); + fprintf(stderr, "\n"); #endif // STEP 3: ensure the minimum length is present and setup the target diff --git a/examples/custom_mutators/custom_mutator_helpers.h b/examples/custom_mutators/custom_mutator_helpers.h index ad5acb08..62e6efba 100644 --- a/examples/custom_mutators/custom_mutator_helpers.h +++ b/examples/custom_mutators/custom_mutator_helpers.h @@ -13,7 +13,7 @@ #define BUF_VAR(type, name) \ type * name##_buf; \ size_t name##_size; -/* this filles in `&structptr->something_buf, &structptr->something_size`. */ +/* this fills in `&structptr->something_buf, &structptr->something_size`. */ #define BUF_PARAMS(struct, name) \ (void **)&struct->name##_buf, &struct->name##_size diff --git a/examples/custom_mutators/post_library_gif.so.c b/examples/custom_mutators/post_library_gif.so.c index 2d72400c..ac10f409 100644 --- a/examples/custom_mutators/post_library_gif.so.c +++ b/examples/custom_mutators/post_library_gif.so.c @@ -94,7 +94,13 @@ void *afl_custom_init(void *afl) { } state->buf = calloc(sizeof(unsigned char), 4096); - if (!state->buf) { return NULL; } + if (!state->buf) { + + free(state); + perror("calloc"); + return NULL; + + } return state; diff --git a/examples/custom_mutators/post_library_png.so.c b/examples/custom_mutators/post_library_png.so.c index 7c1ea93e..941f7e55 100644 --- a/examples/custom_mutators/post_library_png.so.c +++ b/examples/custom_mutators/post_library_png.so.c @@ -54,7 +54,13 @@ void *afl_custom_init(void *afl) { } state->buf = calloc(sizeof(unsigned char), 4096); - if (!state->buf) { return NULL; } + if (!state->buf) { + + free(state); + perror("calloc"); + return NULL; + + } return state; diff --git a/examples/custom_mutators/simple_example.c b/examples/custom_mutators/simple_example.c index a351d787..d888ec1f 100644 --- a/examples/custom_mutators/simple_example.c +++ b/examples/custom_mutators/simple_example.c @@ -8,7 +8,7 @@ #include <stdio.h> #ifndef _FIXED_CHAR - #define 0x41 + #define _FIXED_CHAR 0x41 #endif typedef struct my_mutator { diff --git a/examples/defork/forking_target.c b/examples/defork/forking_target.c index 98f6365a..628d23c9 100644 --- a/examples/defork/forking_target.c +++ b/examples/defork/forking_target.c @@ -26,6 +26,7 @@ int main(int argc, char **argv) { FILE *f = fopen(argv[1], "r"); char buf[4096]; fread(buf, 1, 4096, f); + fclose(f); uint32_t offset = buf[100] + (buf[101] << 8); char test_val = buf[offset]; return test_val < 100; diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index e59d5f90..c355263b 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -310,6 +310,7 @@ enum { /* 09 */ PY_FUNC_HAVOC_MUTATION_PROBABILITY, /* 10 */ PY_FUNC_QUEUE_GET, /* 11 */ PY_FUNC_QUEUE_NEW_ENTRY, + /* 12 */ PY_FUNC_INTROSPECTION, PY_FUNC_COUNT }; @@ -684,6 +685,8 @@ typedef struct afl_state { u32 custom_mutators_count; + struct custom_mutator *current_custom_fuzz; + list_t custom_mutator_list; /* this is a fixed buffer of size map_size that can be used by any function if @@ -748,6 +751,15 @@ struct custom_mutator { void *(*afl_custom_init)(afl_state_t *afl, unsigned int seed); /** + * When afl-fuzz was compiled with INTROSPECTION=1 then custom mutators can + * also give introspection information back with this function. + * + * @param data pointer returned in afl_custom_init for this fuzz case + * @return pointer to a text string (const char*) + */ + const char *(*afl_custom_introspection)(void *data); + + /** * This method is called just before fuzzing a queue entry with the custom * mutator, and receives the initial buffer. It should return the number of * fuzzes to perform. @@ -953,16 +965,17 @@ u8 trim_case_custom(afl_state_t *, struct queue_entry *q, u8 *in_buf, struct custom_mutator *load_custom_mutator_py(afl_state_t *, char *); void finalize_py_module(void *); -u32 fuzz_count_py(void *, const u8 *, size_t); -size_t post_process_py(void *, u8 *, size_t, u8 **); -s32 init_trim_py(void *, u8 *, size_t); -s32 post_trim_py(void *, u8); -size_t trim_py(void *, u8 **); -size_t havoc_mutation_py(void *, u8 *, size_t, u8 **, size_t); -u8 havoc_mutation_probability_py(void *); -u8 queue_get_py(void *, const u8 *); -void queue_new_entry_py(void *, const u8 *, const u8 *); -void deinit_py(void *); +u32 fuzz_count_py(void *, const u8 *, size_t); +size_t post_process_py(void *, u8 *, size_t, u8 **); +s32 init_trim_py(void *, u8 *, size_t); +s32 post_trim_py(void *, u8); +size_t trim_py(void *, u8 **); +size_t havoc_mutation_py(void *, u8 *, size_t, u8 **, size_t); +u8 havoc_mutation_probability_py(void *); +u8 queue_get_py(void *, const u8 *); +const char *introspection_py(void *); +void queue_new_entry_py(void *, const u8 *, const u8 *); +void deinit_py(void *); #endif diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index b3c55108..e85f9cd3 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -544,7 +544,9 @@ bool ModuleSanitizerCoverage::instrumentModule( be_quiet = 1; skip_nozero = getenv("AFL_LLVM_SKIP_NEVERZERO"); - // scanForDangerousFunctions(&M); + + initInstrumentList(); + scanForDangerousFunctions(&M); if (debug) { @@ -819,6 +821,8 @@ void ModuleSanitizerCoverage::instrumentFunction( Function &F, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) { if (F.empty()) return; + if (!isInInstrumentList(&F)) return; + if (F.getName().find(".module_ctor") != std::string::npos) return; // Should not instrument sanitizer init functions. if (F.getName().startswith("__sanitizer_")) @@ -1315,6 +1319,7 @@ std::string ModuleSanitizerCoverage::getSectionEnd( } char ModuleSanitizerCoverageLegacyPass::ID = 0; + INITIALIZE_PASS_BEGIN(ModuleSanitizerCoverageLegacyPass, "sancov", "Pass for instrumenting coverage on functions", false, false) @@ -1323,6 +1328,7 @@ INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass) INITIALIZE_PASS_END(ModuleSanitizerCoverageLegacyPass, "sancov", "Pass for instrumenting coverage on functions", false, false) + ModulePass *llvm::createModuleSanitizerCoverageLegacyPassPass( const SanitizerCoverageOptions &Options, const std::vector<std::string> &AllowlistFiles, diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index f38af668..18501b65 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -123,7 +123,7 @@ void __afl_trace(const u32 x) { u8 c = __builtin_add_overflow(*p, 1, p); *p += c; #else - *p += 1 + ((u8)(1 + *p == 0); + *p += 1 + ((u8)(1 + *p) == 0); #endif #else ++*p; @@ -182,7 +182,7 @@ static void __afl_map_shm_fuzz() { if (!map || map == (void *)-1) { - perror("Could not access fuzzign shared memory"); + perror("Could not access fuzzing shared memory"); exit(1); } diff --git a/qemu_mode/QEMUAFL_VERSION b/qemu_mode/QEMUAFL_VERSION index 75883247..43403430 100644 --- a/qemu_mode/QEMUAFL_VERSION +++ b/qemu_mode/QEMUAFL_VERSION @@ -1 +1 @@ -21ff343837 +d66c9e2654 diff --git a/qemu_mode/libcompcov/pmparser.h b/qemu_mode/libcompcov/pmparser.h index 9421d47e..0eb4fb1d 100644 --- a/qemu_mode/libcompcov/pmparser.h +++ b/qemu_mode/libcompcov/pmparser.h @@ -108,8 +108,7 @@ void pmparser_print(procmaps_struct *map, int order); procmaps_iterator *pmparser_parse(int pid) { - procmaps_iterator *maps_it = malloc(sizeof(procmaps_iterator)); - char maps_path[500]; + char maps_path[500]; if (pid >= 0) { sprintf(maps_path, "/proc/%d/maps", pid); @@ -129,8 +128,9 @@ procmaps_iterator *pmparser_parse(int pid) { } - int ind = 0; - char buf[PROCMAPS_LINE_MAX_LENGTH]; + procmaps_iterator *maps_it = malloc(sizeof(procmaps_iterator)); + int ind = 0; + char buf[PROCMAPS_LINE_MAX_LENGTH]; // int c; procmaps_struct *list_maps = NULL; procmaps_struct *tmp; diff --git a/src/afl-cc.c b/src/afl-cc.c index 771a58f5..5d8d33a5 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -49,14 +49,14 @@ 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, instrument_opt_mode, ngram_size, lto_mode, - compiler_mode, plusplus_mode; -static u8 have_gcc, have_llvm, have_gcc_plugin, have_lto; -static u8 *lto_flag = AFL_CLANG_FLTO, *argvnull; -static u8 debug; -static u8 cwd[4096]; -static u8 cmplog_mode; -u8 use_stdin; /* dummy */ +static u8 instrument_mode, instrument_opt_mode, ngram_size, lto_mode; +static u8 compiler_mode, plusplus_mode, have_instr_env = 0; +static u8 have_gcc, have_llvm, have_gcc_plugin, have_lto, have_instr_list = 0; +static u8 * lto_flag = AFL_CLANG_FLTO, *argvnull; +static u8 debug; +static u8 cwd[4096]; +static u8 cmplog_mode; +u8 use_stdin; /* dummy */ // static u8 *march_opt = CFLAGS_OPT; enum { @@ -354,19 +354,13 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (lto_mode && plusplus_mode) cc_params[cc_par_cnt++] = "-lc++"; // needed by fuzzbench, early - if (lto_mode) { - - if (getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL || - getenv("AFL_LLVM_WHITELIST") || getenv("AFL_LLVM_ALLOWLIST") || - getenv("AFL_LLVM_DENYLIST") || getenv("AFL_LLVM_BLOCKLIST")) { + if (lto_mode && have_instr_env) { - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = "-load"; - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = - alloc_printf("%s/afl-llvm-lto-instrumentlist.so", obj_path); - - } + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = "-load"; + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = + alloc_printf("%s/afl-llvm-lto-instrumentlist.so", obj_path); } @@ -508,11 +502,25 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (instrument_mode == INSTRUMENT_PCGUARD) { #if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = "-load"; - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = - alloc_printf("%s/SanitizerCoveragePCGUARD.so", obj_path); + if (have_instr_list) { + + if (!be_quiet) + SAYF( + "Using unoptimized trace-pc-guard, due usage of " + "-fsanitize-coverage-allow/denylist, you can use " + "AFL_LLVM_ALLOWLIST/AFL_LLMV_DENYLIST instead.\n"); + cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard"; + + } else { + + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = "-load"; + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = + alloc_printf("%s/SanitizerCoveragePCGUARD.so", obj_path); + + } + #else #if LLVM_MAJOR >= 4 if (!be_quiet) @@ -590,6 +598,9 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (!strcmp(cur, "armv7a-linux-androideabi")) bit_mode = 32; if (!strcmp(cur, "-m64")) bit_mode = 64; + if (!strncmp(cur, "-fsanitize-coverage-", 20) && strstr(cur, "list=")) + have_instr_list = 1; + if (!strcmp(cur, "-fsanitize=address") || !strcmp(cur, "-fsanitize=memory")) asan_set = 1; @@ -856,6 +867,14 @@ int main(int argc, char **argv, char **envp) { be_quiet = 1; + if (getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST") || + getenv("AFL_LLVM_ALLOWLIST") || getenv("AFL_LLVM_DENYLIST") || + getenv("AFL_LLVM_BLOCKLIST")) { + + have_instr_env = 1; + + } + if ((ptr = strrchr(callname, '/')) != NULL) callname = ptr + 1; argvnull = (u8 *)argv[0]; check_environment_vars(envp); @@ -1015,14 +1034,14 @@ int main(int argc, char **argv, char **envp) { } - if ((getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL || - getenv("AFL_LLVM_WHITELIST") || getenv("AFL_LLVM_ALLOWLIST") || - getenv("AFL_LLVM_DENYLIST") || getenv("AFL_LLVM_BLOCKLIST")) && - getenv("AFL_DONT_OPTIMIZE")) + if (have_instr_env && getenv("AFL_DONT_OPTIMIZE")) { + WARNF( "AFL_LLVM_ALLOWLIST/DENYLIST and AFL_DONT_OPTIMIZE cannot be combined " "for file matching, only function matching!"); + } + if (getenv("AFL_LLVM_INSTRIM") || getenv("INSTRIM") || getenv("INSTRIM_LIB")) { @@ -1426,22 +1445,20 @@ int main(int argc, char **argv, char **envp) { #if LLVM_MAJOR <= 6 instrument_mode = INSTRUMENT_AFL; #else - if (getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL || - getenv("AFL_LLVM_WHITELIST") || getenv("AFL_LLVM_ALLOWLIST") || - getenv("AFL_LLVM_DENYLIST") || getenv("AFL_LLVM_BLOCKLIST")) { + #if LLVM_MAJOR < 11 && (LLVM_MAJOR < 10 || LLVM_MINOR < 1) + if (have_instr_env) { instrument_mode = INSTRUMENT_AFL; - WARNF( - "switching to classic instrumentation because " - "AFL_LLVM_ALLOWLIST/DENYLIST does not work with PCGUARD. Use " - "-fsanitize-coverage-allowlist=allowlist.txt or " - "-fsanitize-coverage-blocklist=denylist.txt if you want to use " - "PCGUARD. Requires llvm 12+. See https://clang.llvm.org/docs/ " - "SanitizerCoverage.html#partially-disabling-instrumentation"); + if (!be_quiet) + WARNF( + "Switching to classic instrumentation because " + "AFL_LLVM_ALLOWLIST/DENYLIST does not work with PCGUARD < 10.0.1."); } else + #endif instrument_mode = INSTRUMENT_PCGUARD; + #endif } @@ -1487,18 +1504,16 @@ int main(int argc, char **argv, char **envp) { "AFL_LLVM_NOT_ZERO and AFL_LLVM_SKIP_NEVERZERO can not be set " "together"); - if (instrument_mode == INSTRUMENT_PCGUARD && - (getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL || - getenv("AFL_LLVM_WHITELIST") || getenv("AFL_LLVM_ALLOWLIST") || - getenv("AFL_LLVM_DENYLIST") || getenv("AFL_LLVM_BLOCKLIST"))) +#if LLVM_MAJOR < 11 && (LLVM_MAJOR < 10 || LLVM_MINOR < 1) + if (instrument_mode == INSTRUMENT_PCGUARD && have_instr_env) { + FATAL( "Instrumentation type PCGUARD does not support " - "AFL_LLVM_ALLOWLIST/DENYLIST! Use " - "-fsanitize-coverage-allowlist=allowlist.txt or " - "-fsanitize-coverage-blocklist=denylist.txt instead (requires llvm " - "12+), see " - "https://clang.llvm.org/docs/" - "SanitizerCoverage.html#partially-disabling-instrumentation"); + "AFL_LLVM_ALLOWLIST/DENYLIST! Use LLVM 10.0.1+ instead."); + + } + +#endif u8 *ptr2; diff --git a/src/afl-common.c b/src/afl-common.c index 19c9419b..8cf1a444 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -342,7 +342,7 @@ u8 *find_binary(u8 *fname) { if (stat(target_path, &st) || !S_ISREG(st.st_mode) || !(st.st_mode & 0111) || st.st_size < 4) { - free(target_path); + ck_free(target_path); FATAL("Program '%s' not found or not executable", fname); } diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 45be2abd..3814a77e 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -116,7 +116,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { fsrv_to->use_fauxsrv = 0; fsrv_to->last_run_timed_out = 0; - fsrv_to->init_child_func = fsrv_exec_child; + fsrv_to->init_child_func = from->init_child_func; // Note: do not copy ->add_extra_func list_append(&fsrv_list, fsrv_to); @@ -272,7 +272,8 @@ static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) { *(u32 *)fsrv->trace_bits = EXEC_FAIL_SIG; - PFATAL("Execv failed in fauxserver."); + WARNF("Execv failed in fauxserver."); + break; } @@ -286,13 +287,13 @@ static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) { if (waitpid(child_pid, &status, 0) < 0) { // Zombie Child could not be collected. Scary! - PFATAL("Fauxserver could not determin child's exit code. "); + WARNF("Fauxserver could not determine child's exit code. "); } /* Relay wait status to AFL pipe, then loop back. */ - if (write(FORKSRV_FD + 1, &status, 4) != 4) { exit(0); } + if (write(FORKSRV_FD + 1, &status, 4) != 4) { exit(1); } } @@ -330,7 +331,7 @@ static void report_error_and_exit(int error) { "memory failed."); break; default: - FATAL("unknown error code %u from fuzzing target!", error); + FATAL("unknown error code %d from fuzzing target!", error); } @@ -355,7 +356,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if (fsrv->use_fauxsrv) { - /* TODO: Come up with sone nice way to initialize this all */ + /* TODO: Come up with some nice way to initialize this all */ if (fsrv->init_child_func != fsrv_exec_child) { @@ -520,7 +521,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, *(u32 *)fsrv->trace_bits = EXEC_FAIL_SIG; fprintf(stderr, "Error: execv to target failed\n"); - exit(0); + exit(1); } @@ -1137,7 +1138,7 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, } // Fauxserver should handle this now. - // if (tb4 == EXEC_FAIL_SIG) return FSRV_RUN_ERROR; + if (*(u32 *)fsrv->trace_bits == EXEC_FAIL_SIG) return FSRV_RUN_ERROR; return FSRV_RUN_OK; diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 4b29672a..2d14b04e 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -591,8 +591,32 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { add_to_queue(afl, queue_fn, len, 0); #ifdef INTROSPECTION - fprintf(afl->introspection_file, "QUEUE %s = %s\n", afl->mutation, - afl->queue_top->fname); + if (afl->custom_mutators_count && afl->current_custom_fuzz) { + + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (afl->current_custom_fuzz == el && el->afl_custom_introspection) { + + const char *ptr = el->afl_custom_introspection(el->data); + + if (ptr != NULL && *ptr != 0) { + + fprintf(afl->introspection_file, "QUEUE CUSTOM %s = %s\n", ptr, + afl->queue_top->fname); + + } + + } + + }); + + } else if (afl->mutation[0] != 0) { + + fprintf(afl->introspection_file, "QUEUE %s = %s\n", afl->mutation, + afl->queue_top->fname); + + } + #endif if (hnb == 2) { @@ -663,7 +687,32 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { ++afl->unique_tmouts; #ifdef INTROSPECTION - fprintf(afl->introspection_file, "UNIQUE_TIMEOUT %s\n", afl->mutation); + if (afl->custom_mutators_count && afl->current_custom_fuzz) { + + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (afl->current_custom_fuzz == el && el->afl_custom_introspection) { + + const char *ptr = el->afl_custom_introspection(el->data); + + if (ptr != NULL && *ptr != 0) { + + fprintf(afl->introspection_file, + "UNIQUE_TIMEOUT CUSTOM %s = %s\n", ptr, + afl->queue_top->fname); + + } + + } + + }); + + } else if (afl->mutation[0] != 0) { + + fprintf(afl->introspection_file, "UNIQUE_TIMEOUT %s\n", afl->mutation); + + } + #endif /* Before saving, we make sure that it's a genuine hang by re-running @@ -749,7 +798,31 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { ++afl->unique_crashes; #ifdef INTROSPECTION - fprintf(afl->introspection_file, "UNIQUE_CRASH %s\n", afl->mutation); + if (afl->custom_mutators_count && afl->current_custom_fuzz) { + + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (afl->current_custom_fuzz == el && el->afl_custom_introspection) { + + const char *ptr = el->afl_custom_introspection(el->data); + + if (ptr != NULL && *ptr != 0) { + + fprintf(afl->introspection_file, "UNIQUE_CRASH CUSTOM %s = %s\n", + ptr, afl->queue_top->fname); + + } + + } + + }); + + } else if (afl->mutation[0] != 0) { + + fprintf(afl->introspection_file, "UNIQUE_CRASH %s\n", afl->mutation); + + } + #endif if (unlikely(afl->infoexec)) { diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 19a8d77b..6884bb1d 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -2300,12 +2300,6 @@ void fix_up_sync(afl_state_t *afl) { u8 *x = afl->sync_id; - if (afl->non_instrumented_mode) { - - FATAL("-S / -M and -n are mutually exclusive"); - - } - while (*x) { if (!isalnum(*x) && *x != '_' && *x != '-') { @@ -2503,7 +2497,8 @@ void check_binary(afl_state_t *afl, u8 *fname) { } - if (afl->afl_env.afl_skip_bin_check || afl->use_wine || afl->unicorn_mode) { + if (afl->afl_env.afl_skip_bin_check || afl->use_wine || afl->unicorn_mode || + afl->non_instrumented_mode) { return; diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index c4d7233c..1d14f657 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -166,6 +166,13 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { } + /* "afl_custom_introspection", optional */ +#ifdef INTROSPECTION + mutator->afl_custom_introspection = dlsym(dh, "afl_custom_introspection"); + if (!mutator->afl_custom_introspection) + ACTF("optional symbol 'afl_custom_introspection' not found."); +#endif + /* "afl_custom_fuzz_count", optional */ mutator->afl_custom_fuzz_count = dlsym(dh, "afl_custom_fuzz_count"); if (!mutator->afl_custom_fuzz_count) diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 91bbced6..0adc3719 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1780,10 +1780,16 @@ custom_mutator_stage: orig_hit_cnt = afl->queued_paths + afl->unique_crashes; +#ifdef INTROSPECTION + afl->mutation[0] = 0; +#endif + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { if (el->afl_custom_fuzz) { + afl->current_custom_fuzz = el; + if (el->afl_custom_fuzz_count) afl->stage_max = el->afl_custom_fuzz_count(el->data, out_buf, len); else @@ -1840,12 +1846,6 @@ custom_mutator_stage: if (mutated_size > 0) { -#ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s CUSTOM-%s", - afl->queue_cur->fname, - target != NULL ? (char *)target->fname : "none"); -#endif - if (common_fuzz_stuff(afl, mutated_buf, (u32)mutated_size)) { goto abandon_entry; @@ -1889,6 +1889,8 @@ custom_mutator_stage: }); + afl->current_custom_fuzz = NULL; + if (!has_custom_fuzz) goto havoc_stage; new_hit_cnt = afl->queued_paths + afl->unique_crashes; diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index adb92649..cfaf055d 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -163,6 +163,8 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { PyObject_GetAttrString(py_module, "queue_get"); py_functions[PY_FUNC_QUEUE_NEW_ENTRY] = PyObject_GetAttrString(py_module, "queue_new_entry"); + py_functions[PY_FUNC_INTROSPECTION] = + PyObject_GetAttrString(py_module, "introspection"); py_functions[PY_FUNC_DEINIT] = PyObject_GetAttrString(py_module, "deinit"); if (!py_functions[PY_FUNC_DEINIT]) FATAL("deinit function not found in python module"); @@ -212,6 +214,7 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { PyErr_Print(); fprintf(stderr, "Failed to load \"%s\"\n", module_name); + free(py); return NULL; } @@ -326,9 +329,7 @@ struct custom_mutator *load_custom_mutator_py(afl_state_t *afl, if (py_functions[PY_FUNC_DEINIT]) { mutator->afl_custom_deinit = deinit_py; } - /* "afl_custom_fuzz" should not be NULL, but the interface of Python mutator - is quite different from the custom mutator. */ - mutator->afl_custom_fuzz = fuzz_py; + if (py_functions[PY_FUNC_FUZZ]) { mutator->afl_custom_fuzz = fuzz_py; } if (py_functions[PY_FUNC_POST_PROCESS]) { @@ -381,6 +382,15 @@ struct custom_mutator *load_custom_mutator_py(afl_state_t *afl, } + #ifdef INTROSPECTION + if (py_functions[PY_FUNC_INTROSPECTION]) { + + mutator->afl_custom_introspection = introspection_py; + + } + + #endif + OKF("Python mutator '%s' installed successfully.", module_name); /* Initialize the custom mutator */ @@ -679,6 +689,28 @@ u8 havoc_mutation_probability_py(void *py_mutator) { } +const char *introspection_py(void *py_mutator) { + + PyObject *py_args, *py_value; + + py_args = PyTuple_New(0); + py_value = PyObject_CallObject( + ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_INTROSPECTION], + py_args); + Py_DECREF(py_args); + + if (py_value == NULL) { + + return NULL; + + } else { + + return PyByteArray_AsString(py_value); + + } + +} + u8 queue_get_py(void *py_mutator, const u8 *filename) { PyObject *py_args, *py_value; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 269ce1bf..cedfdf8f 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -435,9 +435,26 @@ int main(int argc, char **argv_orig, char **envp) { u8 *c; + if (afl->non_instrumented_mode) { + + FATAL("-M is not supported in non-instrumented mode"); + + } + if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); } + + /* sanity check for argument: should not begin with '-' (possible + * option) */ + if (optarg && *optarg == '-') { + + FATAL( + "argument for -M started with a dash '-', which is used for " + "options"); + + } + afl->sync_id = ck_strdup(optarg); - afl->skip_deterministic = 0; // force determinsitic fuzzing + afl->skip_deterministic = 0; // force deterministic fuzzing afl->old_seed_selection = 1; // force old queue walking seed selection if ((c = strchr(afl->sync_id, ':'))) { @@ -464,7 +481,24 @@ int main(int argc, char **argv_orig, char **envp) { case 'S': /* secondary sync id */ + if (afl->non_instrumented_mode) { + + FATAL("-S is not supported in non-instrumented mode"); + + } + if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); } + + /* sanity check for argument: should not begin with '-' (possible + * option) */ + if (optarg && *optarg == '-') { + + FATAL( + "argument for -M started with a dash '-', which is used for " + "options"); + + } + afl->sync_id = ck_strdup(optarg); afl->is_secondary_node = 1; break; @@ -620,6 +654,12 @@ int main(int argc, char **argv_orig, char **envp) { case 'n': /* dumb mode */ + if (afl->is_main_node || afl->is_secondary_node) { + + FATAL("Non instrumented mode is not supported with -M / -S"); + + } + if (afl->non_instrumented_mode) { FATAL("Multiple -n options not supported"); @@ -906,7 +946,7 @@ int main(int argc, char **argv_orig, char **envp) { afl->power_name = power_names[afl->schedule]; - if (!afl->sync_id) { + if (!afl->non_instrumented_mode && !afl->sync_id) { auto_sync = 1; afl->sync_id = ck_strdup("default"); @@ -1338,7 +1378,11 @@ int main(int argc, char **argv_orig, char **envp) { } - if (!afl->fsrv.qemu_mode) { check_binary(afl, afl->cmplog_binary); } + if (!afl->fsrv.qemu_mode && !afl->non_instrumented_mode) { + + check_binary(afl, afl->cmplog_binary); + + } } diff --git a/src/afl-gotcpu.c b/src/afl-gotcpu.c index bd0f7de6..1aea3e40 100644 --- a/src/afl-gotcpu.c +++ b/src/afl-gotcpu.c @@ -65,7 +65,6 @@ #define cpu_set_t cpuset_t #elif defined(__NetBSD__) #include <pthread.h> - #include <sched.h> #elif defined(__APPLE__) #include <pthread.h> #include <mach/thread_act.h> diff --git a/unicorn_mode/samples/persistent/simple_target_noncrashing.c b/unicorn_mode/samples/persistent/simple_target_noncrashing.c index 00764473..9257643b 100644 --- a/unicorn_mode/samples/persistent/simple_target_noncrashing.c +++ b/unicorn_mode/samples/persistent/simple_target_noncrashing.c @@ -10,7 +10,7 @@ * Written by Nathan Voss <njvoss99@gmail.com> * Adapted by Lukas Seidel <seidel.1@campus.tu-berlin.de> */ - +#include <string.h> int main(int argc, char** argv) { if(argc < 2){ @@ -19,15 +19,19 @@ int main(int argc, char** argv) { char *data_buf = argv[1]; - if len(data_buf < 20) { - if (data_buf[20] != 0) { + if (strlen(data_buf) >= 21 && data_buf[20] != 0) { printf("Not crashing"); - } else if (data_buf[0] > 0x10 && data_buf[0] < 0x20 && data_buf[1] > data_buf[2]) { + } else if (strlen(data_buf) > 1 + && data_buf[0] > 0x10 && data_buf[0] < 0x20 && data_buf[1] > data_buf[2]) { printf("Also not crashing with databuf[0] == %c", data_buf[0]) - } else if (data_buf[9] == 0x00 && data_buf[10] != 0x00 && data_buf[11] == 0x00) { + } +#if 0 + // not possible with argv (zero terminated strings) (hexcoder-) + // do not try to access data_buf[10] and beyond + else if (data_buf[9] == 0x00 && data_buf[10] != 0x00 && data_buf[11] == 0x00) { // Cause a crash if data[10] is not zero, but [9] and [11] are zero unsigned char invalid_read = *(unsigned char *) 0x00000000; } - +#endif return 0; } diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl -Subproject 0bf26f6c2601e1c1c84998551ed7d50b4108fbd +Subproject f44ec48f8d5929f243522c1152b5b3c0985a554 |