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_arm32.c (renamed from frida_mode/src/asan/asan_arm.c)0
-rw-r--r--frida_mode/src/asan/asan_arm64.c76
2 files changed, 72 insertions, 4 deletions
diff --git a/frida_mode/src/asan/asan_arm.c b/frida_mode/src/asan/asan_arm32.c
index 79475ced..79475ced 100644
--- a/frida_mode/src/asan/asan_arm.c
+++ b/frida_mode/src/asan/asan_arm32.c
diff --git a/frida_mode/src/asan/asan_arm64.c b/frida_mode/src/asan/asan_arm64.c
index 6262ee18..66138e42 100644
--- a/frida_mode/src/asan/asan_arm64.c
+++ b/frida_mode/src/asan/asan_arm64.c
@@ -1,18 +1,80 @@
+#include <dlfcn.h>
 #include "frida-gum.h"
 
 #include "debug.h"
 
 #include "asan.h"
+#include "ctx.h"
 #include "util.h"
 
 #if defined(__aarch64__)
+
+typedef struct {
+
+  size_t      size;
+  cs_arm64_op operand;
+
+} asan_ctx_t;
+
+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) {
+
+  asan_ctx_t *  asan_ctx = (asan_ctx_t *)user_data;
+  cs_arm64_op * operand = &asan_ctx->operand;
+  arm64_op_mem *mem = &operand->mem;
+  gsize         base = 0;
+  gsize         index = 0;
+  gsize         address;
+
+  if (mem->base != ARM64_REG_INVALID) { base = ctx_read_reg(ctx, mem->base); }
+
+  if (mem->index != ARM64_REG_INVALID) {
+
+    index = ctx_read_reg(ctx, mem->index);
+
+  }
+
+  address = base + index + mem->disp;
+
+  if ((operand->access & CS_AC_READ) == CS_AC_READ) {
+
+    asan_loadN(address, asan_ctx->size);
+
+  }
+
+  if ((operand->access & CS_AC_WRITE) == CS_AC_WRITE) {
+
+    asan_storeN(address, asan_ctx->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_arm64     arm64 = instr->detail->arm64;
+  cs_arm64_op *operand;
+  asan_ctx_t * ctx;
+
+  if (!asan_initialized) return;
+
+  for (uint8_t i = 0; i < arm64.op_count; i++) {
+
+    operand = &arm64.operands[i];
+
+    if (operand->type != ARM64_OP_MEM) { continue; }
+
+    ctx = g_malloc0(sizeof(asan_ctx_t));
+    ctx->size = ctx_get_size(instr, &arm64.operands[0]);
+    memcpy(&ctx->operand, operand, sizeof(cs_arm64_op));
+    gum_stalker_iterator_put_callout(iterator, asan_callout, ctx, g_free);
 
   }
 
@@ -20,7 +82,13 @@ void asan_instrument(const cs_insn *instr, GumStalkerIterator *iterator) {
 
 void asan_arch_init(void) {
 
-  FATAL("ASAN mode not supported on this architecture");
+  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'");
+
+  }
 
 }