diff options
Diffstat (limited to 'examples')
69 files changed, 0 insertions, 7448 deletions
diff --git a/examples/README.md b/examples/README.md deleted file mode 100644 index 7dd70d6a..00000000 --- a/examples/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# AFL++ Examples - -Here's a quick overview of the stuff you can find in this directory: - - - afl_network_proxy - fuzz a target over the network: afl-fuzz on - a host, target on an embedded system. - - - afl_proxy - skeleton file example to show how to fuzz - something where you gather coverage data via - different means, e.g. hw debugger - - - afl_untracer - fuzz binary-only libraries much faster but with - less coverage than qemu_mode - - - argv_fuzzing - a simple wrapper to allow cmdline to be fuzzed - (e.g., to test setuid programs). - - - asan_cgroups - a contributed script to simplify fuzzing ASAN - binaries with robust memory limits on Linux. - - - bash_shellshock - a simple hack used to find a bunch of - post-Shellshock bugs in bash. - - - canvas_harness - a test harness used to find browser bugs with a - corpus generated using simple image parsing - binaries & afl-fuzz. - - - clang_asm_normalize - a script that makes it easy to instrument - hand-written assembly, provided that you have clang. - - - crash_triage - a very rudimentary example of how to annotate crashes - with additional gdb metadata. - - - custom_mutators - examples for the afl++ custom mutator interface in - C and Python - - - distributed_fuzzing - a sample script for synchronizing fuzzer instances - across multiple machines (see parallel_fuzzing.md). - - - libpng_no_checksum - a sample patch for removing CRC checks in libpng. - - - persistent_mode - an example of how to use the LLVM persistent process - mode to speed up certain fuzzing jobs. - - - socket_fuzzing - a LD_PRELOAD library 'redirects' a socket to stdin - for fuzzing access with afl++ - -Note that the minimize_corpus.sh tool has graduated from the examples/ -directory and is now available as ../afl-cmin. The LLVM mode has likewise -graduated to ../instrumentation/*. - -Most of the tools in this directory are meant chiefly as examples that need to -be tweaked for your specific needs. They come with some basic documentation, -but are not necessarily production-grade. diff --git a/examples/afl_frida/GNUmakefile b/examples/afl_frida/GNUmakefile deleted file mode 100644 index c154f3a4..00000000 --- a/examples/afl_frida/GNUmakefile +++ /dev/null @@ -1,23 +0,0 @@ -ifdef DEBUG - OPT=-O0 -D_DEBUG=\"1\" -else - OPT=-O3 -funroll-loops -endif - -all: afl-frida libtestinstr.so - -libfrida-gum.a: - @echo Download and extract frida-gum-devkit-VERSION-PLATFORM.tar.xz for your platform from https://github.com/frida/frida/releases/latest - @exit 1 - -afl-frida: afl-frida.c libfrida-gum.a - $(CC) -g $(OPT) -o afl-frida -Wno-format -Wno-pointer-sign -I. -fpermissive -fPIC afl-frida.c ../../afl-llvm-rt.o libfrida-gum.a -ldl -lresolv -pthread - -libtestinstr.so: libtestinstr.c - $(CC) -g -O0 -fPIC -o libtestinstr.so -shared libtestinstr.c - -clean: - rm -f afl-frida *~ core *.o libtestinstr.so - -deepclean: clean - rm -f libfrida-gum.a frida-gum* diff --git a/examples/afl_frida/Makefile b/examples/afl_frida/Makefile deleted file mode 100644 index 0b306dde..00000000 --- a/examples/afl_frida/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - @echo please use GNU make, thanks! diff --git a/examples/afl_frida/README.md b/examples/afl_frida/README.md deleted file mode 100644 index 7743479b..00000000 --- a/examples/afl_frida/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# afl-frida - faster fuzzing of binary-only libraries - -## Introduction - -afl-frida is an example skeleton file which can easily be used to fuzz -a closed source library. - -It requires less memory and is x5-10 faster than qemu_mode but does not -provide interesting features like compcov or cmplog. - -## How-to - -### Modify afl-frida.c - -Read and modify afl-frida.c then `make`. -To adapt afl-frida.c to your needs, read the header of the file and then -search and edit the `STEP 1`, `STEP 2` and `STEP 3` locations. - -### Fuzzing - -Example (after modifying afl-frida.c to your needs and compile it): -``` -LD_LIBRARY_PATH=/path/to/the/target/library afl-fuzz -i in -o out -- ./afl-frida -``` -(or even remote via afl-network-proxy). - -# Speed and stability - -The speed is very good, about x12 of fork() qemu_mode. -However the stability is low. Reason is currently unknown. - -# Background - -This code is copied for a larger part from https://github.com/meme/hotwax diff --git a/examples/afl_frida/afl-frida.c b/examples/afl_frida/afl-frida.c deleted file mode 100644 index 31bf8f25..00000000 --- a/examples/afl_frida/afl-frida.c +++ /dev/null @@ -1,542 +0,0 @@ -/* - american fuzzy lop++ - afl-frida skeleton example - ------------------------------------------------- - - Copyright 2020 AFLplusplus Project. All rights reserved. - - Written mostly by meme -> https://github.com/meme/hotwax - - 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. - You may obtain a copy of the License at: - - http://www.apache.org/licenses/LICENSE-2.0 - - HOW-TO - ====== - - You only need to change the following: - - 1. set the defines and function call parameters. - 2. dl load the library you want to fuzz, lookup the functions you need - and setup the calls to these. - 3. in the while loop you call the functions in the necessary order - - incl the cleanup. the cleanup is important! - - Just look these steps up in the code, look for "// STEP x:" - -*/ - -#include <stdio.h> -#include <stdint.h> -#include <unistd.h> -#include <stdint.h> -#include <stddef.h> -#include <sys/shm.h> -#include <dlfcn.h> - -#ifndef __APPLE__ - #include <sys/wait.h> - #include <sys/personality.h> -#endif - -int debug = 0; - -// STEP 1: - -// The presets are for the example libtestinstr.so: - -/* What is the name of the library to fuzz */ -#define TARGET_LIBRARY "libtestinstr.so" - -/* What is the name of the function to fuzz */ -#define TARGET_FUNCTION "testinstr" - -/* here you need to specify the parameter for the target function */ -static void *(*o_function)(uint8_t *, int); - -// END STEP 1 - -#include "frida-gum.h" - -G_BEGIN_DECLS - -#define GUM_TYPE_FAKE_EVENT_SINK (gum_fake_event_sink_get_type()) -G_DECLARE_FINAL_TYPE(GumFakeEventSink, gum_fake_event_sink, GUM, - FAKE_EVENT_SINK, GObject) - -struct _GumFakeEventSink { - - GObject parent; - GumEventType mask; - -}; - -GumEventSink *gum_fake_event_sink_new(void); -void gum_fake_event_sink_reset(GumFakeEventSink *self); - -G_END_DECLS - -static void gum_fake_event_sink_iface_init(gpointer g_iface, - gpointer iface_data); -static void gum_fake_event_sink_finalize(GObject *obj); -static GumEventType gum_fake_event_sink_query_mask(GumEventSink *sink); -static void gum_fake_event_sink_process(GumEventSink *sink, const GumEvent *ev); -void instr_basic_block(GumStalkerIterator *iterator, GumStalkerOutput *output, - gpointer user_data); -void afl_setup(void); -void afl_start_forkserver(void); -int __afl_persistent_loop(unsigned int max_cnt); - -static void gum_fake_event_sink_class_init(GumFakeEventSinkClass *klass) { - - GObjectClass *object_class = G_OBJECT_CLASS(klass); - object_class->finalize = gum_fake_event_sink_finalize; - -} - -static void gum_fake_event_sink_iface_init(gpointer g_iface, - gpointer iface_data) { - - GumEventSinkInterface *iface = (GumEventSinkInterface *)g_iface; - iface->query_mask = gum_fake_event_sink_query_mask; - iface->process = gum_fake_event_sink_process; - -} - -G_DEFINE_TYPE_EXTENDED(GumFakeEventSink, gum_fake_event_sink, G_TYPE_OBJECT, 0, - G_IMPLEMENT_INTERFACE(GUM_TYPE_EVENT_SINK, - gum_fake_event_sink_iface_init)) - -#include "../../config.h" - -// Shared memory fuzzing. -int __afl_sharedmem_fuzzing = 1; -extern unsigned int * __afl_fuzz_len; -extern unsigned char *__afl_fuzz_ptr; - -// Notify AFL about persistent mode. -static volatile char AFL_PERSISTENT[] = "##SIG_AFL_PERSISTENT##"; -int __afl_persistent_loop(unsigned int); - -// Notify AFL about deferred forkserver. -static volatile char AFL_DEFER_FORKSVR[] = "##SIG_AFL_DEFER_FORKSRV##"; -void __afl_manual_init(); - -// Because we do our own logging. -extern uint8_t * __afl_area_ptr; -static __thread guint64 previous_pc; - -// Frida stuff below. -typedef struct { - - GumAddress base_address; - guint64 code_start, code_end; - -} range_t; - -inline static void afl_maybe_log(guint64 current_pc) { - - // fprintf(stderr, "PC: %p ^ %p\n", current_pc, previous_pc); - - current_pc = (current_pc >> 4) ^ (current_pc << 8); - current_pc &= MAP_SIZE - 1; - - __afl_area_ptr[current_pc ^ previous_pc]++; - previous_pc = current_pc >> 1; - -} - -static void on_basic_block(GumCpuContext *context, gpointer user_data) { - - afl_maybe_log((guint64)user_data); - -} - -void instr_basic_block(GumStalkerIterator *iterator, GumStalkerOutput *output, - gpointer user_data) { - - range_t *range = (range_t *)user_data; - - const cs_insn *instr; - gboolean begin = TRUE; - while (gum_stalker_iterator_next(iterator, &instr)) { - - if (begin) { - - if (instr->address >= range->code_start && - instr->address <= range->code_end) { - - gum_stalker_iterator_put_callout(iterator, on_basic_block, - (gpointer)instr->address, NULL); - begin = FALSE; - - } - - } - - gum_stalker_iterator_keep(iterator); - - } - -} - -static void gum_fake_event_sink_init(GumFakeEventSink *self) { - -} - -static void gum_fake_event_sink_finalize(GObject *obj) { - - G_OBJECT_CLASS(gum_fake_event_sink_parent_class)->finalize(obj); - -} - -GumEventSink *gum_fake_event_sink_new(void) { - - GumFakeEventSink *sink; - sink = (GumFakeEventSink *)g_object_new(GUM_TYPE_FAKE_EVENT_SINK, NULL); - return GUM_EVENT_SINK(sink); - -} - -void gum_fake_event_sink_reset(GumFakeEventSink *self) { - -} - -static GumEventType gum_fake_event_sink_query_mask(GumEventSink *sink) { - - return 0; - -} - -typedef struct library_list { - - uint8_t *name; - uint64_t addr_start, addr_end; - -} library_list_t; - -#define MAX_LIB_COUNT 256 -static library_list_t liblist[MAX_LIB_COUNT]; -static u32 liblist_cnt; - -void read_library_information() { - -#if defined(__linux__) - FILE *f; - u8 buf[1024], *b, *m, *e, *n; - - if ((f = fopen("/proc/self/maps", "r")) == NULL) { - - fprintf(stderr, "Error: cannot open /proc/self/maps\n"); - exit(-1); - - } - - if (debug) fprintf(stderr, "Library list:\n"); - while (fgets(buf, sizeof(buf), f)) { - - if (strstr(buf, " r-x")) { - - if (liblist_cnt >= MAX_LIB_COUNT) { - - fprintf( - stderr, - "Warning: too many libraries to old, maximum count of %d reached\n", - liblist_cnt); - return; - - } - - b = buf; - m = index(buf, '-'); - e = index(buf, ' '); - if ((n = rindex(buf, '/')) == NULL) n = rindex(buf, ' '); - if (n && - ((*n >= '0' && *n <= '9') || *n == '[' || *n == '{' || *n == '(')) - n = NULL; - else - n++; - if (b && m && e && n && *n) { - - *m++ = 0; - *e = 0; - if (n[strlen(n) - 1] == '\n') n[strlen(n) - 1] = 0; - - if (rindex(n, '/') != NULL) { - - n = rindex(n, '/'); - n++; - - } - - liblist[liblist_cnt].name = strdup(n); - liblist[liblist_cnt].addr_start = strtoull(b, NULL, 16); - liblist[liblist_cnt].addr_end = strtoull(m, NULL, 16); - if (debug) - fprintf( - stderr, "%s:%llx (%llx-%llx)\n", liblist[liblist_cnt].name, - liblist[liblist_cnt].addr_end - liblist[liblist_cnt].addr_start, - liblist[liblist_cnt].addr_start, - liblist[liblist_cnt].addr_end - 1); - liblist_cnt++; - - } - - } - - } - - if (debug) fprintf(stderr, "\n"); - -#elif defined(__FreeBSD__) - int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_VMMAP, getpid()}; - char * buf, *start, *end; - size_t miblen = sizeof(mib) / sizeof(mib[0]); - size_t len; - - if (debug) fprintf(stderr, "Library list:\n"); - if (sysctl(mib, miblen, NULL, &len, NULL, 0) == -1) { return; } - - len = len * 4 / 3; - - buf = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); - if (buf == MAP_FAILED) { return; } - if (sysctl(mib, miblen, buf, &len, NULL, 0) == -1) { - - munmap(buf, len); - return; - - } - - start = buf; - end = buf + len; - - while (start < end) { - - struct kinfo_vmentry *region = (struct kinfo_vmentry *)start; - size_t size = region->kve_structsize; - - if (size == 0) { break; } - - if ((region->kve_protection & KVME_PROT_READ) && - !(region->kve_protection & KVME_PROT_EXEC)) { - - liblist[liblist_cnt].name = - region->kve_path[0] != '\0' ? strdup(region->kve_path) : 0; - liblist[liblist_cnt].addr_start = region->kve_start; - liblist[liblist_cnt].addr_end = region->kve_end; - - if (debug) { - - fprintf(stderr, "%s:%x (%lx-%lx)\n", liblist[liblist_cnt].name, - liblist[liblist_cnt].addr_end - liblist[liblist_cnt].addr_start, - liblist[liblist_cnt].addr_start, - liblist[liblist_cnt].addr_end - 1); - - } - - liblist_cnt++; - - } - - start += size; - - } - -#endif - -} - -library_list_t *find_library(char *name) { - - char *filename = rindex(name, '/'); - - if (filename) - filename++; - else - filename = name; - -#if defined(__linux__) - u32 i; - for (i = 0; i < liblist_cnt; i++) - if (strcmp(liblist[i].name, filename) == 0) return &liblist[i]; -#elif defined(__APPLE__) && defined(__LP64__) - kern_return_t err; - static library_list_t lib; - - // get the list of all loaded modules from dyld - // the task_info mach API will get the address of the dyld all_image_info - // struct for the given task from which we can get the names and load - // addresses of all modules - task_dyld_info_data_t task_dyld_info; - mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT; - err = task_info(mach_task_self(), TASK_DYLD_INFO, - (task_info_t)&task_dyld_info, &count); - - const struct dyld_all_image_infos *all_image_infos = - (const struct dyld_all_image_infos *)task_dyld_info.all_image_info_addr; - const struct dyld_image_info *image_infos = all_image_infos->infoArray; - - for (size_t i = 0; i < all_image_infos->infoArrayCount; i++) { - - const char * image_name = image_infos[i].imageFilePath; - mach_vm_address_t image_load_address = - (mach_vm_address_t)image_infos[i].imageLoadAddress; - if (strstr(image_name, name)) { - - lib.name = name; - lib.addr_start = (u64)image_load_address; - lib.addr_end = 0; - return &lib; - - } - - } - -#endif - - return NULL; - -} - -static void gum_fake_event_sink_process(GumEventSink * sink, - const GumEvent *ev) { - -} - -/* Because this CAN be called more than once, it will return the LAST range */ -static int enumerate_ranges(const GumRangeDetails *details, - gpointer user_data) { - - GumMemoryRange *code_range = (GumMemoryRange *)user_data; - memcpy(code_range, details->range, sizeof(*code_range)); - return 0; - -} - -int main() { - -#ifndef __APPLE__ - (void)personality(ADDR_NO_RANDOMIZE); // disable ASLR -#endif - - // STEP 2: load the library you want to fuzz and lookup the functions, - // inclusive of the cleanup functions. - // If there is just one function, then there is nothing to change - // or add here. - - void *dl = dlopen(TARGET_LIBRARY, RTLD_LAZY); - if (!dl) { - - fprintf(stderr, "Could not load %s\n", TARGET_LIBRARY); - exit(-1); - - } - - if (!(o_function = dlsym(dl, TARGET_FUNCTION))) { - - fprintf(stderr, "Could not find function %s\n", TARGET_FUNCTION); - exit(-1); - - } - - // END STEP 2 - - read_library_information(); - library_list_t *lib = find_library(TARGET_LIBRARY); - - if (lib == NULL) { - - fprintf(stderr, "Could not find target library\n"); - exit(-1); - - } - - gum_init_embedded(); - if (!gum_stalker_is_supported()) { - - gum_deinit_embedded(); - return 1; - - } - - GumStalker *stalker = gum_stalker_new(); - - /* - This does not work here as we load a shared library. pretty sure this - would also be easily solvable with frida gum, but I already have all the - code I need from afl-untracer - - GumAddress base_address = gum_module_find_base_address(TARGET_LIBRARY); - GumMemoryRange code_range; - gum_module_enumerate_ranges(TARGET_LIBRARY, GUM_PAGE_RX, enumerate_ranges, - &code_range); - guint64 code_start = code_range.base_address - base_address; - guint64 code_end = (code_range.base_address + code_range.size) - base_address; - range_t instr_range = {base_address, code_start, code_end}; - */ - range_t instr_range = {0, lib->addr_start, lib->addr_end}; - - GumStalkerTransformer *transformer = - gum_stalker_transformer_make_from_callback(instr_basic_block, - &instr_range, NULL); - - GumEventSink *event_sink = gum_fake_event_sink_new(); - - // to ensure that the signatures are not optimized out - memcpy(__afl_area_ptr, (void *)AFL_PERSISTENT, sizeof(AFL_PERSISTENT) + 1); - memcpy(__afl_area_ptr + 32, (void *)AFL_DEFER_FORKSVR, - sizeof(AFL_DEFER_FORKSVR) + 1); - __afl_manual_init(); - - // - // any expensive target library initialization that has to be done just once - // - put that here - // - - gum_stalker_follow_me(stalker, transformer, event_sink); - - while (__afl_persistent_loop(UINT32_MAX) != 0) { - - previous_pc = 0; // Required! - -#ifdef _DEBUG - 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"); -#endif - - // STEP 3: ensure the minimum length is present and setup the target - // function to fuzz. - - if (*__afl_fuzz_len > 0) { - - __afl_fuzz_ptr[*__afl_fuzz_len] = 0; // if you need to null terminate - (*o_function)(__afl_fuzz_ptr, *__afl_fuzz_len); - - } - - // END STEP 3 - - } - - gum_stalker_unfollow_me(stalker); - - while (gum_stalker_garbage_collect(stalker)) - g_usleep(10000); - - g_object_unref(stalker); - g_object_unref(transformer); - g_object_unref(event_sink); - gum_deinit_embedded(); - - return 0; - -} - diff --git a/examples/afl_frida/afl-frida.h b/examples/afl_frida/afl-frida.h deleted file mode 100644 index efa3440f..00000000 --- a/examples/afl_frida/afl-frida.h +++ /dev/null @@ -1,53 +0,0 @@ -extern int is_persistent; - -G_BEGIN_DECLS - -#define GUM_TYPE_FAKE_EVENT_SINK (gum_fake_event_sink_get_type()) - -G_DECLARE_FINAL_TYPE(GumFakeEventSink, gum_fake_event_sink, GUM, - FAKE_EVENT_SINK, GObject) - -struct _GumFakeEventSink { - - GObject parent; - GumEventType mask; - -}; - -GumEventSink *gum_fake_event_sink_new(void); -void gum_fake_event_sink_reset(GumFakeEventSink *self); - -G_END_DECLS - -typedef struct { - - GumAddress base_address; - guint64 code_start, code_end; - -} range_t; - -void instr_basic_block(GumStalkerIterator *iterator, GumStalkerOutput *output, - gpointer user_data); -#pragma once - -void afl_setup(void); -void afl_start_forkserver(void); -int __afl_persistent_loop(unsigned int max_cnt); - -inline static inline void afl_maybe_log(guint64 current_pc) { - - extern unsigned int afl_instr_rms; - extern uint8_t * afl_area_ptr; - - static __thread guint64 previous_pc; - - current_pc = (current_pc >> 4) ^ (current_pc << 8); - current_pc &= MAP_SIZE - 1; - - if (current_pc >= afl_instr_rms) return; - - afl_area_ptr[current_pc ^ previous_pc]++; - previous_pc = current_pc >> 1; - -} - diff --git a/examples/afl_frida/libtestinstr.c b/examples/afl_frida/libtestinstr.c deleted file mode 100644 index 96b1cf21..00000000 --- a/examples/afl_frida/libtestinstr.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - american fuzzy lop++ - a trivial program to test the build - -------------------------------------------------------- - Originally written by Michal Zalewski - Copyright 2014 Google Inc. All rights reserved. - Copyright 2019-2020 AFLplusplus Project. All rights reserved. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at: - http://www.apache.org/licenses/LICENSE-2.0 - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - -void testinstr(char *buf, int len) { - - if (len < 1) return; - buf[len] = 0; - - // we support three input cases - if (buf[0] == '0') - printf("Looks like a zero to me!\n"); - else if (buf[0] == '1') - printf("Pretty sure that is a one!\n"); - else - printf("Neither one or zero? How quaint!\n"); - -} - diff --git a/examples/afl_network_proxy/GNUmakefile b/examples/afl_network_proxy/GNUmakefile deleted file mode 100644 index 25a3df82..00000000 --- a/examples/afl_network_proxy/GNUmakefile +++ /dev/null @@ -1,43 +0,0 @@ -PREFIX ?= /usr/local -BIN_PATH = $(PREFIX)/bin -DOC_PATH = $(PREFIX)/share/doc/afl - -PROGRAMS = afl-network-client afl-network-server - -HASH=\# - -CFLAGS += -Wno-pointer-sign - -ifdef STATIC - CFLAGS += -static -endif - -ifeq "$(shell echo '$(HASH)include <libdeflate.h>@int main() { struct libdeflate_compressor *d = libdeflate_alloc_compressor(1); return 0;}' | tr @ '\n' | $(CC) $(CFLAGS) -x c - -o .test2 -ldeflate 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1" - CFLAGS += -DUSE_DEFLATE=1 - LDFLAGS += -ldeflate - $(info libdeflate-dev was detected, using compression) -else - $(warn did not find libdeflate-dev, cannot use compression) -endif - -all: $(PROGRAMS) - -help: - @echo make options: - @echo STATIC - build as static binaries - @echo COMPRESS_TESTCASES - compress test cases - -afl-network-client: afl-network-client.c - $(CC) $(CFLAGS) -I../../include -o afl-network-client afl-network-client.c $(LDFLAGS) - -afl-network-server: afl-network-server.c - $(CC) $(CFLAGS) -I../../include -o afl-network-server afl-network-server.c ../../src/afl-forkserver.c ../../src/afl-sharedmem.c ../../src/afl-common.c -DBIN_PATH=\"$(BIN_PATH)\" $(LDFLAGS) - -clean: - rm -f $(PROGRAMS) *~ core - -install: all - install -d -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(DOC_PATH) - install -m 755 $(PROGRAMS) $${DESTDIR}$(BIN_PATH) - install -T -m 644 README.md $${DESTDIR}$(DOC_PATH)/README.network_proxy.md - diff --git a/examples/afl_network_proxy/Makefile b/examples/afl_network_proxy/Makefile deleted file mode 100644 index 0b306dde..00000000 --- a/examples/afl_network_proxy/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - @echo please use GNU make, thanks! diff --git a/examples/afl_network_proxy/README.md b/examples/afl_network_proxy/README.md deleted file mode 100644 index a5ac3578..00000000 --- a/examples/afl_network_proxy/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# afl-network-proxy - -If you want to run afl-fuzz over the network than this is what you need :) -Note that the impact on fuzzing speed will be huge, expect a loss of 90%. - -## When to use this - -1. when you have to fuzz a target that has to run on a system that cannot - contain the fuzzing output (e.g. /tmp too small and file system is read-only) -2. when the target instantly reboots on crashes -3. ... any other reason you would need this - -## how to get it running - -### Compiling - -Just type `make` and let the autodetection do everything for you. - -Note that you will get a 40-50% performance increase if you have libdeflate-dev -installed. The GNUmakefile will autodetect it if present. - -If your target has large test cases (10+kb) that are ascii only or large chunks -of zero blocks then set `CFLAGS=-DCOMPRESS_TESTCASES=1` to compress them. -For most targets this hurts performance though so it is disabled by default. - -### on the target - -Run `afl-network-server` with your target with the -m and -t values you need. -Important is the -i parameter which is the TCP port to listen on. -e.g.: -``` -afl-network-server -i 1111 -m 25M -t 1000 -- /bin/target -f @@ -``` - -### on the (afl-fuzz) master - -Just run afl-fuzz with your normal options, however the target should be -`afl-network-client` with the IP and PORT of the `afl-network-server` and -increase the -t value: -``` -afl-fuzz -i in -o out -t 2000+ -- afl-network-client TARGET-IP 1111 -``` -Note the '+' on the -t parameter value. The afl-network-server will take -care of proper timeouts hence afl-fuzz should not. The '+' increases the -timeout and the value itself should be 500-1000 higher than the one on -afl-network-server. - -### networking - -The TARGET can be an IPv4 or IPv6 address, or a host name that resolves to -either. Note that also the outgoing interface can be specified with a '%' for -`afl-network-client`, e.g. `fe80::1234%eth0`. - -Also make sure your default TCP window size is larger than your MAP_SIZE -(130kb is a good value). -On Linux that is the middle value of `/proc/sys/net/ipv4/tcp_rmem` - -## how to compile and install - -`make && sudo make install` - diff --git a/examples/afl_network_proxy/afl-network-client.c b/examples/afl_network_proxy/afl-network-client.c deleted file mode 100644 index a2451fdc..00000000 --- a/examples/afl_network_proxy/afl-network-client.c +++ /dev/null @@ -1,415 +0,0 @@ -/* - american fuzzy lop++ - afl-network-client - --------------------------------------- - - Written by Marc Heuse <mh@mh-sec.de> - - Copyright 2019-2020 AFLplusplus Project. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at: - - http://www.apache.org/licenses/LICENSE-2.0 - -*/ - -#ifdef __ANDROID__ - #include "android-ashmem.h" -#endif -#include "config.h" -#include "types.h" -#include "debug.h" - -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <unistd.h> -#include <string.h> -#include <assert.h> -#include <stdint.h> -#include <errno.h> - -#include <netinet/in.h> -#include <netinet/ip6.h> -#include <arpa/inet.h> -#include <sys/mman.h> -#ifndef USEMMAP - #include <sys/shm.h> -#endif -#include <sys/wait.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netdb.h> -#include <fcntl.h> - -#ifdef USE_DEFLATE - #include <libdeflate.h> -#endif - -u8 *__afl_area_ptr; - -#ifdef __ANDROID__ -u32 __afl_map_size = MAP_SIZE; -#else -__thread u32 __afl_map_size = MAP_SIZE; -#endif - -/* Error reporting to forkserver controller */ - -void send_forkserver_error(int error) { - - u32 status; - if (!error || error > 0xffff) return; - status = (FS_OPT_ERROR | FS_OPT_SET_ERROR(error)); - if (write(FORKSRV_FD + 1, (char *)&status, 4) != 4) return; - -} - -/* SHM setup. */ - -static void __afl_map_shm(void) { - - char *id_str = getenv(SHM_ENV_VAR); - char *ptr; - - if ((ptr = getenv("AFL_MAP_SIZE")) != NULL) { - - u32 val = atoi(ptr); - if (val > 0) __afl_map_size = val; - - } - - if (__afl_map_size > MAP_SIZE) { - - if (__afl_map_size > FS_OPT_MAX_MAPSIZE) { - - fprintf(stderr, - "Error: AFL++ tools *require* to set AFL_MAP_SIZE to %u to " - "be able to run this instrumented program!\n", - __afl_map_size); - if (id_str) { - - send_forkserver_error(FS_ERROR_MAP_SIZE); - exit(-1); - - } - - } else { - - fprintf(stderr, - "Warning: AFL++ tools will need to set AFL_MAP_SIZE to %u to " - "be able to run this instrumented program!\n", - __afl_map_size); - - } - - } - - if (id_str) { - -#ifdef USEMMAP - const char * shm_file_path = id_str; - int shm_fd = -1; - unsigned char *shm_base = NULL; - - /* create the shared memory segment as if it was a file */ - shm_fd = shm_open(shm_file_path, O_RDWR, 0600); - if (shm_fd == -1) { - - fprintf(stderr, "shm_open() failed\n"); - send_forkserver_error(FS_ERROR_SHM_OPEN); - exit(1); - - } - - /* map the shared memory segment to the address space of the process */ - shm_base = - mmap(0, __afl_map_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - - if (shm_base == MAP_FAILED) { - - close(shm_fd); - shm_fd = -1; - - fprintf(stderr, "mmap() failed\n"); - send_forkserver_error(FS_ERROR_MMAP); - exit(2); - - } - - __afl_area_ptr = shm_base; -#else - u32 shm_id = atoi(id_str); - - __afl_area_ptr = shmat(shm_id, 0, 0); - -#endif - - if (__afl_area_ptr == (void *)-1) { - - send_forkserver_error(FS_ERROR_SHMAT); - exit(1); - - } - - /* Write something into the bitmap so that the parent doesn't give up */ - - __afl_area_ptr[0] = 1; - - } - -} - -/* Fork server logic. */ - -static void __afl_start_forkserver(void) { - - u8 tmp[4] = {0, 0, 0, 0}; - u32 status = 0; - - if (__afl_map_size <= FS_OPT_MAX_MAPSIZE) - status |= (FS_OPT_SET_MAPSIZE(__afl_map_size) | FS_OPT_MAPSIZE); - if (status) status |= (FS_OPT_ENABLED); - memcpy(tmp, &status, 4); - - /* Phone home and tell the parent that we're OK. */ - - if (write(FORKSRV_FD + 1, tmp, 4) != 4) return; - -} - -static u32 __afl_next_testcase(u8 *buf, u32 max_len) { - - s32 status, res = 0x0fffffff; // res is a dummy pid - - /* Wait for parent by reading from the pipe. Abort if read fails. */ - if (read(FORKSRV_FD, &status, 4) != 4) return 0; - - /* we have a testcase - read it */ - status = read(0, buf, max_len); - - /* report that we are starting the target */ - if (write(FORKSRV_FD + 1, &res, 4) != 4) return 0; - - if (status < 1) - return 0; - else - return status; - -} - -static void __afl_end_testcase(int status) { - - if (write(FORKSRV_FD + 1, &status, 4) != 4) exit(1); - -} - -/* you just need to modify the while() loop in this main() */ - -int main(int argc, char *argv[]) { - - u8 * interface, *buf, *ptr; - s32 s = -1; - struct addrinfo hints, *hres, *aip; - u32 * lenptr, max_len = 65536; -#ifdef USE_DEFLATE - u8 * buf2; - u32 * lenptr1, *lenptr2, buf2_len, compress_len; - size_t decompress_len; -#endif - - if (argc < 3 || argc > 4) { - - printf("Syntax: %s host port [max-input-size]\n\n", argv[0]); - printf("Requires host and port of the remote afl-proxy-server instance.\n"); - printf( - "IPv4 and IPv6 are supported, also binding to an interface with " - "\"%%\"\n"); - printf("The max-input-size default is %u.\n", max_len); - printf( - "The default map size is %u and can be changed with setting " - "AFL_MAP_SIZE.\n", - __afl_map_size); - exit(-1); - - } - - if ((interface = strchr(argv[1], '%')) != NULL) *interface++ = 0; - - if (argc > 3) - if ((max_len = atoi(argv[3])) < 0) - FATAL("max-input-size may not be negative or larger than 2GB: %s", - argv[3]); - - if ((ptr = getenv("AFL_MAP_SIZE")) != NULL) - if ((__afl_map_size = atoi(ptr)) < 8) - FATAL("illegal map size, may not be < 8 or >= 2^30: %s", ptr); - - if ((buf = malloc(max_len + 4)) == NULL) - PFATAL("can not allocate %u memory", max_len + 4); - lenptr = (u32 *)buf; - -#ifdef USE_DEFLATE - buf2_len = (max_len > __afl_map_size ? max_len : __afl_map_size); - if ((buf2 = malloc(buf2_len + 8)) == NULL) - PFATAL("can not allocate %u memory", buf2_len + 8); - lenptr1 = (u32 *)buf2; - lenptr2 = (u32 *)(buf2 + 4); -#endif - - memset(&hints, 0, sizeof(hints)); - hints.ai_socktype = SOCK_STREAM; - hints.ai_family = PF_UNSPEC; - - if (getaddrinfo(argv[1], argv[2], &hints, &hres) != 0) - PFATAL("could not resolve target %s", argv[1]); - - for (aip = hres; aip != NULL && s == -1; aip = aip->ai_next) { - - if ((s = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol)) >= 0) { - -#ifdef SO_BINDTODEVICE - if (interface != NULL) - if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, interface, - strlen(interface) + 1) < 0) - fprintf(stderr, "Warning: could not bind to device %s\n", interface); -#else - fprintf(stderr, - "Warning: binding to interface is not supported for your OS\n"); -#endif - -#ifdef SO_PRIORITY - int priority = 7; - if (setsockopt(s, SOL_SOCKET, SO_PRIORITY, &priority, sizeof(priority)) < - 0) { - - priority = 6; - if (setsockopt(s, SOL_SOCKET, SO_PRIORITY, &priority, - sizeof(priority)) < 0) - WARNF("could not set priority on socket"); - - } - -#endif - - if (connect(s, aip->ai_addr, aip->ai_addrlen) == -1) s = -1; - - } - - } - -#ifdef USE_DEFLATE - struct libdeflate_compressor *compressor; - compressor = libdeflate_alloc_compressor(1); - struct libdeflate_decompressor *decompressor; - decompressor = libdeflate_alloc_decompressor(); - fprintf(stderr, "Compiled with compression support\n"); -#endif - - if (s == -1) - FATAL("could not connect to target tcp://%s:%s", argv[1], argv[2]); - else - fprintf(stderr, "Connected to target tcp://%s:%s\n", argv[1], argv[2]); - - /* we initialize the shared memory map and start the forkserver */ - __afl_map_shm(); - __afl_start_forkserver(); - - int i = 1, j, status, ret, received; - - // fprintf(stderr, "Waiting for first testcase\n"); - while ((*lenptr = __afl_next_testcase(buf + 4, max_len)) > 0) { - - // fprintf(stderr, "Sending testcase with len %u\n", *lenptr); -#ifdef USE_DEFLATE - #ifdef COMPRESS_TESTCASES - // we only compress the testcase if it does not fit in the TCP packet - if (*lenptr > 1500 - 20 - 32 - 4) { - - // set highest byte to signify compression - *lenptr1 = (*lenptr | 0xff000000); - *lenptr2 = (u32)libdeflate_deflate_compress(compressor, buf + 4, *lenptr, - buf2 + 8, buf2_len); - if (send(s, buf2, *lenptr2 + 8, 0) != *lenptr2 + 8) - PFATAL("sending test data failed"); - // fprintf(stderr, "COMPRESS (%u->%u):\n", *lenptr, *lenptr2); - // for (u32 i = 0; i < *lenptr; i++) - // fprintf(stderr, "%02x", buf[i + 4]); - // fprintf(stderr, "\n"); - // for (u32 i = 0; i < *lenptr2; i++) - // fprintf(stderr, "%02x", buf2[i + 8]); - // fprintf(stderr, "\n"); - - } else { - - #endif -#endif - if (send(s, buf, *lenptr + 4, 0) != *lenptr + 4) - PFATAL("sending test data failed"); -#ifdef USE_DEFLATE - #ifdef COMPRESS_TESTCASES - // fprintf(stderr, "unCOMPRESS (%u)\n", *lenptr); - - } - - #endif -#endif - - received = 0; - while (received < 4 && - (ret = recv(s, &status + received, 4 - received, 0)) > 0) - received += ret; - if (received != 4) - FATAL("did not receive waitpid data (%d, %d)", received, ret); - // fprintf(stderr, "Received status\n"); - - received = 0; -#ifdef USE_DEFLATE - while (received < 4 && - (ret = recv(s, &compress_len + received, 4 - received, 0)) > 0) - received += ret; - if (received != 4) - FATAL("did not receive compress_len (%d, %d)", received, ret); - // fprintf(stderr, "Received status\n"); - - received = 0; - while (received < compress_len && - (ret = recv(s, buf2 + received, buf2_len - received, 0)) > 0) - received += ret; - if (received != compress_len) - FATAL("did not receive coverage data (%d, %d)", received, ret); - - if (libdeflate_deflate_decompress(decompressor, buf2, compress_len, - __afl_area_ptr, __afl_map_size, - &decompress_len) != LIBDEFLATE_SUCCESS || - decompress_len != __afl_map_size) - FATAL("decompression failed"); - // fprintf(stderr, "DECOMPRESS (%u->%u): ", compress_len, decompress_len); - // for (u32 i = 0; i < __afl_map_size; i++) fprintf(stderr, "%02x", - // __afl_area_ptr[i]); fprintf(stderr, "\n"); -#else - while (received < __afl_map_size && - (ret = recv(s, __afl_area_ptr + received, __afl_map_size - received, - 0)) > 0) - received += ret; - if (received != __afl_map_size) - FATAL("did not receive coverage data (%d, %d)", received, ret); -#endif - // fprintf(stderr, "Received coverage\n"); - - /* report the test case is done and wait for the next */ - __afl_end_testcase(status); - // fprintf(stderr, "Waiting for next testcase %d\n", ++i); - - } - -#ifdef USE_DEFLATE - libdeflate_free_compressor(compressor); - libdeflate_free_decompressor(decompressor); -#endif - - return 0; - -} - diff --git a/examples/afl_network_proxy/afl-network-server.c b/examples/afl_network_proxy/afl-network-server.c deleted file mode 100644 index 513dc8f2..00000000 --- a/examples/afl_network_proxy/afl-network-server.c +++ /dev/null @@ -1,720 +0,0 @@ -/* - american fuzzy lop++ - network proxy server - ------------------------------------------- - - Originally written by Michal Zalewski - - Forkserver design by Jann Horn <jannhorn@googlemail.com> - - Now maintained by Marc Heuse <mh@mh-sec.de>, - Heiko Eißfeldt <heiko.eissfeldt@hexco.de> and - Andrea Fioraldi <andreafioraldi@gmail.com> and - Dominik Maier <mail@dmnk.co> - - Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2020 AFLplusplus Project. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at: - - http://www.apache.org/licenses/LICENSE-2.0 - - */ - -#define AFL_MAIN - -#ifdef __ANDROID__ - #include "android-ashmem.h" -#endif - -#include "config.h" -#include "types.h" -#include "debug.h" -#include "alloc-inl.h" -#include "hash.h" -#include "forkserver.h" -#include "sharedmem.h" -#include "common.h" - -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <errno.h> -#include <signal.h> -#include <dirent.h> -#include <fcntl.h> - -#include <sys/wait.h> -#include <sys/time.h> -#include <sys/shm.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/resource.h> -#include <netinet/in.h> -#include <netinet/ip6.h> -#include <arpa/inet.h> -#include <sys/mman.h> -#include <sys/shm.h> -#include <sys/socket.h> -#include <netdb.h> - -#ifdef USE_DEFLATE - #include <libdeflate.h> -struct libdeflate_compressor * compressor; -struct libdeflate_decompressor *decompressor; -#endif - -static u8 *in_file, /* Minimizer input test case */ - *out_file; - -static u8 *in_data; /* Input data for trimming */ -static u8 *buf2; - -static s32 in_len; -static s32 buf2_len; -static u32 map_size = MAP_SIZE; - -static volatile u8 stop_soon; /* Ctrl-C pressed? */ - -/* See if any bytes are set in the bitmap. */ - -static inline u8 anything_set(afl_forkserver_t *fsrv) { - - u32 *ptr = (u32 *)fsrv->trace_bits; - u32 i = (map_size >> 2); - - while (i--) { - - if (*(ptr++)) { return 1; } - - } - - return 0; - -} - -static void at_exit_handler(void) { - - afl_fsrv_killall(); - -} - -/* Write output file. */ - -static s32 write_to_file(u8 *path, u8 *mem, u32 len) { - - s32 ret; - - unlink(path); /* Ignore errors */ - - ret = open(path, O_RDWR | O_CREAT | O_EXCL, 0600); - - if (ret < 0) { PFATAL("Unable to create '%s'", path); } - - ck_write(ret, mem, len, path); - - lseek(ret, 0, SEEK_SET); - - return ret; - -} - -/* Execute target application. Returns 0 if the changes are a dud, or - 1 if they should be kept. */ - -static u8 run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len, - u8 first_run) { - - afl_fsrv_write_to_testcase(fsrv, mem, len); - - fsrv_run_result_t ret = - afl_fsrv_run_target(fsrv, fsrv->exec_tmout, &stop_soon); - - if (ret == FSRV_RUN_ERROR) { FATAL("Couldn't run child"); } - - if (stop_soon) { - - SAYF(cRST cLRD "\n+++ aborted by user +++\n" cRST); - exit(1); - - } - - return ret; - -} - -/* Handle Ctrl-C and the like. */ - -static void handle_stop_sig(int sig) { - - stop_soon = 1; - afl_fsrv_killall(); - -} - -/* Do basic preparations - persistent fds, filenames, etc. */ - -static void set_up_environment(afl_forkserver_t *fsrv) { - - u8 *x; - - fsrv->dev_null_fd = open("/dev/null", O_RDWR); - if (fsrv->dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); } - - if (!out_file) { - - u8 *use_dir = "."; - - if (access(use_dir, R_OK | W_OK | X_OK)) { - - use_dir = get_afl_env("TMPDIR"); - if (!use_dir) { use_dir = "/tmp"; } - - } - - out_file = alloc_printf("%s/.afl-input-temp-%u", use_dir, getpid()); - - } - - unlink(out_file); - - fsrv->out_fd = open(out_file, O_RDWR | O_CREAT | O_EXCL, 0600); - - if (fsrv->out_fd < 0) { PFATAL("Unable to create '%s'", out_file); } - - /* Set sane defaults... */ - - x = get_afl_env("ASAN_OPTIONS"); - - if (x) { - - if (!strstr(x, "abort_on_error=1")) { - - FATAL("Custom ASAN_OPTIONS set without abort_on_error=1 - please fix!"); - - } - - if (!strstr(x, "symbolize=0")) { - - FATAL("Custom ASAN_OPTIONS set without symbolize=0 - please fix!"); - - } - - } - - x = get_afl_env("MSAN_OPTIONS"); - - if (x) { - - if (!strstr(x, "exit_code=" STRINGIFY(MSAN_ERROR))) { - - FATAL("Custom MSAN_OPTIONS set without exit_code=" STRINGIFY( - MSAN_ERROR) " - please fix!"); - - } - - if (!strstr(x, "symbolize=0")) { - - FATAL("Custom MSAN_OPTIONS set without symbolize=0 - please fix!"); - - } - - } - - setenv("ASAN_OPTIONS", - "abort_on_error=1:" - "detect_leaks=0:" - "symbolize=0:" - "allocator_may_return_null=1", - 0); - - setenv("MSAN_OPTIONS", "exit_code=" STRINGIFY(MSAN_ERROR) ":" - "symbolize=0:" - "abort_on_error=1:" - "allocator_may_return_null=1:" - "msan_track_origins=0", 0); - - if (get_afl_env("AFL_PRELOAD")) { - - if (fsrv->qemu_mode) { - - u8 *qemu_preload = getenv("QEMU_SET_ENV"); - u8 *afl_preload = getenv("AFL_PRELOAD"); - u8 *buf; - - s32 i, afl_preload_size = strlen(afl_preload); - for (i = 0; i < afl_preload_size; ++i) { - - if (afl_preload[i] == ',') { - - PFATAL( - "Comma (',') is not allowed in AFL_PRELOAD when -Q is " - "specified!"); - - } - - } - - if (qemu_preload) { - - buf = alloc_printf("%s,LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s", - qemu_preload, afl_preload, afl_preload); - - } else { - - buf = alloc_printf("LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s", - afl_preload, afl_preload); - - } - - setenv("QEMU_SET_ENV", buf, 1); - - afl_free(buf); - - } else { - - setenv("LD_PRELOAD", getenv("AFL_PRELOAD"), 1); - setenv("DYLD_INSERT_LIBRARIES", getenv("AFL_PRELOAD"), 1); - - } - - } - -} - -/* Setup signal handlers, duh. */ - -static void setup_signal_handlers(void) { - - struct sigaction sa; - - sa.sa_handler = NULL; - sa.sa_flags = SA_RESTART; - sa.sa_sigaction = NULL; - - sigemptyset(&sa.sa_mask); - - /* Various ways of saying "stop". */ - - sa.sa_handler = handle_stop_sig; - sigaction(SIGHUP, &sa, NULL); - sigaction(SIGINT, &sa, NULL); - sigaction(SIGTERM, &sa, NULL); - -} - -/* Display usage hints. */ - -static void usage(u8 *argv0) { - - SAYF( - "\n%s [ options ] -- /path/to/target_app [ ... ]\n\n" - - "Required parameters:\n" - - " -i port - the port to listen for the client to connect to\n\n" - - "Execution control settings:\n" - - " -f file - input file read by the tested program (stdin)\n" - " -t msec - timeout for each run (%d ms)\n" - " -m megs - memory limit for child process (%d MB)\n" - " -Q - use binary-only instrumentation (QEMU mode)\n" - " -U - use unicorn-based instrumentation (Unicorn mode)\n" - " -W - use qemu-based instrumentation with Wine (Wine " - "mode)\n\n" - - "Environment variables used:\n" - "TMPDIR: directory to use for temporary input files\n" - "ASAN_OPTIONS: custom settings for ASAN\n" - " (must contain abort_on_error=1 and symbolize=0)\n" - "MSAN_OPTIONS: custom settings for MSAN\n" - " (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\n" - "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n" - " the target was compiled for\n" - "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n" - - , argv0, EXEC_TIMEOUT, MEM_LIMIT); - - exit(1); - -} - -int recv_testcase(int s, void **buf) { - - u32 size; - s32 ret; - size_t received; - - received = 0; - while (received < 4 && (ret = recv(s, &size + received, 4 - received, 0)) > 0) - received += ret; - if (received != 4) FATAL("did not receive size information"); - if (size == 0) FATAL("did not receive valid size information"); - // fprintf(stderr, "received size information of %d\n", size); - - if ((size & 0xff000000) != 0xff000000) { - - *buf = afl_realloc(buf, size); - if (unlikely(!*buf)) { PFATAL("Alloc"); } - received = 0; - // fprintf(stderr, "unCOMPRESS (%u)\n", size); - while (received < size && - (ret = recv(s, ((char *)*buf) + received, size - received, 0)) > 0) - received += ret; - - } else { - -#ifdef USE_DEFLATE - u32 clen; - size -= 0xff000000; - *buf = afl_realloc(buf, size); - if (unlikely(!*buf)) { PFATAL("Alloc"); } - received = 0; - while (received < 4 && - (ret = recv(s, &clen + received, 4 - received, 0)) > 0) - received += ret; - if (received != 4) FATAL("did not receive clen1 information"); - // fprintf(stderr, "received clen information of %d\n", clen); - if (clen < 1) - FATAL("did not receive valid compressed len information: %u", clen); - buf2 = afl_realloc((void **)&buf2, clen); - buf2_len = clen; - if (unlikely(!buf2)) { PFATAL("Alloc"); } - received = 0; - while (received < clen && - (ret = recv(s, buf2 + received, clen - received, 0)) > 0) - received += ret; - if (received != clen) FATAL("did not receive compressed information"); - if (libdeflate_deflate_decompress(decompressor, buf2, clen, (char *)*buf, - size, &received) != LIBDEFLATE_SUCCESS) - FATAL("decompression failed"); - // fprintf(stderr, "DECOMPRESS (%u->%u):\n", clen, received); - // for (u32 i = 0; i < clen; i++) fprintf(stderr, "%02x", buf2[i]); - // fprintf(stderr, "\n"); - // for (u32 i = 0; i < received; i++) fprintf(stderr, "%02x", - // ((u8*)(*buf))[i]); fprintf(stderr, "\n"); -#else - FATAL("Received compressed data but not compiled with compression support"); -#endif - - } - - // fprintf(stderr, "receiving testcase %p %p max %u\n", buf, *buf, *max_len); - if (received != size) - FATAL("did not receive testcase data %lu != %u, %d", received, size, ret); - // fprintf(stderr, "received testcase\n"); - return size; - -} - -/* Main entry point */ - -int main(int argc, char **argv_orig, char **envp) { - - s32 opt, s, sock, on = 1, port = -1; - u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0; - char **use_argv; - struct sockaddr_in6 serveraddr, clientaddr; - int addrlen = sizeof(clientaddr); - char str[INET6_ADDRSTRLEN]; - char ** argv = argv_cpy_dup(argc, argv_orig); - u8 * send_buf; -#ifdef USE_DEFLATE - u32 *lenptr; -#endif - - afl_forkserver_t fsrv_var = {0}; - afl_forkserver_t *fsrv = &fsrv_var; - afl_fsrv_init(fsrv); - map_size = get_map_size(); - fsrv->map_size = map_size; - - if ((send_buf = malloc(map_size + 4)) == NULL) PFATAL("malloc"); - - while ((opt = getopt(argc, argv, "+i:f:m:t:QUWh")) > 0) { - - switch (opt) { - - case 'i': - - if (port > 0) { FATAL("Multiple -i options not supported"); } - port = atoi(optarg); - if (port < 1 || port > 65535) - FATAL("invalid port definition, must be between 1-65535: %s", optarg); - break; - - case 'f': - - if (out_file) { FATAL("Multiple -f options not supported"); } - fsrv->use_stdin = 0; - out_file = optarg; - break; - - case 'm': { - - u8 suffix = 'M'; - - if (mem_limit_given) { FATAL("Multiple -m options not supported"); } - mem_limit_given = 1; - - if (!optarg) { FATAL("Wrong usage of -m"); } - - if (!strcmp(optarg, "none")) { - - fsrv->mem_limit = 0; - break; - - } - - if (sscanf(optarg, "%llu%c", &fsrv->mem_limit, &suffix) < 1 || - optarg[0] == '-') { - - FATAL("Bad syntax used for -m"); - - } - - switch (suffix) { - - case 'T': - fsrv->mem_limit *= 1024 * 1024; - break; - case 'G': - fsrv->mem_limit *= 1024; - break; - case 'k': - fsrv->mem_limit /= 1024; - break; - case 'M': - break; - - default: - FATAL("Unsupported suffix or bad syntax for -m"); - - } - - if (fsrv->mem_limit < 5) { FATAL("Dangerously low value of -m"); } - - if (sizeof(rlim_t) == 4 && fsrv->mem_limit > 2000) { - - FATAL("Value of -m out of range on 32-bit systems"); - - } - - } - - break; - - case 't': - - if (timeout_given) { FATAL("Multiple -t options not supported"); } - timeout_given = 1; - - if (!optarg) { FATAL("Wrong usage of -t"); } - - fsrv->exec_tmout = atoi(optarg); - - if (fsrv->exec_tmout < 10 || optarg[0] == '-') { - - FATAL("Dangerously low value of -t"); - - } - - break; - - case 'Q': - - if (fsrv->qemu_mode) { FATAL("Multiple -Q options not supported"); } - if (!mem_limit_given) { fsrv->mem_limit = MEM_LIMIT_QEMU; } - - fsrv->qemu_mode = 1; - break; - - case 'U': - - if (unicorn_mode) { FATAL("Multiple -Q options not supported"); } - if (!mem_limit_given) { fsrv->mem_limit = MEM_LIMIT_UNICORN; } - - unicorn_mode = 1; - break; - - case 'W': /* Wine+QEMU mode */ - - if (use_wine) { FATAL("Multiple -W options not supported"); } - fsrv->qemu_mode = 1; - use_wine = 1; - - if (!mem_limit_given) { fsrv->mem_limit = 0; } - - break; - - case 'h': - usage(argv[0]); - return -1; - break; - - default: - usage(argv[0]); - - } - - } - - if (optind == argc || port < 1) { usage(argv[0]); } - - check_environment_vars(envp); - - sharedmem_t shm = {0}; - fsrv->trace_bits = afl_shm_init(&shm, map_size, 0); - - in_data = afl_realloc((void **)&in_data, 65536); - if (unlikely(!in_data)) { PFATAL("Alloc"); } - - atexit(at_exit_handler); - setup_signal_handlers(); - - set_up_environment(fsrv); - - fsrv->target_path = find_binary(argv[optind]); - detect_file_args(argv + optind, out_file, &fsrv->use_stdin); - - if (fsrv->qemu_mode) { - - if (use_wine) { - - use_argv = get_wine_argv(argv[0], &fsrv->target_path, argc - optind, - argv + optind); - - } else { - - use_argv = get_qemu_argv(argv[0], &fsrv->target_path, argc - optind, - argv + optind); - - } - - } else { - - use_argv = argv + optind; - - } - - if ((sock = socket(AF_INET6, SOCK_STREAM, 0)) < 0) PFATAL("socket() failed"); - -#ifdef SO_REUSEADDR - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) { - - WARNF("setsockopt(SO_REUSEADDR) failed"); - - } - -#endif - -#ifdef SO_PRIORITY - int priority = 7; - if (setsockopt(sock, SOL_SOCKET, SO_PRIORITY, &priority, sizeof(priority)) < - 0) { - - priority = 6; - if (setsockopt(sock, SOL_SOCKET, SO_PRIORITY, &priority, sizeof(priority)) < - 0) - WARNF("could not set priority on socket"); - - } - -#endif - - memset(&serveraddr, 0, sizeof(serveraddr)); - serveraddr.sin6_family = AF_INET6; - serveraddr.sin6_port = htons(port); - serveraddr.sin6_addr = in6addr_any; - - if (bind(sock, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) - PFATAL("bind() failed"); - - if (listen(sock, 1) < 0) { PFATAL("listen() failed"); } - - afl_fsrv_start( - fsrv, use_argv, &stop_soon, - (get_afl_env("AFL_DEBUG_CHILD") || get_afl_env("AFL_DEBUG_CHILD_OUTPUT")) - ? 1 - : 0); - -#ifdef USE_DEFLATE - compressor = libdeflate_alloc_compressor(1); - decompressor = libdeflate_alloc_decompressor(); - buf2 = afl_realloc((void **)&buf2, map_size + 16); - buf2_len = map_size + 16; - if (unlikely(!buf2)) { PFATAL("alloc"); } - lenptr = (u32 *)(buf2 + 4); - fprintf(stderr, "Compiled with compression support\n"); -#endif - - fprintf(stderr, - "Waiting for incoming connection from afl-network-client on port %d " - "...\n", - port); - - if ((s = accept(sock, NULL, NULL)) < 0) { PFATAL("accept() failed"); } - fprintf(stderr, "Received connection, starting ...\n"); - -#ifdef SO_PRIORITY - priority = 7; - if (setsockopt(s, SOL_SOCKET, SO_PRIORITY, &priority, sizeof(priority)) < 0) { - - priority = 6; - if (setsockopt(s, SOL_SOCKET, SO_PRIORITY, &priority, sizeof(priority)) < 0) - WARNF("could not set priority on socket"); - - } - -#endif - - while ((in_len = recv_testcase(s, (void **)&in_data)) > 0) { - - // fprintf(stderr, "received %u\n", in_len); - (void)run_target(fsrv, use_argv, in_data, in_len, 1); - - memcpy(send_buf + 4, fsrv->trace_bits, fsrv->map_size); - -#ifdef USE_DEFLATE - memcpy(buf2, &fsrv->child_status, 4); - *lenptr = (u32)libdeflate_deflate_compress( - compressor, send_buf + 4, fsrv->map_size, buf2 + 8, buf2_len - 8); - // fprintf(stderr, "COMPRESS (%u->%u): ", fsrv->map_size, *lenptr); - // for (u32 i = 0; i < fsrv->map_size; i++) fprintf(stderr, "%02x", - // fsrv->trace_bits[i]); fprintf(stderr, "\n"); - if (send(s, buf2, *lenptr + 8, 0) != 8 + *lenptr) - FATAL("could not send data"); -#else - memcpy(send_buf, &fsrv->child_status, 4); - if (send(s, send_buf, fsrv->map_size + 4, 0) != 4 + fsrv->map_size) - FATAL("could not send data"); -#endif - - // fprintf(stderr, "sent result\n"); - - } - - unlink(out_file); - if (out_file) { ck_free(out_file); } - out_file = NULL; - - afl_shm_deinit(&shm); - afl_fsrv_deinit(fsrv); - if (fsrv->target_path) { ck_free(fsrv->target_path); } - afl_free(in_data); -#if USE_DEFLATE - afl_free(buf2); - libdeflate_free_compressor(compressor); - libdeflate_free_decompressor(decompressor); -#endif - - argv_cpy_free(argv); - - exit(0); - -} - diff --git a/examples/afl_proxy/Makefile b/examples/afl_proxy/Makefile deleted file mode 100644 index 4b368f8d..00000000 --- a/examples/afl_proxy/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -all: afl-proxy - -afl-proxy: afl-proxy.c - $(CC) -I../../include -o afl-proxy afl-proxy.c - -clean: - rm -f afl-proxy *~ core diff --git a/examples/afl_proxy/README.md b/examples/afl_proxy/README.md deleted file mode 100644 index 3c768a19..00000000 --- a/examples/afl_proxy/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# afl-proxy - -afl-proxy is an example skeleton file which can easily be used to fuzz -and instrument non-standard things. - -You only need to change the while() loop of the main() to send the -data of buf[] with length len to the target and write the coverage -information to __afl_area_ptr[__afl_map_size] - diff --git a/examples/afl_proxy/afl-proxy.c b/examples/afl_proxy/afl-proxy.c deleted file mode 100644 index f2dfeac1..00000000 --- a/examples/afl_proxy/afl-proxy.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - american fuzzy lop++ - afl-proxy skeleton example - --------------------------------------------------- - - Written by Marc Heuse <mh@mh-sec.de> - - Copyright 2019-2020 AFLplusplus Project. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at: - - http://www.apache.org/licenses/LICENSE-2.0 - - - HOW-TO - ====== - - You only need to change the while() loop of the main() to send the - data of buf[] with length len to the target and write the coverage - information to __afl_area_ptr[__afl_map_size] - - -*/ - -#ifdef __ANDROID__ - #include "android-ashmem.h" -#endif -#include "config.h" -#include "types.h" - -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <unistd.h> -#include <string.h> -#include <assert.h> -#include <stdint.h> -#include <errno.h> - -#include <sys/mman.h> -#include <sys/shm.h> -#include <sys/wait.h> -#include <sys/types.h> -#include <fcntl.h> - -u8 *__afl_area_ptr; - -#ifdef __ANDROID__ -u32 __afl_map_size = MAP_SIZE; -#else -__thread u32 __afl_map_size = MAP_SIZE; -#endif - -/* Error reporting to forkserver controller */ - -void send_forkserver_error(int error) { - - u32 status; - if (!error || error > 0xffff) return; - status = (FS_OPT_ERROR | FS_OPT_SET_ERROR(error)); - if (write(FORKSRV_FD + 1, (char *)&status, 4) != 4) return; - -} - -/* SHM setup. */ - -static void __afl_map_shm(void) { - - char *id_str = getenv(SHM_ENV_VAR); - char *ptr; - - if ((ptr = getenv("AFL_MAP_SIZE")) != NULL) { - - u32 val = atoi(ptr); - if (val > 0) __afl_map_size = val; - - } - - if (__afl_map_size > MAP_SIZE) { - - if (__afl_map_size > FS_OPT_MAX_MAPSIZE) { - - fprintf(stderr, - "Error: AFL++ tools *require* to set AFL_MAP_SIZE to %u to " - "be able to run this instrumented program!\n", - __afl_map_size); - if (id_str) { - - send_forkserver_error(FS_ERROR_MAP_SIZE); - exit(-1); - - } - - } else { - - fprintf(stderr, - "Warning: AFL++ tools will need to set AFL_MAP_SIZE to %u to " - "be able to run this instrumented program!\n", - __afl_map_size); - - } - - } - - if (id_str) { - -#ifdef USEMMAP - const char * shm_file_path = id_str; - int shm_fd = -1; - unsigned char *shm_base = NULL; - - /* create the shared memory segment as if it was a file */ - shm_fd = shm_open(shm_file_path, O_RDWR, 0600); - if (shm_fd == -1) { - - fprintf(stderr, "shm_open() failed\n"); - send_forkserver_error(FS_ERROR_SHM_OPEN); - exit(1); - - } - - /* map the shared memory segment to the address space of the process */ - shm_base = - mmap(0, __afl_map_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - - if (shm_base == MAP_FAILED) { - - close(shm_fd); - shm_fd = -1; - - fprintf(stderr, "mmap() failed\n"); - send_forkserver_error(FS_ERROR_MMAP); - exit(2); - - } - - __afl_area_ptr = shm_base; -#else - u32 shm_id = atoi(id_str); - - __afl_area_ptr = shmat(shm_id, 0, 0); - -#endif - - if (__afl_area_ptr == (void *)-1) { - - send_forkserver_error(FS_ERROR_SHMAT); - exit(1); - - } - - /* Write something into the bitmap so that the parent doesn't give up */ - - __afl_area_ptr[0] = 1; - - } - -} - -/* Fork server logic. */ - -static void __afl_start_forkserver(void) { - - u8 tmp[4] = {0, 0, 0, 0}; - u32 status = 0; - - if (__afl_map_size <= FS_OPT_MAX_MAPSIZE) - status |= (FS_OPT_SET_MAPSIZE(__afl_map_size) | FS_OPT_MAPSIZE); - if (status) status |= (FS_OPT_ENABLED); - memcpy(tmp, &status, 4); - - /* Phone home and tell the parent that we're OK. */ - - if (write(FORKSRV_FD + 1, tmp, 4) != 4) return; - -} - -static u32 __afl_next_testcase(u8 *buf, u32 max_len) { - - s32 status, res = 0xffffff; - - /* Wait for parent by reading from the pipe. Abort if read fails. */ - if (read(FORKSRV_FD, &status, 4) != 4) return 0; - - /* we have a testcase - read it */ - status = read(0, buf, max_len); - - /* report that we are starting the target */ - if (write(FORKSRV_FD + 1, &res, 4) != 4) return 0; - - if (status < 1) - return 0; - else - return status; - -} - -static void __afl_end_testcase(void) { - - int status = 0xffffff; - - if (write(FORKSRV_FD + 1, &status, 4) != 4) exit(1); - -} - -/* you just need to modify the while() loop in this main() */ - -int main(int argc, char *argv[]) { - - /* This is were the testcase data is written into */ - u8 buf[1024]; // this is the maximum size for a test case! set it! - u32 len; - - /* here you specify the map size you need that you are reporting to - afl-fuzz. */ - __afl_map_size = MAP_SIZE; // default is 65536 - - /* then we initialize the shared memory map and start the forkserver */ - __afl_map_shm(); - __afl_start_forkserver(); - - while ((len = __afl_next_testcase(buf, sizeof(buf))) > 0) { - - /* here you have to create the magic that feeds the buf/len to the - target and write the coverage to __afl_area_ptr */ - - // ... the magic ... - - /* report the test case is done and wait for the next */ - __afl_end_testcase(); - - } - - return 0; - -} - diff --git a/examples/afl_untracer/Makefile b/examples/afl_untracer/Makefile deleted file mode 100644 index 14a09b41..00000000 --- a/examples/afl_untracer/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -ifdef DEBUG - OPT=-O0 -else - OPT=-O3 -endif - -all: afl-untracer libtestinstr.so - -afl-untracer: afl-untracer.c - $(CC) $(OPT) -I../../include -g -o afl-untracer afl-untracer.c -ldl - -libtestinstr.so: libtestinstr.c - $(CC) -g -O0 -fPIC -o libtestinstr.so -shared libtestinstr.c - -clean: - rm -f afl-untracer libtestinstr.so *~ core diff --git a/examples/afl_untracer/README.md b/examples/afl_untracer/README.md deleted file mode 100644 index ada0c916..00000000 --- a/examples/afl_untracer/README.md +++ /dev/null @@ -1,60 +0,0 @@ -# afl-untracer - fast fuzzing of binary-only libraries - -## Introduction - -afl-untracer is an example skeleton file which can easily be used to fuzz -a closed source library. - -It requires less memory and is x3-5 faster than qemu_mode however it is way -more course grained and does not provide interesting features like compcov -or cmplog. - -Supported is so far Intel (i386/x86_64) and AARCH64. - -## How-to - -### Modify afl-untracer.c - -Read and modify afl-untracer.c then `make`. -To adapt afl-untracer.c to your needs, read the header of the file and then -search and edit the `STEP 1`, `STEP 2` and `STEP 3` locations. - -### Generate patches.txt file - -To generate the `patches.txt` file for your target library use the -`ida_get_patchpoints.py` script for IDA Pro or -`ghidra_get_patchpoints.java` for Ghidra. - -The patches.txt file has to be pointed to by `AFL_UNTRACER_FILE`. - -To easily run the scripts without needing to run the GUI with Ghidra: -``` -/opt/ghidra/support/analyzeHeadless /tmp/ tmp$$ -import libtestinstr.so -postscript ./ghidra_get_patchpoints.java -rm -rf /tmp/tmp$$ -``` -The file is created at `~/Desktop/patches.txt` - -### Fuzzing - -Example (after modifying afl-untracer.c to your needs, compiling and creating -patches.txt): -``` -LD_LIBRARY_PATH=/path/to/target/library AFL_UNTRACER_FILE=./patches.txt afl-fuzz -i in -o out -- ./afl-untracer -``` -(or even remote via afl-network-proxy). - -### Testing and debugging - -For testing/debugging you can try: -``` -make DEBUG=1 -AFL_UNTRACER_FILE=./patches.txt AFL_DEBUG=1 gdb ./afl-untracer -``` -and then you can easily set breakpoints to "breakpoint" and "fuzz". - -# Background - -This idea is based on [UnTracer](https://github.com/FoRTE-Research/UnTracer-AFL) -and modified by [Trapfuzz](https://github.com/googleprojectzero/p0tools/tree/master/TrapFuzz). -This implementation is slower because the traps are not patched out with each -run, but on the other hand gives much better coverage information. diff --git a/examples/afl_untracer/TODO b/examples/afl_untracer/TODO deleted file mode 100644 index fffffacf..00000000 --- a/examples/afl_untracer/TODO +++ /dev/null @@ -1,2 +0,0 @@ - * add shmem fuzzing - * add snapshot feature? diff --git a/examples/afl_untracer/afl-untracer.c b/examples/afl_untracer/afl-untracer.c deleted file mode 100644 index cb6f948c..00000000 --- a/examples/afl_untracer/afl-untracer.c +++ /dev/null @@ -1,768 +0,0 @@ -/* - american fuzzy lop++ - afl-untracer skeleton example - --------------------------------------------------- - - Written by Marc Heuse <mh@mh-sec.de> - - Copyright 2019-2020 AFLplusplus Project. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at: - - http://www.apache.org/licenses/LICENSE-2.0 - - - HOW-TO - ====== - - You only need to change the following: - - 1. decide if you want to receive data from stdin [DEFAULT] or file(name) - -> use_stdin = 0 if via file, and what the maximum input size is - 2. dl load the library you want to fuzz, lookup the functions you need - and setup the calls to these - 3. in the while loop you call the functions in the necessary order - - incl the cleanup. the cleanup is important! - - Just look these steps up in the code, look for "// STEP x:" - - -*/ - -#define __USE_GNU -#define _GNU_SOURCE - -#ifdef __ANDROID__ - #include "android-ashmem.h" -#endif -#include "config.h" -#include "types.h" -#include "debug.h" - -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <unistd.h> -#include <string.h> -#include <assert.h> -#include <stdint.h> -#include <errno.h> -#include <dlfcn.h> -#include <fcntl.h> -#include <pthread.h> - -#include <sys/mman.h> -#include <sys/shm.h> -#include <sys/wait.h> -#include <sys/types.h> -#include <sys/personality.h> - -#if defined(__linux__) - #include <sys/ucontext.h> -#elif defined(__APPLE__) && defined(__LP64__) - #include <mach-o/dyld_images.h> -#elif defined(__FreeBSD__) - #include <sys/sysctl.h> - #include <sys/user.h> -#else - #error "Unsupported platform" -#endif - -#define MEMORY_MAP_DECREMENT 0x200000000000 -#define MAX_LIB_COUNT 128 - -// STEP 1: - -/* here you need to specify the parameter for the target function */ -static void *(*o_function)(u8 *buf, int len); - -/* use stdin (1) or a file on the commandline (0) */ -static u32 use_stdin = 1; - -/* This is were the testcase data is written into */ -static u8 buf[10000]; // this is the maximum size for a test case! set it! - -/* If you want to have debug output set this to 1, can also be set with - AFL_DEBUG */ -static u32 debug = 0; - -// END STEP 1 - -typedef struct library_list { - - u8 *name; - u64 addr_start, addr_end; - -} library_list_t; - -#ifdef __ANDROID__ -u32 __afl_map_size = MAP_SIZE; -u32 do_exit; -#else -__thread u32 __afl_map_size = MAP_SIZE; -__thread u32 do_exit; -#endif - -static pid_t pid = 65537; -static pthread_t __afl_thread; -static u8 __afl_dummy[MAP_SIZE]; -static u8 * __afl_area_ptr = __afl_dummy; -static u8 * inputfile; // this will point to argv[1] -static u32 len; - -static library_list_t liblist[MAX_LIB_COUNT]; -static u32 liblist_cnt; - -static void sigtrap_handler(int signum, siginfo_t *si, void *context); -static void fuzz(void); - -/* read the library information */ -void read_library_information(void) { - -#if defined(__linux__) - FILE *f; - u8 buf[1024], *b, *m, *e, *n; - - if ((f = fopen("/proc/self/maps", "r")) == NULL) - FATAL("cannot open /proc/self/maps"); - - if (debug) fprintf(stderr, "Library list:\n"); - while (fgets(buf, sizeof(buf), f)) { - - if (strstr(buf, " r-x")) { - - if (liblist_cnt >= MAX_LIB_COUNT) { - - WARNF("too many libraries to old, maximum count of %d reached", - liblist_cnt); - return; - - } - - b = buf; - m = index(buf, '-'); - e = index(buf, ' '); - if ((n = rindex(buf, '/')) == NULL) n = rindex(buf, ' '); - if (n && - ((*n >= '0' && *n <= '9') || *n == '[' || *n == '{' || *n == '(')) - n = NULL; - else - n++; - if (b && m && e && n && *n) { - - *m++ = 0; - *e = 0; - if (n[strlen(n) - 1] == '\n') n[strlen(n) - 1] = 0; - - liblist[liblist_cnt].name = strdup(n); - liblist[liblist_cnt].addr_start = strtoull(b, NULL, 16); - liblist[liblist_cnt].addr_end = strtoull(m, NULL, 16); - if (debug) - fprintf( - stderr, "%s:%llx (%llx-%llx)\n", liblist[liblist_cnt].name, - liblist[liblist_cnt].addr_end - liblist[liblist_cnt].addr_start, - liblist[liblist_cnt].addr_start, - liblist[liblist_cnt].addr_end - 1); - liblist_cnt++; - - } - - } - - } - - if (debug) fprintf(stderr, "\n"); - -#elif defined(__FreeBSD__) - int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_VMMAP, getpid()}; - char * buf, *start, *end; - size_t miblen = sizeof(mib) / sizeof(mib[0]); - size_t len; - - if (debug) fprintf(stderr, "Library list:\n"); - if (sysctl(mib, miblen, NULL, &len, NULL, 0) == -1) { return; } - - len = len * 4 / 3; - - buf = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); - if (buf == MAP_FAILED) { return; } - - if (sysctl(mib, miblen, buf, &len, NULL, 0) == -1) { - - munmap(buf, len); - return; - - } - - start = buf; - end = buf + len; - - while (start < end) { - - struct kinfo_vmentry *region = (struct kinfo_vmentry *)start; - size_t size = region->kve_structsize; - - if (size == 0) { break; } - - if ((region->kve_protection & KVME_PROT_READ) && - !(region->kve_protection & KVME_PROT_EXEC)) { - - liblist[liblist_cnt].name = - region->kve_path[0] != '\0' ? strdup(region->kve_path) : 0; - liblist[liblist_cnt].addr_start = region->kve_start; - liblist[liblist_cnt].addr_end = region->kve_end; - - if (debug) { - - fprintf(stderr, "%s:%x (%lx-%lx)\n", liblist[liblist_cnt].name, - liblist[liblist_cnt].addr_end - liblist[liblist_cnt].addr_start, - liblist[liblist_cnt].addr_start, - liblist[liblist_cnt].addr_end - 1); - - } - - liblist_cnt++; - - } - - start += size; - - } - -#endif - -} - -library_list_t *find_library(char *name) { - -#if defined(__linux__) - u32 i; - - for (i = 0; i < liblist_cnt; i++) - if (strncmp(liblist[i].name, name, strlen(name)) == 0) return &liblist[i]; -#elif defined(__APPLE__) && defined(__LP64__) - kern_return_t err; - static library_list_t lib; - - // get the list of all loaded modules from dyld - // the task_info mach API will get the address of the dyld all_image_info - // struct for the given task from which we can get the names and load - // addresses of all modules - task_dyld_info_data_t task_dyld_info; - mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT; - err = task_info(mach_task_self(), TASK_DYLD_INFO, - (task_info_t)&task_dyld_info, &count); - - const struct dyld_all_image_infos *all_image_infos = - (const struct dyld_all_image_infos *)task_dyld_info.all_image_info_addr; - const struct dyld_image_info *image_infos = all_image_infos->infoArray; - - for (size_t i = 0; i < all_image_infos->infoArrayCount; i++) { - - const char * image_name = image_infos[i].imageFilePath; - mach_vm_address_t image_load_address = - (mach_vm_address_t)image_infos[i].imageLoadAddress; - if (strstr(image_name, name)) { - - lib.name = name; - lib.addr_start = (u64)image_load_address; - lib.addr_end = 0; - return &lib; - - } - - } - -#endif - - return NULL; - -} - -/* for having an easy breakpoint location after loading the shared library */ -// this seems to work for clang too. nice :) requires gcc 4.4+ -#pragma GCC push_options -#pragma GCC optimize("O0") -void breakpoint(void) { - - if (debug) fprintf(stderr, "Breakpoint function \"breakpoint\" reached.\n"); - -} - -#pragma GCC pop_options - -/* Error reporting to forkserver controller */ - -void send_forkserver_error(int error) { - - u32 status; - if (!error || error > 0xffff) return; - status = (FS_OPT_ERROR | FS_OPT_SET_ERROR(error)); - if (write(FORKSRV_FD + 1, (char *)&status, 4) != 4) return; - -} - -/* SHM setup. */ - -static void __afl_map_shm(void) { - - char *id_str = getenv(SHM_ENV_VAR); - char *ptr; - - if ((ptr = getenv("AFL_MAP_SIZE")) != NULL) { - - u32 val = atoi(ptr); - if (val > 0) __afl_map_size = val; - - } - - if (__afl_map_size > MAP_SIZE) { - - if (__afl_map_size > FS_OPT_MAX_MAPSIZE) { - - fprintf(stderr, - "Error: AFL++ tools *require* to set AFL_MAP_SIZE to %u to " - "be able to run this instrumented program!\n", - __afl_map_size); - if (id_str) { - - send_forkserver_error(FS_ERROR_MAP_SIZE); - exit(-1); - - } - - } else { - - fprintf(stderr, - "Warning: AFL++ tools will need to set AFL_MAP_SIZE to %u to " - "be able to run this instrumented program!\n", - __afl_map_size); - - } - - } - - if (id_str) { - -#ifdef USEMMAP - const char * shm_file_path = id_str; - int shm_fd = -1; - unsigned char *shm_base = NULL; - - /* create the shared memory segment as if it was a file */ - shm_fd = shm_open(shm_file_path, O_RDWR, 0600); - if (shm_fd == -1) { - - fprintf(stderr, "shm_open() failed\n"); - send_forkserver_error(FS_ERROR_SHM_OPEN); - exit(1); - - } - - /* map the shared memory segment to the address space of the process */ - shm_base = - mmap(0, __afl_map_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - - if (shm_base == MAP_FAILED) { - - close(shm_fd); - shm_fd = -1; - - fprintf(stderr, "mmap() failed\n"); - send_forkserver_error(FS_ERROR_MMAP); - exit(2); - - } - - __afl_area_ptr = shm_base; -#else - u32 shm_id = atoi(id_str); - - __afl_area_ptr = shmat(shm_id, 0, 0); - -#endif - - if (__afl_area_ptr == (void *)-1) { - - send_forkserver_error(FS_ERROR_SHMAT); - exit(1); - - } - - /* Write something into the bitmap so that the parent doesn't give up */ - - __afl_area_ptr[0] = 1; - - } - -} - -/* Fork server logic. */ -inline static void __afl_start_forkserver(void) { - - u8 tmp[4] = {0, 0, 0, 0}; - u32 status = 0; - - if (__afl_map_size <= FS_OPT_MAX_MAPSIZE) - status |= (FS_OPT_SET_MAPSIZE(__afl_map_size) | FS_OPT_MAPSIZE); - if (status) status |= (FS_OPT_ENABLED); - memcpy(tmp, &status, 4); - - /* Phone home and tell the parent that we're OK. */ - if (write(FORKSRV_FD + 1, tmp, 4) != 4) do_exit = 1; - // fprintf(stderr, "write0 %d\n", do_exit); - -} - -inline static u32 __afl_next_testcase(u8 *buf, u32 max_len) { - - s32 status; - - /* Wait for parent by reading from the pipe. Abort if read fails. */ - if (read(FORKSRV_FD, &status, 4) != 4) do_exit = 1; - // fprintf(stderr, "read %d\n", do_exit); - - /* we have a testcase - read it if we read from stdin */ - if (use_stdin) { - - if ((status = read(0, buf, max_len)) <= 0) exit(-1); - - } else - - status = 1; - // fprintf(stderr, "stdin: %d %d\n", use_stdin, status); - - /* report that we are starting the target */ - if (write(FORKSRV_FD + 1, &pid, 4) != 4) do_exit = 1; - // fprintf(stderr, "write1 %d\n", do_exit); - - __afl_area_ptr[0] = 1; // put something in the map - - return status; - -} - -inline static void __afl_end_testcase(int status) { - - if (write(FORKSRV_FD + 1, &status, 4) != 4) do_exit = 1; - // fprintf(stderr, "write2 %d\n", do_exit); - if (do_exit) exit(0); - -} - -#ifdef __aarch64__ - #define SHADOW(addr) \ - ((uint64_t *)(((uintptr_t)addr & 0xfffffffffffffff8) - \ - MEMORY_MAP_DECREMENT - \ - ((uintptr_t)addr & 0x7) * 0x10000000000)) -#else - #define SHADOW(addr) \ - ((uint32_t *)(((uintptr_t)addr & 0xfffffffffffffffc) - \ - MEMORY_MAP_DECREMENT - \ - ((uintptr_t)addr & 0x3) * 0x10000000000)) -#endif - -void setup_trap_instrumentation(void) { - - library_list_t *lib_base = NULL; - size_t lib_size = 0; - u8 * lib_addr; - char * line = NULL; - size_t nread, len = 0; - char * filename = getenv("AFL_UNTRACER_FILE"); - if (!filename) filename = getenv("TRAPFUZZ_FILE"); - if (!filename) FATAL("AFL_UNTRACER_FILE environment variable not set"); - - FILE *patches = fopen(filename, "r"); - if (!patches) FATAL("Couldn't open AFL_UNTRACER_FILE file %s", filename); - - // Index into the coverage bitmap for the current trap instruction. -#ifdef __aarch64__ - uint64_t bitmap_index = 0; -#else - uint32_t bitmap_index = 0; -#endif - - while ((nread = getline(&line, &len, patches)) != -1) { - - char *end = line + len; - - char *col = strchr(line, ':'); - if (col) { - - // It's a library:size pair - *col++ = 0; - - lib_base = find_library(line); - if (!lib_base) FATAL("Library %s does not appear to be loaded", line); - - // we ignore the defined lib_size - lib_size = strtoul(col, NULL, 16); -#if (__linux__) - if (lib_size < lib_base->addr_end - lib_base->addr_start) - lib_size = lib_base->addr_end - lib_base->addr_start; -#endif - if (lib_size % 0x1000 != 0) - WARNF("Invalid library size 0x%zx. Must be multiple of 0x1000", - lib_size); - - lib_addr = (u8 *)lib_base->addr_start; - - // Make library code writable. - if (mprotect((void *)lib_addr, lib_size, - PROT_READ | PROT_WRITE | PROT_EXEC) != 0) - FATAL("Failed to mprotect library %s writable", line); - - // Create shadow memory. -#ifdef __aarch64__ - for (int i = 0; i < 8; i++) { - -#else - for (int i = 0; i < 4; i++) { - -#endif - - void *shadow_addr = SHADOW(lib_addr + i); - void *shadow = mmap(shadow_addr, lib_size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON | MAP_FIXED, 0, 0); - if (debug) - fprintf(stderr, "Shadow: %s %d = %p-%p for %p\n", line, i, shadow, - shadow + lib_size - 1, lib_addr); - if (shadow == MAP_FAILED) FATAL("Failed to mmap shadow memory"); - - } - - // Done, continue with next line. - continue; - - } - - // It's an offset, parse it and do the patching. - unsigned long offset = strtoul(line, NULL, 16); - - if (offset > lib_size) - FATAL("Invalid offset: 0x%lx. Current library is 0x%zx bytes large", - offset, lib_size); - - if (bitmap_index >= __afl_map_size) - FATAL("Too many basic blocks to instrument"); - -#ifdef __arch64__ - uint64_t -#else - uint32_t -#endif - *shadow = SHADOW(lib_addr + offset); - if (*shadow != 0) continue; // skip duplicates - - // Make lookup entry in shadow memory. - -#if ((defined(__APPLE__) && defined(__LP64__)) || defined(__x86_64__) || \ - defined(__i386__)) - - // this is for Intel x64 - - uint8_t orig_byte = lib_addr[offset]; - *shadow = (bitmap_index << 8) | orig_byte; - lib_addr[offset] = 0xcc; // replace instruction with debug trap - if (debug) - fprintf(stderr, - "Patch entry: %p[%x] = %p = %02x -> SHADOW(%p) #%d -> %08x\n", - lib_addr, offset, lib_addr + offset, orig_byte, shadow, - bitmap_index, *shadow); - -#elif defined(__aarch64__) - - // this is for aarch64 - - uint32_t *patch_bytes = (uint32_t *)(lib_addr + offset); - uint32_t orig_bytes = *patch_bytes; - *shadow = (bitmap_index << 32) | orig_bytes; - *patch_bytes = 0xd4200000; // replace instruction with debug trap - if (debug) - fprintf(stderr, - "Patch entry: %p[%x] = %p = %02x -> SHADOW(%p) #%d -> %016x\n", - lib_addr, offset, lib_addr + offset, orig_bytes, shadow, - bitmap_index, *shadow); - -#else - // this will be ARM and AARCH64 - // for ARM we will need to identify if the code is in thumb or ARM - #error "non x86_64/aarch64 not supported yet" - //__arm__: - // linux thumb: 0xde01 - // linux arm: 0xe7f001f0 - //__aarch64__: - // linux aarch64: 0xd4200000 -#endif - - bitmap_index++; - - } - - free(line); - fclose(patches); - - // Install signal handler for SIGTRAP. - struct sigaction s; - s.sa_flags = SA_SIGINFO; - s.sa_sigaction = sigtrap_handler; - sigemptyset(&s.sa_mask); - sigaction(SIGTRAP, &s, 0); - - if (debug) fprintf(stderr, "Patched %u locations.\n", bitmap_index); - __afl_map_size = bitmap_index; - if (__afl_map_size % 8) __afl_map_size = (((__afl_map_size + 7) >> 3) << 3); - -} - -/* the signal handler for the traps / debugging interrupts - No debug output here because this would cost speed */ -static void sigtrap_handler(int signum, siginfo_t *si, void *context) { - - uint64_t addr; - // Must re-execute the instruction, so decrement PC by one instruction. - ucontext_t *ctx = (ucontext_t *)context; -#if defined(__APPLE__) && defined(__LP64__) - ctx->uc_mcontext->__ss.__rip -= 1; - addr = ctx->uc_mcontext->__ss.__rip; -#elif defined(__linux__) - #if defined(__x86_64__) || defined(__i386__) - ctx->uc_mcontext.gregs[REG_RIP] -= 1; - addr = ctx->uc_mcontext.gregs[REG_RIP]; - #elif defined(__aarch64__) - ctx->uc_mcontext.pc -= 4; - addr = ctx->uc_mcontext.pc; - #else - #error "Unsupported processor" - #endif -#elif defined(__FreeBSD__) && defined(__LP64__) - ctx->uc_mcontext.mc_rip -= 1; - addr = ctx->uc_mcontext.mc_rip; -#else - #error "Unsupported platform" -#endif - - // fprintf(stderr, "TRAP at context addr = %lx, fault addr = %lx\n", addr, - // si->si_addr); - - // If the trap didn't come from our instrumentation, then we probably will - // just segfault here - uint8_t *faultaddr; - if (unlikely(si->si_addr)) - faultaddr = (u8 *)si->si_addr - 1; - else - faultaddr = (u8 *)addr; - // if (debug) fprintf(stderr, "Shadow location: %p\n", SHADOW(faultaddr)); - uint32_t shadow = *SHADOW(faultaddr); - uint8_t orig_byte = shadow & 0xff; - uint32_t index = shadow >> 8; - - // if (debug) fprintf(stderr, "shadow data: %x, orig_byte %02x, index %d\n", - // shadow, orig_byte, index); - - // Index zero is invalid so that it is still possible to catch actual trap - // instructions in instrumented libraries. - if (unlikely(index == 0)) abort(); - - // Restore original instruction - *faultaddr = orig_byte; - - __afl_area_ptr[index] = 128; - -} - -/* the MAIN function */ -int main(int argc, char *argv[]) { - - (void)personality(ADDR_NO_RANDOMIZE); // disable ASLR - - pid = getpid(); - if (getenv("AFL_DEBUG")) debug = 1; - - /* by default we use stdin, but also a filename can be passed, in this - case the input is argv[1] and we have to disable stdin */ - if (argc > 1) { - - use_stdin = 0; - inputfile = argv[1]; - - } - - // STEP 2: load the library you want to fuzz and lookup the functions, - // inclusive of the cleanup functions - // NOTE: above the main() you have to define the functions! - - void *dl = dlopen("./libtestinstr.so", RTLD_LAZY); - if (!dl) FATAL("could not find target library"); - o_function = dlsym(dl, "testinstr"); - if (!o_function) FATAL("could not resolve target function from library"); - if (debug) fprintf(stderr, "Function address: %p\n", o_function); - - // END STEP 2 - - /* setup instrumentation, shared memory and forkserver */ - breakpoint(); - read_library_information(); - setup_trap_instrumentation(); - __afl_map_shm(); - __afl_start_forkserver(); - - while (1) { - - // instead of fork() we could also use the snapshot lkm or do our own mini - // snapshot feature like in https://github.com/marcinguy/fuzzer - // -> snapshot.c - if ((pid = fork()) == -1) PFATAL("fork failed"); - - if (pid) { - - u32 status; - if (waitpid(pid, &status, 0) < 0) exit(1); - /* report the test case is done and wait for the next */ - __afl_end_testcase(status); - - } else { - - pid = getpid(); - while ((len = __afl_next_testcase(buf, sizeof(buf))) > 0) { - - // in this function the fuzz magic happens, this is STEP 3 - fuzz(); - - // we can use _exit which is faster because our target library - // was loaded via dlopen and therefore cannot have deconstructors - // registered. - _exit(0); - - } - - } - - } - - return 0; - -} - -#ifndef _DEBUG -inline -#endif - static void - fuzz(void) { - - // STEP 3: call the function to fuzz, also the functions you might - // need to call to prepare the function and - important! - - // to clean everything up - - // in this example we use the input file, not stdin! - (*o_function)(buf, len); - - // normally you also need to cleanup - //(*o_LibFree)(foo); - - // END STEP 3 - -} - diff --git a/examples/afl_untracer/ghidra_get_patchpoints.java b/examples/afl_untracer/ghidra_get_patchpoints.java deleted file mode 100644 index d341bea4..00000000 --- a/examples/afl_untracer/ghidra_get_patchpoints.java +++ /dev/null @@ -1,84 +0,0 @@ -/* ### - * IP: GHIDRA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// Find patch points for untracer tools (e.g. afl++ examples/afl_untracer) -// -// Copy to ..../Ghidra/Features/Search/ghidra_scripts/ -// Writes the results to ~/Desktop/patches.txt -// -// This is my very first Ghidra script. I am sure this could be done better. -// -//@category Search - -import ghidra.app.script.GhidraScript; -import ghidra.program.model.address.*; -import ghidra.program.model.block.*; -import ghidra.program.model.listing.*; -import ghidra.program.model.symbol.*; -import ghidra.program.model.mem.*; - -import java.io.*; - -public class ghidra_get_patchpoints extends GhidraScript { - - @Override - public void run() throws Exception { - - long segment_start = 0; - Memory memory = currentProgram.getMemory(); - MultEntSubModel model = new MultEntSubModel(currentProgram); - CodeBlockIterator subIter = model.getCodeBlocks(monitor); - BufferedWriter out = new BufferedWriter(new FileWriter(System.getProperty("user.home") + File.separator + "Desktop" + File.separator + "patches.txt")); - - while (subIter.hasNext()) { - - CodeBlock multiEntryBlock = subIter.next(); - SimpleBlockModel basicBlockModel = new SimpleBlockModel(currentProgram); - CodeBlockIterator bbIter = basicBlockModel.getCodeBlocksContaining(multiEntryBlock, monitor); - - while (bbIter.hasNext()) { - - CodeBlock basicBlock = bbIter.next(); - - if (segment_start == 0) { - - Address firstAddr = basicBlock.getFirstStartAddress(); - long firstBlockAddr = firstAddr.getAddressableWordOffset(); - MemoryBlock mb = memory.getBlock(firstAddr); - Address startAddr = mb.getStart(); - Address endAddr = mb.getEnd(); - segment_start = startAddr.getAddressableWordOffset(); - if ((firstBlockAddr - segment_start) >= 0x1000) - segment_start += 0x1000; - long segment_end = endAddr.getAddressableWordOffset(); - long segment_size = segment_end - segment_start; - if ((segment_size % 0x1000) > 0) - segment_size = (((segment_size / 0x1000) + 1) * 0x1000); - out.write(currentProgram.getName() + ":0x" + Long.toHexString(segment_size) + "\n"); - //println("Start: " + Long.toHexString(segment_start)); - //println("End: " + Long.toHexString(segment_end)); - - } - - if (basicBlock.getFirstStartAddress().getAddressableWordOffset() - segment_start > 0) - out.write("0x" + Long.toHexString(basicBlock.getFirstStartAddress().getAddressableWordOffset() - segment_start) + "\n"); - - } - } - - out.close(); - - } -} diff --git a/examples/afl_untracer/ida_get_patchpoints.py b/examples/afl_untracer/ida_get_patchpoints.py deleted file mode 100644 index 43cf6d89..00000000 --- a/examples/afl_untracer/ida_get_patchpoints.py +++ /dev/null @@ -1,62 +0,0 @@ -# -# IDAPython script for IDA Pro -# Slightly modified from https://github.com/googleprojectzero/p0tools/blob/master/TrapFuzz/findPatchPoints.py -# - -import idautils -import idaapi -import ida_nalt -import idc - -# See https://www.hex-rays.com/products/ida/support/ida74_idapython_no_bc695_porting_guide.shtml - -from os.path import expanduser -home = expanduser("~") - -patchpoints = set() - -max_offset = 0 -for seg_ea in idautils.Segments(): - name = idc.get_segm_name(seg_ea) - #print("Segment: " + name) - if name != "__text" and name != ".text": - continue - - start = idc.get_segm_start(seg_ea) - end = idc.get_segm_end(seg_ea) - first = 0 - subtract_addr = 0 - #print("Start: " + hex(start) + " End: " + hex(end)) - for func_ea in idautils.Functions(start, end): - f = idaapi.get_func(func_ea) - if not f: - continue - for block in idaapi.FlowChart(f): - if start <= block.start_ea < end: - if first == 0: - if block.start_ea >= 0x1000: - subtract_addr = 0x1000 - first = 1 - - max_offset = max(max_offset, block.start_ea) - patchpoints.add(block.start_ea - subtract_addr) - #else: - # print("Warning: broken CFG?") - -# Round up max_offset to page size -size = max_offset -rem = size % 0x1000 -if rem != 0: - size += 0x1000 - rem - -print("Writing to " + home + "/Desktop/patches.txt") - -with open(home + "/Desktop/patches.txt", "w") as f: - f.write(ida_nalt.get_root_filename() + ':' + hex(size) + '\n') - f.write('\n'.join(map(hex, sorted(patchpoints)))) - f.write('\n') - -print("Done, found {} patchpoints".format(len(patchpoints))) - -# For headless script running remove the comment from the next line -#ida_pro.qexit() diff --git a/examples/afl_untracer/libtestinstr.c b/examples/afl_untracer/libtestinstr.c deleted file mode 100644 index 96b1cf21..00000000 --- a/examples/afl_untracer/libtestinstr.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - american fuzzy lop++ - a trivial program to test the build - -------------------------------------------------------- - Originally written by Michal Zalewski - Copyright 2014 Google Inc. All rights reserved. - Copyright 2019-2020 AFLplusplus Project. All rights reserved. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at: - http://www.apache.org/licenses/LICENSE-2.0 - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - -void testinstr(char *buf, int len) { - - if (len < 1) return; - buf[len] = 0; - - // we support three input cases - if (buf[0] == '0') - printf("Looks like a zero to me!\n"); - else if (buf[0] == '1') - printf("Pretty sure that is a one!\n"); - else - printf("Neither one or zero? How quaint!\n"); - -} - diff --git a/examples/afl_untracer/libtestinstr.so b/examples/afl_untracer/libtestinstr.so deleted file mode 100755 index 389a946c..00000000 --- a/examples/afl_untracer/libtestinstr.so +++ /dev/null Binary files differdiff --git a/examples/afl_untracer/patches.txt b/examples/afl_untracer/patches.txt deleted file mode 100644 index 7e964249..00000000 --- a/examples/afl_untracer/patches.txt +++ /dev/null @@ -1,34 +0,0 @@ -libtestinstr.so:0x1000 -0x10 -0x12 -0x20 -0x36 -0x30 -0x40 -0x50 -0x63 -0x6f -0x78 -0x80 -0xa4 -0xb0 -0xb8 -0x100 -0xc0 -0xc9 -0xd7 -0xe3 -0xe8 -0xf8 -0x105 -0x11a -0x135 -0x141 -0x143 -0x14e -0x15a -0x15c -0x168 -0x16a -0x16b -0x170 diff --git a/examples/aflpp_driver/GNUmakefile b/examples/aflpp_driver/GNUmakefile deleted file mode 100644 index c1a087d7..00000000 --- a/examples/aflpp_driver/GNUmakefile +++ /dev/null @@ -1,46 +0,0 @@ -ifeq "" "$(LLVM_CONFIG)" - LLVM_CONFIG=llvm-config -endif - -LLVM_BINDIR = $(shell $(LLVM_CONFIG) --bindir 2>/dev/null) -ifneq "" "$(LLVM_BINDIR)" - LLVM_BINDIR := $(LLVM_BINDIR)/ -endif - -CFLAGS := -O3 -funroll-loops -g - -all: libAFLDriver.a libAFLQemuDriver.a aflpp_qemu_driver_hook.so - -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 - cp -vf libAFLDriver.a ../../ - -debug: - $(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 $(CFLAGS) -O0 -funroll-loops -c aflpp_qemu_driver.c - -libAFLQemuDriver.a: aflpp_qemu_driver.o - ar ru libAFLQemuDriver.a aflpp_qemu_driver.o - cp -vf libAFLQemuDriver.a ../../ - -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 $(CFLAGS) -funroll-loops -c aflpp_qemu_driver_hook.c - -test: debug - #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/Makefile b/examples/aflpp_driver/Makefile deleted file mode 100644 index 3666a74d..00000000 --- a/examples/aflpp_driver/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - @gmake all || echo please install GNUmake diff --git a/examples/aflpp_driver/aflpp_driver.c b/examples/aflpp_driver/aflpp_driver.c deleted file mode 100644 index 017aa72b..00000000 --- a/examples/aflpp_driver/aflpp_driver.c +++ /dev/null @@ -1,326 +0,0 @@ -//===- afl_driver.cpp - a glue between AFL and libFuzzer --------*- C++ -* ===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -//===----------------------------------------------------------------------===// - -/* This file allows to fuzz libFuzzer-style target functions - (LLVMFuzzerTestOneInput) with AFL using AFL's persistent (in-process) mode. - -Usage: -################################################################################ -cat << EOF > test_fuzzer.cc -#include <stddef.h> -#include <stdint.h> -extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - - if (size > 0 && data[0] == 'H') - if (size > 1 && data[1] == 'I') - if (size > 2 && data[2] == '!') - __builtin_trap(); - return 0; - -} - -EOF -# Build your target with -fsanitize-coverage=trace-pc-guard using fresh clang. -clang -g -fsanitize-coverage=trace-pc-guard test_fuzzer.cc -c -# Build afl-llvm-rt.o.c from the AFL distribution. -clang -c -w $AFL_HOME/instrumentation/afl-llvm-rt.o.c -# Build this file, link it with afl-llvm-rt.o.o and the target code. -clang++ afl_driver.cpp test_fuzzer.o afl-llvm-rt.o.o -# Run AFL: -rm -rf IN OUT; mkdir IN OUT; echo z > IN/z; -$AFL_HOME/afl-fuzz -i IN -o OUT ./a.out -################################################################################ -AFL_DRIVER_STDERR_DUPLICATE_FILENAME: Setting this *appends* stderr to the file -specified. If the file does not exist, it is created. This is useful for getting -stack traces (when using ASAN for example) or original error messages on hard -to reproduce bugs. Note that any content written to stderr will be written to -this file instead of stderr's usual location. - -AFL_DRIVER_CLOSE_FD_MASK: Similar to libFuzzer's -close_fd_mask behavior option. -If 1, close stdout at startup. If 2 close stderr; if 3 close both. - -*/ -#include <assert.h> -#include <errno.h> -#include <stdarg.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <limits.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <sys/mman.h> - -#include "config.h" -#include "cmplog.h" - -#ifdef _DEBUG - #include "hash.h" -#endif - -#ifndef MAP_FIXED_NOREPLACE - #define MAP_FIXED_NOREPLACE 0x100000 -#endif - -#define MAX_DUMMY_SIZE 256000 - -// Platform detection. Copied from FuzzerInternal.h -#ifdef __linux__ - #define LIBFUZZER_LINUX 1 - #define LIBFUZZER_APPLE 0 - #define LIBFUZZER_NETBSD 0 - #define LIBFUZZER_FREEBSD 0 - #define LIBFUZZER_OPENBSD 0 -#elif __APPLE__ - #define LIBFUZZER_LINUX 0 - #define LIBFUZZER_APPLE 1 - #define LIBFUZZER_NETBSD 0 - #define LIBFUZZER_FREEBSD 0 - #define LIBFUZZER_OPENBSD 0 -#elif __NetBSD__ - #define LIBFUZZER_LINUX 0 - #define LIBFUZZER_APPLE 0 - #define LIBFUZZER_NETBSD 1 - #define LIBFUZZER_FREEBSD 0 - #define LIBFUZZER_OPENBSD 0 -#elif __FreeBSD__ - #define LIBFUZZER_LINUX 0 - #define LIBFUZZER_APPLE 0 - #define LIBFUZZER_NETBSD 0 - #define LIBFUZZER_FREEBSD 1 - #define LIBFUZZER_OPENBSD 0 -#elif __OpenBSD__ - #define LIBFUZZER_LINUX 0 - #define LIBFUZZER_APPLE 0 - #define LIBFUZZER_NETBSD 0 - #define LIBFUZZER_FREEBSD 0 - #define LIBFUZZER_OPENBSD 1 -#else - #error "Support for your platform has not been implemented" -#endif - -int __afl_sharedmem_fuzzing = 1; -extern unsigned int * __afl_fuzz_len; -extern unsigned char *__afl_fuzz_ptr; - -// libFuzzer interface is thin, so we don't include any libFuzzer headers. -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##"; -int __afl_persistent_loop(unsigned int); - -// Notify AFL about deferred forkserver. -static volatile char AFL_DEFER_FORKSVR[] = "##SIG_AFL_DEFER_FORKSRV##"; -void __afl_manual_init(); - -// Use this optionally defined function to output sanitizer messages even if -// user asks to close stderr. -__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; - -// Experimental feature to use afl_driver without AFL's deferred mode. -// Needs to run before __afl_auto_init. -__attribute__((constructor(0))) static void __decide_deferred_forkserver(void) { - - if (getenv("AFL_DRIVER_DONT_DEFER")) { - - if (unsetenv("__AFL_DEFER_FORKSRV")) { - - perror("Failed to unset __AFL_DEFER_FORKSRV"); - abort(); - - } - - } - -} - -// If the user asks us to duplicate stderr, then do it. -static void maybe_duplicate_stderr() { - - char *stderr_duplicate_filename = - getenv("AFL_DRIVER_STDERR_DUPLICATE_FILENAME"); - - if (!stderr_duplicate_filename) return; - - FILE *stderr_duplicate_stream = - freopen(stderr_duplicate_filename, "a+", stderr); - - if (!stderr_duplicate_stream) { - - fprintf( - stderr, - "Failed to duplicate stderr to AFL_DRIVER_STDERR_DUPLICATE_FILENAME"); - abort(); - - } - - output_file = stderr_duplicate_stream; - -} - -// Most of these I/O functions were inspired by/copied from libFuzzer's code. -static void discard_output(int fd) { - - FILE *temp = fopen("/dev/null", "w"); - if (!temp) abort(); - dup2(fileno(temp), fd); - fclose(temp); - -} - -static void close_stdout() { - - discard_output(STDOUT_FILENO); - -} - -// Prevent the targeted code from writing to "stderr" but allow sanitizers and -// this driver to do so. -static void dup_and_close_stderr() { - - int output_fileno = fileno(output_file); - int output_fd = dup(output_fileno); - if (output_fd <= 0) abort(); - FILE *new_output_file = fdopen(output_fd, "w"); - if (!new_output_file) abort(); - if (!__sanitizer_set_report_fd) return; - __sanitizer_set_report_fd((void *)(long int)output_fd); - discard_output(output_fileno); - -} - -// 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"); - if (!fd_mask_str) return; - int fd_mask = atoi(fd_mask_str); - if (fd_mask & 2) dup_and_close_stderr(); - if (fd_mask & 1) close_stdout(); - -} - -// Define LLVMFuzzerMutate to avoid link failures for targets that use it -// with libFuzzer's LLVMFuzzerCustomMutator. -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++) { - - 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( - "======================= INFO =========================\n" - "This binary is built for afl++.\n" - "To run the target function on individual input(s) execute this:\n" - " %s INPUT_FILE1 [INPUT_FILE2 ... ]\n" - "To fuzz with afl-fuzz execute this:\n" - " afl-fuzz [afl-flags] -- %s [-N]\n" - "afl-fuzz will run N iterations before re-spawning the process (default: " - "1000)\n" - "======================================================\n", - argv[0], argv[0]); - - output_file = stderr; - maybe_duplicate_stderr(); - maybe_close_fd_mask(); - if (LLVMFuzzerInitialize) { - - fprintf(stderr, "Running LLVMFuzzerInitialize ...\n"); - LLVMFuzzerInitialize(&argc, &argv); - fprintf(stderr, "continue...\n"); - - } - - // Do any other expensive one-time initialization here. - - 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); - else if (argc > 1) { - - __afl_sharedmem_fuzzing = 0; - __afl_manual_init(); - return ExecuteFilesOnyByOne(argc, argv); - - } - - assert(N > 0); - - // if (!getenv("AFL_DRIVER_DONT_DEFER")) - __afl_manual_init(); - - // Call LLVMFuzzerTestOneInput here so that coverage caused by initialization - // on the first execution of LLVMFuzzerTestOneInput is ignored. - LLVMFuzzerTestOneInput(dummy_input, 1); - - int num_runs = 0; - while (__afl_persistent_loop(N)) { - -#ifdef _DEBUG - fprintf(stderr, "CLIENT crc: %016llx len: %u\n", - hash64(__afl_fuzz_ptr, *__afl_fuzz_len, 0xa5b35705), - *__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"); -#endif - if (*__afl_fuzz_len) { - - num_runs++; - LLVMFuzzerTestOneInput(__afl_fuzz_ptr, *__afl_fuzz_len); - - } - - } - - printf("%s: successfully executed %d input(s)\n", argv[0], num_runs); - -} - diff --git a/examples/aflpp_driver/aflpp_driver_test.c b/examples/aflpp_driver/aflpp_driver_test.c deleted file mode 100644 index b4ff6bc6..00000000 --- a/examples/aflpp_driver/aflpp_driver_test.c +++ /dev/null @@ -1,32 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> - -#include "hash.h" - -void __attribute__((noinline)) crashme(const uint8_t *Data, size_t Size) { - - if (Size < 5) return; - - if (Data[0] == 'F') - if (Data[1] == 'A') - if (Data[2] == '$') - if (Data[3] == '$') - if (Data[4] == '$') abort(); - -} - -int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { - - if (Size) - fprintf(stderr, "FUNC crc: %016llx len: %lu\n", - hash64((u8 *)Data, (unsigned int)Size, - (unsigned long long int)0xa5b35705), - Size); - - crashme(Data, Size); - - return 0; - -} - diff --git a/examples/aflpp_driver/aflpp_qemu_driver.c b/examples/aflpp_driver/aflpp_qemu_driver.c deleted file mode 100644 index 4f3e5f71..00000000 --- a/examples/aflpp_driver/aflpp_qemu_driver.c +++ /dev/null @@ -1,38 +0,0 @@ -#include <stdint.h> -#include <stdlib.h> -#include <unistd.h> - -// libFuzzer interface is thin, so we don't include any libFuzzer headers. -int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size); -__attribute__((weak)) int LLVMFuzzerInitialize(int *argc, char ***argv); - -static const size_t kMaxAflInputSize = 1 * 1024 * 1024; -static uint8_t AflInputBuf[kMaxAflInputSize]; - -void __attribute__((noinline)) afl_qemu_driver_stdin_input(void) { - - size_t l = read(0, AflInputBuf, kMaxAflInputSize); - LLVMFuzzerTestOneInput(AflInputBuf, l); - -} - -int main(int argc, char **argv) { - - if (LLVMFuzzerInitialize) LLVMFuzzerInitialize(&argc, &argv); - // Do any other expensive one-time initialization here. - - if (getenv("AFL_QEMU_DRIVER_NO_HOOK")) { - - afl_qemu_driver_stdin_input(); - - } else { - - uint8_t dummy_input[1024000] = {0}; - LLVMFuzzerTestOneInput(dummy_input, 1); - - } - - return 0; - -} - diff --git a/examples/aflpp_driver/aflpp_qemu_driver_hook.c b/examples/aflpp_driver/aflpp_qemu_driver_hook.c deleted file mode 100644 index 823cc42d..00000000 --- a/examples/aflpp_driver/aflpp_qemu_driver_hook.c +++ /dev/null @@ -1,22 +0,0 @@ -#include <stdint.h> -#include <string.h> - -#define g2h(x) ((void *)((unsigned long)(x) + guest_base)) - -#define REGS_RDI 7 -#define REGS_RSI 6 - -void afl_persistent_hook(uint64_t *regs, uint64_t guest_base, - uint8_t *input_buf, uint32_t input_len) { - - memcpy(g2h(regs[REGS_RDI]), input_buf, input_len); - regs[REGS_RSI] = input_len; - -} - -int afl_persistent_hook_init(void) { - - return 1; - -} - diff --git a/examples/analysis_scripts/queue2csv.sh b/examples/analysis_scripts/queue2csv.sh deleted file mode 100755 index 2528b438..00000000 --- a/examples/analysis_scripts/queue2csv.sh +++ /dev/null @@ -1,122 +0,0 @@ -#!/bin/bash - -test -z "$1" -o -z "$2" -o "$1" = "-h" -o "$1" = "-hh" -o "$1" = "--help" -o '!' -d "$1" && { - echo "Syntax: [-n] $0 out-directory file.csv [\"tools/target --opt @@\"]" - echo Option -n will suppress the CSV header. - echo If the target execution command is supplied then also edge coverage is gathered. - exit 1 -} - -function getval() { - VAL="" - if [ "$file" != "${file/$1/}" ]; then - TMP="${file/*$1:/}" - VAL="${TMP/,*/}" - fi -} - -SKIP= -if [ "$1" = "-n" ]; then - SKIP=1 - shift -fi - -test -n "$4" && { echo "Error: too many commandline options. Target command and options including @@ have to be passed within \"\"!"; exit 1; } - -test -d "$1"/queue && OUT="$1/queue" || OUT="$1" - -OK=`ls $OUT/id:000000,time:0,orig:* 2> /dev/null` -if [ -n "$OK" ]; then - LISTCMD="ls $OUT/id:"* -else - LISTCMD="ls -tr $OUT/" -fi - -ID=;SRC=;TIME=;OP=;POS=;REP=;EDGES=;EDGES_TOTAL=; -DIR="$OUT/../stats" -rm -rf "$DIR" -> "$2" || exit 1 -mkdir "$DIR" || exit 1 -> "$DIR/../edges.txt" || exit 1 - -{ - - if [ -z "$SKIP" ]; then - echo "time;\"filename\";id;src;new_cov;edges;total_edges;\"op\";pos;rep;unique_edges" - fi - - $LISTCMD | grep -v ,sync: | sed 's/.*id:/id:/g' | while read file; do - - if [ -n "$3" ]; then - - TMP=${3/@@/$OUT/$file} - - if [ "$TMP" = "$3" ]; then - - cat "$OUT/$file" | afl-showmap -o "$DIR/$file" -q -- $3 >/dev/null 2>&1 - - else - - afl-showmap -o "$DIR/$file" -q -- $TMP >/dev/null 2>&1 - - fi - - { cat "$DIR/$file" | sed 's/:.*//' ; cat "$DIR/../edges.txt" ; } | sort -nu > $DIR/../edges.txt.tmp - mv $DIR/../edges.txt.tmp $DIR/../edges.txt - EDGES=$(cat "$DIR/$file" | wc -l) - EDGES_TOTAL=$(cat "$DIR/../edges.txt" | wc -l) - - fi - - getval id; ID="$VAL" - getval src; SRC="$VAL" - getval time; TIME="$VAL" - getval op; OP="$VAL" - getval pos; POS="$VAL" - getval rep; REP="$VAL" - if [ "$file" != "${file/+cov/}" ]; then - COV=1 - else - COV="" - fi - - if [ -n "$3" -a -s "$DIR/../edges.txt" ]; then - echo "$TIME;\"$file\";$ID;$SRC;$COV;$EDGES;$EDGES_TOTAL;\"$OP\";$POS;$REP;UNIQUE$file" - else - echo "$TIME;\"$file\";$ID;$SRC;$COV;;;\"$OP\";$POS;$REP;" - fi - - done - -} | tee "$DIR/../queue.csv" > "$2" || exit 1 - -if [ -n "$3" -a -s "$DIR/../edges.txt" ]; then - - cat "$DIR/"* | sed 's/:.*//' | sort -n | uniq -c | egrep '^[ \t]*1 ' | awk '{print$2}' > $DIR/../unique.txt - - if [ -s "$DIR/../unique.txt" ]; then - - ls "$DIR/id:"* | grep -v ",sync:" |sed 's/.*\/id:/id:/g' | while read file; do - - CNT=$(sed 's/:.*//' "$DIR/$file" | tee "$DIR/../tmp.txt" | wc -l) - DIFF=$(diff -u "$DIR/../tmp.txt" "$DIR/../unique.txt" | egrep '^-[0-9]' | wc -l) - UNIQUE=$(($CNT - $DIFF)) - sed -i "s/;UNIQUE$file/;$UNIQUE/" "$DIR/../queue.csv" "$2" - - done - - rm -f "$DIR/../tmp.txt" - - else - - sed -i 's/;UNIQUE.*/;/' "$DIR/../queue.csv" "$2" - - fi - -fi - -mv "$DIR/../queue.csv" "$DIR/queue.csv" -if [ -e "$DIR/../edges.txt" ]; then mv "$DIR/../edges.txt" "$DIR/edges.txt"; fi -if [ -e "$DIR/../unique.txt" ]; then mv "$DIR/../unique.txt" "$DIR/unique.txt"; fi - -echo "Created $2" diff --git a/examples/argv_fuzzing/Makefile b/examples/argv_fuzzing/Makefile deleted file mode 100644 index 5a0ac6e6..00000000 --- a/examples/argv_fuzzing/Makefile +++ /dev/null @@ -1,58 +0,0 @@ -# -# american fuzzy lop++ - argvfuzz -# -------------------------------- -# -# Copyright 2019-2020 Kjell Braden <afflux@pentabarf.de> -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# - -.PHONY: all install clean - -PREFIX ?= /usr/local -BIN_PATH = $(PREFIX)/bin -HELPER_PATH = $(PREFIX)/lib/afl - -CFLAGS = -fPIC -Wall -Wextra -LDFLAGS = -shared - -UNAME_SAYS_LINUX=$(shell uname | grep -E '^Linux|^GNU' >/dev/null; echo $$?) -UNAME_SAYS_LINUX:sh=uname | grep -E '^Linux|^GNU' >/dev/null; echo $$? - -_LDFLAGS_ADD=$(UNAME_SAYS_LINUX:1=) -LDFLAGS_ADD=$(_LDFLAGS_ADD:0=-ldl) -LDFLAGS += $(LDFLAGS_ADD) - -# on gcc for arm there is no -m32, but -mbe32 -M32FLAG = -m32 -M64FLAG = -m64 - -CC_IS_GCC=$(shell $(CC) --version 2>/dev/null | grep -q gcc; echo $$?) -CC_IS_GCC:sh=$(CC) --version 2>/dev/null | grep -q gcc; echo $$? -CC_IS_ARMCOMPILER=$(shell $(CC) -v 2>&1 >/dev/null | grep -q arm; echo $$?) -CC_IS_ARMCOMPILER:sh=$(CC) -v 2>&1 >/dev/null | grep -q arm; echo $$? - -_M32FLAG=$(CC_IS_GCC)$(CC_IS_ARMCOMPILER) -__M32FLAG=$(_M32FLAG:00=-mbe32) -___M32FLAG=$(__M32FLAG:$(CC_IS_GCC)$(CC_IS_ARMCOMPILER)=-m32) -M32FLAG=$(___M32FLAG) - -all: argvfuzz32.so argvfuzz64.so - -argvfuzz32.so: argvfuzz.c - -@$(CC) $(M32FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ 2>/dev/null || echo "argvfuzz32 build failure (that's fine)" - -argvfuzz64.so: argvfuzz.c - -@$(CC) $(M64FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ 2>/dev/null || echo "argvfuzz64 build failure (that's fine)" - -install: argvfuzz32.so argvfuzz64.so - install -d -m 755 $(DESTDIR)$(HELPER_PATH)/ - if [ -f argvfuzz32.so ]; then set -e; install -m 755 argvfuzz32.so $(DESTDIR)$(HELPER_PATH)/; fi - if [ -f argvfuzz64.so ]; then set -e; install -m 755 argvfuzz64.so $(DESTDIR)$(HELPER_PATH)/; fi - -clean: - rm -f argvfuzz32.so argvfuzz64.so diff --git a/examples/argv_fuzzing/README.md b/examples/argv_fuzzing/README.md deleted file mode 100644 index fa8cad80..00000000 --- a/examples/argv_fuzzing/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# argvfuzz - -afl supports fuzzing file inputs or stdin. When source is available, -`argv-fuzz-inl.h` can be used to change `main()` to build argv from stdin. - -`argvfuzz` tries to provide the same functionality for binaries. When loaded -using `LD_PRELOAD`, it will hook the call to `__libc_start_main` and replace -argv using the same logic of `argv-fuzz-inl.h`. - -A few conditions need to be fulfilled for this mechanism to work correctly: - -1. As it relies on hooking the loader, it cannot work on static binaries. -2. If the target binary does not use the default libc's `_start` implementation - (crt1.o), the hook may not run. -3. The hook will replace argv with pointers to `.data` of `argvfuzz.so`. If the - target binary expects argv to be living on the stack, things may go wrong. diff --git a/examples/argv_fuzzing/argv-fuzz-inl.h b/examples/argv_fuzzing/argv-fuzz-inl.h deleted file mode 100644 index c15c0271..00000000 --- a/examples/argv_fuzzing/argv-fuzz-inl.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - american fuzzy lop++ - sample argv fuzzing wrapper - ------------------------------------------------ - - Originally written by Michal Zalewski - - Copyright 2015 Google Inc. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at: - - http://www.apache.org/licenses/LICENSE-2.0 - - This file shows a simple way to fuzz command-line parameters with stock - afl-fuzz. To use, add: - - #include "/path/to/argv-fuzz-inl.h" - - ...to the file containing main(), ideally placing it after all the - standard includes. Next, put AFL_INIT_ARGV(); near the very beginning of - main(). - - This will cause the program to read NUL-delimited input from stdin and - put it in argv[]. Two subsequent NULs terminate the array. Empty - params are encoded as a lone 0x02. Lone 0x02 can't be generated, but - that shouldn't matter in real life. - - If you would like to always preserve argv[0], use this instead: - AFL_INIT_SET0("prog_name"); - -*/ - -#ifndef _HAVE_ARGV_FUZZ_INL -#define _HAVE_ARGV_FUZZ_INL - -#include <unistd.h> - -#define AFL_INIT_ARGV() \ - do { \ - \ - argv = afl_init_argv(&argc); \ - \ - } while (0) - -#define AFL_INIT_SET0(_p) \ - do { \ - \ - argv = afl_init_argv(&argc); \ - argv[0] = (_p); \ - if (!argc) argc = 1; \ - \ - } while (0) - -#define MAX_CMDLINE_LEN 100000 -#define MAX_CMDLINE_PAR 50000 - -static char **afl_init_argv(int *argc) { - - static char in_buf[MAX_CMDLINE_LEN]; - static char *ret[MAX_CMDLINE_PAR]; - - char *ptr = in_buf; - int rc = 0; - - if (read(0, in_buf, MAX_CMDLINE_LEN - 2) < 0) {} - - while (*ptr && rc < MAX_CMDLINE_PAR) { - - ret[rc] = ptr; - if (ret[rc][0] == 0x02 && !ret[rc][1]) ret[rc]++; - rc++; - - while (*ptr) - ptr++; - ptr++; - - } - - *argc = rc; - - return ret; - -} - -#undef MAX_CMDLINE_LEN -#undef MAX_CMDLINE_PAR - -#endif /* !_HAVE_ARGV_FUZZ_INL */ - diff --git a/examples/argv_fuzzing/argvfuzz.c b/examples/argv_fuzzing/argvfuzz.c deleted file mode 100644 index 4251ca4c..00000000 --- a/examples/argv_fuzzing/argvfuzz.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - american fuzzy lop++ - LD_PRELOAD for fuzzing argv in binaries - ------------------------------------------------------------ - - Copyright 2019-2020 Kjell Braden <afflux@pentabarf.de> - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at: - - http://www.apache.org/licenses/LICENSE-2.0 - - */ - -#define _GNU_SOURCE /* for RTLD_NEXT */ -#include <dlfcn.h> -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include "argv-fuzz-inl.h" - -int __libc_start_main(int (*main)(int, char **, char **), int argc, char **argv, - void (*init)(void), void (*fini)(void), - void (*rtld_fini)(void), void *stack_end) { - - int (*orig)(int (*main)(int, char **, char **), int argc, char **argv, - void (*init)(void), void (*fini)(void), void (*rtld_fini)(void), - void *stack_end); - int sub_argc; - char **sub_argv; - - (void)argc; - (void)argv; - - orig = dlsym(RTLD_NEXT, __func__); - - if (!orig) { - - fprintf(stderr, "hook did not find original %s: %s\n", __func__, dlerror()); - exit(EXIT_FAILURE); - - } - - sub_argv = afl_init_argv(&sub_argc); - - return orig(main, sub_argc, sub_argv, init, fini, rtld_fini, stack_end); - -} - diff --git a/examples/asan_cgroups/limit_memory.sh b/examples/asan_cgroups/limit_memory.sh deleted file mode 100755 index 1f0f04ad..00000000 --- a/examples/asan_cgroups/limit_memory.sh +++ /dev/null @@ -1,157 +0,0 @@ -#!/usr/bin/env bash -# -# american fuzzy lop++ - limit memory using cgroups -# ----------------------------------------------- -# -# Written by Samir Khakimov <samir.hakim@nyu.edu> and -# David A. Wheeler <dwheeler@ida.org> -# -# Edits to bring the script in line with afl-cmin and other companion scripts -# by Michal Zalewski. All bugs are my fault. -# -# Copyright 2015 Institute for Defense Analyses. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# This tool allows the amount of actual memory allocated to a program -# to be limited on Linux systems using cgroups, instead of the traditional -# setrlimit() API. This helps avoid the address space problems discussed in -# docs/notes_for_asan.md. -# -# Important: the limit covers *both* afl-fuzz and the fuzzed binary. In some -# hopefully rare circumstances, afl-fuzz could be killed before the fuzzed -# task. -# - -echo "cgroup tool for afl-fuzz by <samir.hakim@nyu.edu> and <dwheeler@ida.org>" -echo - -unset NEW_USER -MEM_LIMIT="50" - -while getopts "+u:m:" opt; do - - case "$opt" in - - "u") - NEW_USER="$OPTARG" - ;; - - "m") - MEM_LIMIT="$[OPTARG]" - ;; - - "?") - exit 1 - ;; - - esac - -done - -if [ "$MEM_LIMIT" -lt "5" ]; then - echo "[-] Error: malformed or dangerously low value of -m." 1>&2 - exit 1 -fi - -shift $((OPTIND-1)) - -TARGET_BIN="$1" - -if [ "$TARGET_BIN" = "" -o "$NEW_USER" = "" ]; then - - cat 1>&2 <<_EOF_ -Usage: $0 [ options ] -- /path/to/afl-fuzz [ ...afl options... ] - -Required parameters: - - -u user - run the fuzzer as a specific user after setting up limits - -Optional parameters: - - -m megs - set memory limit to a specified value ($MEM_LIMIT MB) - -This tool configures cgroups-based memory limits for a fuzzing job to simplify -the task of fuzzing ASAN or MSAN binaries. You would normally want to use it in -conjunction with '-m none' passed to the afl-fuzz binary itself, say: - - $0 -u joe ./afl-fuzz -i input -o output -m none /path/to/target - -_EOF_ - - exit 1 - -fi - -# Basic sanity checks - -if [ ! "`uname -s`" = "Linux" ]; then - echo "[-] Error: this tool does not support non-Linux systems." 1>&2 - exit 1 -fi - -if [ ! "`id -u`" = "0" ]; then - echo "[-] Error: you need to run this script as root (sorry!)." 1>&2 - exit 1 -fi - -if ! type cgcreate 2>/dev/null 1>&2; then - - echo "[-] Error: you need to install cgroup tools first." 1>&2 - - if type apt-get 2>/dev/null 1>&2; then - echo " (Perhaps 'apt-get install cgroup-bin' will work.)" 1>&2 - elif type yum 2>/dev/null 1>&2; then - echo " (Perhaps 'yum install libcgroup-tools' will work.)" 1>&2 - fi - - exit 1 - -fi - -if ! id -u "$NEW_USER" 2>/dev/null 1>&2; then - echo "[-] Error: user '$NEW_USER' does not seem to exist." 1>&2 - exit 1 -fi - -# Create a new cgroup path if necessary... We used PID-keyed groups to keep -# parallel afl-fuzz tasks separate from each other. - -CID="afl-$NEW_USER-$$" - -CPATH="/sys/fs/cgroup/memory/$CID" - -if [ ! -d "$CPATH" ]; then - - cgcreate -a "$NEW_USER" -g memory:"$CID" || exit 1 - -fi - -# Set the appropriate limit... - -if [ -f "$CPATH/memory.memsw.limit_in_bytes" ]; then - - echo "${MEM_LIMIT}M" > "$CPATH/memory.limit_in_bytes" 2>/dev/null - echo "${MEM_LIMIT}M" > "$CPATH/memory.memsw.limit_in_bytes" || exit 1 - echo "${MEM_LIMIT}M" > "$CPATH/memory.limit_in_bytes" || exit 1 - -elif grep -qE 'partition|file' /proc/swaps; then - - echo "[-] Error: your system requires swap to be disabled first (swapoff -a)." 1>&2 - exit 1 - -else - - echo "${MEM_LIMIT}M" > "$CPATH/memory.limit_in_bytes" || exit 1 - -fi - -# All right. At this point, we can just run the command. - -cgexec -g "memory:$CID" su -c "$*" "$NEW_USER" - -cgdelete -g "memory:$CID" diff --git a/examples/bash_shellshock/shellshock-fuzz.diff b/examples/bash_shellshock/shellshock-fuzz.diff deleted file mode 100644 index 3fa05bf8..00000000 --- a/examples/bash_shellshock/shellshock-fuzz.diff +++ /dev/null @@ -1,59 +0,0 @@ -This patch shows a very simple way to find post-Shellshock bugs in bash, as -discussed here: - - http://lcamtuf.blogspot.com/2014/10/bash-bug-how-we-finally-cracked.html - -In essence, it shows a way to fuzz environmental variables. Instructions: - -1) Download bash 4.3, apply this patch, compile with: - - CC=/path/to/afl-gcc ./configure - make clean all - - Note that the harness puts the fuzzed output in $TEST_VARIABLE. With - Florian's Shellshock patch (bash43-028), this is no longer passed down - to the parser. - -2) Create and cd to an empty directory, put the compiled bash binary in - there, and run these commands: - - mkdir in_dir - echo -n '() { a() { a; }; : >b; }' >in_dir/script.txt - -3) Run the fuzzer with: - - /path/to/afl-fuzz -d -i in_dir -o out_dir ./bash -c : - - The -d parameter is advisable only if the tested shell is fairly slow - or if you are in a hurry; will cover more ground faster, but - less systematically. - -4) Watch for crashes in out_dir/crashes/. Also watch for any new files - created in cwd if you're interested in non-crash RCEs (files will be - created whenever the shell executes "foo>bar" or something like - that). You can correlate their creation date with new entries in - out_dir/queue/. - - You can also modify the bash binary to directly check for more subtle - fault conditions, or use the synthesized entries in out_dir/queue/ - as a seed for other, possibly slower or more involved testing regimes. - - Expect several hours to get decent coverage. - ---- bash-4.3/shell.c.orig 2014-01-14 14:04:32.000000000 +0100 -+++ bash-4.3/shell.c 2015-04-30 05:56:46.000000000 +0200 -@@ -371,6 +371,14 @@ - env = environ; - #endif /* __OPENNT */ - -+ { -+ -+ static char val[1024 * 16]; -+ read(0, val, sizeof(val) - 1); -+ setenv("TEST_VARIABLE", val, 1); -+ -+ } -+ - USE_VAR(argc); - USE_VAR(argv); - USE_VAR(env); diff --git a/examples/canvas_harness/canvas_harness.html b/examples/canvas_harness/canvas_harness.html deleted file mode 100644 index a37b6937..00000000 --- a/examples/canvas_harness/canvas_harness.html +++ /dev/null @@ -1,170 +0,0 @@ -<html> -<!-- - - american fuzzy lop++ - <canvas> harness - ------------------------------------- - - Originally written by Michal Zalewski - - Copyright 2013, 2014 Google Inc. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at: - - http://www.apache.org/licenses/LICENSE-2.0 - - A simple harness for going through afl-generated test cases, rendering them in - the browser environment, and discovering the use of uninitialized memory and - similar bugs. This code led to the discovery of a fair number of library and - browser security bugs! - - The url_list[] array is a placeholder; for this to work properly, it needs to - be initialized with web-reachable paths to individual test cases. This can - be done manually or with a simple script. - ---> - -<body onload="set_images()"> - -<div id="status"></div> - -<div id="image_div"></div> - -<canvas height=64 width=64 id=cvs></canvas> - -<h2>Results</h2> - -<ul id="output"></ul> - -<script> - -var c = document.getElementById('cvs'); -var ctx = c.getContext('2d'); - -var url_list = [ - "images/id:000000,[...].jpg", - "images/id:000001,[...].jpg", - /* ... */ - null -]; - -var USE_IMAGES = 50; -var cur_image = 0; - -if (location.hash) cur_image = parseInt(location.hash.substr(1)); - -var loaded = 0; -var image_obj = []; - -var msie_cleanup; - -function check_results() { - - var uniques = []; - - clearTimeout(msie_cleanup); - - ctx.clearRect(0, 0, 64, 64); - - uniques.push(image_obj[0].imgdata); - - for (var i = 1; i < USE_IMAGES; i++) { - - if (!image_obj[i].imgdata) continue; - - if (image_obj[0].imgdata != image_obj[i].imgdata) { - - for (var j = 1; j < uniques.length; j++) - if (uniques[j] == image_obj[i].imgdata) break; - - if (j == uniques.length) uniques.push(image_obj[i].imgdata); - - - } - - } - - if (uniques.length > 1) { - - var str = '<li> Image ' + url_list[cur_image] + ' has ' + uniques.length + ' variants: '; - - for (var i = 0; i < uniques.length; i++) - str += '<img src="' + uniques[i] + '">'; - - document.getElementById('output').innerHTML += str; - - } - - cur_image++; - set_images(); -} - - -function count_image() { - - if (!this.complete || this.counted) return; - - this.counted = true; - - loaded++; - - ctx.clearRect(0, 0, 64, 64); - - try { - ctx.drawImage(this, 0, 0, 64, 64); - } catch (e) { } - - this.imgdata = c.toDataURL(); - - if (loaded == USE_IMAGES) check_results(); -} - - -function set_images() { - - loaded = 0; - - document.getElementById('status').innerHTML = 'Now processing ' + cur_image + '...'; - location.hash = '#' + cur_image; - - if (url_list[cur_image] == null) { - alert('Done!'); - return; - } - - restart_images(); - - msie_cleanup = setTimeout(check_results, 5000); - - for (var i = 0; i < USE_IMAGES; i++) - image_obj[i].src = url_list[cur_image] + '?' + Math.random(); - -} - - -function restart_images() { - - for (var i = 0; i < USE_IMAGES; i++) - if (image_obj[i]) image_obj[i].counted = true; - - document.getElementById('image_div').innerHTML = ''; - image_obj = []; - - for (var i = 0; i < USE_IMAGES; i++) { - - image_obj[i] = new Image(); - image_obj[i].height = 64; - image_obj[i].width = 64; - image_obj[i].onerror = count_image; - image_obj[i].onload = count_image; - - document.getElementById('image_div').appendChild(image_obj[i]); - - } - -} - -</script> - -<iframe src='http://www.cnn.com/'></iframe> diff --git a/examples/clang_asm_normalize/as b/examples/clang_asm_normalize/as deleted file mode 100755 index 45537cae..00000000 --- a/examples/clang_asm_normalize/as +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/sh -# -# american fuzzy lop++ - clang assembly normalizer -# ---------------------------------------------- -# -# Originally written by Michal Zalewski -# The idea for this wrapper comes from Ryan Govostes. -# -# Copyright 2013, 2014 Google Inc. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# This 'as' wrapper should allow you to instrument unruly, hand-written -# assembly with afl-as. -# -# Usage: -# -# export AFL_REAL_PATH=/path/to/directory/with/afl-as/ -# AFL_PATH=/path/to/this/directory/ make clean all - -if [ "$#" -lt "2" ]; then - echo "[-] Error: this utility can't be called directly." 1>&2 - exit 1 -fi - -if [ "$AFL_REAL_PATH" = "" ]; then - echo "[-] Error: AFL_REAL_PATH not set!" 1>&2 - exit 1 -fi - -if [ ! -x "$AFL_REAL_PATH/afl-as" ]; then - echo "[-] Error: AFL_REAL_PATH does not contain the 'afl-as' binary." 1>&2 - exit 1 -fi - -unset __AFL_AS_CMDLINE __AFL_FNAME - -while [ ! "$#" = "0" ]; do - - if [ "$#" = "1" ]; then - __AFL_FNAME="$1" - else - __AFL_AS_CMDLINE="${__AFL_AS_CMDLINE} $1" - fi - - shift - -done - -test "$TMPDIR" = "" && TMPDIR=/tmp - -TMPFILE=`mktemp $TMPDIR/.afl-XXXXXXXXXX.s` - -test "$TMPFILE" = "" && exit 1 - -clang -cc1as -filetype asm -output-asm-variant 0 "${__AFL_FNAME}" >"$TMPFILE" - -ERR="$?" - -if [ ! "$ERR" = "0" ]; then - rm -f "$TMPFILE" - exit $ERR -fi - -"$AFL_REAL_PATH/afl-as" ${__AFL_AS_CMDLINE} "$TMPFILE" - -ERR="$?" - -rm -f "$TMPFILE" - -exit "$ERR" diff --git a/examples/crash_triage/triage_crashes.sh b/examples/crash_triage/triage_crashes.sh deleted file mode 100755 index bf763cba..00000000 --- a/examples/crash_triage/triage_crashes.sh +++ /dev/null @@ -1,115 +0,0 @@ -#!/bin/sh -# -# american fuzzy lop++ - crash triage utility -# ----------------------------------------- -# -# Originally written by Michal Zalewski -# -# Copyright 2013, 2014, 2017 Google Inc. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Note that this assumes that the targeted application reads from stdin -# and requires no other cmdline parameters. Modify as needed if this is -# not the case. -# -# Note that on OpenBSD, you may need to install a newer version of gdb -# (e.g., from ports). You can set GDB=/some/path to point to it if -# necessary. -# - -echo "crash triage utility for afl-fuzz by Michal Zalewski" -echo - -ulimit -v 100000 2>/dev/null -ulimit -d 100000 2>/dev/null - -if [ "$#" -lt "2" ]; then - echo "Usage: $0 /path/to/afl_output_dir /path/to/tested_binary [...target params...]" 1>&2 - echo 1>&2 - exit 1 -fi - -DIR="$1" -BIN="$2" -shift -shift - -if [ "$AFL_ALLOW_TMP" = "" ]; then - - echo "$DIR" | grep -qE '^(/var)?/tmp/' - T1="$?" - - echo "$BIN" | grep -qE '^(/var)?/tmp/' - T2="$?" - - if [ "$T1" = "0" -o "$T2" = "0" ]; then - echo "[-] Error: do not use shared /tmp or /var/tmp directories with this script." 1>&2 - exit 1 - fi - -fi - -if - [ "$GDB" = "" ]; then - GDB=gdb -fi - -if [ ! -f "$BIN" -o ! -x "$BIN" ]; then - echo "[-] Error: binary '$2' not found or is not executable." 1>&2 - exit 1 -fi - -if [ ! -d "$DIR/queue" ]; then - echo "[-] Error: directory '$1' not found or not created by afl-fuzz." 1>&2 - exit 1 -fi - -CCOUNT=$((`ls -- "$DIR/crashes" 2>/dev/null | wc -l`)) - -if [ "$CCOUNT" = "0" ]; then - echo "No crashes recorded in the target directory - nothing to be done." - exit 0 -fi - -echo - -for crash in $DIR/crashes/id:*; do - - id=`basename -- "$crash" | cut -d, -f1 | cut -d: -f2` - sig=`basename -- "$crash" | cut -d, -f2 | cut -d: -f2` - - # Grab the args, converting @@ to $crash - - use_args="" - use_stdio=1 - - for a in $@; do - - if [ "$a" = "@@" ] ; then - use_args="$use_args $crash" - unset use_stdio - else - use_args="$use_args $a" - fi - - done - - # Strip the trailing space - use_args="${use_args# }" - - echo "+++ ID $id, SIGNAL $sig +++" - echo - - if [ "$use_stdio" = "1" ]; then - $GDB --batch -q --ex "r $use_args <$crash" --ex 'back' --ex 'disass $pc, $pc+16' --ex 'info reg' --ex 'quit' "$BIN" 0</dev/null - else - $GDB --batch -q --ex "r $use_args" --ex 'back' --ex 'disass $pc, $pc+16' --ex 'info reg' --ex 'quit' "$BIN" 0</dev/null - fi - echo - -done diff --git a/examples/custom_mutators/Makefile b/examples/custom_mutators/Makefile deleted file mode 100644 index 9849f3f4..00000000 --- a/examples/custom_mutators/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -all: libexamplemutator.so - -libexamplemutator.so: - $(CC) $(CFLAGS) -D_FORTIFY_SOURCE=2 -O3 -fPIC -shared -g -I ../../include example.c -o libexamplemutator.so - -clean: - rm -rf libexamplemutator.so diff --git a/examples/custom_mutators/README.md b/examples/custom_mutators/README.md deleted file mode 100644 index 655f7a5e..00000000 --- a/examples/custom_mutators/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# Examples for the custom mutator - -These are example and helper files for the custom mutator feature. -See [docs/custom_mutators.md](../../docs/custom_mutators.md) for more information - -Note that if you compile with python3.7 you must use python3 scripts, and if -you use python2.7 to compile python2 scripts! - -simple_example.c - most simplest example. generates a random sized buffer - filled with 'A' - -example.c - this is a simple example written in C and should be compiled to a - shared library. Use make to compile it and produce libexamplemutator.so - -example.py - this is the template you can use, the functions are there but they - are empty - -post_library_gif.so.c - fix a fuzz input to ensure it is valid for GIF - -post_library_png.so.c - fix a fuzz input to ensure it is valid for PNG - -simple-chunk-replace.py - this is a simple example where chunks are replaced - -common.py - this can be used for common functions and helpers. - the examples do not use this though. But you can :) - -wrapper_afl_min.py - mutation of XML documents, loads XmlMutatorMin.py - -XmlMutatorMin.py - module for XML mutation - -custom_mutator_helpers.h is an header that defines some helper routines -like surgical_havoc_mutate() that allow to perform a randomly chosen -mutation from a subset of the havoc mutations. -If you do so, you have to specify -I /path/to/AFLplusplus/include when -compiling. diff --git a/examples/custom_mutators/XmlMutatorMin.py b/examples/custom_mutators/XmlMutatorMin.py deleted file mode 100644 index 4c80a2ba..00000000 --- a/examples/custom_mutators/XmlMutatorMin.py +++ /dev/null @@ -1,332 +0,0 @@ -#!/usr/bin/python - -""" Mutation of XML documents, should be called from one of its wrappers (CLI, AFL, ...) """ - -from __future__ import print_function -from copy import deepcopy -from lxml import etree as ET -import random, re, io - - -########################### -# The XmlMutatorMin class # -########################### - -class XmlMutatorMin: - - """ - Optionals parameters: - seed Seed used by the PRNG (default: "RANDOM") - verbose Verbosity (default: False) - """ - - def __init__(self, seed="RANDOM", verbose=False): - - """ Initialize seed, database and mutators """ - - # Verbosity - self.verbose = verbose - - # Initialize PRNG - self.seed = str(seed) - if self.seed == "RANDOM": - random.seed() - else: - if self.verbose: - print("Static seed '%s'" % self.seed) - random.seed(self.seed) - - # Initialize input and output documents - self.input_tree = None - self.tree = None - - # High-level mutators (no database needed) - hl_mutators_delete = ["del_node_and_children", "del_node_but_children", "del_attribute", "del_content"] # Delete items - hl_mutators_fuzz = ["fuzz_attribute"] # Randomly change attribute values - - # Exposed mutators - self.hl_mutators_all = hl_mutators_fuzz + hl_mutators_delete - - def __parse_xml(self, xml): - - """ Parse an XML string. Basic wrapper around lxml.parse() """ - - try: - # Function parse() takes care of comments / DTD / processing instructions / ... - tree = ET.parse(io.BytesIO(xml)) - except ET.ParseError: - raise RuntimeError("XML isn't well-formed!") - except LookupError as e: - raise RuntimeError(e) - - # Return a document wrapper - return tree - - def __exec_among(self, module, functions, min_times, max_times): - - """ Randomly execute $functions between $min and $max times """ - - for i in xrange(random.randint(min_times, max_times)): - # Function names are mangled because they are "private" - getattr(module, "_XmlMutatorMin__" + random.choice(functions))() - - def __serialize_xml(self, tree): - - """ Serialize a XML document. Basic wrapper around lxml.tostring() """ - - return ET.tostring(tree, with_tail=False, xml_declaration=True, encoding=tree.docinfo.encoding) - - def __ver(self, version): - - """ Helper for displaying lxml version numbers """ - - return ".".join(map(str, version)) - - def reset(self): - - """ Reset the mutator """ - - self.tree = deepcopy(self.input_tree) - - def init_from_string(self, input_string): - - """ Initialize the mutator from a XML string """ - - # Get a pointer to the top-element - self.input_tree = self.__parse_xml(input_string) - - # Get a working copy - self.tree = deepcopy(self.input_tree) - - def save_to_string(self): - - """ Return the current XML document as UTF-8 string """ - - # Return a text version of the tree - return self.__serialize_xml(self.tree) - - def __pick_element(self, exclude_root_node=False): - - """ Pick a random element from the current document """ - - # Get a list of all elements, but nodes like PI and comments - elems = list(self.tree.getroot().iter(tag=ET.Element)) - - # Is the root node excluded? - if exclude_root_node: - start = 1 - else: - start = 0 - - # Pick a random element - try: - elem_id = random.randint(start, len(elems) - 1) - elem = elems[elem_id] - except ValueError: - # Should only occurs if "exclude_root_node = True" - return (None, None) - - return (elem_id, elem) - - def __fuzz_attribute(self): - - """ Fuzz (part of) an attribute value """ - - # Select a node to modify - (rand_elem_id, rand_elem) = self.__pick_element() - - # Get all the attributes - attribs = rand_elem.keys() - - # Is there attributes? - if len(attribs) < 1: - if self.verbose: - print("No attribute: can't replace!") - return - - # Pick a random attribute - rand_attrib_id = random.randint(0, len(attribs) - 1) - rand_attrib = attribs[rand_attrib_id] - - # We have the attribute to modify - # Get its value - attrib_value = rand_elem.get(rand_attrib) - # print("- Value: " + attrib_value) - - # Should we work on the whole value? - func_call = "(?P<func>[a-zA-Z:\-]+)\((?P<args>.*?)\)" - p = re.compile(func_call) - l = p.findall(attrib_value) - if random.choice((True, False)) and l: - # Randomly pick one the function calls - (func, args) = random.choice(l) - # Split by "," and randomly pick one of the arguments - value = random.choice(args.split(',')) - # Remove superfluous characters - unclean_value = value - value = value.strip(" ").strip("'") - # print("Selected argument: [%s]" % value) - else: - value = attrib_value - - # For each type, define some possible replacement values - choices_number = ( \ - "0", \ - "11111", \ - "-128", \ - "2", \ - "-1", \ - "1/3", \ - "42/0", \ - "1094861636 idiv 1.0", \ - "-1123329771506872 idiv 3.8", \ - "17=$numericRTF", \ - str(3 + random.randrange(0, 100)), \ - ) - - choices_letter = ( \ - "P" * (25 * random.randrange(1, 100)), \ - "%s%s%s%s%s%s", \ - "foobar", \ - ) - - choices_alnum = ( \ - "Abc123", \ - "020F0302020204030204", \ - "020F0302020204030204" * (random.randrange(5, 20)), \ - ) - - # Fuzz the value - if random.choice((True,False)) and value == "": - - # Empty - new_value = value - - elif random.choice((True,False)) and value.isdigit(): - - # Numbers - new_value = random.choice(choices_number) - - elif random.choice((True,False)) and value.isalpha(): - - # Letters - new_value = random.choice(choices_letter) - - elif random.choice((True,False)) and value.isalnum(): - - # Alphanumeric - new_value = random.choice(choices_alnum) - - else: - - # Default type - new_value = random.choice(choices_alnum + choices_letter + choices_number) - - # If we worked on a substring, apply changes to the whole string - if value != attrib_value: - # No ' around empty values - if new_value != "" and value != "": - new_value = "'" + new_value + "'" - # Apply changes - new_value = attrib_value.replace(unclean_value, new_value) - - # Log something - if self.verbose: - print("Fuzzing attribute #%i '%s' of tag #%i '%s'" % (rand_attrib_id, rand_attrib, rand_elem_id, rand_elem.tag)) - - # Modify the attribute - rand_elem.set(rand_attrib, new_value.decode("utf-8")) - - def __del_node_and_children(self): - - """ High-level minimizing mutator - Delete a random node and its children (i.e. delete a random tree) """ - - self.__del_node(True) - - def __del_node_but_children(self): - - """ High-level minimizing mutator - Delete a random node but its children (i.e. link them to the parent of the deleted node) """ - - self.__del_node(False) - - def __del_node(self, delete_children): - - """ Called by the __del_node_* mutators """ - - # Select a node to modify (but the root one) - (rand_elem_id, rand_elem) = self.__pick_element(exclude_root_node=True) - - # If the document includes only a top-level element - # Then we can't pick a element (given that "exclude_root_node = True") - - # Is the document deep enough? - if rand_elem is None: - if self.verbose: - print("Can't delete a node: document not deep enough!") - return - - # Log something - if self.verbose: - but_or_and = "and" if delete_children else "but" - print("Deleting tag #%i '%s' %s its children" % (rand_elem_id, rand_elem.tag, but_or_and)) - - if delete_children is False: - # Link children of the random (soon to be deleted) node to its parent - for child in rand_elem: - rand_elem.getparent().append(child) - - # Remove the node - rand_elem.getparent().remove(rand_elem) - - def __del_content(self): - - """ High-level minimizing mutator - Delete the attributes and children of a random node """ - - # Select a node to modify - (rand_elem_id, rand_elem) = self.__pick_element() - - # Log something - if self.verbose: - print("Reseting tag #%i '%s'" % (rand_elem_id, rand_elem.tag)) - - # Reset the node - rand_elem.clear() - - def __del_attribute(self): - - """ High-level minimizing mutator - Delete a random attribute from a random node """ - - # Select a node to modify - (rand_elem_id, rand_elem) = self.__pick_element() - - # Get all the attributes - attribs = rand_elem.keys() - - # Is there attributes? - if len(attribs) < 1: - if self.verbose: - print("No attribute: can't delete!") - return - - # Pick a random attribute - rand_attrib_id = random.randint(0, len(attribs) - 1) - rand_attrib = attribs[rand_attrib_id] - - # Log something - if self.verbose: - print("Deleting attribute #%i '%s' of tag #%i '%s'" % (rand_attrib_id, rand_attrib, rand_elem_id, rand_elem.tag)) - - # Delete the attribute - rand_elem.attrib.pop(rand_attrib) - - def mutate(self, min=1, max=5): - - """ Execute some high-level mutators between $min and $max times, then some medium-level ones """ - - # High-level mutation - self.__exec_among(self, self.hl_mutators_all, min, max) - diff --git a/examples/custom_mutators/common.py b/examples/custom_mutators/common.py deleted file mode 100644 index 9a1ef0a3..00000000 --- a/examples/custom_mutators/common.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -''' -Module containing functions shared between multiple AFL modules - -@author: Christian Holler (:decoder) - -@license: - -This Source Code Form is subject to the terms of the Mozilla Public -License, v. 2.0. If a copy of the MPL was not distributed with this -file, You can obtain one at http://mozilla.org/MPL/2.0/. - -@contact: choller@mozilla.com -''' - -from __future__ import print_function -import random -import os -import re - - -def randel(l): - if not l: - return None - return l[random.randint(0, len(l)-1)] - - -def randel_pop(l): - if not l: - return None - return l.pop(random.randint(0, len(l)-1)) - - -def write_exc_example(data, exc): - exc_name = re.sub(r'[^a-zA-Z0-9]', '_', repr(exc)) - - if not os.path.exists(exc_name): - with open(exc_name, 'w') as f: - f.write(data) diff --git a/examples/custom_mutators/custom_mutator_helpers.h b/examples/custom_mutators/custom_mutator_helpers.h deleted file mode 100644 index 62e6efba..00000000 --- a/examples/custom_mutators/custom_mutator_helpers.h +++ /dev/null @@ -1,342 +0,0 @@ -#ifndef CUSTOM_MUTATOR_HELPERS -#define CUSTOM_MUTATOR_HELPERS - -#include "config.h" -#include "types.h" -#include <stdlib.h> - -#define INITIAL_GROWTH_SIZE (64) - -#define RAND_BELOW(limit) (rand() % (limit)) - -/* Use in a struct: creates a name_buf and a name_size variable. */ -#define BUF_VAR(type, name) \ - type * name##_buf; \ - size_t name##_size; -/* this fills in `&structptr->something_buf, &structptr->something_size`. */ -#define BUF_PARAMS(struct, name) \ - (void **)&struct->name##_buf, &struct->name##_size - -typedef struct { - -} afl_t; - -static void surgical_havoc_mutate(u8 *out_buf, s32 begin, s32 end) { - - static s8 interesting_8[] = {INTERESTING_8}; - static s16 interesting_16[] = {INTERESTING_8, INTERESTING_16}; - static s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32}; - - switch (RAND_BELOW(12)) { - - case 0: { - - /* Flip a single bit somewhere. Spooky! */ - - s32 bit_idx = ((RAND_BELOW(end - begin) + begin) << 3) + RAND_BELOW(8); - - out_buf[bit_idx >> 3] ^= 128 >> (bit_idx & 7); - - break; - - } - - case 1: { - - /* Set byte to interesting value. */ - - u8 val = interesting_8[RAND_BELOW(sizeof(interesting_8))]; - out_buf[(RAND_BELOW(end - begin) + begin)] = val; - - break; - - } - - case 2: { - - /* Set word to interesting value, randomly choosing endian. */ - - if (end - begin < 2) break; - - s32 byte_idx = (RAND_BELOW(end - begin) + begin); - - if (byte_idx >= end - 1) break; - - switch (RAND_BELOW(2)) { - - case 0: - *(u16 *)(out_buf + byte_idx) = - interesting_16[RAND_BELOW(sizeof(interesting_16) >> 1)]; - break; - case 1: - *(u16 *)(out_buf + byte_idx) = - SWAP16(interesting_16[RAND_BELOW(sizeof(interesting_16) >> 1)]); - break; - - } - - break; - - } - - case 3: { - - /* Set dword to interesting value, randomly choosing endian. */ - - if (end - begin < 4) break; - - s32 byte_idx = (RAND_BELOW(end - begin) + begin); - - if (byte_idx >= end - 3) break; - - switch (RAND_BELOW(2)) { - - case 0: - *(u32 *)(out_buf + byte_idx) = - interesting_32[RAND_BELOW(sizeof(interesting_32) >> 2)]; - break; - case 1: - *(u32 *)(out_buf + byte_idx) = - SWAP32(interesting_32[RAND_BELOW(sizeof(interesting_32) >> 2)]); - break; - - } - - break; - - } - - case 4: { - - /* Set qword to interesting value, randomly choosing endian. */ - - if (end - begin < 8) break; - - s32 byte_idx = (RAND_BELOW(end - begin) + begin); - - if (byte_idx >= end - 7) break; - - switch (RAND_BELOW(2)) { - - case 0: - *(u64 *)(out_buf + byte_idx) = - (s64)interesting_32[RAND_BELOW(sizeof(interesting_32) >> 2)]; - break; - case 1: - *(u64 *)(out_buf + byte_idx) = SWAP64( - (s64)interesting_32[RAND_BELOW(sizeof(interesting_32) >> 2)]); - break; - - } - - break; - - } - - case 5: { - - /* Randomly subtract from byte. */ - - out_buf[(RAND_BELOW(end - begin) + begin)] -= 1 + RAND_BELOW(ARITH_MAX); - - break; - - } - - case 6: { - - /* Randomly add to byte. */ - - out_buf[(RAND_BELOW(end - begin) + begin)] += 1 + RAND_BELOW(ARITH_MAX); - - break; - - } - - case 7: { - - /* Randomly subtract from word, random endian. */ - - if (end - begin < 2) break; - - s32 byte_idx = (RAND_BELOW(end - begin) + begin); - - if (byte_idx >= end - 1) break; - - if (RAND_BELOW(2)) { - - *(u16 *)(out_buf + byte_idx) -= 1 + RAND_BELOW(ARITH_MAX); - - } else { - - u16 num = 1 + RAND_BELOW(ARITH_MAX); - - *(u16 *)(out_buf + byte_idx) = - SWAP16(SWAP16(*(u16 *)(out_buf + byte_idx)) - num); - - } - - break; - - } - - case 8: { - - /* Randomly add to word, random endian. */ - - if (end - begin < 2) break; - - s32 byte_idx = (RAND_BELOW(end - begin) + begin); - - if (byte_idx >= end - 1) break; - - if (RAND_BELOW(2)) { - - *(u16 *)(out_buf + byte_idx) += 1 + RAND_BELOW(ARITH_MAX); - - } else { - - u16 num = 1 + RAND_BELOW(ARITH_MAX); - - *(u16 *)(out_buf + byte_idx) = - SWAP16(SWAP16(*(u16 *)(out_buf + byte_idx)) + num); - - } - - break; - - } - - case 9: { - - /* Randomly subtract from dword, random endian. */ - - if (end - begin < 4) break; - - s32 byte_idx = (RAND_BELOW(end - begin) + begin); - - if (byte_idx >= end - 3) break; - - if (RAND_BELOW(2)) { - - *(u32 *)(out_buf + byte_idx) -= 1 + RAND_BELOW(ARITH_MAX); - - } else { - - u32 num = 1 + RAND_BELOW(ARITH_MAX); - - *(u32 *)(out_buf + byte_idx) = - SWAP32(SWAP32(*(u32 *)(out_buf + byte_idx)) - num); - - } - - break; - - } - - case 10: { - - /* Randomly add to dword, random endian. */ - - if (end - begin < 4) break; - - s32 byte_idx = (RAND_BELOW(end - begin) + begin); - - if (byte_idx >= end - 3) break; - - if (RAND_BELOW(2)) { - - *(u32 *)(out_buf + byte_idx) += 1 + RAND_BELOW(ARITH_MAX); - - } else { - - u32 num = 1 + RAND_BELOW(ARITH_MAX); - - *(u32 *)(out_buf + byte_idx) = - SWAP32(SWAP32(*(u32 *)(out_buf + byte_idx)) + num); - - } - - break; - - } - - case 11: { - - /* Just set a random byte to a random value. Because, - why not. We use XOR with 1-255 to eliminate the - possibility of a no-op. */ - - out_buf[(RAND_BELOW(end - begin) + begin)] ^= 1 + RAND_BELOW(255); - - break; - - } - - } - -} - -/* This function calculates the next power of 2 greater or equal its argument. - @return The rounded up power of 2 (if no overflow) or 0 on overflow. -*/ -static inline size_t next_pow2(size_t in) { - - if (in == 0 || in > (size_t)-1) - return 0; /* avoid undefined behaviour under-/overflow */ - size_t out = in - 1; - out |= out >> 1; - out |= out >> 2; - out |= out >> 4; - out |= out >> 8; - out |= out >> 16; - return out + 1; - -} - -/* This function makes sure *size is > size_needed after call. - It will realloc *buf otherwise. - *size will grow exponentially as per: - https://blog.mozilla.org/nnethercote/2014/11/04/please-grow-your-buffers-exponentially/ - Will return NULL and free *buf if size_needed is <1 or realloc failed. - @return For convenience, this function returns *buf. - */ -static inline void *maybe_grow(void **buf, size_t *size, size_t size_needed) { - - /* No need to realloc */ - if (likely(size_needed && *size >= size_needed)) return *buf; - - /* No initial size was set */ - if (size_needed < INITIAL_GROWTH_SIZE) size_needed = INITIAL_GROWTH_SIZE; - - /* grow exponentially */ - size_t next_size = next_pow2(size_needed); - - /* handle overflow */ - if (!next_size) { next_size = size_needed; } - - /* alloc */ - *buf = realloc(*buf, next_size); - *size = *buf ? next_size : 0; - - return *buf; - -} - -/* Swaps buf1 ptr and buf2 ptr, as well as their sizes */ -static inline void afl_swap_bufs(void **buf1, size_t *size1, void **buf2, - size_t *size2) { - - void * scratch_buf = *buf1; - size_t scratch_size = *size1; - *buf1 = *buf2; - *size1 = *size2; - *buf2 = scratch_buf; - *size2 = scratch_size; - -} - -#undef INITIAL_GROWTH_SIZE - -#endif - diff --git a/examples/custom_mutators/example.c b/examples/custom_mutators/example.c deleted file mode 100644 index 23add128..00000000 --- a/examples/custom_mutators/example.c +++ /dev/null @@ -1,376 +0,0 @@ -/* - New Custom Mutator for AFL++ - Written by Khaled Yakdan <yakdan@code-intelligence.de> - Andrea Fioraldi <andreafioraldi@gmail.com> - Shengtuo Hu <h1994st@gmail.com> - Dominik Maier <mail@dmnk.co> -*/ - -// You need to use -I /path/to/AFLplusplus/include -#include "custom_mutator_helpers.h" - -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -#define DATA_SIZE (100) - -static const char *commands[] = { - - "GET", - "PUT", - "DEL", - -}; - -typedef struct my_mutator { - - afl_t *afl; - - // any additional data here! - size_t trim_size_current; - int trimmming_steps; - int cur_step; - - // Reused buffers: - BUF_VAR(u8, fuzz); - BUF_VAR(u8, data); - BUF_VAR(u8, havoc); - BUF_VAR(u8, trim); - BUF_VAR(u8, post_process); - -} my_mutator_t; - -/** - * Initialize this custom mutator - * - * @param[in] afl a pointer to the internal state object. Can be ignored for - * now. - * @param[in] seed A seed for this mutator - the same seed should always mutate - * in the same way. - * @return Pointer to the data object this custom mutator instance should use. - * There may be multiple instances of this mutator in one afl-fuzz run! - * Return NULL on error. - */ -my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) { - - srand(seed); // needed also by surgical_havoc_mutate() - - my_mutator_t *data = calloc(1, sizeof(my_mutator_t)); - if (!data) { - - perror("afl_custom_init alloc"); - return NULL; - - } - - data->afl = afl; - - return data; - -} - -/** - * Perform custom mutations on a given input - * - * (Optional for now. Required in the future) - * - * @param[in] data pointer returned in afl_custom_init for this fuzz case - * @param[in] buf Pointer to input data to be mutated - * @param[in] buf_size Size of input data - * @param[out] out_buf the buffer we will work on. we can reuse *buf. NULL on - * error. - * @param[in] add_buf Buffer containing the additional test case - * @param[in] add_buf_size Size of the additional test case - * @param[in] max_size Maximum size of the mutated output. The mutation must not - * produce data larger than max_size. - * @return Size of the mutated output. - */ -size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, - u8 **out_buf, uint8_t *add_buf, - size_t add_buf_size, // add_buf can be NULL - size_t max_size) { - - // Make sure that the packet size does not exceed the maximum size expected by - // the fuzzer - size_t mutated_size = DATA_SIZE <= max_size ? DATA_SIZE : max_size; - - // maybe_grow is optimized to be quick for reused buffers. - u8 *mutated_out = maybe_grow(BUF_PARAMS(data, fuzz), mutated_size); - if (!mutated_out) { - - *out_buf = NULL; - perror("custom mutator allocation (maybe_grow)"); - return 0; /* afl-fuzz will very likely error out after this. */ - - } - - // Randomly select a command string to add as a header to the packet - memcpy(mutated_out, commands[rand() % 3], 3); - - // Mutate the payload of the packet - int i; - for (i = 0; i < 8; ++i) { - - // Randomly perform one of the (no len modification) havoc mutations - surgical_havoc_mutate(mutated_out, 3, mutated_size); - - } - - *out_buf = mutated_out; - return mutated_size; - -} - -/** - * A post-processing function to use right before AFL writes the test case to - * disk in order to execute the target. - * - * (Optional) If this functionality is not needed, simply don't define this - * function. - * - * @param[in] data pointer returned in afl_custom_init for this fuzz case - * @param[in] buf Buffer containing the test case to be executed - * @param[in] buf_size Size of the test case - * @param[out] out_buf Pointer to the buffer containing the test case after - * processing. External library should allocate memory for out_buf. - * The buf pointer may be reused (up to the given buf_size); - * @return Size of the output buffer after processing or the needed amount. - * A return of 0 indicates an error. - */ -size_t afl_custom_post_process(my_mutator_t *data, uint8_t *buf, - size_t buf_size, uint8_t **out_buf) { - - uint8_t *post_process_buf = - maybe_grow(BUF_PARAMS(data, post_process), buf_size + 5); - if (!post_process_buf) { - - perror("custom mutator realloc failed."); - *out_buf = NULL; - return 0; - - } - - memcpy(post_process_buf + 5, buf, buf_size); - post_process_buf[0] = 'A'; - post_process_buf[1] = 'F'; - post_process_buf[2] = 'L'; - post_process_buf[3] = '+'; - post_process_buf[4] = '+'; - - *out_buf = post_process_buf; - - return buf_size + 5; - -} - -/** - * This method is called at the start of each trimming operation and receives - * the initial buffer. It should return the amount of iteration steps possible - * on this input (e.g. if your input has n elements and you want to remove - * them one by one, return n, if you do a binary search, return log(n), - * and so on...). - * - * If your trimming algorithm doesn't allow you to determine the amount of - * (remaining) steps easily (esp. while running), then you can alternatively - * return 1 here and always return 0 in post_trim until you are finished and - * no steps remain. In that case, returning 1 in post_trim will end the - * trimming routine. The whole current index/max iterations stuff is only used - * to show progress. - * - * (Optional) - * - * @param data pointer returned in afl_custom_init for this fuzz case - * @param buf Buffer containing the test case - * @param buf_size Size of the test case - * @return The amount of possible iteration steps to trim the input. - * negative on error. - */ -int32_t afl_custom_init_trim(my_mutator_t *data, uint8_t *buf, - size_t buf_size) { - - // We simply trim once - data->trimmming_steps = 1; - - data->cur_step = 0; - - if (!maybe_grow(BUF_PARAMS(data, trim), buf_size)) { - - perror("init_trim grow"); - return -1; - - } - - memcpy(data->trim_buf, buf, buf_size); - - data->trim_size_current = buf_size; - - return data->trimmming_steps; - -} - -/** - * This method is called for each trimming operation. It doesn't have any - * arguments because we already have the initial buffer from init_trim and we - * can memorize the current state in *data. This can also save - * reparsing steps for each iteration. It should return the trimmed input - * buffer, where the returned data must not exceed the initial input data in - * length. Returning anything that is larger than the original data (passed - * to init_trim) will result in a fatal abort of AFLFuzz. - * - * (Optional) - * - * @param[in] data pointer returned in afl_custom_init for this fuzz case - * @param[out] out_buf Pointer to the buffer containing the trimmed test case. - * External library should allocate memory for out_buf. - * AFL++ will not release the memory after saving the test case. - * Keep a ref in *data. - * *out_buf = NULL is treated as error. - * @return Pointer to the size of the trimmed test case - */ -size_t afl_custom_trim(my_mutator_t *data, uint8_t **out_buf) { - - *out_buf = data->trim_buf; - - // Remove the last byte of the trimming input - return data->trim_size_current - 1; - -} - -/** - * This method is called after each trim operation to inform you if your - * trimming step was successful or not (in terms of coverage). If you receive - * a failure here, you should reset your input to the last known good state. - * - * (Optional) - * - * @param[in] data pointer returned in afl_custom_init for this fuzz case - * @param success Indicates if the last trim operation was successful. - * @return The next trim iteration index (from 0 to the maximum amount of - * steps returned in init_trim). negative ret on failure. - */ -int32_t afl_custom_post_trim(my_mutator_t *data, int success) { - - if (success) { - - ++data->cur_step; - return data->cur_step; - - } - - return data->trimmming_steps; - -} - -/** - * Perform a single custom mutation on a given input. - * This mutation is stacked with the other muatations in havoc. - * - * (Optional) - * - * @param[in] data pointer returned in afl_custom_init for this fuzz case - * @param[in] buf Pointer to the input data to be mutated and the mutated - * output - * @param[in] buf_size Size of input data - * @param[out] out_buf The output buffer. buf can be reused, if the content - * fits. *out_buf = NULL is treated as error. - * @param[in] max_size Maximum size of the mutated output. The mutation must - * not produce data larger than max_size. - * @return Size of the mutated output. - */ -size_t afl_custom_havoc_mutation(my_mutator_t *data, u8 *buf, size_t buf_size, - u8 **out_buf, size_t max_size) { - - if (buf_size == 0) { - - *out_buf = maybe_grow(BUF_PARAMS(data, havoc), 1); - if (!*out_buf) { - - perror("custom havoc: maybe_grow"); - return 0; - - } - - **out_buf = rand() % 256; - buf_size = 1; - - } else { - - // We reuse buf here. It's legal and faster. - *out_buf = buf; - - } - - size_t victim = rand() % buf_size; - (*out_buf)[victim] += rand() % 10; - - return buf_size; - -} - -/** - * Return the probability (in percentage) that afl_custom_havoc_mutation - * is called in havoc. By default it is 6 %. - * - * (Optional) - * - * @param[in] data pointer returned in afl_custom_init for this fuzz case - * @return The probability (0-100). - */ -uint8_t afl_custom_havoc_mutation_probability(my_mutator_t *data) { - - return 5; // 5 % - -} - -/** - * Determine whether the fuzzer should fuzz the queue entry or not. - * - * (Optional) - * - * @param[in] data pointer returned in afl_custom_init for this fuzz case - * @param filename File name of the test case in the queue entry - * @return Return True(1) if the fuzzer will fuzz the queue entry, and - * False(0) otherwise. - */ -uint8_t afl_custom_queue_get(my_mutator_t *data, const uint8_t *filename) { - - return 1; - -} - -/** - * Allow for additional analysis (e.g. calling a different tool that does a - * different kind of coverage and saves this for the custom mutator). - * - * (Optional) - * - * @param data pointer returned in afl_custom_init for this fuzz case - * @param filename_new_queue File name of the new queue entry - * @param filename_orig_queue File name of the original queue entry - */ -void afl_custom_queue_new_entry(my_mutator_t * data, - const uint8_t *filename_new_queue, - const uint8_t *filename_orig_queue) { - - /* Additional analysis on the original or new test case */ - -} - -/** - * Deinitialize everything - * - * @param data The data ptr from afl_custom_init - */ -void afl_custom_deinit(my_mutator_t *data) { - - free(data->post_process_buf); - free(data->havoc_buf); - free(data->data_buf); - free(data->fuzz_buf); - free(data->trim_buf); - free(data); - -} - diff --git a/examples/custom_mutators/example.py b/examples/custom_mutators/example.py deleted file mode 100644 index cf659e5a..00000000 --- a/examples/custom_mutators/example.py +++ /dev/null @@ -1,186 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -''' -Example Python Module for AFLFuzz - -@author: Christian Holler (:decoder) - -@license: - -This Source Code Form is subject to the terms of the Mozilla Public -License, v. 2.0. If a copy of the MPL was not distributed with this -file, You can obtain one at http://mozilla.org/MPL/2.0/. - -@contact: choller@mozilla.com -''' - -import random - - -COMMANDS = [ - b"GET", - b"PUT", - b"DEL", - b"AAAAAAAAAAAAAAAAA", -] - - -def init(seed): - ''' - Called once when AFLFuzz starts up. Used to seed our RNG. - - @type seed: int - @param seed: A 32-bit random value - ''' - random.seed(seed) - - -def deinit(): - pass - - -def fuzz(buf, add_buf, max_size): - ''' - Called per fuzzing iteration. - - @type buf: bytearray - @param buf: The buffer that should be mutated. - - @type add_buf: bytearray - @param add_buf: A second buffer that can be used as mutation source. - - @type max_size: int - @param max_size: Maximum size of the mutated output. The mutation must not - produce data larger than max_size. - - @rtype: bytearray - @return: A new bytearray containing the mutated data - ''' - ret = bytearray(100) - - ret[:3] = random.choice(COMMANDS) - - return ret - -# Uncomment and implement the following methods if you want to use a custom -# trimming algorithm. See also the documentation for a better API description. - -# def init_trim(buf): -# ''' -# Called per trimming iteration. -# -# @type buf: bytearray -# @param buf: The buffer that should be trimmed. -# -# @rtype: int -# @return: The maximum number of trimming steps. -# ''' -# global ... -# -# # Initialize global variables -# -# # Figure out how many trimming steps are possible. -# # If this is not possible for your trimming, you can -# # return 1 instead and always return 0 in post_trim -# # until you are done (then you return 1). -# -# return steps -# -# def trim(): -# ''' -# Called per trimming iteration. -# -# @rtype: bytearray -# @return: A new bytearray containing the trimmed data. -# ''' -# global ... -# -# # Implement the actual trimming here -# -# return bytearray(...) -# -# def post_trim(success): -# ''' -# Called after each trimming operation. -# -# @type success: bool -# @param success: Indicates if the last trim operation was successful. -# -# @rtype: int -# @return: The next trim index (0 to max number of steps) where max -# number of steps indicates the trimming is done. -# ''' -# global ... -# -# if not success: -# # Restore last known successful input, determine next index -# else: -# # Just determine the next index, based on what was successfully -# # removed in the last step -# -# return next_index -# -# def post_process(buf): -# ''' -# Called just before the execution to write the test case in the format -# expected by the target -# -# @type buf: bytearray -# @param buf: The buffer containing the test case to be executed -# -# @rtype: bytearray -# @return: The buffer containing the test case after -# ''' -# return buf -# -# def havoc_mutation(buf, max_size): -# ''' -# Perform a single custom mutation on a given input. -# -# @type buf: bytearray -# @param buf: The buffer that should be mutated. -# -# @type max_size: int -# @param max_size: Maximum size of the mutated output. The mutation must not -# produce data larger than max_size. -# -# @rtype: bytearray -# @return: A new bytearray containing the mutated data -# ''' -# return mutated_buf -# -# def havoc_mutation_probability(): -# ''' -# Called for each `havoc_mutation`. Return the probability (in percentage) -# that `havoc_mutation` is called in havoc. Be default it is 6%. -# -# @rtype: int -# @return: The probability (0-100) -# ''' -# return prob -# -# def queue_get(filename): -# ''' -# Called at the beginning of each fuzz iteration to determine whether the -# test case should be fuzzed -# -# @type filename: str -# @param filename: File name of the test case in the current queue entry -# -# @rtype: bool -# @return: Return True if the custom mutator decides to fuzz the test case, -# and False otherwise -# ''' -# return True -# -# def queue_new_entry(filename_new_queue, filename_orig_queue): -# ''' -# Called after adding a new test case to the queue -# -# @type filename_new_queue: str -# @param filename_new_queue: File name of the new queue entry -# -# @type filename_orig_queue: str -# @param filename_orig_queue: File name of the original queue entry -# ''' -# pass diff --git a/examples/custom_mutators/post_library_gif.so.c b/examples/custom_mutators/post_library_gif.so.c deleted file mode 100644 index ac10f409..00000000 --- a/examples/custom_mutators/post_library_gif.so.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - american fuzzy lop++ - postprocessor library example - -------------------------------------------------- - - Originally written by Michal Zalewski - Edited by Dominik Maier, 2020 - - Copyright 2015 Google Inc. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at: - - http://www.apache.org/licenses/LICENSE-2.0 - - Postprocessor libraries can be passed to afl-fuzz to perform final cleanup - of any mutated test cases - for example, to fix up checksums in PNG files. - - Please heed the following warnings: - - 1) In almost all cases, it is more productive to comment out checksum logic - in the targeted binary (as shown in ../libpng_no_checksum/). One possible - exception is the process of fuzzing binary-only software in QEMU mode. - - 2) The use of postprocessors for anything other than checksums is - questionable and may cause more harm than good. AFL is normally pretty good - about dealing with length fields, magic values, etc. - - 3) Postprocessors that do anything non-trivial must be extremely robust to - gracefully handle malformed data and other error conditions - otherwise, - they will crash and take afl-fuzz down with them. Be wary of reading past - *len and of integer overflows when calculating file offsets. - - In other words, THIS IS PROBABLY NOT WHAT YOU WANT - unless you really, - honestly know what you're doing =) - - With that out of the way: the postprocessor library is passed to afl-fuzz - via AFL_POST_LIBRARY. The library must be compiled with: - - gcc -shared -Wall -O3 post_library.so.c -o post_library.so - - AFL will call the afl_custom_post_process() function for every mutated output - buffer. From there, you have three choices: - - 1) If you don't want to modify the test case, simply set `*out_buf = in_buf` - and return the original `len`. - - 2) If you want to skip this test case altogether and have AFL generate a - new one, return 0 or set `*out_buf = NULL`. - Use this sparingly - it's faster than running the target program - with patently useless inputs, but still wastes CPU time. - - 3) If you want to modify the test case, allocate an appropriately-sized - buffer, move the data into that buffer, make the necessary changes, and - then return the new pointer as out_buf. Return an appropriate len - afterwards. - - Note that the buffer will *not* be freed for you. To avoid memory leaks, - you need to free it or reuse it on subsequent calls (as shown below). - - *** Feel free to reuse the original 'in_buf' BUFFER and return it. *** - - Aight. The example below shows a simple postprocessor that tries to make - sure that all input files start with "GIF89a". - - PS. If you don't like C, you can try out the unix-based wrapper from - Ben Nagy instead: https://github.com/bnagy/aflfix - - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -/* Header that must be present at the beginning of every test case: */ - -#define HEADER "GIF89a" - -typedef struct post_state { - - unsigned char *buf; - size_t size; - -} post_state_t; - -void *afl_custom_init(void *afl) { - - post_state_t *state = malloc(sizeof(post_state_t)); - if (!state) { - - perror("malloc"); - return NULL; - - } - - state->buf = calloc(sizeof(unsigned char), 4096); - if (!state->buf) { - - free(state); - perror("calloc"); - return NULL; - - } - - return state; - -} - -/* The actual postprocessor routine called by afl-fuzz: */ - -size_t afl_custom_post_process(post_state_t *data, unsigned char *in_buf, - unsigned int len, unsigned char **out_buf) { - - /* Skip execution altogether for buffers shorter than 6 bytes (just to - show how it's done). We can trust len to be sane. */ - - if (len < strlen(HEADER)) return 0; - - /* Do nothing for buffers that already start with the expected header. */ - - if (!memcmp(in_buf, HEADER, strlen(HEADER))) { - - *out_buf = in_buf; - return len; - - } - - /* Allocate memory for new buffer, reusing previous allocation if - possible. */ - - *out_buf = realloc(data->buf, len); - - /* If we're out of memory, the most graceful thing to do is to return the - original buffer and give up on modifying it. Let AFL handle OOM on its - own later on. */ - - if (!*out_buf) { - - *out_buf = in_buf; - return len; - - } - - /* Copy the original data to the new location. */ - - memcpy(*out_buf, in_buf, len); - - /* Insert the new header. */ - - memcpy(*out_buf, HEADER, strlen(HEADER)); - - /* Return the new len. It hasn't changed, so it's just len. */ - - return len; - -} - -/* Gets called afterwards */ -void afl_custom_deinit(post_state_t *data) { - - free(data->buf); - free(data); - -} - diff --git a/examples/custom_mutators/post_library_png.so.c b/examples/custom_mutators/post_library_png.so.c deleted file mode 100644 index 941f7e55..00000000 --- a/examples/custom_mutators/post_library_png.so.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - american fuzzy lop++ - postprocessor for PNG - ------------------------------------------ - - Originally written by Michal Zalewski - - Copyright 2015 Google Inc. All rights reserved. - Adapted to the new API, 2020 by Dominik Maier - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at: - - http://www.apache.org/licenses/LICENSE-2.0 - - See post_library.so.c for a general discussion of how to implement - postprocessors. This specific postprocessor attempts to fix up PNG - checksums, providing a slightly more complicated example than found - in post_library.so.c. - - Compile with: - - gcc -shared -Wall -O3 post_library_png.so.c -o post_library_png.so -lz - - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <zlib.h> - -#include <arpa/inet.h> - -/* A macro to round an integer up to 4 kB. */ - -#define UP4K(_i) ((((_i) >> 12) + 1) << 12) - -typedef struct post_state { - - unsigned char *buf; - size_t size; - -} post_state_t; - -void *afl_custom_init(void *afl) { - - post_state_t *state = malloc(sizeof(post_state_t)); - if (!state) { - - perror("malloc"); - return NULL; - - } - - state->buf = calloc(sizeof(unsigned char), 4096); - if (!state->buf) { - - free(state); - perror("calloc"); - return NULL; - - } - - return state; - -} - -size_t afl_custom_post_process(post_state_t *data, const unsigned char *in_buf, - unsigned int len, - const unsigned char **out_buf) { - - unsigned char *new_buf = (unsigned char *)in_buf; - unsigned int pos = 8; - - /* Don't do anything if there's not enough room for the PNG header - (8 bytes). */ - - if (len < 8) { - - *out_buf = in_buf; - return len; - - } - - /* Minimum size of a zero-length PNG chunk is 12 bytes; if we - don't have that, we can bail out. */ - - while (pos + 12 <= len) { - - unsigned int chunk_len, real_cksum, file_cksum; - - /* Chunk length is the first big-endian dword in the chunk. */ - - chunk_len = ntohl(*(uint32_t *)(in_buf + pos)); - - /* Bail out if chunk size is too big or goes past EOF. */ - - if (chunk_len > 1024 * 1024 || pos + 12 + chunk_len > len) break; - - /* Chunk checksum is calculated for chunk ID (dword) and the actual - payload. */ - - real_cksum = htonl(crc32(0, in_buf + pos + 4, chunk_len + 4)); - - /* The in-file checksum is the last dword past the chunk data. */ - - file_cksum = *(uint32_t *)(in_buf + pos + 8 + chunk_len); - - /* If the checksums do not match, we need to fix the file. */ - - if (real_cksum != file_cksum) { - - /* First modification? Make a copy of the input buffer. Round size - up to 4 kB to minimize the number of reallocs needed. */ - - if (new_buf == in_buf) { - - if (len <= data->size) { - - new_buf = data->buf; - - } else { - - new_buf = realloc(data->buf, UP4K(len)); - if (!new_buf) { - - *out_buf = in_buf; - return len; - - } - - data->buf = new_buf; - data->size = UP4K(len); - memcpy(new_buf, in_buf, len); - - } - - } - - *(uint32_t *)(new_buf + pos + 8 + chunk_len) = real_cksum; - - } - - /* Skip the entire chunk and move to the next one. */ - - pos += 12 + chunk_len; - - } - - *out_buf = new_buf; - return len; - -} - -/* Gets called afterwards */ -void afl_custom_deinit(post_state_t *data) { - - free(data->buf); - free(data); - -} - diff --git a/examples/custom_mutators/simple-chunk-replace.py b/examples/custom_mutators/simple-chunk-replace.py deleted file mode 100644 index df2f4ca7..00000000 --- a/examples/custom_mutators/simple-chunk-replace.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -''' -Simple Chunk Cross-Over Replacement Module for AFLFuzz - -@author: Christian Holler (:decoder) - -@license: - -This Source Code Form is subject to the terms of the Mozilla Public -License, v. 2.0. If a copy of the MPL was not distributed with this -file, You can obtain one at http://mozilla.org/MPL/2.0/. - -@contact: choller@mozilla.com -''' - -import random - - -def init(seed): - ''' - Called once when AFLFuzz starts up. Used to seed our RNG. - - @type seed: int - @param seed: A 32-bit random value - ''' - # Seed our RNG - random.seed(seed) - - -def fuzz(buf, add_buf, max_size): - ''' - Called per fuzzing iteration. - - @type buf: bytearray - @param buf: The buffer that should be mutated. - - @type add_buf: bytearray - @param add_buf: A second buffer that can be used as mutation source. - - @type max_size: int - @param max_size: Maximum size of the mutated output. The mutation must not - produce data larger than max_size. - - @rtype: bytearray - @return: A new bytearray containing the mutated data - ''' - # Make a copy of our input buffer for returning - ret = bytearray(buf) - - # Take a random fragment length between 2 and 32 (or less if add_buf is shorter) - fragment_len = random.randint(1, min(len(add_buf), 32)) - - # Determine a random source index where to take the data chunk from - rand_src_idx = random.randint(0, len(add_buf) - fragment_len) - - # Determine a random destination index where to put the data chunk - rand_dst_idx = random.randint(0, len(buf)) - - # Make the chunk replacement - ret[rand_dst_idx:rand_dst_idx + fragment_len] = add_buf[rand_src_idx:rand_src_idx + fragment_len] - - # Return data - return ret diff --git a/examples/custom_mutators/simple_example.c b/examples/custom_mutators/simple_example.c deleted file mode 100644 index d888ec1f..00000000 --- a/examples/custom_mutators/simple_example.c +++ /dev/null @@ -1,74 +0,0 @@ -// This simple example just creates random buffer <= 100 filled with 'A' -// needs -I /path/to/AFLplusplus/include -#include "custom_mutator_helpers.h" - -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -#ifndef _FIXED_CHAR - #define _FIXED_CHAR 0x41 -#endif - -typedef struct my_mutator { - - afl_t *afl; - - // Reused buffers: - BUF_VAR(u8, fuzz); - -} my_mutator_t; - -my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) { - - srand(seed); - my_mutator_t *data = calloc(1, sizeof(my_mutator_t)); - if (!data) { - - perror("afl_custom_init alloc"); - return NULL; - - } - - data->afl = afl; - - return data; - -} - -size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, - u8 **out_buf, uint8_t *add_buf, - size_t add_buf_size, // add_buf can be NULL - size_t max_size) { - - int size = (rand() % 100) + 1; - if (size > max_size) size = max_size; - u8 *mutated_out = maybe_grow(BUF_PARAMS(data, fuzz), size); - if (!mutated_out) { - - *out_buf = NULL; - perror("custom mutator allocation (maybe_grow)"); - return 0; /* afl-fuzz will very likely error out after this. */ - - } - - memset(mutated_out, _FIXED_CHAR, size); - - *out_buf = mutated_out; - return size; - -} - -/** - * Deinitialize everything - * - * @param data The data ptr from afl_custom_init - */ -void afl_custom_deinit(my_mutator_t *data) { - - free(data->fuzz_buf); - free(data); - -} - diff --git a/examples/custom_mutators/wrapper_afl_min.py b/examples/custom_mutators/wrapper_afl_min.py deleted file mode 100644 index ecb03b55..00000000 --- a/examples/custom_mutators/wrapper_afl_min.py +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/bin/env python - -from XmlMutatorMin import XmlMutatorMin - -# Default settings (production mode) - -__mutator__ = None -__seed__ = "RANDOM" -__log__ = False -__log_file__ = "wrapper.log" - - -# AFL functions -def log(text): - """ - Logger - """ - - global __seed__ - global __log__ - global __log_file__ - - if __log__: - with open(__log_file__, "a") as logf: - logf.write("[%s] %s\n" % (__seed__, text)) - - -def init(seed): - """ - Called once when AFL starts up. Seed is used to identify the AFL instance in log files - """ - - global __mutator__ - global __seed__ - - # Get the seed - __seed__ = seed - - # Create a global mutation class - try: - __mutator__ = XmlMutatorMin(__seed__, verbose=__log__) - log("init(): Mutator created") - except RuntimeError as e: - log("init(): Can't create mutator: %s" % e.message) - - -def fuzz(buf, add_buf, max_size): - """ - Called for each fuzzing iteration. - """ - - global __mutator__ - - # Do we have a working mutator object? - if __mutator__ is None: - log("fuzz(): Can't fuzz, no mutator available") - return buf - - # Try to use the AFL buffer - via_buffer = True - - # Interpret the AFL buffer (an array of bytes) as a string - if via_buffer: - try: - buf_str = str(buf) - log("fuzz(): AFL buffer converted to a string") - except Exception: - via_buffer = False - log("fuzz(): Can't convert AFL buffer to a string") - - # Load XML from the AFL string - if via_buffer: - try: - __mutator__.init_from_string(buf_str) - log("fuzz(): Mutator successfully initialized with AFL buffer (%d bytes)" % len(buf_str)) - except Exception: - via_buffer = False - log("fuzz(): Can't initialize mutator with AFL buffer") - - # If init from AFL buffer wasn't succesful - if not via_buffer: - log("fuzz(): Returning unmodified AFL buffer") - return buf - - # Sucessful initialization -> mutate - try: - __mutator__.mutate(max=5) - log("fuzz(): Input mutated") - except Exception: - log("fuzz(): Can't mutate input => returning buf") - return buf - - # Convert mutated data to a array of bytes - try: - data = bytearray(__mutator__.save_to_string()) - log("fuzz(): Mutated data converted as bytes") - except Exception: - log("fuzz(): Can't convert mutated data to bytes => returning buf") - return buf - - # Everything went fine, returning mutated content - log("fuzz(): Returning %d bytes" % len(data)) - return data - - -# Main (for debug) -if __name__ == '__main__': - - __log__ = True - __log_file__ = "/dev/stdout" - __seed__ = "RANDOM" - - init(__seed__) - - in_1 = bytearray("<foo ddd='eeee'>ffff<a b='c' d='456' eee='ffffff'>zzzzzzzzzzzz</a><b yyy='YYY' zzz='ZZZ'></b></foo>") - in_2 = bytearray("<abc abc123='456' abcCBA='ppppppppppppppppppppppppppppp'/>") - out = fuzz(in_1, in_2) - print(out) diff --git a/examples/defork/Makefile b/examples/defork/Makefile deleted file mode 100644 index e8240dba..00000000 --- a/examples/defork/Makefile +++ /dev/null @@ -1,64 +0,0 @@ -# -# american fuzzy lop++ - defork -# ---------------------------------- -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# - -.PHONY: all install clean - -PREFIX ?= /usr/local -BIN_PATH = $(PREFIX)/bin -HELPER_PATH = $(PREFIX)/lib/afl - -CFLAGS = -fPIC -Wall -Wextra -LDFLAGS = -shared - -UNAME_SAYS_LINUX=$(shell uname | grep -E '^Linux|^GNU' >/dev/null; echo $$?) -UNAME_SAYS_LINUX:sh=uname | grep -E '^Linux|^GNU' >/dev/null; echo $$? - -_LDFLAGS_ADD=$(UNAME_SAYS_LINUX:1=) -LDFLAGS_ADD=$(_LDFLAGS_ADD:0=-ldl) -LDFLAGS += $(LDFLAGS_ADD) - -# on gcc for arm there is no -m32, but -mbe32 -M32FLAG = -m32 -M64FLAG = -m64 - -CC_IS_GCC=$(shell $(CC) --version 2>/dev/null | grep -q gcc; echo $$?) -CC_IS_GCC:sh=$(CC) --version 2>/dev/null | grep -q gcc; echo $$? -CC_IS_ARMCOMPILER=$(shell $(CC) -v 2>&1 >/dev/null | grep -q arm; echo $$?) -CC_IS_ARMCOMPILER:sh=$(CC) -v 2>&1 >/dev/null | grep -q arm; echo $$? - -_M32FLAG=$(CC_IS_GCC)$(CC_IS_ARMCOMPILER) -__M32FLAG=$(_M32FLAG:00=-mbe32) -___M32FLAG=$(__M32FLAG:$(CC_IS_GCC)$(CC_IS_ARMCOMPILER)=-m32) -M32FLAG=$(___M32FLAG) -#ifeq "$(findstring clang, $(shell $(CC) --version 2>/dev/null))" "" -# ifneq (,$(findstring arm, "$(shell $(CC) -v 2>&1 >/dev/null)")) -# M32FLAG = -mbe32 -# endif -#endif - -all: defork32.so defork64.so - -defork32.so: defork.c - -@$(CC) $(M32FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ 2>/dev/null || echo "defork32 build failure (that's fine)" - -defork64.so: defork.c - -@$(CC) $(M64FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ 2>/dev/null || echo "defork64 build failure (that's fine)" - -install: defork32.so defork64.so - install -d -m 755 $(DESTDIR)$(HELPER_PATH)/ - if [ -f defork32.so ]; then set -e; install -m 755 defork32.so $(DESTDIR)$(HELPER_PATH)/; fi - if [ -f defork64.so ]; then set -e; install -m 755 defork64.so $(DESTDIR)$(HELPER_PATH)/; fi - -target: - ../../afl-clang forking_target.c -o forking_target -Wall -Wextra -Werror - -clean: - rm -f defork32.so defork64.so forking_target diff --git a/examples/defork/README.md b/examples/defork/README.md deleted file mode 100644 index 7e950323..00000000 --- a/examples/defork/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# defork - -when the target forks, this breaks all normal fuzzing runs. -Sometimes, though, it is enough to just run the child process. -If this is the case, then this LD_PRELOAD library will always return 0 on fork, -the target will belive it is running as the child, post-fork. - -This is defork.c from the amazing preeny project -https://github.com/zardus/preeny - -It is altered for afl++ to work with its fork-server: the initial fork will go through, the second fork will be blocked. diff --git a/examples/defork/defork.c b/examples/defork/defork.c deleted file mode 100644 index f71d1124..00000000 --- a/examples/defork/defork.c +++ /dev/null @@ -1,50 +0,0 @@ -#define __GNU_SOURCE -#include <dlfcn.h> -#include <unistd.h> -#include <stdio.h> -#include <stdbool.h> - -#include "../../include/config.h" - -/* we want to fork once (for the afl++ forkserver), - then immediately return as child on subsequent forks. */ -static bool forked = 0; - -pid_t (*original_fork)(void); - -/* In case we are not running in afl, we use a dummy original_fork */ -static pid_t nop(void) { - - return 0; - -} - -__attribute__((constructor)) void preeny_fork_orig() { - - if (getenv(SHM_ENV_VAR)) { - - printf("defork: running in AFL++. Allowing forkserver.\n"); - original_fork = dlsym(RTLD_NEXT, "socket"); - - } else { - - printf("defork: no AFL++ detected. Disabling fork from the start.\n"); - original_fork = &nop; - - } - -} - -pid_t fork(void) { - - /* If we forked before, or if we're in the child (pid==0), - we don't want to fork anymore, else, we are still in the forkserver. - The forkserver parent needs to fork infinite times, each child should never - fork again. This can be written without branches and I hate myself for it. - */ - pid_t ret = !forked && original_fork(); - forked = !ret; - return ret; - -} - diff --git a/examples/defork/forking_target.c b/examples/defork/forking_target.c deleted file mode 100644 index 628d23c9..00000000 --- a/examples/defork/forking_target.c +++ /dev/null @@ -1,49 +0,0 @@ -#include <stdio.h> -#include <unistd.h> -#include <stdint.h> -#include <sys/types.h> - -/* This is an example target for defork.c - fuzz using -``` -mkdir in; echo a > ./in/a -AFL_PRELOAD=./defork64.so ../../afl-fuzz -i in -o out -- ./forking_target @@ -``` -*/ - -int main(int argc, char **argv) { - - if (argc < 2) { - - printf("Example tool to test defork.\nUsage ./forking_target <input>\n"); - return -1; - - } - - pid_t pid = fork(); - if (pid == 0) { - - printf("We're in the child.\n"); - 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; - - } else if (pid < 0) { - - perror("fork"); - return -1; - - } else { - - printf("We are in the parent - defork didn't work! :( (pid=%d)\n", - (int)pid); - - } - - return 0; - -} - diff --git a/examples/distributed_fuzzing/sync_script.sh b/examples/distributed_fuzzing/sync_script.sh deleted file mode 100755 index b28ff6cd..00000000 --- a/examples/distributed_fuzzing/sync_script.sh +++ /dev/null @@ -1,97 +0,0 @@ -#!/bin/sh -# -# american fuzzy lop++ - fuzzer synchronization tool -# -------------------------------------------------- -# -# Originally written by Michal Zalewski -# -# Copyright 2014 Google Inc. All rights reserved. -# Copyright 2019-2020 AFLplusplus Project. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# To make this script work: -# -# - Edit FUZZ_HOSTS, FUZZ_DOMAIN, FUZZ_USER, and SYNC_DIR to reflect your -# environment. -# -# - Make sure that the system you are running this on can log into FUZZ_HOSTS -# without a password (authorized_keys or otherwise). -# -# - Make sure that every fuzzer is running with -o pointing to SYNC_DIR and -S -# that consists of its local host name, followed by an underscore, and then -# by some host-local fuzzer ID. -# - -# Hosts to synchronize the data across. -FUZZ_HOSTS='host1 host2 host3 host4' - -# Domain for all hosts -FUZZ_DOMAIN='example.com' - -# Remote user for SSH -FUZZ_USER=bob - -# Directory to synchronize -SYNC_DIR='/home/bob/sync_dir' - -# We only capture -M main nodes, set the name to your chosen naming scheme -MAIN_NAME='main' - -# Interval (seconds) between sync attempts (eg one hour) -SYNC_INTERVAL=$((60 * 60)) - -if [ "$AFL_ALLOW_TMP" = "" ]; then - - if [ "$PWD" = "/tmp" -o "$PWD" = "/var/tmp" ]; then - echo "[-] Error: do not use shared /tmp or /var/tmp directories with this script." 1>&2 - exit 1 - fi - -fi - -rm -rf .sync_tmp 2>/dev/null -mkdir .sync_tmp || exit 1 - -while :; do - - # Pull data in... - - for host in $FUZZ_HOSTS; do - - echo "[*] Retrieving data from ${host}.${FUZZ_DOMAIN}..." - - ssh -o 'passwordauthentication no' ${FUZZ_USER}@${host}.$FUZZ_DOMAIN \ - "cd '$SYNC_DIR' && tar -czf - ${host}_${MAIN_NAME}*/" > ".sync_tmp/${host}.tgz" - - done - - # Distribute data. For large fleets, see tips in the docs/ directory. - - for dst_host in $FUZZ_HOSTS; do - - echo "[*] Distributing data to ${dst_host}.${FUZZ_DOMAIN}..." - - for src_host in $FUZZ_HOSTS; do - - test "$src_host" = "$dst_host" && continue - - echo " Sending fuzzer data from ${src_host}.${FUZZ_DOMAIN}..." - - ssh -o 'passwordauthentication no' ${FUZZ_USER}@$dst_host \ - "cd '$SYNC_DIR' && tar -xkzf - " < ".sync_tmp/${src_host}.tgz" - - done - - done - - echo "[+] Done. Sleeping for $SYNC_INTERVAL seconds (Ctrl-C to quit)." - - sleep $SYNC_INTERVAL - -done - diff --git a/examples/libpng_no_checksum/libpng-nocrc.patch b/examples/libpng_no_checksum/libpng-nocrc.patch deleted file mode 100644 index 0a3793a0..00000000 --- a/examples/libpng_no_checksum/libpng-nocrc.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- pngrutil.c.orig 2014-06-12 03:35:16.000000000 +0200 -+++ pngrutil.c 2014-07-01 05:08:31.000000000 +0200 -@@ -268,7 +268,11 @@ - if (need_crc != 0) - { - crc = png_get_uint_32(crc_bytes); -- return ((int)(crc != png_ptr->crc)); -+ -+ if (crc != png_ptr->crc) -+ fprintf(stderr, "NOTE: CRC in the file is 0x%08x, change to 0x%08x\n", crc, png_ptr->crc); -+ -+ return ((int)(1 != 1)); - } - - else diff --git a/examples/persistent_mode/Makefile b/examples/persistent_mode/Makefile deleted file mode 100644 index 6fa1c30e..00000000 --- a/examples/persistent_mode/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -all: - afl-clang-fast -o persistent_demo persistent_demo.c - afl-clang-fast -o persistent_demo_new persistent_demo_new.c - AFL_DONT_OPTIMIZE=1 afl-clang-fast -o test-instr test-instr.c - -document: - AFL_DONT_OPTIMIZE=1 afl-clang-fast -D_AFL_DOCUMENT_MUTATIONS -o test-instr test-instr.c - -clean: - rm -f persistent_demo persistent_demo_new test-instr diff --git a/examples/persistent_mode/persistent_demo.c b/examples/persistent_mode/persistent_demo.c deleted file mode 100644 index 4cedc32c..00000000 --- a/examples/persistent_mode/persistent_demo.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - american fuzzy lop++ - persistent mode example - -------------------------------------------- - - Originally written by Michal Zalewski - - Copyright 2015 Google Inc. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at: - - http://www.apache.org/licenses/LICENSE-2.0 - - This file demonstrates the high-performance "persistent mode" that may be - suitable for fuzzing certain fast and well-behaved libraries, provided that - they are stateless or that their internal state can be easily reset - across runs. - - To make this work, the library and this shim need to be compiled in LLVM - mode using afl-clang-fast (other compiler wrappers will *not* work). - - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <signal.h> -#include <string.h> - -/* Main entry point. */ - -int main(int argc, char **argv) { - - ssize_t len; /* how much input did we read? */ - char buf[100]; /* Example-only buffer, you'd replace it with other global or - local variables appropriate for your use case. */ - - /* The number passed to __AFL_LOOP() controls the maximum number of - iterations before the loop exits and the program is allowed to - terminate normally. This limits the impact of accidental memory leaks - and similar hiccups. */ - - __AFL_INIT(); - while (__AFL_LOOP(1000)) { - - /*** PLACEHOLDER CODE ***/ - - /* STEP 1: Fully re-initialize all critical variables. In our example, this - involves zeroing buf[], our input buffer. */ - - memset(buf, 0, 100); - - /* STEP 2: Read input data. When reading from stdin, no special preparation - is required. When reading from a named file, you need to close - the old descriptor and reopen the file first! - - Beware of reading from buffered FILE* objects such as stdin. Use - raw file descriptors or call fopen() / fdopen() in every pass. */ - - len = read(0, buf, 100); - - /* STEP 3: This is where we'd call the tested library on the read data. - We just have some trivial inline code that faults on 'foo!'. */ - - /* do we have enough data? */ - if (len < 8) continue; - - if (buf[0] == 'f') { - - printf("one\n"); - if (buf[1] == 'o') { - - printf("two\n"); - if (buf[2] == 'o') { - - printf("three\n"); - if (buf[3] == '!') { - - printf("four\n"); - if (buf[4] == '!') { - - printf("five\n"); - if (buf[5] == '!') { - - printf("six\n"); - abort(); - - } - - } - - } - - } - - } - - } - - /*** END PLACEHOLDER CODE ***/ - - } - - /* Once the loop is exited, terminate normally - AFL will restart the process - when this happens, with a clean slate when it comes to allocated memory, - leftover file descriptors, etc. */ - - return 0; - -} - diff --git a/examples/persistent_mode/persistent_demo_new.c b/examples/persistent_mode/persistent_demo_new.c deleted file mode 100644 index a29792ff..00000000 --- a/examples/persistent_mode/persistent_demo_new.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - american fuzzy lop++ - persistent mode example - -------------------------------------------- - - Originally written by Michal Zalewski - - Copyright 2015 Google Inc. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at: - - http://www.apache.org/licenses/LICENSE-2.0 - - This file demonstrates the high-performance "persistent mode" that may be - suitable for fuzzing certain fast and well-behaved libraries, provided that - they are stateless or that their internal state can be easily reset - across runs. - - To make this work, the library and this shim need to be compiled in LLVM - mode using afl-clang-fast (other compiler wrappers will *not* work). - - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <signal.h> -#include <string.h> - -/* this lets the source compile without afl-clang-fast/lto */ -#ifndef __AFL_FUZZ_TESTCASE_LEN - -ssize_t fuzz_len; -unsigned char fuzz_buf[1024000]; - - #define __AFL_FUZZ_TESTCASE_LEN fuzz_len - #define __AFL_FUZZ_TESTCASE_BUF fuzz_buf - #define __AFL_FUZZ_INIT() void sync(void); - #define __AFL_LOOP(x) \ - ((fuzz_len = read(0, fuzz_buf, sizeof(fuzz_buf))) > 0 ? 1 : 0) - #define __AFL_INIT() sync() - -#endif - -__AFL_FUZZ_INIT(); - -/* Main entry point. */ - -int main(int argc, char **argv) { - - ssize_t len; /* how much input did we read? */ - unsigned char *buf; /* test case buffer pointer */ - - /* The number passed to __AFL_LOOP() controls the maximum number of - iterations before the loop exits and the program is allowed to - terminate normally. This limits the impact of accidental memory leaks - and similar hiccups. */ - - __AFL_INIT(); - buf = __AFL_FUZZ_TESTCASE_BUF; // this must be assigned before __AFL_LOOP! - - while (__AFL_LOOP(1000)) { // increase if you have good stability - - len = __AFL_FUZZ_TESTCASE_LEN; // do not use the macro directly in a call! - - fprintf(stderr, "input: %zd \"%s\"\n", len, buf); - - /* do we have enough data? */ - if (len < 8) continue; - - if (strcmp((char *)buf, "thisisateststring") == 0) printf("teststring\n"); - - if (buf[0] == 'f') { - - printf("one\n"); - if (buf[1] == 'o') { - - printf("two\n"); - if (buf[2] == 'o') { - - printf("three\n"); - if (buf[3] == '!') { - - printf("four\n"); - if (buf[4] == '!') { - - printf("five\n"); - if (buf[6] == '!') { - - printf("six\n"); - abort(); - - } - - } - - } - - } - - } - - } - - /*** END PLACEHOLDER CODE ***/ - - } - - /* Once the loop is exited, terminate normally - AFL will restart the process - when this happens, with a clean slate when it comes to allocated memory, - leftover file descriptors, etc. */ - - return 0; - -} - diff --git a/examples/persistent_mode/test-instr.c b/examples/persistent_mode/test-instr.c deleted file mode 100644 index a6188b22..00000000 --- a/examples/persistent_mode/test-instr.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - american fuzzy lop++ - a trivial program to test the build - -------------------------------------------------------- - Originally written by Michal Zalewski - Copyright 2014 Google Inc. All rights reserved. - Copyright 2019-2020 AFLplusplus Project. All rights reserved. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at: - http://www.apache.org/licenses/LICENSE-2.0 - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - -__AFL_FUZZ_INIT(); - -int main(int argc, char **argv) { - - __AFL_INIT(); - unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF; - - while (__AFL_LOOP(2147483647)) { // MAX_INT if you have 100% stability - - unsigned int len = __AFL_FUZZ_TESTCASE_LEN; - -#ifdef _AFL_DOCUMENT_MUTATIONS - static unsigned int counter = 0; - char fn[32]; - sprintf(fn, "%09u:test-instr", counter); - int fd_doc = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600); - if (fd_doc >= 0) { - - if (write(fd_doc, buf, len) != __afl_fuzz_len) { - - fprintf(stderr, "write of mutation file failed: %s\n", fn); - unlink(fn); - - } - - close(fd_doc); - - } - - counter++; -#endif - - // fprintf(stderr, "len: %u\n", len); - - if (!len) continue; - - if (buf[0] == '0') - printf("Looks like a zero to me!\n"); - else if (buf[0] == '1') - printf("Pretty sure that is a one!\n"); - else - printf("Neither one or zero? How quaint!\n"); - - } - - return 0; - -} - diff --git a/examples/qemu_persistent_hook/Makefile b/examples/qemu_persistent_hook/Makefile deleted file mode 100644 index 85db1b46..00000000 --- a/examples/qemu_persistent_hook/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -all: - $(CC) -no-pie test.c -o test - $(CC) -fPIC -shared read_into_rdi.c -o read_into_rdi.so - -clean: - rm -rf in out test read_into_rdi.so diff --git a/examples/qemu_persistent_hook/README.md b/examples/qemu_persistent_hook/README.md deleted file mode 100644 index 3f908c22..00000000 --- a/examples/qemu_persistent_hook/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# QEMU persistent hook example - -Compile the test binary and the library: - -``` -make -``` - -Fuzz with: - -``` -export AFL_QEMU_PERSISTENT_ADDR=0x$(nm test | grep "T target_func" | awk '{print $1}') -export AFL_QEMU_PERSISTENT_HOOK=./read_into_rdi.so - -mkdir in -echo 0000 > in/in - -../../afl-fuzz -Q -i in -o out -- ./test -``` diff --git a/examples/qemu_persistent_hook/read_into_rdi.c b/examples/qemu_persistent_hook/read_into_rdi.c deleted file mode 100644 index f4a8ae59..00000000 --- a/examples/qemu_persistent_hook/read_into_rdi.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "../../qemu_mode/qemuafl/qemuafl/api.h" - -#include <stdio.h> -#include <string.h> - -void afl_persistent_hook(struct x86_64_regs *regs, uint64_t guest_base, - uint8_t *input_buf, uint32_t input_buf_len) { -\ -#define g2h(x) ((void *)((unsigned long)(x) + guest_base)) -#define h2g(x) ((uint64_t)(x)-guest_base) - - // In this example the register RDI is pointing to the memory location - // of the target buffer, and the length of the input is in RSI. - // This can be seen with a debugger, e.g. gdb (and "disass main") - - printf("Placing input into 0x%lx\n", regs->rdi); - - if (input_buf_len > 1024) input_buf_len = 1024; - memcpy(g2h(regs->rdi), input_buf, input_buf_len); - regs->rsi = input_buf_len; - -#undef g2h -#undef h2g - -} - -int afl_persistent_hook_init(void) { - - // 1 for shared memory input (faster), 0 for normal input (you have to use - // read(), input_buf will be NULL) - return 1; - -} - diff --git a/examples/qemu_persistent_hook/test.c b/examples/qemu_persistent_hook/test.c deleted file mode 100644 index afeff202..00000000 --- a/examples/qemu_persistent_hook/test.c +++ /dev/null @@ -1,35 +0,0 @@ -#include <stdio.h> - -int target_func(unsigned char *buf, int size) { - - printf("buffer:%p, size:%p\n", buf, size); - switch (buf[0]) { - - case 1: - if (buf[1] == '\x44') { puts("a"); } - break; - case 0xff: - if (buf[2] == '\xff') { - - if (buf[1] == '\x44') { puts("b"); } - - } - - break; - default: - break; - - } - - return 1; - -} - -char data[1024]; - -int main() { - - target_func(data, 1024); - -} - diff --git a/examples/socket_fuzzing/Makefile b/examples/socket_fuzzing/Makefile deleted file mode 100644 index 9476e2d5..00000000 --- a/examples/socket_fuzzing/Makefile +++ /dev/null @@ -1,61 +0,0 @@ -# -# american fuzzy lop++ - socket_fuzz -# ---------------------------------- -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# - -.PHONY: all install clean - -PREFIX ?= /usr/local -BIN_PATH = $(PREFIX)/bin -HELPER_PATH = $(PREFIX)/lib/afl - -CFLAGS = -fPIC -Wall -Wextra -LDFLAGS = -shared - -UNAME_SAYS_LINUX=$(shell uname | grep -E '^Linux|^GNU' >/dev/null; echo $$?) -UNAME_SAYS_LINUX:sh=uname | grep -E '^Linux|^GNU' >/dev/null; echo $$? - -_LDFLAGS_ADD=$(UNAME_SAYS_LINUX:1=) -LDFLAGS_ADD=$(_LDFLAGS_ADD:0=-ldl) -LDFLAGS += $(LDFLAGS_ADD) - -# on gcc for arm there is no -m32, but -mbe32 -M32FLAG = -m32 -M64FLAG = -m64 - -CC_IS_GCC=$(shell $(CC) --version 2>/dev/null | grep -q gcc; echo $$?) -CC_IS_GCC:sh=$(CC) --version 2>/dev/null | grep -q gcc; echo $$? -CC_IS_ARMCOMPILER=$(shell $(CC) -v 2>&1 >/dev/null | grep -q arm; echo $$?) -CC_IS_ARMCOMPILER:sh=$(CC) -v 2>&1 >/dev/null | grep -q arm; echo $$? - -_M32FLAG=$(CC_IS_GCC)$(CC_IS_ARMCOMPILER) -__M32FLAG=$(_M32FLAG:00=-mbe32) -___M32FLAG=$(__M32FLAG:$(CC_IS_GCC)$(CC_IS_ARMCOMPILER)=-m32) -M32FLAG=$(___M32FLAG) -#ifeq "$(findstring clang, $(shell $(CC) --version 2>/dev/null))" "" -# ifneq (,$(findstring arm, "$(shell $(CC) -v 2>&1 >/dev/null)")) -# M32FLAG = -mbe32 -# endif -#endif - -all: socketfuzz32.so socketfuzz64.so - -socketfuzz32.so: socketfuzz.c - -@$(CC) $(M32FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ 2>/dev/null || echo "socketfuzz32 build failure (that's fine)" - -socketfuzz64.so: socketfuzz.c - -@$(CC) $(M64FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ 2>/dev/null || echo "socketfuzz64 build failure (that's fine)" - -install: socketfuzz32.so socketfuzz64.so - install -d -m 755 $(DESTDIR)$(HELPER_PATH)/ - if [ -f socketfuzz32.so ]; then set -e; install -m 755 socketfuzz32.so $(DESTDIR)$(HELPER_PATH)/; fi - if [ -f socketfuzz64.so ]; then set -e; install -m 755 socketfuzz64.so $(DESTDIR)$(HELPER_PATH)/; fi - -clean: - rm -f socketfuzz32.so socketfuzz64.so diff --git a/examples/socket_fuzzing/README.md b/examples/socket_fuzzing/README.md deleted file mode 100644 index 79f28bea..00000000 --- a/examples/socket_fuzzing/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# socketfuzz - -when you want to fuzz a network service and you can not/do not want to modify -the source (or just have a binary), then this LD_PRELOAD library will allow -for sending input to stdin which the target binary will think is coming from -a network socket. - -This is desock_dup.c from the amazing preeny project -https://github.com/zardus/preeny - -It is packaged in afl++ to have it at hand if needed diff --git a/examples/socket_fuzzing/socketfuzz.c b/examples/socket_fuzzing/socketfuzz.c deleted file mode 100644 index 3ec8383b..00000000 --- a/examples/socket_fuzzing/socketfuzz.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * This is desock_dup.c from the amazing preeny project - * https://github.com/zardus/preeny - * - * It is packaged in afl++ to have it at hand if needed - * - */ - -#define _GNU_SOURCE - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <sys/types.h> // -#include <sys/socket.h> // -#include <sys/stat.h> // -#include <fcntl.h> // -#include <netinet/in.h> -#include <pthread.h> -#include <signal.h> -#include <dlfcn.h> -#include <errno.h> -#include <stdio.h> -#include <poll.h> -//#include "logging.h" // switche from preeny_info() to fprintf(stderr, "Info: " - -// -// originals -// -int (*original_close)(int); -int (*original_dup2)(int, int); -__attribute__((constructor)) void preeny_desock_dup_orig() { - - original_close = dlsym(RTLD_NEXT, "close"); - original_dup2 = dlsym(RTLD_NEXT, "dup2"); - -} - -int close(int sockfd) { - - if (sockfd <= 2) { - - fprintf(stderr, "Info: Disabling close on %d\n", sockfd); - return 0; - - } else { - - return original_close(sockfd); - - } - -} - -int dup2(int old, int new) { - - if (new <= 2) { - - fprintf(stderr, "Info: Disabling dup from %d to %d\n", old, new); - return 0; - - } else { - - return original_dup2(old, new); - - } - -} - -int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { - - (void)sockfd; - (void)addr; - (void)addrlen; - fprintf(stderr, "Info: Emulating accept on %d\n", sockfd); - return 0; - -} - -int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { - - (void)sockfd; - (void)addr; - (void)addrlen; - fprintf(stderr, "Info: Emulating bind on port %d\n", - ntohs(((struct sockaddr_in *)addr)->sin_port)); - return 0; - -} - -int listen(int sockfd, int backlog) { - - (void)sockfd; - (void)backlog; - return 0; - -} - -int setsockopt(int sockfd, int level, int optid, const void *optdata, - socklen_t optdatalen) { - - (void)sockfd; - (void)level; - (void)optid; - (void)optdata; - (void)optdatalen; - return 0; - -} - |