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/instrument/instrument.c8
-rw-r--r--frida_mode/src/instrument/instrument_x64.c205
-rw-r--r--frida_mode/src/prefetch.c8
-rw-r--r--frida_mode/src/seccomp/seccomp_callback.c6
4 files changed, 192 insertions, 35 deletions
diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c
index fd0982f8..71d9bdf6 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;
 
   }
 
diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c
index fec8afbb..1c2cf113 100644
--- a/frida_mode/src/instrument/instrument_x64.c
+++ b/frida_mode/src/instrument/instrument_x64.c
@@ -1,6 +1,9 @@
+#include <stddef.h>
+
 #include "frida-gumjs.h"
 
 #include "config.h"
+#include "debug.h"
 
 #include "instrument.h"
 
@@ -8,38 +11,120 @@
 
 static GumAddress current_log_impl = GUM_ADDRESS(0);
 
-static const guint8 afl_log_code[] = {
+  #pragma pack(push, 1)
+
+typedef struct {
+
+  /*
+   * pushfq
+   * push rdx
+   * mov rdx, [&previouspc] (rip relative addr)
+   * xor rdx, rdi (current_pc)
+   * shr rdi. 1
+   * mov [&previouspc], rdi
+   * lea rsi, [&_afl_area_ptr] (rip relative)
+   * add rdx, rsi
+   * add byte ptr [rdx], 1
+   * adc byte ptr [rdx], 0
+
+   * pop rdx
+   * popfq
+   */
+  uint8_t push_fq;
+  uint8_t push_rdx;
+  uint8_t mov_rdx_rip_off[7];
+  uint8_t xor_rdx_rdi[3];
+  uint8_t shr_rdi[3];
+  uint8_t mov_rip_off_rdi[7];
+
+  uint8_t lea_rdi_rip_off[7];
+  uint8_t add_rdx_rdi[3];
+  uint8_t add_byte_ptr_rdx[3];
+  uint8_t adc_byte_ptr_rdx[3];
+
+  uint8_t pop_rdx;
+  uint8_t pop_fq;
+  uint8_t ret;
+
+} afl_log_code_asm_t;
+
+  #pragma pack(pop)
+
+  #pragma pack(push, 8)
+typedef struct {
+
+  afl_log_code_asm_t assembly;
+  uint64_t           current_pc;
+
+} afl_log_code_t;
+
+  #pragma pack(pop)
+
+typedef union {
+
+  afl_log_code_t data;
+  uint8_t        bytes[0];
+
+} afl_log_code;
+
+static const afl_log_code_asm_t template = {
+
+    .push_fq = 0x9c,
+    .push_rdx = 0x52,
+    .mov_rdx_rip_off =
+        {
+
+            0x48, 0x8b, 0x15,
+            /* TBC */
+
+        },
+
+    .xor_rdx_rdi =
+        {
+
+            0x48,
+            0x31,
+            0xfa,
+
+        },
+
+    .shr_rdi = {0x48, 0xd1, 0xef},
+    .mov_rip_off_rdi = {0x48, 0x89, 0x3d},
+
+    .lea_rdi_rip_off =
+        {
+
+            0x48,
+            0x8d,
+            0x3d,
 
-    0x9c,                                                         /* pushfq */
-    0x51,                                                       /* push rcx */
-    0x52,                                                       /* push rdx */
+        },
 
-    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 */
+    .add_rdx_rdi = {0x48, 0x01, 0xfA},
 
-    0x48, 0x03, 0x15, 0x11,
-    0x00, 0x00, 0x00,                     /* add rdx, sym._afl_area_ptr_ptr */
+    .add_byte_ptr_rdx =
+        {
 
-    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 */
+            0x80,
+            0x02,
+            0x01,
 
-    0x5a,                                                        /* pop rdx */
-    0x59,                                                        /* pop rcx */
-    0x9d,                                                          /* popfq */
+        },
 
-    0xc3,                                                            /* ret */
+    .adc_byte_ptr_rdx =
+        {
 
-    0x90
+            0x80,
+            0x12,
+            0x00,
 
-    /* Read-only data goes here: */
-    /* uint8_t* __afl_area_ptr */
-    /* uint64_t* &previous_pc */
+        },
 
-};
+    .pop_rdx = 0x5a,
+    .pop_fq = 0x9d,
+    .ret = 0xc3};
+
+static guint8 align_pad[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
 
 gboolean instrument_is_coverage_optimize_supported(void) {
 
@@ -47,12 +132,19 @@ gboolean instrument_is_coverage_optimize_supported(void) {
 
 }
 
-static guint8 align_pad[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
+static gboolean instrument_coverage_in_range(gssize offset) {
+
+  return (offset >= G_MININT32 && offset <= G_MAXINT32);
+
+}
 
 static void instrument_coverate_write_function(GumStalkerOutput *output) {
 
   guint64       misalign = 0;
   GumX86Writer *cw = output->writer.x86;
+  GumAddress    code_addr = 0;
+  afl_log_code  code = {0};
+  /*guint64       instrument_hash_zero = 0;*/
 
   if (current_log_impl == 0 ||
       !gum_x86_writer_can_branch_directly_between(cw->pc, current_log_impl) ||
@@ -71,13 +163,66 @@ static void instrument_coverate_write_function(GumStalkerOutput *output) {
     }
 
     current_log_impl = cw->pc;
-    gum_x86_writer_put_bytes(cw, afl_log_code, sizeof(afl_log_code));
+    // gum_x86_writer_put_breakpoint(cw);
+    code_addr = cw->pc;
+
+    code.data.assembly = template;
+    code.data.current_pc = instrument_get_offset_hash(0);
+
+    gssize current_pc_value1 =
+        GPOINTER_TO_SIZE(&instrument_previous_pc) -
+        (code_addr + offsetof(afl_log_code, data.assembly.mov_rdx_rip_off) +
+         sizeof(code.data.assembly.mov_rdx_rip_off));
+    gssize patch_offset1 =
+        offsetof(afl_log_code, data.assembly.mov_rdx_rip_off) +
+        sizeof(code.data.assembly.mov_rdx_rip_off) - sizeof(gint);
+    if (!instrument_coverage_in_range(current_pc_value1)) {
+
+      FATAL("Patch out of range (current_pc_value1): 0x%016lX",
+            current_pc_value1);
+
+    }
+
+    gint *dst_pc_value = (gint *)&code.bytes[patch_offset1];
+    *dst_pc_value = (gint)current_pc_value1;
+
+    gssize current_pc_value2 =
+        GPOINTER_TO_SIZE(&instrument_previous_pc) -
+        (code_addr + offsetof(afl_log_code, data.assembly.mov_rip_off_rdi) +
+         sizeof(code.data.assembly.mov_rip_off_rdi));
+    gssize patch_offset2 =
+        offsetof(afl_log_code, data.assembly.mov_rip_off_rdi) +
+        sizeof(code.data.assembly.mov_rip_off_rdi) - sizeof(gint);
+
+    if (!instrument_coverage_in_range(current_pc_value2)) {
+
+      FATAL("Patch out of range (current_pc_value2): 0x%016lX",
+            current_pc_value2);
+
+    }
+
+    dst_pc_value = (gint *)&code.bytes[patch_offset2];
+    *dst_pc_value = (gint)current_pc_value2;
+
+    gsize afl_area_ptr_value =
+        GPOINTER_TO_SIZE(__afl_area_ptr) -
+        (code_addr + offsetof(afl_log_code, data.assembly.lea_rdi_rip_off) +
+         sizeof(code.data.assembly.lea_rdi_rip_off));
+    gssize afl_area_ptr_offset =
+        offsetof(afl_log_code, data.assembly.lea_rdi_rip_off) +
+        sizeof(code.data.assembly.lea_rdi_rip_off) - sizeof(gint);
+
+    if (!instrument_coverage_in_range(afl_area_ptr_value)) {
+
+      FATAL("Patch out of range (afl_area_ptr_value): 0x%016lX",
+            afl_area_ptr_value);
+
+    }
+
+    gint *dst_afl_area_ptr_value = (gint *)&code.bytes[afl_area_ptr_offset];
+    *dst_afl_area_ptr_value = (gint)afl_area_ptr_value;
 
-    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));
+    gum_x86_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code));
 
     gum_x86_writer_put_label(cw, after_log_impl);
 
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/seccomp/seccomp_callback.c b/frida_mode/src/seccomp/seccomp_callback.c
index 4af2ed0c..7e1e2070 100644
--- a/frida_mode/src/seccomp/seccomp_callback.c
+++ b/frida_mode/src/seccomp/seccomp_callback.c
@@ -14,8 +14,12 @@ static void seccomp_callback_filter(struct seccomp_notif *     req,
   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(