diff options
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.c | 76 |
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'"); + + } } |