mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-10 17:21:33 +00:00
commit
77ebab64d3
@ -57,7 +57,10 @@ ifdef DEBUG
|
||||
CFLAGS+=-Werror \
|
||||
-Wall \
|
||||
-Wextra \
|
||||
-Wpointer-arith
|
||||
-Wpointer-arith \
|
||||
-Wno-unknown-pragmas \
|
||||
-Wno-pointer-to-int-cast \
|
||||
-Wno-int-to-pointer-cast
|
||||
else
|
||||
CFLAGS+=-Wno-pointer-arith
|
||||
endif
|
||||
@ -142,7 +145,7 @@ ifndef OS
|
||||
$(error "Operating system unsupported")
|
||||
endif
|
||||
|
||||
GUM_DEVKIT_VERSION=15.2.1
|
||||
GUM_DEVKIT_VERSION=16.0.1
|
||||
GUM_DEVKIT_FILENAME=frida-gumjs-devkit-$(GUM_DEVKIT_VERSION)-$(OS)-$(ARCH).tar.xz
|
||||
GUM_DEVKIT_URL="https://github.com/frida/frida/releases/download/$(GUM_DEVKIT_VERSION)/$(GUM_DEVKIT_FILENAME)"
|
||||
|
||||
@ -206,7 +209,7 @@ $(FRIDA_MAKEFILE): | $(BUILD_DIR)
|
||||
.PHONY: $(GUM_DEVIT_LIBRARY)
|
||||
|
||||
$(GUM_DEVIT_LIBRARY): $(FRIDA_MAKEFILE)
|
||||
cd $(FRIDA_DIR) && make gum-$(OS)$(GUM_ARCH)
|
||||
cd $(FRIDA_DIR) && make gum-$(OS)$(GUM_ARCH) FRIDA_V8=disabled
|
||||
|
||||
$(GUM_DEVIT_HEADER): $(FRIDA_MAKEFILE) | $(FRIDA_BUILD_DIR)
|
||||
echo "#include <stdio.h>" > $@
|
||||
@ -245,40 +248,40 @@ TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/lib/libfrida-gum-1.0.a \
|
||||
|
||||
else ifeq "$(ARCH)" "arm64"
|
||||
|
||||
CFLAGS+=-I $(FRIDA_DIR)build/frida_thin-$(OS)-$(ARCH)/include/frida-1.0 \
|
||||
-I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/glib-2.0/ \
|
||||
-I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/glib-2.0/include/ \
|
||||
-I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/capstone/ \
|
||||
-I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/json-glib-1.0/ \
|
||||
CFLAGS+=-I $(FRIDA_DIR)build/$(OS)-$(ARCH)/include/frida-1.0 \
|
||||
-I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/glib-2.0/ \
|
||||
-I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/glib-2.0/include/ \
|
||||
-I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/capstone/ \
|
||||
-I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/json-glib-1.0/ \
|
||||
|
||||
ifeq "$(OS)" "android"
|
||||
CFLAGS += -static-libstdc++
|
||||
endif
|
||||
else
|
||||
CFLAGS+=-I $(FRIDA_DIR)build/frida_thin-$(OS)-$(ARCH)/include/frida-1.0 \
|
||||
-I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/glib-2.0/ \
|
||||
-I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/glib-2.0/include/ \
|
||||
-I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/capstone/ \
|
||||
-I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/json-glib-1.0/ \
|
||||
CFLAGS+=-I $(FRIDA_DIR)build/$(OS)-$(ARCH)/include/frida-1.0 \
|
||||
-I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/glib-2.0/ \
|
||||
-I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/glib-2.0/include/ \
|
||||
-I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/capstone/ \
|
||||
-I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/json-glib-1.0/ \
|
||||
|
||||
endif
|
||||
|
||||
TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/lib/libfrida-gum-1.0.a \
|
||||
$(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libsoup-2.4.a \
|
||||
$(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libsqlite3.a \
|
||||
$(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libtcc.a \
|
||||
$(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libjson-glib-1.0.a \
|
||||
$(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libquickjs.a \
|
||||
$(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libcapstone.a \
|
||||
$(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libunwind.a \
|
||||
$(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libffi.a \
|
||||
$(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libdwarf.a \
|
||||
$(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libelf.a \
|
||||
$(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libgio-2.0.a \
|
||||
$(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libgobject-2.0.a \
|
||||
$(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libglib-2.0.a \
|
||||
$(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/liblzma.a \
|
||||
$(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libz.a \
|
||||
$(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libsoup-2.4.a \
|
||||
$(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libsqlite3.a \
|
||||
$(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libtcc.a \
|
||||
$(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libjson-glib-1.0.a \
|
||||
$(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libquickjs.a \
|
||||
$(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libcapstone.a \
|
||||
$(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libunwind.a \
|
||||
$(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libffi.a \
|
||||
$(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libdwarf.a \
|
||||
$(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libelf.a \
|
||||
$(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libgio-2.0.a \
|
||||
$(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libgobject-2.0.a \
|
||||
$(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libglib-2.0.a \
|
||||
$(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/liblzma.a \
|
||||
$(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libz.a \
|
||||
|
||||
CFLAGS+=-I $(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/include/frida-1.0 \
|
||||
-I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/glib-2.0/ \
|
||||
|
@ -54,10 +54,12 @@ __attribute__((visibility("default"))) void afl_persistent_hook(
|
||||
|
||||
__attribute__((visibility("default"))) void afl_persistent_hook(
|
||||
GumCpuContext *regs, uint8_t *input_buf, uint32_t input_buf_len) {
|
||||
|
||||
// do a length check matching the target!
|
||||
|
||||
memcpy((void *)regs->r[0], input_buf, input_buf_len);
|
||||
regs->r[1] = input_buf_len;
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -7,6 +7,8 @@
|
||||
|
||||
gsize ctx_read_reg(GumArmCpuContext *ctx, arm_reg reg) {
|
||||
|
||||
UNUSED_PARAMETER(ctx);
|
||||
UNUSED_PARAMETER(reg);
|
||||
FFATAL("ctx_read_reg unimplemented for this architecture");
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "frida-gumjs.h"
|
||||
|
||||
#include "instrument.h"
|
||||
#include "stalker.h"
|
||||
#include "util.h"
|
||||
|
||||
#if defined(__arm__)
|
||||
@ -8,8 +9,9 @@
|
||||
#define PAGE_MASK (~(GUM_ADDRESS(0xfff)))
|
||||
#define PAGE_ALIGNED(x) ((GUM_ADDRESS(x) & PAGE_MASK) == GUM_ADDRESS(x))
|
||||
|
||||
gboolean instrument_cache_enabled = FALSE;
|
||||
gsize instrument_cache_size = 0;
|
||||
gboolean instrument_cache_enabled = FALSE;
|
||||
gsize instrument_cache_size = 0;
|
||||
static GHashTable *coverage_blocks = NULL;
|
||||
|
||||
extern __thread guint64 instrument_previous_pc;
|
||||
|
||||
@ -22,7 +24,24 @@ typedef struct {
|
||||
// shared_mem[cur_location ^ prev_location]++;
|
||||
// prev_location = cur_location >> 1;
|
||||
|
||||
/* We can remove this branch when we add support for branch suppression */
|
||||
// str r0, [sp, #-128] ; 0xffffff80
|
||||
// str r1, [sp, #-132] ; 0xffffff7c
|
||||
// ldr r0, [pc, #-20] ; 0xf691b29c
|
||||
// ldrh r1, [r0]
|
||||
// movw r0, #33222 ; 0x81c6
|
||||
// eor r0, r0, r1
|
||||
// ldr r1, [pc, #-40] ; 0xf691b298
|
||||
// add r1, r1, r0
|
||||
// ldrb r0, [r1]
|
||||
// add r0, r0, #1
|
||||
// add r0, r0, r0, lsr #8
|
||||
// strb r0, [r1]
|
||||
// movw r0, #49379 ; 0xc0e3
|
||||
// ldr r1, [pc, #-64] ; 0xf691b29c
|
||||
// strh r0, [r1]
|
||||
// ldr r1, [sp, #-132] ; 0xffffff7c
|
||||
// ldr r0, [sp, #-128] ; 0xffffff80
|
||||
|
||||
uint32_t b_code; /* b imm */
|
||||
uint8_t *shared_mem;
|
||||
uint64_t *prev_location;
|
||||
@ -115,6 +134,46 @@ gboolean instrument_is_coverage_optimize_supported(void) {
|
||||
|
||||
}
|
||||
|
||||
static void instrument_coverage_switch(GumStalkerObserver *self,
|
||||
gpointer from_address,
|
||||
gpointer start_address, void *from_insn,
|
||||
gpointer *target) {
|
||||
|
||||
UNUSED_PARAMETER(self);
|
||||
UNUSED_PARAMETER(from_address);
|
||||
UNUSED_PARAMETER(start_address);
|
||||
UNUSED_PARAMETER(from_insn);
|
||||
|
||||
if (!g_hash_table_contains(coverage_blocks, GSIZE_TO_POINTER(*target))) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
*target =
|
||||
(guint8 *)*target + G_STRUCT_OFFSET(afl_log_code_asm_t, str_r0_sp_rz);
|
||||
|
||||
}
|
||||
|
||||
static void instrument_coverage_suppress_init(void) {
|
||||
|
||||
static gboolean initialized = false;
|
||||
if (initialized) { return; }
|
||||
initialized = true;
|
||||
|
||||
GumStalkerObserver *observer = stalker_get_observer();
|
||||
GumStalkerObserverInterface *iface = GUM_STALKER_OBSERVER_GET_IFACE(observer);
|
||||
iface->switch_callback = instrument_coverage_switch;
|
||||
|
||||
coverage_blocks = g_hash_table_new(g_direct_hash, g_direct_equal);
|
||||
if (coverage_blocks == NULL) {
|
||||
|
||||
FATAL("Failed to g_hash_table_new, errno: %d", errno);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void patch_t3_insn(uint32_t *insn, uint16_t val) {
|
||||
|
||||
uint32_t orig = GUINT32_FROM_LE(*insn);
|
||||
@ -135,14 +194,17 @@ void instrument_coverage_optimize(const cs_insn *instr,
|
||||
guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address));
|
||||
gsize map_size_pow2;
|
||||
gsize area_offset_ror;
|
||||
GumAddress code_addr = 0;
|
||||
|
||||
// gum_arm64_writer_put_brk_imm(cw, 0x0);
|
||||
|
||||
code_addr = cw->pc;
|
||||
instrument_coverage_suppress_init();
|
||||
|
||||
block_start = GSIZE_TO_POINTER(GUM_ADDRESS(cw->code));
|
||||
|
||||
if (!g_hash_table_add(coverage_blocks, block_start)) {
|
||||
|
||||
FATAL("Failed - g_hash_table_add");
|
||||
|
||||
}
|
||||
|
||||
code.code = template;
|
||||
|
||||
g_assert(PAGE_ALIGNED(__afl_area_ptr));
|
||||
|
@ -156,26 +156,47 @@ static gboolean instrument_is_deterministic(const cs_insn *from_insn) {
|
||||
|
||||
}
|
||||
|
||||
cs_insn *instrument_disassemble(gconstpointer address) {
|
||||
|
||||
csh capstone;
|
||||
cs_insn *insn = NULL;
|
||||
|
||||
cs_open(CS_ARCH_ARM64, GUM_DEFAULT_CS_ENDIAN, &capstone);
|
||||
cs_option(capstone, CS_OPT_DETAIL, CS_OPT_ON);
|
||||
|
||||
cs_disasm(capstone, address, 16, GPOINTER_TO_SIZE(address), 1, &insn);
|
||||
|
||||
cs_close(&capstone);
|
||||
|
||||
return insn;
|
||||
|
||||
}
|
||||
|
||||
static void instrument_coverage_switch(GumStalkerObserver *self,
|
||||
gpointer from_address,
|
||||
gpointer start_address,
|
||||
const cs_insn *from_insn,
|
||||
gpointer *target) {
|
||||
gpointer start_address, void *from_insn,
|
||||
gpointer *target) {
|
||||
|
||||
UNUSED_PARAMETER(self);
|
||||
UNUSED_PARAMETER(from_address);
|
||||
UNUSED_PARAMETER(start_address);
|
||||
|
||||
gsize fixup_offset;
|
||||
cs_insn *insn = NULL;
|
||||
gboolean deterministic = FALSE;
|
||||
gsize fixup_offset;
|
||||
|
||||
if (!g_hash_table_contains(coverage_blocks, GSIZE_TO_POINTER(*target)) &&
|
||||
!g_hash_table_contains(coverage_blocks, GSIZE_TO_POINTER(*target + 4))) {
|
||||
!g_hash_table_contains(coverage_blocks,
|
||||
GSIZE_TO_POINTER((guint8 *)*target + 4))) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (instrument_is_deterministic(from_insn)) { return; }
|
||||
insn = instrument_disassemble(from_insn);
|
||||
deterministic = instrument_is_deterministic(insn);
|
||||
cs_free(insn, 1);
|
||||
if (deterministic) { return; }
|
||||
|
||||
/*
|
||||
* Since each block is prefixed with a restoration prologue, we need to be
|
||||
@ -208,7 +229,7 @@ static void instrument_coverage_switch(GumStalkerObserver *self,
|
||||
*/
|
||||
fixup_offset = GUM_RESTORATION_PROLOG_SIZE +
|
||||
G_STRUCT_OFFSET(afl_log_code_asm_t, restoration_prolog);
|
||||
*target += fixup_offset;
|
||||
*target = (guint8 *)*target + fixup_offset;
|
||||
|
||||
}
|
||||
|
||||
|
@ -171,11 +171,11 @@ void instrument_coverage_optimize_init(void) {
|
||||
|
||||
}
|
||||
|
||||
static void instrument_coverage_switch(GumStalkerObserver *self,
|
||||
gpointer from_address,
|
||||
gpointer start_address,
|
||||
const cs_insn *from_insn,
|
||||
gpointer *target) {
|
||||
static void instrument_coverage_switch_insn(GumStalkerObserver *self,
|
||||
gpointer from_address,
|
||||
gpointer start_address,
|
||||
const cs_insn *from_insn,
|
||||
gpointer *target) {
|
||||
|
||||
UNUSED_PARAMETER(self);
|
||||
UNUSED_PARAMETER(from_address);
|
||||
@ -224,6 +224,35 @@ static void instrument_coverage_switch(GumStalkerObserver *self,
|
||||
|
||||
}
|
||||
|
||||
cs_insn *instrument_disassemble(gconstpointer address) {
|
||||
|
||||
csh capstone;
|
||||
cs_insn *insn = NULL;
|
||||
|
||||
cs_open(CS_ARCH_X86, GUM_CPU_MODE, &capstone);
|
||||
cs_option(capstone, CS_OPT_DETAIL, CS_OPT_ON);
|
||||
|
||||
cs_disasm(capstone, address, 16, GPOINTER_TO_SIZE(address), 1, &insn);
|
||||
|
||||
cs_close(&capstone);
|
||||
|
||||
return insn;
|
||||
|
||||
}
|
||||
|
||||
static void instrument_coverage_switch(GumStalkerObserver *self,
|
||||
gpointer from_address,
|
||||
gpointer start_address, void *from_insn,
|
||||
gpointer *target) {
|
||||
|
||||
if (from_insn == NULL) { return; }
|
||||
cs_insn *insn = instrument_disassemble(from_insn);
|
||||
instrument_coverage_switch_insn(self, from_address, start_address, insn,
|
||||
target);
|
||||
cs_free(insn, 1);
|
||||
|
||||
}
|
||||
|
||||
static void instrument_coverage_suppress_init(void) {
|
||||
|
||||
static gboolean initialized = false;
|
||||
|
@ -83,11 +83,11 @@ gboolean instrument_is_coverage_optimize_supported(void) {
|
||||
|
||||
}
|
||||
|
||||
static void instrument_coverage_switch(GumStalkerObserver *self,
|
||||
gpointer from_address,
|
||||
gpointer start_address,
|
||||
const cs_insn *from_insn,
|
||||
gpointer *target) {
|
||||
static void instrument_coverage_switch_insn(GumStalkerObserver *self,
|
||||
gpointer from_address,
|
||||
gpointer start_address,
|
||||
const cs_insn *from_insn,
|
||||
gpointer *target) {
|
||||
|
||||
UNUSED_PARAMETER(self);
|
||||
UNUSED_PARAMETER(from_address);
|
||||
@ -130,6 +130,35 @@ static void instrument_coverage_switch(GumStalkerObserver *self,
|
||||
|
||||
}
|
||||
|
||||
cs_insn *instrument_disassemble(gconstpointer address) {
|
||||
|
||||
csh capstone;
|
||||
cs_insn *insn = NULL;
|
||||
|
||||
cs_open(CS_ARCH_X86, GUM_CPU_MODE, &capstone);
|
||||
cs_option(capstone, CS_OPT_DETAIL, CS_OPT_ON);
|
||||
|
||||
cs_disasm(capstone, address, 16, GPOINTER_TO_SIZE(address), 1, &insn);
|
||||
|
||||
cs_close(&capstone);
|
||||
|
||||
return insn;
|
||||
|
||||
}
|
||||
|
||||
static void instrument_coverage_switch(GumStalkerObserver *self,
|
||||
gpointer from_address,
|
||||
gpointer start_address, void *from_insn,
|
||||
gpointer *target) {
|
||||
|
||||
if (from_insn == NULL) { return; }
|
||||
cs_insn *insn = instrument_disassemble(from_insn);
|
||||
instrument_coverage_switch_insn(self, from_address, start_address, insn,
|
||||
target);
|
||||
cs_free(insn, 1);
|
||||
|
||||
}
|
||||
|
||||
static void instrument_coverage_suppress_init(void) {
|
||||
|
||||
static gboolean initialized = false;
|
||||
|
@ -18,10 +18,8 @@ static GumScriptScheduler *scheduler;
|
||||
static GMainContext *context;
|
||||
static GMainLoop *main_loop;
|
||||
|
||||
static void js_msg(GumScript *script, const gchar *message, GBytes *data,
|
||||
gpointer user_data) {
|
||||
static void js_msg(const gchar *message, GBytes *data, gpointer user_data) {
|
||||
|
||||
UNUSED_PARAMETER(script);
|
||||
UNUSED_PARAMETER(data);
|
||||
UNUSED_PARAMETER(user_data);
|
||||
FOKF("%s", message);
|
||||
@ -124,8 +122,8 @@ void js_start(void) {
|
||||
main_loop = g_main_loop_new(context, true);
|
||||
g_main_context_push_thread_default(context);
|
||||
|
||||
gum_script_backend_create(backend, "example", source, cancellable, create_cb,
|
||||
&error);
|
||||
gum_script_backend_create(backend, "example", source, NULL, cancellable,
|
||||
create_cb, &error);
|
||||
|
||||
while (g_main_context_pending(context))
|
||||
g_main_context_iteration(context, FALSE);
|
||||
|
@ -29,7 +29,6 @@ gboolean prefetch_enable = TRUE;
|
||||
gboolean prefetch_backpatch = TRUE;
|
||||
|
||||
static prefetch_data_t *prefetch_data = NULL;
|
||||
static int prefetch_shm_id = -1;
|
||||
|
||||
static GHashTable *cant_prefetch = NULL;
|
||||
|
||||
|
@ -13,6 +13,7 @@ void starts_arch_init(void) {
|
||||
|
||||
void stats_write_arch(stats_data_t *data) {
|
||||
|
||||
UNUSED_PARAMETER(data);
|
||||
FFATAL("Stats not supported on this architecture");
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user