diff options
Diffstat (limited to 'frida_mode')
-rw-r--r-- | frida_mode/src/instrument/instrument_x64.c | 222 | ||||
-rw-r--r-- | frida_mode/test/libxml/GNUmakefile | 172 | ||||
-rw-r--r-- | frida_mode/test/libxml/Makefile | 13 | ||||
-rwxr-xr-x | frida_mode/test/libxml/get_symbol_addr.py | 36 |
4 files changed, 387 insertions, 56 deletions
diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c index 41162f2a..b51cb697 100644 --- a/frida_mode/src/instrument/instrument_x64.c +++ b/frida_mode/src/instrument/instrument_x64.c @@ -45,7 +45,9 @@ static gboolean instrument_coverage_in_range(gssize offset) { } - #pragma pack(push, 1) + #ifdef __APPLE__ + #pragma pack(push, 1) + typedef struct { // cur_location = (block_address >> 4) ^ (block_address << 8); @@ -58,7 +60,7 @@ typedef struct { // mov QWORD PTR [rsp-0x90],rbx // mov eax,DWORD PTR [rip+0x333d5a] # 0x7ffff6ff2740 // mov DWORD PTR [rip+0x333d3c],0x9fbb # 0x7ffff6ff2740 - // xor eax,0x103f77 + // lea rax,[rip + 0x103f77] // mov bl,BYTE PTR [rax] // add bl,0x1 // adc bl,0x0 @@ -76,7 +78,7 @@ typedef struct { uint8_t mov_eax_prev_loc[6]; uint8_t mov_prev_loc_curr_loc_shr1[10]; - uint8_t xor_eax_curr_loc[5]; + uint8_t leax_eax_curr_loc[7]; uint8_t mov_rbx_ptr_rax[2]; uint8_t add_bl_1[3]; @@ -90,14 +92,81 @@ typedef struct { } afl_log_code_asm_t; - #pragma pack(pop) + #pragma pack(pop) -typedef union { +static const afl_log_code_asm_t template = + { - afl_log_code_asm_t code; - uint8_t bytes[0]; + .mov_rax_rsp_88 = {0x48, 0x89, 0x84, 0x24, 0x78, 0xFF, 0xFF, 0xFF}, + .lahf = 0x9f, + .mov_rax_rsp_90 = {0x48, 0x89, 0x84, 0x24, 0x70, 0xFF, 0xFF, 0xFF}, + .mov_rbx_rsp_98 = {0x48, 0x89, 0x9C, 0x24, 0x68, 0xFF, 0xFF, 0xFF}, -} afl_log_code; + .mov_eax_prev_loc = {0x8b, 0x05}, + .mov_prev_loc_curr_loc_shr1 = {0xc7, 0x05}, + + .leax_eax_curr_loc = {0x48, 0x8d, 0x05}, + .mov_rbx_ptr_rax = {0x8a, 0x18}, + .add_bl_1 = {0x80, 0xc3, 0x01}, + .adc_bl_0 = {0x80, 0xd3, 0x00}, + .mov_ptr_rax_rbx = {0x88, 0x18}, + + .mov_rsp_98_rbx = {0x48, 0x8B, 0x9C, 0x24, 0x68, 0xFF, 0xFF, 0xFF}, + .mov_rsp_90_rax = {0x48, 0x8B, 0x84, 0x24, 0x70, 0xFF, 0xFF, 0xFF}, + .sahf = 0x9e, + .mov_rsp_88_rax = {0x48, 0x8B, 0x84, 0x24, 0x78, 0xFF, 0xFF, 0xFF}, + +} + +; + + #else + #pragma pack(push, 1) +typedef struct { + + // cur_location = (block_address >> 4) ^ (block_address << 8); + // shared_mem[cur_location ^ prev_location]++; + // prev_location = cur_location >> 1; + + // mov QWORD PTR [rsp-0x80],rax + // lahf + // mov QWORD PTR [rsp-0x88],rax + // mov QWORD PTR [rsp-0x90],rbx + // mov eax,DWORD PTR [rip+0x333d5a] # 0x7ffff6ff2740 + // mov DWORD PTR [rip+0x333d3c],0x9fbb # 0x7ffff6ff2740 + // xor eax,0x103f77 + // mov bl,BYTE PTR [rax] + // add bl,0x1 + // adc bl,0x0 + // mov BYTE PTR [rax],bl + // mov rbx,QWORD PTR [rsp-0x90] + // mov rax,QWORD PTR [rsp-0x88] + // sahf + // mov rax,QWORD PTR [rsp-0x80] + + uint8_t mov_rax_rsp_88[8]; + uint8_t lahf; + uint8_t mov_rax_rsp_90[8]; + uint8_t mov_rbx_rsp_98[8]; + + uint8_t mov_eax_prev_loc[6]; + uint8_t mov_prev_loc_curr_loc_shr1[10]; + + uint8_t xor_eax_curr_loc[5]; + + uint8_t mov_rbx_ptr_rax[2]; + uint8_t add_bl_1[3]; + uint8_t adc_bl_0[3]; + uint8_t mov_ptr_rax_rbx[2]; + + uint8_t mov_rsp_98_rbx[8]; + uint8_t mov_rsp_90_rax[8]; + uint8_t sahf; + uint8_t mov_rsp_88_rax[8]; + +} afl_log_code_asm_t; + + #pragma pack(pop) static const afl_log_code_asm_t template = { @@ -124,6 +193,22 @@ static const afl_log_code_asm_t template = } ; + #endif + +typedef union { + + afl_log_code_asm_t code; + uint8_t bytes[0]; + +} afl_log_code; + + #ifdef __APPLE__ + +void instrument_coverage_optimize_init(void) { + +} + + #else static gboolean instrument_coverage_find_low(const GumRangeDetails *details, gpointer user_data) { @@ -181,10 +266,10 @@ static void instrument_coverage_optimize_map_mmap(char * shm_file_path, __afl_area_ptr = NULL; - #if !defined(__ANDROID__) + #if !defined(__ANDROID__) shm_fd = shm_open(shm_file_path, O_RDWR, DEFAULT_PERMISSION); if (shm_fd == -1) { FATAL("shm_open() failed\n"); } - #else + #else shm_fd = open("/dev/ashmem", O_RDWR); if (shm_fd == -1) { FATAL("open() failed\n"); } if (ioctl(shm_fd, ASHMEM_SET_NAME, shm_file_path) == -1) { @@ -199,7 +284,7 @@ static void instrument_coverage_optimize_map_mmap(char * shm_file_path, } - #endif + #endif __afl_area_ptr = mmap(address, __afl_map_size, PROT_READ | PROT_WRITE, MAP_FIXED_NOREPLACE | MAP_SHARED, shm_fd, 0); @@ -231,51 +316,6 @@ static void instrument_coverage_optimize_map_shm(guint64 shm_env_val, } -static void instrument_coverage_switch(GumStalkerObserver *self, - gpointer start_address, - const cs_insn * from_insn, - gpointer * target) { - - UNUSED_PARAMETER(self); - UNUSED_PARAMETER(start_address); - - cs_x86 * x86; - cs_x86_op *op; - if (from_insn == NULL) { return; } - - x86 = &from_insn->detail->x86; - op = x86->operands; - - if (!g_hash_table_contains(coverage_blocks, GSIZE_TO_POINTER(*target))) { - - return; - - } - - switch (from_insn->id) { - - case X86_INS_CALL: - case X86_INS_JMP: - if (x86->op_count != 1) { - - FATAL("Unexpected operand count: %d", x86->op_count); - - } - - if (op[0].type != X86_OP_IMM) { return; } - - break; - case X86_INS_RET: - break; - default: - return; - - } - - *target = (guint8 *)*target + sizeof(afl_log_code); - -} - void instrument_coverage_optimize_init(void) { gpointer low_address = NULL; @@ -324,6 +364,53 @@ void instrument_coverage_optimize_init(void) { } + #endif + +static void instrument_coverage_switch(GumStalkerObserver *self, + gpointer start_address, + const cs_insn * from_insn, + gpointer * target) { + + UNUSED_PARAMETER(self); + UNUSED_PARAMETER(start_address); + + cs_x86 * x86; + cs_x86_op *op; + if (from_insn == NULL) { return; } + + x86 = &from_insn->detail->x86; + op = x86->operands; + + if (!g_hash_table_contains(coverage_blocks, GSIZE_TO_POINTER(*target))) { + + return; + + } + + switch (from_insn->id) { + + case X86_INS_CALL: + case X86_INS_JMP: + if (x86->op_count != 1) { + + FATAL("Unexpected operand count: %d", x86->op_count); + + } + + if (op[0].type != X86_OP_IMM) { return; } + + break; + case X86_INS_RET: + break; + default: + return; + + } + + *target = (guint8 *)*target + sizeof(afl_log_code); + +} + static void instrument_coverage_suppress_init(void) { static gboolean initialized = false; @@ -405,12 +492,35 @@ void instrument_coverage_optimize(const cs_insn * instr, *((gint *)&code.bytes[prev_loc_value_offset2]) = (gint)prev_loc_value2; + #ifdef __APPLE__ + + gssize xor_curr_loc_offset = offsetof(afl_log_code, code.leax_eax_curr_loc) + + sizeof(code.code.leax_eax_curr_loc) - + sizeof(guint32); + + gssize xor_curr_loc_value = + ((GPOINTER_TO_SIZE(__afl_area_ptr) | area_offset) - + (code_addr + offsetof(afl_log_code, code.mov_eax_prev_loc) + + sizeof(code.code.mov_eax_prev_loc))); + + if (!instrument_coverage_in_range(xor_curr_loc_value)) { + + FATAL("Patch out of range (xor_curr_loc_value): 0x%016lX", + xor_curr_loc_value); + + } + + *((guint32 *)&code.bytes[xor_curr_loc_offset]) = xor_curr_loc_value; + + #else + gssize xor_curr_loc_offset = offsetof(afl_log_code, code.xor_eax_curr_loc) + sizeof(code.code.xor_eax_curr_loc) - sizeof(guint32); *((guint32 *)&code.bytes[xor_curr_loc_offset]) = (guint32)(GPOINTER_TO_SIZE(__afl_area_ptr) | area_offset); + #endif gum_x86_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code)); diff --git a/frida_mode/test/libxml/GNUmakefile b/frida_mode/test/libxml/GNUmakefile new file mode 100644 index 00000000..1d675187 --- /dev/null +++ b/frida_mode/test/libxml/GNUmakefile @@ -0,0 +1,172 @@ +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 + +LIBXML_GIT_REPO:=https://gitlab.gnome.org/GNOME/libxml2.git +LIBXML_DIR:=$(BUILD_DIR)libxml/ +LIBXML_BIN:=$(LIBXML_DIR).libs/libxml2.a + +TARGET_URL:=https://raw.githubusercontent.com/google/fuzzbench/master/benchmarks/libxml2-v2.9.2/target.cc +TARGET_SRC:=$(BUILD_DIR)target.cc +TARGET_OBJ:=$(BUILD_DIR)target.o + +HARNESS_URL:="https://raw.githubusercontent.com/llvm/llvm-project/main/compiler-rt/lib/fuzzer/standalone/StandaloneFuzzTargetMain.c" +HARNESS_SRC:=$(BUILD_DIR)StandaloneFuzzTargetMain.c +HARNESS_OBJ:=$(BUILD_DIR)StandaloneFuzzTargetMain.o + +TEST_BIN:=$(BUILD_DIR)test + +ifeq "$(shell uname)" "Darwin" +TEST_BIN_LDFLAGS:=-undefined dynamic_lookup -Wl,-no_pie +endif + +TEST_DATA_DIR:=$(BUILD_DIR)in/ +TEST_DATA_FILE:=$(TEST_DATA_DIR)default_seed +DUMMY_DATA_FILE:=$(BUILD_DIR)dummy.dat + +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 + +GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh + +AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000) + +ifeq "$(ARCH)" "aarch64" + AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x0000aaaaaaaaa000) +endif + +ifeq "$(ARCH)" "x86_64" + AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x0000555555554000) +endif + +ifeq "$(ARCH)" "x86" + AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x56555000) +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 $@ + +########## LIBXML ####### + +$(LIBXML_DIR): | $(BUILD_DIR) + git clone --depth 1 $(LIBXML_GIT_REPO) $@ + +$(LIBXML_BIN): | $(LIBXML_DIR) + cd $(LIBXML_DIR) && git fetch --tags + cd $(LIBXML_DIR) && git checkout -f v2.9.2 + cd $(LIBXML_DIR) && ./autogen.sh + cd $(LIBXML_DIR) && CCLD="$CXX $CXXFLAGS" ./configure --without-python --with-threads=no \ + --with-zlib=no --with-lzma=no + cd $(LIBXML_DIR) && make + +libxml: $(LIBXML_BIN) + +########## TARGET ####### + +$(TARGET_SRC): + wget -O $@ $(TARGET_URL) + +$(TARGET_OBJ): $(TARGET_SRC) $(LIBXML_BIN) + $(CXX) \ + $(CXXFLAGS) \ + -std=c++11 \ + -I $(LIBXML_DIR)include \ + -c $< \ + -o $@ + +target: $(TARGET_OBJ) + + +######### HARNESS ######## +$(HARNESS_SRC): | $(BUILD_DIR) + wget -O $@ $(HARNESS_URL) + +$(HARNESS_OBJ): $(HARNESS_SRC) + $(CC) $(CXXFLAGS) $(LDFLAGS) -o $@ -c $< + +harness: $(HARNESS_OBJ) + +######### TEST ######## + +$(TEST_BIN): $(HARNESS_OBJ) $(TARGET_OBJ) $(LIBXML_BIN) + $(CXX) \ + $(CFLAGS) \ + -o $@ \ + $(HARNESS_OBJ) \ + $(TARGET_OBJ) \ + $(LIBXML_BIN) \ + $(LDFLAGS) \ + $(TEST_BIN_LDFLAGS) \ + +test: $(TEST_BIN) + +########## DUMMY ####### + +$(DUMMY_DATA_FILE): | $(BUILD_DIR) + dd if=/dev/zero bs=1048576 count=1 of=$@ + +###### TEST DATA ####### + +$(TEST_DATA_DIR): | $(BUILD_DIR) + mkdir -p $@ + +$(TEST_DATA_FILE): | $(TEST_DATA_DIR) + dd if=/dev/zero bs=1048576 count=1 of=$@ + +###### ####### + +clean: + rm -rf $(BUILD_DIR) + +frida: $(TEST_BIN) $(AFLPP_FRIDA_DRIVER_HOOK_OBJ) $(TEST_DATA_FILE) $(DUMMY_DATA_FILE) + 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) + 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/libxml/Makefile b/frida_mode/test/libxml/Makefile new file mode 100644 index 00000000..07b139e9 --- /dev/null +++ b/frida_mode/test/libxml/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 diff --git a/frida_mode/test/libxml/get_symbol_addr.py b/frida_mode/test/libxml/get_symbol_addr.py new file mode 100755 index 00000000..1c46e010 --- /dev/null +++ b/frida_mode/test/libxml/get_symbol_addr.py @@ -0,0 +1,36 @@ +#!/usr/bin/python3 +import argparse +from elftools.elf.elffile import ELFFile + +def process_file(file, symbol, base): + with open(file, 'rb') as f: + elf = ELFFile(f) + symtab = elf.get_section_by_name('.symtab') + mains = symtab.get_symbol_by_name(symbol) + if len(mains) != 1: + print ("Failed to find main") + return 1 + + main_addr = mains[0]['st_value'] + main = base + main_addr + print ("0x%016x" % main) + return 0 + +def hex_value(x): + return int(x, 16) + +def main(): + parser = argparse.ArgumentParser(description='Process some integers.') + parser.add_argument('-f', '--file', dest='file', type=str, + help='elf file name', required=True) + parser.add_argument('-s', '--symbol', dest='symbol', type=str, + help='symbol name', required=True) + parser.add_argument('-b', '--base', dest='base', type=hex_value, + help='elf base address', required=True) + + args = parser.parse_args() + return process_file (args.file, args.symbol, args.base) + +if __name__ == "__main__": + ret = main() + exit(ret) |