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_x64.c202
1 files changed, 172 insertions, 30 deletions
diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c
index fec8afbb..8948c4df 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,63 @@ 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 *)&code.bytes[patch_offset1]) = (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);
+
+    }
+
+    *((gint *)&code.bytes[patch_offset2]) = (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 *)&code.bytes[afl_area_ptr_offset]) = (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);