diff options
author | hexcoder- <heiko@hexco.de> | 2020-07-30 13:48:16 +0200 |
---|---|---|
committer | hexcoder- <heiko@hexco.de> | 2020-07-30 13:48:16 +0200 |
commit | 13350bf22f79250e73b7c7e43ca6f687e4a277cb (patch) | |
tree | d174daa2ca53ebc7b8e7145f484350ba6036c31e | |
parent | 5ce55d87ecf5d3f0e8fbd0e1ce68f74efb0cf528 (diff) | |
parent | fc401f1acc61b73f328a16ac10bed268134c495e (diff) | |
download | afl++-13350bf22f79250e73b7c7e43ca6f687e4a277cb.tar.gz |
Merge branch 'dev' of https://github.com/AFLplusplus/AFLplusplus into dev
-rw-r--r-- | examples/aflpp_driver/GNUmakefile | 22 | ||||
-rw-r--r-- | examples/aflpp_driver/aflpp_driver.c (renamed from examples/aflpp_driver/aflpp_driver.cpp) | 74 | ||||
-rw-r--r-- | examples/aflpp_driver/aflpp_driver_test.c (renamed from examples/aflpp_driver/aflpp_driver_test.cpp) | 3 | ||||
-rw-r--r-- | src/afl-fuzz-run.c | 90 |
4 files changed, 124 insertions, 65 deletions
diff --git a/examples/aflpp_driver/GNUmakefile b/examples/aflpp_driver/GNUmakefile index a993c8a9..b118a8b5 100644 --- a/examples/aflpp_driver/GNUmakefile +++ b/examples/aflpp_driver/GNUmakefile @@ -7,25 +7,25 @@ ifneq "" "$(LLVM_BINDIR)" LLVM_BINDIR := $(LLVM_BINDIR)/ endif -FLAGS=-O3 -funroll-loops -g +CFLAGS := -O3 -funroll-loops -g all: libAFLDriver.a libAFLQemuDriver.a aflpp_qemu_driver_hook.so -aflpp_driver.o: aflpp_driver.cpp - $(LLVM_BINDIR)clang++ $(FLAGS) -stdlib=libc++ -std=c++11 -c aflpp_driver.cpp +aflpp_driver.o: aflpp_driver.c + $(LLVM_BINDIR)clang -I. -I../../include $(CFLAGS) -c aflpp_driver.c libAFLDriver.a: aflpp_driver.o ar ru libAFLDriver.a aflpp_driver.o debug: - $(LLVM_BINDIR)clang++ -Wno-deprecated -I../../include $(FLAGS) -D_DEBUG=\"1\" -c -o afl-performance.o ../../src/afl-performance.c - $(LLVM_BINDIR)clang++ -I../../include -D_DEBUG=\"1\" -g -stdlib=libc++ -funroll-loops -std=c++11 -c aflpp_driver.cpp - #$(LLVM_BINDIR)clang++ -S -emit-llvm -Wno-deprecated -I../../include $(FLAGS) -D_DEBUG=\"1\" -c -o afl-performance.ll ../../src/afl-performance.c - #$(LLVM_BINDIR)clang++ -S -emit-llvm -I../../include -D_DEBUG=\"1\" -g -stdlib=libc++ -funroll-loops -std=c++11 -c aflpp_driver.cpp + $(LLVM_BINDIR)clang -Wno-deprecated -I../../include $(CFLAGS) -D_DEBUG=\"1\" -c -o afl-performance.o ../../src/afl-performance.c + $(LLVM_BINDIR)clang -I../../include -D_DEBUG=\"1\" -g -funroll-loops -c aflpp_driver.c + #$(LLVM_BINDIR)clang -S -emit-llvm -Wno-deprecated -I../../include $(CFLAGS) -D_DEBUG=\"1\" -c -o afl-performance.ll ../../src/afl-performance.c + #$(LLVM_BINDIR)clang -S -emit-llvm -I../../include -D_DEBUG=\"1\" -g -funroll-loops -c aflpp_driver.c ar ru libAFLDriver.a afl-performance.o aflpp_driver.o aflpp_qemu_driver.o: aflpp_qemu_driver.c - $(LLVM_BINDIR)clang $(FLAGS) -O0 -funroll-loops -c aflpp_qemu_driver.c + $(LLVM_BINDIR)clang $(CFLAGS) -O0 -funroll-loops -c aflpp_qemu_driver.c libAFLQemuDriver.a: aflpp_qemu_driver.o ar ru libAFLQemuDriver.a aflpp_qemu_driver.o @@ -34,11 +34,11 @@ aflpp_qemu_driver_hook.so: aflpp_qemu_driver_hook.o $(LLVM_BINDIR)clang -shared aflpp_qemu_driver_hook.o -o aflpp_qemu_driver_hook.so aflpp_qemu_driver_hook.o: aflpp_qemu_driver_hook.c - $(LLVM_BINDIR)clang -fPIC $(FLAGS) -funroll-loops -c aflpp_qemu_driver_hook.c + $(LLVM_BINDIR)clang -fPIC $(CFLAGS) -funroll-loops -c aflpp_qemu_driver_hook.c test: debug - #clang++ -S -emit-llvm -D_DEBUG=\"1\" -I../../include -Wl,--allow-multiple-definition -stdlib=libc++ -funroll-loops -std=c++11 -o aflpp_driver_test.ll aflpp_driver_test.cpp - afl-clang-fast++ -D_DEBUG=\"1\" -I../../include -Wl,--allow-multiple-definition -stdlib=libc++ -funroll-loops -std=c++11 -o aflpp_driver_test aflpp_driver_test.cpp libAFLDriver.a + #clang -S -emit-llvm -D_DEBUG=\"1\" -I../../include -Wl,--allow-multiple-definition -funroll-loops -o aflpp_driver_test.ll aflpp_driver_test.c + afl-clang-fast -D_DEBUG=\"1\" -I../../include -Wl,--allow-multiple-definition -funroll-loops -o aflpp_driver_test aflpp_driver_test.c libAFLDriver.a afl-performance.o clean: rm -f *.o libAFLDriver*.a libAFLQemuDriver.a aflpp_qemu_driver_hook.so *~ core aflpp_driver_test diff --git a/examples/aflpp_driver/aflpp_driver.cpp b/examples/aflpp_driver/aflpp_driver.c index d6163bdf..eca3dcd1 100644 --- a/examples/aflpp_driver/aflpp_driver.cpp +++ b/examples/aflpp_driver/aflpp_driver.c @@ -49,10 +49,12 @@ If 1, close stdout at startup. If 2 close stderr; if 3 close both. #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <limits.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> -#include <fstream> -#include <iostream> -#include <vector> +#include "config.h" #ifdef _DEBUG #include "hash.h" @@ -98,32 +100,24 @@ extern unsigned int *__afl_fuzz_len; extern unsigned char *__afl_fuzz_ptr; // libFuzzer interface is thin, so we don't include any libFuzzer headers. -extern "C" { int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size); __attribute__((weak)) int LLVMFuzzerInitialize(int *argc, char ***argv); -} // Notify AFL about persistent mode. static volatile char AFL_PERSISTENT[] = "##SIG_AFL_PERSISTENT##"; -extern "C" int __afl_persistent_loop(unsigned int); -static volatile char suppress_warning2 = AFL_PERSISTENT[0]; +int __afl_persistent_loop(unsigned int); // Notify AFL about deferred forkserver. static volatile char AFL_DEFER_FORKSVR[] = "##SIG_AFL_DEFER_FORKSRV##"; -extern "C" void __afl_manual_init(); -static volatile char suppress_warning1 = AFL_DEFER_FORKSVR[0]; - -// Input buffer. -static const size_t kMaxAflInputSize = 1 << 20; -static uint8_t AflInputBuf[kMaxAflInputSize]; +void __afl_manual_init(); // Use this optionally defined function to output sanitizer messages even if // user asks to close stderr. -__attribute__((weak)) extern "C" void __sanitizer_set_report_fd(void *); +__attribute__((weak)) void __sanitizer_set_report_fd(void *); // Keep track of where stderr content is being written to, so that // dup_and_close_stderr can use the correct one. -static FILE *output_file = stderr; +static FILE *output_file; // Experimental feature to use afl_driver without AFL's deferred mode. // Needs to run before __afl_auto_init. @@ -179,18 +173,10 @@ static void dup_and_close_stderr() { abort(); if (!__sanitizer_set_report_fd) return; - __sanitizer_set_report_fd(reinterpret_cast<void *>(output_fd)); + __sanitizer_set_report_fd((void*)output_fd); discard_output(output_fileno); } -static void Printf(const char *Fmt, ...) { - va_list ap; - va_start(ap, Fmt); - vfprintf(output_file, Fmt, ap); - va_end(ap); - fflush(output_file); -} - // Close stdout and/or stderr if user asks for it. static void maybe_close_fd_mask() { char *fd_mask_str = getenv("AFL_DRIVER_CLOSE_FD_MASK"); @@ -205,32 +191,30 @@ static void maybe_close_fd_mask() { // Define LLVMFuzzerMutate to avoid link failures for targets that use it // with libFuzzer's LLVMFuzzerCustomMutator. -extern "C" size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize) { - assert(false && "LLVMFuzzerMutate should not be called from afl_driver"); +size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize) { + //assert(false && "LLVMFuzzerMutate should not be called from afl_driver"); return 0; } // Execute any files provided as parameters. static int ExecuteFilesOnyByOne(int argc, char **argv) { + unsigned char *buf = malloc(MAX_FILE); for (int i = 1; i < argc; i++) { - std::ifstream in(argv[i], std::ios::binary); - in.seekg(0, in.end); - size_t length = in.tellg(); - in.seekg (0, in.beg); - std::cout << "Reading " << length << " bytes from " << argv[i] << std::endl; - // Allocate exactly length bytes so that we reliably catch buffer overflows. - std::vector<char> bytes(length); - in.read(bytes.data(), bytes.size()); - assert(in); - LLVMFuzzerTestOneInput(reinterpret_cast<const uint8_t *>(bytes.data()), - bytes.size()); - std::cout << "Execution successful" << std::endl; + int fd = open(argv[i], O_RDONLY); + if (fd == -1) continue; + ssize_t length = read(fd, buf, MAX_FILE); + if (length > 0) { + printf("Reading %zu bytes from %s\n", length, argv[i]); + LLVMFuzzerTestOneInput(buf, length); + printf("Execution successful.\n"); + } } + free(buf); return 0; } int main(int argc, char **argv) { - Printf( + printf( "======================= INFO =========================\n" "This binary is built for AFL-fuzz.\n" "To run the target function on individual input(s) execute this:\n" @@ -244,18 +228,22 @@ int main(int argc, char **argv) { "======================================================\n", argv[0], argv[0], argv[0]); + output_file = stderr; maybe_duplicate_stderr(); maybe_close_fd_mask(); if (LLVMFuzzerInitialize) LLVMFuzzerInitialize(&argc, &argv); + // Do any other expensive one-time initialization here. - uint8_t dummy_input[1] = {0}; - int N = 100000; + uint8_t dummy_input[64] = {0}; + memcpy(dummy_input, (void*)AFL_PERSISTENT, sizeof(AFL_PERSISTENT)); + memcpy(dummy_input + 32, (void*)AFL_DEFER_FORKSVR, sizeof(AFL_DEFER_FORKSVR)); + int N = INT_MAX; if (argc == 2 && argv[1][0] == '-') N = atoi(argv[1] + 1); else if(argc == 2 && (N = atoi(argv[1])) > 0) - Printf("WARNING: using the deprecated call style `%s %d`\n", argv[0], N); + printf("WARNING: using the deprecated call style `%s %d`\n", argv[0], N); else if (argc > 1) { // if (!getenv("AFL_DRIVER_DONT_DEFER")) { __afl_sharedmem_fuzzing = 0; @@ -288,5 +276,5 @@ int main(int argc, char **argv) { LLVMFuzzerTestOneInput(__afl_fuzz_ptr, *__afl_fuzz_len); } } - Printf("%s: successfully executed %d input(s)\n", argv[0], num_runs); + printf("%s: successfully executed %d input(s)\n", argv[0], num_runs); } diff --git a/examples/aflpp_driver/aflpp_driver_test.cpp b/examples/aflpp_driver/aflpp_driver_test.c index 13dc09b9..83278f5c 100644 --- a/examples/aflpp_driver/aflpp_driver_test.cpp +++ b/examples/aflpp_driver/aflpp_driver_test.c @@ -1,9 +1,10 @@ #include <stdio.h> #include <stdlib.h> #include <stdint.h> + #include "hash.h" -extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { fprintf(stderr, "FUNC crc: %016llx len: %lu\n", hash64((u8*)Data, (unsigned int) Size, (unsigned long long int) 0xa5b35705), Size); diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 6e3be72b..44d3c522 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -134,6 +134,8 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) { } +#define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size + /* The same, but with an adjustable gap. Used for trimming. */ static void write_with_gap(afl_state_t *afl, void *mem, u32 len, u32 skip_at, @@ -142,18 +144,81 @@ static void write_with_gap(afl_state_t *afl, void *mem, u32 len, u32 skip_at, s32 fd = afl->fsrv.out_fd; u32 tail_len = len - skip_at - skip_len; + /* + This memory is used to carry out the post_processing(if present) after copying + the testcase by removing the gaps. This can break though + */ + u8 *mem_trimmed = ck_maybe_grow(BUF_PARAMS(out_scratch), len - skip_len + 1); + + ssize_t new_size = len - skip_len; + void * new_mem = mem; + u8 * new_buf = NULL; + + bool post_process_skipped = true; + + if (unlikely(afl->custom_mutators_count)) { + + new_mem = mem_trimmed; + + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (el->afl_custom_post_process) { + + // We copy into the mem_trimmed only if we actually have custom mutators + // *with* post_processing installed + + if (post_process_skipped) { + + if (skip_at) { memcpy(mem_trimmed, (u8 *)mem, skip_at); } + + if (tail_len) { + + memcpy(mem_trimmed + skip_at, (u8 *)mem + skip_at + skip_len, + tail_len); + + } + + post_process_skipped = false; + + } + + new_size = + el->afl_custom_post_process(el->data, new_mem, new_size, &new_buf); + + if (unlikely(!new_buf || (new_size <= 0))) { + + FATAL("Custom_post_process failed (ret: %lu)", + (long unsigned)new_size); + + } + + } + + new_mem = new_buf; + + }); + + } + if (afl->fsrv.shmem_fuzz) { - if (skip_at) { memcpy(afl->fsrv.shmem_fuzz, mem, skip_at); } + if (!post_process_skipped) { - if (tail_len) { + // If we did post_processing, copy directly from the new_buf bufer - memcpy(afl->fsrv.shmem_fuzz + skip_at, (u8 *)mem + skip_at + skip_len, - tail_len); + memcpy(afl->fsrv.shmem_fuzz, new_buf, new_size); } - *afl->fsrv.shmem_fuzz_len = len - skip_len; + else { + + memcpy(afl->fsrv.shmem_fuzz, mem, skip_at); + + memcpy(afl->fsrv.shmem_fuzz, mem + skip_at + skip_len, tail_len); + + } + + *afl->fsrv.shmem_fuzz_len = new_size; #ifdef _DEBUG if (afl->debug) { @@ -197,18 +262,21 @@ static void write_with_gap(afl_state_t *afl, void *mem, u32 len, u32 skip_at, } - if (skip_at) { ck_write(fd, mem, skip_at, afl->fsrv.out_file); } + if (!post_process_skipped) { + + ck_write(fd, new_buf, new_size, afl->fsrv.out_file); - u8 *memu8 = mem; - if (tail_len) { + } else { - ck_write(fd, memu8 + skip_at + skip_len, tail_len, afl->fsrv.out_file); + ck_write(fd, mem, skip_at, afl->fsrv.out_file); + + ck_write(fd, mem + skip_at + skip_len, tail_len, afl->fsrv.out_file); } if (!afl->fsrv.out_file) { - if (ftruncate(fd, len - skip_len)) { PFATAL("ftruncate() failed"); } + if (ftruncate(fd, new_size)) { PFATAL("ftruncate() failed"); } lseek(fd, 0, SEEK_SET); } else { @@ -219,6 +287,8 @@ static void write_with_gap(afl_state_t *afl, void *mem, u32 len, u32 skip_at, } +#undef BUF_PARAMS + /* Calibrate a new test case. This is done when processing the input directory to warn about flaky or otherwise problematic test cases early on; and when new paths are discovered to detect variable behavior and so on. */ |