diff options
-rw-r--r-- | frida_mode/GNUmakefile | 2 | ||||
-rw-r--r-- | frida_mode/addr/addr.c | 2 | ||||
-rw-r--r-- | frida_mode/include/instrument.h | 17 | ||||
-rw-r--r-- | frida_mode/src/instrument/instrument.c | 21 | ||||
-rw-r--r-- | frida_mode/src/instrument/instrument_arm64.c | 28 | ||||
-rw-r--r-- | frida_mode/src/instrument/instrument_x64.c | 17 | ||||
-rw-r--r-- | frida_mode/src/instrument/instrument_x86.c | 17 | ||||
-rw-r--r-- | frida_mode/src/persistent/persistent_arm64.c | 8 | ||||
-rw-r--r-- | frida_mode/src/persistent/persistent_x64.c | 8 | ||||
-rw-r--r-- | frida_mode/src/persistent/persistent_x86.c | 8 | ||||
-rw-r--r-- | frida_mode/test/libxslt/GNUmakefile | 177 | ||||
-rw-r--r-- | frida_mode/test/libxslt/Makefile | 13 |
12 files changed, 288 insertions, 30 deletions
diff --git a/frida_mode/GNUmakefile b/frida_mode/GNUmakefile index a8e6ce90..254c82db 100644 --- a/frida_mode/GNUmakefile +++ b/frida_mode/GNUmakefile @@ -141,9 +141,11 @@ AFLPP_FRIDA_DRIVER_HOOK_OBJ=$(BUILD_DIR)frida_hook.so AFLPP_QEMU_DRIVER_HOOK_SRC:=$(HOOK_DIR)qemu_hook.c AFLPP_QEMU_DRIVER_HOOK_OBJ:=$(BUILD_DIR)qemu_hook.so +ifneq "$(shell uname)" "Darwin" ADDR_DIR:=$(PWD)addr/ ADDR_SRC:=$(ADDR_DIR)addr.c ADDR_BIN:=$(BUILD_DIR)addr +endif BIN2C:=$(BUILD_DIR)bin2c BIN2C_SRC:=$(PWD)util/bin2c.c diff --git a/frida_mode/addr/addr.c b/frida_mode/addr/addr.c index 40ddc5ba..371f69d4 100644 --- a/frida_mode/addr/addr.c +++ b/frida_mode/addr/addr.c @@ -32,7 +32,7 @@ int main (int argc, char** argv, char** envp) { dl_iterate_phdr(phdr_callback, &base); - printf("0x%016lx\n", base); + printf("%p\n", (void *)base); if (base == 0) { return 1; } return 0; diff --git a/frida_mode/include/instrument.h b/frida_mode/include/instrument.h index 63f12181..abb89c9f 100644 --- a/frida_mode/include/instrument.h +++ b/frida_mode/include/instrument.h @@ -5,14 +5,13 @@ #include "config.h" -extern char * instrument_debug_filename; -extern char * instrument_coverage_filename; -extern gboolean instrument_tracing; -extern gboolean instrument_optimize; -extern gboolean instrument_unique; -extern __thread guint64 instrument_previous_pc; -extern guint64 instrument_hash_zero; -extern char * instrument_coverage_unstable_filename; +extern char * instrument_debug_filename; +extern char * instrument_coverage_filename; +extern gboolean instrument_tracing; +extern gboolean instrument_optimize; +extern gboolean instrument_unique; +extern guint64 instrument_hash_zero; +extern char * instrument_coverage_unstable_filename; extern gboolean instrument_use_fixed_seed; extern guint64 instrument_fixed_seed; @@ -20,6 +19,8 @@ extern guint64 instrument_fixed_seed; extern uint8_t *__afl_area_ptr; extern uint32_t __afl_map_size; +extern __thread guint64 *instrument_previous_pc_addr; + void instrument_config(void); void instrument_init(void); diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c index bf102a82..46ed1a34 100644 --- a/frida_mode/src/instrument/instrument.c +++ b/frida_mode/src/instrument/instrument.c @@ -32,12 +32,13 @@ char * instrument_coverage_unstable_filename = NULL; static GumStalkerTransformer *transformer = NULL; -__attribute__((aligned(0x1000))) __thread guint64 instrument_previous_pc = 0; - static GumAddress previous_rip = 0; static GumAddress previous_end = 0; static u8 * edges_notified = NULL; +__thread guint64 instrument_previous_pc; +__thread guint64 *instrument_previous_pc_addr = NULL; + typedef struct { GumAddress address; @@ -105,8 +106,14 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context, guint16 current_end = ctx->end; guint64 current_pc = instrument_get_offset_hash(current_rip); guint64 edge; + if (instrument_previous_pc_addr == NULL) { + + instrument_previous_pc_addr = &instrument_previous_pc; + *instrument_previous_pc_addr = instrument_hash_zero; + + } - edge = current_pc ^ instrument_previous_pc; + edge = current_pc ^ *instrument_previous_pc_addr; instrument_increment_map(edge); @@ -136,7 +143,7 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context, previous_end = current_end; gsize map_size_pow2 = util_log2(__afl_map_size); - instrument_previous_pc = util_rotate(current_pc, 1, map_size_pow2); + *instrument_previous_pc_addr = util_rotate(current_pc, 1, map_size_pow2); } @@ -393,7 +400,11 @@ GumStalkerTransformer *instrument_get_transformer(void) { void instrument_on_fork() { - instrument_previous_pc = instrument_hash_zero; + if (instrument_previous_pc_addr != NULL) { + + *instrument_previous_pc_addr = instrument_hash_zero; + + } } diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c index 27142f1f..360806f5 100644 --- a/frida_mode/src/instrument/instrument_arm64.c +++ b/frida_mode/src/instrument/instrument_arm64.c @@ -87,7 +87,7 @@ static const afl_log_code_asm_t template = .stp_x0_x1 = 0xa93607e0, - .adrp_x0_prev_loc1 = 0xb0000000, + .adrp_x0_prev_loc1 = 0x90000000, .ldr_x1_ptr_x0 = 0xf9400001, .mov_x0_curr_loc = 0xd2800000, @@ -104,7 +104,7 @@ static const afl_log_code_asm_t template = .strb_w1_ptr_x0 = 0x39000001, - .adrp_x0_prev_loc2 = 0xb0000000, + .adrp_x0_prev_loc2 = 0x90000000, .mov_x1_curr_loc_shr_1 = 0xd2800001, .str_x1_ptr_x0 = 0xf9000001, @@ -155,10 +155,23 @@ void instrument_coverage_optimize(const cs_insn * instr, afl_log_code code = {0}; GumArm64Writer *cw = output->writer.arm64; guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address)); - gsize map_size_pow2; - gsize area_offset_ror; + gsize map_size_pow2; + gsize area_offset_ror; GumAddress code_addr = 0; + if (instrument_previous_pc_addr == NULL) { + + GumAddressSpec spec = {.near_address = cw->code, + .max_distance = 1ULL << 30}; + + instrument_previous_pc_addr = gum_memory_allocate_near( + &spec, sizeof(guint64), 0x1000, GUM_PAGE_READ | GUM_PAGE_WRITE); + *instrument_previous_pc_addr = instrument_hash_zero; + FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr); + FVERBOSE("code_addr: %p", cw->code); + + } + // gum_arm64_writer_put_brk_imm(cw, 0x0); code_addr = cw->pc; @@ -170,13 +183,13 @@ void instrument_coverage_optimize(const cs_insn * instr, * 64KB in size, then it should also end on a 64 KB boundary. It is followed * by our previous_pc, so this too should be 64KB aligned. */ - g_assert(PAGE_ALIGNED(&instrument_previous_pc)); + g_assert(PAGE_ALIGNED(instrument_previous_pc_addr)); g_assert(PAGE_ALIGNED(__afl_area_ptr)); instrument_patch_ardp( &code.code.adrp_x0_prev_loc1, code_addr + offsetof(afl_log_code, code.adrp_x0_prev_loc1), - GUM_ADDRESS(&instrument_previous_pc)); + GUM_ADDRESS(instrument_previous_pc_addr)); code.code.mov_x0_curr_loc |= area_offset << 5; @@ -191,7 +204,7 @@ void instrument_coverage_optimize(const cs_insn * instr, instrument_patch_ardp( &code.code.adrp_x0_prev_loc2, code_addr + offsetof(afl_log_code, code.adrp_x0_prev_loc2), - GUM_ADDRESS(&instrument_previous_pc)); + GUM_ADDRESS(instrument_previous_pc_addr)); code.code.mov_x1_curr_loc_shr_1 |= (area_offset_ror << 5); @@ -214,7 +227,6 @@ void instrument_coverage_optimize_init(void) { } FVERBOSE("__afl_area_ptr: %p", __afl_area_ptr); - FVERBOSE("instrument_previous_pc: %p", &instrument_previous_pc); } diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c index b7b6ca6f..0ea4f7f0 100644 --- a/frida_mode/src/instrument/instrument_x64.c +++ b/frida_mode/src/instrument/instrument_x64.c @@ -360,7 +360,6 @@ void instrument_coverage_optimize_init(void) { } FVERBOSE("__afl_area_ptr: %p", __afl_area_ptr); - FVERBOSE("instrument_previous_pc: %p", &instrument_previous_pc); } @@ -439,6 +438,18 @@ void instrument_coverage_optimize(const cs_insn * instr, gsize map_size_pow2; gsize area_offset_ror; GumAddress code_addr = 0; + if (instrument_previous_pc_addr == NULL) { + + GumAddressSpec spec = {.near_address = cw->code, + .max_distance = 1ULL << 30}; + + instrument_previous_pc_addr = gum_memory_allocate_near( + &spec, sizeof(guint64), 0x1000, GUM_PAGE_READ | GUM_PAGE_WRITE); + *instrument_previous_pc_addr = instrument_hash_zero; + FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr); + FVERBOSE("code_addr: %p", cw->code); + + } instrument_coverage_suppress_init(); @@ -462,7 +473,7 @@ void instrument_coverage_optimize(const cs_insn * instr, *((guint32 *)&code.bytes[curr_loc_shr_1_offset]) = (guint32)(area_offset_ror); gssize prev_loc_value = - GPOINTER_TO_SIZE(&instrument_previous_pc) - + GPOINTER_TO_SIZE(instrument_previous_pc_addr) - (code_addr + offsetof(afl_log_code, code.mov_prev_loc_curr_loc_shr1) + sizeof(code.code.mov_prev_loc_curr_loc_shr1)); gssize prev_loc_value_offset = @@ -478,7 +489,7 @@ void instrument_coverage_optimize(const cs_insn * instr, *((gint *)&code.bytes[prev_loc_value_offset]) = (gint)prev_loc_value; gssize prev_loc_value2 = - GPOINTER_TO_SIZE(&instrument_previous_pc) - + GPOINTER_TO_SIZE(instrument_previous_pc_addr) - (code_addr + offsetof(afl_log_code, code.mov_eax_prev_loc) + sizeof(code.code.mov_eax_prev_loc)); gssize prev_loc_value_offset2 = diff --git a/frida_mode/src/instrument/instrument_x86.c b/frida_mode/src/instrument/instrument_x86.c index ad837e2d..c4e93324 100644 --- a/frida_mode/src/instrument/instrument_x86.c +++ b/frida_mode/src/instrument/instrument_x86.c @@ -153,6 +153,19 @@ void instrument_coverage_optimize(const cs_insn * instr, gsize map_size_pow2; gsize area_offset_ror; + if (instrument_previous_pc_addr == NULL) { + + GumAddressSpec spec = {.near_address = cw->code, + .max_distance = 1ULL << 30}; + + instrument_previous_pc_addr = gum_memory_allocate_near( + &spec, sizeof(guint64), 0x1000, GUM_PAGE_READ | GUM_PAGE_WRITE); + *instrument_previous_pc_addr = instrument_hash_zero; + FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr); + FVERBOSE("code_addr: %p", cw->code); + + } + code.code = template; instrument_coverage_suppress_init(); @@ -170,7 +183,7 @@ void instrument_coverage_optimize(const cs_insn * instr, sizeof(code.code.mov_eax_prev_loc) - sizeof(gint); *((gint *)&code.bytes[prev_loc_value_offset2]) = - (gint)GPOINTER_TO_SIZE(&instrument_previous_pc); + (gint)GPOINTER_TO_SIZE(instrument_previous_pc_addr); gssize curr_loc_shr_1_offset = offsetof(afl_log_code, code.mov_prev_loc_curr_loc_shr1) + @@ -187,7 +200,7 @@ void instrument_coverage_optimize(const cs_insn * instr, sizeof(guint32); *((gint *)&code.bytes[prev_loc_value_offset]) = - (gint)GPOINTER_TO_SIZE(&instrument_previous_pc); + (gint)GPOINTER_TO_SIZE(instrument_previous_pc_addr); gssize xor_curr_loc_offset = offsetof(afl_log_code, code.xor_eax_curr_loc) + sizeof(code.code.xor_eax_curr_loc) - diff --git a/frida_mode/src/persistent/persistent_arm64.c b/frida_mode/src/persistent/persistent_arm64.c index 48f29bb0..16ecf39c 100644 --- a/frida_mode/src/persistent/persistent_arm64.c +++ b/frida_mode/src/persistent/persistent_arm64.c @@ -236,7 +236,13 @@ static void instrument_exit(GumArm64Writer *cw) { static int instrument_afl_persistent_loop_func(void) { int ret = __afl_persistent_loop(persistent_count); - instrument_previous_pc = instrument_hash_zero; + if (instrument_previous_pc_addr == NULL) { + + FATAL("instrument_previous_pc_addr uninitialized"); + + } + + *instrument_previous_pc_addr = instrument_hash_zero; return ret; } diff --git a/frida_mode/src/persistent/persistent_x64.c b/frida_mode/src/persistent/persistent_x64.c index 13d6a090..56141787 100644 --- a/frida_mode/src/persistent/persistent_x64.c +++ b/frida_mode/src/persistent/persistent_x64.c @@ -173,7 +173,13 @@ static void instrument_exit(GumX86Writer *cw) { static int instrument_afl_persistent_loop_func(void) { int ret = __afl_persistent_loop(persistent_count); - instrument_previous_pc = instrument_hash_zero; + if (instrument_previous_pc_addr == NULL) { + + FATAL("instrument_previous_pc_addr uninitialized"); + + } + + *instrument_previous_pc_addr = instrument_hash_zero; return ret; } diff --git a/frida_mode/src/persistent/persistent_x86.c b/frida_mode/src/persistent/persistent_x86.c index 3fe5891c..76c25334 100644 --- a/frida_mode/src/persistent/persistent_x86.c +++ b/frida_mode/src/persistent/persistent_x86.c @@ -130,7 +130,13 @@ static void instrument_exit(GumX86Writer *cw) { static int instrument_afl_persistent_loop_func(void) { int ret = __afl_persistent_loop(persistent_count); - instrument_previous_pc = instrument_hash_zero; + if (instrument_previous_pc_addr == NULL) { + + FATAL("instrument_previous_pc_addr uninitialized"); + + } + + *instrument_previous_pc_addr = instrument_hash_zero; return ret; } diff --git a/frida_mode/test/libxslt/GNUmakefile b/frida_mode/test/libxslt/GNUmakefile new file mode 100644 index 00000000..655e652b --- /dev/null +++ b/frida_mode/test/libxslt/GNUmakefile @@ -0,0 +1,177 @@ +PWD:=$(shell pwd)/ +ROOT:=$(PWD)../../../ +BUILD_DIR:=$(PWD)build/ + +AFLPP_FRIDA_DRIVER_HOOK_OBJ=$(ROOT)frida_mode/build/frida_hook.so +AFLPP_QEMU_DRIVER_HOOK_OBJ=$(ROOT)frida_mode/build/qemu_hook.so + +LIBFUZZER_LIB:=/usr/lib/llvm-12/lib/libFuzzer.a + +LIBXSLT_GIT_REPO:=https://gitlab.gnome.org/GNOME/libxslt.git +LIBXSLT_DIR:=$(BUILD_DIR)libxslt/ +LIBXSLT_LIB:=$(LIBXSLT_DIR)libxslt/.libs/libxslt.a + +LIBZXML2_GIT_REPO:=https://gitlab.gnome.org/GNOME/libxml2.git +LIBXML2_DIR:=$(BUILD_DIR)libxml2/ +LIBXML2_LIB:=$(LIBXML2_DIR).libs/libxml2.a + +TEST_BIN:=$(BUILD_DIR)test +XPATH_XML:=$(BUILD_DIR)xpath.xml + +ifeq "$(shell uname)" "Darwin" +TEST_BIN_LDFLAGS:=-undefined dynamic_lookup -Wl,-no_pie +endif + +TEST_DATA_DIR:=$(BUILD_DIR)in/ +TEST_DATA_SRC:=$(LIBXSLT_DIR)tests/testdata/fuzz_corpus/ +DUMMY_DATA_FILE:=$(BUILD_DIR)default_seed + +FRIDA_OUT:=$(BUILD_DIR)frida-out +QEMU_OUT:=$(BUILD_DIR)qemu-out + +ifndef ARCH + +ARCH=$(shell uname -m) +ifeq "$(ARCH)" "aarch64" + ARCH:=arm64 +endif + +ifeq "$(ARCH)" "i686" + ARCH:=x86 +endif +endif + +ADDR_BIN:=$(ROOT)frida_mode/build/addr +GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh + +AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN)) +AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR)) + +ifeq "$(ARCH)" "arm64" + AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x5500000000) +endif + +ifeq "$(ARCH)" "x86_64" + AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000) +endif + +ifeq "$(ARCH)" "x86" + AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000) +endif + +.PHONY: all clean frida hook + +all: $(TEST_BIN) + make -C $(ROOT)frida_mode/ + +32: + CXXFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all + +$(BUILD_DIR): + mkdir -p $@ + +########## LIBXML2 ####### + +$(LIBXML2_DIR): | $(BUILD_DIR) + git clone --depth 1 $(LIBZXML2_GIT_REPO) $@ + +$(LIBXML2_LIB): | $(LIBXML2_DIR) + cd $(LIBXML2_DIR) && ./autogen.sh \ + --disable-shared \ + --without-c14n \ + --without-legacy \ + --without-push \ + --without-python \ + --without-reader \ + --without-regexps \ + --without-sax1 \ + --without-schemas \ + --without-schematron \ + --without-valid \ + --without-writer \ + --without-zlib \ + --without-lzma + cd $(LIBXML2_DIR) && make -j$(nproc) V=1 + +libxml2: $(LIBXML2_LIB) + +########## LIBZXSLT ####### + +$(LIBXSLT_DIR): | $(BUILD_DIR) + git clone --depth 1 $(LIBXSLT_GIT_REPO) $@ + +$(LIBXSLT_LIB): | $(LIBXSLT_DIR) $(LIBXML2_DIR) + cd $(LIBXSLT_DIR) && ./autogen.sh \ + --with-libxml-src=../libxml2 \ + --disable-shared \ + --without-python \ + --with-crypto \ + --without-debug \ + --without-debugger \ + --without-profiler + cd $(LIBXSLT_DIR) && make -j$(nproc) V=1 + +libxslt: $(LIBXSLT_LIB) + +$(TEST_BIN): $(LIBXSLT_LIB) $(LIBXML2_LIB) + clang \ + -o $@ \ + -fsanitize=fuzzer \ + -I $(LIBXSLT_DIR) \ + -I $(LIBXML2_DIR)include \ + $(LIBXSLT_DIR)tests/fuzz/xpath.c \ + $(LIBXSLT_DIR)tests/fuzz/fuzz.c \ + $(LIBXSLT_DIR)libxslt/.libs/libxslt.a \ + $(LIBXSLT_DIR)libexslt/.libs/libexslt.a \ + $(LIBXML2_LIB) \ + -lgcrypt + +test: $(TEST_BIN) + + +########## DUMMY ####### + +$(DUMMY_DATA_FILE): | $(TEST_DATA_DIR) + dd if=/dev/zero bs=1048576 count=1 of=$@ + +###### TEST DATA ####### + +$(TEST_DATA_DIR): | $(LIBXSLT_DIR) $(BUILD_DIR) + cp -av $(LIBXSLT_DIR)tests/fuzz/seed/* $@ + +$(XPATH_XML): | $(LIBXSLT_DIR) + cp $(LIBXSLT_DIR)tests/fuzz/xpath.xml $@ + + +clean: + rm -rf $(BUILD_DIR) + +frida: $(TEST_BIN) $(AFLPP_FRIDA_DRIVER_HOOK_OBJ) $(TEST_DATA_FILE) $(DUMMY_DATA_FILE) $(XPATH_XML) + AFL_FRIDA_PERSISTENT_CNT=1000000 \ + AFL_FRIDA_PERSISTENT_HOOK=$(AFLPP_FRIDA_DRIVER_HOOK_OBJ) \ + AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \ + AFL_ENTRYPOINT=$(AFL_FRIDA_PERSISTENT_ADDR) \ + $(ROOT)afl-fuzz \ + -i $(TEST_DATA_DIR) \ + -o $(FRIDA_OUT) \ + -m none \ + -d \ + -O \ + -V 30 \ + -- \ + $(TEST_BIN) $(DUMMY_DATA_FILE) + +qemu: $(TEST_BIN) $(AFLPP_QEMU_DRIVER_HOOK_OBJ) $(TEST_DATA_FILE) $(DUMMY_DATA_FILE) $(XPATH_XML) + AFL_QEMU_PERSISTENT_CNT=1000000 \ + AFL_QEMU_PERSISTENT_HOOK=$(AFLPP_QEMU_DRIVER_HOOK_OBJ) \ + AFL_QEMU_PERSISTENT_ADDR=$(AFL_QEMU_PERSISTENT_ADDR) \ + AFL_ENTRYPOINT=$(AFL_QEMU_PERSISTENT_ADDR) \ + $(ROOT)afl-fuzz \ + -i $(TEST_DATA_DIR) \ + -o $(QEMU_OUT) \ + -m none \ + -d \ + -Q \ + -V 30 \ + -- \ + $(TEST_BIN) $(DUMMY_DATA_FILE) diff --git a/frida_mode/test/libxslt/Makefile b/frida_mode/test/libxslt/Makefile new file mode 100644 index 00000000..07b139e9 --- /dev/null +++ b/frida_mode/test/libxslt/Makefile @@ -0,0 +1,13 @@ +all: + @echo trying to use GNU make... + @gmake all || echo please install GNUmake + +32: + @echo trying to use GNU make... + @gmake 32 || echo please install GNUmake + +clean: + @gmake clean + +frida: + @gmake frida |