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/entry.c32
-rw-r--r--frida_mode/src/instrument/instrument.c9
-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_coverage.c1
-rw-r--r--frida_mode/src/instrument/instrument_x64.c318
-rw-r--r--frida_mode/src/instrument/instrument_x86.c3
-rw-r--r--frida_mode/src/js/api.js7
-rw-r--r--frida_mode/src/js/js_api.c6
-rw-r--r--frida_mode/src/main.c13
-rw-r--r--frida_mode/src/prefetch.c8
-rw-r--r--frida_mode/src/ranges.c13
-rw-r--r--frida_mode/src/seccomp/seccomp.c136
-rw-r--r--frida_mode/src/seccomp/seccomp_atomic.c10
-rw-r--r--frida_mode/src/seccomp/seccomp_callback.c144
-rw-r--r--frida_mode/src/seccomp/seccomp_child.c28
-rw-r--r--frida_mode/src/seccomp/seccomp_event.c18
-rw-r--r--frida_mode/src/seccomp/seccomp_filter.c61
-rw-r--r--frida_mode/src/seccomp/seccomp_print.c30
-rw-r--r--frida_mode/src/seccomp/seccomp_socket.c16
-rw-r--r--frida_mode/src/seccomp/seccomp_syscall.c12
21 files changed, 619 insertions, 253 deletions
diff --git a/frida_mode/src/entry.c b/frida_mode/src/entry.c
index 186ddd3a..c51e202f 100644
--- a/frida_mode/src/entry.c
+++ b/frida_mode/src/entry.c
@@ -1,5 +1,9 @@
 #include <dlfcn.h>
 
+#if defined(__linux__) && !defined(__ANDROID__)
+  #include <sys/prctl.h>
+#endif
+
 #include "frida-gumjs.h"
 
 #include "debug.h"
@@ -16,6 +20,7 @@
 extern void __afl_manual_init();
 
 guint64  entry_point = 0;
+gboolean traceable = FALSE;
 gboolean entry_compiled = FALSE;
 gboolean entry_run = FALSE;
 
@@ -26,21 +31,48 @@ static void entry_launch(void) {
 
   /* Child here */
   entry_run = TRUE;
+  entry_on_fork();
   instrument_on_fork();
   seccomp_on_fork();
   stats_on_fork();
 
 }
 
+#if defined(__linux__) && !defined(__ANDROID__)
+void entry_on_fork(void) {
+
+  if (traceable) {
+
+    if (prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY) < 0) {
+
+      FATAL("Failed to PR_SET_PTRACER");
+
+    }
+
+  }
+
+}
+
+#else
+void entry_on_fork(void) {
+
+  if (traceable) { WARNF("AFL_FRIDA_TRACEABLE unsupported"); }
+
+}
+
+#endif
+
 void entry_config(void) {
 
   entry_point = util_read_address("AFL_ENTRYPOINT");
+  if (getenv("AFL_FRIDA_TRACEABLE") != NULL) { traceable = TRUE; }
 
 }
 
 void entry_init(void) {
 
   OKF("entry_point: 0x%016" G_GINT64_MODIFIER "X", entry_point);
+  OKF("dumpable: [%c]", traceable ? 'X' : ' ');
 
   if (dlopen(NULL, RTLD_NOW) == NULL) { FATAL("Failed to dlopen: %d", errno); }
 
diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c
index fd0982f8..81d85aa1 100644
--- a/frida_mode/src/instrument/instrument.c
+++ b/frida_mode/src/instrument/instrument.c
@@ -341,8 +341,14 @@ void instrument_init(void) {
      * parallel fuzzing. The seed itself, doesn't have to be random, it
      * just needs to be different for each instance.
      */
+    guint64 tid;
+#if defined(__APPLE__)
+    pthread_threadid_np(NULL, &tid);
+#else
+    tid = syscall(SYS_gettid);
+#endif
     instrument_hash_seed = g_get_monotonic_time() ^
-                           (((guint64)getpid()) << 32) ^ syscall(SYS_gettid);
+                           (((guint64)getpid()) << 32) ^ tid;
 
   }
 
@@ -350,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_coverage.c b/frida_mode/src/instrument/instrument_coverage.c
index 46c816bc..513df29a 100644
--- a/frida_mode/src/instrument/instrument_coverage.c
+++ b/frida_mode/src/instrument/instrument_coverage.c
@@ -711,7 +711,6 @@ void instrument_coverage_normal_init(void) {
 
 void instrument_coverage_unstable_find_output(void) {
 
-  pid_t  parent = getpid();
   gchar *fds_name = g_strdup_printf("/proc/%d/fd/", getppid());
 
   gchar *root = g_file_read_link("/proc/self/root", NULL);
diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c
index fec8afbb..a7eb650a 100644
--- a/frida_mode/src/instrument/instrument_x64.c
+++ b/frida_mode/src/instrument/instrument_x64.c
@@ -1,105 +1,307 @@
+#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"
 
 #include "config.h"
+#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
 
-static const guint8 afl_log_code[] = {
+gboolean instrument_is_coverage_optimize_supported(void) {
 
-    0x9c,                                                         /* pushfq */
-    0x51,                                                       /* push rcx */
-    0x52,                                                       /* push rdx */
+  return true;
 
-    0x48, 0x8b, 0x0d, 0x26,
-    0x00, 0x00, 0x00,                          /* mov rcx, sym.&previous_pc */
-    0x48, 0x8b, 0x11,                               /* mov rdx, qword [rcx] */
-    0x48, 0x31, 0xfa,                                       /* xor rdx, rdi */
+}
 
-    0x48, 0x03, 0x15, 0x11,
-    0x00, 0x00, 0x00,                     /* add rdx, sym._afl_area_ptr_ptr */
+static gboolean instrument_coverage_in_range(gssize offset) {
 
-    0x80, 0x02, 0x01,                              /* add byte ptr [rdx], 1 */
-    0x80, 0x12, 0x00,                              /* adc byte ptr [rdx], 0 */
-    0x66, 0xd1, 0xcf,                                          /* ror di, 1 */
-    0x48, 0x89, 0x39,                               /* mov qword [rcx], rdi */
+  return (offset >= G_MININT32 && offset <= G_MAXINT32);
 
-    0x5a,                                                        /* pop rdx */
-    0x59,                                                        /* pop rcx */
-    0x9d,                                                          /* popfq */
+}
 
-    0xc3,                                                            /* ret */
+  #pragma pack(push, 1)
+typedef struct {
 
-    0x90
+  // cur_location = (block_address >> 4) ^ (block_address << 8);
+  // shared_mem[cur_location ^ prev_location]++;
+  // prev_location = cur_location >> 1;
 
-    /* Read-only data goes here: */
-    /* uint8_t* __afl_area_ptr */
-    /* uint64_t* &previous_pc */
+  // => 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]
 
-};
 
-gboolean instrument_is_coverage_optimize_supported(void) {
+  uint8_t lea_rsp_rsp_sub_rz[5];
+  uint8_t push_fq;
+  uint8_t push_rsi;
 
-  return true;
+  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 lsa_rsp_rsp_add_rz[8];
+
+} afl_log_code_asm_t;
+
+  #pragma pack(pop)
+
+typedef union {
+
+  afl_log_code_asm_t code;
+  uint8_t            bytes[0];
+
+} afl_log_code;
+
+static const afl_log_code_asm_t template =
+    {
+
+        .lea_rsp_rsp_sub_rz = {0x48, 0x8D, 0x64, 0x24, 0x80},
+        .push_fq = 0x9c,
+        .push_rsi = 0x56,
+
+        .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},
+
+        .add_rsi_1 = {0x80, 0x86, 0x00, 0x00, 0x00, 0x00, 0x01},
+        .adc_rsi_0 = {0x80, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00},
+
+        .pop_rsi = 0x5E,
+        .pop_fq = 0x9D,
+        .lsa_rsp_rsp_add_rz = {0x48, 0x8D, 0xA4, 0x24, 0x80, 0x00, 0x00, 0x00},
 
 }
 
-static guint8 align_pad[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
+;
 
-static void instrument_coverate_write_function(GumStalkerOutput *output) {
+static gboolean instrument_coverage_find_low(const GumRangeDetails *details,
+                                             gpointer               user_data) {
 
-  guint64       misalign = 0;
-  GumX86Writer *cw = output->writer.x86;
+  static GumAddress last_limit = (64ULL << 10);
+  gpointer *        address = (gpointer *)user_data;
 
-  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)) {
+  if ((details->range->base_address - last_limit) > __afl_map_size) {
 
-    gconstpointer after_log_impl = cw->code + 1;
+    *address = GSIZE_TO_POINTER(last_limit);
+    return FALSE;
 
-    gum_x86_writer_put_jmp_near_label(cw, after_log_impl);
+  }
 
-    misalign = (cw->pc & 0x7);
-    if (misalign != 0) {
+  if (details->range->base_address > ((2ULL << 20) - __afl_map_size)) {
 
-      gum_x86_writer_put_bytes(cw, align_pad, 8 - misalign);
+    return FALSE;
 
-    }
+  }
+
+  last_limit = details->range->base_address + details->range->size;
+  return TRUE;
+
+}
+
+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) {
+
+    FATAL("Failed to map mmap __afl_area_ptr: %d", errno);
+
+  }
+
+}
+
+static void instrument_coverage_optimize_map_mmap(char *   shm_file_path,
+                                                  gpointer address) {
+
+  int shm_fd = -1;
+
+  if (munmap(__afl_area_ptr, __afl_map_size) != 0) {
+
+    FATAL("Failed to unmap previous __afl_area_ptr");
+
+  }
+
+  __afl_area_ptr = NULL;
+
+#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"); }
+
+}
 
-    current_log_impl = cw->pc;
-    gum_x86_writer_put_bytes(cw, afl_log_code, sizeof(afl_log_code));
+static void instrument_coverage_optimize_map_shm(guint64  shm_env_val,
+                                                 gpointer address) {
 
-    uint64_t *afl_prev_loc_ptr = &instrument_previous_pc;
-    gum_x86_writer_put_bytes(cw, (const guint8 *)&__afl_area_ptr,
-                             sizeof(__afl_area_ptr));
-    gum_x86_writer_put_bytes(cw, (const guint8 *)&afl_prev_loc_ptr,
-                             sizeof(afl_prev_loc_ptr));
+  if (shmdt(__afl_area_ptr) != 0) {
 
-    gum_x86_writer_put_label(cw, after_log_impl);
+    FATAL("Failed to detach previous __afl_area_ptr");
+
+  }
+
+  __afl_area_ptr = shmat(shm_env_val, address, 0);
+  if (__afl_area_ptr != address) {
+
+    FATAL("Failed to map shm __afl_area_ptr: %d", errno);
 
   }
 
 }
 
+void instrument_coverage_optimize_init(void) {
+
+  gpointer low_address = NULL;
+
+  gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, instrument_coverage_find_low,
+                               &low_address);
+
+  OKF("Low address: %p", low_address);
+
+  if (low_address == 0 ||
+      GPOINTER_TO_SIZE(low_address) > ((2UL << 20) - __afl_map_size)) {
+
+    FATAL("Invalid low_address: %p", low_address);
+
+  }
+
+  ranges_print_debug_maps();
+
+  char *shm_env = getenv(SHM_ENV_VAR);
+  OKF("SHM_ENV_VAR: %s", shm_env);
+
+  if (shm_env == NULL) {
+
+    WARNF("SHM_ENV_VAR not set, using anonymous map for debugging purposes");
+
+    instrument_coverage_optimize_map_mmap_anon(low_address);
+
+  } else {
+
+    guint64 shm_env_val = g_ascii_strtoull(shm_env, NULL, 10);
+
+    if (shm_env_val == 0) {
+
+      instrument_coverage_optimize_map_mmap(shm_env, low_address);
+
+    } else {
+
+      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/js/api.js b/frida_mode/src/js/api.js
index 40bb4a16..6f9f05d8 100644
--- a/frida_mode/src/js/api.js
+++ b/frida_mode/src/js/api.js
@@ -243,6 +243,12 @@ class Afl {
         const buf = Memory.allocUtf8String(file);
         Afl.jsApiSetStdOut(buf);
     }
+    /**
+     * See `AFL_FRIDA_TRACEABLE`.
+     */
+    static setTraceable() {
+        Afl.jsApiSetTraceable();
+    }
     static jsApiGetFunction(name, retType, argTypes) {
         const addr = Afl.module.getExportByName(name);
         return new NativeFunction(addr, retType, argTypes);
@@ -286,6 +292,7 @@ Afl.jsApiSetStatsFile = Afl.jsApiGetFunction("js_api_set_stats_file", "void", ["
 Afl.jsApiSetStatsInterval = Afl.jsApiGetFunction("js_api_set_stats_interval", "void", ["uint64"]);
 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.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_api.c b/frida_mode/src/js/js_api.c
index 9dba79aa..f3d81a32 100644
--- a/frida_mode/src/js/js_api.c
+++ b/frida_mode/src/js/js_api.c
@@ -231,3 +231,9 @@ __attribute__((visibility("default"))) void js_api_set_stalker_ic_entries(
 
 }
 
+__attribute__((visibility("default"))) void js_api_set_traceable(void) {
+
+  traceable = TRUE;
+
+}
+
diff --git a/frida_mode/src/main.c b/frida_mode/src/main.c
index c0de9c6b..c8183d8f 100644
--- a/frida_mode/src/main.c
+++ b/frida_mode/src/main.c
@@ -6,6 +6,7 @@
 #ifdef __APPLE__
   #include <mach/mach.h>
   #include <mach-o/dyld_images.h>
+  #include <crt_externs.h>
 #else
   #include <sys/wait.h>
   #include <sys/personality.h>
@@ -90,6 +91,7 @@ static void embedded_init(void) {
 
 static void afl_print_cmdline(void) {
 
+#if defined(__linux__)
   char * buffer = g_malloc0(PROC_MAX);
   gchar *fname = g_strdup_printf("/proc/%d/cmdline", getppid());
   int    fd = open(fname, O_RDONLY);
@@ -123,6 +125,17 @@ static void afl_print_cmdline(void) {
   close(fd);
   g_free(fname);
   g_free(buffer);
+#elif defined(__APPLE__)
+  int idx;
+  char **argv = *_NSGetArgv();
+  int nargv = *_NSGetArgc();
+
+  for (idx = 0; idx < nargv; idx ++) {
+
+    OKF("AFL - COMMANDLINE: argv[%d] = %s", idx, argv[idx]);
+
+  }
+#endif
 
 }
 
diff --git a/frida_mode/src/prefetch.c b/frida_mode/src/prefetch.c
index 0efbc9bf..c30ca65c 100644
--- a/frida_mode/src/prefetch.c
+++ b/frida_mode/src/prefetch.c
@@ -44,8 +44,9 @@ static void gum_afl_stalker_backpatcher_notify(GumStalkerObserver *self,
       sizeof(prefetch_data->backpatch_data) - prefetch_data->backpatch_size;
   if (sizeof(gsize) + size > remaining) { return; }
 
-  *(gsize *)(&prefetch_data->backpatch_data[prefetch_data->backpatch_size]) =
-      size;
+  gsize *dst_backpatch_size = (gsize *)
+      &prefetch_data->backpatch_data[prefetch_data->backpatch_size];
+  *dst_backpatch_size = size;
   prefetch_data->backpatch_size += sizeof(gsize);
 
   memcpy(&prefetch_data->backpatch_data[prefetch_data->backpatch_size],
@@ -115,7 +116,8 @@ static void prefetch_read_patches(void) {
        remaining > sizeof(gsize);
        remaining = prefetch_data->backpatch_size - offset) {
 
-    gsize size = *(gsize *)(&prefetch_data->backpatch_data[offset]);
+    gsize *src_backpatch_data = (gsize *)&prefetch_data->backpatch_data[offset];
+    gsize size = *src_backpatch_data;
     offset += sizeof(gsize);
 
     if (prefetch_data->backpatch_size - offset < size) {
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.c b/frida_mode/src/seccomp/seccomp.c
index 7683cd71..99111591 100644
--- a/frida_mode/src/seccomp/seccomp.c
+++ b/frida_mode/src/seccomp/seccomp.c
@@ -1,9 +1,3 @@
-#include <execinfo.h>
-#include <fcntl.h>
-#include <linux/seccomp.h>
-#include <stdio.h>
-#include <unistd.h>
-
 #include "frida-gumjs.h"
 
 #include "debug.h"
@@ -13,111 +7,15 @@
 
 char *seccomp_filename = NULL;
 
-static void seccomp_vprint(int fd, char *format, va_list ap) {
-
-  char buffer[4096] = {0};
-  int  len;
-
-  if (vsnprintf(buffer, sizeof(buffer) - 1, format, ap) < 0) { return; }
-
-  len = strnlen(buffer, sizeof(buffer));
-  IGNORED_RETURN(write(fd, buffer, len));
-
-}
-
-void seccomp_print(char *format, ...) {
-
-  va_list ap;
-  va_start(ap, format);
-  seccomp_vprint(SECCOMP_OUTPUT_FILE_FD, format, ap);
-  va_end(ap);
-
-}
-
-static void seccomp_filter_callback(struct seccomp_notif *     req,
-                                    struct seccomp_notif_resp *resp,
-                                    GumReturnAddressArray *    frames) {
-
-  GumDebugSymbolDetails details = {0};
-  if (req->data.nr == SYS_OPENAT) {
-
-    seccomp_print("SYS_OPENAT: (%s)\n", (char *)req->data.args[1]);
-
-  }
-
-  seccomp_print(
-      "\nID (%#llx) for PID %d - %d (%s) [0x%llx 0x%llx 0x%llx 0x%llx 0x%llx "
-      "0x%llx ]\n",
-      req->id, req->pid, req->data.nr, seccomp_syscall_lookup(req->data.nr),
-      req->data.args[0], req->data.args[1], req->data.args[2],
-      req->data.args[3], req->data.args[4], req->data.args[5]);
-
-  seccomp_print("FRAMES: (%u)\n", frames->len);
-  char **syms = backtrace_symbols(frames->items, frames->len);
-  if (syms == NULL) { FATAL("Failed to get symbols"); }
-
-  for (guint i = 0; i < frames->len; i++) {
-
-    if (gum_symbol_details_from_address(frames->items[i], &details)) {
-
-      seccomp_print("\t%3d. %s!%s\n", i, details.module_name,
-                    details.symbol_name);
-
-    } else {
-
-      seccomp_print("\t%3d. %s\n", i, syms[i]);
-
-    }
-
-  }
-
-  free(syms);
-
-  resp->error = 0;
-  resp->val = 0;
-  resp->id = req->id;
-  resp->flags = SECCOMP_USER_NOTIF_FLAG_CONTINUE;
-
-}
-
-static void seccomp_child(int signal_parent, void *ctx) {
-
-  int sock_fd = *((int *)ctx);
-  int fd = seccomp_socket_recv(sock_fd);
-
-  if (close(sock_fd) < 0) { FATAL("child - close"); }
-
-  seccomp_event_signal(signal_parent);
-  seccomp_filter_child_install();
-  seccomp_filter_run(fd, seccomp_filter_callback);
-
-}
-
 void seccomp_on_fork(void) {
 
-  int   sock[2] = {-1, -1};
-  pid_t child = -1;
-  int   child_fd = -1;
-
   if (seccomp_filename == NULL) { return; }
 
-  seccomp_socket_create(sock);
-  seccomp_child_run(seccomp_child, sock, &child, &child_fd);
-
-  if (dup2(child_fd, SECCOMP_PARENT_EVENT_FD) < 0) { FATAL("dup2"); }
-
-  if (close(child_fd) < 0) { FATAL("seccomp_on_fork - close (1)"); }
-
-  if (close(sock[STDIN_FILENO]) < 0) { FATAL("grandparent - close (2)"); }
-
-  int fd = seccomp_filter_install(child);
-  seccomp_socket_send(sock[STDOUT_FILENO], fd);
-
-  if (close(sock[STDOUT_FILENO]) < 0) { FATAL("grandparent - close (3)"); }
-
-  if (close(fd) < 0) { FATAL("grandparent - close (4)"); }
-
-  seccomp_child_wait(SECCOMP_PARENT_EVENT_FD);
+#ifdef __APPLE__
+  FATAL("Seccomp not supported on OSX");
+#else
+  seccomp_callback_parent();
+#endif
 
 }
 
@@ -129,29 +27,15 @@ void seccomp_config(void) {
 
 void seccomp_init(void) {
 
-  char *path = NULL;
-  int   fd;
-
   OKF("Seccomp - file [%s]", seccomp_filename);
 
   if (seccomp_filename == NULL) { return; }
 
-  path = g_canonicalize_filename(seccomp_filename, g_get_current_dir());
-
-  OKF("Seccomp - path [%s]", path);
-
-  fd = open(path, O_RDWR | O_CREAT | O_TRUNC,
-            S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
-
-  if (dup2(fd, SECCOMP_OUTPUT_FILE_FD) < 0) {
-
-    FATAL("Failed to duplicate seccomp output file");
-
-  }
-
-  if (close(fd) < 0) { FATAL("Failed to close seccomp output file fd"); }
-
-  g_free(path);
+#ifdef __APPLE__
+  FATAL("Seccomp not supported on OSX");
+#else
+  seccomp_callback_initialize();
+#endif
 
 }
 
diff --git a/frida_mode/src/seccomp/seccomp_atomic.c b/frida_mode/src/seccomp/seccomp_atomic.c
index 1720a726..c2042f97 100644
--- a/frida_mode/src/seccomp/seccomp_atomic.c
+++ b/frida_mode/src/seccomp/seccomp_atomic.c
@@ -1,7 +1,9 @@
-#include <stdbool.h>
-#include <stdio.h>
+#if defined(__linux__) && !defined(__ANDROID__)
 
-#include "debug.h"
+  #include <stdbool.h>
+  #include <stdio.h>
+
+  #include "debug.h"
 
 void seccomp_atomic_set(volatile bool *ptr, bool val) {
 
@@ -26,3 +28,5 @@ void seccomp_atomic_wait(volatile bool *ptr, bool val) {
 
 }
 
+#endif
+
diff --git a/frida_mode/src/seccomp/seccomp_callback.c b/frida_mode/src/seccomp/seccomp_callback.c
new file mode 100644
index 00000000..4232d842
--- /dev/null
+++ b/frida_mode/src/seccomp/seccomp_callback.c
@@ -0,0 +1,144 @@
+#if defined(__linux__) && !defined(__ANDROID__)
+
+#if !defined(__MUSL__)
+  #include <execinfo.h>
+#endif
+  #include <fcntl.h>
+
+  #include "seccomp.h"
+
+  #include "debug.h"
+
+static void seccomp_callback_filter(struct seccomp_notif *     req,
+                                    struct seccomp_notif_resp *resp,
+                                    GumReturnAddressArray *    frames) {
+
+  GumDebugSymbolDetails details = {0};
+  if (req->data.nr == SYS_OPENAT) {
+
+#if UINTPTR_MAX == 0xffffffffffffffffu
+    seccomp_print("SYS_OPENAT: (%s)\n", (char *)req->data.args[1]);
+#endif
+#if UINTPTR_MAX == 0xffffffff
+    seccomp_print("SYS_OPENAT: (%s)\n", (char *)(__u32)req->data.args[1]);
+#endif
+  }
+
+  seccomp_print(
+      "\nID (%#llx) for PID %d - %d (%s) [0x%llx 0x%llx 0x%llx 0x%llx 0x%llx "
+      "0x%llx ]\n",
+      req->id, req->pid, req->data.nr, seccomp_syscall_lookup(req->data.nr),
+      req->data.args[0], req->data.args[1], req->data.args[2],
+      req->data.args[3], req->data.args[4], req->data.args[5]);
+
+#if !defined(__MUSL__)
+  seccomp_print("FRAMES: (%u)\n", frames->len);
+  char **syms = backtrace_symbols(frames->items, frames->len);
+  if (syms == NULL) { FATAL("Failed to get symbols"); }
+
+  for (guint i = 0; i < frames->len; i++) {
+
+    if (gum_symbol_details_from_address(frames->items[i], &details)) {
+
+      seccomp_print("\t%3d. %s!%s\n", i, details.module_name,
+                    details.symbol_name);
+
+    } else {
+
+      seccomp_print("\t%3d. %s\n", i, syms[i]);
+
+    }
+
+  }
+
+  free(syms);
+#else
+  void **syms = (void **)__builtin_frame_address(0);
+  void *framep = __builtin_frame_address(1);
+  int i = 0;
+
+  syms = framep;
+  while (syms) {
+   
+    framep = *syms;   
+    syms = framep;
+
+    if (!syms) break;
+
+    seccomp_print("\%3d. %s\n", i ++, (char *)framep);
+
+  }
+#endif
+
+  resp->error = 0;
+  resp->val = 0;
+  resp->id = req->id;
+  resp->flags = SECCOMP_USER_NOTIF_FLAG_CONTINUE;
+
+}
+
+static void seccomp_callback_child(int signal_parent, void *ctx) {
+
+  int sock_fd = *((int *)ctx);
+  int fd = seccomp_socket_recv(sock_fd);
+
+  if (close(sock_fd) < 0) { FATAL("child - close"); }
+
+  seccomp_event_signal(signal_parent);
+  seccomp_filter_child_install();
+  seccomp_filter_run(fd, seccomp_callback_filter);
+
+}
+
+void seccomp_callback_parent(void) {
+
+  int   sock[2] = {-1, -1};
+  pid_t child = -1;
+  int   child_fd = -1;
+
+  seccomp_socket_create(sock);
+  seccomp_child_run(seccomp_callback_child, sock, &child, &child_fd);
+
+  if (dup2(child_fd, SECCOMP_PARENT_EVENT_FD) < 0) { FATAL("dup2"); }
+
+  if (close(child_fd) < 0) { FATAL("seccomp_on_fork - close (1)"); }
+
+  if (close(sock[STDIN_FILENO]) < 0) { FATAL("grandparent - close (2)"); }
+
+  int fd = seccomp_filter_install(child);
+  seccomp_socket_send(sock[STDOUT_FILENO], fd);
+
+  if (close(sock[STDOUT_FILENO]) < 0) { FATAL("grandparent - close (3)"); }
+
+  if (close(fd) < 0) { FATAL("grandparent - close (4)"); }
+
+  seccomp_child_wait(SECCOMP_PARENT_EVENT_FD);
+
+}
+
+void seccomp_callback_initialize(void) {
+
+  char *path = NULL;
+  int   fd;
+
+  path = g_canonicalize_filename(seccomp_filename, g_get_current_dir());
+
+  OKF("Seccomp - path [%s]", path);
+
+  fd = open(path, O_RDWR | O_CREAT | O_TRUNC,
+            S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+
+  if (dup2(fd, SECCOMP_OUTPUT_FILE_FD) < 0) {
+
+    FATAL("Failed to duplicate seccomp output file");
+
+  }
+
+  if (close(fd) < 0) { FATAL("Failed to close seccomp output file fd"); }
+
+  g_free(path);
+
+}
+
+#endif
+
diff --git a/frida_mode/src/seccomp/seccomp_child.c b/frida_mode/src/seccomp/seccomp_child.c
index 4d494137..43a79894 100644
--- a/frida_mode/src/seccomp/seccomp_child.c
+++ b/frida_mode/src/seccomp/seccomp_child.c
@@ -1,18 +1,20 @@
-#include <fcntl.h>
-#include <sched.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-#include <sys/prctl.h>
-#include <sys/types.h>
-#include <unistd.h>
+#if defined(__linux__) && !defined(__ANDROID__)
 
-#include "debug.h"
+  #include <fcntl.h>
+  #include <sched.h>
+  #include <signal.h>
+  #include <stdio.h>
+  #include <stdlib.h>
+  #include <sys/mman.h>
+  #include <sys/prctl.h>
+  #include <sys/types.h>
+  #include <unistd.h>
 
-#include "seccomp.h"
+  #include "debug.h"
 
-#define SECCOMP_CHILD_STACK_SIZE (1UL << 20)
+  #include "seccomp.h"
+
+  #define SECCOMP_CHILD_STACK_SIZE (1UL << 20)
 
 typedef void (*seccomp_child_func_t)(int event_fd, void *ctx);
 
@@ -67,3 +69,5 @@ void seccomp_child_wait(int event_fd) {
 
 }
 
+#endif
+
diff --git a/frida_mode/src/seccomp/seccomp_event.c b/frida_mode/src/seccomp/seccomp_event.c
index ecb9be32..e2f592ca 100644
--- a/frida_mode/src/seccomp/seccomp_event.c
+++ b/frida_mode/src/seccomp/seccomp_event.c
@@ -1,15 +1,17 @@
-#include <stdint.h>
-#include <stdio.h>
-#include <sys/eventfd.h>
-#include <unistd.h>
+#if defined(__linux__) && !defined(__ANDROID__)
 
-#include "debug.h"
+  #include <stdint.h>
+  #include <stdio.h>
+  #include <sys/syscall.h>
+  #include <unistd.h>
 
-#include "seccomp.h"
+  #include "debug.h"
+
+  #include "seccomp.h"
 
 int seccomp_event_create(void) {
 
-  int fd = eventfd(0, 0);
+  int fd = syscall(SYS_eventfd, 0, 0);
   if (fd < 0) { FATAL("seccomp_event_create"); }
   return fd;
 
@@ -43,3 +45,5 @@ void seccomp_event_destroy(int fd) {
 
 }
 
+#endif
+
diff --git a/frida_mode/src/seccomp/seccomp_filter.c b/frida_mode/src/seccomp/seccomp_filter.c
index c16e7ebd..7ee5ead1 100644
--- a/frida_mode/src/seccomp/seccomp_filter.c
+++ b/frida_mode/src/seccomp/seccomp_filter.c
@@ -1,27 +1,30 @@
-#include <alloca.h>
-#include <errno.h>
-#include <execinfo.h>
-#include <linux/filter.h>
-#include <linux/seccomp.h>
-#include <sys/ioctl.h>
-#include <sys/prctl.h>
-#include <sys/syscall.h>
-#include <signal.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "debug.h"
-
-#include "frida-gumjs.h"
-
-#include "seccomp.h"
-#include "util.h"
-
-#define SECCOMP_FILTER_NUM_FRAMES 512
+#if defined(__linux__) && !defined(__ANDROID__)
+
+  #include <alloca.h>
+  #include <errno.h>
+#if !defined(__MUSL__)
+  #include <execinfo.h>
+#endif
+  #include <linux/filter.h>
+  #include <sys/ioctl.h>
+  #include <sys/prctl.h>
+  #include <sys/syscall.h>
+  #include <signal.h>
+  #include <stdbool.h>
+  #include <stddef.h>
+  #include <stdio.h>
+  #include <stdlib.h>
+  #include <string.h>
+  #include <unistd.h>
+
+  #include "debug.h"
+
+  #include "frida-gumjs.h"
+
+  #include "seccomp.h"
+  #include "util.h"
+
+  #define SECCOMP_FILTER_NUM_FRAMES 512
 
 extern void gum_linux_parse_ucontext(const ucontext_t *uc, GumCpuContext *ctx);
 
@@ -127,7 +130,10 @@ static GumBacktracer *       seccomp_filter_backtracer = NULL;
 static void seccomp_filter_child_handler(int sig, siginfo_t *info,
                                          void *ucontext) {
 
-  GumCpuContext cpu_context;
+  UNUSED_PARAMETER(sig);
+  UNUSED_PARAMETER(info);
+  UNUSED_PARAMETER(ucontext);
+
   if (seccomp_filter_backtracer == NULL) {
 
     seccomp_filter_backtracer = gum_backtracer_make_fuzzy();
@@ -150,7 +156,8 @@ static void seccomp_filter_parent_handler(int sig, siginfo_t *info,
   ucontext_t *uc = (ucontext_t *)ucontext;
   gum_linux_parse_ucontext(uc, &seccomp_filter_cpu_context);
 
-  if (tgkill(seccomp_filter_child, seccomp_filter_child, SIGUSR1) < 0) {
+  if (syscall(SYS_tgkill, seccomp_filter_child, seccomp_filter_child, SIGUSR1) <
+      0) {
 
     FATAL("kill");
 
@@ -256,3 +263,5 @@ void seccomp_filter_run(int fd, seccomp_filter_callback_t callback) {
 
 }
 
+#endif
+
diff --git a/frida_mode/src/seccomp/seccomp_print.c b/frida_mode/src/seccomp/seccomp_print.c
new file mode 100644
index 00000000..3cea1239
--- /dev/null
+++ b/frida_mode/src/seccomp/seccomp_print.c
@@ -0,0 +1,30 @@
+#if defined(__linux__) && !defined(__ANDROID__)
+
+  #include <stdarg.h>
+
+  #include "seccomp.h"
+  #include "util.h"
+
+static void seccomp_print_v(int fd, char *format, va_list ap) {
+
+  char buffer[4096] = {0};
+  int  len;
+
+  if (vsnprintf(buffer, sizeof(buffer) - 1, format, ap) < 0) { return; }
+
+  len = strnlen(buffer, sizeof(buffer));
+  IGNORED_RETURN(write(fd, buffer, len));
+
+}
+
+void seccomp_print(char *format, ...) {
+
+  va_list ap;
+  va_start(ap, format);
+  seccomp_print_v(SECCOMP_OUTPUT_FILE_FD, format, ap);
+  va_end(ap);
+
+}
+
+#endif
+
diff --git a/frida_mode/src/seccomp/seccomp_socket.c b/frida_mode/src/seccomp/seccomp_socket.c
index ca42e158..ef937420 100644
--- a/frida_mode/src/seccomp/seccomp_socket.c
+++ b/frida_mode/src/seccomp/seccomp_socket.c
@@ -1,11 +1,13 @@
-#include <stdio.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <unistd.h>
+#if defined(__linux__) && !defined(__ANDROID__)
 
-#include "debug.h"
+  #include <stdio.h>
+  #include <string.h>
+  #include <sys/socket.h>
+  #include <unistd.h>
 
-#include "seccomp.h"
+  #include "debug.h"
+
+  #include "seccomp.h"
 
 union cmsg {
 
@@ -119,3 +121,5 @@ int seccomp_socket_recv(int sockfd) {
 
 }
 
+#endif
+
diff --git a/frida_mode/src/seccomp/seccomp_syscall.c b/frida_mode/src/seccomp/seccomp_syscall.c
index b2c084c8..8335b93c 100644
--- a/frida_mode/src/seccomp/seccomp_syscall.c
+++ b/frida_mode/src/seccomp/seccomp_syscall.c
@@ -1,9 +1,11 @@
-#include <limits.h>
-#include <stdio.h>
+#if defined(__linux__) && !defined(__ANDROID__)
 
-#include "debug.h"
+  #include <limits.h>
+  #include <stdio.h>
 
-#include "seccomp.h"
+  #include "debug.h"
+
+  #include "seccomp.h"
 
 typedef struct {
 
@@ -333,3 +335,5 @@ char *seccomp_syscall_lookup(int id) {
 
 }
 
+#endif
+