about summary refs log tree commit diff
diff options
context:
space:
mode:
m---------custom_mutators/grammar_mutator/grammar_mutator0
-rw-r--r--docs/Changelog.md8
-rw-r--r--docs/life_pro_tips.md87
-rw-r--r--frida_mode/GNUmakefile23
-rw-r--r--frida_mode/README.md14
-rw-r--r--frida_mode/include/instrument.h1
-rw-r--r--frida_mode/include/ranges.h2
-rw-r--r--frida_mode/src/instrument/instrument.c1
-rw-r--r--frida_mode/src/instrument/instrument_arm32.c4
-rw-r--r--frida_mode/src/instrument/instrument_arm64.c3
-rw-r--r--frida_mode/src/instrument/instrument_x64.c369
-rw-r--r--frida_mode/src/instrument/instrument_x86.c3
-rw-r--r--frida_mode/src/ranges.c13
-rw-r--r--frida_mode/src/seccomp/seccomp_atomic.c2
-rw-r--r--frida_mode/src/seccomp/seccomp_callback.c2
-rw-r--r--frida_mode/src/seccomp/seccomp_child.c2
-rw-r--r--frida_mode/src/seccomp/seccomp_event.c2
-rw-r--r--frida_mode/src/seccomp/seccomp_filter.c2
-rw-r--r--frida_mode/src/seccomp/seccomp_print.c2
-rw-r--r--frida_mode/src/seccomp/seccomp_socket.c2
-rw-r--r--frida_mode/src/seccomp/seccomp_syscall.c2
-rw-r--r--include/afl-fuzz.h1
-rw-r--r--instrumentation/SanitizerCoveragePCGUARD.so.cc2
-rw-r--r--instrumentation/afl-llvm-lto-instrumentation.so.cc4
-rw-r--r--instrumentation/afl-llvm-lto-instrumentlist.so.cc5
-rw-r--r--src/afl-forkserver.c6
-rw-r--r--src/afl-fuzz-init.c37
-rw-r--r--src/afl-fuzz-run.c30
-rw-r--r--src/afl-fuzz-stats.c49
-rw-r--r--src/afl-fuzz.c17
-rw-r--r--src/afl-showmap.c11
-rw-r--r--unicorn_mode/UNICORNAFL_VERSION2
-rw-r--r--unicorn_mode/samples/speedtest/rust/src/main.rs23
m---------unicorn_mode/unicornafl0
34 files changed, 384 insertions, 347 deletions
diff --git a/custom_mutators/grammar_mutator/grammar_mutator b/custom_mutators/grammar_mutator/grammar_mutator
-Subproject eedf07ddb0fb1f437f5e76b77cfd4064cf6a5d6
+Subproject b79d51a8daccbd7a693f9b6765c81ead14f28e2
diff --git a/docs/Changelog.md b/docs/Changelog.md
index dad5fee2..63896622 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -16,11 +16,16 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
     - fix a regression introduced in 3.10 that resulted in less
       coverage being detected. thanks to Collin May for reporting!
     - fix -n dumb mode (nobody should use this)
+    - fix stability issue with LTO and cmplog
+    - better banner
+  - frida_mode: David Carlier added Android support :)
   - afl-showmap, afl-tmin and afl-analyze now honor persistent mode
     for more speed. thanks to dloffre-snl for reporting!
+  - Prevent accidently killing non-afl/fuzz services when aborting
+    afl-showmap and other tools.
   - afl-cc:
     - fix for shared linking on MacOS
-    - llvm and LTO mode verified to work with new llvm 14-dev
+    - llvm and LTO mode modified to work with new llvm 14-dev (again)
   - added the very good grammar mutator "GramaTron" to the
     custom_mutators
   - added optimin, a faster and better corpus minimizer by
@@ -32,6 +37,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
   - fix AFL_PRELOAD issues on MacOS
   - removed utils/afl_frida because frida_mode/ is now so much better
   - added uninstall target to makefile (todo: update new readme!)
+  - removed indirections in rust callbacks for unicornafl
 
 
 ### Version ++3.14c (release)
diff --git a/docs/life_pro_tips.md b/docs/life_pro_tips.md
deleted file mode 100644
index e79bcafa..00000000
--- a/docs/life_pro_tips.md
+++ /dev/null
@@ -1,87 +0,0 @@
-# AFL "Life Pro Tips"
-
-Bite-sized advice for those who understand the basics, but can't be bothered
-to read or memorize every other piece of documentation for AFL.
-
-## Get more bang for your buck by using fuzzing dictionaries.
-
-See [dictionaries/README.md](../dictionaries/README.md) to learn how.
-
-## You can get the most out of your hardware by parallelizing AFL jobs.
-
-See [parallel_fuzzing.md](parallel_fuzzing.md) for step-by-step tips.
-
-## Improve the odds of spotting memory corruption bugs with libdislocator.so!
-
-It's easy. Consult [utils/libdislocator/README.md](../utils/libdislocator/README.md) for usage tips.
-
-## Want to understand how your target parses a particular input file?
-
-Try the bundled `afl-analyze` tool; it's got colors and all!
-
-## You can visually monitor the progress of your fuzzing jobs.
-
-Run the bundled `afl-plot` utility to generate browser-friendly graphs.
-
-## Need to monitor AFL jobs programmatically? 
-Check out the `fuzzer_stats` file in the AFL output dir or try `afl-whatsup`.
-
-## Puzzled by something showing up in red or purple in the AFL UI?
-It could be important - consult [status_screen.md](status_screen.md) right away!
-
-## Know your target? Convert it to persistent mode for a huge performance gain!
-Consult section #5 in [instrumentation/README.llvm.md](../instrumentation/README.llvm.md) for tips.
-
-## Using clang? 
-Check out [instrumentation/](../instrumentation/) for a faster alternative to afl-gcc!
-
-## Did you know that AFL can fuzz closed-source or cross-platform binaries?
-Check out [qemu_mode/README.md](../qemu_mode/README.md) and [unicorn_mode/README.md](../unicorn_mode/README.md) for more.
-
-## Did you know that afl-fuzz can minimize any test case for you?
-Try the bundled `afl-tmin` tool - and get small repro files fast!
-
-## Not sure if a crash is exploitable? AFL can help you figure it out. Specify
-`-C` to enable the peruvian were-rabbit mode.
-
-## Trouble dealing with a machine uprising? Relax, we've all been there.
-
-Find essential survival tips at [http://lcamtuf.coredump.cx/prep/](http://lcamtuf.coredump.cx/prep/).
-
-## Want to automatically spot non-crashing memory handling bugs?
-
-Try running an AFL-generated corpus through ASAN, MSAN, or Valgrind.
-
-## Good selection of input files is critical to a successful fuzzing job.
-
-See [perf_tips.md](perf_tips.md) for pro tips.
-
-## You can improve the odds of automatically spotting stack corruption issues.
-
-Specify `AFL_HARDEN=1` in the environment to enable hardening flags.
-
-## Bumping into problems with non-reproducible crashes? 
-It happens, but usually
-isn't hard to diagnose. See section #7 in README.md for tips.
-
-## Fuzzing is not just about memory corruption issues in the codebase. 
-Add some
-sanity-checking `assert()` / `abort()` statements to effortlessly catch logic bugs.
-
-## Hey kid... pssst... want to figure out how AFL really works?
-
-Check out [technical_details.md](technical_details.md) for all the gory details in one place!
-
-## There's a ton of third-party helper tools designed to work with AFL!
-
-Be sure to check out [sister_projects.md](sister_projects.md) before writing your own.
-
-## Need to fuzz the command-line arguments of a particular program?
-
-You can find a simple solution in [utils/argv_fuzzing](../utils/argv_fuzzing/).
-
-## Attacking a format that uses checksums? 
-
-Remove the checksum-checking code or use a postprocessor!
-See `afl_custom_post_process` in [custom_mutators/examples/example.c](../custom_mutators/examples/example.c) for more.
-
diff --git a/frida_mode/GNUmakefile b/frida_mode/GNUmakefile
index 3e35e2f6..ed35c9f6 100644
--- a/frida_mode/GNUmakefile
+++ b/frida_mode/GNUmakefile
@@ -30,8 +30,7 @@ AFL_CFLAGS:=-Wno-unused-parameter \
 
 LDFLAGS+=-shared \
 		 -lpthread \
-		 -lresolv \
-		 -ldl
+		 -lresolv
 
 ifdef DEBUG
 CFLAGS+=-Werror \
@@ -71,7 +70,9 @@ ifdef DEBUG
 endif
 LDFLAGS+=	-z noexecstack \
 			-Wl,--gc-sections \
-			-Wl,--exclude-libs,ALL
+			-Wl,--exclude-libs,ALL \
+		    -ldl \
+		    -lrt
 LDSCRIPT:=-Wl,--version-script=$(PWD)frida.map
 endif
 
@@ -79,6 +80,22 @@ ifeq "$(shell uname)" "Linux"
  OS:=linux
 endif
 
+ifneq "$(findstring android, $(shell $(CC) --version 2>/dev/null))" ""
+ OS:=android
+ ifneq "$(findstring aarch64, $(shell $(CC) --version 2>/dev/null))" ""
+   ARCH:=arm64
+ endif
+ ifneq "$(findstring arm, $(shell $(CC) --version 2>/dev/null))" ""
+   ARCH:=arm
+ endif
+ ifneq "$(findstring x86_64, $(shell $(CC) --version 2>/dev/null))" ""
+   ARCH:=x86_64
+ endif
+ ifneq "$(findstring i686, $(shell $(CC) --version 2>/dev/null))" ""
+   ARCH:=x86
+ endif
+endif
+
 ifndef OS
  $(error "Operating system unsupported")
 endif
diff --git a/frida_mode/README.md b/frida_mode/README.md
index 165f8089..df40c771 100644
--- a/frida_mode/README.md
+++ b/frida_mode/README.md
@@ -55,6 +55,20 @@ tests in 32-bit mode, run `make ARCH=x86 frida`. When switching between
 architectures it may be necessary to run `make clean` first for a given build
 target to remove previously generated binaries for a different architecture.
 
+### Android
+
+In order to build, you need to download the Android SDK.
+
+```
+https://developer.android.com/ndk/downloads
+```
+
+Then creating locally a standalone chain as follow.
+
+```
+https://developer.android.com/ndk/guides/standalone_toolchain
+```
+
 ## Usage
 
 FRIDA mode added some small modifications to `afl-fuzz` and similar tools
diff --git a/frida_mode/include/instrument.h b/frida_mode/include/instrument.h
index 909b2a2c..cac5ee93 100644
--- a/frida_mode/include/instrument.h
+++ b/frida_mode/include/instrument.h
@@ -29,6 +29,7 @@ GumStalkerTransformer *instrument_get_transformer(void);
 /* Functions to be implemented by the different architectures */
 gboolean instrument_is_coverage_optimize_supported(void);
 
+void instrument_coverage_optimize_init(void);
 void instrument_coverage_optimize(const cs_insn *   instr,
                                   GumStalkerOutput *output);
 
diff --git a/frida_mode/include/ranges.h b/frida_mode/include/ranges.h
index 0220a59d..3bd9eaa6 100644
--- a/frida_mode/include/ranges.h
+++ b/frida_mode/include/ranges.h
@@ -10,6 +10,8 @@ extern gboolean ranges_inst_jit;
 void ranges_config(void);
 void ranges_init(void);
 
+void ranges_print_debug_maps(void);
+
 gboolean range_is_excluded(GumAddress address);
 
 void ranges_exclude();
diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c
index 71d9bdf6..81d85aa1 100644
--- a/frida_mode/src/instrument/instrument.c
+++ b/frida_mode/src/instrument/instrument.c
@@ -356,6 +356,7 @@ void instrument_init(void) {
       instrument_hash_seed);
   instrument_hash_zero = instrument_get_offset_hash(0);
 
+  instrument_coverage_optimize_init();
   instrument_debug_init();
   instrument_coverage_init();
   asan_init();
diff --git a/frida_mode/src/instrument/instrument_arm32.c b/frida_mode/src/instrument/instrument_arm32.c
index 0e15940a..4b0a648e 100644
--- a/frida_mode/src/instrument/instrument_arm32.c
+++ b/frida_mode/src/instrument/instrument_arm32.c
@@ -22,6 +22,10 @@ void instrument_coverage_optimize(const cs_insn *   instr,
 
 }
 
+void instrument_coverage_optimize_init(void) {
+  WARNF("Optimized coverage not supported on this architecture");
+}
+
 void instrument_flush(GumStalkerOutput *output) {
 
   gum_arm_writer_flush(output->writer.arm);
diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c
index cf37e048..80d1d845 100644
--- a/frida_mode/src/instrument/instrument_arm64.c
+++ b/frida_mode/src/instrument/instrument_arm64.c
@@ -95,6 +95,9 @@ void instrument_coverage_optimize(const cs_insn *   instr,
 
 }
 
+void instrument_coverage_optimize_init(void) {
+}
+
 void instrument_flush(GumStalkerOutput *output) {
 
   gum_arm64_writer_flush(output->writer.arm64);
diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c
index 1c2cf113..a7eb650a 100644
--- a/frida_mode/src/instrument/instrument_x64.c
+++ b/frida_mode/src/instrument/instrument_x64.c
@@ -1,4 +1,16 @@
+#include <fcntl.h>
 #include <stddef.h>
+#include <sys/mman.h>
+#include <sys/shm.h>
+
+#if defined(__linux__)
+#if !defined(__ANDROID__)
+#include <asm/prctl.h>
+#include <sys/syscall.h>
+#else
+#include <linux/ashmem.h>
+#endif
+#endif
 
 #include "frida-gumjs.h"
 
@@ -6,245 +18,290 @@
 #include "debug.h"
 
 #include "instrument.h"
+#include "ranges.h"
 
 #if defined(__x86_64__)
 
-static GumAddress current_log_impl = GUM_ADDRESS(0);
+#ifndef MAP_FIXED_NOREPLACE
+  #ifdef MAP_EXCL
+    #define MAP_FIXED_NOREPLACE MAP_EXCL | MAP_FIXED
+  #else
+    #define MAP_FIXED_NOREPLACE MAP_FIXED
+  #endif
+#endif
 
-  #pragma pack(push, 1)
+gboolean instrument_is_coverage_optimize_supported(void) {
 
+  return true;
+
+}
+
+static gboolean instrument_coverage_in_range(gssize offset) {
+
+  return (offset >= G_MININT32 && offset <= G_MAXINT32);
+
+}
+
+  #pragma pack(push, 1)
 typedef struct {
 
-  /*
-   * pushfq
-   * push rdx
-   * mov rdx, [&previouspc] (rip relative addr)
-   * xor rdx, rdi (current_pc)
-   * shr rdi. 1
-   * mov [&previouspc], rdi
-   * lea rsi, [&_afl_area_ptr] (rip relative)
-   * add rdx, rsi
-   * add byte ptr [rdx], 1
-   * adc byte ptr [rdx], 0
-
-   * pop rdx
-   * popfq
-   */
+  // cur_location = (block_address >> 4) ^ (block_address << 8);
+  // shared_mem[cur_location ^ prev_location]++;
+  // prev_location = cur_location >> 1;
+
+  // => 0x7ffff6cfb086:      lea    rsp,[rsp-0x80]
+  //    0x7ffff6cfb08b:      pushf
+  //    0x7ffff6cfb08c:      push   rsi
+  //    0x7ffff6cfb08d:      mov    rsi,0x228
+  //    0x7ffff6cfb094:      xchg   QWORD PTR [rip+0x3136a5],rsi        # 0x7ffff700e740
+  //    0x7ffff6cfb09b:      xor    rsi,0x451
+  //    0x7ffff6cfb0a2:      add    BYTE PTR [rsi+0x10000],0x1
+  //    0x7ffff6cfb0a9:      adc    BYTE PTR [rsi+0x10000],0x0
+  //    0x7ffff6cfb0b0:      pop    rsi
+  //    0x7ffff6cfb0b1:      popf
+  //    0x7ffff6cfb0b2:      lea    rsp,[rsp+0x80]
+
+
+  uint8_t lea_rsp_rsp_sub_rz[5];
   uint8_t push_fq;
-  uint8_t push_rdx;
-  uint8_t mov_rdx_rip_off[7];
-  uint8_t xor_rdx_rdi[3];
-  uint8_t shr_rdi[3];
-  uint8_t mov_rip_off_rdi[7];
-
-  uint8_t lea_rdi_rip_off[7];
-  uint8_t add_rdx_rdi[3];
-  uint8_t add_byte_ptr_rdx[3];
-  uint8_t adc_byte_ptr_rdx[3];
-
-  uint8_t pop_rdx;
+  uint8_t push_rsi;
+
+  uint8_t mov_rsi_curr_loc_shr_1[7];
+  uint8_t xchg_rsi_prev_loc_curr_loc[7];
+  uint8_t xor_rsi_curr_loc[7];
+
+  uint8_t add_rsi_1[7];
+  uint8_t adc_rsi_0[7];
+
+  uint8_t pop_rsi;
   uint8_t pop_fq;
-  uint8_t ret;
+  uint8_t lsa_rsp_rsp_add_rz[8];
 
 } afl_log_code_asm_t;
 
   #pragma pack(pop)
 
-  #pragma pack(push, 8)
-typedef struct {
+typedef union {
 
-  afl_log_code_asm_t assembly;
-  uint64_t           current_pc;
+  afl_log_code_asm_t code;
+  uint8_t            bytes[0];
 
-} afl_log_code_t;
+} afl_log_code;
 
-  #pragma pack(pop)
+static const afl_log_code_asm_t template =
+    {
 
-typedef union {
+        .lea_rsp_rsp_sub_rz = {0x48, 0x8D, 0x64, 0x24, 0x80},
+        .push_fq = 0x9c,
+        .push_rsi = 0x56,
 
-  afl_log_code_t data;
-  uint8_t        bytes[0];
+        .mov_rsi_curr_loc_shr_1 = {0x48, 0xC7, 0xC6},
+        .xchg_rsi_prev_loc_curr_loc = {0x48, 0x87, 0x35},
+        .xor_rsi_curr_loc = {0x48, 0x81, 0xF6},
 
-} afl_log_code;
+        .add_rsi_1 = {0x80, 0x86, 0x00, 0x00, 0x00, 0x00, 0x01},
+        .adc_rsi_0 = {0x80, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00},
 
-static const afl_log_code_asm_t template = {
+        .pop_rsi = 0x5E,
+        .pop_fq = 0x9D,
+        .lsa_rsp_rsp_add_rz = {0x48, 0x8D, 0xA4, 0x24, 0x80, 0x00, 0x00, 0x00},
 
-    .push_fq = 0x9c,
-    .push_rdx = 0x52,
-    .mov_rdx_rip_off =
-        {
+}
 
-            0x48, 0x8b, 0x15,
-            /* TBC */
+;
 
-        },
+static gboolean instrument_coverage_find_low(const GumRangeDetails *details,
+                                             gpointer               user_data) {
 
-    .xor_rdx_rdi =
-        {
+  static GumAddress last_limit = (64ULL << 10);
+  gpointer *        address = (gpointer *)user_data;
 
-            0x48,
-            0x31,
-            0xfa,
+  if ((details->range->base_address - last_limit) > __afl_map_size) {
 
-        },
+    *address = GSIZE_TO_POINTER(last_limit);
+    return FALSE;
 
-    .shr_rdi = {0x48, 0xd1, 0xef},
-    .mov_rip_off_rdi = {0x48, 0x89, 0x3d},
+  }
 
-    .lea_rdi_rip_off =
-        {
+  if (details->range->base_address > ((2ULL << 20) - __afl_map_size)) {
 
-            0x48,
-            0x8d,
-            0x3d,
+    return FALSE;
 
-        },
+  }
 
-    .add_rdx_rdi = {0x48, 0x01, 0xfA},
+  last_limit = details->range->base_address + details->range->size;
+  return TRUE;
 
-    .add_byte_ptr_rdx =
-        {
+}
 
-            0x80,
-            0x02,
-            0x01,
+static void instrument_coverage_optimize_map_mmap_anon(gpointer address) {
 
-        },
+  __afl_area_ptr =
+      mmap(address, __afl_map_size, PROT_READ | PROT_WRITE,
+           MAP_FIXED_NOREPLACE | MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+  if (__afl_area_ptr != address) {
 
-    .adc_byte_ptr_rdx =
-        {
+    FATAL("Failed to map mmap __afl_area_ptr: %d", errno);
 
-            0x80,
-            0x12,
-            0x00,
+  }
 
-        },
+}
 
-    .pop_rdx = 0x5a,
-    .pop_fq = 0x9d,
-    .ret = 0xc3};
+static void instrument_coverage_optimize_map_mmap(char *   shm_file_path,
+                                                  gpointer address) {
 
-static guint8 align_pad[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
+  int shm_fd = -1;
 
-gboolean instrument_is_coverage_optimize_supported(void) {
+  if (munmap(__afl_area_ptr, __afl_map_size) != 0) {
 
-  return true;
+    FATAL("Failed to unmap previous __afl_area_ptr");
 
-}
+  }
 
-static gboolean instrument_coverage_in_range(gssize offset) {
+  __afl_area_ptr = NULL;
 
-  return (offset >= G_MININT32 && offset <= G_MAXINT32);
+#if !defined(__ANDROID__)
+  shm_fd = shm_open(shm_file_path, O_RDWR, DEFAULT_PERMISSION);
+  if (shm_fd == -1) { FATAL("shm_open() failed\n"); }
+#else
+  shm_fd = open("/dev/ashmem", O_RDWR);
+  if (shm_fd == -1) { FATAL("open() failed\n"); }
+  if (ioctl(shm_fd, ASHMEM_SET_NAME, shm_file_path) == -1) { FATAL("ioctl(ASHMEM_SET_NAME) failed"); }
+  if (ioctl(shm_fd, ASHMEM_SET_SIZE, __afl_map_size) == -1) { FATAL("ioctl(ASHMEM_SET_SIZE) failed"); }
+
+#endif
+
+  __afl_area_ptr = mmap(address, __afl_map_size, PROT_READ | PROT_WRITE,
+                        MAP_FIXED_NOREPLACE | MAP_SHARED, shm_fd, 0);
+  if (__afl_area_ptr != address) {
+
+    FATAL("Failed to map mmap __afl_area_ptr: %d", errno);
+
+  }
+
+  if (close(shm_fd) != 0) { FATAL("Failed to close shm_fd"); }
 
 }
 
-static void instrument_coverate_write_function(GumStalkerOutput *output) {
+static void instrument_coverage_optimize_map_shm(guint64  shm_env_val,
+                                                 gpointer address) {
 
-  guint64       misalign = 0;
-  GumX86Writer *cw = output->writer.x86;
-  GumAddress    code_addr = 0;
-  afl_log_code  code = {0};
-  /*guint64       instrument_hash_zero = 0;*/
+  if (shmdt(__afl_area_ptr) != 0) {
 
-  if (current_log_impl == 0 ||
-      !gum_x86_writer_can_branch_directly_between(cw->pc, current_log_impl) ||
-      !gum_x86_writer_can_branch_directly_between(cw->pc + 128,
-                                                  current_log_impl)) {
+    FATAL("Failed to detach previous __afl_area_ptr");
 
-    gconstpointer after_log_impl = cw->code + 1;
+  }
 
-    gum_x86_writer_put_jmp_near_label(cw, after_log_impl);
+  __afl_area_ptr = shmat(shm_env_val, address, 0);
+  if (__afl_area_ptr != address) {
 
-    misalign = (cw->pc & 0x7);
-    if (misalign != 0) {
+    FATAL("Failed to map shm __afl_area_ptr: %d", errno);
 
-      gum_x86_writer_put_bytes(cw, align_pad, 8 - misalign);
+  }
 
-    }
+}
 
-    current_log_impl = cw->pc;
-    // gum_x86_writer_put_breakpoint(cw);
-    code_addr = cw->pc;
+void instrument_coverage_optimize_init(void) {
 
-    code.data.assembly = template;
-    code.data.current_pc = instrument_get_offset_hash(0);
+  gpointer low_address = NULL;
 
-    gssize current_pc_value1 =
-        GPOINTER_TO_SIZE(&instrument_previous_pc) -
-        (code_addr + offsetof(afl_log_code, data.assembly.mov_rdx_rip_off) +
-         sizeof(code.data.assembly.mov_rdx_rip_off));
-    gssize patch_offset1 =
-        offsetof(afl_log_code, data.assembly.mov_rdx_rip_off) +
-        sizeof(code.data.assembly.mov_rdx_rip_off) - sizeof(gint);
-    if (!instrument_coverage_in_range(current_pc_value1)) {
+  gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, instrument_coverage_find_low,
+                               &low_address);
 
-      FATAL("Patch out of range (current_pc_value1): 0x%016lX",
-            current_pc_value1);
+  OKF("Low address: %p", low_address);
 
-    }
+  if (low_address == 0 ||
+      GPOINTER_TO_SIZE(low_address) > ((2UL << 20) - __afl_map_size)) {
 
-    gint *dst_pc_value = (gint *)&code.bytes[patch_offset1];
-    *dst_pc_value = (gint)current_pc_value1;
+    FATAL("Invalid low_address: %p", low_address);
 
-    gssize current_pc_value2 =
-        GPOINTER_TO_SIZE(&instrument_previous_pc) -
-        (code_addr + offsetof(afl_log_code, data.assembly.mov_rip_off_rdi) +
-         sizeof(code.data.assembly.mov_rip_off_rdi));
-    gssize patch_offset2 =
-        offsetof(afl_log_code, data.assembly.mov_rip_off_rdi) +
-        sizeof(code.data.assembly.mov_rip_off_rdi) - sizeof(gint);
+  }
 
-    if (!instrument_coverage_in_range(current_pc_value2)) {
+  ranges_print_debug_maps();
 
-      FATAL("Patch out of range (current_pc_value2): 0x%016lX",
-            current_pc_value2);
+  char *shm_env = getenv(SHM_ENV_VAR);
+  OKF("SHM_ENV_VAR: %s", shm_env);
 
-    }
+  if (shm_env == NULL) {
 
-    dst_pc_value = (gint *)&code.bytes[patch_offset2];
-    *dst_pc_value = (gint)current_pc_value2;
+    WARNF("SHM_ENV_VAR not set, using anonymous map for debugging purposes");
 
-    gsize afl_area_ptr_value =
-        GPOINTER_TO_SIZE(__afl_area_ptr) -
-        (code_addr + offsetof(afl_log_code, data.assembly.lea_rdi_rip_off) +
-         sizeof(code.data.assembly.lea_rdi_rip_off));
-    gssize afl_area_ptr_offset =
-        offsetof(afl_log_code, data.assembly.lea_rdi_rip_off) +
-        sizeof(code.data.assembly.lea_rdi_rip_off) - sizeof(gint);
+    instrument_coverage_optimize_map_mmap_anon(low_address);
 
-    if (!instrument_coverage_in_range(afl_area_ptr_value)) {
+  } else {
 
-      FATAL("Patch out of range (afl_area_ptr_value): 0x%016lX",
-            afl_area_ptr_value);
+    guint64 shm_env_val = g_ascii_strtoull(shm_env, NULL, 10);
 
-    }
+    if (shm_env_val == 0) {
 
-    gint *dst_afl_area_ptr_value = (gint *)&code.bytes[afl_area_ptr_offset];
-    *dst_afl_area_ptr_value = (gint)afl_area_ptr_value;
+      instrument_coverage_optimize_map_mmap(shm_env, low_address);
 
-    gum_x86_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code));
+    } else {
 
-    gum_x86_writer_put_label(cw, after_log_impl);
+      instrument_coverage_optimize_map_shm(shm_env_val, low_address);
+
+    }
 
   }
 
+  OKF("__afl_area_ptr: %p", __afl_area_ptr);
+  OKF("instrument_previous_pc: %p", &instrument_previous_pc);
+
 }
 
 void instrument_coverage_optimize(const cs_insn *   instr,
                                   GumStalkerOutput *output) {
 
+  afl_log_code  code = {0};
   GumX86Writer *cw = output->writer.x86;
   guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address));
-  instrument_coverate_write_function(output);
-
-  gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP,
-                                        -GUM_RED_ZONE_SIZE);
-  gum_x86_writer_put_push_reg(cw, GUM_REG_RDI);
-  gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RDI, area_offset);
-  gum_x86_writer_put_call_address(cw, current_log_impl);
-  gum_x86_writer_put_pop_reg(cw, GUM_REG_RDI);
-  gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP,
-                                        GUM_RED_ZONE_SIZE);
+  GumAddress code_addr = 0;
+
+  // gum_x86_writer_put_breakpoint(cw);
+  code_addr = cw->pc;
+  code.code = template;
+
+  gssize curr_loc_shr_1_offset =
+      offsetof(afl_log_code, code.mov_rsi_curr_loc_shr_1) +
+      sizeof(code.code.mov_rsi_curr_loc_shr_1) - sizeof(guint32);
+
+  *((guint32 *)&code.bytes[curr_loc_shr_1_offset]) =
+      (guint32)(area_offset >> 1);
+
+  gssize prev_loc_value =
+      GPOINTER_TO_SIZE(&instrument_previous_pc) -
+      (code_addr + offsetof(afl_log_code, code.xchg_rsi_prev_loc_curr_loc) +
+       sizeof(code.code.xchg_rsi_prev_loc_curr_loc));
+  gssize prev_loc_value_offset =
+      offsetof(afl_log_code, code.xchg_rsi_prev_loc_curr_loc) +
+      sizeof(code.code.xchg_rsi_prev_loc_curr_loc) - sizeof(gint);
+  if (!instrument_coverage_in_range(prev_loc_value)) {
+
+    FATAL("Patch out of range (current_pc_value1): 0x%016lX", prev_loc_value);
+
+  }
+
+  *((gint *)&code.bytes[prev_loc_value_offset]) = (gint)prev_loc_value;
+
+  gssize xor_curr_loc_offset = offsetof(afl_log_code, code.xor_rsi_curr_loc) +
+                               sizeof(code.code.xor_rsi_curr_loc) -
+                               sizeof(guint32);
+
+  *((guint32 *)&code.bytes[xor_curr_loc_offset]) = (guint32)(area_offset);
+
+  gssize add_rsi_1_offset = offsetof(afl_log_code, code.add_rsi_1) +
+                            sizeof(code.code.add_rsi_1) - sizeof(guint32) - 1;
+
+  *((guint32 *)&code.bytes[add_rsi_1_offset]) =
+      (guint32)GPOINTER_TO_SIZE(__afl_area_ptr);
+
+  gssize adc_rsi_0_ffset = offsetof(afl_log_code, code.adc_rsi_0) +
+                           sizeof(code.code.adc_rsi_0) - sizeof(guint32) - 1;
+
+  *((guint32 *)&code.bytes[adc_rsi_0_ffset]) =
+      (guint32)GPOINTER_TO_SIZE(__afl_area_ptr);
+
+  gum_x86_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code));
 
 }
 
diff --git a/frida_mode/src/instrument/instrument_x86.c b/frida_mode/src/instrument/instrument_x86.c
index 7bf48f96..1ff5c920 100644
--- a/frida_mode/src/instrument/instrument_x86.c
+++ b/frida_mode/src/instrument/instrument_x86.c
@@ -83,6 +83,9 @@ void instrument_coverage_optimize(const cs_insn *   instr,
 
 }
 
+void instrument_coverage_optimize_init(void) {
+}
+
 void instrument_flush(GumStalkerOutput *output) {
 
   gum_x86_writer_flush(output->writer.x86);
diff --git a/frida_mode/src/ranges.c b/frida_mode/src/ranges.c
index 5b6eb462..1b666fce 100644
--- a/frida_mode/src/ranges.c
+++ b/frida_mode/src/ranges.c
@@ -549,18 +549,19 @@ static GArray *merge_ranges(GArray *a) {
 
 }
 
+void ranges_print_debug_maps(void) {
+
+  gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, print_ranges_callback, NULL);
+
+}
+
 void ranges_config(void) {
 
   if (getenv("AFL_FRIDA_DEBUG_MAPS") != NULL) { ranges_debug_maps = TRUE; }
   if (getenv("AFL_INST_LIBS") != NULL) { ranges_inst_libs = TRUE; }
   if (getenv("AFL_FRIDA_INST_JIT") != NULL) { ranges_inst_jit = TRUE; }
 
-  if (ranges_debug_maps) {
-
-    gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, print_ranges_callback,
-                                 NULL);
-
-  }
+  if (ranges_debug_maps) { ranges_print_debug_maps(); }
 
   include_ranges = collect_ranges("AFL_FRIDA_INST_RANGES");
   exclude_ranges = collect_ranges("AFL_FRIDA_EXCLUDE_RANGES");
diff --git a/frida_mode/src/seccomp/seccomp_atomic.c b/frida_mode/src/seccomp/seccomp_atomic.c
index 5097511a..c2042f97 100644
--- a/frida_mode/src/seccomp/seccomp_atomic.c
+++ b/frida_mode/src/seccomp/seccomp_atomic.c
@@ -1,4 +1,4 @@
-#ifndef __APPLE__
+#if defined(__linux__) && !defined(__ANDROID__)
 
   #include <stdbool.h>
   #include <stdio.h>
diff --git a/frida_mode/src/seccomp/seccomp_callback.c b/frida_mode/src/seccomp/seccomp_callback.c
index 7e1e2070..a88196ac 100644
--- a/frida_mode/src/seccomp/seccomp_callback.c
+++ b/frida_mode/src/seccomp/seccomp_callback.c
@@ -1,4 +1,4 @@
-#ifndef __APPLE__
+#if defined(__linux__) && !defined(__ANDROID__)
 
   #include <execinfo.h>
   #include <fcntl.h>
diff --git a/frida_mode/src/seccomp/seccomp_child.c b/frida_mode/src/seccomp/seccomp_child.c
index f665f472..43a79894 100644
--- a/frida_mode/src/seccomp/seccomp_child.c
+++ b/frida_mode/src/seccomp/seccomp_child.c
@@ -1,4 +1,4 @@
-#ifndef __APPLE__
+#if defined(__linux__) && !defined(__ANDROID__)
 
   #include <fcntl.h>
   #include <sched.h>
diff --git a/frida_mode/src/seccomp/seccomp_event.c b/frida_mode/src/seccomp/seccomp_event.c
index dd4abde7..e2f592ca 100644
--- a/frida_mode/src/seccomp/seccomp_event.c
+++ b/frida_mode/src/seccomp/seccomp_event.c
@@ -1,4 +1,4 @@
-#ifndef __APPLE__
+#if defined(__linux__) && !defined(__ANDROID__)
 
   #include <stdint.h>
   #include <stdio.h>
diff --git a/frida_mode/src/seccomp/seccomp_filter.c b/frida_mode/src/seccomp/seccomp_filter.c
index 13ff7522..8d56c367 100644
--- a/frida_mode/src/seccomp/seccomp_filter.c
+++ b/frida_mode/src/seccomp/seccomp_filter.c
@@ -1,4 +1,4 @@
-#ifndef __APPLE__
+#if defined(__linux__) && !defined(__ANDROID__)
 
   #include <alloca.h>
   #include <errno.h>
diff --git a/frida_mode/src/seccomp/seccomp_print.c b/frida_mode/src/seccomp/seccomp_print.c
index be4d80ce..3cea1239 100644
--- a/frida_mode/src/seccomp/seccomp_print.c
+++ b/frida_mode/src/seccomp/seccomp_print.c
@@ -1,4 +1,4 @@
-#ifndef __APPLE__
+#if defined(__linux__) && !defined(__ANDROID__)
 
   #include <stdarg.h>
 
diff --git a/frida_mode/src/seccomp/seccomp_socket.c b/frida_mode/src/seccomp/seccomp_socket.c
index fae95805..ef937420 100644
--- a/frida_mode/src/seccomp/seccomp_socket.c
+++ b/frida_mode/src/seccomp/seccomp_socket.c
@@ -1,4 +1,4 @@
-#ifndef __APPLE__
+#if defined(__linux__) && !defined(__ANDROID__)
 
   #include <stdio.h>
   #include <string.h>
diff --git a/frida_mode/src/seccomp/seccomp_syscall.c b/frida_mode/src/seccomp/seccomp_syscall.c
index e023c131..8335b93c 100644
--- a/frida_mode/src/seccomp/seccomp_syscall.c
+++ b/frida_mode/src/seccomp/seccomp_syscall.c
@@ -1,4 +1,4 @@
-#ifndef __APPLE__
+#if defined(__linux__) && !defined(__ANDROID__)
 
   #include <limits.h>
   #include <stdio.h>
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 4b19e698..eaf55fb8 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -1130,7 +1130,6 @@ void   get_core_count(afl_state_t *);
 void   fix_up_sync(afl_state_t *);
 void   check_asan_opts(afl_state_t *);
 void   check_binary(afl_state_t *, u8 *);
-void   fix_up_banner(afl_state_t *, u8 *);
 void   check_if_tty(afl_state_t *);
 void   setup_signal_handlers(void);
 void   save_cmdline(afl_state_t *, u32, char **);
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 48ad2d02..013492f9 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -881,8 +881,6 @@ void ModuleSanitizerCoverage::InjectCoverageForIndirectCalls(
     Function &F, ArrayRef<Instruction *> IndirCalls) {
 
   if (IndirCalls.empty()) return;
-  assert(Options.TracePC || Options.TracePCGuard ||
-         Options.Inline8bitCounters /*|| Options.InlineBoolFlag*/);
   for (auto I : IndirCalls) {
 
     IRBuilder<> IRB(I);
diff --git a/instrumentation/afl-llvm-lto-instrumentation.so.cc b/instrumentation/afl-llvm-lto-instrumentation.so.cc
index 73e41f60..4eb8424f 100644
--- a/instrumentation/afl-llvm-lto-instrumentation.so.cc
+++ b/instrumentation/afl-llvm-lto-instrumentation.so.cc
@@ -244,7 +244,11 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
     // the instrument file list check
     AttributeList Attrs = F.getAttributes();
+#if LLVM_VERSION_MAJOR < 14
     if (Attrs.hasAttribute(-1, StringRef("skipinstrument"))) {
+#else
+    if (Attrs.hasFnAttr(StringRef("skipinstrument"))) {
+#endif
 
       if (debug)
         fprintf(stderr,
diff --git a/instrumentation/afl-llvm-lto-instrumentlist.so.cc b/instrumentation/afl-llvm-lto-instrumentlist.so.cc
index 416dbb88..0ec0e427 100644
--- a/instrumentation/afl-llvm-lto-instrumentlist.so.cc
+++ b/instrumentation/afl-llvm-lto-instrumentlist.so.cc
@@ -116,10 +116,15 @@ bool AFLcheckIfInstrument::runOnModule(Module &M) {
 
       auto &        Ctx = F.getContext();
       AttributeList Attrs = F.getAttributes();
+#if LLVM_VERSION_MAJOR < 14
       AttrBuilder   NewAttrs;
       NewAttrs.addAttribute("skipinstrument");
       F.setAttributes(
           Attrs.addAttributes(Ctx, AttributeList::FunctionIndex, NewAttrs));
+#else
+      AttributeList NewAttrs = Attrs.addFnAttribute(Ctx, "skipinstrument");
+      F.setAttributes(NewAttrs);
+#endif
 
     }
 
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index c8c94c08..54f510c4 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -610,12 +610,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
 
     if (!time_ms) {
 
-      kill(fsrv->fsrv_pid, fsrv->kill_signal);
+      if (fsrv->fsrv_pid > 0) { kill(fsrv->fsrv_pid, fsrv->kill_signal); }
 
     } else if (time_ms > fsrv->init_tmout) {
 
       fsrv->last_run_timed_out = 1;
-      kill(fsrv->fsrv_pid, fsrv->kill_signal);
+      if (fsrv->fsrv_pid > 0) { kill(fsrv->fsrv_pid, fsrv->kill_signal); }
 
     } else {
 
@@ -1248,7 +1248,7 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
     /* If there was no response from forkserver after timeout seconds,
     we kill the child. The forkserver should inform us afterwards */
 
-    kill(fsrv->child_pid, fsrv->kill_signal);
+    if (fsrv->child_pid > 0) { kill(fsrv->child_pid, fsrv->kill_signal); }
     fsrv->last_run_timed_out = 1;
     if (read(fsrv->fsrv_st_fd, &fsrv->child_status, 4) < 4) { exec_ms = 0; }
 
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 9bb25785..9c45f08a 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -2815,43 +2815,6 @@ void check_binary(afl_state_t *afl, u8 *fname) {
 
 }
 
-/* Trim and possibly create a banner for the run. */
-
-void fix_up_banner(afl_state_t *afl, u8 *name) {
-
-  if (!afl->use_banner) {
-
-    if (afl->sync_id) {
-
-      afl->use_banner = afl->sync_id;
-
-    } else {
-
-      u8 *trim = strrchr(name, '/');
-      if (!trim) {
-
-        afl->use_banner = name;
-
-      } else {
-
-        afl->use_banner = trim + 1;
-
-      }
-
-    }
-
-  }
-
-  if (strlen(afl->use_banner) > 32) {
-
-    u8 *tmp = ck_alloc(36);
-    sprintf(tmp, "%.32s...", afl->use_banner);
-    afl->use_banner = tmp;
-
-  }
-
-}
-
 /* Check if we're on TTY. */
 
 void check_if_tty(afl_state_t *afl) {
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index 4173f4e1..da6ba7d9 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -291,8 +291,6 @@ static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at,
 u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
                   u32 handicap, u8 from_queue) {
 
-  if (unlikely(afl->shm.cmplog_mode)) { q->exec_cksum = 0; }
-
   u8 fault = 0, new_bits = 0, var_detected = 0, hnb = 0,
      first_run = (q->exec_cksum == 0);
   u64 start_us, stop_us, diff_us;
@@ -300,6 +298,8 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
   u32 use_tmout = afl->fsrv.exec_tmout;
   u8 *old_sn = afl->stage_name;
 
+  if (unlikely(afl->shm.cmplog_mode)) { q->exec_cksum = 0; }
+
   /* Be a bit more generous about timeouts when resuming sessions, or when
      trying to calibrate already-added finds. This helps avoid trouble due
      to intermittent latency. */
@@ -343,6 +343,32 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
 
   }
 
+  /* we need a dummy run if this is LTO + cmplog */
+  if (unlikely(afl->shm.cmplog_mode)) {
+
+    write_to_testcase(afl, use_mem, q->len);
+
+    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. */
+
+    if (afl->stop_soon || fault != afl->crash_mode) { goto abort_calibration; }
+
+    if (!afl->non_instrumented_mode && !afl->stage_cur &&
+        !count_bytes(afl, afl->fsrv.trace_bits)) {
+
+      fault = FSRV_RUN_NOINST;
+      goto abort_calibration;
+
+    }
+
+#ifdef INTROSPECTION
+    if (unlikely(!q->bitsmap_size)) q->bitsmap_size = afl->bitsmap_size;
+#endif
+
+  }
+
   if (q->exec_cksum) {
 
     memcpy(afl->first_trace, afl->fsrv.trace_bits, afl->fsrv.map_size);
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 870ba69a..0c06232b 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -441,9 +441,10 @@ void show_stats(afl_state_t *afl) {
   u64 cur_ms;
   u32 t_bytes, t_bits;
 
-  u32 banner_len, banner_pad;
-  u8  tmp[256];
-  u8  time_tmp[64];
+  static u8 banner[128];
+  u32       banner_len, banner_pad;
+  u8        tmp[256];
+  u8        time_tmp[64];
 
   u8 val_buf[8][STRINGIFY_VAL_SIZE_MAX];
 #define IB(i) (val_buf[(i)])
@@ -656,26 +657,34 @@ void show_stats(afl_state_t *afl) {
   }
 
   /* Let's start by drawing a centered banner. */
+  if (unlikely(!banner[0])) {
 
-  banner_len = (afl->crash_mode ? 24 : 22) + strlen(VERSION) +
-               strlen(afl->use_banner) + strlen(afl->power_name) + 3 + 5;
-  banner_pad = (79 - banner_len) / 2;
-  memset(tmp, ' ', banner_pad);
+    char *si = "";
+    if (afl->sync_id) { si = afl->sync_id; }
+    memset(banner, 0, sizeof(banner));
+    banner_len = (afl->crash_mode ? 20 : 18) + strlen(VERSION) + strlen(si) +
+                 strlen(afl->power_name) + 4 + 6;
 
-#ifdef HAVE_AFFINITY
-  sprintf(
-      tmp + banner_pad,
-      "%s " cLCY VERSION cLGN " (%s) " cPIN "[%s]" cBLU " {%d}",
-      afl->crash_mode ? cPIN "peruvian were-rabbit" : cYEL "american fuzzy lop",
-      afl->use_banner, afl->power_name, afl->cpu_aff);
-#else
-  sprintf(
-      tmp + banner_pad, "%s " cLCY VERSION cLGN " (%s) " cPIN "[%s]",
-      afl->crash_mode ? cPIN "peruvian were-rabbit" : cYEL "american fuzzy lop",
-      afl->use_banner, afl->power_name);
-#endif                                                     /* HAVE_AFFINITY */
+    if (strlen(afl->use_banner) + banner_len > 75) {
+
+      afl->use_banner += (strlen(afl->use_banner) + banner_len) - 76;
+      memset(afl->use_banner, '.', 3);
+
+    }
+
+    banner_len += strlen(afl->use_banner);
+    banner_pad = (79 - banner_len) / 2;
+    memset(banner, ' ', banner_pad);
+
+    sprintf(banner + banner_pad,
+            "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s]",
+            afl->crash_mode ? cPIN "peruvian were-rabbit"
+                            : cYEL "american fuzzy lop",
+            si, afl->use_banner, afl->power_name);
+
+  }
 
-  SAYF("\n%s\n", tmp);
+  SAYF("\n%s\n", banner);
 
   /* "Handy" shortcuts for drawing boxes... */
 
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 92a37697..26886a4f 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1189,7 +1189,17 @@ int main(int argc, char **argv_orig, char **envp) {
 
   }
 
-  if (afl->sync_id) { fix_up_sync(afl); }
+  if (afl->sync_id) {
+
+    if (strlen(afl->sync_id) > 24) {
+
+      FATAL("sync_id max length is 24 characters");
+
+    }
+
+    fix_up_sync(afl);
+
+  }
 
   if (!strcmp(afl->in_dir, afl->out_dir)) {
 
@@ -1218,6 +1228,8 @@ int main(int argc, char **argv_orig, char **envp) {
 
   if (unlikely(afl->afl_env.afl_statsd)) { statsd_setup_format(afl); }
 
+  if (!afl->use_banner) { afl->use_banner = argv[optind]; }
+
   if (strchr(argv[optind], '/') == NULL && !afl->unicorn_mode) {
 
     WARNF(cLRD
@@ -1486,9 +1498,6 @@ int main(int argc, char **argv_orig, char **envp) {
   }
 
   save_cmdline(afl, argc, argv);
-
-  fix_up_banner(afl, argv[optind]);
-
   check_if_tty(afl);
   if (afl->afl_env.afl_force_ui) { afl->not_on_tty = 0; }
 
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 75b0ff99..5df07bf2 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -242,9 +242,14 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
   if (cmin_mode &&
       (fsrv->last_run_timed_out || (!caa && child_crashed != cco))) {
 
-    // create empty file to prevent error messages in afl-cmin
-    fd = open(outfile, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
-    close(fd);
+    if (strcmp(outfile, "-")) {
+
+      // create empty file to prevent error messages in afl-cmin
+      fd = open(outfile, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
+      close(fd);
+
+    }
+
     return ret;
 
   }
diff --git a/unicorn_mode/UNICORNAFL_VERSION b/unicorn_mode/UNICORNAFL_VERSION
index cbca63e5..cc8d5b34 100644
--- a/unicorn_mode/UNICORNAFL_VERSION
+++ b/unicorn_mode/UNICORNAFL_VERSION
@@ -1 +1 @@
-f1c853648a74b0157d233a2ef9f1693cfee78c11
+d4915053d477dd827b3fe4b494173d3fbf9f456e
diff --git a/unicorn_mode/samples/speedtest/rust/src/main.rs b/unicorn_mode/samples/speedtest/rust/src/main.rs
index 77356a67..89e10833 100644
--- a/unicorn_mode/samples/speedtest/rust/src/main.rs
+++ b/unicorn_mode/samples/speedtest/rust/src/main.rs
@@ -12,11 +12,11 @@ use std::{
 
 use unicornafl::{
     unicorn_const::{uc_error, Arch, Mode, Permission},
-    RegisterX86::{self, *},
-    Unicorn, UnicornHandle,
+    RegisterX86::*,
+    Unicorn,
 };
 
-const BINARY: &str = &"../target";
+const BINARY: &str = "../target";
 
 // Memory map for the code to be tested
 // Arbitrary address where code to test will be loaded
@@ -47,7 +47,7 @@ fn read_file(filename: &str) -> Result<Vec<u8>, io::Error> {
 fn parse_locs(loc_name: &str) -> Result<Vec<u64>, io::Error> {
     let contents = &read_file(&format!("../target.offsets.{}", loc_name))?;
     //println!("Read: {:?}", contents);
-    Ok(str_from_u8_unchecked(&contents)
+    Ok(str_from_u8_unchecked(contents)
         .split('\n')
         .map(|x| {
             //println!("Trying to convert {}", &x[2..]);
@@ -87,8 +87,7 @@ fn main() {
 }
 
 fn fuzz(input_file: &str) -> Result<(), uc_error> {
-    let mut unicorn = Unicorn::new(Arch::X86, Mode::MODE_64, 0)?;
-    let mut uc: UnicornHandle<'_, _> = unicorn.borrow();
+    let mut uc = Unicorn::new(Arch::X86, Mode::MODE_64, 0)?;
 
     let binary =
         read_file(BINARY).unwrap_or_else(|_| panic!("Could not read modem image: {}", BINARY));
@@ -133,7 +132,7 @@ fn fuzz(input_file: &str) -> Result<(), uc_error> {
     let already_allocated_malloc = already_allocated.clone();
     // We use a very simple malloc/free stub here,
     // that only works for exactly one allocation at a time.
-    let hook_malloc = move |mut uc: UnicornHandle<'_, _>, addr: u64, size: u32| {
+    let hook_malloc = move |uc: &mut Unicorn<'_, _>, addr: u64, size: u32| {
         if already_allocated_malloc.get() {
             println!("Double malloc, not supported right now!");
             abort();
@@ -154,7 +153,7 @@ fn fuzz(input_file: &str) -> Result<(), uc_error> {
 
     let already_allocated_free = already_allocated;
     // No real free, just set the "used"-flag to false.
-    let hook_free = move |mut uc: UnicornHandle<'_, _>, addr, size| {
+    let hook_free = move |uc: &mut Unicorn<'_, _>, addr, size| {
         if already_allocated_free.get() {
             println!("Double free detected. Real bug?");
             abort();
@@ -177,7 +176,7 @@ fn fuzz(input_file: &str) -> Result<(), uc_error> {
     */
 
     // This is a fancy print function that we're just going to skip for fuzzing.
-    let hook_magicfn = move |mut uc: UnicornHandle<'_, _>, addr, size| {
+    let hook_magicfn = move |uc: &mut Unicorn<'_, _>, addr, size| {
         uc.reg_write(RIP, addr + size as u64).unwrap();
     };
 
@@ -195,7 +194,7 @@ fn fuzz(input_file: &str) -> Result<(), uc_error> {
     }
 
     let place_input_callback =
-        |uc: &mut UnicornHandle<'_, _>, afl_input: &mut [u8], _persistent_round| {
+        |uc: &mut Unicorn<'_, _>, afl_input: &mut [u8], _persistent_round| {
             // apply constraints to the mutated input
             if afl_input.len() > INPUT_MAX as usize {
                 //println!("Skipping testcase with leng {}", afl_input.len());
@@ -209,9 +208,7 @@ fn fuzz(input_file: &str) -> Result<(), uc_error> {
 
     // return true if the last run should be counted as crash
     let crash_validation_callback =
-        |_uc: &mut UnicornHandle<'_, _>, result, _input: &[u8], _persistent_round| {
-            result != uc_error::OK
-        };
+        |_uc: &mut Unicorn<'_, _>, result, _input: &[u8], _persistent_round| result != uc_error::OK;
 
     let end_addrs = parse_locs("main_ends").unwrap();
 
diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl
-Subproject f1c853648a74b0157d233a2ef9f1693cfee78c1
+Subproject d4915053d477dd827b3fe4b494173d3fbf9f456