about summary refs log tree commit diff
path: root/frida_mode/src
diff options
context:
space:
mode:
Diffstat (limited to 'frida_mode/src')
-rw-r--r--frida_mode/src/asan/asan.c14
-rw-r--r--frida_mode/src/cmplog/cmplog.c13
-rw-r--r--frida_mode/src/entry.c8
-rw-r--r--frida_mode/src/instrument/instrument.c49
-rw-r--r--frida_mode/src/instrument/instrument_arm64.c241
-rw-r--r--frida_mode/src/instrument/instrument_coverage.c22
-rw-r--r--frida_mode/src/instrument/instrument_debug.c18
-rw-r--r--frida_mode/src/instrument/instrument_x64.c23
-rw-r--r--frida_mode/src/instrument/instrument_x86.c17
-rw-r--r--frida_mode/src/js/api.js9
-rw-r--r--frida_mode/src/js/js.c7
-rw-r--r--frida_mode/src/js/js_api.c6
-rw-r--r--frida_mode/src/lib/lib.c31
-rw-r--r--frida_mode/src/lib/lib_apple.c18
-rw-r--r--frida_mode/src/main.c20
-rw-r--r--frida_mode/src/output.c8
-rw-r--r--frida_mode/src/persistent/persistent.c15
-rw-r--r--frida_mode/src/persistent/persistent_arm64.c17
-rw-r--r--frida_mode/src/persistent/persistent_x64.c10
-rw-r--r--frida_mode/src/persistent/persistent_x86.c10
-rw-r--r--frida_mode/src/prefetch.c6
-rw-r--r--frida_mode/src/ranges.c78
-rw-r--r--frida_mode/src/seccomp/seccomp.c3
-rw-r--r--frida_mode/src/seccomp/seccomp_callback.c2
-rw-r--r--frida_mode/src/seccomp/seccomp_filter.c2
-rw-r--r--frida_mode/src/stalker.c10
-rw-r--r--frida_mode/src/stats/stats.c10
-rw-r--r--frida_mode/src/util.c24
28 files changed, 473 insertions, 218 deletions
diff --git a/frida_mode/src/asan/asan.c b/frida_mode/src/asan/asan.c
index 884bec53..cad409ee 100644
--- a/frida_mode/src/asan/asan.c
+++ b/frida_mode/src/asan/asan.c
@@ -9,21 +9,15 @@ gboolean        asan_initialized = FALSE;
 
 void asan_config(void) {
 
-  if (getenv("AFL_USE_FASAN") != NULL) {
-
-    FOKF("Frida ASAN mode enabled");
-    asan_enabled = TRUE;
-
-  } else {
-
-    FOKF("Frida ASAN mode disabled");
-
-  }
+  if (getenv("AFL_USE_FASAN") != NULL) { asan_enabled = TRUE; }
 
 }
 
 void asan_init(void) {
 
+  FOKF(cBLU "Instrumentation" cRST " - " cGRN "asan:" cYEL " [%c]",
+       asan_enabled ? 'X' : ' ');
+
   if (asan_enabled) {
 
     asan_arch_init();
diff --git a/frida_mode/src/cmplog/cmplog.c b/frida_mode/src/cmplog/cmplog.c
index 443baa1d..355df0b7 100644
--- a/frida_mode/src/cmplog/cmplog.c
+++ b/frida_mode/src/cmplog/cmplog.c
@@ -54,7 +54,7 @@ static gint cmplog_sort(gconstpointer a, gconstpointer b) {
 
 static void cmplog_get_ranges(void) {
 
-  FOKF("CMPLOG - Collecting ranges");
+  FVERBOSE("CMPLOG - Collecting ranges");
 
   cmplog_ranges = g_array_sized_new(false, false, sizeof(GumMemoryRange), 100);
   gum_process_enumerate_ranges(GUM_PAGE_READ, cmplog_range, cmplog_ranges);
@@ -68,18 +68,21 @@ void cmplog_config(void) {
 
 void cmplog_init(void) {
 
-  FOKF("CMPLOG - Enabled [%c]", __afl_cmp_map == NULL ? ' ' : 'X');
+  FOKF(cBLU "Instrumentation" cRST " - " cGRN "cmplog:" cYEL " [%c]",
+       __afl_cmp_map == NULL ? ' ' : 'X');
 
   if (__afl_cmp_map == NULL) { return; }
 
   cmplog_get_ranges();
 
+  FVERBOSE("Cmplog Ranges");
+
   for (guint i = 0; i < cmplog_ranges->len; i++) {
 
     GumMemoryRange *range = &g_array_index(cmplog_ranges, GumMemoryRange, i);
-    FOKF("CMPLOG Range - %3u: 0x%016" G_GINT64_MODIFIER
-         "X - 0x%016" G_GINT64_MODIFIER "X",
-         i, range->base_address, range->base_address + range->size);
+    FVERBOSE("\t%3u: 0x%016" G_GINT64_MODIFIER "X - 0x%016" G_GINT64_MODIFIER
+             "X",
+             i, range->base_address, range->base_address + range->size);
 
   }
 
diff --git a/frida_mode/src/entry.c b/frida_mode/src/entry.c
index de645fdb..995f765f 100644
--- a/frida_mode/src/entry.c
+++ b/frida_mode/src/entry.c
@@ -24,7 +24,7 @@ gboolean entry_run = FALSE;
 
 static void entry_launch(void) {
 
-  FOKF("Entry point reached");
+  FVERBOSE("Entry point reached");
   __afl_manual_init();
 
   /* Child here */
@@ -69,8 +69,8 @@ void entry_config(void) {
 
 void entry_init(void) {
 
-  FOKF("entry_point: 0x%016" G_GINT64_MODIFIER "X", entry_point);
-  FOKF("dumpable: [%c]", traceable ? 'X' : ' ');
+  FVERBOSE("Entry Point: 0x%016" G_GINT64_MODIFIER "X", entry_point);
+  FVERBOSE("Dumpable: [%c]", traceable ? 'X' : ' ');
 
   if (dlopen(NULL, RTLD_NOW) == NULL) { FFATAL("Failed to dlopen: %d", errno); }
 
@@ -94,7 +94,7 @@ static void entry_callout(GumCpuContext *cpu_context, gpointer user_data) {
 void entry_prologue(GumStalkerIterator *iterator, GumStalkerOutput *output) {
 
   UNUSED_PARAMETER(output);
-  FOKF("AFL_ENTRYPOINT reached");
+  FVERBOSE("AFL_ENTRYPOINT reached");
 
   if (persistent_start == 0) {
 
diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c
index 8ee21f5b..46ed1a34 100644
--- a/frida_mode/src/instrument/instrument.c
+++ b/frida_mode/src/instrument/instrument.c
@@ -32,12 +32,13 @@ char *   instrument_coverage_unstable_filename = NULL;
 
 static GumStalkerTransformer *transformer = NULL;
 
-__thread guint64 instrument_previous_pc = 0;
-
 static GumAddress previous_rip = 0;
 static GumAddress previous_end = 0;
 static u8 *       edges_notified = NULL;
 
+__thread guint64  instrument_previous_pc;
+__thread guint64 *instrument_previous_pc_addr = NULL;
+
 typedef struct {
 
   GumAddress address;
@@ -105,8 +106,14 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context,
   guint16      current_end = ctx->end;
   guint64      current_pc = instrument_get_offset_hash(current_rip);
   guint64      edge;
+  if (instrument_previous_pc_addr == NULL) {
 
-  edge = current_pc ^ instrument_previous_pc;
+    instrument_previous_pc_addr = &instrument_previous_pc;
+    *instrument_previous_pc_addr = instrument_hash_zero;
+
+  }
+
+  edge = current_pc ^ *instrument_previous_pc_addr;
 
   instrument_increment_map(edge);
 
@@ -136,7 +143,7 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context,
   previous_end = current_end;
 
   gsize map_size_pow2 = util_log2(__afl_map_size);
-  instrument_previous_pc = util_rotate(current_pc, 1, map_size_pow2);
+  *instrument_previous_pc_addr = util_rotate(current_pc, 1, map_size_pow2);
 
 }
 
@@ -274,14 +281,19 @@ void instrument_init(void) {
 
   if (!instrument_is_coverage_optimize_supported()) instrument_optimize = false;
 
-  FOKF("Instrumentation - optimize [%c]", instrument_optimize ? 'X' : ' ');
-  FOKF("Instrumentation - tracing [%c]", instrument_tracing ? 'X' : ' ');
-  FOKF("Instrumentation - unique [%c]", instrument_unique ? 'X' : ' ');
-  FOKF("Instrumentation - fixed seed [%c] [0x%016" G_GINT64_MODIFIER "x]",
+  FOKF(cBLU "Instrumentation" cRST " - " cGRN "optimize:" cYEL " [%c]",
+       instrument_optimize ? 'X' : ' ');
+  FOKF(cBLU "Instrumentation" cRST " - " cGRN "tracing:" cYEL " [%c]",
+       instrument_tracing ? 'X' : ' ');
+  FOKF(cBLU "Instrumentation" cRST " - " cGRN "unique:" cYEL " [%c]",
+       instrument_unique ? 'X' : ' ');
+  FOKF(cBLU "Instrumentation" cRST " - " cGRN "fixed seed:" cYEL
+            " [%c] [0x%016" G_GINT64_MODIFIER "x]",
        instrument_use_fixed_seed ? 'X' : ' ', instrument_fixed_seed);
-  FOKF("Instrumentation - unstable coverage [%c] [%s]",
-       instrument_coverage_unstable_filename == NULL ? ' ' : 'X',
-       instrument_coverage_unstable_filename);
+  FOKF(cBLU "Instrumentation" cRST " - " cGRN "unstable coverage:" cYEL " [%s]",
+       instrument_coverage_unstable_filename == NULL
+           ? " "
+           : instrument_coverage_unstable_filename);
 
   if (instrument_tracing && instrument_optimize) {
 
@@ -366,15 +378,16 @@ void instrument_init(void) {
 
   }
 
-  FOKF("Instrumentation - seed [0x%016" G_GINT64_MODIFIER "x]",
+  FOKF(cBLU "Instrumentation" cRST " - " cGRN "seed:" cYEL
+            " [0x%016" G_GINT64_MODIFIER "x]",
        instrument_hash_seed);
   instrument_hash_zero = instrument_get_offset_hash(0);
 
-  instrument_coverage_optimize_init();
-  instrument_debug_init();
-  instrument_coverage_init();
   asan_init();
   cmplog_init();
+  instrument_coverage_init();
+  instrument_coverage_optimize_init();
+  instrument_debug_init();
 
 }
 
@@ -387,7 +400,11 @@ GumStalkerTransformer *instrument_get_transformer(void) {
 
 void instrument_on_fork() {
 
-  instrument_previous_pc = instrument_hash_zero;
+  if (instrument_previous_pc_addr != NULL) {
+
+    *instrument_previous_pc_addr = instrument_hash_zero;
+
+  }
 
 }
 
diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c
index 0f635458..57b60317 100644
--- a/frida_mode/src/instrument/instrument_arm64.c
+++ b/frida_mode/src/instrument/instrument_arm64.c
@@ -1,50 +1,118 @@
+#include <stddef.h>
+
 #include "frida-gumjs.h"
 
 #include "config.h"
 
 #include "instrument.h"
+#include "ranges.h"
+#include "stalker.h"
+#include "util.h"
+
+#define G_MININT33 ((gssize)0xffffffff00000000)
+#define G_MAXINT33 ((gssize)0x00000000ffffffff)
+
+#define PAGE_MASK (~(GUM_ADDRESS(0xfff)))
+#define PAGE_ALIGNED(x) ((GUM_ADDRESS(x) & PAGE_MASK) == GUM_ADDRESS(x))
 
 #if defined(__aarch64__)
 
-static GumAddress current_log_impl = GUM_ADDRESS(0);
+__attribute__((aligned(0x1000))) static guint8 area_ptr_dummy[MAP_SIZE];
+
+  #pragma pack(push, 1)
+typedef struct {
+
+  // cur_location = (block_address >> 4) ^ (block_address << 8);
+  // shared_mem[cur_location ^ prev_location]++;
+  // prev_location = cur_location >> 1;
+
+  // stp     x0, x1, [sp, #-160]
+  // adrp    x0, 0x7fb7738000
+  // ldr     x1, [x0]
+  // mov     x0, #0x18b8
+  // eor     x0, x1, x0
+  // adrp    x1, 0x7fb7d73000
+  // add     x0, x1, x0
+  // ldrb    w1, [x0]
+  // add     w1, w1, #0x1
+  // add     x1, x1, x1, lsr #8
+  // strb    w1, [x0]
+  // adrp    x0, 0x7fb7738000
+  // mov     x1, #0xc5c
+  // str     x1, [x0]
+  // ldp     x0, x1, [sp, #-160]
+  // b       0x7fb6f0dee4
+  // ldp     x16, x17, [sp], #144
+
+  uint32_t stp_x0_x1;                           /* stp x0, x1, [sp, #-0xa0] */
+
+  uint32_t adrp_x0_prev_loc1;                           /* adrp x0, #0xXXXX */
+  uint32_t ldr_x1_ptr_x0;                                   /* ldr x1, [x0] */
+
+  uint32_t mov_x0_curr_loc;                             /* movz x0, #0xXXXX */
+  uint32_t eor_x0_x1_x0;                                  /* eor x0, x1, x0 */
+  uint32_t adrp_x1_area_ptr;                            /* adrp x1, #0xXXXX */
+  uint32_t add_x0_x1_x0;                                  /* add x0, x1, x0 */
+
+  uint32_t ldrb_w1_x0;                                     /* ldrb w1, [x0] */
+  uint32_t add_w1_w1_1;                                   /* add w1, w1, #1 */
+  uint32_t add_w1_w1_w1_lsr_8;                    /* add x1, x1, x1, lsr #8 */
+
+  uint32_t strb_w1_ptr_x0;                                 /* strb w1, [x0] */
+
+  uint32_t adrp_x0_prev_loc2;                           /* adrp x0, #0xXXXX */
+  uint32_t mov_x1_curr_loc_shr_1;                       /* movz x1, #0xXXXX */
+  uint32_t str_x1_ptr_x0;                                   /* str x1, [x0] */
+
+  uint32_t ldp_x0_x1;                           /* ldp x0, x1, [sp, #-0xa0] */
+
+  uint32_t b_imm8;                                                 /* br #8 */
+  uint32_t restoration_prolog;                 /* ldp x16, x17, [sp], #0x90 */
 
-static const guint8 afl_log_code[] = {
+} afl_log_code_asm_t;
 
-    // __afl_area_ptr[current_pc ^ previous_pc]++;
-    // previous_pc = current_pc ROR 1;
-    0xE1, 0x0B, 0xBF, 0xA9,  // stp x1, x2, [sp, -0x10]!
-    0xE3, 0x13, 0xBF, 0xA9,  // stp x3, x4, [sp, -0x10]!
+  #pragma pack(pop)
 
-    // x0 = current_pc
-    0x21, 0x02, 0x00, 0x58,  // ldr x1, #0x44, =&__afl_area_ptr
-    0x21, 0x00, 0x40, 0xf9,  // ldr x1, [x1] (=__afl_area_ptr)
+typedef union {
 
-    0x22, 0x02, 0x00, 0x58,  // ldr x2, #0x44, =&previous_pc
-    0x42, 0x00, 0x40, 0xf9,  // ldr x2, [x2] (=previous_pc)
+  afl_log_code_asm_t code;
+  uint8_t            bytes[0];
 
-    // __afl_area_ptr[current_pc ^ previous_pc]++;
-    0x42, 0x00, 0x00, 0xca,  // eor x2, x2, x0
-    0x23, 0x68, 0x62, 0xf8,  // ldr x3, [x1, x2]
-    0x63, 0x04, 0x00, 0x91,  // add x3, x3, #1
-    0x63, 0x00, 0x1f, 0x9a,  // adc x3, x3, xzr
-    0x23, 0x68, 0x22, 0xf8,  // str x3, [x1, x2]
+} afl_log_code;
 
-    // previous_pc = current_pc ROR 1;
-    0xe4, 0x07, 0x40, 0x8b,  // add x4, xzr, x0, LSR #1
-    0xe0, 0xff, 0x00, 0x8b,  // add x0, xzr, x0, LSL #63
-    0x80, 0xc0, 0x40, 0x8b,  // add x0, x4, x0, LSR #48
+static const afl_log_code_asm_t template =
+    {
 
-    0xe2, 0x00, 0x00, 0x58,  // ldr x2, #0x1c, =&previous_pc
-    0x40, 0x00, 0x00, 0xf9,  // str x0, [x2]
+        .stp_x0_x1 = 0xa93607e0,
 
-    0xE3, 0x13, 0xc1, 0xA8,  // ldp x3, x4, [sp], #0x10
-    0xE1, 0x0B, 0xc1, 0xA8,  // ldp x1, x2, [sp], #0x10
-    0xC0, 0x03, 0x5F, 0xD6,  // ret
+        .adrp_x0_prev_loc1 = 0x90000000,
+        .ldr_x1_ptr_x0 = 0xf9400001,
 
-    // &afl_area_ptr_ptr
-    // &afl_prev_loc_ptr
+        .mov_x0_curr_loc = 0xd2800000,
+        .eor_x0_x1_x0 = 0xca000020,
 
-};
+        .adrp_x1_area_ptr = 0x90000001,
+        .add_x0_x1_x0 = 0x8b000020,
+
+        .ldrb_w1_x0 = 0x39400001,
+
+        .add_w1_w1_1 = 0x11000421,
+        .add_w1_w1_w1_lsr_8 = 0x8b412021,
+
+        .strb_w1_ptr_x0 = 0x39000001,
+
+        .adrp_x0_prev_loc2 = 0x90000000,
+        .mov_x1_curr_loc_shr_1 = 0xd2800001,
+        .str_x1_ptr_x0 = 0xf9000001,
+
+        .ldp_x0_x1 = 0xa97607e0,
+
+        .b_imm8 = 0x14000002,
+        .restoration_prolog = 0xa8c947f0,
+
+}
+
+;
 
 gboolean instrument_is_coverage_optimize_supported(void) {
 
@@ -52,50 +120,111 @@ gboolean instrument_is_coverage_optimize_supported(void) {
 
 }
 
+static gboolean instrument_coverage_in_range(gssize offset) {
+
+  return (offset >= G_MININT33 && offset <= G_MAXINT33);
+
+}
+
+static void instrument_patch_ardp(guint32 *patch, GumAddress insn,
+                                  GumAddress target) {
+
+  if (!PAGE_ALIGNED(target)) { FATAL("Target not page aligned"); }
+
+  gssize distance = target - (GUM_ADDRESS(insn) & PAGE_MASK);
+  if (!instrument_coverage_in_range(distance)) {
+
+    FATAL("Patch out of range 0x%016lX->0x%016lX = 0x%016lX", insn, target,
+          distance);
+
+  }
+
+  guint32 imm_low = ((distance >> 12) & 0x3) << 29;
+  guint32 imm_high = ((distance >> 14) & 0x7FFFF) << 5;
+  *patch |= imm_low;
+  *patch |= imm_high;
+
+}
+
 void instrument_coverage_optimize(const cs_insn *   instr,
                                   GumStalkerOutput *output) {
 
-  guint64 current_pc = instr->address;
-  guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address));
+  afl_log_code    code = {0};
   GumArm64Writer *cw = output->writer.arm64;
+  guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address));
+  gsize   map_size_pow2;
+  gsize   area_offset_ror;
+  GumAddress code_addr = 0;
 
-  if (current_log_impl == 0 ||
-      !gum_arm64_writer_can_branch_directly_between(cw, cw->pc,
-                                                    current_log_impl) ||
-      !gum_arm64_writer_can_branch_directly_between(cw, cw->pc + 128,
-                                                    current_log_impl)) {
+  if (instrument_previous_pc_addr == NULL) {
 
-    gconstpointer after_log_impl = cw->code + 1;
+    GumAddressSpec spec = {.near_address = cw->code,
+                           .max_distance = 1ULL << 30};
 
-    gum_arm64_writer_put_b_label(cw, after_log_impl);
+    instrument_previous_pc_addr = gum_memory_allocate_near(
+        &spec, sizeof(guint64), 0x1000, GUM_PAGE_READ | GUM_PAGE_WRITE);
+    *instrument_previous_pc_addr = instrument_hash_zero;
+    FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr);
+    FVERBOSE("code_addr: %p", cw->code);
 
-    current_log_impl = cw->pc;
-    gum_arm64_writer_put_bytes(cw, afl_log_code, sizeof(afl_log_code));
+  }
 
-    uint8_t **afl_area_ptr_ptr = &__afl_area_ptr;
-    uint64_t *afl_prev_loc_ptr = &instrument_previous_pc;
-    gum_arm64_writer_put_bytes(cw, (const guint8 *)&afl_area_ptr_ptr,
-                               sizeof(afl_area_ptr_ptr));
-    gum_arm64_writer_put_bytes(cw, (const guint8 *)&afl_prev_loc_ptr,
-                               sizeof(afl_prev_loc_ptr));
+  // gum_arm64_writer_put_brk_imm(cw, 0x0);
 
-    gum_arm64_writer_put_label(cw, after_log_impl);
+  code_addr = cw->pc;
 
-  }
+  code.code = template;
+
+  /*
+   * Given our map is allocated on a 64KB boundary and our map is a multiple of
+   * 64KB in size, then it should also end on a 64 KB boundary. It is followed
+   * by our previous_pc, so this too should be 64KB aligned.
+   */
+  g_assert(PAGE_ALIGNED(instrument_previous_pc_addr));
+  g_assert(PAGE_ALIGNED(__afl_area_ptr));
 
-  gum_arm64_writer_put_stp_reg_reg_reg_offset(
-      cw, ARM64_REG_LR, ARM64_REG_X0, ARM64_REG_SP, -(16 + GUM_RED_ZONE_SIZE),
-      GUM_INDEX_PRE_ADJUST);
-  gum_arm64_writer_put_ldr_reg_u64(cw, ARM64_REG_X0, area_offset);
-  gum_arm64_writer_put_bl_imm(cw, current_log_impl);
-  gum_arm64_writer_put_ldp_reg_reg_reg_offset(
-      cw, ARM64_REG_LR, ARM64_REG_X0, ARM64_REG_SP, 16 + GUM_RED_ZONE_SIZE,
-      GUM_INDEX_POST_ADJUST);
+  instrument_patch_ardp(
+      &code.code.adrp_x0_prev_loc1,
+      code_addr + offsetof(afl_log_code, code.adrp_x0_prev_loc1),
+      GUM_ADDRESS(instrument_previous_pc_addr));
+
+  code.code.mov_x0_curr_loc |= area_offset << 5;
+
+  instrument_patch_ardp(
+      &code.code.adrp_x1_area_ptr,
+      code_addr + offsetof(afl_log_code, code.adrp_x1_area_ptr),
+      GUM_ADDRESS(__afl_area_ptr));
+
+  map_size_pow2 = util_log2(__afl_map_size);
+  area_offset_ror = util_rotate(area_offset, 1, map_size_pow2);
+
+  instrument_patch_ardp(
+      &code.code.adrp_x0_prev_loc2,
+      code_addr + offsetof(afl_log_code, code.adrp_x0_prev_loc2),
+      GUM_ADDRESS(instrument_previous_pc_addr));
+
+  code.code.mov_x1_curr_loc_shr_1 |= (area_offset_ror << 5);
+
+  gum_arm64_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code));
 
 }
 
 void instrument_coverage_optimize_init(void) {
 
+  char *shm_env = getenv(SHM_ENV_VAR);
+  FVERBOSE("SHM_ENV_VAR: %s", shm_env);
+
+  if (shm_env == NULL) {
+
+    FWARNF("SHM_ENV_VAR not set, using dummy for debugging purposes");
+
+    __afl_area_ptr = area_ptr_dummy;
+    memset(area_ptr_dummy, '\0', sizeof(area_ptr_dummy));
+
+  }
+
+  FVERBOSE("__afl_area_ptr: %p", __afl_area_ptr);
+
 }
 
 void instrument_flush(GumStalkerOutput *output) {
diff --git a/frida_mode/src/instrument/instrument_coverage.c b/frida_mode/src/instrument/instrument_coverage.c
index c1984eb2..098e7269 100644
--- a/frida_mode/src/instrument/instrument_coverage.c
+++ b/frida_mode/src/instrument/instrument_coverage.c
@@ -659,17 +659,17 @@ void instrument_coverage_config(void) {
 
 void instrument_coverage_normal_init(void) {
 
-  FOKF("Coverage - enabled [%c]",
-       instrument_coverage_filename == NULL ? ' ' : 'X');
+  FOKF(cBLU "Instrumentation" cRST " - " cGRN "coverage:" cYEL " [%s]",
+       instrument_coverage_filename == NULL ? " "
+                                            : instrument_coverage_filename);
 
   if (instrument_coverage_filename == NULL) { return; }
 
-  FOKF("Coverage - file [%s]", instrument_coverage_filename);
-
   char *path = g_canonicalize_filename(instrument_coverage_filename,
                                        g_get_current_dir());
 
-  FOKF("Coverage - path [%s]", path);
+  FOKF(cBLU "Instrumentation" cRST " - " cGRN "coverage path:" cYEL " [%s]",
+       path);
 
   normal_coverage_fd = open(path, O_RDWR | O_CREAT | O_TRUNC,
                             S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
@@ -718,7 +718,7 @@ void instrument_coverage_unstable_find_output(void) {
 
   GDir *dir = g_dir_open(fds_name, 0, NULL);
 
-  FOKF("Coverage Unstable - fds: %s", fds_name);
+  FVERBOSE("Coverage Unstable - fds: %s", fds_name);
 
   for (const gchar *filename = g_dir_read_name(dir); filename != NULL;
        filename = g_dir_read_name(dir)) {
@@ -782,18 +782,24 @@ void instrument_coverage_unstable_find_output(void) {
 
   }
 
-  FOKF("Fuzzer stats: %s", unstable_coverage_fuzzer_stats);
+  FVERBOSE("Fuzzer stats: %s", unstable_coverage_fuzzer_stats);
 
 }
 
 void instrument_coverage_unstable_init(void) {
 
+  FOKF(cBLU "Instrumentation" cRST " - " cGRN "unstable coverage:" cYEL " [%s]",
+       instrument_coverage_unstable_filename == NULL
+           ? " "
+           : instrument_coverage_unstable_filename);
   if (instrument_coverage_unstable_filename == NULL) { return; }
 
   char *path = g_canonicalize_filename(instrument_coverage_unstable_filename,
                                        g_get_current_dir());
 
-  FOKF("Coverage - unstable path [%s]", instrument_coverage_unstable_filename);
+  FOKF(cBLU "Instrumentation" cRST " - " cGRN "unstable coverage path:" cYEL
+            " [%s]",
+       path == NULL ? " " : path);
 
   unstable_coverage_fd = open(path, O_RDWR | O_CREAT | O_TRUNC,
                               S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
diff --git a/frida_mode/src/instrument/instrument_debug.c b/frida_mode/src/instrument/instrument_debug.c
index 9c95857f..592ab673 100644
--- a/frida_mode/src/instrument/instrument_debug.c
+++ b/frida_mode/src/instrument/instrument_debug.c
@@ -35,6 +35,10 @@ static void instrument_debug(char *format, ...) {
 static void instrument_disasm(guint8 *start, guint8 *end,
                               GumStalkerOutput *output) {
 
+#if !defined(__arm__)
+  UNUSED_PARAMETER(output);
+#endif
+
   csh      capstone;
   cs_err   err;
   cs_mode  mode;
@@ -50,9 +54,7 @@ static void instrument_disasm(guint8 *start, guint8 *end,
   if (output->encoding == GUM_INSTRUCTION_SPECIAL) { mode |= CS_MODE_THUMB; }
 #endif
 
-  err = cs_open(GUM_DEFAULT_CS_ARCH,
-                CS_MODE_THUMB | GUM_DEFAULT_CS_MODE | GUM_DEFAULT_CS_ENDIAN,
-                &capstone);
+  err = cs_open(GUM_DEFAULT_CS_ARCH, mode, &capstone);
   g_assert(err == CS_ERR_OK);
 
   size = GPOINTER_TO_SIZE(end) - GPOINTER_TO_SIZE(start);
@@ -96,19 +98,15 @@ void instrument_debug_config(void) {
 
 void instrument_debug_init(void) {
 
-  FOKF("Instrumentation debugging - enabled [%c]",
-       instrument_debug_filename == NULL ? ' ' : 'X');
-
-  if (instrument_debug_filename == NULL) { return; }
-
-  FOKF("Instrumentation debugging - file [%s]", instrument_debug_filename);
+  FOKF(cBLU "Instrumentation" cRST " - " cGRN "debugging:" cYEL " [%s]",
+       instrument_debug_filename == NULL ? " " : instrument_debug_filename);
 
   if (instrument_debug_filename == NULL) { return; }
 
   char *path =
       g_canonicalize_filename(instrument_debug_filename, g_get_current_dir());
 
-  FOKF("Instrumentation debugging - path [%s]", path);
+  FOKF(cBLU "Instrumentation" cRST " - " cGRN "path:" cYEL " [%s]", path);
 
   debugging_fd = open(path, O_RDWR | O_CREAT | O_TRUNC,
                       S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c
index b51cb697..0ea4f7f0 100644
--- a/frida_mode/src/instrument/instrument_x64.c
+++ b/frida_mode/src/instrument/instrument_x64.c
@@ -323,7 +323,7 @@ void instrument_coverage_optimize_init(void) {
   gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, instrument_coverage_find_low,
                                &low_address);
 
-  FOKF("Low address: %p", low_address);
+  FVERBOSE("Low address: %p", low_address);
 
   if (low_address == 0 ||
       GPOINTER_TO_SIZE(low_address) > ((2UL << 20) - __afl_map_size)) {
@@ -335,7 +335,7 @@ void instrument_coverage_optimize_init(void) {
   ranges_print_debug_maps();
 
   char *shm_env = getenv(SHM_ENV_VAR);
-  FOKF("SHM_ENV_VAR: %s", shm_env);
+  FVERBOSE("SHM_ENV_VAR: %s", shm_env);
 
   if (shm_env == NULL) {
 
@@ -359,8 +359,7 @@ void instrument_coverage_optimize_init(void) {
 
   }
 
-  FOKF("__afl_area_ptr: %p", __afl_area_ptr);
-  FOKF("instrument_previous_pc: %p", &instrument_previous_pc);
+  FVERBOSE("__afl_area_ptr: %p", __afl_area_ptr);
 
 }
 
@@ -439,6 +438,18 @@ void instrument_coverage_optimize(const cs_insn *   instr,
   gsize   map_size_pow2;
   gsize   area_offset_ror;
   GumAddress code_addr = 0;
+  if (instrument_previous_pc_addr == NULL) {
+
+    GumAddressSpec spec = {.near_address = cw->code,
+                           .max_distance = 1ULL << 30};
+
+    instrument_previous_pc_addr = gum_memory_allocate_near(
+        &spec, sizeof(guint64), 0x1000, GUM_PAGE_READ | GUM_PAGE_WRITE);
+    *instrument_previous_pc_addr = instrument_hash_zero;
+    FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr);
+    FVERBOSE("code_addr: %p", cw->code);
+
+  }
 
   instrument_coverage_suppress_init();
 
@@ -462,7 +473,7 @@ void instrument_coverage_optimize(const cs_insn *   instr,
   *((guint32 *)&code.bytes[curr_loc_shr_1_offset]) = (guint32)(area_offset_ror);
 
   gssize prev_loc_value =
-      GPOINTER_TO_SIZE(&instrument_previous_pc) -
+      GPOINTER_TO_SIZE(instrument_previous_pc_addr) -
       (code_addr + offsetof(afl_log_code, code.mov_prev_loc_curr_loc_shr1) +
        sizeof(code.code.mov_prev_loc_curr_loc_shr1));
   gssize prev_loc_value_offset =
@@ -478,7 +489,7 @@ void instrument_coverage_optimize(const cs_insn *   instr,
   *((gint *)&code.bytes[prev_loc_value_offset]) = (gint)prev_loc_value;
 
   gssize prev_loc_value2 =
-      GPOINTER_TO_SIZE(&instrument_previous_pc) -
+      GPOINTER_TO_SIZE(instrument_previous_pc_addr) -
       (code_addr + offsetof(afl_log_code, code.mov_eax_prev_loc) +
        sizeof(code.code.mov_eax_prev_loc));
   gssize prev_loc_value_offset2 =
diff --git a/frida_mode/src/instrument/instrument_x86.c b/frida_mode/src/instrument/instrument_x86.c
index ad837e2d..c4e93324 100644
--- a/frida_mode/src/instrument/instrument_x86.c
+++ b/frida_mode/src/instrument/instrument_x86.c
@@ -153,6 +153,19 @@ void instrument_coverage_optimize(const cs_insn *   instr,
   gsize   map_size_pow2;
   gsize   area_offset_ror;
 
+  if (instrument_previous_pc_addr == NULL) {
+
+    GumAddressSpec spec = {.near_address = cw->code,
+                           .max_distance = 1ULL << 30};
+
+    instrument_previous_pc_addr = gum_memory_allocate_near(
+        &spec, sizeof(guint64), 0x1000, GUM_PAGE_READ | GUM_PAGE_WRITE);
+    *instrument_previous_pc_addr = instrument_hash_zero;
+    FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr);
+    FVERBOSE("code_addr: %p", cw->code);
+
+  }
+
   code.code = template;
 
   instrument_coverage_suppress_init();
@@ -170,7 +183,7 @@ void instrument_coverage_optimize(const cs_insn *   instr,
       sizeof(code.code.mov_eax_prev_loc) - sizeof(gint);
 
   *((gint *)&code.bytes[prev_loc_value_offset2]) =
-      (gint)GPOINTER_TO_SIZE(&instrument_previous_pc);
+      (gint)GPOINTER_TO_SIZE(instrument_previous_pc_addr);
 
   gssize curr_loc_shr_1_offset =
       offsetof(afl_log_code, code.mov_prev_loc_curr_loc_shr1) +
@@ -187,7 +200,7 @@ void instrument_coverage_optimize(const cs_insn *   instr,
       sizeof(guint32);
 
   *((gint *)&code.bytes[prev_loc_value_offset]) =
-      (gint)GPOINTER_TO_SIZE(&instrument_previous_pc);
+      (gint)GPOINTER_TO_SIZE(instrument_previous_pc_addr);
 
   gssize xor_curr_loc_offset = offsetof(afl_log_code, code.xor_eax_curr_loc) +
                                sizeof(code.code.xor_eax_curr_loc) -
diff --git a/frida_mode/src/js/api.js b/frida_mode/src/js/api.js
index 215fbdaf..52e9e45c 100644
--- a/frida_mode/src/js/api.js
+++ b/frida_mode/src/js/api.js
@@ -63,7 +63,7 @@ class Afl {
         Afl.jsApiWrite(STDOUT_FILENO, buf, log.length);
     }
     /**
-     * See `AFL_FRIDA_INST_NO_BACKPATCH`.
+     * See `AFL_FRIDA_STALKER_NO_BACKPATCH`.
      */
     static setBackpatchDisable() {
         Afl.jsApiSetBackpatchDisable();
@@ -268,6 +268,12 @@ class Afl {
     static setTraceable() {
         Afl.jsApiSetTraceable();
     }
+    /**
+     * See `AFL_FRIDA_VERBOSE`
+     */
+    static setVerbose() {
+        Afl.jsApiSetVerbose();
+    }
     static jsApiGetFunction(name, retType, argTypes) {
         const addr = Afl.module.getExportByName(name);
         return new NativeFunction(addr, retType, argTypes);
@@ -315,6 +321,7 @@ Afl.jsApiSetStatsInterval = Afl.jsApiGetFunction("js_api_set_stats_interval", "v
 Afl.jsApiSetStdErr = Afl.jsApiGetFunction("js_api_set_stderr", "void", ["pointer"]);
 Afl.jsApiSetStdOut = Afl.jsApiGetFunction("js_api_set_stdout", "void", ["pointer"]);
 Afl.jsApiSetTraceable = Afl.jsApiGetFunction("js_api_set_traceable", "void", []);
+Afl.jsApiSetVerbose = Afl.jsApiGetFunction("js_api_set_verbose", "void", []);
 Afl.jsApiWrite = new NativeFunction(
 /* tslint:disable-next-line:no-null-keyword */
 Module.getExportByName(null, "write"), "int", ["int", "pointer", "int"]);
diff --git a/frida_mode/src/js/js.c b/frida_mode/src/js/js.c
index 5f477388..1ca2237f 100644
--- a/frida_mode/src/js/js.c
+++ b/frida_mode/src/js/js.c
@@ -55,7 +55,10 @@ static gchar *js_get_script() {
 
   } else {
 
-    FOKF("Loaded AFL script: %s, %" G_GSIZE_MODIFIER "d bytes", filename,
+    FOKF(cBLU "Javascript" cRST " - " cGRN "script:" cYEL " [%s]",
+         filename == NULL ? " " : filename);
+    FOKF(cBLU "Javascript" cRST " - " cGRN "size: " cYEL "%" G_GSIZE_MODIFIER
+              "d bytes",
          length);
 
     gchar *source = g_malloc0(api_js_len + length + 1);
@@ -74,7 +77,7 @@ static void js_print_script(gchar *source) {
 
   for (size_t i = 0; split[i] != NULL; i++) {
 
-    FOKF("%3" G_GSIZE_MODIFIER "d. %s", i + 1, split[i]);
+    FVERBOSE("%3" G_GSIZE_MODIFIER "d. %s", i + 1, split[i]);
 
   }
 
diff --git a/frida_mode/src/js/js_api.c b/frida_mode/src/js/js_api.c
index 5021b531..94ec8842 100644
--- a/frida_mode/src/js/js_api.c
+++ b/frida_mode/src/js/js_api.c
@@ -262,3 +262,9 @@ __attribute__((visibility("default"))) void js_api_set_js_main_hook(
 
 }
 
+__attribute__((visibility("default"))) void js_api_set_verbose(void) {
+
+  util_verbose = TRUE;
+
+}
+
diff --git a/frida_mode/src/lib/lib.c b/frida_mode/src/lib/lib.c
index 48d2ea2a..39480ce9 100644
--- a/frida_mode/src/lib/lib.c
+++ b/frida_mode/src/lib/lib.c
@@ -93,17 +93,18 @@ static void lib_read_text_section(lib_details_t *lib_details, Elf_Ehdr *hdr) {
 
   }
 
-  FOKF("Image preferred load address 0x%016" G_GSIZE_MODIFIER "x",
-       preferred_base);
+  FVERBOSE("\tpreferred load address: 0x%016" G_GSIZE_MODIFIER "x",
+           preferred_base);
 
   shdr = (Elf_Shdr *)((char *)hdr + hdr->e_shoff);
   shstrtab = &shdr[hdr->e_shstrndx];
   shstr = (char *)hdr + shstrtab->sh_offset;
 
-  FOKF("shdr: %p", shdr);
-  FOKF("shstrtab: %p", shstrtab);
-  FOKF("shstr: %p", shstr);
+  FVERBOSE("\tshdr:                   %p", shdr);
+  FVERBOSE("\tshstrtab:               %p", shstrtab);
+  FVERBOSE("\tshstr:                  %p", shstr);
 
+  FVERBOSE("Sections:");
   for (size_t i = 0; i < hdr->e_shnum; i++) {
 
     curr = &shdr[i];
@@ -111,21 +112,23 @@ static void lib_read_text_section(lib_details_t *lib_details, Elf_Ehdr *hdr) {
     if (curr->sh_name == 0) continue;
 
     section_name = &shstr[curr->sh_name];
-    FOKF("Section: %2" G_GSIZE_MODIFIER "u - base: 0x%016" G_GSIZE_MODIFIER
-         "X size: 0x%016" G_GSIZE_MODIFIER "X %s",
-         i, curr->sh_addr, curr->sh_size, section_name);
+    FVERBOSE("\t%2" G_GSIZE_MODIFIER "u - base: 0x%016" G_GSIZE_MODIFIER
+             "X size: 0x%016" G_GSIZE_MODIFIER "X %s",
+             i, curr->sh_addr, curr->sh_size, section_name);
     if (memcmp(section_name, text_name, sizeof(text_name)) == 0 &&
         text_base == 0) {
 
       text_base = lib_details->base_address + curr->sh_addr - preferred_base;
       text_limit = text_base + curr->sh_size;
-      FOKF("> text_addr: 0x%016" G_GINT64_MODIFIER "X", text_base);
-      FOKF("> text_limit: 0x%016" G_GINT64_MODIFIER "X", text_limit);
 
     }
 
   }
 
+  FVERBOSE(".text\n");
+  FVERBOSE("\taddr: 0x%016" G_GINT64_MODIFIER "X", text_base);
+  FVERBOSE("\tlimit: 0x%016" G_GINT64_MODIFIER "X", text_limit);
+
 }
 
 static void lib_get_text_section(lib_details_t *details) {
@@ -141,7 +144,7 @@ static void lib_get_text_section(lib_details_t *details) {
 
   if (len == (off_t)-1) { FFATAL("Failed to lseek %s", details->path); }
 
-  FOKF("len: %ld", len);
+  FVERBOSE("\tlength:                 %ld", len);
 
   hdr = (Elf_Ehdr *)mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
   if (hdr == MAP_FAILED) { FFATAL("Failed to map %s", details->path); }
@@ -162,8 +165,10 @@ void lib_init(void) {
 
   lib_details_t lib_details;
   gum_process_enumerate_modules(lib_find_exe, &lib_details);
-  FOKF("Executable: 0x%016" G_GINT64_MODIFIER "x - %s",
-       lib_details.base_address, lib_details.path);
+  FVERBOSE("Image");
+  FVERBOSE("\tbase:                   0x%016" G_GINT64_MODIFIER "x",
+           lib_details.base_address);
+  FVERBOSE("\tpath:                   %s", lib_details.path);
   lib_get_text_section(&lib_details);
 
 }
diff --git a/frida_mode/src/lib/lib_apple.c b/frida_mode/src/lib/lib_apple.c
index 3bdb8c10..65c1d937 100644
--- a/frida_mode/src/lib/lib_apple.c
+++ b/frida_mode/src/lib/lib_apple.c
@@ -20,7 +20,7 @@ static gboolean lib_get_main_module(const GumModuleDetails *details,
       details->path, mach_task_self(), details->range->base_address,
       GUM_DARWIN_MODULE_FLAGS_NONE, NULL);
 
-  FOKF("Found main module: %s", module->name);
+  FVERBOSE("Found main module: %s", module->name);
 
   *ret = module;
 
@@ -35,21 +35,23 @@ gboolean lib_get_text_section(const GumDarwinSectionDetails *details,
   static size_t idx = 0;
   char          text_name[] = "__text";
 
-  FOKF("Section: %2lu - base: 0x%016" G_GINT64_MODIFIER
-       "X size: 0x%016" G_GINT64_MODIFIER "X %s",
-       idx++, details->vm_address, details->vm_address + details->size,
-       details->section_name);
+  FVERBOSE("\t%2lu - base: 0x%016" G_GINT64_MODIFIER
+           "X size: 0x%016" G_GINT64_MODIFIER "X %s",
+           idx++, details->vm_address, details->vm_address + details->size,
+           details->section_name);
 
   if (memcmp(details->section_name, text_name, sizeof(text_name)) == 0 &&
       text_base == 0) {
 
     text_base = details->vm_address;
     text_limit = details->vm_address + details->size;
-    FOKF("> text_addr: 0x%016" G_GINT64_MODIFIER "X", text_base);
-    FOKF("> text_limit: 0x%016" G_GINT64_MODIFIER "X", text_limit);
 
   }
 
+  FVERBOSE(".text\n");
+  FVERBOSE("\taddr: 0x%016" G_GINT64_MODIFIER "X", text_base);
+  FVERBOSE("\tlimit: 0x%016" G_GINT64_MODIFIER "X", text_limit);
+
   return TRUE;
 
 }
@@ -62,6 +64,8 @@ void lib_init(void) {
 
   GumDarwinModule *module = NULL;
   gum_darwin_enumerate_modules(mach_task_self(), lib_get_main_module, &module);
+
+  FVERBOSE("Sections:");
   gum_darwin_module_enumerate_sections(module, lib_get_text_section, NULL);
 
 }
diff --git a/frida_mode/src/main.c b/frida_mode/src/main.c
index 1be63bc4..d8521300 100644
--- a/frida_mode/src/main.c
+++ b/frida_mode/src/main.c
@@ -111,11 +111,13 @@ static void afl_print_cmdline(void) {
 
   int idx = 0;
 
+  FVERBOSE("Command Line");
+
   for (ssize_t i = 0; i < bytes_read; i++) {
 
     if (i == 0 || buffer[i - 1] == '\0') {
 
-      FOKF("AFL - COMMANDLINE: argv[%d] = %s", idx++, &buffer[i]);
+      FVERBOSE("\targv[%d] = %s", idx++, &buffer[i]);
 
     }
 
@@ -131,7 +133,7 @@ static void afl_print_cmdline(void) {
 
   for (idx = 0; idx < nargv; idx++) {
 
-    FOKF("AFL - COMMANDLINE: argv[%d] = %s", idx, argv[idx]);
+    FVERBOSE("\targv[%d] = %s", idx, argv[idx]);
 
   }
 
@@ -161,11 +163,12 @@ static void afl_print_env(void) {
 
   int idx = 0;
 
+  FVERBOSE("ENVIRONMENT");
   for (ssize_t i = 0; i < bytes_read; i++) {
 
     if (i == 0 || buffer[i - 1] == '\0') {
 
-      FOKF("AFL - ENVIRONMENT %3d: %s", idx++, &buffer[i]);
+      FVERBOSE("\t%3d: %s", idx++, &buffer[i]);
 
     }
 
@@ -179,6 +182,13 @@ static void afl_print_env(void) {
 
 __attribute__((visibility("default"))) void afl_frida_start(void) {
 
+  FOKF(cRED "**********************");
+  FOKF(cRED "* " cYEL "******************" cRED " *");
+  FOKF(cRED "* " cYEL "* " cGRN "**************" cYEL " *" cRED " *");
+  FOKF(cRED "* " cYEL "* " cGRN "* FRIDA MODE *" cYEL " *" cRED " *");
+  FOKF(cRED "* " cYEL "* " cGRN "**************" cYEL " *" cRED " *");
+  FOKF(cRED "* " cYEL "******************" cRED " *");
+  FOKF(cRED "**********************");
   afl_print_cmdline();
   afl_print_env();
 
@@ -255,9 +265,9 @@ static void intercept_main(void) {
 static void intercept_main(void) {
 
   mach_port_t task = mach_task_self();
-  FOKF("Task Id: %u", task);
+  FVERBOSE("Task Id: %u", task);
   GumAddress entry = gum_darwin_find_entrypoint(task);
-  FOKF("Entry Point: 0x%016" G_GINT64_MODIFIER "x", entry);
+  FVERBOSE("Entry Point: 0x%016" G_GINT64_MODIFIER "x", entry);
   void *main = GSIZE_TO_POINTER(entry);
   main_fn = main;
   intercept_hook(main, on_main, NULL);
diff --git a/frida_mode/src/output.c b/frida_mode/src/output.c
index f570fe91..66208992 100644
--- a/frida_mode/src/output.c
+++ b/frida_mode/src/output.c
@@ -18,7 +18,7 @@ static void output_redirect(int fd, char *filename) {
 
   path = g_canonicalize_filename(filename, g_get_current_dir());
 
-  FOKF("Redirect %d -> '%s'", fd, path);
+  FVERBOSE("Redirect %d -> '%s'", fd, path);
 
   int output_fd = open(path, O_RDWR | O_CREAT | O_TRUNC,
                        S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
@@ -46,8 +46,10 @@ void output_config(void) {
 
 void output_init(void) {
 
-  FOKF("Output - StdOut: %s", output_stdout);
-  FOKF("Output - StdErr: %s", output_stderr);
+  FOKF(cBLU "Output" cRST " - " cGRN "stdout:" cYEL " [%s]",
+       output_stdout == NULL ? " " : output_stdout);
+  FOKF(cBLU "Output" cRST " - " cGRN "stderr:" cYEL " [%s]",
+       output_stderr == NULL ? " " : output_stderr);
 
   output_redirect(STDOUT_FILENO, output_stdout);
   output_redirect(STDERR_FILENO, output_stderr);
diff --git a/frida_mode/src/persistent/persistent.c b/frida_mode/src/persistent/persistent.c
index 817d9925..7fd7d351 100644
--- a/frida_mode/src/persistent/persistent.c
+++ b/frida_mode/src/persistent/persistent.c
@@ -72,13 +72,16 @@ void persistent_config(void) {
 
 void persistent_init(void) {
 
-  FOKF("Instrumentation - persistent mode [%c] (0x%016" G_GINT64_MODIFIER "X)",
+  FOKF(cBLU "Instrumentation" cRST " - " cGRN "persistent mode:" cYEL
+            " [%c] (0x%016" G_GINT64_MODIFIER "X)",
        persistent_start == 0 ? ' ' : 'X', persistent_start);
-  FOKF("Instrumentation - persistent count [%c] (%" G_GINT64_MODIFIER "d)",
+  FOKF(cBLU "Instrumentation" cRST " - " cGRN "persistent count:" cYEL
+            " [%c] (%" G_GINT64_MODIFIER "d)",
        persistent_start == 0 ? ' ' : 'X', persistent_count);
-  FOKF("Instrumentation - hook [%s]", hook_name);
+  FOKF(cBLU "Instrumentation" cRST " - " cGRN "hook:" cYEL " [%s]", hook_name);
 
-  FOKF("Instrumentation - persistent ret [%c] (0x%016" G_GINT64_MODIFIER "X)",
+  FOKF(cBLU "Instrumentation" cRST " - " cGRN "persistent ret:" cYEL
+            " [%c] (0x%016" G_GINT64_MODIFIER "X)",
        persistent_ret == 0 ? ' ' : 'X', persistent_ret);
 
   if (persistent_hook != NULL) { __afl_sharedmem_fuzzing = 1; }
@@ -87,7 +90,7 @@ void persistent_init(void) {
 
 void persistent_prologue(GumStalkerOutput *output) {
 
-  FOKF("AFL_FRIDA_PERSISTENT_ADDR reached");
+  FVERBOSE("AFL_FRIDA_PERSISTENT_ADDR reached");
   entry_compiled = TRUE;
   ranges_exclude();
   stalker_trust();
@@ -97,7 +100,7 @@ void persistent_prologue(GumStalkerOutput *output) {
 
 void persistent_epilogue(GumStalkerOutput *output) {
 
-  FOKF("AFL_FRIDA_PERSISTENT_RET reached");
+  FVERBOSE("AFL_FRIDA_PERSISTENT_RET reached");
   persistent_epilogue_arch(output);
 
 }
diff --git a/frida_mode/src/persistent/persistent_arm64.c b/frida_mode/src/persistent/persistent_arm64.c
index c9159ca1..16ecf39c 100644
--- a/frida_mode/src/persistent/persistent_arm64.c
+++ b/frida_mode/src/persistent/persistent_arm64.c
@@ -89,7 +89,7 @@ static void instrument_persitent_save_regs(GumArm64Writer *  cw,
 
   /* LR (x30) */
   gum_arm64_writer_put_str_reg_reg_offset(cw, ARM64_REG_X30, ARM64_REG_X0,
-                                          offsetof(GumCpuContext, x[30]));
+                                          offsetof(GumCpuContext, lr));
 
   /* PC & Adjusted SP (31) */
   gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X2,
@@ -189,7 +189,7 @@ static void instrument_persitent_restore_regs(GumArm64Writer *  cw,
 
   /* LR (x30) */
   gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X30, ARM64_REG_X0,
-                                          offsetof(GumCpuContext, x[30]));
+                                          offsetof(GumCpuContext, lr));
 
   /* Adjusted SP (31) (use x1 as clobber)*/
   gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X1, ARM64_REG_X0,
@@ -236,7 +236,13 @@ static void instrument_exit(GumArm64Writer *cw) {
 static int instrument_afl_persistent_loop_func(void) {
 
   int ret = __afl_persistent_loop(persistent_count);
-  instrument_previous_pc = instrument_hash_zero;
+  if (instrument_previous_pc_addr == NULL) {
+
+    FATAL("instrument_previous_pc_addr uninitialized");
+
+  }
+
+  *instrument_previous_pc_addr = instrument_hash_zero;
   return ret;
 
 }
@@ -264,8 +270,7 @@ static void persistent_prologue_hook(GumArm64Writer *  cw,
   gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X2, 0);
   gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X2, 0);
 
-  gum_arm64_writer_put_and_reg_reg_imm(cw, ARM64_REG_X2, ARM64_REG_X2,
-                                       G_MAXULONG);
+  gum_arm64_writer_put_mov_reg_reg(cw, ARM64_REG_W2, ARM64_REG_W2);
 
   gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X1,
                                        GUM_ADDRESS(&__afl_fuzz_ptr));
@@ -324,7 +329,7 @@ void persistent_prologue_arch(GumStalkerOutput *output) {
 
   gconstpointer loop = cw->code + 1;
 
-  FOKF("Persistent loop reached");
+  FVERBOSE("Persistent loop reached");
 
   instrument_persitent_save_regs(cw, &saved_regs);
 
diff --git a/frida_mode/src/persistent/persistent_x64.c b/frida_mode/src/persistent/persistent_x64.c
index 8cbde633..56141787 100644
--- a/frida_mode/src/persistent/persistent_x64.c
+++ b/frida_mode/src/persistent/persistent_x64.c
@@ -173,7 +173,13 @@ static void instrument_exit(GumX86Writer *cw) {
 static int instrument_afl_persistent_loop_func(void) {
 
   int ret = __afl_persistent_loop(persistent_count);
-  instrument_previous_pc = instrument_hash_zero;
+  if (instrument_previous_pc_addr == NULL) {
+
+    FATAL("instrument_previous_pc_addr uninitialized");
+
+  }
+
+  *instrument_previous_pc_addr = instrument_hash_zero;
   return ret;
 
 }
@@ -269,7 +275,7 @@ void persistent_prologue_arch(GumStalkerOutput *output) {
 
   gconstpointer loop = cw->code + 1;
 
-  FOKF("Persistent loop reached");
+  FVERBOSE("Persistent loop reached");
 
   /* Pop the return value */
   gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, 8);
diff --git a/frida_mode/src/persistent/persistent_x86.c b/frida_mode/src/persistent/persistent_x86.c
index 5425b01b..76c25334 100644
--- a/frida_mode/src/persistent/persistent_x86.c
+++ b/frida_mode/src/persistent/persistent_x86.c
@@ -130,7 +130,13 @@ static void instrument_exit(GumX86Writer *cw) {
 static int instrument_afl_persistent_loop_func(void) {
 
   int ret = __afl_persistent_loop(persistent_count);
-  instrument_previous_pc = instrument_hash_zero;
+  if (instrument_previous_pc_addr == NULL) {
+
+    FATAL("instrument_previous_pc_addr uninitialized");
+
+  }
+
+  *instrument_previous_pc_addr = instrument_hash_zero;
   return ret;
 
 }
@@ -210,7 +216,7 @@ void persistent_prologue_arch(GumStalkerOutput *output) {
 
   gconstpointer loop = cw->code + 1;
 
-  FOKF("Persistent loop reached");
+  FVERBOSE("Persistent loop reached");
 
   /* Pop the return value */
   gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_ESP, GUM_REG_ESP, 4);
diff --git a/frida_mode/src/prefetch.c b/frida_mode/src/prefetch.c
index 8c9ce94d..fa0288cc 100644
--- a/frida_mode/src/prefetch.c
+++ b/frida_mode/src/prefetch.c
@@ -178,8 +178,10 @@ static void prefetch_hook_fork(void) {
 
 void prefetch_init(void) {
 
-  FOKF("Instrumentation - prefetch [%c]", prefetch_enable ? 'X' : ' ');
-  FOKF("Instrumentation - prefetch_backpatch [%c]",
+  FOKF(cBLU "Instrumentation" cRST " - " cGRN "prefetch:" cYEL " [%c]",
+       prefetch_enable ? 'X' : ' ');
+  FOKF(cBLU "Instrumentation" cRST " - " cGRN "prefetch_backpatch:" cYEL
+            " [%c]",
        prefetch_backpatch ? 'X' : ' ');
 
   if (!prefetch_enable) { return; }
diff --git a/frida_mode/src/ranges.c b/frida_mode/src/ranges.c
index 9844c74c..84803453 100644
--- a/frida_mode/src/ranges.c
+++ b/frida_mode/src/ranges.c
@@ -122,10 +122,10 @@ static gboolean convert_name_token_for_module(const GumModuleDetails *details,
 
   if (!g_str_has_suffix(details->path, ctx->suffix)) { return true; };
 
-  FOKF("Found module - prefix: %s, 0x%016" G_GINT64_MODIFIER
-       "x-0x%016" G_GINT64_MODIFIER "x %s",
-       ctx->suffix, details->range->base_address,
-       details->range->base_address + details->range->size, details->path);
+  FVERBOSE("Found module - prefix: %s, 0x%016" G_GINT64_MODIFIER
+           "x-0x%016" G_GINT64_MODIFIER "x %s",
+           ctx->suffix, details->range->base_address,
+           details->range->base_address + details->range->size, details->path);
 
   *ctx->range = *details->range;
   ctx->done = true;
@@ -158,9 +158,9 @@ static void convert_token(gchar *token, GumMemoryRange *range) {
 
   }
 
-  FOKF("Converted token: %s -> 0x%016" G_GINT64_MODIFIER
-       "x-0x%016" G_GINT64_MODIFIER "x\n",
-       token, range->base_address, range->base_address + range->size);
+  FVERBOSE("Converted token: %s -> 0x%016" G_GINT64_MODIFIER
+           "x-0x%016" G_GINT64_MODIFIER "x\n",
+           token, range->base_address, range->base_address + range->size);
 
 }
 
@@ -192,24 +192,24 @@ static gboolean print_ranges_callback(const GumRangeDetails *details,
 
   if (details->file == NULL) {
 
-    FOKF("MAP - 0x%016" G_GINT64_MODIFIER "x - 0x%016" G_GINT64_MODIFIER
-         "X %c%c%c",
-         details->range->base_address,
-         details->range->base_address + details->range->size,
-         details->protection & GUM_PAGE_READ ? 'R' : '-',
-         details->protection & GUM_PAGE_WRITE ? 'W' : '-',
-         details->protection & GUM_PAGE_EXECUTE ? 'X' : '-');
+    FVERBOSE("\t0x%016" G_GINT64_MODIFIER "x-0x%016" G_GINT64_MODIFIER
+             "X %c%c%c",
+             details->range->base_address,
+             details->range->base_address + details->range->size,
+             details->protection & GUM_PAGE_READ ? 'R' : '-',
+             details->protection & GUM_PAGE_WRITE ? 'W' : '-',
+             details->protection & GUM_PAGE_EXECUTE ? 'X' : '-');
 
   } else {
 
-    FOKF("MAP - 0x%016" G_GINT64_MODIFIER "x - 0x%016" G_GINT64_MODIFIER
-         "X %c%c%c %s(0x%016" G_GINT64_MODIFIER "x)",
-         details->range->base_address,
-         details->range->base_address + details->range->size,
-         details->protection & GUM_PAGE_READ ? 'R' : '-',
-         details->protection & GUM_PAGE_WRITE ? 'W' : '-',
-         details->protection & GUM_PAGE_EXECUTE ? 'X' : '-',
-         details->file->path, details->file->offset);
+    FVERBOSE("\t0x%016" G_GINT64_MODIFIER "x-0x%016" G_GINT64_MODIFIER
+             "X %c%c%c %s(0x%016" G_GINT64_MODIFIER "x)",
+             details->range->base_address,
+             details->range->base_address + details->range->size,
+             details->protection & GUM_PAGE_READ ? 'R' : '-',
+             details->protection & GUM_PAGE_WRITE ? 'W' : '-',
+             details->protection & GUM_PAGE_EXECUTE ? 'X' : '-',
+             details->file->path, details->file->offset);
 
   }
 
@@ -219,14 +219,14 @@ static gboolean print_ranges_callback(const GumRangeDetails *details,
 
 static void print_ranges(char *key, GArray *ranges) {
 
-  FOKF("Range: %s Length: %d", key, ranges->len);
+  FVERBOSE("Range: [%s], Length: %d", key, ranges->len);
   for (guint i = 0; i < ranges->len; i++) {
 
     GumMemoryRange *curr = &g_array_index(ranges, GumMemoryRange, i);
     GumAddress      curr_limit = curr->base_address + curr->size;
-    FOKF("Range: %s Idx: %3d - 0x%016" G_GINT64_MODIFIER
-         "x-0x%016" G_GINT64_MODIFIER "x",
-         key, i, curr->base_address, curr_limit);
+    FVERBOSE("\t%3d - 0x%016" G_GINT64_MODIFIER "x-0x%016" G_GINT64_MODIFIER
+             "x",
+             i, curr->base_address, curr_limit);
 
   }
 
@@ -248,7 +248,7 @@ static GArray *collect_module_ranges(void) {
   result = g_array_new(false, false, sizeof(GumMemoryRange));
   gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS,
                                collect_module_ranges_callback, result);
-  print_ranges("Modules", result);
+  print_ranges("modules", result);
   return result;
 
 }
@@ -348,7 +348,7 @@ static GArray *collect_libs_ranges(void) {
 
   g_array_append_val(result, range);
 
-  print_ranges("AFL_INST_LIBS", result);
+  print_ranges("libs", result);
 
   return result;
 
@@ -382,7 +382,7 @@ static GArray *collect_jit_ranges(void) {
 
   }
 
-  print_ranges("JIT", result);
+  print_ranges("jit", result);
   return result;
 
 }
@@ -564,6 +564,7 @@ static GArray *merge_ranges(GArray *a) {
 
 void ranges_print_debug_maps(void) {
 
+  FVERBOSE("Maps");
   gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, print_ranges_callback, NULL);
 
 }
@@ -590,16 +591,15 @@ void ranges_init(void) {
   GArray *       step4;
   GArray *       step5;
 
-  FOKF("Ranges - Instrument jit [%c]", ranges_inst_jit ? 'X' : ' ');
-  FOKF("Ranges - Instrument libraries [%c]", ranges_inst_libs ? 'X' : ' ');
+  FOKF(cBLU "Ranges" cRST " - " cGRN "instrument jit:" cYEL " [%c]",
+       ranges_inst_jit ? 'X' : ' ');
+  FOKF(cBLU "Ranges" cRST " - " cGRN "instrument libraries:" cYEL " [%c]",
+       ranges_inst_libs ? 'X' : ' ');
+  FOKF(cBLU "Ranges" cRST " - " cGRN "instrument libraries:" cYEL " [%c]",
+       ranges_inst_libs ? 'X' : ' ');
 
-  print_ranges("AFL_FRIDA_INST_RANGES", include_ranges);
-  print_ranges("AFL_FRIDA_EXCLUDE_RANGES", exclude_ranges);
-
-  FOKF("Ranges - Instrument libraries [%c]", ranges_inst_libs ? 'X' : ' ');
-
-  print_ranges("AFL_FRIDA_INST_RANGES", include_ranges);
-  print_ranges("AFL_FRIDA_EXCLUDE_RANGES", exclude_ranges);
+  print_ranges("include", include_ranges);
+  print_ranges("exclude", exclude_ranges);
 
   module_ranges = collect_module_ranges();
   libs_ranges = collect_libs_ranges();
@@ -673,7 +673,7 @@ void ranges_exclude() {
   GumMemoryRange *r;
   GumStalker *    stalker = stalker_get();
 
-  FOKF("Excluding ranges");
+  FVERBOSE("Excluding ranges");
 
   for (guint i = 0; i < ranges->len; i++) {
 
diff --git a/frida_mode/src/seccomp/seccomp.c b/frida_mode/src/seccomp/seccomp.c
index 9d8fdd5d..984a3990 100644
--- a/frida_mode/src/seccomp/seccomp.c
+++ b/frida_mode/src/seccomp/seccomp.c
@@ -25,7 +25,8 @@ void seccomp_config(void) {
 
 void seccomp_init(void) {
 
-  FOKF("Seccomp - file [%s]", seccomp_filename);
+  FOKF(cBLU "Seccomp" cRST " - " cGRN "file:" cYEL " [%s]",
+       seccomp_filename == NULL ? " " : seccomp_filename);
 
   if (seccomp_filename == NULL) { return; }
 
diff --git a/frida_mode/src/seccomp/seccomp_callback.c b/frida_mode/src/seccomp/seccomp_callback.c
index f7aaf78b..c86e753f 100644
--- a/frida_mode/src/seccomp/seccomp_callback.c
+++ b/frida_mode/src/seccomp/seccomp_callback.c
@@ -124,7 +124,7 @@ void seccomp_callback_initialize(void) {
 
   path = g_canonicalize_filename(seccomp_filename, g_get_current_dir());
 
-  FOKF("Seccomp - path [%s]", path);
+  FVERBOSE("Seccomp - path [%s]", path);
 
   fd = open(path, O_RDWR | O_CREAT | O_TRUNC,
             S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
diff --git a/frida_mode/src/seccomp/seccomp_filter.c b/frida_mode/src/seccomp/seccomp_filter.c
index 1d050303..075d793a 100644
--- a/frida_mode/src/seccomp/seccomp_filter.c
+++ b/frida_mode/src/seccomp/seccomp_filter.c
@@ -258,7 +258,7 @@ void seccomp_filter_run(int fd, seccomp_filter_callback_t callback) {
     if (ioctl(fd, SECCOMP_IOCTL_NOTIF_SEND, resp) < 0) {
 
       if (errno == ENOENT) { continue; }
-      FOKF("SECCOMP_IOCTL_NOTIF_SEND");
+      FVERBOSE("SECCOMP_IOCTL_NOTIF_SEND");
       continue;
 
     }
diff --git a/frida_mode/src/stalker.c b/frida_mode/src/stalker.c
index caa16b3f..3a421867 100644
--- a/frida_mode/src/stalker.c
+++ b/frida_mode/src/stalker.c
@@ -93,10 +93,12 @@ static gboolean stalker_exclude_self(const GumRangeDetails *details,
 
 void stalker_init(void) {
 
-  FOKF("Instrumentation - backpatch [%c]", backpatch_enable ? 'X' : ' ');
-
-  FOKF("Stalker - ic_entries [%u]", stalker_ic_entries);
-  FOKF("Stalker - adjacent_blocks [%u]", stalker_adjacent_blocks);
+  FOKF(cBLU "Stalker" cRST " - " cGRN "backpatch:" cYEL " [%c]",
+       backpatch_enable ? 'X' : ' ');
+  FOKF(cBLU "Stalker" cRST " - " cGRN "ic_entries:" cYEL " [%u]",
+       stalker_ic_entries);
+  FOKF(cBLU "Stalker" cRST " - " cGRN "adjacent_blocks:" cYEL " [%u]",
+       stalker_adjacent_blocks);
 
 #if !(defined(__x86_64__) || defined(__i386__))
   if (getenv("AFL_FRIDA_STALKER_IC_ENTRIES") != NULL) {
diff --git a/frida_mode/src/stats/stats.c b/frida_mode/src/stats/stats.c
index 83ecf89a..39aca0db 100644
--- a/frida_mode/src/stats/stats.c
+++ b/frida_mode/src/stats/stats.c
@@ -329,8 +329,11 @@ void stats_config(void) {
 
 void stats_init(void) {
 
-  FOKF("Stats - file [%s]", stats_filename);
-  FOKF("Stats - interval [%" G_GINT64_MODIFIER "u]", stats_interval);
+  FOKF(cBLU "Stats" cRST " - " cGRN "file:" cYEL " [%s]",
+       stats_filename == NULL ? " " : stats_filename);
+  FOKF(cBLU "Stats" cRST " - " cGRN "interval:" cYEL " [%" G_GINT64_MODIFIER
+            "u]",
+       stats_interval);
 
   if (getenv("AFL_FRIDA_STATS_INTERVAL") != NULL &&
       getenv("AFL_FRIDA_STATS_FILE") == NULL) {
@@ -347,7 +350,8 @@ void stats_init(void) {
 
   char *path = g_canonicalize_filename(stats_filename, g_get_current_dir());
 
-  FOKF("Stats - path [%s]", path);
+  FOKF(cBLU "Stats" cRST " - " cGRN "path:" cYEL " [%s]",
+       path == NULL ? " " : path);
 
   stats_fd = open(path, O_RDWR | O_CREAT | O_TRUNC,
                   S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
diff --git a/frida_mode/src/util.c b/frida_mode/src/util.c
index 6f52b6cb..90c10917 100644
--- a/frida_mode/src/util.c
+++ b/frida_mode/src/util.c
@@ -1,5 +1,7 @@
 #include "util.h"
 
+gboolean util_verbose = FALSE;
+
 guint64 util_read_address(char *key, guint64 default_value) {
 
   char *value_str = getenv(key);
@@ -66,7 +68,7 @@ guint64 util_read_num(char *key, guint64 default_value) {
 
   errno = 0;
 
-  guint64 value = g_ascii_strtoull(value_str, NULL, 10);
+  guint64 value = g_ascii_strtoull(value_str, &end_ptr, 10);
 
   if (errno != 0) {
 
@@ -87,12 +89,13 @@ guint64 util_read_num(char *key, guint64 default_value) {
 gboolean util_output_enabled(void) {
 
   static gboolean initialized = FALSE;
-  static gboolean enabled = TRUE;
+  static gboolean enabled = FALSE;
 
   if (!initialized) {
 
     initialized = TRUE;
-    if (getenv("AFL_DEBUG_CHILD") == NULL) { enabled = FALSE; }
+    if (getenv("AFL_DEBUG_CHILD") != NULL) { enabled = TRUE; }
+    if (util_verbose_enabled()) { enabled = TRUE; }
 
   }
 
@@ -100,6 +103,21 @@ gboolean util_output_enabled(void) {
 
 }
 
+gboolean util_verbose_enabled(void) {
+
+  static gboolean initialized = FALSE;
+
+  if (!initialized) {
+
+    initialized = TRUE;
+    if (getenv("AFL_FRIDA_VERBOSE") != NULL) { util_verbose = TRUE; }
+
+  }
+
+  return util_verbose;
+
+}
+
 gsize util_rotate(gsize val, gsize shift, gsize size) {
 
   if (shift == 0) { return val; }