about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAndrea Fioraldi <andreafioraldi@gmail.com>2020-04-16 19:53:51 +0200
committerAndrea Fioraldi <andreafioraldi@gmail.com>2020-04-16 19:53:51 +0200
commit23ea7279159dce964c69b3dfa5e7e36f3d5a5085 (patch)
treec29eeca17acee61a862646149b8cd1d9a4cf97f3
parentf157bca54858dce131e90f664da2505d43e0f65f (diff)
parent35937e62634f69b34c852abb0aaeca546a712f4f (diff)
downloadafl++-23ea7279159dce964c69b3dfa5e7e36f3d5a5085.tar.gz
Merge branch 'dev' of github.com:vanhauser-thc/AFLplusplus into dev
-rw-r--r--GNUmakefile2
-rw-r--r--README.md1
-rw-r--r--include/afl-fuzz.h4
-rw-r--r--include/common.h10
-rw-r--r--include/debug.h4
-rw-r--r--include/forkserver.h16
-rw-r--r--llvm_mode/README.lto.md16
-rw-r--r--llvm_mode/afl-clang-fast.c6
-rw-r--r--src/afl-analyze.c73
-rw-r--r--src/afl-common.c80
-rw-r--r--src/afl-forkserver.c84
-rw-r--r--src/afl-fuzz-bitmap.c36
-rw-r--r--src/afl-fuzz-cmplog.c2
-rw-r--r--src/afl-fuzz-mutators.c5
-rw-r--r--src/afl-fuzz-one.c4
-rw-r--r--src/afl-fuzz-python.c2
-rw-r--r--src/afl-fuzz-redqueen.c4
-rw-r--r--src/afl-fuzz-run.c56
-rw-r--r--src/afl-fuzz.c4
-rw-r--r--src/afl-sharedmem.c2
-rw-r--r--src/afl-showmap.c133
-rw-r--r--src/afl-tmin.c161
-rw-r--r--src/third_party/libradamsa/libradamsa.c76
-rw-r--r--src/third_party/libradamsa/radamsa.h6
-rw-r--r--test/unittests/unit_list.c2
-rw-r--r--test/unittests/unit_maybe_alloc.c2
-rw-r--r--test/unittests/unit_preallocable.c2
27 files changed, 345 insertions, 448 deletions
diff --git a/GNUmakefile b/GNUmakefile
index 74a290e6..11dfa803 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -69,7 +69,7 @@ ifneq "$(shell uname -m)" "x86_64"
 endif
 
 CFLAGS     ?= -O3 -funroll-loops $(CFLAGS_OPT)
-override CFLAGS += -Wall -g -Wno-pointer-sign \
+override CFLAGS += -Wall -g -Wno-pointer-sign -Wmissing-declarations\
 			  -I include/ -Werror -DAFL_PATH=\"$(HELPER_PATH)\" \
 			  -DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\"
 
diff --git a/README.md b/README.md
index f14ccd36..a6afe73a 100644
--- a/README.md
+++ b/README.md
@@ -352,6 +352,7 @@ Here are some good writeups to show how to effectively use AFL++:
  * [https://aflplus.plus/docs/tutorials/libxml2_tutorial/](https://aflplus.plus/docs/tutorials/libxml2_tutorial/)
  * [https://bananamafia.dev/post/gb-fuzz/](https://bananamafia.dev/post/gb-fuzz/)
  * [https://securitylab.github.com/research/fuzzing-challenges-solutions-1](https://securitylab.github.com/research/fuzzing-challenges-solutions-1)
+ * [https://securitylab.github.com/research/fuzzing-sockets-FTP](https://securitylab.github.com/research/fuzzing-sockets-FTP)
 
 If you are interested in fuzzing structured data (where you define what the
 structure is), these two links have you covered:
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 7c6019e6..363776cb 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -808,6 +808,7 @@ u8   trim_case_custom(afl_state_t *, struct queue_entry *q, u8 *in_buf);
 /* Python */
 #ifdef USE_PYTHON
 
+void load_custom_mutator_py(afl_state_t *, char *);
 void finalize_py_module(void *);
 
 size_t pre_save_py(void *, u8 *, size_t, u8 **);
@@ -835,7 +836,6 @@ u32  calculate_score(afl_state_t *, struct queue_entry *);
 
 /* Bitmap */
 
-void read_bitmap(afl_state_t *, u8 *);
 void write_bitmap(afl_state_t *);
 u32  count_bits(afl_state_t *, u8 *);
 u32  count_bytes(afl_state_t *, u8 *);
@@ -873,7 +873,7 @@ void show_init_stats(afl_state_t *);
 
 /* Run */
 
-fsrv_run_result_t run_target(afl_state_t *, afl_forkserver_t *fsrv, u32);
+fsrv_run_result_t fuzz_run_target(afl_state_t *, afl_forkserver_t *fsrv, u32);
 void              write_to_testcase(afl_state_t *, void *, u32);
 u8   calibrate_case(afl_state_t *, struct queue_entry *, u8 *, u32, u8);
 void sync_fuzzers(afl_state_t *);
diff --git a/include/common.h b/include/common.h
index 8dd66355..f5ace878 100644
--- a/include/common.h
+++ b/include/common.h
@@ -51,6 +51,16 @@ char * get_afl_env(char *env);
 extern u8  be_quiet;
 extern u8 *doc_path;                    /* path to documentation dir        */
 
+/* Find binary, used by analyze, showmap, tmin
+   @returns the path, allocating the string */
+
+u8 *find_binary(u8 *fname);
+
+/* Read a bitmap from file fname to memory
+   This is for the -B option again. */
+
+void read_bitmap(u8 *fname, u8 *map, size_t len);
+
 /* Get unix time in milliseconds */
 
 u64 get_cur_time(void);
diff --git a/include/debug.h b/include/debug.h
index 8824ff6b..4cce56b5 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -29,12 +29,8 @@
 #include "config.h"
 
 /* __FUNCTION__ is non-iso */
-#ifndef __FUNCTION__
 #ifdef __func__
 #define __FUNCTION__ __func__
-#else
-#define __FUNCTION__ "func_unknown"
-#endif
 #endif
 
 /*******************
diff --git a/include/forkserver.h b/include/forkserver.h
index f24393bc..ac89b681 100644
--- a/include/forkserver.h
+++ b/include/forkserver.h
@@ -51,6 +51,8 @@ typedef struct afl_forkserver {
       fsrv_ctl_fd,                      /* Fork server control pipe (write) */
       fsrv_st_fd;                       /* Fork server status pipe (read)   */
 
+  u8 no_unlink;                         /* do not unlink cur_input          */
+
   u32 exec_tmout;                       /* Configurable exec timeout (ms)   */
   u32 map_size;                         /* map size used by the target      */
   u32 snapshot;                         /* is snapshot feature used         */
@@ -63,7 +65,8 @@ typedef struct afl_forkserver {
 
   FILE *plot_file;                      /* Gnuplot output file              */
 
-  u8 last_run_timed_out;                /* Traced process timed out?        */
+  /* Note: lat_run_timed_out is u32 to send it to the child as 4 byte array */
+  u32 last_run_timed_out;               /* Traced process timed out?        */
 
   u8 last_kill_signal;                  /* Signal that killed the child     */
 
@@ -97,12 +100,11 @@ void afl_fsrv_init(afl_forkserver_t *fsrv);
 void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from);
 void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
                     volatile u8 *stop_soon_p, u8 debug_child_output);
-fsrv_run_result_t afl_fsrv_run_target(
-    afl_forkserver_t *fsrv, u32 timeout,
-    void(classify_counts_func)(afl_forkserver_t *fsrv),
-    volatile u8 *stop_soon_p);
-void afl_fsrv_killall(void);
-void afl_fsrv_deinit(afl_forkserver_t *fsrv);
+void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len);
+fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
+                                      volatile u8 *stop_soon_p);
+void              afl_fsrv_killall(void);
+void              afl_fsrv_deinit(afl_forkserver_t *fsrv);
 
 #ifdef __APPLE__
 #define MSG_FORK_ON_APPLE                                                    \
diff --git a/llvm_mode/README.lto.md b/llvm_mode/README.lto.md
index 51b50544..9af9ffff 100644
--- a/llvm_mode/README.lto.md
+++ b/llvm_mode/README.lto.md
@@ -17,17 +17,17 @@ This version requires a current llvm 11 compiled from the github master.
 ## Introduction and problem description
 
 A big issue with how afl/afl++ works is that the basic block IDs that are
-set during compilation are random - and hence natually the larger the number
-of instrumented locations, the higher the number of edge collisions in the
+set during compilation are random - and hence naturally the larger the number
+of instrumented locations, the higher the number of edge collisions are in the
 map. This can result in not discovering new paths and therefore degrade the
-efficiency of the fuzzing.
+efficiency of the fuzzing process.
 
-*This issue is understimated in the fuzzing community!*
+*This issue is underestimated in the fuzzing community!*
 With a 2^16 = 64kb standard map at already 256 instrumented blocks there is
 on average one collision. On average a target has 10.000 to 50.000
 instrumented blocks hence the real collisions are between 750-18.000!
 
-To get to a solution that prevents any collision took several approaches
+To reach a solution that prevents any collisions took several approaches
 and many dead ends until we got to this:
 
  * We instrument at link time when we have all files pre-compiled
@@ -76,7 +76,7 @@ $ make install
 
 ## How to use afl-clang-lto
 
-Just use afl-clang-lto like you did afl-clang-fast or afl-gcc.
+Just use afl-clang-lto like you did with afl-clang-fast or afl-gcc.
 
 Also whitelisting (AFL_LLVM_WHITELIST -> [README.whitelist.md](README.whitelist.md)) and
 laf-intel/compcov (AFL_LLVM_LAF_* -> [README.laf-intel.md](README.laf-intel.md)) work.
@@ -120,7 +120,7 @@ Please report issues at:
 
 ## Upcoming Work
 
-1. Currently the LTO whitelist feature does not allow to not instrument main,
+1. Currently the LTO whitelist feature does not allow to instrument main,
    start and init functions
 
 ## History
@@ -138,7 +138,7 @@ This was first implemented in January and work ... kinda.
 The LTO time instrumentation worked, however the "how" the basic blocks were
 instrumented was a problem, as reducing duplicates turned out to be very,
 very difficult with a program that has so many paths and therefore so many
-dependencies. At lot of stratgies were implemented - and failed.
+dependencies. At lot of strategies were implemented - and failed.
 And then sat solvers were tried, but with over 10.000 variables that turned
 out to be a dead-end too.
 
diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c
index 57d7b89a..c0471033 100644
--- a/llvm_mode/afl-clang-fast.c
+++ b/llvm_mode/afl-clang-fast.c
@@ -223,8 +223,10 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
   }
 
-  if (getenv("LAF_TRANSFORM_COMPARES") ||
-      getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES")) {
+  if ((!(getenv("AFL_LLVM_LTO_AUTODICTIONARY")   // disabled when autodictionary
+         && instrument_mode != INSTRUMENT_LTO))  // and lto_mode is used
+      && (getenv("LAF_TRANSFORM_COMPARES") ||
+          getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES"))) {
 
     cc_params[cc_par_cnt++] = "-Xclang";
     cc_params[cc_par_cnt++] = "-load";
diff --git a/src/afl-analyze.c b/src/afl-analyze.c
index 952786b0..6f946ed5 100644
--- a/src/afl-analyze.c
+++ b/src/afl-analyze.c
@@ -209,7 +209,7 @@ static s32 write_to_file(u8 *path, u8 *mem, u32 len) {
 /* Execute target application. Returns exec checksum, or 0 if program
    times out. */
 
-static u32 run_target(char **argv, u8 *mem, u32 len, u8 first_run) {
+static u32 analyze_run_target(char **argv, u8 *mem, u32 len, u8 first_run) {
 
   static struct itimerval it;
   int                     status = 0;
@@ -560,16 +560,16 @@ static void analyze(char **argv) {
        code. */
 
     in_data[i] ^= 0xff;
-    xor_ff = run_target(argv, in_data, in_len, 0);
+    xor_ff = analyze_run_target(argv, in_data, in_len, 0);
 
     in_data[i] ^= 0xfe;
-    xor_01 = run_target(argv, in_data, in_len, 0);
+    xor_01 = analyze_run_target(argv, in_data, in_len, 0);
 
     in_data[i] = (in_data[i] ^ 0x01) - 0x10;
-    sub_10 = run_target(argv, in_data, in_len, 0);
+    sub_10 = analyze_run_target(argv, in_data, in_len, 0);
 
     in_data[i] += 0x20;
-    add_10 = run_target(argv, in_data, in_len, 0);
+    add_10 = analyze_run_target(argv, in_data, in_len, 0);
     in_data[i] -= 0x10;
 
     /* Classify current behavior. */
@@ -805,61 +805,6 @@ static void usage(u8 *argv0) {
 
 }
 
-/* Find binary. */
-
-static void find_binary(u8 *fname) {
-
-  u8 *        env_path = 0;
-  struct stat st;
-
-  if (strchr(fname, '/') || !(env_path = getenv("PATH"))) {
-
-    target_path = ck_strdup(fname);
-
-    if (stat(target_path, &st) || !S_ISREG(st.st_mode) ||
-        !(st.st_mode & 0111) || st.st_size < 4)
-      FATAL("Program '%s' not found or not executable", fname);
-
-  } else {
-
-    while (env_path) {
-
-      u8 *cur_elem, *delim = strchr(env_path, ':');
-
-      if (delim) {
-
-        cur_elem = ck_alloc(delim - env_path + 1);
-        memcpy(cur_elem, env_path, delim - env_path);
-        delim++;
-
-      } else
-
-        cur_elem = ck_strdup(env_path);
-
-      env_path = delim;
-
-      if (cur_elem[0])
-        target_path = alloc_printf("%s/%s", cur_elem, fname);
-      else
-        target_path = ck_strdup(fname);
-
-      ck_free(cur_elem);
-
-      if (!stat(target_path, &st) && S_ISREG(st.st_mode) &&
-          (st.st_mode & 0111) && st.st_size >= 4)
-        break;
-
-      ck_free(target_path);
-      target_path = 0;
-
-    }
-
-    if (!target_path) FATAL("Program '%s' not found or not executable", fname);
-
-  }
-
-}
-
 /* Main entry point */
 
 int main(int argc, char **argv, char **envp) {
@@ -902,7 +847,7 @@ int main(int argc, char **argv, char **envp) {
         if (mem_limit_given) FATAL("Multiple -m options not supported");
         mem_limit_given = 1;
 
-        if (!optarg) { FATAL("Bad syntax used for -m"); }
+        if (!optarg) { FATAL("Wrong usage of -m"); }
 
         if (!strcmp(optarg, "none")) {
 
@@ -997,7 +942,7 @@ int main(int argc, char **argv, char **envp) {
 
   set_up_environment();
 
-  find_binary(argv[optind]);
+  target_path = find_binary(argv[optind]);
   detect_file_args(argv + optind, prog_in, &use_stdin);
 
   if (qemu_mode) {
@@ -1020,7 +965,7 @@ int main(int argc, char **argv, char **envp) {
   ACTF("Performing dry run (mem limit = %llu MB, timeout = %u ms%s)...",
        mem_limit, exec_tmout, edges_only ? ", edges only" : "");
 
-  run_target(use_argv, in_data, in_len, 1);
+  analyze_run_target(use_argv, in_data, in_len, 1);
 
   if (child_timed_out)
     FATAL("Target binary times out (adjusting -t may help).");
@@ -1032,6 +977,8 @@ int main(int argc, char **argv, char **envp) {
 
   OKF("We're done here. Have a nice day!\n");
 
+  if (target_path) ck_free(target_path);
+
   afl_shm_deinit(&shm);
 
   exit(0);
diff --git a/src/afl-common.c b/src/afl-common.c
index 1ac1a2f3..ffc32533 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -37,6 +37,10 @@
 #include <unistd.h>
 #endif
 #include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
 
 u8  be_quiet = 0;
 u8 *doc_path = "";
@@ -353,6 +357,68 @@ char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
 
 }
 
+/* Find binary, used by analyze, showmap, tmin
+   @returns the path, allocating the string */
+
+u8 *find_binary(u8 *fname) {
+
+  // TODO: Merge this function with check_binary of afl-fuzz-init.c
+
+  u8 *env_path = NULL;
+  u8 *target_path = NULL;
+
+  struct stat st;
+
+  if (strchr(fname, '/') || !(env_path = getenv("PATH"))) {
+
+    target_path = ck_strdup(fname);
+
+    if (stat(target_path, &st) || !S_ISREG(st.st_mode) ||
+        !(st.st_mode & 0111) || st.st_size < 4)
+      FATAL("Program '%s' not found or not executable", fname);
+
+  } else {
+
+    while (env_path) {
+
+      u8 *cur_elem, *delim = strchr(env_path, ':');
+
+      if (delim) {
+
+        cur_elem = ck_alloc(delim - env_path + 1);
+        memcpy(cur_elem, env_path, delim - env_path);
+        delim++;
+
+      } else
+
+        cur_elem = ck_strdup(env_path);
+
+      env_path = delim;
+
+      if (cur_elem[0])
+        target_path = alloc_printf("%s/%s", cur_elem, fname);
+      else
+        target_path = ck_strdup(fname);
+
+      ck_free(cur_elem);
+
+      if (!stat(target_path, &st) && S_ISREG(st.st_mode) &&
+          (st.st_mode & 0111) && st.st_size >= 4)
+        break;
+
+      ck_free(target_path);
+      target_path = NULL;
+
+    }
+
+    if (!target_path) FATAL("Program '%s' not found or not executable", fname);
+
+  }
+
+  return target_path;
+
+}
+
 void check_environment_vars(char **envp) {
 
   if (be_quiet) return;
@@ -414,6 +480,20 @@ char *get_afl_env(char *env) {
 
 }
 
+/* Read mask bitmap from file. This is for the -B option. */
+
+void read_bitmap(u8 *fname, u8 *map, size_t len) {
+
+  s32 fd = open(fname, O_RDONLY);
+
+  if (fd < 0) PFATAL("Unable to open '%s'", fname);
+
+  ck_read(fd, map, len, fname);
+
+  close(fd);
+
+}
+
 u64 get_cur_time(void) {
 
   struct timeval  tv;
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 9c89a723..006764d9 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -8,7 +8,9 @@
 
    Now maintained by Marc Heuse <mh@mh-sec.de>,
                         Heiko Eißfeldt <heiko.eissfeldt@hexco.de> and
-                        Andrea Fioraldi <andreafioraldi@gmail.com>
+                        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.
@@ -38,10 +40,12 @@
 #include <time.h>
 #include <errno.h>
 #include <signal.h>
+#include <fcntl.h>
 #include <sys/time.h>
 #include <sys/wait.h>
 #include <sys/resource.h>
 #include <sys/select.h>
+#include <sys/stat.h>
 
 /**
  * The correct fds for reading and writing pipes
@@ -64,15 +68,20 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) {
   // this structure needs default so we initialize it if this was not done
   // already
 
-  fsrv->use_stdin = 1;
   fsrv->out_fd = -1;
   fsrv->out_dir_fd = -1;
   fsrv->dev_null_fd = -1;
 #ifndef HAVE_ARC4RANDOM
   fsrv->dev_urandom_fd = -1;
 #endif
+  /* Settings */
+  fsrv->use_stdin = 1;
+  fsrv->no_unlink = 0;
   fsrv->exec_tmout = EXEC_TIMEOUT;
   fsrv->mem_limit = MEM_LIMIT;
+  fsrv->out_file = NULL;
+
+  /* exec related stuff */
   fsrv->child_pid = -1;
   fsrv->map_size = MAP_SIZE;
   fsrv->use_fauxsrv = 0;
@@ -103,6 +112,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) {
   fsrv_to->child_pid = -1;
   fsrv_to->use_fauxsrv = 0;
   fsrv_to->last_run_timed_out = 0;
+  fsrv_to->out_file = NULL;
 
   fsrv_to->init_child_func = fsrv_exec_child;
 
@@ -385,7 +395,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
 
     if ((status & FS_OPT_ENABLED) == FS_OPT_ENABLED) {
 
-      if (!be_quiet)
+      if (!be_quiet && getenv("AFL_DEBUG"))
         ACTF("Extended forkserver functions received (%08x).", status);
 
       if ((status & FS_OPT_SNAPSHOT) == FS_OPT_SNAPSHOT) {
@@ -398,13 +408,19 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
       if ((status & FS_OPT_MAPSIZE) == FS_OPT_MAPSIZE) {
 
         fsrv->map_size = FS_OPT_GET_MAPSIZE(status);
-        if (fsrv->map_size % 8)  // should not happen
+        if (unlikely(fsrv->map_size % 8)) {
+
+          // should not happen
+          WARNF("Target reported non-aligned map size of %ud", fsrv->map_size);
           fsrv->map_size = (((fsrv->map_size + 8) >> 3) << 3);
+
+        }
+
         if (!be_quiet) ACTF("Target map size: %u", fsrv->map_size);
         if (fsrv->map_size > MAP_SIZE)
           FATAL(
               "Target's coverage map size of %u is larger than the one this "
-              "afl++ is compiled with (%u)\n",
+              "afl++ is compiled with (%u) (change MAP_SIZE and recompile)\n",
               fsrv->map_size, MAP_SIZE);
 
       }
@@ -434,7 +450,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
         u32 len = status, offset = 0, count = 0;
         u8 *dict = ck_alloc(len);
         if (dict == NULL)
-          FATAL("Could not allocate %u bytes of autodictionary memmory", len);
+          FATAL("Could not allocate %u bytes of autodictionary memory", len);
 
         while (len != 0) {
 
@@ -640,13 +656,53 @@ static void afl_fsrv_kill(afl_forkserver_t *fsrv) {
 
 }
 
+/* Delete the current testcase and write the buf to the testcase file */
+
+void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) {
+
+  s32 fd = fsrv->out_fd;
+
+  if (fsrv->out_file) {
+
+    if (fsrv->no_unlink) {
+
+      fd = open(fsrv->out_file, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+
+    } else {
+
+      unlink(fsrv->out_file);                             /* Ignore errors. */
+      fd = open(fsrv->out_file, O_WRONLY | O_CREAT | O_EXCL, 0600);
+
+    }
+
+    if (fd < 0) PFATAL("Unable to create '%s'", fsrv->out_file);
+
+  } else {
+
+    lseek(fd, 0, SEEK_SET);
+
+  }
+
+  ck_write(fd, buf, len, fsrv->out_file);
+
+  if (!fsrv->out_file) {
+
+    if (ftruncate(fd, len)) PFATAL("ftruncate() failed");
+    lseek(fd, 0, SEEK_SET);
+
+  } else {
+
+    close(fd);
+
+  }
+
+}
+
 /* Execute target application, monitoring for timeouts. Return status
    information. The called program will update afl->fsrv->trace_bits. */
 
-fsrv_run_result_t afl_fsrv_run_target(
-    afl_forkserver_t *fsrv, u32 timeout,
-    void(classify_counts_func)(afl_forkserver_t *fsrv),
-    volatile u8 *stop_soon_p) {
+fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
+                                      volatile u8 *stop_soon_p) {
 
   s32 res;
   u32 exec_ms;
@@ -675,7 +731,7 @@ fsrv_run_result_t afl_fsrv_run_target(
 
   if ((res = read(fsrv->fsrv_st_fd, &fsrv->child_pid, 4)) != 4) {
 
-    if (stop_soon_p) return 0;
+    if (*stop_soon_p) return 0;
     RPFATAL(res, "Unable to request new process from fork server (OOM?)");
 
   }
@@ -732,9 +788,6 @@ fsrv_run_result_t afl_fsrv_run_target(
      behave very normally and do not have to be treated as volatile. */
 
   MEM_BARRIER();
-  u32 tb4 = *(u32 *)fsrv->trace_bits;
-
-  if (likely(classify_counts_func)) classify_counts_func(fsrv);
 
   /* Report outcome to caller. */
 
@@ -759,7 +812,8 @@ fsrv_run_result_t afl_fsrv_run_target(
 
   }
 
-  if (tb4 == EXEC_FAIL_SIG) return FSRV_RUN_ERROR;
+  // Fauxserver should handle this now.
+  // if (tb4 == EXEC_FAIL_SIG) return FSRV_RUN_ERROR;
 
   return FSRV_RUN_OK;
 
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index 852e3a7c..be8f504e 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -49,20 +49,6 @@ void write_bitmap(afl_state_t *afl) {
 
 }
 
-/* Read bitmap from file. This is for the -B option again. */
-
-void read_bitmap(afl_state_t *afl, u8 *fname) {
-
-  s32 fd = open(fname, O_RDONLY);
-
-  if (fd < 0) PFATAL("Unable to open '%s'", fname);
-
-  ck_read(fd, afl->virgin_bits, MAP_SIZE, fname);
-
-  close(fd);
-
-}
-
 /* Check if the current execution path brings anything new to the table.
    Update virgin bits to reflect the finds. Returns 1 if the only change is
    the hit-count for a particular tuple; 2 if there are new tuples seen.
@@ -88,7 +74,8 @@ u8 has_new_bits(afl_state_t *afl, u8 *virgin_map) {
   u32 i = (afl->fsrv.map_size >> 2);
 
 #endif                                                     /* ^WORD_SIZE_64 */
-  if (i == 0) i = 1;
+  // the map size must be a minimum of 8 bytes.
+  // for variable/dynamic map sizes this is ensured in the forkserver
 
   u8 ret = 0;
 
@@ -98,6 +85,7 @@ u8 has_new_bits(afl_state_t *afl, u8 *virgin_map) {
        that have not been already cleared from the virgin map - since this will
        almost always be the case. */
 
+    // the (*current) is unnecessary but speeds up the overall comparison
     if (unlikely(*current) && unlikely(*current & *virgin)) {
 
       if (likely(ret < 2)) {
@@ -110,18 +98,20 @@ u8 has_new_bits(afl_state_t *afl, u8 *virgin_map) {
 
 #ifdef WORD_SIZE_64
 
-        if ((cur[0] && vir[0] == 0xff) || (cur[1] && vir[1] == 0xff) ||
-            (cur[2] && vir[2] == 0xff) || (cur[3] && vir[3] == 0xff) ||
-            (cur[4] && vir[4] == 0xff) || (cur[5] && vir[5] == 0xff) ||
-            (cur[6] && vir[6] == 0xff) || (cur[7] && vir[7] == 0xff))
+        if (*virgin == 0xffffffffffffffff || (cur[0] && vir[0] == 0xff) ||
+            (cur[1] && vir[1] == 0xff) || (cur[2] && vir[2] == 0xff) ||
+            (cur[3] && vir[3] == 0xff) || (cur[4] && vir[4] == 0xff) ||
+            (cur[5] && vir[5] == 0xff) || (cur[6] && vir[6] == 0xff) ||
+            (cur[7] && vir[7] == 0xff))
           ret = 2;
         else
           ret = 1;
 
 #else
 
-        if ((cur[0] && vir[0] == 0xff) || (cur[1] && vir[1] == 0xff) ||
-            (cur[2] && vir[2] == 0xff) || (cur[3] && vir[3] == 0xff))
+        if (*virgin == 0xffffffff || (cur[0] && vir[0] == 0xff) ||
+            (cur[1] && vir[1] == 0xff) || (cur[2] && vir[2] == 0xff) ||
+            (cur[3] && vir[3] == 0xff))
           ret = 2;
         else
           ret = 1;
@@ -139,7 +129,7 @@ u8 has_new_bits(afl_state_t *afl, u8 *virgin_map) {
 
   }
 
-  if (unlikely(ret) && unlikely(virgin_map == afl->virgin_bits))
+  if (unlikely(ret) && likely(virgin_map == afl->virgin_bits))
     afl->bitmap_changed = 1;
 
   return ret;
@@ -649,7 +639,7 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
 
         u8 new_fault;
         write_to_testcase(afl, mem, len);
-        new_fault = run_target(afl, &afl->fsrv, afl->hang_tmout);
+        new_fault = fuzz_run_target(afl, &afl->fsrv, afl->hang_tmout);
 
         /* A corner case that one user reported bumping into: increasing the
            timeout actually uncovers a crash. Make sure we don't discard it if
diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c
index ab93d838..12c814ba 100644
--- a/src/afl-fuzz-cmplog.c
+++ b/src/afl-fuzz-cmplog.c
@@ -62,7 +62,7 @@ u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
 
   write_to_testcase(afl, out_buf, len);
 
-  fault = run_target(afl, &afl->cmplog_fsrv, afl->fsrv.exec_tmout);
+  fault = fuzz_run_target(afl, &afl->cmplog_fsrv, afl->fsrv.exec_tmout);
 
   if (afl->stop_soon) return 1;
 
diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c
index 7bf23e84..434b4673 100644
--- a/src/afl-fuzz-mutators.c
+++ b/src/afl-fuzz-mutators.c
@@ -27,9 +27,6 @@
 #include "afl-fuzz.h"
 
 void load_custom_mutator(afl_state_t *, const char *);
-#ifdef USE_PYTHON
-void load_custom_mutator_py(afl_state_t *, char *);
-#endif
 
 void setup_custom_mutator(afl_state_t *afl) {
 
@@ -239,7 +236,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
 
     write_to_testcase(afl, retbuf, retlen);
 
-    fault = run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
+    fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
     ++afl->trim_execs;
 
     if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; }
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index cc97654a..a4ba739e 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -27,7 +27,7 @@
 
 /* MOpt */
 
-int select_algorithm(afl_state_t *afl) {
+static int select_algorithm(afl_state_t *afl) {
 
   int i_puppet, j_puppet;
 
@@ -2366,7 +2366,7 @@ abandon_entry:
 }
 
 /* MOpt mode */
-u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
+static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
 
   if (!MOpt_globals.is_pilot_mode) {
 
diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c
index 12c3a09d..33f01797 100644
--- a/src/afl-fuzz-python.c
+++ b/src/afl-fuzz-python.c
@@ -41,7 +41,7 @@ it just fills in `&py_mutator->something_buf, &py_mutator->something_size`. */
   (void **)&((py_mutator_t *)py_mutator)->name##_buf, \
       &((py_mutator_t *)py_mutator)->name##_size
 
-size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf,
+static size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf,
                u8 *add_buf, size_t add_buf_size, size_t max_size) {
 
   size_t    mutated_size;
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 6f2fb144..3e9af088 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -37,7 +37,7 @@ struct range {
 
 };
 
-struct range *add_range(struct range *ranges, u32 start, u32 end) {
+static struct range *add_range(struct range *ranges, u32 start, u32 end) {
 
   struct range *r = ck_alloc_nozero(sizeof(struct range));
   r->start = start;
@@ -47,7 +47,7 @@ struct range *add_range(struct range *ranges, u32 start, u32 end) {
 
 }
 
-struct range *pop_biggest_range(struct range **ranges) {
+static struct range *pop_biggest_range(struct range **ranges) {
 
   struct range *r = *ranges;
   struct range *prev = NULL;
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index c3ed59ef..6ad6444a 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -6,7 +6,8 @@
 
    Now maintained by Marc Heuse <mh@mh-sec.de>,
                         Heiko Eißfeldt <heiko.eissfeldt@hexco.de> and
-                        Andrea Fioraldi <andreafioraldi@gmail.com>
+                        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.
@@ -32,10 +33,13 @@
 /* Execute target application, monitoring for timeouts. Return status
    information. The called program will update afl->fsrv->trace_bits. */
 
-fsrv_run_result_t run_target(afl_state_t *afl, afl_forkserver_t *fsrv,
+fsrv_run_result_t fuzz_run_target(afl_state_t *afl, afl_forkserver_t *fsrv,
                              u32 timeout) {
 
-  return afl_fsrv_run_target(fsrv, timeout, classify_counts, &afl->stop_soon);
+  fsrv_run_result_t res = afl_fsrv_run_target(fsrv, timeout, &afl->stop_soon);
+  // TODO: Don't classify for faults?
+  classify_counts(fsrv);
+  return res;
 
 }
 
@@ -45,13 +49,11 @@ fsrv_run_result_t run_target(afl_state_t *afl, afl_forkserver_t *fsrv,
 
 void write_to_testcase(afl_state_t *afl, void *mem, u32 len) {
 
-  s32 fd = afl->fsrv.out_fd;
-
 #ifdef _AFL_DOCUMENT_MUTATIONS
   s32  doc_fd;
   char fn[PATH_MAX];
-  snprintf(fn, PATH_MAX, ("%s/mutations/%09u:%s", afl->out_dir,
-                          afl->document_counter++, describe_op(afl, 0));
+  snprintf(fn, PATH_MAX, "%s/mutations/%09u:%s", afl->out_dir,
+           afl->document_counter++, describe_op(afl, 0));
 
   if ((doc_fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600)) >= 0) {
 
@@ -63,25 +65,6 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) {
 
 #endif
 
-  if (afl->fsrv.out_file) {
-
-    if (afl->no_unlink) {
-
-      fd = open(afl->fsrv.out_file, O_WRONLY | O_CREAT | O_TRUNC, 0600);
-
-    } else {
-
-      unlink(afl->fsrv.out_file);                         /* Ignore errors. */
-      fd = open(afl->fsrv.out_file, O_WRONLY | O_CREAT | O_EXCL, 0600);
-
-    }
-
-    if (fd < 0) PFATAL("Unable to create '%s'", afl->fsrv.out_file);
-
-  } else
-
-    lseek(fd, 0, SEEK_SET);
-
   if (unlikely(afl->mutator && afl->mutator->afl_custom_pre_save)) {
 
     u8 *new_buf = NULL;
@@ -93,24 +76,15 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) {
       FATAL("Custom_pre_save failed (ret: %lu)", (long unsigned)new_size);
 
     /* everything as planned. use the new data. */
-    ck_write(fd, new_buf, new_size, afl->fsrv.out_file);
+    afl_fsrv_write_to_testcase(&afl->fsrv, new_buf, new_size);
 
   } else {
 
     /* boring uncustom. */
-    ck_write(fd, mem, len, afl->fsrv.out_file);
+    afl_fsrv_write_to_testcase(&afl->fsrv, mem, len);
 
   }
 
-  if (!afl->fsrv.out_file) {
-
-    if (ftruncate(fd, len)) PFATAL("ftruncate() failed");
-    lseek(fd, 0, SEEK_SET);
-
-  } else
-
-    close(fd);
-
 }
 
 /* The same, but with an adjustable gap. Used for trimming. */
@@ -217,7 +191,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
 
     write_to_testcase(afl, use_mem, q->len);
 
-    fault = run_target(afl, &afl->fsrv, use_tmout);
+    fault = fuzz_run_target(afl, &afl->fsrv, use_tmout);
 
     /* afl->stop_soon is set by the handler for Ctrl+C. When it's pressed,
        we want to bail out quickly. */
@@ -435,7 +409,7 @@ void sync_fuzzers(afl_state_t *afl) {
 
         write_to_testcase(afl, mem, st.st_size);
 
-        fault = run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
+        fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
 
         if (afl->stop_soon) goto close_sync;
 
@@ -522,7 +496,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
 
       write_with_gap(afl, in_buf, q->len, remove_pos, trim_avail);
 
-      fault = run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
+      fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
       ++afl->trim_execs;
 
       if (afl->stop_soon || fault == FSRV_RUN_ERROR) goto abort_trimming;
@@ -629,7 +603,7 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
 
   write_to_testcase(afl, out_buf, len);
 
-  fault = run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
+  fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
 
   if (afl->stop_soon) return 1;
 
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 9f17b61b..925dbb1a 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -420,6 +420,8 @@ int main(int argc, char **argv_orig, char **envp) {
         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")) {
 
           afl->fsrv.mem_limit = 0;
@@ -474,7 +476,7 @@ int main(int argc, char **argv_orig, char **envp) {
         if (afl->in_bitmap) FATAL("Multiple -B options not supported");
 
         afl->in_bitmap = optarg;
-        read_bitmap(afl, afl->in_bitmap);
+        read_bitmap(afl->in_bitmap, afl->virgin_bits, MAP_SIZE);
         break;
 
       case 'C':                                               /* crash mode */
diff --git a/src/afl-sharedmem.c b/src/afl-sharedmem.c
index 16d6fe41..01ba62aa 100644
--- a/src/afl-sharedmem.c
+++ b/src/afl-sharedmem.c
@@ -60,7 +60,7 @@
 #include <sys/shm.h>
 #endif
 
-list_t shm_list = {.element_prealloc_count = 0};
+static list_t shm_list = {.element_prealloc_count = 0};
 
 /* Get rid of shared memory. */
 
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 2326d469..61c1754f 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -8,7 +8,8 @@
 
    Now maintained by Marc Heuse <mh@mh-sec.de>,
                         Heiko Eißfeldt <heiko.eissfeldt@hexco.de> and
-                        Andrea Fioraldi <andreafioraldi@gmail.com>
+                        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.
@@ -61,8 +62,8 @@
 
 static char *stdin_file;               /* stdin file                        */
 
-static u8 *in_dir,                     /* input folder                      */
-    *at_file = NULL;              /* Substitution string for @@             */
+static u8 *in_dir = NULL,              /* input folder                      */
+    *out_file = NULL, *at_file = NULL;        /* Substitution string for @@ */
 
 static u8 *in_data;                    /* Input data                        */
 
@@ -157,7 +158,7 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
 
     fd = open(outfile, O_WRONLY);
 
-    if (fd < 0) PFATAL("Unable to open '%s'", fsrv->out_file);
+    if (fd < 0) PFATAL("Unable to open '%s'", out_file);
 
   } else if (!strcmp(outfile, "-")) {
 
@@ -215,41 +216,22 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
 
 }
 
-/* Write results. */
-
-static u32 write_results(afl_forkserver_t *fsrv) {
-
-  return write_results_to_file(fsrv, fsrv->out_file);
-
-}
-
-/* Write modified data to file for testing. If use_stdin is clear, the old file
-   is unlinked and a new one is created. Otherwise, out_fd is rewound and
-   truncated. */
-
-static void write_to_testcase(afl_forkserver_t *fsrv, void *mem, u32 len) {
-
-  lseek(fsrv->out_fd, 0, SEEK_SET);
-  ck_write(fsrv->out_fd, mem, len, fsrv->out_file);
-  if (ftruncate(fsrv->out_fd, len)) PFATAL("ftruncate() failed");
-  lseek(fsrv->out_fd, 0, SEEK_SET);
-
-}
-
 /* Execute target application. */
 
-void run_target_forkserver(afl_forkserver_t *fsrv, char **argv, u8 *mem,
+static void showmap_run_target_forkserver(afl_forkserver_t *fsrv, char **argv, u8 *mem,
                            u32 len) {
 
-  write_to_testcase(fsrv, mem, len);
+  afl_fsrv_write_to_testcase(fsrv, mem, len);
 
-  if (afl_fsrv_run_target(fsrv, fsrv->exec_tmout, classify_counts,
-                          &stop_soon) == FSRV_RUN_ERROR) {
+  if (afl_fsrv_run_target(fsrv, fsrv->exec_tmout, &stop_soon) ==
+      FSRV_RUN_ERROR) {
 
     FATAL("Error running target");
 
   }
 
+  classify_counts(fsrv);
+
   if (stop_soon) {
 
     SAYF(cRST cLRD "\n+++ afl-showmap folder mode aborted by user +++\n" cRST);
@@ -261,7 +243,7 @@ void run_target_forkserver(afl_forkserver_t *fsrv, char **argv, u8 *mem,
 
 /* Read initial file. */
 
-u32 read_file(u8 *in_file) {
+static u32 read_file(u8 *in_file) {
 
   struct stat st;
   s32         fd = open(in_file, O_RDONLY);
@@ -286,7 +268,7 @@ u32 read_file(u8 *in_file) {
 
 /* Execute target application. */
 
-static void run_target(afl_forkserver_t *fsrv, char **argv) {
+static void showmap_run_target(afl_forkserver_t *fsrv, char **argv) {
 
   static struct itimerval it;
   int                     status = 0;
@@ -544,62 +526,6 @@ static void usage(u8 *argv0) {
 
 }
 
-/* Find binary. */
-
-static void find_binary(afl_forkserver_t *fsrv, u8 *fname) {
-
-  u8 *        env_path = 0;
-  struct stat st;
-
-  if (strchr(fname, '/') || !(env_path = getenv("PATH"))) {
-
-    fsrv->target_path = ck_strdup(fname);
-
-    if (stat(fsrv->target_path, &st) || !S_ISREG(st.st_mode) ||
-        !(st.st_mode & 0111) || st.st_size < 4)
-      FATAL("Program '%s' not found or not executable", fname);
-
-  } else {
-
-    while (env_path) {
-
-      u8 *cur_elem, *delim = strchr(env_path, ':');
-
-      if (delim) {
-
-        cur_elem = ck_alloc(delim - env_path + 1);
-        memcpy(cur_elem, env_path, delim - env_path);
-        delim++;
-
-      } else
-
-        cur_elem = ck_strdup(env_path);
-
-      env_path = delim;
-
-      if (cur_elem[0])
-        fsrv->target_path = alloc_printf("%s/%s", cur_elem, fname);
-      else
-        fsrv->target_path = ck_strdup(fname);
-
-      ck_free(cur_elem);
-
-      if (!stat(fsrv->target_path, &st) && S_ISREG(st.st_mode) &&
-          (st.st_mode & 0111) && st.st_size >= 4)
-        break;
-
-      ck_free(fsrv->target_path);
-      fsrv->target_path = NULL;
-
-    }
-
-    if (!fsrv->target_path)
-      FATAL("Program '%s' not found or not executable", fname);
-
-  }
-
-}
-
 /* Main entry point */
 
 int main(int argc, char **argv_orig, char **envp) {
@@ -632,8 +558,8 @@ int main(int argc, char **argv_orig, char **envp) {
 
       case 'o':
 
-        if (fsrv->out_file) FATAL("Multiple -o options not supported");
-        fsrv->out_file = optarg;
+        if (out_file) FATAL("Multiple -o options not supported");
+        out_file = optarg;
         break;
 
       case 'm': {
@@ -643,6 +569,8 @@ int main(int argc, char **argv_orig, char **envp) {
         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;
@@ -686,6 +614,8 @@ int main(int argc, char **argv_orig, char **envp) {
         if (timeout_given) FATAL("Multiple -t options not supported");
         timeout_given = 1;
 
+        if (!optarg) FATAL("Wrong usage of -t");
+
         if (strcmp(optarg, "none")) {
 
           fsrv->exec_tmout = atoi(optarg);
@@ -780,7 +710,7 @@ int main(int argc, char **argv_orig, char **envp) {
 
     }
 
-  if (optind == argc || !fsrv->out_file) usage(argv[0]);
+  if (optind == argc || !out_file) usage(argv[0]);
 
   check_environment_vars(envp);
 
@@ -790,7 +720,7 @@ int main(int argc, char **argv_orig, char **envp) {
 
   set_up_environment(fsrv);
 
-  find_binary(fsrv, argv[optind]);
+  fsrv->target_path = find_binary(argv[optind]);
 
   if (!quiet_mode) {
 
@@ -831,7 +761,7 @@ int main(int argc, char **argv_orig, char **envp) {
     DIR *          dir_in, *dir_out;
     struct dirent *dir_ent;
     int            done = 0;
-    u8             infile[4096], outfile[4096];
+    u8             infile[PATH_MAX], outfile[PATH_MAX];
 #if !defined(DT_REG)
     struct stat statbuf;
 #endif
@@ -841,9 +771,9 @@ int main(int argc, char **argv_orig, char **envp) {
 
     if (!(dir_in = opendir(in_dir))) PFATAL("cannot open directory %s", in_dir);
 
-    if (!(dir_out = opendir(fsrv->out_file)))
-      if (mkdir(fsrv->out_file, 0700))
-        PFATAL("cannot create output directory %s", fsrv->out_file);
+    if (!(dir_out = opendir(out_file)))
+      if (mkdir(out_file, 0700))
+        PFATAL("cannot create output directory %s", out_file);
 
     u8 *use_dir = ".";
 
@@ -858,7 +788,7 @@ int main(int argc, char **argv_orig, char **envp) {
     unlink(stdin_file);
     atexit(at_exit_handler);
     fsrv->out_fd = open(stdin_file, O_RDWR | O_CREAT | O_EXCL, 0600);
-    if (fsrv->out_fd < 0) PFATAL("Unable to create '%s'", fsrv->out_file);
+    if (fsrv->out_fd < 0) PFATAL("Unable to create '%s'", out_file);
 
     if (arg_offset && argv[arg_offset] != stdin_file) {
 
@@ -897,12 +827,11 @@ int main(int argc, char **argv_orig, char **envp) {
       if (-1 == stat(infile, &statbuf) || !S_ISREG(statbuf.st_mode)) continue;
 #endif
 
-      snprintf(outfile, sizeof(outfile), "%s/%s", fsrv->out_file,
-               dir_ent->d_name);
+      snprintf(outfile, sizeof(outfile), "%s/%s", out_file, dir_ent->d_name);
 
       if (read_file(infile)) {
 
-        run_target_forkserver(fsrv, use_argv, in_data, in_len);
+        showmap_run_target_forkserver(fsrv, use_argv, in_data, in_len);
         ck_free(in_data);
         tcnt = write_results_to_file(fsrv, outfile);
 
@@ -917,8 +846,8 @@ int main(int argc, char **argv_orig, char **envp) {
 
   } else {
 
-    run_target(fsrv, use_argv);
-    tcnt = write_results(fsrv);
+    showmap_run_target(fsrv, use_argv);
+    tcnt = write_results_to_file(fsrv, out_file);
 
   }
 
@@ -926,7 +855,7 @@ int main(int argc, char **argv_orig, char **envp) {
 
     if (!tcnt) FATAL("No instrumentation detected" cRST);
     OKF("Captured %u tuples (highest value %u, total values %u) in '%s'." cRST,
-        tcnt, highest, total, fsrv->out_file);
+        tcnt, highest, total, out_file);
 
   }
 
diff --git a/src/afl-tmin.c b/src/afl-tmin.c
index 84e9a498..431ff0c4 100644
--- a/src/afl-tmin.c
+++ b/src/afl-tmin.c
@@ -8,7 +8,8 @@
 
    Now maintained by Marc Heuse <mh@mh-sec.de>,
                         Heiko Eißfeldt <heiko.eissfeldt@hexco.de> and
-                        Andrea Fioraldi <andreafioraldi@gmail.com>
+                        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.
@@ -61,7 +62,7 @@
 static u8 *mask_bitmap;                /* Mask for trace bits (-B)          */
 
 static u8 *in_file,                    /* Minimizer input test case         */
-    *output_file;                      /* Minimizer output file             */
+    *out_file, *output_file;           /* Minimizer output file             */
 
 static u8 *in_data;                    /* Input data for trimming           */
 
@@ -120,8 +121,6 @@ static void apply_mask(u32 *mem, u32 *mask) {
 
 static void classify_counts(afl_forkserver_t *fsrv) {
 
-  if (hang_mode) return;                              /* We only want hangs */
-
   u8 *mem = fsrv->trace_bits;
   u32 i = MAP_SIZE;
 
@@ -145,8 +144,6 @@ static void classify_counts(afl_forkserver_t *fsrv) {
 
   }
 
-  apply_mask((u32 *)fsrv->trace_bits, (u32 *)mask_bitmap);
-
 }
 
 /* See if any bytes are set in the bitmap. */
@@ -214,49 +211,16 @@ static s32 write_to_file(u8 *path, u8 *mem, u32 len) {
 
 }
 
-/* Write modified data to file for testing. If use_stdin is clear, the old file
-   is unlinked and a new one is created. Otherwise, out_fd is rewound and
-   truncated. */
-
-static void write_to_testcase(afl_forkserver_t *fsrv, void *mem, u32 len) {
-
-  s32 fd = fsrv->out_fd;
-
-  if (!fsrv->use_stdin) {
-
-    unlink(fsrv->out_file);                               /* Ignore errors. */
-
-    fd = open(fsrv->out_file, O_WRONLY | O_CREAT | O_EXCL, 0600);
-
-    if (fd < 0) PFATAL("Unable to create '%s'", fsrv->out_file);
-
-  } else
-
-    lseek(fd, 0, SEEK_SET);
-
-  ck_write(fd, mem, len, fsrv->out_file);
-
-  if (fsrv->use_stdin) {
-
-    if (ftruncate(fd, len)) PFATAL("ftruncate() failed");
-    lseek(fd, 0, SEEK_SET);
-
-  } else
-
-    close(fd);
-
-}
-
 /* 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,
+static u8 tmin_run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len,
                      u8 first_run) {
 
-  write_to_testcase(fsrv, mem, len);
+  afl_fsrv_write_to_testcase(fsrv, mem, len);
 
   fsrv_run_result_t ret =
-      afl_fsrv_run_target(fsrv, fsrv->exec_tmout, classify_counts, &stop_soon);
+      afl_fsrv_run_target(fsrv, fsrv->exec_tmout, &stop_soon);
 
   if (ret == FSRV_RUN_ERROR) FATAL("Couldn't run child");
 
@@ -282,6 +246,9 @@ static u8 run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len,
 
   }
 
+  classify_counts(fsrv);
+  apply_mask((u32 *)fsrv->trace_bits, (u32 *)mask_bitmap);
+
   if (ret == FSRV_RUN_TMOUT) {
 
     missed_hangs++;
@@ -369,7 +336,7 @@ static void minimize(afl_forkserver_t *fsrv, char **argv) {
       memset(tmp_buf + set_pos, '0', use_len);
 
       u8 res;
-      res = run_target(fsrv, argv, tmp_buf, in_len, 0);
+      res = tmin_run_target(fsrv, argv, tmp_buf, in_len, 0);
 
       if (res) {
 
@@ -442,7 +409,7 @@ next_del_blksize:
     /* Tail */
     memcpy(tmp_buf + del_pos, in_data + del_pos + del_len, tail_len);
 
-    res = run_target(fsrv, argv, tmp_buf, del_pos + tail_len, 0);
+    res = tmin_run_target(fsrv, argv, tmp_buf, del_pos + tail_len, 0);
 
     if (res) {
 
@@ -505,7 +472,7 @@ next_del_blksize:
     for (r = 0; r < in_len; r++)
       if (tmp_buf[r] == i) tmp_buf[r] = '0';
 
-    res = run_target(fsrv, argv, tmp_buf, in_len, 0);
+    res = tmin_run_target(fsrv, argv, tmp_buf, in_len, 0);
 
     if (res) {
 
@@ -541,7 +508,7 @@ next_del_blksize:
     if (orig == '0') continue;
     tmp_buf[i] = '0';
 
-    res = run_target(fsrv, argv, tmp_buf, in_len, 0);
+    res = tmin_run_target(fsrv, argv, tmp_buf, in_len, 0);
 
     if (res) {
 
@@ -613,7 +580,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
   fsrv->dev_null_fd = open("/dev/null", O_RDWR);
   if (fsrv->dev_null_fd < 0) PFATAL("Unable to open /dev/null");
 
-  if (!fsrv->out_file) {
+  if (!out_file) {
 
     u8 *use_dir = ".";
 
@@ -624,15 +591,15 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
 
     }
 
-    fsrv->out_file = alloc_printf("%s/.afl-tmin-temp-%u", use_dir, getpid());
+    out_file = alloc_printf("%s/.afl-tmin-temp-%u", use_dir, getpid());
 
   }
 
-  unlink(fsrv->out_file);
+  unlink(out_file);
 
-  fsrv->out_fd = open(fsrv->out_file, O_RDWR | O_CREAT | O_EXCL, 0600);
+  fsrv->out_fd = open(out_file, O_RDWR | O_CREAT | O_EXCL, 0600);
 
-  if (fsrv->out_fd < 0) PFATAL("Unable to create '%s'", fsrv->out_file);
+  if (fsrv->out_fd < 0) PFATAL("Unable to create '%s'", out_file);
 
   /* Set sane defaults... */
 
@@ -782,76 +749,6 @@ static void usage(u8 *argv0) {
 
 }
 
-/* Find binary. */
-
-static void find_binary(afl_forkserver_t *fsrv, u8 *fname) {
-
-  u8 *        env_path = 0;
-  struct stat st;
-
-  if (strchr(fname, '/') || !(env_path = getenv("PATH"))) {
-
-    fsrv->target_path = ck_strdup(fname);
-
-    if (stat(fsrv->target_path, &st) || !S_ISREG(st.st_mode) ||
-        !(st.st_mode & 0111) || st.st_size < 4)
-      FATAL("Program '%s' not found or not executable", fname);
-
-  } else {
-
-    while (env_path) {
-
-      u8 *cur_elem, *delim = strchr(env_path, ':');
-
-      if (delim) {
-
-        cur_elem = ck_alloc(delim - env_path + 1);
-        memcpy(cur_elem, env_path, delim - env_path);
-        delim++;
-
-      } else
-
-        cur_elem = ck_strdup(env_path);
-
-      env_path = delim;
-
-      if (cur_elem[0])
-        fsrv->target_path = alloc_printf("%s/%s", cur_elem, fname);
-      else
-        fsrv->target_path = ck_strdup(fname);
-
-      ck_free(cur_elem);
-
-      if (!stat(fsrv->target_path, &st) && S_ISREG(st.st_mode) &&
-          (st.st_mode & 0111) && st.st_size >= 4)
-        break;
-
-      ck_free(fsrv->target_path);
-      fsrv->target_path = NULL;
-
-    }
-
-    if (!fsrv->target_path)
-      FATAL("Program '%s' not found or not executable", fname);
-
-  }
-
-}
-
-/* Read mask bitmap from file. This is for the -B option. */
-
-static void read_bitmap(u8 *fname) {
-
-  s32 fd = open(fname, O_RDONLY);
-
-  if (fd < 0) PFATAL("Unable to open '%s'", fname);
-
-  ck_read(fd, mask_bitmap, MAP_SIZE, fname);
-
-  close(fd);
-
-}
-
 /* Main entry point */
 
 int main(int argc, char **argv_orig, char **envp) {
@@ -888,9 +785,9 @@ int main(int argc, char **argv_orig, char **envp) {
 
       case 'f':
 
-        if (fsrv->out_file) FATAL("Multiple -f options not supported");
+        if (out_file) FATAL("Multiple -f options not supported");
         fsrv->use_stdin = 0;
-        fsrv->out_file = optarg;
+        out_file = optarg;
         break;
 
       case 'e':
@@ -914,6 +811,8 @@ int main(int argc, char **argv_orig, char **envp) {
         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;
@@ -950,6 +849,8 @@ int main(int argc, char **argv_orig, char **envp) {
         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] == '-')
@@ -1010,7 +911,7 @@ int main(int argc, char **argv_orig, char **envp) {
 
         if (mask_bitmap) FATAL("Multiple -B options not supported");
         mask_bitmap = ck_alloc(MAP_SIZE);
-        read_bitmap(optarg);
+        read_bitmap(optarg, mask_bitmap, MAP_SIZE);
         break;
 
       case 'h':
@@ -1034,8 +935,8 @@ int main(int argc, char **argv_orig, char **envp) {
 
   set_up_environment(fsrv);
 
-  find_binary(fsrv, argv[optind]);
-  detect_file_args(argv + optind, fsrv->out_file, &fsrv->use_stdin);
+  fsrv->target_path = find_binary(argv[optind]);
+  detect_file_args(argv + optind, out_file, &fsrv->use_stdin);
 
   if (fsrv->qemu_mode) {
 
@@ -1069,7 +970,7 @@ int main(int argc, char **argv_orig, char **envp) {
   ACTF("Performing dry run (mem limit = %llu MB, timeout = %u ms%s)...",
        fsrv->mem_limit, fsrv->exec_tmout, edges_only ? ", edges only" : "");
 
-  run_target(fsrv, use_argv, in_data, in_len, 1);
+  tmin_run_target(fsrv, use_argv, in_data, in_len, 1);
 
   if (hang_mode && !fsrv->last_run_timed_out)
     FATAL(
@@ -1105,9 +1006,9 @@ int main(int argc, char **argv_orig, char **envp) {
 
   ACTF("Writing output to '%s'...", output_file);
 
-  unlink(fsrv->out_file);
-  if (fsrv->out_file) ck_free(fsrv->out_file);
-  fsrv->out_file = NULL;
+  unlink(out_file);
+  if (out_file) ck_free(out_file);
+  out_file = NULL;
 
   close(write_to_file(output_file, in_data, in_len));
 
diff --git a/src/third_party/libradamsa/libradamsa.c b/src/third_party/libradamsa/libradamsa.c
index 27cf91bc..4f5515e5 100644
--- a/src/third_party/libradamsa/libradamsa.c
+++ b/src/third_party/libradamsa/libradamsa.c
@@ -1841,6 +1841,8 @@ static const unsigned char heap[] = {2,3,4,105,111,116,97,2,3,7,112,97,116,116,1
 #include <stdio.h>
 #include <netdb.h>
 
+#include "./radamsa.h"
+
 #ifndef EMULTIHOP
 #define EMULTIHOP -1
 #endif
@@ -2155,17 +2157,17 @@ static word *gc(int size, word *regs) {
 
 /*** OS Interaction and Helpers ***/
 
-static void signal_handler(int signal) {
-   switch (signal) {
-      case SIGINT:
-         breaked |= 2;
-         break;
-      case SIGPIPE:
-         break; /* can cause loop when reporting errors */
-      default:
-         breaked |= 4;
-   }
-}
+//static void signal_handler(int signal) {
+//   switch (signal) {
+//      case SIGINT:
+//         breaked |= 2;
+//         break;
+//      case SIGPIPE:
+//         break; /* can cause loop when reporting errors */
+//      default:
+//         breaked |= 4;
+//   }
+//}
 
 /* list length, no overflow or valid termination checks */
 static uint llen(word *ptr) {
@@ -2176,7 +2178,7 @@ static uint llen(word *ptr) {
    }
    return len;
 }
-
+/*
 static void set_signal_handler(void) {
    struct sigaction sa;
    sa.sa_handler = signal_handler;
@@ -2185,7 +2187,7 @@ static void set_signal_handler(void) {
    sigaction(SIGINT, &sa, NULL);
    sigaction(SIGPIPE, &sa, NULL);
 }
-
+*/
 static word mkpair(word h, word a, word d) {
    word *pair;
    allocate(3, pair);
@@ -30683,7 +30685,7 @@ static void heap_metrics(int *rwords, int *rnobjs) {
       get_obj_metrics(rwords, rnobjs);
    hp = hp_start;
 }
-
+/*
 static void read_heap(const char *path) {
    struct stat st;
    off_t pos = 0;
@@ -30703,25 +30705,26 @@ static void read_heap(const char *path) {
    } while (n && (pos += n) < st.st_size);
    close(fd);
 }
+*/
 
 /* find a fasl image source to *hp or exit */
-static void find_heap(int *nargs, char ***argv, int *nobjs, int *nwords) {
-   file_heap = NULL;
-   if ((word)heap == 0) {
+//static void find_heap(int *nargs, char ***argv, int *nobjs, int *nwords) {
+//   file_heap = NULL;
+//   if ((word)heap == 0) {
       /* if no preloaded heap, try to load it from first vm arg */
-      if (*nargs < 2)
-         exit(1);
-      read_heap(argv[0][1]);
-      ++*argv;
-      --*nargs;
-      hp = file_heap;
-      if (*hp == '#')
-         while (*hp++ != '\n');
-   } else {
-      hp = heap; /* builtin heap */
-   }
-   heap_metrics(nwords, nobjs);
-}
+//      if (*nargs < 2)
+//         exit(1);
+//      read_heap(argv[0][1]);
+//      ++*argv;
+//      --*nargs;
+//      hp = file_heap;
+//      if (*hp == '#')
+//         while (*hp++ != '\n');
+//   } else {
+//      hp = heap; /* builtin heap */
+//   }
+//   heap_metrics(nwords, nobjs);
+//}
 
 static word *decode_fasl(uint nobjs) {
    word *ptrs;
@@ -30744,7 +30747,7 @@ static word *load_heap(uint nobjs) {
       free(file_heap);
    return entry;
 }
-
+/*
 static void setup(int nwords, int nobjs) {
    tcgetattr(0, &tsettings);
    state = IFALSE;
@@ -30757,7 +30760,7 @@ static void setup(int nwords, int nobjs) {
    memend = memstart + nwords - MEMPAD;
 }
 
-int secondary(int nargs, char **argv) {
+static int secondary(int nargs, char **argv) {
    word *prog;
    int rval, nobjs=0, nwords=0;
    find_heap(&nargs, &argv, &nobjs, &nwords);
@@ -30772,6 +30775,7 @@ int secondary(int nargs, char **argv) {
    }
    return 127;
 }
+*/
 
 void radamsa_init(void) {
    int nobjs=0, nwords=0;
@@ -30787,7 +30791,7 @@ void radamsa_init(void) {
 }
 
 /* bvec → value library call test with preserved state */
-word library_call(word val) {
+static word library_call(word val) {
    word program_state = state;
    word res;
    state = IFALSE; 
@@ -30798,7 +30802,8 @@ word library_call(word val) {
    return res;
 }
 
-size_t list_length(word lispval) {
+/*
+static size_t list_length(word lispval) {
    size_t l = 0;
    while(lispval != INULL) {
       lispval = G(lispval, 2);
@@ -30806,8 +30811,9 @@ size_t list_length(word lispval) {
    }
    return l;
 }
+*/
 
-size_t copy_list(uint8_t *ptr, word lispval, size_t max) {
+static size_t copy_list(uint8_t *ptr, word lispval, size_t max) {
    size_t n = 0;
    while(pairp((word)lispval) && max-- && lispval != INULL) {
       *ptr++ = 255 & immval(G(lispval, 1)); // *ptr++ = car(list)
diff --git a/src/third_party/libradamsa/radamsa.h b/src/third_party/libradamsa/radamsa.h
index 33cccde4..073599da 100644
--- a/src/third_party/libradamsa/radamsa.h
+++ b/src/third_party/libradamsa/radamsa.h
@@ -1,13 +1,13 @@
 #include <inttypes.h>
 #include <stddef.h>
 
-extern void radamsa_init(void);
+void radamsa_init(void);
 
-extern size_t radamsa(uint8_t *ptr, size_t len,
+size_t radamsa(uint8_t *ptr, size_t len,
                       uint8_t *target, size_t max,
                       unsigned int seed);
 
-extern size_t radamsa_inplace(uint8_t *ptr,
+size_t radamsa_inplace(uint8_t *ptr,
                               size_t len,
                               size_t max,
                               unsigned int seed);
diff --git a/test/unittests/unit_list.c b/test/unittests/unit_list.c
index 11d3227c..90700a11 100644
--- a/test/unittests/unit_list.c
+++ b/test/unittests/unit_list.c
@@ -27,6 +27,7 @@ extern void mock_assert(const int result, const char* const expression,
     (compile with `--wrap=exit`) */
 extern void exit(int status);
 extern void __real_exit(int status);
+void __wrap_exit(int status);
 void __wrap_exit(int status) {
     assert(0);
 }
@@ -34,6 +35,7 @@ void __wrap_exit(int status) {
 /* ignore all printfs */
 extern int printf(const char *format, ...);
 extern int __real_printf(const char *format, ...);
+int __wrap_printf(const char *format, ...);
 int __wrap_printf(const char *format, ...) {
     return 1;
 }
diff --git a/test/unittests/unit_maybe_alloc.c b/test/unittests/unit_maybe_alloc.c
index d9c037a0..8cd8b11a 100644
--- a/test/unittests/unit_maybe_alloc.c
+++ b/test/unittests/unit_maybe_alloc.c
@@ -22,6 +22,7 @@ extern void mock_assert(const int result, const char* const expression,
     mock_assert((int)(expression), #expression, __FILE__, __LINE__);
 #include "alloc-inl.h"
 
+void __wrap_exit(int status);
 /* remap exit -> assert, then use cmocka's mock_assert
     (compile with `--wrap=exit`) */
 extern void exit(int status);
@@ -30,6 +31,7 @@ void __wrap_exit(int status) {
     assert(0);
 }
 
+int __wrap_printf(const char *format, ...);
 /* ignore all printfs */
 extern int printf(const char *format, ...);
 extern int __real_printf(const char *format, ...);
diff --git a/test/unittests/unit_preallocable.c b/test/unittests/unit_preallocable.c
index 8cd36165..8d619b78 100644
--- a/test/unittests/unit_preallocable.c
+++ b/test/unittests/unit_preallocable.c
@@ -27,6 +27,7 @@ extern void mock_assert(const int result, const char* const expression,
     (compile with `--wrap=exit`) */
 extern void exit(int status);
 extern void __real_exit(int status);
+void __wrap_exit(int status);
 void __wrap_exit(int status) {
     assert(0);
 }
@@ -34,6 +35,7 @@ void __wrap_exit(int status) {
 /* ignore all printfs */
 extern int printf(const char *format, ...);
 extern int __real_printf(const char *format, ...);
+int __wrap_printf(const char *format, ...);
 int __wrap_printf(const char *format, ...) {
     return 1;
 }