about summary refs log tree commit diff
path: root/frida_mode/src/asan
diff options
context:
space:
mode:
Diffstat (limited to 'frida_mode/src/asan')
-rw-r--r--frida_mode/src/asan/asan_arm.c6
-rw-r--r--frida_mode/src/asan/asan_arm64.c6
-rw-r--r--frida_mode/src/asan/asan_x64.c10
-rw-r--r--frida_mode/src/asan/asan_x86.c77
4 files changed, 91 insertions, 8 deletions
diff --git a/frida_mode/src/asan/asan_arm.c b/frida_mode/src/asan/asan_arm.c
index 526017be..79475ced 100644
--- a/frida_mode/src/asan/asan_arm.c
+++ b/frida_mode/src/asan/asan_arm.c
@@ -18,5 +18,11 @@ void asan_instrument(const cs_insn *instr, GumStalkerIterator *iterator) {
 
 }
 
+void asan_arch_init(void) {
+
+  FATAL("ASAN mode not supported on this architecture");
+
+}
+
 #endif
 
diff --git a/frida_mode/src/asan/asan_arm64.c b/frida_mode/src/asan/asan_arm64.c
index 4e3fbafd..6262ee18 100644
--- a/frida_mode/src/asan/asan_arm64.c
+++ b/frida_mode/src/asan/asan_arm64.c
@@ -18,5 +18,11 @@ void asan_instrument(const cs_insn *instr, GumStalkerIterator *iterator) {
 
 }
 
+void asan_arch_init(void) {
+
+  FATAL("ASAN mode not supported on this architecture");
+
+}
+
 #endif
 
diff --git a/frida_mode/src/asan/asan_x64.c b/frida_mode/src/asan/asan_x64.c
index bdf4ac30..a2eabe3c 100644
--- a/frida_mode/src/asan/asan_x64.c
+++ b/frida_mode/src/asan/asan_x64.c
@@ -7,23 +7,23 @@
 #include "ctx.h"
 #include "util.h"
 
+#if defined(__x86_64__)
+
 typedef void (*asan_loadN_t)(uint64_t address, uint8_t size);
 typedef void (*asan_storeN_t)(uint64_t address, uint8_t size);
 
 asan_loadN_t  asan_loadN = NULL;
 asan_storeN_t asan_storeN = NULL;
 
-#if defined(__x86_64__)
-
 static void asan_callout(GumCpuContext *ctx, gpointer user_data) {
 
   UNUSED_PARAMETER(user_data);
 
   cs_x86_op * operand = (cs_x86_op *)user_data;
   x86_op_mem *mem = &operand->mem;
-  uint64_t    base = 0;
-  uint64_t    index = 0;
-  uint64_t    address;
+  gsize       base = 0;
+  gsize       index = 0;
+  gsize       address;
   uint8_t     size;
 
   if (mem->base != X86_REG_INVALID) { base = ctx_read_reg(ctx, mem->base); }
diff --git a/frida_mode/src/asan/asan_x86.c b/frida_mode/src/asan/asan_x86.c
index b946b3bf..8490b490 100644
--- a/frida_mode/src/asan/asan_x86.c
+++ b/frida_mode/src/asan/asan_x86.c
@@ -1,18 +1,89 @@
+#include <dlfcn.h>
 #include "frida-gum.h"
 
 #include "debug.h"
 
 #include "asan.h"
+#include "ctx.h"
 #include "util.h"
 
 #if defined(__i386__)
+
+typedef void (*asan_loadN_t)(gsize address, uint8_t size);
+typedef void (*asan_storeN_t)(gsize address, uint8_t size);
+
+asan_loadN_t  asan_loadN = NULL;
+asan_storeN_t asan_storeN = NULL;
+
+static void asan_callout(GumCpuContext *ctx, gpointer user_data) {
+
+  UNUSED_PARAMETER(user_data);
+
+  cs_x86_op * operand = (cs_x86_op *)user_data;
+  x86_op_mem *mem = &operand->mem;
+  gsize       base = 0;
+  gsize       index = 0;
+  gsize       address;
+  uint8_t     size;
+
+  if (mem->base != X86_REG_INVALID) { base = ctx_read_reg(ctx, mem->base); }
+
+  if (mem->index != X86_REG_INVALID) { index = ctx_read_reg(ctx, mem->index); }
+
+  address = base + (mem->scale * index) + mem->disp;
+  size = operand->size;
+
+  if (operand->access == CS_AC_READ) {
+
+    asan_loadN(address, size);
+
+  } else if (operand->access == CS_AC_WRITE) {
+
+    asan_storeN(address, size);
+
+  }
+
+}
+
 void asan_instrument(const cs_insn *instr, GumStalkerIterator *iterator) {
 
-  UNUSED_PARAMETER(instr);
   UNUSED_PARAMETER(iterator);
-  if (asan_initialized) {
 
-    FATAL("ASAN mode not supported on this architecture");
+  cs_x86      x86 = instr->detail->x86;
+  cs_x86_op * operand;
+  x86_op_mem *mem;
+  cs_x86_op * ctx;
+
+  if (!asan_initialized) return;
+
+  if (instr->id == X86_INS_LEA) return;
+
+  if (instr->id == X86_INS_NOP) return;
+
+  for (uint8_t i = 0; i < x86.op_count; i++) {
+
+    operand = &x86.operands[i];
+
+    if (operand->type != X86_OP_MEM) { continue; }
+
+    mem = &operand->mem;
+    if (mem->segment != X86_REG_INVALID) { continue; }
+
+    ctx = g_malloc0(sizeof(cs_x86_op));
+    memcpy(ctx, operand, sizeof(cs_x86_op));
+    gum_stalker_iterator_put_callout(iterator, asan_callout, ctx, g_free);
+
+  }
+
+}
+
+void asan_arch_init(void) {
+
+  asan_loadN = (asan_loadN_t)dlsym(RTLD_DEFAULT, "__asan_loadN");
+  asan_storeN = (asan_loadN_t)dlsym(RTLD_DEFAULT, "__asan_storeN");
+  if (asan_loadN == NULL || asan_storeN == NULL) {
+
+    FATAL("Frida ASAN failed to find '__asan_loadN' or '__asan_storeN'");
 
   }