From 06264df16891070a09a31cd981a9dcaaf01de7c7 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 30 Jun 2020 17:28:21 +0200 Subject: rename whitelist -> instrumentlist --- src/afl-fuzz.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/afl-fuzz.c') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index f25f8bb6..7580caad 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -790,8 +790,8 @@ int main(int argc, char **argv_orig, char **envp) { OKF("afl++ is open source, get it at " "https://github.com/AFLplusplus/AFLplusplus"); OKF("Power schedules from github.com/mboehme/aflfast"); - OKF("Python Mutator and llvm_mode whitelisting from github.com/choller/afl"); - OKF("afl-tmin fork server patch from github.com/nccgroup/TriforceAFL"); + OKF("Python Mutator and llvm_mode instrument file list from " + "github.com/choller/afl"); OKF("MOpt Mutator from github.com/puppet-meteor/MOpt-AFL"); if (afl->sync_id && afl->is_main_node && -- cgit 1.4.1 From 7527c76c7446f8197b9f7acb8ca0ccd44fe7bd39 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 30 Jun 2020 17:33:47 +0200 Subject: reduce the time interval in which the secondaries sync --- include/config.h | 2 +- src/afl-fuzz.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/afl-fuzz.c') diff --git a/include/config.h b/include/config.h index 087e0a76..5ee93389 100644 --- a/include/config.h +++ b/include/config.h @@ -234,7 +234,7 @@ /* Sync interval (every n havoc cycles): */ -#define SYNC_INTERVAL 5 +#define SYNC_INTERVAL 8 /* Output directory reuse grace period (minutes): */ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 7580caad..e4e2669c 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1280,7 +1280,7 @@ int main(int argc, char **argv_orig, char **envp) { if (unlikely(afl->is_main_node)) { - if (!(sync_interval_cnt++ % (SYNC_INTERVAL / 2))) { sync_fuzzers(afl); } + if (!(sync_interval_cnt++ % (SYNC_INTERVAL / 3))) { sync_fuzzers(afl); } } else { -- cgit 1.4.1 From d8984180377fb244d43990feb7cda2d212924ab3 Mon Sep 17 00:00:00 2001 From: hexcoder Date: Wed, 1 Jul 2020 07:43:14 +0200 Subject: restore credit for afl-tmin fork server patch --- src/afl-fuzz.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/afl-fuzz.c') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index e4e2669c..15a68096 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -792,6 +792,7 @@ int main(int argc, char **argv_orig, char **envp) { OKF("Power schedules from github.com/mboehme/aflfast"); OKF("Python Mutator and llvm_mode instrument file list from " "github.com/choller/afl"); + OKF("afl-tmin fork server patch from github.com/nccgroup/TriforceAFL"); OKF("MOpt Mutator from github.com/puppet-meteor/MOpt-AFL"); if (afl->sync_id && afl->is_main_node && -- cgit 1.4.1 From 6b98157c1a235c10ed5f9fc3220aa1869ea8f3e4 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 1 Jul 2020 09:15:47 +0200 Subject: v2.66c release preparation --- README.md | 4 ++-- TODO.md | 2 +- docs/Changelog.md | 2 +- include/config.h | 2 +- src/afl-fuzz.c | 1 - 5 files changed, 5 insertions(+), 6 deletions(-) (limited to 'src/afl-fuzz.c') diff --git a/README.md b/README.md index dd32e28e..14a42b7e 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ ![Travis State](https://api.travis-ci.com/AFLplusplus/AFLplusplus.svg?branch=stable) - Release Version: [2.65c](https://github.com/AFLplusplus/AFLplusplus/releases) + Release Version: [2.66c](https://github.com/AFLplusplus/AFLplusplus/releases) - Github Version: 2.65d + Github Version: 2.66d includes all necessary/interesting changes from Google's afl 2.56b diff --git a/TODO.md b/TODO.md index 55b886e4..8085bc07 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,6 @@ # TODO list for AFL++ -## Roadmap 2.65+ +## Roadmap 2.66+ - AFL_MAP_SIZE for qemu_mode and unicorn_mode - namespace for targets? e.g. network diff --git a/docs/Changelog.md b/docs/Changelog.md index eede6751..1bf77839 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -9,7 +9,7 @@ Want to stay in the loop on major new features? Join our mailing list by sending a mail to . -### Version ++2.65d (dev) +### Version ++2.66c (release) - renamed the main branch on Github to "stable" - renamed master/slave to main/secondary - renamed blacklist/whitelist to ignorelist/instrumentlist -> diff --git a/include/config.h b/include/config.h index 5ee93389..e8f52f45 100644 --- a/include/config.h +++ b/include/config.h @@ -28,7 +28,7 @@ /* Version string: */ // c = release, d = volatile github dev, e = experimental branch -#define VERSION "++2.65d" +#define VERSION "++2.66c" /****************************************************** * * diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 15a68096..e4e2669c 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -792,7 +792,6 @@ int main(int argc, char **argv_orig, char **envp) { OKF("Power schedules from github.com/mboehme/aflfast"); OKF("Python Mutator and llvm_mode instrument file list from " "github.com/choller/afl"); - OKF("afl-tmin fork server patch from github.com/nccgroup/TriforceAFL"); OKF("MOpt Mutator from github.com/puppet-meteor/MOpt-AFL"); if (afl->sync_id && afl->is_main_node && -- cgit 1.4.1 From 83790d65afb52a055d093451a50ce55690a25002 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 8 Jul 2020 11:16:39 +0200 Subject: eliminate race condition for cpu affinity on -M/-S --- docs/Changelog.md | 4 ++- include/config.h | 4 +++ src/afl-fuzz-init.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++------- src/afl-fuzz.c | 24 +++++++------ 4 files changed, 105 insertions(+), 24 deletions(-) (limited to 'src/afl-fuzz.c') diff --git a/docs/Changelog.md b/docs/Changelog.md index 57b2b4a2..18e4e97e 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -10,7 +10,9 @@ sending a mail to . ### Version ++2.66d (devel) - - ... ? + - afl-fuzz: + - eliminated CPU affinity race condition for -S/-M runs + - small fixes to afl-plot, afl-whatsup and man page creation ### Version ++2.66c (release) diff --git a/include/config.h b/include/config.h index 7de74009..4503c3e9 100644 --- a/include/config.h +++ b/include/config.h @@ -380,6 +380,10 @@ #define CMPLOG_SHM_ENV_VAR "__AFL_CMPLOG_SHM_ID" +/* CPU Affinity lockfile env var */ + +#define CPU_AFFINITY_ENV_VAR "__AFL_LOCKFILE" + /* Uncomment this to use inferior block-coverage-based instrumentation. Note that you need to recompile the target binary for this to have any effect: */ diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index a2e849dc..e51b4729 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -36,14 +36,11 @@ void bind_to_free_cpu(afl_state_t *afl) { #if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__) cpu_set_t c; #elif defined(__NetBSD__) - cpuset_t * c; + cpuset_t *c; #elif defined(__sun) - psetid_t c; + psetid_t c; #endif - u8 cpu_used[4096] = {0}; - u32 i; - if (afl->cpu_core_count < 2) { return; } if (afl->afl_env.afl_no_affinity) { @@ -53,13 +50,46 @@ void bind_to_free_cpu(afl_state_t *afl) { } + u8 cpu_used[4096] = {0}, lockfile[PATH_MAX] = ""; + u32 i; + + if (afl->sync_id) { + + s32 lockfd, first = 1; + + snprintf(lockfile, sizeof(lockfile), "%s/.affinity_lock", afl->sync_dir); + setenv(CPU_AFFINITY_ENV_VAR, lockfile, 1); + + do { + + if ((lockfd = open(lockfile, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0) { + + if (first) { + + WARNF("CPU affinity lock file present, waiting ..."); + first = 0; + + } + + usleep(1000); + + } + + } while (lockfd < 0); + + close(lockfd); + + } + #if defined(__linux__) + DIR * d; struct dirent *de; d = opendir("/proc"); if (!d) { + if (lockfile[0]) unlink(lockfile); WARNF("Unable to access /proc - can't scan for free CPU cores."); return; @@ -67,11 +97,6 @@ void bind_to_free_cpu(afl_state_t *afl) { ACTF("Checking CPU core loadout..."); - /* Introduce some jitter, in case multiple AFL tasks are doing the same - thing at the same time... */ - - usleep(R(1000) * 250); - /* Scan all /proc//status entries, checking for Cpus_allowed_list. Flag all processes bound to a specific CPU using cpu_used[]. This will fail for some exotic binding setups, but is likely good enough in almost @@ -114,20 +139,29 @@ void bind_to_free_cpu(afl_state_t *afl) { } closedir(d); + #elif defined(__FreeBSD__) || defined(__DragonFly__) + struct kinfo_proc *procs; size_t nprocs; size_t proccount; int s_name[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL}; size_t s_name_l = sizeof(s_name) / sizeof(s_name[0]); - if (sysctl(s_name, s_name_l, NULL, &nprocs, NULL, 0) != 0) return; + if (sysctl(s_name, s_name_l, NULL, &nprocs, NULL, 0) != 0) { + + if (lockfile[0]) unlink(lockfile); + return; + + } + proccount = nprocs / sizeof(*procs); nprocs = nprocs * 4 / 3; procs = ck_alloc(nprocs); if (sysctl(s_name, s_name_l, procs, &nprocs, NULL, 0) != 0) { + if (lockfile[0]) unlink(lockfile); ck_free(procs); return; @@ -136,6 +170,7 @@ void bind_to_free_cpu(afl_state_t *afl) { for (i = 0; i < proccount; i++) { #if defined(__FreeBSD__) + if (!strcmp(procs[i].ki_comm, "idle")) continue; // fix when ki_oncpu = -1 @@ -145,16 +180,21 @@ void bind_to_free_cpu(afl_state_t *afl) { if (oncpu != -1 && oncpu < sizeof(cpu_used) && procs[i].ki_pctcpu > 60) cpu_used[oncpu] = 1; + #elif defined(__DragonFly__) + if (procs[i].kp_lwp.kl_cpuid < sizeof(cpu_used) && procs[i].kp_lwp.kl_pctcpu > 10) cpu_used[procs[i].kp_lwp.kl_cpuid] = 1; + #endif } ck_free(procs); + #elif defined(__NetBSD__) + struct kinfo_proc2 *procs; size_t nprocs; size_t proccount; @@ -163,13 +203,20 @@ void bind_to_free_cpu(afl_state_t *afl) { CTL_KERN, KERN_PROC2, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2), 0}; size_t s_name_l = sizeof(s_name) / sizeof(s_name[0]); - if (sysctl(s_name, s_name_l, NULL, &nprocs, NULL, 0) != 0) return; + if (sysctl(s_name, s_name_l, NULL, &nprocs, NULL, 0) != 0) { + + if (lockfile[0]) unlink(lockfile); + return; + + } + proccount = nprocs / sizeof(struct kinfo_proc2); procs = ck_alloc(nprocs * sizeof(struct kinfo_proc2)); s_name[5] = proccount; if (sysctl(s_name, s_name_l, procs, &nprocs, NULL, 0) != 0) { + if (lockfile[0]) unlink(lockfile); ck_free(procs); return; @@ -183,7 +230,9 @@ void bind_to_free_cpu(afl_state_t *afl) { } ck_free(procs); + #elif defined(__sun) + kstat_named_t *n; kstat_ctl_t * m; kstat_t * k; @@ -198,6 +247,7 @@ void bind_to_free_cpu(afl_state_t *afl) { if (!k) { + if (lockfile[0]) unlink(lockfile); kstat_close(m); return; @@ -205,6 +255,7 @@ void bind_to_free_cpu(afl_state_t *afl) { if (kstat_read(m, k, NULL)) { + if (lockfile[0]) unlink(lockfile); kstat_close(m); return; @@ -220,6 +271,7 @@ void bind_to_free_cpu(afl_state_t *afl) { k = kstat_lookup(m, "cpu_stat", i, NULL); if (kstat_read(m, k, &cs)) { + if (lockfile[0]) unlink(lockfile); kstat_close(m); return; @@ -233,6 +285,7 @@ void bind_to_free_cpu(afl_state_t *afl) { } kstat_close(m); + #else #warning \ "For this platform we do not have free CPU binding code yet. If possible, please supply a PR to https://github.com/AFLplusplus/AFLplusplus" @@ -241,7 +294,9 @@ void bind_to_free_cpu(afl_state_t *afl) { size_t cpu_start = 0; try: + #if !defined(__ANDROID__) + for (i = cpu_start; i < afl->cpu_core_count; i++) { if (!cpu_used[i]) { break; } @@ -251,6 +306,7 @@ void bind_to_free_cpu(afl_state_t *afl) { if (i == afl->cpu_core_count) { #else + for (i = afl->cpu_core_count - cpu_start - 1; i > -1; i--) if (!cpu_used[i]) break; if (i == -1) { @@ -274,18 +330,25 @@ void bind_to_free_cpu(afl_state_t *afl) { afl->cpu_aff = i; #if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__) + CPU_ZERO(&c); CPU_SET(i, &c); + #elif defined(__NetBSD__) + c = cpuset_create(); if (c == NULL) PFATAL("cpuset_create failed"); cpuset_set(i, c); + #elif defined(__sun) + pset_create(&c); if (pset_assign(c, i, NULL)) PFATAL("pset_assign failed"); + #endif #if defined(__linux__) + if (sched_setaffinity(0, sizeof(c), &c)) { if (cpu_start == afl->cpu_core_count) { @@ -302,6 +365,7 @@ if (pset_assign(c, i, NULL)) PFATAL("pset_assign failed"); } #elif defined(__FreeBSD__) || defined(__DragonFly__) + if (pthread_setaffinity_np(pthread_self(), sizeof(c), &c)) { if (cpu_start == afl->cpu_core_count) @@ -314,6 +378,7 @@ if (pset_assign(c, i, NULL)) PFATAL("pset_assign failed"); } #elif defined(__NetBSD__) + if (pthread_setaffinity_np(pthread_self(), cpuset_size(c), c)) { if (cpu_start == afl->cpu_core_count) @@ -326,7 +391,9 @@ if (pthread_setaffinity_np(pthread_self(), cpuset_size(c), c)) { } cpuset_destroy(c); + #elif defined(__sun) + if (pset_bind(c, P_PID, getpid(), NULL)) { if (cpu_start == afl->cpu_core_count) @@ -339,11 +406,17 @@ if (pset_bind(c, P_PID, getpid(), NULL)) { } pset_destroy(c); + #else + // this will need something for other platforms // TODO: Solaris/Illumos has processor_bind ... might worth a try + #endif + if (lockfile[0]) unlink(lockfile); + // we leave the environment variable to ensure a cleanup for other processes + } #endif /* HAVE_AFFINITY */ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index e4e2669c..f7f247f3 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -42,19 +42,21 @@ static void at_exit() { int i; char *list[4] = {SHM_ENV_VAR, SHM_FUZZ_ENV_VAR, CMPLOG_SHM_ENV_VAR, NULL}; - char *ptr = getenv("__AFL_TARGET_PID1"); + char *ptr; + ptr = getenv(CPU_AFFINITY_ENV_VAR); + if (ptr && *ptr) unlink(ptr); + + ptr = getenv("__AFL_TARGET_PID1"); if (ptr && *ptr && (i = atoi(ptr)) > 0) kill(i, SIGKILL); ptr = getenv("__AFL_TARGET_PID2"); - if (ptr && *ptr && (i = atoi(ptr)) > 0) kill(i, SIGKILL); i = 0; while (list[i] != NULL) { ptr = getenv(list[i]); - if (ptr && *ptr) { #ifdef USEMMAP @@ -1011,17 +1013,19 @@ int main(int argc, char **argv_orig, char **envp) { } + check_crash_handling(); + check_cpu_governor(afl); + get_core_count(afl); + atexit(at_exit); + + setup_dirs_fds(afl); + #ifdef HAVE_AFFINITY bind_to_free_cpu(afl); #endif /* HAVE_AFFINITY */ - check_crash_handling(); - check_cpu_governor(afl); - - atexit(at_exit); - afl->fsrv.trace_bits = afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->non_instrumented_mode); @@ -1038,12 +1042,10 @@ int main(int argc, char **argv_orig, char **envp) { } - setup_dirs_fds(afl); - if (afl->is_secondary_node && check_main_node_exists(afl) == 0) { WARNF("no -M main node found. You need to run one main instance!"); - sleep(5); + sleep(3); } -- cgit 1.4.1 From 383b280531a92a8b81d112a9acb4e44c08987be0 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 14 Jul 2020 23:26:11 +0200 Subject: added frida gum extension --- examples/afl_frida/Makefile | 23 ++ examples/afl_frida/README.md | 38 +++ examples/afl_frida/afl-frida.c | 312 ++++++++++++++++++++++++ examples/afl_frida/afl-frida.h | 53 ++++ examples/afl_frida/libtestinstr.c | 35 +++ examples/afl_network_proxy/afl-network-client.c | 2 +- src/afl-fuzz.c | 5 +- test/test-floatingpoint.c | 24 +- test/test-fp_cases.c | 73 ++++-- 9 files changed, 525 insertions(+), 40 deletions(-) create mode 100644 examples/afl_frida/Makefile create mode 100644 examples/afl_frida/README.md create mode 100644 examples/afl_frida/afl-frida.c create mode 100644 examples/afl_frida/afl-frida.h create mode 100644 examples/afl_frida/libtestinstr.c (limited to 'src/afl-fuzz.c') diff --git a/examples/afl_frida/Makefile b/examples/afl_frida/Makefile new file mode 100644 index 00000000..5d482e54 --- /dev/null +++ b/examples/afl_frida/Makefile @@ -0,0 +1,23 @@ +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 -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/README.md b/examples/afl_frida/README.md new file mode 100644 index 00000000..93e8f35a --- /dev/null +++ b/examples/afl_frida/README.md @@ -0,0 +1,38 @@ +# 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): +``` +afl-fuzz -i in -o out -- ./afl-frida +``` +(or even remote via afl-network-proxy). + +### Testing and debugging + +For testing/debugging you can try: +``` +make DEBUG=1 +AFL_DEBUG=1 gdb ./afl-frida +``` +and then you can easily set breakpoints to "breakpoint" and "fuzz". + +# Background + +This code ist 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 new file mode 100644 index 00000000..c24e05b7 --- /dev/null +++ b/examples/afl_frida/afl-frida.c @@ -0,0 +1,312 @@ +/* + american fuzzy lop++ - afl-frida skeleton example + ------------------------------------------------- + + Copyright 2020 AFLplusplus Project. All rights reserved. + + Written mostly by meme -> https://github.com/meme/hotwax + + Modificationy by Marc Heuse + + 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 +#include +#include +#include +#include +#include +#include + +#ifndef __APPLE__ + #include +#endif + + +// 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; + +// Frida stuff below. +typedef struct { + + GumAddress base_address; + guint64 code_start, code_end; + +} range_t; + +inline static void afl_maybe_log(guint64 current_pc) { + + static __thread guint64 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) { + + guint64 current_pc = instr->address - range->base_address; + gum_stalker_iterator_put_callout(iterator, on_basic_block, + (gpointer)current_pc, 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; + +} + +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() { + + // 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 + + gum_init_embedded(); + if (!gum_stalker_is_supported()) { + + gum_deinit_embedded(); + return 1; + + } + + GumStalker *stalker = gum_stalker_new(); + + 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}; + + GumStalkerTransformer *transformer = + gum_stalker_transformer_make_from_callback(instr_basic_block, + &instr_range, NULL); + + GumEventSink *event_sink = gum_fake_event_sink_new(); + + __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) { + +#ifdef _DEBUG + fprintf(stderr, "CLIENT crc: %016llx len: %u\n", hash64(__afl_fuzz_ptr, *__a + 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 new file mode 100644 index 00000000..efa3440f --- /dev/null +++ b/examples/afl_frida/afl-frida.h @@ -0,0 +1,53 @@ +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 new file mode 100644 index 00000000..96b1cf21 --- /dev/null +++ b/examples/afl_frida/libtestinstr.c @@ -0,0 +1,35 @@ +/* + 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 +#include +#include +#include +#include +#include +#include + +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/afl-network-client.c b/examples/afl_network_proxy/afl-network-client.c index 7c4d8b35..a2451fdc 100644 --- a/examples/afl_network_proxy/afl-network-client.c +++ b/examples/afl_network_proxy/afl-network-client.c @@ -35,7 +35,7 @@ #include #include #ifndef USEMMAP -#include + #include #endif #include #include diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index f7f247f3..872ed9ae 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -266,6 +266,8 @@ int main(int argc, char **argv_orig, char **envp) { gettimeofday(&tv, &tz); rand_set_seed(afl, tv.tv_sec ^ tv.tv_usec ^ getpid()); + afl->shmem_testcase_mode = 1; // we always try to perform shmem fuzzing + while ((opt = getopt(argc, argv, "+c:i:I:o:f:m:t:T:dDnCB:S:M:x:QNUWe:p:s:V:E:L:hRP:")) > 0) { @@ -563,7 +565,6 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->fsrv.qemu_mode) { FATAL("Multiple -Q options not supported"); } afl->fsrv.qemu_mode = 1; - afl->shmem_testcase_mode = 1; if (!mem_limit_given) { afl->fsrv.mem_limit = MEM_LIMIT_QEMU; } @@ -580,7 +581,6 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->unicorn_mode) { FATAL("Multiple -U options not supported"); } afl->unicorn_mode = 1; - afl->shmem_testcase_mode = 1; if (!mem_limit_given) { afl->fsrv.mem_limit = MEM_LIMIT_UNICORN; } @@ -591,7 +591,6 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->use_wine) { FATAL("Multiple -W options not supported"); } afl->fsrv.qemu_mode = 1; afl->use_wine = 1; - afl->shmem_testcase_mode = 1; if (!mem_limit_given) { afl->fsrv.mem_limit = 0; } diff --git a/test/test-floatingpoint.c b/test/test-floatingpoint.c index f78b5d9f..76cdccf0 100644 --- a/test/test-floatingpoint.c +++ b/test/test-floatingpoint.c @@ -1,18 +1,20 @@ #include #include -int main(void) -{ - long double magic; +int main(void) { - ssize_t bytes_read = read(STDIN_FILENO, &magic, sizeof(magic)); - if (bytes_read < (ssize_t)sizeof(magic)) { - return 1; - } + long double magic; - if( (-magic == 15.0 + 0.5 + 0.125 + 0.03125 + 0.0078125) ){ /* 15 + 1/2 + 1/8 + 1/32 + 1/128 */ - abort(); - } + ssize_t bytes_read = read(STDIN_FILENO, &magic, sizeof(magic)); + if (bytes_read < (ssize_t)sizeof(magic)) { return 1; } + + if ((-magic == 15.0 + 0.5 + 0.125 + 0.03125 + + 0.0078125)) { /* 15 + 1/2 + 1/8 + 1/32 + 1/128 */ + abort(); + + } + + return 0; - return 0; } + diff --git a/test/test-fp_cases.c b/test/test-fp_cases.c index 006ae32f..b0f792bc 100644 --- a/test/test-fp_cases.c +++ b/test/test-fp_cases.c @@ -4,13 +4,14 @@ * or -DFLOAT_TYPE="long double" */ - #include int main() { - volatile FLOAT_TYPE a,b; + + volatile FLOAT_TYPE a, b; /* different values */ - a = -2.1; b = -2; /* signs equal, exp equal, mantissa > */ + a = -2.1; + b = -2; /* signs equal, exp equal, mantissa > */ assert((a < b)); assert((a <= b)); assert(!(a > b)); @@ -18,7 +19,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = 1.8; b = 2.1; /* signs equal, exp differ, mantissa > */ + a = 1.8; + b = 2.1; /* signs equal, exp differ, mantissa > */ assert((a < b)); assert((a <= b)); assert(!(a > b)); @@ -26,7 +28,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = 2; b = 2.1; /* signs equal, exp equal, mantissa < */ + a = 2; + b = 2.1; /* signs equal, exp equal, mantissa < */ assert((a < b)); assert((a <= b)); assert(!(a > b)); @@ -34,7 +37,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = -2; b = -1.8; /* signs equal, exp differ, mantissa < */ + a = -2; + b = -1.8; /* signs equal, exp differ, mantissa < */ assert((a < b)); assert((a <= b)); assert(!(a > b)); @@ -42,7 +46,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = -1; b = 1; /* signs differ, exp equal, mantissa equal */ + a = -1; + b = 1; /* signs differ, exp equal, mantissa equal */ assert((a < b)); assert((a <= b)); assert(!(a > b)); @@ -50,7 +55,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = -1; b = 0; /* signs differ, exp differ, mantissa equal */ + a = -1; + b = 0; /* signs differ, exp differ, mantissa equal */ assert((a < b)); assert((a <= b)); assert(!(a > b)); @@ -58,7 +64,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = -2; b = 2.8; /* signs differ, exp equal, mantissa < */ + a = -2; + b = 2.8; /* signs differ, exp equal, mantissa < */ assert((a < b)); assert((a <= b)); assert(!(a > b)); @@ -66,7 +73,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = -2; b = 1.8; /* signs differ, exp differ, mantissa < */ + a = -2; + b = 1.8; /* signs differ, exp differ, mantissa < */ assert((a < b)); assert((a <= b)); assert(!(a > b)); @@ -74,8 +82,8 @@ int main() { assert((a != b)); assert(!(a == b)); - - a = -2; b = -2.1; /* signs equal, exp equal, mantissa > */ + a = -2; + b = -2.1; /* signs equal, exp equal, mantissa > */ assert((a > b)); assert((a >= b)); assert(!(a < b)); @@ -83,7 +91,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = 2.1; b = 1.8; /* signs equal, exp differ, mantissa > */ + a = 2.1; + b = 1.8; /* signs equal, exp differ, mantissa > */ assert((a > b)); assert((a >= b)); assert(!(a < b)); @@ -91,7 +100,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = 2.1; b = 2; /* signs equal, exp equal, mantissa < */ + a = 2.1; + b = 2; /* signs equal, exp equal, mantissa < */ assert((a > b)); assert((a >= b)); assert(!(a < b)); @@ -99,7 +109,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = -1.8; b = -2; /* signs equal, exp differ, mantissa < */ + a = -1.8; + b = -2; /* signs equal, exp differ, mantissa < */ assert((a > b)); assert((a >= b)); assert(!(a < b)); @@ -107,7 +118,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = 1; b = -1; /* signs differ, exp equal, mantissa equal */ + a = 1; + b = -1; /* signs differ, exp equal, mantissa equal */ assert((a > b)); assert((a >= b)); assert(!(a < b)); @@ -115,7 +127,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = 0; b = -1; /* signs differ, exp differ, mantissa equal */ + a = 0; + b = -1; /* signs differ, exp differ, mantissa equal */ assert((a > b)); assert((a >= b)); assert(!(a < b)); @@ -123,7 +136,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = 2.8; b = -2; /* signs differ, exp equal, mantissa < */ + a = 2.8; + b = -2; /* signs differ, exp equal, mantissa < */ assert((a > b)); assert((a >= b)); assert(!(a < b)); @@ -131,7 +145,8 @@ int main() { assert((a != b)); assert(!(a == b)); - a = 1.8; b = -2; /* signs differ, exp differ, mantissa < */ + a = 1.8; + b = -2; /* signs differ, exp differ, mantissa < */ assert((a > b)); assert((a >= b)); assert(!(a < b)); @@ -140,7 +155,8 @@ int main() { assert(!(a == b)); /* equal values */ - a = 0; b = 0; + a = 0; + b = 0; assert(!(a < b)); assert((a <= b)); assert(!(a > b)); @@ -148,7 +164,8 @@ int main() { assert(!(a != b)); assert((a == b)); - a = -0; b = 0; + a = -0; + b = 0; assert(!(a < b)); assert((a <= b)); assert(!(a > b)); @@ -156,7 +173,8 @@ int main() { assert(!(a != b)); assert((a == b)); - a = 1; b = 1; + a = 1; + b = 1; assert(!(a < b)); assert((a <= b)); assert(!(a > b)); @@ -164,7 +182,8 @@ int main() { assert(!(a != b)); assert((a == b)); - a = 0.5; b = 0.5; + a = 0.5; + b = 0.5; assert(!(a < b)); assert((a <= b)); assert(!(a > b)); @@ -172,7 +191,8 @@ int main() { assert(!(a != b)); assert((a == b)); - a = -1; b = -1; + a = -1; + b = -1; assert(!(a < b)); assert((a <= b)); assert(!(a > b)); @@ -180,11 +200,14 @@ int main() { assert(!(a != b)); assert((a == b)); - a = -0.5; b = -0.5; + a = -0.5; + b = -0.5; assert(!(a < b)); assert((a <= b)); assert(!(a > b)); assert((a >= b)); assert(!(a != b)); assert((a == b)); + } + -- cgit 1.4.1