about summary refs log tree commit diff
path: root/frida_mode
diff options
context:
space:
mode:
Diffstat (limited to 'frida_mode')
-rw-r--r--frida_mode/src/instrument/instrument_x64.c222
-rw-r--r--frida_mode/test/libxml/GNUmakefile172
-rw-r--r--frida_mode/test/libxml/Makefile13
-rwxr-xr-xfrida_mode/test/libxml/get_symbol_addr.py36
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)