aboutsummaryrefslogtreecommitdiff
path: root/frida_mode/src
diff options
context:
space:
mode:
authorWorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>2021-05-17 19:02:45 +0100
committerGitHub <noreply@github.com>2021-05-17 20:02:45 +0200
commite40c0c2da16f14dfddb5641f6f825903879534a9 (patch)
tree363135f288fd63253471a0455ebadd24a512a1ce /frida_mode/src
parent9d50ae7468970412177c9e08edf7f32ff9fdf1ce (diff)
downloadafl++-e40c0c2da16f14dfddb5641f6f825903879534a9.tar.gz
FASAN Support (#918)
* FASAN Support * Fix handling of Address Sanitizer DSO * Changes to identification of Address Sanitizer DSO Co-authored-by: Your Name <you@example.com>
Diffstat (limited to 'frida_mode/src')
-rw-r--r--frida_mode/src/asan/asan.c24
-rw-r--r--frida_mode/src/asan/asan_arm.c22
-rw-r--r--frida_mode/src/asan/asan_arm64.c22
-rw-r--r--frida_mode/src/asan/asan_x64.c93
-rw-r--r--frida_mode/src/asan/asan_x86.c22
-rw-r--r--frida_mode/src/cmplog/cmplog_x64.c119
-rw-r--r--frida_mode/src/ctx/ctx_x64.c114
-rw-r--r--frida_mode/src/instrument/instrument.c3
8 files changed, 308 insertions, 111 deletions
diff --git a/frida_mode/src/asan/asan.c b/frida_mode/src/asan/asan.c
new file mode 100644
index 00000000..f78f690c
--- /dev/null
+++ b/frida_mode/src/asan/asan.c
@@ -0,0 +1,24 @@
+#include "frida-gum.h"
+
+#include "debug.h"
+
+#include "asan.h"
+
+gboolean asan_initialized = FALSE;
+
+void asan_init(void) {
+
+ if (getenv("AFL_USE_FASAN") != NULL) {
+
+ OKF("Frida ASAN mode enabled");
+ asan_arch_init();
+ asan_initialized = TRUE;
+
+ } else {
+
+ OKF("Frida ASAN mode disabled");
+
+ }
+
+}
+
diff --git a/frida_mode/src/asan/asan_arm.c b/frida_mode/src/asan/asan_arm.c
new file mode 100644
index 00000000..526017be
--- /dev/null
+++ b/frida_mode/src/asan/asan_arm.c
@@ -0,0 +1,22 @@
+#include "frida-gum.h"
+
+#include "debug.h"
+
+#include "asan.h"
+#include "util.h"
+
+#if defined(__arm__)
+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");
+
+ }
+
+}
+
+#endif
+
diff --git a/frida_mode/src/asan/asan_arm64.c b/frida_mode/src/asan/asan_arm64.c
new file mode 100644
index 00000000..4e3fbafd
--- /dev/null
+++ b/frida_mode/src/asan/asan_arm64.c
@@ -0,0 +1,22 @@
+#include "frida-gum.h"
+
+#include "debug.h"
+
+#include "asan.h"
+#include "util.h"
+
+#if defined(__aarch64__)
+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");
+
+ }
+
+}
+
+#endif
+
diff --git a/frida_mode/src/asan/asan_x64.c b/frida_mode/src/asan/asan_x64.c
new file mode 100644
index 00000000..bdf4ac30
--- /dev/null
+++ b/frida_mode/src/asan/asan_x64.c
@@ -0,0 +1,93 @@
+#include <dlfcn.h>
+#include "frida-gum.h"
+
+#include "debug.h"
+
+#include "asan.h"
+#include "ctx.h"
+#include "util.h"
+
+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;
+ 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(iterator);
+
+ 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'");
+
+ }
+
+}
+
+#endif
+
diff --git a/frida_mode/src/asan/asan_x86.c b/frida_mode/src/asan/asan_x86.c
new file mode 100644
index 00000000..b946b3bf
--- /dev/null
+++ b/frida_mode/src/asan/asan_x86.c
@@ -0,0 +1,22 @@
+#include "frida-gum.h"
+
+#include "debug.h"
+
+#include "asan.h"
+#include "util.h"
+
+#if defined(__i386__)
+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");
+
+ }
+
+}
+
+#endif
+
diff --git a/frida_mode/src/cmplog/cmplog_x64.c b/frida_mode/src/cmplog/cmplog_x64.c
index 4d8f243a..c3621a29 100644
--- a/frida_mode/src/cmplog/cmplog_x64.c
+++ b/frida_mode/src/cmplog/cmplog_x64.c
@@ -3,46 +3,12 @@
#include "debug.h"
#include "cmplog.h"
+#include "ctx.h"
#include "frida_cmplog.h"
#include "util.h"
#if defined(__x86_64__)
- #define X86_REG_8L(LABEL, REG) \
- case LABEL: { \
- \
- return REG & GUM_INT8_MASK; \
- \
- }
-
- #define X86_REG_8H(LABEL, REG) \
- case LABEL: { \
- \
- return (REG & GUM_INT16_MASK) >> 8; \
- \
- }
-
- #define X86_REG_16(LABEL, REG) \
- case LABEL: { \
- \
- return (REG & GUM_INT16_MASK); \
- \
- }
-
- #define X86_REG_32(LABEL, REG) \
- case LABEL: { \
- \
- return (REG & GUM_INT32_MASK); \
- \
- }
-
- #define X86_REG_64(LABEL, REG) \
- case LABEL: { \
- \
- return (REG); \
- \
- }
-
typedef struct {
x86_op_type type;
@@ -65,75 +31,6 @@ typedef struct {
} cmplog_pair_ctx_t;
-static guint64 cmplog_read_reg(GumX64CpuContext *ctx, x86_reg reg) {
-
- switch (reg) {
-
- X86_REG_8L(X86_REG_AL, ctx->rax)
- X86_REG_8L(X86_REG_BL, ctx->rbx)
- X86_REG_8L(X86_REG_CL, ctx->rcx)
- X86_REG_8L(X86_REG_DL, ctx->rdx)
- X86_REG_8L(X86_REG_BPL, ctx->rbp)
- X86_REG_8L(X86_REG_SIL, ctx->rsi)
- X86_REG_8L(X86_REG_DIL, ctx->rdi)
-
- X86_REG_8H(X86_REG_AH, ctx->rax)
- X86_REG_8H(X86_REG_BH, ctx->rbx)
- X86_REG_8H(X86_REG_CH, ctx->rcx)
- X86_REG_8H(X86_REG_DH, ctx->rdx)
-
- X86_REG_16(X86_REG_AX, ctx->rax)
- X86_REG_16(X86_REG_BX, ctx->rbx)
- X86_REG_16(X86_REG_CX, ctx->rcx)
- X86_REG_16(X86_REG_DX, ctx->rdx)
- X86_REG_16(X86_REG_DI, ctx->rdi)
- X86_REG_16(X86_REG_SI, ctx->rsi)
- X86_REG_16(X86_REG_BP, ctx->rbp)
-
- X86_REG_32(X86_REG_EAX, ctx->rax)
- X86_REG_32(X86_REG_ECX, ctx->rcx)
- X86_REG_32(X86_REG_EDX, ctx->rdx)
- X86_REG_32(X86_REG_EBX, ctx->rbx)
- X86_REG_32(X86_REG_ESP, ctx->rsp)
- X86_REG_32(X86_REG_EBP, ctx->rbp)
- X86_REG_32(X86_REG_ESI, ctx->rsi)
- X86_REG_32(X86_REG_EDI, ctx->rdi)
- X86_REG_32(X86_REG_R8D, ctx->r8)
- X86_REG_32(X86_REG_R9D, ctx->r9)
- X86_REG_32(X86_REG_R10D, ctx->r10)
- X86_REG_32(X86_REG_R11D, ctx->r11)
- X86_REG_32(X86_REG_R12D, ctx->r12)
- X86_REG_32(X86_REG_R13D, ctx->r13)
- X86_REG_32(X86_REG_R14D, ctx->r14)
- X86_REG_32(X86_REG_R15D, ctx->r15)
- X86_REG_32(X86_REG_EIP, ctx->rip)
-
- X86_REG_64(X86_REG_RAX, ctx->rax)
- X86_REG_64(X86_REG_RCX, ctx->rcx)
- X86_REG_64(X86_REG_RDX, ctx->rdx)
- X86_REG_64(X86_REG_RBX, ctx->rbx)
- X86_REG_64(X86_REG_RSP, ctx->rsp)
- X86_REG_64(X86_REG_RBP, ctx->rbp)
- X86_REG_64(X86_REG_RSI, ctx->rsi)
- X86_REG_64(X86_REG_RDI, ctx->rdi)
- X86_REG_64(X86_REG_R8, ctx->r8)
- X86_REG_64(X86_REG_R9, ctx->r9)
- X86_REG_64(X86_REG_R10, ctx->r10)
- X86_REG_64(X86_REG_R11, ctx->r11)
- X86_REG_64(X86_REG_R12, ctx->r12)
- X86_REG_64(X86_REG_R13, ctx->r13)
- X86_REG_64(X86_REG_R14, ctx->r14)
- X86_REG_64(X86_REG_R15, ctx->r15)
- X86_REG_64(X86_REG_RIP, ctx->rip)
-
- default:
- FATAL("Failed to read register: %d", reg);
- return 0;
-
- }
-
-}
-
static gboolean cmplog_read_mem(GumX64CpuContext *ctx, uint8_t size,
x86_op_mem *mem, guint64 *val) {
@@ -141,9 +38,9 @@ static gboolean cmplog_read_mem(GumX64CpuContext *ctx, uint8_t size,
guint64 index = 0;
guint64 address;
- if (mem->base != X86_REG_INVALID) base = cmplog_read_reg(ctx, mem->base);
+ if (mem->base != X86_REG_INVALID) base = ctx_read_reg(ctx, mem->base);
- if (mem->index != X86_REG_INVALID) index = cmplog_read_reg(ctx, mem->index);
+ if (mem->index != X86_REG_INVALID) index = ctx_read_reg(ctx, mem->index);
address = base + (index * mem->scale) + mem->disp;
@@ -178,7 +75,7 @@ static gboolean cmplog_get_operand_value(GumCpuContext *context,
switch (ctx->type) {
case X86_OP_REG:
- *val = cmplog_read_reg(context, ctx->reg);
+ *val = ctx_read_reg(context, ctx->reg);
return TRUE;
case X86_OP_IMM:
*val = ctx->imm;
@@ -198,9 +95,9 @@ static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
UNUSED_PARAMETER(user_data);
- guint64 address = cmplog_read_reg(context, X86_REG_RIP);
- guint64 rdi = cmplog_read_reg(context, X86_REG_RDI);
- guint64 rsi = cmplog_read_reg(context, X86_REG_RSI);
+ guint64 address = ctx_read_reg(context, X86_REG_RIP);
+ guint64 rdi = ctx_read_reg(context, X86_REG_RDI);
+ guint64 rsi = ctx_read_reg(context, X86_REG_RSI);
if (((G_MAXULONG - rdi) < 32) || ((G_MAXULONG - rsi) < 32)) return;
@@ -275,7 +172,7 @@ static void cmplog_instrument_call(const cs_insn * instr,
static void cmplog_handle_cmp_sub(GumCpuContext *context, guint64 operand1,
guint64 operand2, uint8_t size) {
- guint64 address = cmplog_read_reg(context, X86_REG_RIP);
+ guint64 address = ctx_read_reg(context, X86_REG_RIP);
register uintptr_t k = (uintptr_t)address;
diff --git a/frida_mode/src/ctx/ctx_x64.c b/frida_mode/src/ctx/ctx_x64.c
new file mode 100644
index 00000000..dec759f4
--- /dev/null
+++ b/frida_mode/src/ctx/ctx_x64.c
@@ -0,0 +1,114 @@
+#include "frida-gum.h"
+
+#include "debug.h"
+
+#include "ctx.h"
+
+#if defined(__x86_64__)
+
+ #define X86_REG_8L(LABEL, REG) \
+ case LABEL: { \
+ \
+ return REG & GUM_INT8_MASK; \
+ \
+ }
+
+ #define X86_REG_8H(LABEL, REG) \
+ case LABEL: { \
+ \
+ return (REG & GUM_INT16_MASK) >> 8; \
+ \
+ }
+
+ #define X86_REG_16(LABEL, REG) \
+ case LABEL: { \
+ \
+ return (REG & GUM_INT16_MASK); \
+ \
+ }
+
+ #define X86_REG_32(LABEL, REG) \
+ case LABEL: { \
+ \
+ return (REG & GUM_INT32_MASK); \
+ \
+ }
+
+ #define X86_REG_64(LABEL, REG) \
+ case LABEL: { \
+ \
+ return (REG); \
+ \
+ }
+
+guint64 ctx_read_reg(GumX64CpuContext *ctx, x86_reg reg) {
+
+ switch (reg) {
+
+ X86_REG_8L(X86_REG_AL, ctx->rax)
+ X86_REG_8L(X86_REG_BL, ctx->rbx)
+ X86_REG_8L(X86_REG_CL, ctx->rcx)
+ X86_REG_8L(X86_REG_DL, ctx->rdx)
+ X86_REG_8L(X86_REG_BPL, ctx->rbp)
+ X86_REG_8L(X86_REG_SIL, ctx->rsi)
+ X86_REG_8L(X86_REG_DIL, ctx->rdi)
+
+ X86_REG_8H(X86_REG_AH, ctx->rax)
+ X86_REG_8H(X86_REG_BH, ctx->rbx)
+ X86_REG_8H(X86_REG_CH, ctx->rcx)
+ X86_REG_8H(X86_REG_DH, ctx->rdx)
+
+ X86_REG_16(X86_REG_AX, ctx->rax)
+ X86_REG_16(X86_REG_BX, ctx->rbx)
+ X86_REG_16(X86_REG_CX, ctx->rcx)
+ X86_REG_16(X86_REG_DX, ctx->rdx)
+ X86_REG_16(X86_REG_DI, ctx->rdi)
+ X86_REG_16(X86_REG_SI, ctx->rsi)
+ X86_REG_16(X86_REG_BP, ctx->rbp)
+
+ X86_REG_32(X86_REG_EAX, ctx->rax)
+ X86_REG_32(X86_REG_ECX, ctx->rcx)
+ X86_REG_32(X86_REG_EDX, ctx->rdx)
+ X86_REG_32(X86_REG_EBX, ctx->rbx)
+ X86_REG_32(X86_REG_ESP, ctx->rsp)
+ X86_REG_32(X86_REG_EBP, ctx->rbp)
+ X86_REG_32(X86_REG_ESI, ctx->rsi)
+ X86_REG_32(X86_REG_EDI, ctx->rdi)
+ X86_REG_32(X86_REG_R8D, ctx->r8)
+ X86_REG_32(X86_REG_R9D, ctx->r9)
+ X86_REG_32(X86_REG_R10D, ctx->r10)
+ X86_REG_32(X86_REG_R11D, ctx->r11)
+ X86_REG_32(X86_REG_R12D, ctx->r12)
+ X86_REG_32(X86_REG_R13D, ctx->r13)
+ X86_REG_32(X86_REG_R14D, ctx->r14)
+ X86_REG_32(X86_REG_R15D, ctx->r15)
+ X86_REG_32(X86_REG_EIP, ctx->rip)
+
+ X86_REG_64(X86_REG_RAX, ctx->rax)
+ X86_REG_64(X86_REG_RCX, ctx->rcx)
+ X86_REG_64(X86_REG_RDX, ctx->rdx)
+ X86_REG_64(X86_REG_RBX, ctx->rbx)
+ X86_REG_64(X86_REG_RSP, ctx->rsp)
+ X86_REG_64(X86_REG_RBP, ctx->rbp)
+ X86_REG_64(X86_REG_RSI, ctx->rsi)
+ X86_REG_64(X86_REG_RDI, ctx->rdi)
+ X86_REG_64(X86_REG_R8, ctx->r8)
+ X86_REG_64(X86_REG_R9, ctx->r9)
+ X86_REG_64(X86_REG_R10, ctx->r10)
+ X86_REG_64(X86_REG_R11, ctx->r11)
+ X86_REG_64(X86_REG_R12, ctx->r12)
+ X86_REG_64(X86_REG_R13, ctx->r13)
+ X86_REG_64(X86_REG_R14, ctx->r14)
+ X86_REG_64(X86_REG_R15, ctx->r15)
+ X86_REG_64(X86_REG_RIP, ctx->rip)
+
+ default:
+ FATAL("Failed to read register: %d", reg);
+ return 0;
+
+ }
+
+}
+
+#endif
+
diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c
index 971f80c0..5c77ade6 100644
--- a/frida_mode/src/instrument/instrument.c
+++ b/frida_mode/src/instrument/instrument.c
@@ -5,6 +5,7 @@
#include "config.h"
#include "debug.h"
+#include "asan.h"
#include "entry.h"
#include "frida_cmplog.h"
#include "instrument.h"
@@ -107,6 +108,7 @@ static void instr_basic_block(GumStalkerIterator *iterator,
if (!range_is_excluded((void *)instr->address)) {
+ asan_instrument(instr, iterator);
cmplog_instrument(instr, iterator);
}
@@ -142,6 +144,7 @@ void instrument_init(void) {
transformer =
gum_stalker_transformer_make_from_callback(instr_basic_block, NULL, NULL);
+ asan_init();
cmplog_init();
}