Support for x86 (#920)

Co-authored-by: Your Name <you@example.com>
This commit is contained in:
WorksButNotTested
2021-05-17 20:14:40 +01:00
committed by GitHub
parent e40c0c2da1
commit d0af55e78f
37 changed files with 1176 additions and 102 deletions

View File

@ -19,6 +19,7 @@ RT_CFLAGS:=-Wno-unused-parameter \
-Wno-sign-compare \ -Wno-sign-compare \
-Wno-unused-function \ -Wno-unused-function \
-Wno-unused-result \ -Wno-unused-result \
-Wno-int-to-pointer-cast \
LDFLAGS+=-shared \ LDFLAGS+=-shared \
-lpthread \ -lpthread \
@ -38,6 +39,8 @@ FRIDA_BUILD_DIR:=$(BUILD_DIR)frida/
FRIDA_TRACE:=$(BUILD_DIR)afl-frida-trace.so FRIDA_TRACE:=$(BUILD_DIR)afl-frida-trace.so
FRIDA_TRACE_EMBEDDED:=$(BUILD_DIR)afl-frida-trace-embedded FRIDA_TRACE_EMBEDDED:=$(BUILD_DIR)afl-frida-trace-embedded
ifndef ARCH
ARCH=$(shell uname -m) ARCH=$(shell uname -m)
ifeq "$(ARCH)" "aarch64" ifeq "$(ARCH)" "aarch64"
ARCH:=arm64 ARCH:=arm64
@ -46,6 +49,7 @@ endif
ifeq "$(ARCH)" "i686" ifeq "$(ARCH)" "i686"
ARCH:=x86 ARCH:=x86
endif endif
endif
ifeq "$(shell uname)" "Darwin" ifeq "$(shell uname)" "Darwin"
OS:=macos OS:=macos
@ -83,13 +87,16 @@ FRIDA_GUM_DEVKIT_COMPRESSED_TARBALL:=$(FRIDA_DIR)build/$(GUM_DEVKIT_FILENAME)
AFL_COMPILER_RT_SRC:=$(ROOT)instrumentation/afl-compiler-rt.o.c AFL_COMPILER_RT_SRC:=$(ROOT)instrumentation/afl-compiler-rt.o.c
AFL_COMPILER_RT_OBJ:=$(OBJ_DIR)afl-compiler-rt.o AFL_COMPILER_RT_OBJ:=$(OBJ_DIR)afl-compiler-rt.o
.PHONY: all clean format $(FRIDA_GUM) .PHONY: all 32 clean format $(FRIDA_GUM)
############################## ALL ############################################# ############################## ALL #############################################
all: $(FRIDA_TRACE) all: $(FRIDA_TRACE)
make -C $(ROOT) make -C $(ROOT)
32:
CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all
$(BUILD_DIR): $(BUILD_DIR):
mkdir -p $(BUILD_DIR) mkdir -p $(BUILD_DIR)
@ -161,11 +168,11 @@ $(foreach src,$(SOURCES),$(eval $(call BUILD_SOURCE,$(src),$(OBJ_DIR)$(notdir $(
$(FRIDA_TRACE): $(GUM_DEVIT_LIBRARY) $(GUM_DEVIT_HEADER) $(OBJS) $(AFL_COMPILER_RT_OBJ) GNUmakefile | $(BUILD_DIR) $(FRIDA_TRACE): $(GUM_DEVIT_LIBRARY) $(GUM_DEVIT_HEADER) $(OBJS) $(AFL_COMPILER_RT_OBJ) GNUmakefile | $(BUILD_DIR)
$(CC) \ $(CC) \
-o $@ \
$(OBJS) \ $(OBJS) \
$(GUM_DEVIT_LIBRARY) \ $(GUM_DEVIT_LIBRARY) \
$(AFL_COMPILER_RT_OBJ) \ $(AFL_COMPILER_RT_OBJ) \
$(LDFLAGS) \ $(LDFLAGS) \
-o $@ \
cp -v $(FRIDA_TRACE) $(ROOT) cp -v $(FRIDA_TRACE) $(ROOT)

View File

@ -2,6 +2,10 @@ all:
@echo trying to use GNU make... @echo trying to use GNU make...
@gmake all || echo please install GNUmake @gmake all || echo please install GNUmake
32:
@echo trying to use GNU make...
@gmake 32 || echo please install GNUmake
clean: clean:
@gmake clean @gmake clean

View File

@ -3,8 +3,8 @@
#include "frida-gum.h" #include "frida-gum.h"
#if defined(__x86_64__) #if defined(__x86_64__) || defined(__i386__)
guint64 ctx_read_reg(GumX64CpuContext *ctx, x86_reg reg); gsize ctx_read_reg(GumCpuContext *ctx, x86_reg reg);
#endif #endif
#endif #endif

View File

@ -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 #endif

View File

@ -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 #endif

View File

@ -7,23 +7,23 @@
#include "ctx.h" #include "ctx.h"
#include "util.h" #include "util.h"
#if defined(__x86_64__)
typedef void (*asan_loadN_t)(uint64_t address, uint8_t size); typedef void (*asan_loadN_t)(uint64_t address, uint8_t size);
typedef void (*asan_storeN_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_loadN_t asan_loadN = NULL;
asan_storeN_t asan_storeN = NULL; asan_storeN_t asan_storeN = NULL;
#if defined(__x86_64__)
static void asan_callout(GumCpuContext *ctx, gpointer user_data) { static void asan_callout(GumCpuContext *ctx, gpointer user_data) {
UNUSED_PARAMETER(user_data); UNUSED_PARAMETER(user_data);
cs_x86_op * operand = (cs_x86_op *)user_data; cs_x86_op * operand = (cs_x86_op *)user_data;
x86_op_mem *mem = &operand->mem; x86_op_mem *mem = &operand->mem;
uint64_t base = 0; gsize base = 0;
uint64_t index = 0; gsize index = 0;
uint64_t address; gsize address;
uint8_t size; uint8_t size;
if (mem->base != X86_REG_INVALID) { base = ctx_read_reg(ctx, mem->base); } if (mem->base != X86_REG_INVALID) { base = ctx_read_reg(ctx, mem->base); }

View File

@ -1,18 +1,89 @@
#include <dlfcn.h>
#include "frida-gum.h" #include "frida-gum.h"
#include "debug.h" #include "debug.h"
#include "asan.h" #include "asan.h"
#include "ctx.h"
#include "util.h" #include "util.h"
#if defined(__i386__) #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) { void asan_instrument(const cs_insn *instr, GumStalkerIterator *iterator) {
UNUSED_PARAMETER(instr);
UNUSED_PARAMETER(iterator); 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'");
} }

View File

@ -31,12 +31,12 @@ typedef struct {
} cmplog_pair_ctx_t; } cmplog_pair_ctx_t;
static gboolean cmplog_read_mem(GumX64CpuContext *ctx, uint8_t size, static gboolean cmplog_read_mem(GumCpuContext *ctx, uint8_t size,
x86_op_mem *mem, guint64 *val) { x86_op_mem *mem, gsize *val) {
guint64 base = 0; gsize base = 0;
guint64 index = 0; gsize index = 0;
guint64 address; gsize address;
if (mem->base != X86_REG_INVALID) base = ctx_read_reg(ctx, mem->base); if (mem->base != X86_REG_INVALID) base = ctx_read_reg(ctx, mem->base);
@ -49,16 +49,16 @@ static gboolean cmplog_read_mem(GumX64CpuContext *ctx, uint8_t size,
switch (size) { switch (size) {
case 1: case 1:
*val = *((guint8 *)address); *val = *((guint8 *)GSIZE_TO_POINTER(address));
return TRUE; return TRUE;
case 2: case 2:
*val = *((guint16 *)address); *val = *((guint16 *)GSIZE_TO_POINTER(address));
return TRUE; return TRUE;
case 4: case 4:
*val = *((guint32 *)address); *val = *((guint32 *)GSIZE_TO_POINTER(address));
return TRUE; return TRUE;
case 8: case 8:
*val = *((guint64 *)address); *val = *((guint64 *)GSIZE_TO_POINTER(address));
return TRUE; return TRUE;
default: default:
FATAL("Invalid operand size: %d\n", size); FATAL("Invalid operand size: %d\n", size);
@ -70,7 +70,7 @@ static gboolean cmplog_read_mem(GumX64CpuContext *ctx, uint8_t size,
} }
static gboolean cmplog_get_operand_value(GumCpuContext *context, static gboolean cmplog_get_operand_value(GumCpuContext *context,
cmplog_ctx_t *ctx, guint64 *val) { cmplog_ctx_t *ctx, gsize *val) {
switch (ctx->type) { switch (ctx->type) {
@ -95,9 +95,9 @@ static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
UNUSED_PARAMETER(user_data); UNUSED_PARAMETER(user_data);
guint64 address = ctx_read_reg(context, X86_REG_RIP); gsize address = ctx_read_reg(context, X86_REG_RIP);
guint64 rdi = ctx_read_reg(context, X86_REG_RDI); gsize rdi = ctx_read_reg(context, X86_REG_RDI);
guint64 rsi = ctx_read_reg(context, X86_REG_RSI); gsize rsi = ctx_read_reg(context, X86_REG_RSI);
if (((G_MAXULONG - rdi) < 32) || ((G_MAXULONG - rsi) < 32)) return; if (((G_MAXULONG - rdi) < 32) || ((G_MAXULONG - rsi) < 32)) return;
@ -169,10 +169,10 @@ static void cmplog_instrument_call(const cs_insn * instr,
} }
static void cmplog_handle_cmp_sub(GumCpuContext *context, guint64 operand1, static void cmplog_handle_cmp_sub(GumCpuContext *context, gsize operand1,
guint64 operand2, uint8_t size) { gsize operand2, uint8_t size) {
guint64 address = ctx_read_reg(context, X86_REG_RIP); gsize address = ctx_read_reg(context, X86_REG_RIP);
register uintptr_t k = (uintptr_t)address; register uintptr_t k = (uintptr_t)address;
@ -195,8 +195,8 @@ static void cmplog_handle_cmp_sub(GumCpuContext *context, guint64 operand1,
static void cmplog_cmp_sub_callout(GumCpuContext *context, gpointer user_data) { static void cmplog_cmp_sub_callout(GumCpuContext *context, gpointer user_data) {
cmplog_pair_ctx_t *ctx = (cmplog_pair_ctx_t *)user_data; cmplog_pair_ctx_t *ctx = (cmplog_pair_ctx_t *)user_data;
guint64 operand1; gsize operand1;
guint64 operand2; gsize operand2;
if (ctx->operand1.size != ctx->operand2.size) FATAL("Operand size mismatch"); if (ctx->operand1.size != ctx->operand2.size) FATAL("Operand size mismatch");

View File

@ -1,17 +1,275 @@
#include "frida-gum.h" #include "frida-gum.h"
#include "debug.h" #include "debug.h"
#include "cmplog.h"
#include "ctx.h"
#include "frida_cmplog.h" #include "frida_cmplog.h"
#include "util.h" #include "util.h"
#if defined(__i386__) #if defined(__i386__)
typedef struct {
x86_op_type type;
uint8_t size;
union {
x86_op_mem mem;
x86_reg reg;
int64_t imm;
};
} cmplog_ctx_t;
typedef struct {
cmplog_ctx_t operand1;
cmplog_ctx_t operand2;
} cmplog_pair_ctx_t;
static gboolean cmplog_read_mem(GumCpuContext *ctx, uint8_t size,
x86_op_mem *mem, gsize *val) {
gsize base = 0;
gsize index = 0;
gsize address;
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 + (index * mem->scale) + mem->disp;
if (!cmplog_is_readable(address, size)) { return FALSE; }
switch (size) {
case 1:
*val = *((guint8 *)GSIZE_TO_POINTER(address));
return TRUE;
case 2:
*val = *((guint16 *)GSIZE_TO_POINTER(address));
return TRUE;
case 4:
*val = *((guint32 *)GSIZE_TO_POINTER(address));
return TRUE;
default:
FATAL("Invalid operand size: %d\n", size);
}
return FALSE;
}
static gboolean cmplog_get_operand_value(GumCpuContext *context,
cmplog_ctx_t *ctx, gsize *val) {
switch (ctx->type) {
case X86_OP_REG:
*val = ctx_read_reg(context, ctx->reg);
return TRUE;
case X86_OP_IMM:
*val = ctx->imm;
return TRUE;
case X86_OP_MEM:
return cmplog_read_mem(context, ctx->size, &ctx->mem, val);
default:
FATAL("Invalid operand type: %d\n", ctx->type);
}
return FALSE;
}
static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
UNUSED_PARAMETER(user_data);
gsize address = ctx_read_reg(context, X86_REG_EIP);
gsize *esp = (gsize *)ctx_read_reg(context, X86_REG_ESP);
if (!cmplog_is_readable(GPOINTER_TO_SIZE(esp), 12)) return;
/*
* This callout is place immediately before the call instruction, and hence
* the return address is not yet pushed on the top of the stack.
*/
gsize arg1 = esp[0];
gsize arg2 = esp[1];
if (((G_MAXULONG - arg1) < 32) || ((G_MAXULONG - arg2) < 32)) return;
if (!cmplog_is_readable(arg1, 32) || !cmplog_is_readable(arg2, 32)) return;
void *ptr1 = GSIZE_TO_POINTER(arg1);
void *ptr2 = GSIZE_TO_POINTER(arg2);
uintptr_t k = address;
k = (k >> 4) ^ (k << 8);
k &= CMP_MAP_W - 1;
__afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
u32 hits = __afl_cmp_map->headers[k].hits;
__afl_cmp_map->headers[k].hits = hits + 1;
__afl_cmp_map->headers[k].shape = 31;
hits &= CMP_MAP_RTN_H - 1;
gum_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0, ptr1,
32);
gum_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1, ptr2,
32);
}
static void cmplog_instrument_put_operand(cmplog_ctx_t *ctx,
cs_x86_op * operand) {
ctx->type = operand->type;
ctx->size = operand->size;
switch (operand->type) {
case X86_OP_REG:
gum_memcpy(&ctx->reg, &operand->reg, sizeof(x86_reg));
break;
case X86_OP_IMM:
gum_memcpy(&ctx->imm, &operand->imm, sizeof(int64_t));
break;
case X86_OP_MEM:
gum_memcpy(&ctx->mem, &operand->mem, sizeof(x86_op_mem));
break;
default:
FATAL("Invalid operand type: %d\n", operand->type);
}
}
static void cmplog_instrument_call(const cs_insn * instr,
GumStalkerIterator *iterator) {
cs_x86 x86 = instr->detail->x86;
cs_x86_op *operand;
if (instr->id != X86_INS_CALL) return;
if (x86.op_count != 1) return;
operand = &x86.operands[0];
if (operand->type == X86_OP_INVALID) return;
if (operand->type == X86_OP_MEM && operand->mem.segment != X86_REG_INVALID)
return;
gum_stalker_iterator_put_callout(iterator, cmplog_call_callout, NULL, NULL);
}
static void cmplog_handle_cmp_sub(GumCpuContext *context, gsize operand1,
gsize operand2, uint8_t size) {
gsize address = ctx_read_reg(context, X86_REG_EIP);
register uintptr_t k = (uintptr_t)address;
k = (k >> 4) ^ (k << 8);
k &= CMP_MAP_W - 1;
__afl_cmp_map->headers[k].type = CMP_TYPE_INS;
u32 hits = __afl_cmp_map->headers[k].hits;
__afl_cmp_map->headers[k].hits = hits + 1;
__afl_cmp_map->headers[k].shape = (size - 1);
hits &= CMP_MAP_H - 1;
__afl_cmp_map->log[k][hits].v0 = operand1;
__afl_cmp_map->log[k][hits].v1 = operand2;
}
static void cmplog_cmp_sub_callout(GumCpuContext *context, gpointer user_data) {
cmplog_pair_ctx_t *ctx = (cmplog_pair_ctx_t *)user_data;
gsize operand1;
gsize operand2;
if (ctx->operand1.size != ctx->operand2.size) FATAL("Operand size mismatch");
if (!cmplog_get_operand_value(context, &ctx->operand1, &operand1)) { return; }
if (!cmplog_get_operand_value(context, &ctx->operand2, &operand2)) { return; }
cmplog_handle_cmp_sub(context, operand1, operand2, ctx->operand1.size);
}
static void cmplog_instrument_cmp_sub_put_callout(GumStalkerIterator *iterator,
cs_x86_op * operand1,
cs_x86_op *operand2) {
cmplog_pair_ctx_t *ctx = g_malloc(sizeof(cmplog_pair_ctx_t));
if (ctx == NULL) return;
cmplog_instrument_put_operand(&ctx->operand1, operand1);
cmplog_instrument_put_operand(&ctx->operand2, operand2);
gum_stalker_iterator_put_callout(iterator, cmplog_cmp_sub_callout, ctx,
g_free);
}
static void cmplog_instrument_cmp_sub(const cs_insn * instr,
GumStalkerIterator *iterator) {
cs_x86 x86 = instr->detail->x86;
cs_x86_op *operand1;
cs_x86_op *operand2;
switch (instr->id) {
case X86_INS_CMP:
case X86_INS_SUB:
break;
default:
return;
}
if (x86.op_count != 2) return;
operand1 = &x86.operands[0];
operand2 = &x86.operands[1];
if (operand1->type == X86_OP_INVALID) return;
if (operand2->type == X86_OP_INVALID) return;
if ((operand1->type == X86_OP_MEM) &&
(operand1->mem.segment != X86_REG_INVALID))
return;
if ((operand2->type == X86_OP_MEM) &&
(operand2->mem.segment != X86_REG_INVALID))
return;
cmplog_instrument_cmp_sub_put_callout(iterator, operand1, operand2);
}
void cmplog_instrument(const cs_insn *instr, GumStalkerIterator *iterator) { void cmplog_instrument(const cs_insn *instr, GumStalkerIterator *iterator) {
UNUSED_PARAMETER(instr); if (__afl_cmp_map == NULL) return;
UNUSED_PARAMETER(iterator);
if (__afl_cmp_map == NULL) { return; } cmplog_instrument_call(instr, iterator);
FATAL("CMPLOG mode not supported on this architecture"); cmplog_instrument_cmp_sub(instr, iterator);
} }

View File

@ -41,7 +41,7 @@
\ \
} }
guint64 ctx_read_reg(GumX64CpuContext *ctx, x86_reg reg) { gsize ctx_read_reg(GumX64CpuContext *ctx, x86_reg reg) {
switch (reg) { switch (reg) {

View File

@ -0,0 +1,81 @@
#include "frida-gum.h"
#include "debug.h"
#include "ctx.h"
#if defined(__i386__)
#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); \
\
}
gsize ctx_read_reg(GumIA32CpuContext *ctx, x86_reg reg) {
switch (reg) {
X86_REG_8L(X86_REG_AL, ctx->eax)
X86_REG_8L(X86_REG_BL, ctx->ebx)
X86_REG_8L(X86_REG_CL, ctx->ecx)
X86_REG_8L(X86_REG_DL, ctx->edx)
X86_REG_8L(X86_REG_BPL, ctx->ebp)
X86_REG_8L(X86_REG_SIL, ctx->esi)
X86_REG_8L(X86_REG_DIL, ctx->edi)
X86_REG_8H(X86_REG_AH, ctx->eax)
X86_REG_8H(X86_REG_BH, ctx->ebx)
X86_REG_8H(X86_REG_CH, ctx->ecx)
X86_REG_8H(X86_REG_DH, ctx->edx)
X86_REG_16(X86_REG_AX, ctx->eax)
X86_REG_16(X86_REG_BX, ctx->ebx)
X86_REG_16(X86_REG_CX, ctx->ecx)
X86_REG_16(X86_REG_DX, ctx->edx)
X86_REG_16(X86_REG_DI, ctx->edi)
X86_REG_16(X86_REG_SI, ctx->esi)
X86_REG_16(X86_REG_BP, ctx->ebp)
X86_REG_32(X86_REG_EAX, ctx->eax)
X86_REG_32(X86_REG_ECX, ctx->ecx)
X86_REG_32(X86_REG_EDX, ctx->edx)
X86_REG_32(X86_REG_EBX, ctx->ebx)
X86_REG_32(X86_REG_ESP, ctx->esp)
X86_REG_32(X86_REG_EBP, ctx->ebp)
X86_REG_32(X86_REG_ESI, ctx->esi)
X86_REG_32(X86_REG_EDI, ctx->edi)
X86_REG_32(X86_REG_EIP, ctx->eip)
default:
FATAL("Failed to read register: %d", reg);
return 0;
}
}
#endif

View File

@ -34,7 +34,7 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context,
*/ */
static char buffer[200]; static char buffer[200];
int len; int len;
guint64 current_pc = (guint64)user_data; GumAddress current_pc = GUM_ADDRESS(user_data);
uint8_t * cursor; uint8_t * cursor;
uint64_t value; uint64_t value;
if (unlikely(tracing)) { if (unlikely(tracing)) {
@ -86,8 +86,8 @@ static void instr_basic_block(GumStalkerIterator *iterator,
if (begin) { if (begin) {
prefetch_write((void *)instr->address); prefetch_write(GSIZE_TO_POINTER(instr->address));
if (!range_is_excluded((void *)instr->address)) { if (!range_is_excluded(GSIZE_TO_POINTER(instr->address))) {
if (optimize) { if (optimize) {
@ -95,8 +95,8 @@ static void instr_basic_block(GumStalkerIterator *iterator,
} else { } else {
gum_stalker_iterator_put_callout(iterator, on_basic_block, gum_stalker_iterator_put_callout(
(gpointer)instr->address, NULL); iterator, on_basic_block, GSIZE_TO_POINTER(instr->address), NULL);
} }
@ -106,7 +106,7 @@ static void instr_basic_block(GumStalkerIterator *iterator,
} }
if (!range_is_excluded((void *)instr->address)) { if (!range_is_excluded(GSIZE_TO_POINTER(instr->address))) {
asan_instrument(instr, iterator); asan_instrument(instr, iterator);
cmplog_instrument(instr, iterator); cmplog_instrument(instr, iterator);

View File

@ -3,6 +3,7 @@
#include "debug.h" #include "debug.h"
#include "instrument.h" #include "instrument.h"
#include "util.h"
#if defined(__arm__) #if defined(__arm__)
@ -15,6 +16,8 @@ gboolean instrument_is_coverage_optimize_supported(void) {
void instrument_coverage_optimize(const cs_insn * instr, void instrument_coverage_optimize(const cs_insn * instr,
GumStalkerOutput *output) { GumStalkerOutput *output) {
UNUSED_PARAMETER(instr);
UNUSED_PARAMETER(output);
FATAL("Optimized coverage not supported on this architecture"); FATAL("Optimized coverage not supported on this architecture");
} }

View File

@ -3,19 +3,81 @@
#include "debug.h" #include "debug.h"
#include "instrument.h" #include "instrument.h"
#include "util.h"
#if defined(__i386__) #if defined(__i386__)
static GumAddress current_log_impl = GUM_ADDRESS(0);
static void instrument_coverage_function(GumX86Writer *cw) {
gum_x86_writer_put_pushfx(cw);
gum_x86_writer_put_push_reg(cw, GUM_REG_ECX);
gum_x86_writer_put_push_reg(cw, GUM_REG_EDX);
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_ECX,
GUM_ADDRESS(&previous_pc));
gum_x86_writer_put_mov_reg_reg_ptr(cw, GUM_REG_EDX, GUM_REG_ECX);
gum_x86_writer_put_xor_reg_reg(cw, GUM_REG_EDX, GUM_REG_EDI);
gum_x86_writer_put_add_reg_imm(cw, GUM_REG_EDX, GUM_ADDRESS(__afl_area_ptr));
/* add byte ptr [edx], 1 */
uint8_t add_byte_ptr_edx_1[] = {0x80, 0x02, 0x01};
gum_x86_writer_put_bytes(cw, add_byte_ptr_edx_1, sizeof(add_byte_ptr_edx_1));
/* adc byte ptr [edx], 0 */
uint8_t adc_byte_ptr_edx_0[] = {0x80, 0x12, 0x00};
gum_x86_writer_put_bytes(cw, adc_byte_ptr_edx_0, sizeof(adc_byte_ptr_edx_0));
gum_x86_writer_put_shr_reg_u8(cw, GUM_REG_EDI, 1);
gum_x86_writer_put_mov_reg_ptr_reg(cw, GUM_REG_ECX, GUM_REG_EDI);
gum_x86_writer_put_pop_reg(cw, GUM_REG_EDX);
gum_x86_writer_put_pop_reg(cw, GUM_REG_ECX);
gum_x86_writer_put_popfx(cw);
gum_x86_writer_put_ret(cw);
}
gboolean instrument_is_coverage_optimize_supported(void) { gboolean instrument_is_coverage_optimize_supported(void) {
return false; return true;
} }
void instrument_coverage_optimize(const cs_insn * instr, void instrument_coverage_optimize(const cs_insn * instr,
GumStalkerOutput *output) { GumStalkerOutput *output) {
FATAL("Optimized coverage not supported on this architecture"); UNUSED_PARAMETER(instr);
UNUSED_PARAMETER(output);
guint64 current_pc = instr->address;
guint64 area_offset = (current_pc >> 4) ^ (current_pc << 8);
area_offset &= MAP_SIZE - 1;
GumX86Writer *cw = output->writer.x86;
if (current_log_impl == 0 ||
!gum_x86_writer_can_branch_directly_between(cw->pc, current_log_impl) ||
!gum_x86_writer_can_branch_directly_between(cw->pc + 128,
current_log_impl)) {
gconstpointer after_log_impl = cw->code + 1;
gum_x86_writer_put_jmp_near_label(cw, after_log_impl);
current_log_impl = cw->pc;
instrument_coverage_function(cw);
gum_x86_writer_put_label(cw, after_log_impl);
}
// gum_x86_writer_put_breakpoint(cw);
gum_x86_writer_put_push_reg(cw, GUM_REG_EDI);
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EDI, area_offset);
gum_x86_writer_put_call_address(cw, current_log_impl);
gum_x86_writer_put_pop_reg(cw, GUM_REG_EDI);
} }

View File

@ -90,7 +90,8 @@ static void lib_read_text_section(lib_details_t *lib_details, Elf_Ehdr *hdr) {
if (!found_preferred_base) { FATAL("Failed to find preferred load address"); } if (!found_preferred_base) { FATAL("Failed to find preferred load address"); }
OKF("Image preferred load address 0x%016lx", preferred_base); OKF("Image preferred load address 0x%016" G_GSIZE_MODIFIER "x",
preferred_base);
shdr = (Elf_Shdr *)((char *)hdr + hdr->e_shoff); shdr = (Elf_Shdr *)((char *)hdr + hdr->e_shoff);
shstrtab = &shdr[hdr->e_shstrndx]; shstrtab = &shdr[hdr->e_shstrndx];
@ -107,15 +108,16 @@ static void lib_read_text_section(lib_details_t *lib_details, Elf_Ehdr *hdr) {
if (curr->sh_name == 0) continue; if (curr->sh_name == 0) continue;
section_name = &shstr[curr->sh_name]; section_name = &shstr[curr->sh_name];
OKF("Section: %2lu - base: 0x%016lX size: 0x%016lX %s", i, curr->sh_addr, OKF("Section: %2" G_GSIZE_MODIFIER "u - base: 0x%016" G_GSIZE_MODIFIER
curr->sh_size, section_name); "X size: 0x%016" G_GSIZE_MODIFIER "X %s",
i, curr->sh_addr, curr->sh_size, section_name);
if (memcmp(section_name, text_name, sizeof(text_name)) == 0 && if (memcmp(section_name, text_name, sizeof(text_name)) == 0 &&
text_base == 0) { text_base == 0) {
text_base = lib_details->base_address + curr->sh_addr - preferred_base; text_base = lib_details->base_address + curr->sh_addr - preferred_base;
text_limit = text_base + curr->sh_size; text_limit = text_base + curr->sh_size;
OKF("> text_addr: 0x%016lX", text_base); OKF("> text_addr: 0x%016" G_GINT64_MODIFIER "X", text_base);
OKF("> text_limit: 0x%016lX", text_limit); OKF("> text_limit: 0x%016" G_GINT64_MODIFIER "X", text_limit);
} }
@ -153,7 +155,8 @@ void lib_init(void) {
lib_details_t lib_details; lib_details_t lib_details;
gum_process_enumerate_modules(lib_find_exe, &lib_details); gum_process_enumerate_modules(lib_find_exe, &lib_details);
OKF("Executable: 0x%016lx - %s", lib_details.base_address, lib_details.path); OKF("Executable: 0x%016" G_GINT64_MODIFIER "x - %s", lib_details.base_address,
lib_details.path);
lib_get_text_section(&lib_details); lib_get_text_section(&lib_details);
} }

View File

@ -1,9 +1,9 @@
#include "frida-gum.h" #include "frida-gum.h"
#include "debug.h" #include "config.h"
#include "instrument.h"
#include "persistent.h" #include "persistent.h"
#include "util.h"
#if defined(__i386__) #if defined(__i386__)
@ -38,16 +38,239 @@ struct x86_regs {
typedef struct x86_regs arch_api_regs; typedef struct x86_regs arch_api_regs;
static arch_api_regs saved_regs = {0};
static void * saved_return = NULL;
gboolean persistent_is_supported(void) { gboolean persistent_is_supported(void) {
return false; return true;
}
static void instrument_persitent_save_regs(GumX86Writer * cw,
struct x86_regs *regs) {
GumAddress regs_address = GUM_ADDRESS(regs);
/* Should be pushing FPU here, but meh */
gum_x86_writer_put_pushfx(cw);
gum_x86_writer_put_push_reg(cw, GUM_REG_EAX);
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EAX, regs_address);
gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 1),
GUM_REG_EBX);
gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 2),
GUM_REG_ECX);
gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 3),
GUM_REG_EDX);
gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 4),
GUM_REG_EDI);
gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 5),
GUM_REG_ESI);
gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 6),
GUM_REG_EBP);
/* Store RIP */
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EBX,
GUM_ADDRESS(persistent_start));
gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 7),
GUM_REG_EBX);
/* Store adjusted RSP */
gum_x86_writer_put_mov_reg_reg(cw, GUM_REG_EBX, GUM_REG_ESP);
/* RED_ZONE + Saved flags, RAX */
gum_x86_writer_put_add_reg_imm(cw, GUM_REG_EBX, (0x4 * 2));
gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 8),
GUM_REG_EBX);
/* Save the flags */
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_ESP, 0x4);
gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 9),
GUM_REG_EBX);
/* Save the RAX */
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_ESP, 0x0);
gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 0),
GUM_REG_EBX);
/* Pop the saved values */
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_ESP, GUM_REG_ESP, 0x8);
}
static void instrument_persitent_restore_regs(GumX86Writer * cw,
struct x86_regs *regs) {
GumAddress regs_address = GUM_ADDRESS(regs);
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EAX, regs_address);
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ECX, GUM_REG_EAX,
(0x4 * 2));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EDX, GUM_REG_EAX,
(0x4 * 3));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EDI, GUM_REG_EAX,
(0x4 * 4));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ESI, GUM_REG_EAX,
(0x4 * 5));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBP, GUM_REG_EAX,
(0x4 * 6));
/* Don't restore RIP or RSP */
/* Restore RBX, RAX & Flags */
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_EAX,
(0x4 * 1));
gum_x86_writer_put_push_reg(cw, GUM_REG_EBX);
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_EAX,
(0x4 * 0));
gum_x86_writer_put_push_reg(cw, GUM_REG_EBX);
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_EAX,
(0x4 * 9));
gum_x86_writer_put_push_reg(cw, GUM_REG_EBX);
gum_x86_writer_put_popfx(cw);
gum_x86_writer_put_pop_reg(cw, GUM_REG_EAX);
gum_x86_writer_put_pop_reg(cw, GUM_REG_EBX);
}
static void instrument_save_ret(GumX86Writer *cw, void **saved_return_ptr) {
GumAddress saved_return_address = GUM_ADDRESS(saved_return_ptr);
gum_x86_writer_put_push_reg(cw, GUM_REG_EAX);
gum_x86_writer_put_push_reg(cw, GUM_REG_EBX);
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EAX, saved_return_address);
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_ESP, 0x8);
gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, 0, GUM_REG_EBX);
gum_x86_writer_put_pop_reg(cw, GUM_REG_EBX);
gum_x86_writer_put_pop_reg(cw, GUM_REG_EAX);
}
static void instrument_jump_ret(GumX86Writer *cw, void **saved_return_ptr) {
GumAddress saved_return_address = GUM_ADDRESS(saved_return_ptr);
/* Place holder for ret */
gum_x86_writer_put_push_reg(cw, GUM_REG_EAX);
gum_x86_writer_put_push_reg(cw, GUM_REG_EAX);
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EAX, saved_return_address);
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EAX, GUM_REG_EAX, 0);
gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_ESP, 0x4, GUM_REG_EAX);
gum_x86_writer_put_pop_reg(cw, GUM_REG_EAX);
gum_x86_writer_put_ret(cw);
}
static int instrument_afl_persistent_loop_func(void) {
int ret = __afl_persistent_loop(persistent_count);
previous_pc = 0;
return ret;
}
static void instrument_afl_persistent_loop(GumX86Writer *cw) {
gum_x86_writer_put_call_address_with_arguments(
cw, GUM_CALL_CAPI, GUM_ADDRESS(instrument_afl_persistent_loop_func), 0);
gum_x86_writer_put_test_reg_reg(cw, GUM_REG_EAX, GUM_REG_EAX);
}
static void persistent_prologue_hook(GumX86Writer *cw, struct x86_regs *regs) {
if (hook == NULL) return;
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_ECX,
GUM_ADDRESS(&__afl_fuzz_len));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ECX, GUM_REG_ECX, 0);
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ECX, GUM_REG_ECX, 0);
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EDX,
GUM_ADDRESS(&__afl_fuzz_ptr));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EDX, GUM_REG_EDX, 0);
/* Base address is 64-bits (hence two zero arguments) */
gum_x86_writer_put_call_address_with_arguments(
cw, GUM_CALL_CAPI, GUM_ADDRESS(hook), 5, GUM_ARG_ADDRESS,
GUM_ADDRESS(regs), GUM_ARG_ADDRESS, GUM_ADDRESS(0), GUM_ARG_ADDRESS,
GUM_ADDRESS(0), GUM_ARG_REGISTER, GUM_REG_EDX, GUM_ARG_REGISTER,
GUM_REG_ECX);
} }
void persistent_prologue(GumStalkerOutput *output) { void persistent_prologue(GumStalkerOutput *output) {
UNUSED_PARAMETER(output); /*
FATAL("Persistent mode not supported on this architecture"); * SAVE REGS
* SAVE RET
* POP RET
* loop:
* CALL instrument_afl_persistent_loop
* TEST EAX, EAX
* JZ end:
* call hook (optionally)
* RESTORE REGS
* call original
* jmp loop:
*
* end:
* JMP SAVED RET
*
* original:
* INSTRUMENTED PERSISTENT FUNC
*/
GumX86Writer *cw = output->writer.x86;
gconstpointer loop = cw->code + 1;
/* Stack must be 16-byte aligned per ABI */
instrument_persitent_save_regs(cw, &saved_regs);
/* Stash and pop the return value */
instrument_save_ret(cw, &saved_return);
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_ESP, GUM_REG_ESP, (4));
/* loop: */
gum_x86_writer_put_label(cw, loop);
/* call instrument_prologue_func */
instrument_afl_persistent_loop(cw);
/* jz done */
gconstpointer done = cw->code + 1;
gum_x86_writer_put_jcc_near_label(cw, X86_INS_JE, done, GUM_UNLIKELY);
/* Optionally call the persistent hook */
persistent_prologue_hook(cw, &saved_regs);
instrument_persitent_restore_regs(cw, &saved_regs);
gconstpointer original = cw->code + 1;
/* call original */
gum_x86_writer_put_call_near_label(cw, original);
/* jmp loop */
gum_x86_writer_put_jmp_near_label(cw, loop);
/* done: */
gum_x86_writer_put_label(cw, done);
instrument_jump_ret(cw, &saved_return);
/* original: */
gum_x86_writer_put_label(cw, original);
gum_x86_writer_flush(cw);
} }

View File

@ -2,8 +2,8 @@ PWD:=$(shell pwd)/
ROOT:=$(shell realpath $(PWD)../../../)/ ROOT:=$(shell realpath $(PWD)../../../)/
BUILD_DIR:=$(PWD)build/ BUILD_DIR:=$(PWD)build/
TEST_CMPLOG_DIR:=$(ROOT)qemu_mode/libcompcov/ TEST_CMPLOG_SRC=$(PWD)cmplog.c
TEST_CMPLOG_OBJ=$(TEST_CMPLOG_DIR)compcovtest TEST_CMPLOG_OBJ=$(BUILD_DIR)compcovtest
TEST_BIN:=$(PWD)../../build/test TEST_BIN:=$(PWD)../../build/test
@ -13,20 +13,14 @@ CMP_LOG_INPUT:=$(TEST_DATA_DIR)in
QEMU_OUT:=$(BUILD_DIR)qemu-out QEMU_OUT:=$(BUILD_DIR)qemu-out
FRIDA_OUT:=$(BUILD_DIR)frida-out FRIDA_OUT:=$(BUILD_DIR)frida-out
ARCH=$(shell uname -m) .PHONY: all 32 clean qemu frida format
ifeq "$(ARCH)" "aarch64"
AFL_FRIDA_INST_RANGES=$(shell $(PWD)get_section_addrs.py -f $(TEST_CMPLOG_OBJ) -s .text -b 0x0000aaaaaaaaa000)
endif
ifeq "$(ARCH)" "x86_64" all: $(TEST_CMPLOG_OBJ)
AFL_FRIDA_INST_RANGES=$(shell $(PWD)get_section_addrs.py -f $(TEST_CMPLOG_OBJ) -s .text -b 0x0000555555554000)
endif
.PHONY: all clean qemu frida
all:
make -C $(ROOT)frida_mode/ make -C $(ROOT)frida_mode/
32:
CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all
$(BUILD_DIR): $(BUILD_DIR):
mkdir -p $@ mkdir -p $@
@ -34,10 +28,10 @@ $(TEST_DATA_DIR): | $(BUILD_DIR)
mkdir -p $@ mkdir -p $@
$(CMP_LOG_INPUT): | $(TEST_DATA_DIR) $(CMP_LOG_INPUT): | $(TEST_DATA_DIR)
truncate -s 64 $@ echo -n "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" > $@
$(TEST_CMPLOG_OBJ): $(TEST_CMPLOG_DIR)compcovtest.cc $(TEST_CMPLOG_OBJ): $(TEST_CMPLOG_SRC) | $(BUILD_DIR)
make -C $(TEST_CMPLOG_DIR) compcovtest $(CXX) -std=c++11 -g $(CFLAGS) $(LDFLAGS) $< -o $@
qemu: $(TEST_CMPLOG_OBJ) $(CMP_LOG_INPUT) qemu: $(TEST_CMPLOG_OBJ) $(CMP_LOG_INPUT)
$(ROOT)afl-fuzz \ $(ROOT)afl-fuzz \
@ -51,7 +45,6 @@ qemu: $(TEST_CMPLOG_OBJ) $(CMP_LOG_INPUT)
$(TEST_CMPLOG_OBJ) @@ $(TEST_CMPLOG_OBJ) @@
frida: $(TEST_CMPLOG_OBJ) $(CMP_LOG_INPUT) frida: $(TEST_CMPLOG_OBJ) $(CMP_LOG_INPUT)
XAFL_FRIDA_INST_RANGES=$(AFL_FRIDA_INST_RANGES) \
$(ROOT)afl-fuzz \ $(ROOT)afl-fuzz \
-O \ -O \
-i $(TEST_DATA_DIR) \ -i $(TEST_DATA_DIR) \
@ -62,5 +55,15 @@ frida: $(TEST_CMPLOG_OBJ) $(CMP_LOG_INPUT)
-- \ -- \
$(TEST_CMPLOG_OBJ) @@ $(TEST_CMPLOG_OBJ) @@
debug: $(TEST_CMPLOG_OBJ) $(CMP_LOG_INPUT)
gdb \
--ex 'set environment LD_PRELOAD=$(ROOT)afl-frida-trace.so' \
--ex 'set disassembly-flavor intel' \
--ex 'r $(CMP_LOG_INPUT)' \
--args $(TEST_CMPLOG_OBJ) $(CMP_LOG_INPUT)
clean: clean:
rm -rf $(BUILD_DIR) rm -rf $(BUILD_DIR)
format:
cd $(ROOT) && echo $(TEST_CMPLOG_SRC) | xargs -L1 ./.custom-format.py -i

View File

@ -2,6 +2,10 @@ all:
@echo trying to use GNU make... @echo trying to use GNU make...
@gmake all || echo please install GNUmake @gmake all || echo please install GNUmake
32:
@echo trying to use GNU make...
@gmake 32 || echo please install GNUmake
clean: clean:
@gmake clean @gmake clean
@ -9,4 +13,10 @@ qemu:
@gmake qemu @gmake qemu
frida: frida:
@gmake frida @gmake frida
format:
@gmake format
debug:
@gmake debug

View File

@ -0,0 +1,100 @@
/////////////////////////////////////////////////////////////////////////
//
// Author: Mateusz Jurczyk (mjurczyk@google.com)
//
// Copyright 2019-2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// solution: echo -ne 'The quick brown fox jumps over the lazy
// dog\xbe\xba\xfe\xca\xbe\xba\xfe\xca\xde\xc0\xad\xde\xef\xbe' | ./compcovtest
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
char buffer[44] = {/* zero padding */};
FILE *file = stdin;
if (argc > 1) {
if ((file = fopen(argv[1], "r")) == NULL) {
perror(argv[1]);
exit(-1);
}
}
fread(buffer, 1, sizeof(buffer) - 1, file);
if (memcmp(&buffer[0], "The quick brown fox ", 20) != 0 ||
strncmp(&buffer[20], "jumps over ", 11) != 0 ||
strcmp(&buffer[31], "the lazy dog") != 0) {
if (argc > 1) { fclose(file); }
return 1;
}
#if defined(__x86_64__)
uint64_t x = 0;
fread(&x, sizeof(x), 1, file);
if (x != 0xCAFEBABECAFEBABE) {
if (argc > 1) { fclose(file); }
return 2;
}
#endif
uint32_t y = 0;
fread(&y, sizeof(y), 1, file);
if (y != 0xDEADC0DE) {
if (argc > 1) { fclose(file); }
return 3;
}
uint16_t z = 0;
fread(&z, sizeof(z), 1, file);
switch (z) {
case 0xBEEF:
break;
default:
if (argc > 1) { fclose(file); }
return 4;
}
printf("Puzzle solved, congrats!\n");
abort();
if (argc > 1) { fclose(file); }
return 0;
}

View File

@ -12,6 +12,18 @@ FRIDA_OUT:=$(BUILD_DIR)frida-out
GET_SYMBOL_ADDR:=$(ROOT)frida_mode/test/png/persistent/get_symbol_addr.py GET_SYMBOL_ADDR:=$(ROOT)frida_mode/test/png/persistent/get_symbol_addr.py
ifndef ARCH
ARCH=$(shell uname -m)
ifeq "$(ARCH)" "aarch64"
ARCH:=arm64
endif
ifeq "$(ARCH)" "i686"
ARCH:=x86
endif
endif
ARCH=$(shell uname -m) ARCH=$(shell uname -m)
ifeq "$(ARCH)" "aarch64" ifeq "$(ARCH)" "aarch64"
AFL_ENTRYPOINT=$(shell $(GET_SYMBOL_ADDR) -f $(TESTINSTBIN) -s run -b 0x0000aaaaaaaaa000) AFL_ENTRYPOINT=$(shell $(GET_SYMBOL_ADDR) -f $(TESTINSTBIN) -s run -b 0x0000aaaaaaaaa000)
@ -21,11 +33,18 @@ ifeq "$(ARCH)" "x86_64"
AFL_ENTRYPOINT=$(shell $(GET_SYMBOL_ADDR) -f $(TESTINSTBIN) -s run -b 0x0000555555554000) AFL_ENTRYPOINT=$(shell $(GET_SYMBOL_ADDR) -f $(TESTINSTBIN) -s run -b 0x0000555555554000)
endif endif
ifeq "$(ARCH)" "x86"
AFL_ENTRYPOINT=$(shell $(GET_SYMBOL_ADDR) -f $(TESTINSTBIN) -s run -b 0x56555000)
endif
.PHONY: all clean qemu frida .PHONY: all clean qemu frida
all: $(TESTINSTBIN) all: $(TESTINSTBIN)
make -C $(ROOT)frida_mode/ make -C $(ROOT)frida_mode/
32:
CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all
$(BUILD_DIR): $(BUILD_DIR):
mkdir -p $@ mkdir -p $@
@ -36,7 +55,7 @@ $(TESTINSTR_DATA_FILE): | $(TESTINSTR_DATA_DIR)
echo -n "000" > $@ echo -n "000" > $@
$(TESTINSTBIN): $(TESTINSTSRC) | $(BUILD_DIR) $(TESTINSTBIN): $(TESTINSTSRC) | $(BUILD_DIR)
$(CC) -o $@ $< $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
clean: clean:
rm -rf $(BUILD_DIR) rm -rf $(BUILD_DIR)
@ -58,4 +77,4 @@ frida_entry: $(TESTINSTBIN) $(TESTINSTR_DATA_FILE)
-i $(TESTINSTR_DATA_DIR) \ -i $(TESTINSTR_DATA_DIR) \
-o $(FRIDA_OUT) \ -o $(FRIDA_OUT) \
-- \ -- \
$(TESTINSTBIN) @@ $(TESTINSTBIN) @@

View File

@ -2,6 +2,10 @@ all:
@echo trying to use GNU make... @echo trying to use GNU make...
@gmake all || echo please install GNUmake @gmake all || echo please install GNUmake
32:
@echo trying to use GNU make...
@gmake 32 || echo please install GNUmake
clean: clean:
@gmake clean @gmake clean
@ -9,4 +13,4 @@ frida:
@gmake frida @gmake frida
frida_entry: frida_entry:
@gmake frida @gmake frida

View File

@ -106,7 +106,9 @@ int run(char *file) {
} }
void slow() { void slow() {
usleep(100000); usleep(100000);
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {

View File

@ -10,11 +10,14 @@ TESTINSTSRC:=$(PWD)testinstr.c
QEMU_OUT:=$(BUILD_DIR)qemu-out QEMU_OUT:=$(BUILD_DIR)qemu-out
FRIDA_OUT:=$(BUILD_DIR)frida-out FRIDA_OUT:=$(BUILD_DIR)frida-out
.PHONY: all clean qemu frida .PHONY: all 32 clean qemu frida
all: $(TESTINSTBIN) all: $(TESTINSTBIN)
make -C $(ROOT)frida_mode/ make -C $(ROOT)frida_mode/
32:
CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all
$(BUILD_DIR): $(BUILD_DIR):
mkdir -p $@ mkdir -p $@
@ -25,7 +28,7 @@ $(TESTINSTR_DATA_FILE): | $(TESTINSTR_DATA_DIR)
echo -n "000" > $@ echo -n "000" > $@
$(TESTINSTBIN): $(TESTINSTSRC) | $(BUILD_DIR) $(TESTINSTBIN): $(TESTINSTSRC) | $(BUILD_DIR)
$(CC) -o $@ $< -no-pie $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -no-pie
clean: clean:
rm -rf $(BUILD_DIR) rm -rf $(BUILD_DIR)
@ -47,4 +50,4 @@ frida: $(TESTINSTBIN) $(TESTINSTR_DATA_FILE)
-i $(TESTINSTR_DATA_DIR) \ -i $(TESTINSTR_DATA_DIR) \
-o $(FRIDA_OUT) \ -o $(FRIDA_OUT) \
-- \ -- \
$(TESTINSTBIN) @@ $(TESTINSTBIN) @@

View File

@ -2,6 +2,10 @@ all:
@echo trying to use GNU make... @echo trying to use GNU make...
@gmake all || echo please install GNUmake @gmake all || echo please install GNUmake
32:
@echo trying to use GNU make...
@gmake 32 || echo please install GNUmake
clean: clean:
@gmake clean @gmake clean
@ -9,4 +13,4 @@ qemu:
@gmake qemu @gmake qemu
frida: frida:
@gmake frida @gmake frida

View File

@ -42,7 +42,7 @@ ifeq "$(ARCH)" "x86"
LIBASAN_FILE:=libclang_rt.asan-i386.so LIBASAN_FILE:=libclang_rt.asan-i386.so
endif endif
ifeq "$(ARCH)" "x64" ifeq "$(ARCH)" "x86_64"
LIBASAN_FILE:=libclang_rt.asan-x86_64.so LIBASAN_FILE:=libclang_rt.asan-x86_64.so
endif endif
@ -85,12 +85,15 @@ else
endif endif
.PHONY: all clean format frida-noasan frida debug run .PHONY: all 32 clean format frida-noasan frida debug run
############################## ALL ############################################# ############################## ALL #############################################
all: $(TEST_BIN) all: $(TEST_BIN)
32:
CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all
$(TEST_BIN): $(TEST_SRC) GNUmakefile | $(BUILD_DIR) $(TEST_BIN): $(TEST_SRC) GNUmakefile | $(BUILD_DIR)
$(CC) \ $(CC) \
$(CFLAGS) \ $(CFLAGS) \
@ -120,7 +123,7 @@ frida-noasan: $(TEST_BIN) $(TEST_DATA_FILE)
frida: $(TEST_BIN) $(TEST_DATA_FILE) frida: $(TEST_BIN) $(TEST_DATA_FILE)
AFL_PRELOAD=/usr/lib/llvm-10/lib/clang/10.0.0/lib/linux/libclang_rt.asan-x86_64.so \ AFL_PRELOAD=$(LIBASAN) \
AFL_USE_FASAN=1 \ AFL_USE_FASAN=1 \
$(ROOT)afl-fuzz \ $(ROOT)afl-fuzz \
-D \ -D \

View File

@ -2,6 +2,10 @@ all:
@echo trying to use GNU make... @echo trying to use GNU make...
@gmake all || echo please install GNUmake @gmake all || echo please install GNUmake
32:
@echo trying to use GNU make...
@gmake 32 || echo please install GNUmake
clean: clean:
@gmake clean @gmake clean
@ -15,4 +19,4 @@ debug:
@gmake debug @gmake debug
run: run:
@gmake run @gmake run

View File

@ -5,6 +5,8 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#define UNUSED_PARAMETER(x) (void)(x)
#define LOG(x) \ #define LOG(x) \
do { \ do { \
\ \
@ -67,6 +69,9 @@ void test(char data) {
int main(int argc, char **argv) { int main(int argc, char **argv) {
UNUSED_PARAMETER(argc);
UNUSED_PARAMETER(argv);
char input = '\0'; char input = '\0';
if (read(STDIN_FILENO, &input, 1) < 0) { if (read(STDIN_FILENO, &input, 1) < 0) {

View File

@ -35,6 +35,9 @@ FRIDA_OUT:=$(BUILD_DIR)frida-out
all: $(TEST_BIN) all: $(TEST_BIN)
make -C $(ROOT)frida_mode/ make -C $(ROOT)frida_mode/
32:
CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all
$(BUILD_DIR): $(BUILD_DIR):
mkdir -p $@ mkdir -p $@
@ -46,7 +49,7 @@ $(HARNESS_FILE): | $(HARNESS_BUILD_DIR)
wget -O $@ $(HARNESS_URL) wget -O $@ $(HARNESS_URL)
$(HARNESS_OBJ): $(HARNESS_FILE) $(HARNESS_OBJ): $(HARNESS_FILE)
$(CC) -o $@ -c $< $(CC) $(CFLAGS) $(LDFLAGS) -o $@ -c $<
######### PNGTEST ######## ######### PNGTEST ########
@ -57,7 +60,7 @@ $(PNGTEST_FILE): | $(PNGTEST_BUILD_DIR)
wget -O $@ $(PNGTEST_URL) wget -O $@ $(PNGTEST_URL)
$(PNGTEST_OBJ): $(PNGTEST_FILE) | $(LIBPNG_DIR) $(PNGTEST_OBJ): $(PNGTEST_FILE) | $(LIBPNG_DIR)
$(CXX) -std=c++11 -I $(LIBPNG_DIR) -o $@ -c $< $(CXX) $(CFLAGS) $(LDFLAGS) -std=c++11 -I $(LIBPNG_DIR) -o $@ -c $<
######### LIBPNG ######## ######### LIBPNG ########
@ -80,6 +83,8 @@ $(LIBPNG_LIB): $(LIBPNG_MAKEFILE)
$(TEST_BIN): $(HARNESS_OBJ) $(PNGTEST_OBJ) $(LIBPNG_LIB) $(TEST_BIN): $(HARNESS_OBJ) $(PNGTEST_OBJ) $(LIBPNG_LIB)
$(CXX) \ $(CXX) \
$(CFLAGS) \
$(LDFLAGS) \
-o $@ \ -o $@ \
$(HARNESS_OBJ) $(PNGTEST_OBJ) $(LIBPNG_LIB) \ $(HARNESS_OBJ) $(PNGTEST_OBJ) $(LIBPNG_LIB) \
-lz \ -lz \

View File

@ -2,6 +2,10 @@ all:
@echo trying to use GNU make... @echo trying to use GNU make...
@gmake all || echo please install GNUmake @gmake all || echo please install GNUmake
32:
@echo trying to use GNU make...
@gmake 32 || echo please install GNUmake
clean: clean:
@gmake clean @gmake clean
@ -9,4 +13,4 @@ qemu:
@gmake qemu @gmake qemu
frida: frida:
@gmake frida @gmake frida

View File

@ -8,6 +8,18 @@ TEST_DATA_DIR:=../build/libpng/libpng-1.2.56/contrib/pngsuite/
QEMU_OUT:=$(BUILD_DIR)qemu-out QEMU_OUT:=$(BUILD_DIR)qemu-out
FRIDA_OUT:=$(BUILD_DIR)frida-out FRIDA_OUT:=$(BUILD_DIR)frida-out
ifndef ARCH
ARCH=$(shell uname -m)
ifeq "$(ARCH)" "aarch64"
ARCH:=arm64
endif
ifeq "$(ARCH)" "i686"
ARCH:=x86
endif
endif
AFL_QEMU_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TEST_BIN) -s main -b 0x4000000000) AFL_QEMU_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TEST_BIN) -s main -b 0x4000000000)
ARCH=$(shell uname -m) ARCH=$(shell uname -m)
@ -19,11 +31,18 @@ ifeq "$(ARCH)" "x86_64"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TEST_BIN) -s main -b 0x0000555555554000) AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TEST_BIN) -s main -b 0x0000555555554000)
endif endif
.PHONY: all clean qemu qemu_entry frida frida_entry ifeq "$(ARCH)" "x86"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TEST_BIN) -s main -b 0x56555000)
endif
.PHONY: all 32 clean qemu qemu_entry frida frida_entry
all: all:
make -C $(ROOT)frida_mode/test/png/ make -C $(ROOT)frida_mode/test/png/
32:
CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all
$(BUILD_DIR): $(BUILD_DIR):
mkdir -p $@ mkdir -p $@
@ -76,4 +95,4 @@ frida_entry: | $(BUILD_DIR)
$(TEST_BIN) @@ $(TEST_BIN) @@
clean: clean:
rm -rf $(BUILD_DIR) rm -rf $(BUILD_DIR)

View File

@ -2,6 +2,10 @@ all:
@echo trying to use GNU make... @echo trying to use GNU make...
@gmake all || echo please install GNUmake @gmake all || echo please install GNUmake
32:
@echo trying to use GNU make...
@gmake 32 || echo please install GNUmake
clean: clean:
@gmake clean @gmake clean
@ -15,4 +19,4 @@ frida:
@gmake frida @gmake frida
frida_entry: frida_entry:
@gmake frida_entry @gmake frida_entry

View File

@ -33,4 +33,4 @@ def main():
if __name__ == "__main__": if __name__ == "__main__":
ret = main() ret = main()
exit(ret) exit(ret)

View File

@ -2,8 +2,16 @@ PWD:=$(shell pwd)/
ROOT:=$(shell realpath $(PWD)../../../../..)/ ROOT:=$(shell realpath $(PWD)../../../../..)/
BUILD_DIR:=$(PWD)build/ BUILD_DIR:=$(PWD)build/
AFLPP_DRIVER_HOOK_DIR=$(ROOT)utils/aflpp_driver/ AFLPP_DRIVER_HOOK_SRC=$(PWD)aflpp_qemu_driver_hook.c
AFLPP_DRIVER_HOOK_OBJ=$(AFLPP_DRIVER_HOOK_DIR)aflpp_qemu_driver_hook.so AFLPP_DRIVER_HOOK_OBJ=$(BUILD_DIR)aflpp_qemu_driver_hook.so
CFLAGS+=-O3 \
-funroll-loops \
-g \
-fPIC \
-funroll-loops \
LDFLAGS+=-shared \
TEST_BIN:=$(PWD)../../build/test TEST_BIN:=$(PWD)../../build/test
TEST_DATA_DIR:=../../build/libpng/libpng-1.2.56/contrib/pngsuite/ TEST_DATA_DIR:=../../build/libpng/libpng-1.2.56/contrib/pngsuite/
@ -12,9 +20,20 @@ AFLPP_DRIVER_DUMMY_INPUT:=$(BUILD_DIR)in
QEMU_OUT:=$(BUILD_DIR)qemu-out QEMU_OUT:=$(BUILD_DIR)qemu-out
FRIDA_OUT:=$(BUILD_DIR)frida-out FRIDA_OUT:=$(BUILD_DIR)frida-out
AFL_QEMU_PERSISTENT_ADDR=$(shell $(PWD)../get_symbol_addr.py -f $(TEST_BIN) -s LLVMFuzzerTestOneInput -b 0x4000000000) ifndef ARCH
ARCH=$(shell uname -m) ARCH=$(shell uname -m)
ifeq "$(ARCH)" "aarch64"
ARCH:=arm64
endif
ifeq "$(ARCH)" "i686"
ARCH:=x86
endif
endif
AFL_QEMU_PERSISTENT_ADDR=$(shell $(PWD)../get_symbol_addr.py -f $(TEST_BIN) -s LLVMFuzzerTestOneInput -b 0x4000000000)
ifeq "$(ARCH)" "aarch64" ifeq "$(ARCH)" "aarch64"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)../get_symbol_addr.py -f $(TEST_BIN) -s LLVMFuzzerTestOneInput -b 0x0000aaaaaaaaa000) AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)../get_symbol_addr.py -f $(TEST_BIN) -s LLVMFuzzerTestOneInput -b 0x0000aaaaaaaaa000)
endif endif
@ -23,11 +42,18 @@ ifeq "$(ARCH)" "x86_64"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)../get_symbol_addr.py -f $(TEST_BIN) -s LLVMFuzzerTestOneInput -b 0x0000555555554000) AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)../get_symbol_addr.py -f $(TEST_BIN) -s LLVMFuzzerTestOneInput -b 0x0000555555554000)
endif endif
.PHONY: all clean qemu qemu_entry frida frida_entry ifeq "$(ARCH)" "x86"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)../get_symbol_addr.py -f $(TEST_BIN) -s LLVMFuzzerTestOneInput -b 0x56555000)
endif
all: .PHONY: all 32 clean format qemu qemu_entry frida frida_entry debug
all: $(AFLPP_DRIVER_HOOK_OBJ)
make -C $(ROOT)frida_mode/test/png/persistent/ make -C $(ROOT)frida_mode/test/png/persistent/
32:
CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all
$(BUILD_DIR): $(BUILD_DIR):
mkdir -p $@ mkdir -p $@
@ -37,8 +63,8 @@ $(TEST_DATA_DIR): | $(BUILD_DIR)
$(AFLPP_DRIVER_DUMMY_INPUT): | $(BUILD_DIR) $(AFLPP_DRIVER_DUMMY_INPUT): | $(BUILD_DIR)
truncate -s 1M $@ truncate -s 1M $@
$(AFLPP_DRIVER_HOOK_OBJ): | $(AFLPP_DRIVER_HOOK_DIR) $(AFLPP_DRIVER_HOOK_OBJ): $(AFLPP_DRIVER_HOOK_SRC) | $(BUILD_DIR)
make -C $(AFLPP_DRIVER_HOOK_DIR) $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
qemu: $(AFLPP_DRIVER_DUMMY_INPUT) $(AFLPP_DRIVER_HOOK_OBJ) | $(BUILD_DIR) qemu: $(AFLPP_DRIVER_DUMMY_INPUT) $(AFLPP_DRIVER_HOOK_OBJ) | $(BUILD_DIR)
AFL_QEMU_PERSISTENT_HOOK=$(AFLPP_DRIVER_HOOK_OBJ) \ AFL_QEMU_PERSISTENT_HOOK=$(AFLPP_DRIVER_HOOK_OBJ) \
@ -93,6 +119,18 @@ frida_entry: $(AFLPP_DRIVER_DUMMY_INPUT) $(AFLPP_DRIVER_HOOK_OBJ) | $(BUILD_DIR)
-- \ -- \
$(TEST_BIN) $(AFLPP_DRIVER_DUMMY_INPUT) $(TEST_BIN) $(AFLPP_DRIVER_DUMMY_INPUT)
debug:
echo $(AFL_FRIDA_PERSISTENT_ADDR)
gdb \
--ex 'set environment LD_PRELOAD=$(ROOT)afl-frida-trace.so' \
--ex 'set environment AFL_FRIDA_PERSISTENT_HOOK=$(AFLPP_DRIVER_HOOK_OBJ)' \
--ex 'set environment AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR)' \
--ex 'set disassembly-flavor intel' \
--args $(TEST_BIN) $(AFLPP_DRIVER_DUMMY_INPUT)
clean: clean:
rm -rf $(BUILD_DIR) rm -rf $(BUILD_DIR)
format:
cd $(ROOT) && echo $(AFLPP_DRIVER_HOOK_SRC) | xargs -L1 ./.custom-format.py -i

View File

@ -2,9 +2,16 @@ all:
@echo trying to use GNU make... @echo trying to use GNU make...
@gmake all || echo please install GNUmake @gmake all || echo please install GNUmake
32:
@echo trying to use GNU make...
@gmake 32 || echo please install GNUmake
clean: clean:
@gmake clean @gmake clean
format:
@gmake format
qemu: qemu:
@gmake qemu @gmake qemu
@ -15,4 +22,7 @@ frida:
@gmake frida @gmake frida
frida_entry: frida_entry:
@gmake frida_entry @gmake frida_entry
debug:
@gmake debug

View File

@ -0,0 +1,97 @@
#include <stdint.h>
#include <string.h>
#if defined(__x86_64__)
struct x86_64_regs {
uint64_t rax, rbx, rcx, rdx, rdi, rsi, rbp, r8, r9, r10, r11, r12, r13, r14,
r15;
union {
uint64_t rip;
uint64_t pc;
};
union {
uint64_t rsp;
uint64_t sp;
};
union {
uint64_t rflags;
uint64_t flags;
};
uint8_t zmm_regs[32][64];
};
void afl_persistent_hook(struct x86_64_regs *regs, uint64_t guest_base,
uint8_t *input_buf, uint32_t input_buf_len) {
memcpy((void *)regs->rdi, input_buf, input_buf_len);
regs->rsi = input_buf_len;
}
#elif defined(__i386__)
struct x86_regs {
uint32_t eax, ebx, ecx, edx, edi, esi, ebp;
union {
uint32_t eip;
uint32_t pc;
};
union {
uint32_t esp;
uint32_t sp;
};
union {
uint32_t eflags;
uint32_t flags;
};
uint8_t xmm_regs[8][16];
};
void afl_persistent_hook(struct x86_regs *regs, uint64_t guest_base,
uint8_t *input_buf, uint32_t input_buf_len) {
void **esp = (void **)regs->esp;
void * arg1 = esp[1];
void **arg2 = &esp[2];
memcpy(arg1, input_buf, input_buf_len);
*arg2 = (void *)input_buf_len;
}
#else
#pragma error "Unsupported architecture"
#endif
int afl_persistent_hook_init(void) {
// 1 for shared memory input (faster), 0 for normal input (you have to use
// read(), input_buf will be NULL)
return 1;
}

View File

@ -10,11 +10,14 @@ TESTINSTSRC:=$(PWD)testinstr.c
QEMU_OUT:=$(BUILD_DIR)qemu-out QEMU_OUT:=$(BUILD_DIR)qemu-out
FRIDA_OUT:=$(BUILD_DIR)frida-out FRIDA_OUT:=$(BUILD_DIR)frida-out
.PHONY: all clean qemu frida .PHONY: all 32 clean qemu frida
all: $(TESTINSTBIN) all: $(TESTINSTBIN)
make -C $(ROOT)frida_mode/ make -C $(ROOT)frida_mode/
32:
CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all
$(BUILD_DIR): $(BUILD_DIR):
mkdir -p $@ mkdir -p $@
@ -25,7 +28,7 @@ $(TESTINSTR_DATA_FILE): | $(TESTINSTR_DATA_DIR)
echo -n "000" > $@ echo -n "000" > $@
$(TESTINSTBIN): $(TESTINSTSRC) | $(BUILD_DIR) $(TESTINSTBIN): $(TESTINSTSRC) | $(BUILD_DIR)
$(CC) -o $@ $< $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
clean: clean:
rm -rf $(BUILD_DIR) rm -rf $(BUILD_DIR)
@ -47,4 +50,10 @@ frida: $(TESTINSTBIN) $(TESTINSTR_DATA_FILE)
-i $(TESTINSTR_DATA_DIR) \ -i $(TESTINSTR_DATA_DIR) \
-o $(FRIDA_OUT) \ -o $(FRIDA_OUT) \
-- \ -- \
$(TESTINSTBIN) @@ $(TESTINSTBIN) @@
debug:
gdb \
--ex 'set environment LD_PRELOAD=$(ROOT)afl-frida-trace.so' \
--ex 'set disassembly-flavor intel' \
--args $(TESTINSTBIN) $(TESTINSTR_DATA_FILE)

View File

@ -2,6 +2,10 @@ all:
@echo trying to use GNU make... @echo trying to use GNU make...
@gmake all || echo please install GNUmake @gmake all || echo please install GNUmake
32:
@echo trying to use GNU make...
@gmake 32 || echo please install GNUmake
clean: clean:
@gmake clean @gmake clean
@ -9,4 +13,7 @@ qemu:
@gmake qemu @gmake qemu
frida: frida:
@gmake frida @gmake frida
debug:
@gmake debug