From dd8ad4dfa35c8b11ebcc6005f44855db02fefb74 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 18 Feb 2022 07:55:26 +0000 Subject: Changes to simplify coverage code --- frida_mode/src/instrument/instrument_x64.c | 344 +++++------------------------ 1 file changed, 59 insertions(+), 285 deletions(-) (limited to 'frida_mode/src') diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c index fb84d6d2..c28285ff 100644 --- a/frida_mode/src/instrument/instrument_x64.c +++ b/frida_mode/src/instrument/instrument_x64.c @@ -23,14 +23,6 @@ #if defined(__x86_64__) - #ifndef MAP_FIXED_NOREPLACE - #ifdef MAP_EXCL - #define MAP_FIXED_NOREPLACE MAP_EXCL | MAP_FIXED - #else - #define MAP_FIXED_NOREPLACE MAP_FIXED - #endif - #endif - static GHashTable *coverage_blocks = NULL; gboolean instrument_is_coverage_optimize_supported(void) { @@ -45,8 +37,7 @@ static gboolean instrument_coverage_in_range(gssize offset) { } - #ifdef __APPLE__ - #pragma pack(push, 1) + #pragma pack(push, 1) typedef struct { @@ -54,95 +45,28 @@ typedef struct { // 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 - // lea rax,[rip + 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 leax_eax_curr_loc[7]; - - 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 = - { + // mov QWORD PTR [rsp-0x88],rax + // lahf + // mov QWORD PTR [rsp-0x90],rax + // mov QWORD PTR [rsp-0x98],rbx - .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}, - - .mov_eax_prev_loc = {0x8b, 0x05}, - .mov_prev_loc_curr_loc_shr1 = {0xc7, 0x05}, + // mov eax,DWORD PTR [rip+0x1312334] + // xor eax,0x3f77 - .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}, + // lea rbx,[rip+0x132338] + // add rax,rbx - .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}, + // mov bl,BYTE PTR [rax] + // add bl,0x1 + // adc bl,0x0 + // mov BYTE PTR [rax],bl -} + // mov rbx,QWORD PTR [rsp-0x98] + // mov rax,QWORD PTR [rsp-0x90] + // sahf + // mov rax,QWORD PTR [rsp-0x88] -; - - #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] + // mov DWORD PTR [rip+0x13122f8],0x9fbb uint8_t mov_rax_rsp_88[8]; uint8_t lahf; @@ -150,10 +74,11 @@ typedef struct { 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 lea_rbx_area_ptr[7]; + uint8_t add_rax_rbx[3]; + uint8_t mov_rbx_ptr_rax[2]; uint8_t add_bl_1[3]; uint8_t adc_bl_0[3]; @@ -164,9 +89,11 @@ typedef struct { uint8_t sahf; uint8_t mov_rsp_88_rax[8]; + uint8_t mov_prev_loc_curr_loc_shr1[10]; + } afl_log_code_asm_t; - #pragma pack(pop) + #pragma pack(pop) static const afl_log_code_asm_t template = { @@ -177,9 +104,10 @@ static const afl_log_code_asm_t template = .mov_rbx_rsp_98 = {0x48, 0x89, 0x9C, 0x24, 0x68, 0xFF, 0xFF, 0xFF}, .mov_eax_prev_loc = {0x8b, 0x05}, - .mov_prev_loc_curr_loc_shr1 = {0xc7, 0x05}, - .xor_eax_curr_loc = {0x35}, + .lea_rbx_area_ptr = {0x48, 0x8d, 0x1d}, + .add_rax_rbx = {0x48, 0x01, 0xd8}, + .mov_rbx_ptr_rax = {0x8a, 0x18}, .add_bl_1 = {0x80, 0xc3, 0x01}, .adc_bl_0 = {0x80, 0xd3, 0x00}, @@ -190,10 +118,11 @@ static const afl_log_code_asm_t template = .sahf = 0x9e, .mov_rsp_88_rax = {0x48, 0x8B, 0x84, 0x24, 0x78, 0xFF, 0xFF, 0xFF}, + .mov_prev_loc_curr_loc_shr1 = {0xc7, 0x05}, + } ; - #endif typedef union { @@ -202,171 +131,12 @@ typedef union { } afl_log_code; - #ifdef __APPLE__ - -void instrument_coverage_optimize_init(void) { - -} - - #else - -static gboolean instrument_coverage_find_low(const GumRangeDetails *details, - gpointer user_data) { - - static GumAddress last_limit = (64ULL << 10); - gpointer * address = (gpointer *)user_data; - - last_limit = GUM_ALIGN_SIZE(last_limit, __afl_map_size); - - if ((details->range->base_address - last_limit) > __afl_map_size) { - - *address = GSIZE_TO_POINTER(last_limit); - return FALSE; - - } - - if (details->range->base_address > ((2ULL << 30) - __afl_map_size)) { - - return FALSE; - - } - - /* - * Align our buffer on a 64k boundary so that the low 16-bits of the address - * are zero, then we can just XOR the base address in, when we XOR with the - * current block ID. - */ - last_limit = GUM_ALIGN_SIZE( - details->range->base_address + details->range->size, __afl_map_size); - return TRUE; - -} - -static void instrument_coverage_optimize_map_mmap_anon(gpointer address) { - - __afl_area_ptr = - mmap(address, __afl_map_size, PROT_READ | PROT_WRITE, - MAP_FIXED_NOREPLACE | MAP_SHARED | MAP_ANONYMOUS, -1, 0); - if (__afl_area_ptr != address) { - - FATAL("Failed to map mmap __afl_area_ptr: %d", errno); - - } - -} - -static void instrument_coverage_optimize_map_mmap(char * shm_file_path, - gpointer address) { - - int shm_fd = -1; - - if (munmap(__afl_area_ptr, __afl_map_size) != 0) { - - FATAL("Failed to unmap previous __afl_area_ptr"); - - } - - __afl_area_ptr = NULL; - - #if !defined(__ANDROID__) - shm_fd = shm_open(shm_file_path, O_RDWR, DEFAULT_PERMISSION); - if (shm_fd == -1) { FATAL("shm_open() failed\n"); } - #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) { - - FATAL("ioctl(ASHMEM_SET_NAME) failed"); - - } - - if (ioctl(shm_fd, ASHMEM_SET_SIZE, __afl_map_size) == -1) { - - FATAL("ioctl(ASHMEM_SET_SIZE) failed"); - - } - - #endif - - __afl_area_ptr = mmap(address, __afl_map_size, PROT_READ | PROT_WRITE, - MAP_FIXED_NOREPLACE | MAP_SHARED, shm_fd, 0); - if (__afl_area_ptr != address) { - - FATAL("Failed to map mmap __afl_area_ptr: %d", errno); - - } - - if (close(shm_fd) != 0) { FATAL("Failed to close shm_fd"); } - -} - -static void instrument_coverage_optimize_map_shm(guint64 shm_env_val, - gpointer address) { - - if (shmdt(__afl_area_ptr) != 0) { - - FATAL("Failed to detach previous __afl_area_ptr"); - - } - - __afl_area_ptr = shmat(shm_env_val, address, 0); - if (__afl_area_ptr != address) { - - FATAL("Failed to map shm __afl_area_ptr: %d", errno); - - } - -} - void instrument_coverage_optimize_init(void) { - gpointer low_address = NULL; - - gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, instrument_coverage_find_low, - &low_address); - - FVERBOSE("Low address: %p", low_address); - - if (low_address == 0 || - GPOINTER_TO_SIZE(low_address) > ((2UL << 30) - __afl_map_size)) { - - FATAL("Invalid low_address: %p", low_address); - - } - - ranges_print_debug_maps(); - - char *shm_env = getenv(SHM_ENV_VAR); - FVERBOSE("SHM_ENV_VAR: %s", shm_env); - - if (shm_env == NULL) { - - FWARNF("SHM_ENV_VAR not set, using anonymous map for debugging purposes"); - - instrument_coverage_optimize_map_mmap_anon(low_address); - - } else { - - guint64 shm_env_val = g_ascii_strtoull(shm_env, NULL, 10); - - if (shm_env_val == 0) { - - instrument_coverage_optimize_map_mmap(shm_env, low_address); - - } else { - - instrument_coverage_optimize_map_shm(shm_env_val, low_address); - - } - - } - FVERBOSE("__afl_area_ptr: %p", __afl_area_ptr); } - #endif - static void instrument_coverage_switch(GumStalkerObserver *self, gpointer start_address, const cs_insn * from_insn, @@ -465,14 +235,7 @@ void instrument_coverage_optimize(const cs_insn * instr, code.code = template; - gssize curr_loc_shr_1_offset = - offsetof(afl_log_code, code.mov_prev_loc_curr_loc_shr1) + - sizeof(code.code.mov_prev_loc_curr_loc_shr1) - sizeof(guint32); - - map_size_pow2 = util_log2(__afl_map_size); - area_offset_ror = util_rotate(area_offset, 1, map_size_pow2); - - *((guint32 *)&code.bytes[curr_loc_shr_1_offset]) = (guint32)(area_offset_ror); + /* mov_prev_loc_curr_loc_shr1 */ gssize prev_loc_value = GPOINTER_TO_SIZE(instrument_previous_pc_addr) - @@ -490,6 +253,8 @@ void instrument_coverage_optimize(const cs_insn * instr, *((gint *)&code.bytes[prev_loc_value_offset]) = (gint)prev_loc_value; + /* mov_eax_prev_loc */ + gssize prev_loc_value2 = GPOINTER_TO_SIZE(instrument_previous_pc_addr) - (code_addr + offsetof(afl_log_code, code.mov_eax_prev_loc) + @@ -505,35 +270,44 @@ void instrument_coverage_optimize(const cs_insn * instr, *((gint *)&code.bytes[prev_loc_value_offset2]) = (gint)prev_loc_value2; - #ifdef __APPLE__ + /* xor_eax_curr_loc */ - gssize xor_curr_loc_offset = offsetof(afl_log_code, code.leax_eax_curr_loc) + - sizeof(code.code.leax_eax_curr_loc) - + gssize xor_curr_loc_offset = offsetof(afl_log_code, code.xor_eax_curr_loc) + + sizeof(code.code.xor_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))); + *((guint32 *)&code.bytes[xor_curr_loc_offset]) = area_offset; - if (!instrument_coverage_in_range(xor_curr_loc_value)) { + /* lea_rbx_area_ptr */ - FATAL("Patch out of range (xor_curr_loc_value): 0x%016lX", - xor_curr_loc_value); + gssize lea_rbx_area_ptr_offset = + offsetof(afl_log_code, code.lea_rbx_area_ptr) + + sizeof(code.code.lea_rbx_area_ptr) - sizeof(guint32); + + gssize lea_rbx_area_ptr_value = + (GPOINTER_TO_SIZE(__afl_area_ptr) - + (code_addr + offsetof(afl_log_code, code.lea_rbx_area_ptr) + + sizeof(code.code.lea_rbx_area_ptr))); + + if (!instrument_coverage_in_range(lea_rbx_area_ptr_value)) { + + FATAL("Patch out of range (lea_rbx_area_ptr_value): 0x%016lX", + lea_rbx_area_ptr_value); } - *((guint32 *)&code.bytes[xor_curr_loc_offset]) = xor_curr_loc_value; + *((guint32 *)&code.bytes[lea_rbx_area_ptr_offset]) = lea_rbx_area_ptr_value; - #else + /* mov_prev_loc_curr_loc_shr1 */ - gssize xor_curr_loc_offset = offsetof(afl_log_code, code.xor_eax_curr_loc) + - sizeof(code.code.xor_eax_curr_loc) - - sizeof(guint32); + gssize curr_loc_shr_1_offset = + offsetof(afl_log_code, code.mov_prev_loc_curr_loc_shr1) + + sizeof(code.code.mov_prev_loc_curr_loc_shr1) - sizeof(guint32); - *((guint32 *)&code.bytes[xor_curr_loc_offset]) = - (guint32)(GPOINTER_TO_SIZE(__afl_area_ptr) | area_offset); - #endif + map_size_pow2 = util_log2(__afl_map_size); + area_offset_ror = util_rotate(area_offset, 1, map_size_pow2); + + *((guint32 *)&code.bytes[curr_loc_shr_1_offset]) = (guint32)(area_offset_ror); gum_x86_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code)); -- cgit 1.4.1 From cb1256499f7e07fd0edf0958d08b958fec63c34c Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 18 Feb 2022 07:55:45 +0000 Subject: Added instrumentation for CMOV instructions --- frida_mode/README.md | 2 + frida_mode/frida.map | 1 + frida_mode/include/instrument.h | 3 + frida_mode/src/instrument/instrument.c | 8 ++ frida_mode/src/instrument/instrument_arm32.c | 9 ++ frida_mode/src/instrument/instrument_arm64.c | 8 ++ frida_mode/src/instrument/instrument_x64.c | 191 +++++++++++++++++++++++---- frida_mode/src/instrument/instrument_x86.c | 8 ++ frida_mode/src/js/api.js | 7 + frida_mode/src/js/js_api.c | 7 + frida_mode/test/cmov/GNUmakefile | 87 ++++++++++++ frida_mode/test/cmov/Makefile | 19 +++ frida_mode/test/cmov/cmov.c | 122 +++++++++++++++++ frida_mode/ts/lib/afl.ts | 12 ++ include/envs.h | 1 + 15 files changed, 457 insertions(+), 28 deletions(-) create mode 100644 frida_mode/test/cmov/GNUmakefile create mode 100644 frida_mode/test/cmov/Makefile create mode 100644 frida_mode/test/cmov/cmov.c (limited to 'frida_mode/src') diff --git a/frida_mode/README.md b/frida_mode/README.md index e5b46baf..bf5cffec 100644 --- a/frida_mode/README.md +++ b/frida_mode/README.md @@ -173,6 +173,8 @@ instances run CMPLOG mode and instrumentation of the binary is less frequent * `AFL_FRIDA_INST_JIT` - Enable the instrumentation of Just-In-Time compiled code. Code is considered to be JIT if the executable segment is not backed by a file. +* `AFL_FRIDA_INST_NO_INSN` - Don't generate instrumentation for conditional + instructions (e.g. `CMOV` instructions on x64). * `AFL_FRIDA_INST_NO_OPTIMIZE` - Don't use optimized inline assembly coverage instrumentation (the default where available). Required to use `AFL_FRIDA_INST_TRACE`. diff --git a/frida_mode/frida.map b/frida_mode/frida.map index d059bdb6..e9afac1b 100644 --- a/frida_mode/frida.map +++ b/frida_mode/frida.map @@ -15,6 +15,7 @@ js_api_set_instrument_debug_file; js_api_set_instrument_jit; js_api_set_instrument_libraries; + js_api_set_instrument_no_instructions; js_api_set_instrument_no_optimize; js_api_set_instrument_seed; js_api_set_instrument_trace; diff --git a/frida_mode/include/instrument.h b/frida_mode/include/instrument.h index abb89c9f..20312a4b 100644 --- a/frida_mode/include/instrument.h +++ b/frida_mode/include/instrument.h @@ -12,6 +12,7 @@ extern gboolean instrument_optimize; extern gboolean instrument_unique; extern guint64 instrument_hash_zero; extern char * instrument_coverage_unstable_filename; +extern gboolean instrument_coverage_insn; extern gboolean instrument_use_fixed_seed; extern guint64 instrument_fixed_seed; @@ -33,6 +34,8 @@ gboolean instrument_is_coverage_optimize_supported(void); void instrument_coverage_optimize_init(void); void instrument_coverage_optimize(const cs_insn * instr, GumStalkerOutput *output); +void instrument_coverage_optimize_insn(const cs_insn * instr, + GumStalkerOutput *output); void instrument_debug_config(void); void instrument_debug_init(void); diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c index 418b35e8..4877f4fb 100644 --- a/frida_mode/src/instrument/instrument.c +++ b/frida_mode/src/instrument/instrument.c @@ -29,6 +29,7 @@ guint64 instrument_hash_seed = 0; gboolean instrument_use_fixed_seed = FALSE; guint64 instrument_fixed_seed = 0; char * instrument_coverage_unstable_filename = NULL; +gboolean instrument_coverage_insn = FALSE; static GumStalkerTransformer *transformer = NULL; @@ -233,6 +234,12 @@ static void instrument_basic_block(GumStalkerIterator *iterator, } + if (instrument_coverage_insn) { + + instrument_coverage_optimize_insn(instr, output); + + } + instrument_debug_instruction(instr->address, instr->size, output); if (likely(!excluded)) { @@ -269,6 +276,7 @@ void instrument_config(void) { instrument_fixed_seed = util_read_num("AFL_FRIDA_INST_SEED", 0); instrument_coverage_unstable_filename = (getenv("AFL_FRIDA_INST_UNSTABLE_COVERAGE_FILE")); + instrument_coverage_insn = (getenv("AFL_FRIDA_INST_NO_INSN") == NULL); instrument_debug_config(); instrument_coverage_config(); diff --git a/frida_mode/src/instrument/instrument_arm32.c b/frida_mode/src/instrument/instrument_arm32.c index 16e8eaab..705faa64 100644 --- a/frida_mode/src/instrument/instrument_arm32.c +++ b/frida_mode/src/instrument/instrument_arm32.c @@ -20,6 +20,15 @@ void instrument_coverage_optimize(const cs_insn * instr, } +void instrument_coverage_optimize_insn(const cs_insn * instr, + GumStalkerOutput *output) { + + UNUSED_PARAMETER(instr); + UNUSED_PARAMETER(output); + FFATAL("Optimized coverage not supported on this architecture"); + +} + void instrument_coverage_optimize_init(void) { FWARNF("Optimized coverage not supported on this architecture"); diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c index 1a704585..4abc0625 100644 --- a/frida_mode/src/instrument/instrument_arm64.c +++ b/frida_mode/src/instrument/instrument_arm64.c @@ -341,6 +341,14 @@ void instrument_coverage_optimize(const cs_insn * instr, } +void instrument_coverage_optimize_insn(const cs_insn * instr, + GumStalkerOutput *output) { + + UNUSED_PARAMETER(instr); + UNUSED_PARAMETER(output); + +} + void instrument_coverage_optimize_init(void) { char *shm_env = getenv(SHM_ENV_VAR); diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c index c28285ff..4b1a2d68 100644 --- a/frida_mode/src/instrument/instrument_x64.c +++ b/frida_mode/src/instrument/instrument_x64.c @@ -23,6 +23,40 @@ #if defined(__x86_64__) +enum jcc_opcodes { + + OPC_JO = 0x70, + OPC_JNO = 0x71, + OPC_JB = 0x72, + OPC_JAE = 0x73, + OPC_JE = 0x74, + OPC_JNE = 0x75, + OPC_JBE = 0x76, + OPC_JA = 0x77, + OPC_JS = 0x78, + OPC_JNS = 0x79, + OPC_JP = 0x7a, + OPC_JNP = 0x7b, + OPC_JL = 0x7c, + OPC_JGE = 0x7d, + OPC_JLE = 0x7e, + OPC_JG = 0x7f, + +}; + +typedef union { + + struct { + + uint8_t opcode; + uint8_t distance; + + }; + + uint8_t bytes[0]; + +} jcc_insn; + static GHashTable *coverage_blocks = NULL; gboolean instrument_is_coverage_optimize_supported(void) { @@ -201,37 +235,15 @@ static void instrument_coverage_suppress_init(void) { } -void instrument_coverage_optimize(const cs_insn * instr, - GumStalkerOutput *output) { +static void instrument_coverage_write(GumAddress address, + GumStalkerOutput *output) { afl_log_code code = {0}; GumX86Writer *cw = output->writer.x86; - guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address)); - 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(); - - // gum_x86_writer_put_breakpoint(cw); - code_addr = cw->pc; - if (!g_hash_table_add(coverage_blocks, GSIZE_TO_POINTER(cw->code))) { - - FATAL("Failed - g_hash_table_add"); - - } + guint64 area_offset = instrument_get_offset_hash(address); + gsize map_size_pow2; + gsize area_offset_ror; + GumAddress code_addr = cw->pc; code.code = template; @@ -313,6 +325,129 @@ void instrument_coverage_optimize(const cs_insn * instr, } +void instrument_coverage_optimize(const cs_insn * instr, + GumStalkerOutput *output) { + + GumX86Writer *cw = output->writer.x86; + guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address)); + 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(); + + if (!g_hash_table_add(coverage_blocks, GSIZE_TO_POINTER(cw->code))) { + + FATAL("Failed - g_hash_table_add"); + + } + + instrument_coverage_write(GUM_ADDRESS(instr->address), output); + +} + +void instrument_coverage_optimize_insn(const cs_insn * instr, + GumStalkerOutput *output) { + + GumX86Writer *cw = output->writer.x86; + jcc_insn taken, not_taken; + + switch (instr->id) { + + case X86_INS_CMOVA: + taken.opcode = OPC_JA; + not_taken.opcode = OPC_JBE; + break; + case X86_INS_CMOVAE: + taken.opcode = OPC_JAE; + not_taken.opcode = OPC_JB; + break; + case X86_INS_CMOVB: + taken.opcode = OPC_JB; + not_taken.opcode = OPC_JAE; + break; + case X86_INS_CMOVBE: + taken.opcode = OPC_JBE; + not_taken.opcode = OPC_JA; + break; + case X86_INS_CMOVE: + taken.opcode = OPC_JE; + not_taken.opcode = OPC_JNE; + break; + case X86_INS_CMOVG: + taken.opcode = OPC_JG; + not_taken.opcode = OPC_JLE; + break; + case X86_INS_CMOVGE: + taken.opcode = OPC_JGE; + not_taken.opcode = OPC_JL; + break; + case X86_INS_CMOVL: + taken.opcode = OPC_JL; + not_taken.opcode = OPC_JGE; + break; + case X86_INS_CMOVLE: + taken.opcode = OPC_JLE; + not_taken.opcode = OPC_JG; + break; + case X86_INS_CMOVNE: + taken.opcode = OPC_JNE; + not_taken.opcode = OPC_JE; + break; + case X86_INS_CMOVNO: + taken.opcode = OPC_JNO; + not_taken.opcode = OPC_JO; + break; + case X86_INS_CMOVNP: + taken.opcode = OPC_JNP; + not_taken.opcode = OPC_JP; + break; + case X86_INS_CMOVNS: + taken.opcode = OPC_JNS; + not_taken.opcode = OPC_JS; + break; + case X86_INS_CMOVO: + taken.opcode = OPC_JO; + not_taken.opcode = OPC_JNO; + break; + case X86_INS_CMOVP: + taken.opcode = OPC_JP; + not_taken.opcode = OPC_JNP; + break; + case X86_INS_CMOVS: + taken.opcode = OPC_JS; + not_taken.opcode = OPC_JNS; + break; + default: + return; + + } + + taken.distance = sizeof(afl_log_code); + not_taken.distance = sizeof(afl_log_code); + + // gum_x86_writer_put_breakpoint(cw); + + gum_x86_writer_put_bytes(cw, taken.bytes, sizeof(jcc_insn)); + instrument_coverage_write(GUM_ADDRESS(instr->address), output); + + gum_x86_writer_put_bytes(cw, not_taken.bytes, sizeof(jcc_insn)); + instrument_coverage_write(GUM_ADDRESS(instr->address + instr->size), output); + + FVERBOSE("Instrument - 0x%016lx: %s %s", instr->address, instr->mnemonic, + instr->op_str); + +} + void instrument_flush(GumStalkerOutput *output) { gum_x86_writer_flush(output->writer.x86); diff --git a/frida_mode/src/instrument/instrument_x86.c b/frida_mode/src/instrument/instrument_x86.c index c4e93324..916cd0e2 100644 --- a/frida_mode/src/instrument/instrument_x86.c +++ b/frida_mode/src/instrument/instrument_x86.c @@ -218,6 +218,14 @@ void instrument_coverage_optimize(const cs_insn * instr, } +void instrument_coverage_optimize_insn(const cs_insn * instr, + GumStalkerOutput *output) { + + UNUSED_PARAMETER(instr); + UNUSED_PARAMETER(output); + +} + void instrument_coverage_optimize_init(void) { } diff --git a/frida_mode/src/js/api.js b/frida_mode/src/js/api.js index 52e9e45c..c2d9a2d4 100644 --- a/frida_mode/src/js/api.js +++ b/frida_mode/src/js/api.js @@ -125,6 +125,12 @@ class Afl { static setInstrumentLibraries() { Afl.jsApiSetInstrumentLibraries(); } + /** + * See `AFL_FRIDA_INST_NO_INSN` + */ + static setInstrumentNoInstructions() { + Afl.jsApiSetInstrumentNoInstructions(); + } /** * See `AFL_FRIDA_INST_NO_OPTIMIZE` */ @@ -299,6 +305,7 @@ Afl.jsApiSetInstrumentCoverageFile = Afl.jsApiGetFunction("js_api_set_instrument Afl.jsApiSetInstrumentDebugFile = Afl.jsApiGetFunction("js_api_set_instrument_debug_file", "void", ["pointer"]); Afl.jsApiSetInstrumentJit = Afl.jsApiGetFunction("js_api_set_instrument_jit", "void", []); Afl.jsApiSetInstrumentLibraries = Afl.jsApiGetFunction("js_api_set_instrument_libraries", "void", []); +Afl.jsApiSetInstrumentNoInstructions = Afl.jsApiGetFunction("js_api_set_instrument_no_instructions", "void", []); Afl.jsApiSetInstrumentNoOptimize = Afl.jsApiGetFunction("js_api_set_instrument_no_optimize", "void", []); Afl.jsApiSetInstrumentSeed = Afl.jsApiGetFunction("js_api_set_instrument_seed", "void", ["uint64"]); Afl.jsApiSetInstrumentTrace = Afl.jsApiGetFunction("js_api_set_instrument_trace", "void", []); diff --git a/frida_mode/src/js/js_api.c b/frida_mode/src/js/js_api.c index 94ec8842..613747b8 100644 --- a/frida_mode/src/js/js_api.c +++ b/frida_mode/src/js/js_api.c @@ -142,6 +142,13 @@ js_api_set_prefetch_backpatch_disable(void) { } +__attribute__((visibility("default"))) void +js_api_set_instrument_no_instructions(void) { + + instrument_coverage_insn = FALSE; + +} + __attribute__((visibility("default"))) void js_api_set_instrument_no_optimize( void) { diff --git a/frida_mode/test/cmov/GNUmakefile b/frida_mode/test/cmov/GNUmakefile new file mode 100644 index 00000000..318b2ad0 --- /dev/null +++ b/frida_mode/test/cmov/GNUmakefile @@ -0,0 +1,87 @@ +PWD:=$(shell pwd)/ +ROOT:=$(PWD)../../../ +BUILD_DIR:=$(PWD)build/ + +TEST_CMOV_SRC:=$(PWD)cmov.c +TEST_CMOV_OBJ:=$(BUILD_DIR)cmov + +TEST_DATA_DIR:=$(BUILD_DIR)in/ +CMP_LOG_INPUT:=$(TEST_DATA_DIR)in +QEMU_OUT:=$(BUILD_DIR)qemu-out +FRIDA_OUT:=$(BUILD_DIR)frida-out + +ADDR_BIN:=$(ROOT)frida_mode/build/addr +GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh + +AFLPP_FRIDA_DRIVER_HOOK_OBJ=$(ROOT)frida_mode/build/frida_hook.so + +AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN)) +AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_CMOV_OBJ) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR)) + +DUMMY_DATA_FILE:=$(BUILD_DIR)dummy.dat + +.PHONY: all 32 clean frida frida_noinst debug format + +all: $(TEST_CMOV_OBJ) + make -C $(ROOT)frida_mode/ + +32: + CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all + +$(BUILD_DIR): + mkdir -p $@ + +$(TEST_DATA_DIR): | $(BUILD_DIR) + mkdir -p $@ + +$(CMP_LOG_INPUT): | $(TEST_DATA_DIR) + echo -n "ABC" > $@ + +$(TEST_CMOV_OBJ): $(TEST_CMOV_SRC) | $(BUILD_DIR) + $(CC) -g $(CFLAGS) $(LDFLAGS) $< -o $@ + +########## DUMMY ####### + +$(DUMMY_DATA_FILE): | $(BUILD_DIR) + dd if=/dev/zero bs=1048576 count=1 of=$@ + +frida: $(TEST_CMOV_OBJ) $(CMP_LOG_INPUT) $(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 \ + -O \ + -i $(TEST_DATA_DIR) \ + -o $(FRIDA_OUT) \ + -Z \ + -t 10000+ \ + -- \ + $(TEST_CMOV_OBJ) $(DUMMY_DATA_FILE) + +frida_noinst: $(TEST_CMOV_OBJ) $(CMP_LOG_INPUT) $(DUMMY_DATA_FILE) + AFL_FRIDA_INST_NO_INSN=1 \ + 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 \ + -O \ + -i $(TEST_DATA_DIR) \ + -o $(FRIDA_OUT) \ + -Z \ + -- \ + $(TEST_CMOV_OBJ) $(DUMMY_DATA_FILE) + +debug: $(TEST_CMOV_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_CMOV_OBJ) $(CMP_LOG_INPUT) + +clean: + rm -rf $(BUILD_DIR) + +format: + cd $(ROOT) && echo $(TEST_CMOV_SRC) | xargs -L1 ./.custom-format.py -i diff --git a/frida_mode/test/cmov/Makefile b/frida_mode/test/cmov/Makefile new file mode 100644 index 00000000..9ef6fc8f --- /dev/null +++ b/frida_mode/test/cmov/Makefile @@ -0,0 +1,19 @@ +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 + +format: + @gmake format + +debug: + @gmake debug diff --git a/frida_mode/test/cmov/cmov.c b/frida_mode/test/cmov/cmov.c new file mode 100644 index 00000000..08c7c132 --- /dev/null +++ b/frida_mode/test/cmov/cmov.c @@ -0,0 +1,122 @@ +#include +#include +#include +#include +#include + +static bool cmov_test(char *x, char *y, size_t len) { + + register char * __rdi __asm__("rdi") = x; + register char * __rsi __asm__("rsi") = y; + register size_t __rcx __asm__("rcx") = len; + + register long __rax __asm__("rax"); + + __asm__ __volatile__( + "mov $0x1, %%rax\n" + "mov $0x0, %%r8\n" + "1:\n" + "mov (%%rsi), %%bl\n" + "mov (%%rdi), %%dl\n" + "cmp %%bl, %%dl\n" + "cmovne %%r8, %%rax\n" + "inc %%rsi\n" + "inc %%rdi\n" + "dec %%rcx\n" + "jnz 1b\n" + : "=r"(__rax) + : "r"(__rdi), "r"(__rsi) + : "r8", "bl", "dl", "memory"); + + return __rax; + +} + +void LLVMFuzzerTestOneInput(char *buf, int len) { + + char match[] = "CBAABC"; + + if (len > sizeof(match)) { return; } + + if (cmov_test(buf, match, sizeof(buf)) != 0) { + + printf("Puzzle solved, congrats!\n"); + abort(); + + } + +} + +int main(int argc, char **argv) { + + char * file; + int fd = -1; + off_t len; + char * buf = NULL; + size_t n_read; + int result = -1; + + if (argc != 2) { return 1; } + + do { + + file = argv[1]; + + dprintf(STDERR_FILENO, "Running: %s\n", file); + + fd = open(file, O_RDONLY); + if (fd < 0) { + + perror("open"); + break; + + } + + len = lseek(fd, 0, SEEK_END); + if (len < 0) { + + perror("lseek (SEEK_END)"); + break; + + } + + if (lseek(fd, 0, SEEK_SET) != 0) { + + perror("lseek (SEEK_SET)"); + break; + + } + + buf = (char *)malloc(len); + if (buf == NULL) { + + perror("malloc"); + break; + + } + + n_read = read(fd, buf, len); + if (n_read != len) { + + perror("read"); + break; + + } + + dprintf(STDERR_FILENO, "Running: %s: (%zd bytes)\n", file, n_read); + + LLVMFuzzerTestOneInput(buf, len); + dprintf(STDERR_FILENO, "Done: %s: (%zd bytes)\n", file, n_read); + + result = 0; + + } while (false); + + if (buf != NULL) { free(buf); } + + if (fd != -1) { close(fd); } + + return result; + +} + diff --git a/frida_mode/ts/lib/afl.ts b/frida_mode/ts/lib/afl.ts index 57d7b5b5..9d31370e 100644 --- a/frida_mode/ts/lib/afl.ts +++ b/frida_mode/ts/lib/afl.ts @@ -149,6 +149,13 @@ class Afl { Afl.jsApiSetInstrumentLibraries(); } + /** + * See `AFL_FRIDA_INST_NO_INSN` + */ + public static setInstrumentNoInstructions(): void { + Afl.jsApiSetInstrumentNoInstructions(); + } + /** * See `AFL_FRIDA_INST_NO_OPTIMIZE` */ @@ -377,6 +384,11 @@ class Afl { "void", []); + private static readonly jsApiSetInstrumentNoInstructions = Afl.jsApiGetFunction( + "js_api_set_instrument_no_instructions", + "void", + []); + private static readonly jsApiSetInstrumentNoOptimize = Afl.jsApiGetFunction( "js_api_set_instrument_no_optimize", "void", diff --git a/include/envs.h b/include/envs.h index f4327d8c..2ab3a387 100644 --- a/include/envs.h +++ b/include/envs.h @@ -60,6 +60,7 @@ static char *afl_environment_variables[] = { "AFL_FRIDA_INST_COVERAGE_FILE", "AFL_FRIDA_INST_DEBUG_FILE", "AFL_FRIDA_INST_JIT", + "AFL_FRIDA_INST_NO_INSN", "AFL_FRIDA_INST_NO_OPTIMIZE", "AFL_FRIDA_INST_NO_PREFETCH", "AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH", -- cgit 1.4.1 From 5f45f380c3d9837a5a8457cf749b27a8afbd3f53 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 18 Feb 2022 08:10:19 +0000 Subject: Changes to default CMOV instrumentation to off --- frida_mode/README.md | 4 ++-- frida_mode/frida.map | 2 +- frida_mode/src/instrument/instrument.c | 4 +++- frida_mode/src/js/api.js | 14 +++++++------- frida_mode/src/js/js_api.c | 6 +++--- frida_mode/src/ranges.c | 2 -- frida_mode/test/cmov/GNUmakefile | 2 +- frida_mode/ts/lib/afl.ts | 24 ++++++++++++------------ include/envs.h | 2 +- 9 files changed, 30 insertions(+), 30 deletions(-) (limited to 'frida_mode/src') diff --git a/frida_mode/README.md b/frida_mode/README.md index bf5cffec..50e3b8d7 100644 --- a/frida_mode/README.md +++ b/frida_mode/README.md @@ -170,11 +170,11 @@ instances run CMPLOG mode and instrumentation of the binary is less frequent *** ``` +* `AFL_FRIDA_INST_INSN` - Generate instrumentation for conditional + instructions (e.g. `CMOV` instructions on x64). * `AFL_FRIDA_INST_JIT` - Enable the instrumentation of Just-In-Time compiled code. Code is considered to be JIT if the executable segment is not backed by a file. -* `AFL_FRIDA_INST_NO_INSN` - Don't generate instrumentation for conditional - instructions (e.g. `CMOV` instructions on x64). * `AFL_FRIDA_INST_NO_OPTIMIZE` - Don't use optimized inline assembly coverage instrumentation (the default where available). Required to use `AFL_FRIDA_INST_TRACE`. diff --git a/frida_mode/frida.map b/frida_mode/frida.map index e9afac1b..41220d4b 100644 --- a/frida_mode/frida.map +++ b/frida_mode/frida.map @@ -15,7 +15,7 @@ js_api_set_instrument_debug_file; js_api_set_instrument_jit; js_api_set_instrument_libraries; - js_api_set_instrument_no_instructions; + js_api_set_instrument_instructions; js_api_set_instrument_no_optimize; js_api_set_instrument_seed; js_api_set_instrument_trace; diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c index 4877f4fb..43560478 100644 --- a/frida_mode/src/instrument/instrument.c +++ b/frida_mode/src/instrument/instrument.c @@ -276,7 +276,7 @@ void instrument_config(void) { instrument_fixed_seed = util_read_num("AFL_FRIDA_INST_SEED", 0); instrument_coverage_unstable_filename = (getenv("AFL_FRIDA_INST_UNSTABLE_COVERAGE_FILE")); - instrument_coverage_insn = (getenv("AFL_FRIDA_INST_NO_INSN") == NULL); + instrument_coverage_insn = (getenv("AFL_FRIDA_INST_INSN") != NULL); instrument_debug_config(); instrument_coverage_config(); @@ -302,6 +302,8 @@ void instrument_init(void) { instrument_coverage_unstable_filename == NULL ? " " : instrument_coverage_unstable_filename); + FOKF(cBLU "Instrumentation" cRST " - " cGRN "instructions:" cYEL " [%c]", + instrument_coverage_insn ? 'X' : ' '); if (instrument_tracing && instrument_optimize) { diff --git a/frida_mode/src/js/api.js b/frida_mode/src/js/api.js index c2d9a2d4..82b8e63d 100644 --- a/frida_mode/src/js/api.js +++ b/frida_mode/src/js/api.js @@ -113,6 +113,12 @@ class Afl { static setInstrumentEnableTracing() { Afl.jsApiSetInstrumentTrace(); } + /** + * See `AFL_FRIDA_INST_INSN` + */ + static setInstrumentInstructions() { + Afl.jsApiSetInstrumentInstructions(); + } /** * See `AFL_FRIDA_INST_JIT`. */ @@ -125,12 +131,6 @@ class Afl { static setInstrumentLibraries() { Afl.jsApiSetInstrumentLibraries(); } - /** - * See `AFL_FRIDA_INST_NO_INSN` - */ - static setInstrumentNoInstructions() { - Afl.jsApiSetInstrumentNoInstructions(); - } /** * See `AFL_FRIDA_INST_NO_OPTIMIZE` */ @@ -303,9 +303,9 @@ Afl.jsApiSetDebugMaps = Afl.jsApiGetFunction("js_api_set_debug_maps", "void", [] Afl.jsApiSetEntryPoint = Afl.jsApiGetFunction("js_api_set_entrypoint", "void", ["pointer"]); Afl.jsApiSetInstrumentCoverageFile = Afl.jsApiGetFunction("js_api_set_instrument_coverage_file", "void", ["pointer"]); Afl.jsApiSetInstrumentDebugFile = Afl.jsApiGetFunction("js_api_set_instrument_debug_file", "void", ["pointer"]); +Afl.jsApiSetInstrumentInstructions = Afl.jsApiGetFunction("js_api_set_instrument_instructions", "void", []); Afl.jsApiSetInstrumentJit = Afl.jsApiGetFunction("js_api_set_instrument_jit", "void", []); Afl.jsApiSetInstrumentLibraries = Afl.jsApiGetFunction("js_api_set_instrument_libraries", "void", []); -Afl.jsApiSetInstrumentNoInstructions = Afl.jsApiGetFunction("js_api_set_instrument_no_instructions", "void", []); Afl.jsApiSetInstrumentNoOptimize = Afl.jsApiGetFunction("js_api_set_instrument_no_optimize", "void", []); Afl.jsApiSetInstrumentSeed = Afl.jsApiGetFunction("js_api_set_instrument_seed", "void", ["uint64"]); Afl.jsApiSetInstrumentTrace = Afl.jsApiGetFunction("js_api_set_instrument_trace", "void", []); diff --git a/frida_mode/src/js/js_api.c b/frida_mode/src/js/js_api.c index 613747b8..89df7803 100644 --- a/frida_mode/src/js/js_api.c +++ b/frida_mode/src/js/js_api.c @@ -142,10 +142,10 @@ js_api_set_prefetch_backpatch_disable(void) { } -__attribute__((visibility("default"))) void -js_api_set_instrument_no_instructions(void) { +__attribute__((visibility("default"))) void js_api_set_instrument_instructions( + void) { - instrument_coverage_insn = FALSE; + instrument_coverage_insn = TRUE; } diff --git a/frida_mode/src/ranges.c b/frida_mode/src/ranges.c index 84803453..d47d1c14 100644 --- a/frida_mode/src/ranges.c +++ b/frida_mode/src/ranges.c @@ -595,8 +595,6 @@ void ranges_init(void) { ranges_inst_jit ? 'X' : ' '); FOKF(cBLU "Ranges" cRST " - " cGRN "instrument libraries:" cYEL " [%c]", ranges_inst_libs ? 'X' : ' '); - FOKF(cBLU "Ranges" cRST " - " cGRN "instrument libraries:" cYEL " [%c]", - ranges_inst_libs ? 'X' : ' '); print_ranges("include", include_ranges); print_ranges("exclude", exclude_ranges); diff --git a/frida_mode/test/cmov/GNUmakefile b/frida_mode/test/cmov/GNUmakefile index 318b2ad0..96f1ae5b 100644 --- a/frida_mode/test/cmov/GNUmakefile +++ b/frida_mode/test/cmov/GNUmakefile @@ -46,6 +46,7 @@ $(DUMMY_DATA_FILE): | $(BUILD_DIR) dd if=/dev/zero bs=1048576 count=1 of=$@ frida: $(TEST_CMOV_OBJ) $(CMP_LOG_INPUT) $(DUMMY_DATA_FILE) + AFL_FRIDA_INST_INSN=1 \ AFL_FRIDA_PERSISTENT_CNT=1000000 \ AFL_FRIDA_PERSISTENT_HOOK=$(AFLPP_FRIDA_DRIVER_HOOK_OBJ) \ AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \ @@ -60,7 +61,6 @@ frida: $(TEST_CMOV_OBJ) $(CMP_LOG_INPUT) $(DUMMY_DATA_FILE) $(TEST_CMOV_OBJ) $(DUMMY_DATA_FILE) frida_noinst: $(TEST_CMOV_OBJ) $(CMP_LOG_INPUT) $(DUMMY_DATA_FILE) - AFL_FRIDA_INST_NO_INSN=1 \ AFL_FRIDA_PERSISTENT_CNT=1000000 \ AFL_FRIDA_PERSISTENT_HOOK=$(AFLPP_FRIDA_DRIVER_HOOK_OBJ) \ AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \ diff --git a/frida_mode/ts/lib/afl.ts b/frida_mode/ts/lib/afl.ts index 9d31370e..7999b661 100644 --- a/frida_mode/ts/lib/afl.ts +++ b/frida_mode/ts/lib/afl.ts @@ -135,6 +135,13 @@ class Afl { Afl.jsApiSetInstrumentTrace(); } + /** + * See `AFL_FRIDA_INST_INSN` + */ + public static setInstrumentInstructions(): void { + Afl.jsApiSetInstrumentInstructions(); + } + /** * See `AFL_FRIDA_INST_JIT`. */ @@ -149,13 +156,6 @@ class Afl { Afl.jsApiSetInstrumentLibraries(); } - /** - * See `AFL_FRIDA_INST_NO_INSN` - */ - public static setInstrumentNoInstructions(): void { - Afl.jsApiSetInstrumentNoInstructions(); - } - /** * See `AFL_FRIDA_INST_NO_OPTIMIZE` */ @@ -374,6 +374,11 @@ class Afl { "void", ["pointer"]); + private static readonly jsApiSetInstrumentInstructions = Afl.jsApiGetFunction( + "js_api_set_instrument_instructions", + "void", + []); + private static readonly jsApiSetInstrumentJit = Afl.jsApiGetFunction( "js_api_set_instrument_jit", "void", @@ -384,11 +389,6 @@ class Afl { "void", []); - private static readonly jsApiSetInstrumentNoInstructions = Afl.jsApiGetFunction( - "js_api_set_instrument_no_instructions", - "void", - []); - private static readonly jsApiSetInstrumentNoOptimize = Afl.jsApiGetFunction( "js_api_set_instrument_no_optimize", "void", diff --git a/include/envs.h b/include/envs.h index 2ab3a387..1f6d33e6 100644 --- a/include/envs.h +++ b/include/envs.h @@ -59,8 +59,8 @@ static char *afl_environment_variables[] = { "AFL_FRIDA_EXCLUDE_RANGES", "AFL_FRIDA_INST_COVERAGE_FILE", "AFL_FRIDA_INST_DEBUG_FILE", + "AFL_FRIDA_INST_INSN", "AFL_FRIDA_INST_JIT", - "AFL_FRIDA_INST_NO_INSN", "AFL_FRIDA_INST_NO_OPTIMIZE", "AFL_FRIDA_INST_NO_PREFETCH", "AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH", -- cgit 1.4.1 From fc7bf33fb144162ede0c2d56b91ad31143113f16 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 18 Feb 2022 08:21:36 +0000 Subject: Reserved used address space on dlclose to prevent re-use --- frida_mode/include/module.h | 11 +++++ frida_mode/src/main.c | 3 ++ frida_mode/src/module.c | 106 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 frida_mode/include/module.h create mode 100644 frida_mode/src/module.c (limited to 'frida_mode/src') diff --git a/frida_mode/include/module.h b/frida_mode/include/module.h new file mode 100644 index 00000000..b66f7feb --- /dev/null +++ b/frida_mode/include/module.h @@ -0,0 +1,11 @@ +#ifndef _MODULE_H +#define _MODULE_H + +#include "frida-gumjs.h" + +void module_config(void); + +void module_init(void); + +#endif + diff --git a/frida_mode/src/main.c b/frida_mode/src/main.c index d8521300..bb6e4109 100644 --- a/frida_mode/src/main.c +++ b/frida_mode/src/main.c @@ -21,6 +21,7 @@ #include "intercept.h" #include "js.h" #include "lib.h" +#include "module.h" #include "output.h" #include "persistent.h" #include "prefetch.h" @@ -197,6 +198,7 @@ __attribute__((visibility("default"))) void afl_frida_start(void) { instrument_config(); js_config(); lib_config(); + module_config(); output_config(); persistent_config(); prefetch_config(); @@ -214,6 +216,7 @@ __attribute__((visibility("default"))) void afl_frida_start(void) { entry_init(); instrument_init(); lib_init(); + module_init(); persistent_init(); prefetch_init(); seccomp_init(); diff --git a/frida_mode/src/module.c b/frida_mode/src/module.c new file mode 100644 index 00000000..65b394cd --- /dev/null +++ b/frida_mode/src/module.c @@ -0,0 +1,106 @@ +#include "intercept.h" +#include "module.h" +#include "util.h" + +#if defined(__linux__) + #include + #include +#endif + +static guint page_size = 0; +static gboolean handle_dlclose = FALSE; + +void module_config(void) { + +#if defined(__linux__) + handle_dlclose = (getenv("AFL_FRIDA_NO_MODULE") == NULL); +#else + FWARNF("AFL_FRIDA_MODULE not supported"); +#endif + +} + +typedef struct { + + GumMemoryRange range; + GumPageProtection protection; + GumFileMapping file; + +} gum_range_t; + +gboolean found_range(const GumRangeDetails *details, gpointer user_data) { + + gum_range_t range = {0}; + GArray * ranges = (GArray *)user_data; + + range.range = *details->range; + range.protection = details->protection; + if (details->file != NULL) { range.file = *details->file; } + + g_array_append_val(ranges, range); + return FALSE; + +} + +#if defined(__linux__) +static int on_dlclose(void *handle) { + + GArray * ranges = NULL; + struct link_map *lm = NULL; + gum_range_t * range = NULL; + GumAddress base; + GumAddress limit; + gpointer mem; + + if (dlinfo(handle, RTLD_DI_LINKMAP, &lm) < 0) { + + FFATAL("Failed to dlinfo: %s", dlerror()); + + } + + FVERBOSE("on_dlclose: %s", lm->l_name); + + ranges = g_array_new(FALSE, TRUE, sizeof(gum_range_t)); + gum_module_enumerate_ranges(lm->l_name, GUM_PAGE_EXECUTE, found_range, + ranges); + + int ret = dlclose(handle); + if (ret != 0) { + + FWARNF("dlclose returned: %d (%s)", ret, dlerror()); + return ret; + + } + + for (guint i = 0; i < ranges->len; i++) { + + range = &g_array_index(ranges, gum_range_t, i); + base = range->range.base_address; + limit = base + range->range.size; + FVERBOSE("Reserving range: 0x%016lx, 0x%016lX", base, limit); + mem = gum_memory_allocate(GSIZE_TO_POINTER(base), range->range.size, + page_size, GUM_PAGE_NO_ACCESS); + if (mem == NULL) { FATAL("Failed to allocate %p (%d)", mem, errno); } + + } + + g_array_free(ranges, TRUE); + return 0; + +} + +#endif + +void module_init(void) { + + FOKF(cBLU "Module" cRST " - " cYEL " [%c]", handle_dlclose ? 'X' : ' '); + +#if defined(__linux__) + if (!handle_dlclose) { return; } + + page_size = gum_query_page_size(); + intercept_hook(dlclose, on_dlclose, NULL); +#endif + +} + -- cgit 1.4.1 From 852c036cae97113daac3ba5a791554bbbd5c8903 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 18 Feb 2022 17:39:21 +0000 Subject: Add global caching of block translation to instrumentation --- frida_mode/README.md | 30 +- frida_mode/frida.map | 2 + frida_mode/include/instrument.h | 8 + frida_mode/include/util.h | 8 + frida_mode/src/instrument/instrument.c | 4 + frida_mode/src/instrument/instrument_arm32.c | 25 ++ frida_mode/src/instrument/instrument_arm64.c | 22 ++ frida_mode/src/instrument/instrument_x64.c | 9 +- frida_mode/src/instrument/instrument_x64_cache.c | 435 +++++++++++++++++++++++ frida_mode/src/instrument/instrument_x86.c | 25 ++ frida_mode/src/js/api.js | 15 + frida_mode/src/js/js_api.c | 13 + frida_mode/test/cache/GNUmakefile | 97 +++++ frida_mode/test/cache/Makefile | 22 ++ frida_mode/test/cache/cache.c | 115 ++++++ frida_mode/test/vorbis/GNUmakefile | 8 +- frida_mode/ts/lib/afl.ts | 25 ++ include/envs.h | 2 + 18 files changed, 846 insertions(+), 19 deletions(-) create mode 100644 frida_mode/src/instrument/instrument_x64_cache.c create mode 100644 frida_mode/test/cache/GNUmakefile create mode 100644 frida_mode/test/cache/Makefile create mode 100644 frida_mode/test/cache/cache.c (limited to 'frida_mode/src') diff --git a/frida_mode/README.md b/frida_mode/README.md index 50e3b8d7..4025dba5 100644 --- a/frida_mode/README.md +++ b/frida_mode/README.md @@ -151,25 +151,25 @@ instances run CMPLOG mode and instrumentation of the binary is less frequent * `AFL_FRIDA_INST_DEBUG_FILE` - File to write raw assembly of original blocks and their instrumented counterparts during block compilation. - ``` - *** +Creating block for 0x7ffff7953313: + 0x7ffff7953313 mov qword ptr [rax], 0 + 0x7ffff795331a add rsp, 8 + 0x7ffff795331e ret - Creating block for 0x7ffff7953313: - 0x7ffff7953313 mov qword ptr [rax], 0 - 0x7ffff795331a add rsp, 8 - 0x7ffff795331e ret +Generated block 0x7ffff75e98e2 + 0x7ffff75e98e2 mov qword ptr [rax], 0 + 0x7ffff75e98e9 add rsp, 8 + 0x7ffff75e98ed lea rsp, [rsp - 0x80] + 0x7ffff75e98f5 push rcx + 0x7ffff75e98f6 movabs rcx, 0x7ffff795331e + 0x7ffff75e9900 jmp 0x7ffff75e9384 - Generated block 0x7ffff75e98e2 - 0x7ffff75e98e2 mov qword ptr [rax], 0 - 0x7ffff75e98e9 add rsp, 8 - 0x7ffff75e98ed lea rsp, [rsp - 0x80] - 0x7ffff75e98f5 push rcx - 0x7ffff75e98f6 movabs rcx, 0x7ffff795331e - 0x7ffff75e9900 jmp 0x7ffff75e9384 *** ``` - +* `AFL_FRIDA_INST_CACHE_SIZE` - Set the size of the instrumentation cache used +as a look-up table to cache real to instrumented address block translations. +Default is 256Mb. * `AFL_FRIDA_INST_INSN` - Generate instrumentation for conditional instructions (e.g. `CMOV` instructions on x64). * `AFL_FRIDA_INST_JIT` - Enable the instrumentation of Just-In-Time compiled @@ -178,6 +178,8 @@ instances run CMPLOG mode and instrumentation of the binary is less frequent * `AFL_FRIDA_INST_NO_OPTIMIZE` - Don't use optimized inline assembly coverage instrumentation (the default where available). Required to use `AFL_FRIDA_INST_TRACE`. +* `AFL_FRIDA_INST_NO_CACHE` - Don't use a look-up table to cache real to +instrumented address block translations. * `AFL_FRIDA_INST_NO_PREFETCH` - Disable prefetching. By default, the child will report instrumented blocks back to the parent so that it can also instrument them and they be inherited by the next child on fork, implies diff --git a/frida_mode/frida.map b/frida_mode/frida.map index 41220d4b..6726dbbd 100644 --- a/frida_mode/frida.map +++ b/frida_mode/frida.map @@ -9,8 +9,10 @@ js_api_done; js_api_error; js_api_set_backpatch_disable; + js_api_set_cache_disable; js_api_set_debug_maps; js_api_set_entrypoint; + js_api_set_instrument_cache_size; js_api_set_instrument_coverage_file; js_api_set_instrument_debug_file; js_api_set_instrument_jit; diff --git a/frida_mode/include/instrument.h b/frida_mode/include/instrument.h index 20312a4b..4a54ee22 100644 --- a/frida_mode/include/instrument.h +++ b/frida_mode/include/instrument.h @@ -22,6 +22,9 @@ extern uint32_t __afl_map_size; extern __thread guint64 *instrument_previous_pc_addr; +extern gboolean instrument_cache_enabled; +extern gsize instrument_cache_size; + void instrument_config(void); void instrument_init(void); @@ -59,5 +62,10 @@ void instrument_on_fork(void); guint64 instrument_get_offset_hash(GumAddress current_rip); +void instrument_cache_config(void); +void instrument_cache_init(void); +void instrument_cache_insert(gpointer real_address, gpointer code_address); +void instrument_cache(const cs_insn *instr, GumStalkerOutput *output); + #endif diff --git a/frida_mode/include/util.h b/frida_mode/include/util.h index bd37687c..b04e0a26 100644 --- a/frida_mode/include/util.h +++ b/frida_mode/include/util.h @@ -5,6 +5,14 @@ #include "debug.h" +#ifndef MAP_FIXED_NOREPLACE + #ifdef MAP_EXCL + #define MAP_FIXED_NOREPLACE MAP_EXCL | MAP_FIXED + #else + #define MAP_FIXED_NOREPLACE MAP_FIXED + #endif +#endif + #define UNUSED_PARAMETER(x) (void)(x) #define IGNORED_RETURN(x) (void)!(x) diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c index 43560478..003c3d00 100644 --- a/frida_mode/src/instrument/instrument.c +++ b/frida_mode/src/instrument/instrument.c @@ -249,6 +249,8 @@ static void instrument_basic_block(GumStalkerIterator *iterator, } + instrument_cache(instr, output); + if (js_stalker_callback(instr, begin, excluded, output)) { gum_stalker_iterator_keep(iterator); @@ -282,6 +284,7 @@ void instrument_config(void) { instrument_coverage_config(); asan_config(); cmplog_config(); + instrument_cache_config(); } @@ -392,6 +395,7 @@ void instrument_init(void) { instrument_coverage_init(); instrument_coverage_optimize_init(); instrument_debug_init(); + instrument_cache_init(); } diff --git a/frida_mode/src/instrument/instrument_arm32.c b/frida_mode/src/instrument/instrument_arm32.c index 705faa64..80f3c26d 100644 --- a/frida_mode/src/instrument/instrument_arm32.c +++ b/frida_mode/src/instrument/instrument_arm32.c @@ -5,6 +5,9 @@ #if defined(__arm__) +gboolean instrument_cache_enabled = FALSE; +gsize instrument_cache_size = 0; + gboolean instrument_is_coverage_optimize_supported(void) { return false; @@ -55,5 +58,27 @@ gpointer instrument_cur(GumStalkerOutput *output) { } +void instrument_cache_config(void) { + +} + +void instrument_cache_init(void) { + +} + +void instrument_cache_insert(gpointer real_address, gpointer code_address) { + + UNUSED_PARAMETER(real_address); + UNUSED_PARAMETER(code_address); + +} + +void instrument_cache(const cs_insn *instr, GumStalkerOutput *output) { + + UNUSED_PARAMETER(instr); + UNUSED_PARAMETER(output); + +} + #endif diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c index 4abc0625..eb736386 100644 --- a/frida_mode/src/instrument/instrument_arm64.c +++ b/frida_mode/src/instrument/instrument_arm64.c @@ -379,5 +379,27 @@ gpointer instrument_cur(GumStalkerOutput *output) { } +void instrument_cache_config(void) { + +} + +void instrument_cache_init(void) { + +} + +void instrument_cache_insert(gpointer real_address, gpointer code_address) { + + UNUSED_PARAMETER(real_address); + UNUSED_PARAMETER(code_address); + +} + +void instrument_cache(const cs_insn *instr, GumStalkerOutput *output) { + + UNUSED_PARAMETER(instr); + UNUSED_PARAMETER(output); + +} + #endif diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c index 4b1a2d68..0bff3e02 100644 --- a/frida_mode/src/instrument/instrument_x64.c +++ b/frida_mode/src/instrument/instrument_x64.c @@ -202,10 +202,17 @@ static void instrument_coverage_switch(GumStalkerObserver *self, } - if (op[0].type != X86_OP_IMM) { return; } + if (op[0].type != X86_OP_IMM) { + + instrument_cache_insert(start_address, *target); + return; + + } break; case X86_INS_RET: + instrument_cache_insert(start_address, + (guint8 *)*target + sizeof(afl_log_code)); break; default: return; diff --git a/frida_mode/src/instrument/instrument_x64_cache.c b/frida_mode/src/instrument/instrument_x64_cache.c new file mode 100644 index 00000000..3ea4421a --- /dev/null +++ b/frida_mode/src/instrument/instrument_x64_cache.c @@ -0,0 +1,435 @@ +#include +#include + +#include "instrument.h" +#include "util.h" + +#if defined(__x86_64__) + + #define INVALID 1 + #define DEFAULT_CACHE_SIZE (256ULL << 20) + +gboolean instrument_cache_enabled = TRUE; +gsize instrument_cache_size = DEFAULT_CACHE_SIZE; +static gpointer *map_base = MAP_FAILED; + +void instrument_cache_config(void) { + + instrument_cache_enabled = (getenv("AFL_FRIDA_INST_NO_CACHE") == NULL); + + if (getenv("AFL_FRIDA_INST_CACHE_SIZE") != NULL) { + + if (!instrument_cache_enabled) { + + FFATAL( + "AFL_FRIDA_INST_CACHE_SIZE incomatible with " + "AFL_FRIDA_INST_NO_CACHE"); + + } + + instrument_cache_size = + util_read_address("AFL_FRIDA_INST_CACHE_SIZE", DEFAULT_CACHE_SIZE); + util_log2(instrument_cache_size); + + } + +} + +void instrument_cache_init(void) { + + FOKF(cBLU "Instrumentation" cRST " - " cGRN "cache:" cYEL " [%c]", + instrument_cache_enabled ? 'X' : ' '); + if (!instrument_cache_enabled) { return; } + + FOKF(cBLU "Instrumentation" cRST " - " cGRN "cache size:" cYEL " [0x%016lX]", + instrument_cache_size); + + const struct rlimit data_limit = {.rlim_cur = RLIM_INFINITY, + .rlim_max = RLIM_INFINITY}; + + if (setrlimit(RLIMIT_AS, &data_limit) != 0) { + + FFATAL("Failed to setrlimit: %d", errno); + + } + + map_base = + gum_memory_allocate(NULL, instrument_cache_size, instrument_cache_size, + GUM_PAGE_READ | GUM_PAGE_WRITE); + if (map_base == MAP_FAILED) { FFATAL("Failed to map segment: %d", errno); } + + FOKF(cBLU "Instrumentation" cRST " - " cGRN "cache addr:" cYEL " [0x%016lX]", + GUM_ADDRESS(map_base)); + +} + +static gpointer *instrument_cache_get_addr(gpointer addr) { + + gsize mask = (instrument_cache_size / sizeof(gpointer)) - 1; + return &map_base[GPOINTER_TO_SIZE(addr) & mask]; + +} + +void instrument_cache_insert(gpointer real_address, gpointer code_address) { + + if (!instrument_cache_enabled) { return; } + + gpointer *target = instrument_cache_get_addr(real_address); + if (*target == code_address) { + + return; + + } else if (*target == NULL) { + + *target = code_address; + + } else { + + *target = GSIZE_TO_POINTER(INVALID); + + } + +} + +static gboolean instrument_cache_relocate(GumAddress old_pc, GumAddress new_pc, + gint32 old_offset, + gint32 *new_offset) { + + guint64 old_target = old_pc + old_offset; + gint64 relocated = old_target - new_pc; + + if (relocated > G_MAXINT32 || relocated < G_MININT32) { return FALSE; } + + *new_offset = relocated; + return TRUE; + +} + +static void instrument_cache_rewrite_branch_insn(const cs_insn * instr, + GumStalkerOutput *output) { + + GumX86Writer *cw = output->writer.x86; + cs_x86 * x86 = &instr->detail->x86; + guint8 modified[sizeof(instr->bytes)] = {0}; + guint8 offset = 0; + guint8 skip = 0; + + g_assert(sizeof(x86->prefix) == 4); + g_assert(sizeof(x86->opcode) == 4); + + /* + * If the target is simply RAX, we can skip writing the code to load the + * RIP + */ + if (x86->operands[0].type == X86_OP_REG || + x86->operands[0].reg == X86_REG_RAX) { + + return; + + } + + /* Write the prefix */ + for (gsize i = 0; i < sizeof(x86->prefix); i++) { + + if (x86->prefix[i] != 0) { + + if (x86->prefix[i] == 0xf2) { + + skip++; + + } else { + + modified[offset++] = x86->prefix[i]; + skip++; + + } + + } + + } + + /* Write the REX */ + if (x86->rex == 0) { + + /* + * CALL (near) and JMP (near) default to 64-bit operands, MOV does not, + * write REX.W + */ + modified[offset++] = 0x48; + + } else { + + if ((x86->rex & 0xF8) != 0x40) { + + FATAL("Unexpected REX byte: 0x%02x", x86->rex); + + } + + modified[offset++] = x86->rex | 0x08; + skip++; + + } + + /* + * CALL is FF /2, JMP is FF /4. The remaining op-code fields should thus be + * unused + */ + + if (x86->opcode[0] != 0xFF || x86->opcode[1] != 0x00 || + x86->opcode[2] != 0x00 || x86->opcode[3] != 0x00) { + + FFATAL("Unexpected Op-code: 0x%02x 0x%02x 0x%02x 0x%02x", x86->opcode[0], + x86->opcode[1], x86->opcode[2], x86->opcode[3]); + + } + + /* The reg field of the ModRM should be set to 2 for CALL and 4 for JMP */ + guint8 reg = (x86->modrm >> 3) & 7; + if (reg != 0x4 && reg != 0x2) { + + FFATAL("Unexpected Reg: 0x%02x, ModRM: 0x%02x", reg, x86->modrm); + + } + + /* MOV */ + modified[offset++] = 0x8b; + skip++; + + /* Clear the reg field (RAX) */ + modified[offset++] = x86->modrm & 0xc7; + skip++; + + /* Operands */ + guint8 op_len = instr->size - skip; + + /* If our branch was RIP relative, we'll need to fix-up the offset */ + if (x86->operands[0].type == X86_OP_MEM && + x86->operands[0].mem.base == X86_REG_RIP) { + + /* RIP relative offsets should be 32-bits */ + if (op_len != sizeof(gint32)) { + + FFATAL("Unexpected operand length: %d\n", op_len); + + } + + gint32 old_offset = *(gint32 *)&instr->bytes[skip]; + gint32 new_offset = 0; + if (instrument_cache_relocate(instr->address, cw->pc, old_offset, + &new_offset)) { + + gint32 *output = (gint32 *)&modified[offset]; + *output = new_offset; + offset += sizeof(gint32); + + } else { + + GumAddress target = instr->address + old_offset; + gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, target); + gum_x86_writer_put_mov_reg_reg_ptr(cw, GUM_REG_RAX, GUM_REG_RAX); + return; + + } + + } else { + + for (int i = 0; i < op_len; i++) { + + guint8 val = instr->bytes[i + skip]; + modified[offset++] = val; + + } + + } + + gum_x86_writer_put_bytes(cw, modified, offset); + +} + +static void instrument_cache_write_push_frame(GumX86Writer *cw) { + + gum_x86_writer_put_mov_reg_offset_ptr_reg( + cw, GUM_REG_XSP, -(GUM_RED_ZONE_SIZE + (1 * sizeof(gpointer))), + GUM_REG_XAX); + gum_x86_writer_put_lahf(cw); + gum_x86_writer_put_mov_reg_offset_ptr_reg( + cw, GUM_REG_XSP, -(GUM_RED_ZONE_SIZE + (2 * sizeof(gpointer))), + GUM_REG_XAX); + gum_x86_writer_put_mov_reg_offset_ptr_reg( + cw, GUM_REG_XSP, -(GUM_RED_ZONE_SIZE + (3 * sizeof(gpointer))), + GUM_REG_XBX); + +} + +static void instrument_cache_write_pop_frame(GumX86Writer *cw) { + + gum_x86_writer_put_mov_reg_reg_offset_ptr( + cw, GUM_REG_XBX, GUM_REG_XSP, + -(GUM_RED_ZONE_SIZE + (3 * sizeof(gpointer)))); + gum_x86_writer_put_mov_reg_reg_offset_ptr( + cw, GUM_REG_XAX, GUM_REG_XSP, + -(GUM_RED_ZONE_SIZE + (2 * sizeof(gpointer)))); + gum_x86_writer_put_sahf(cw); + gum_x86_writer_put_mov_reg_reg_offset_ptr( + cw, GUM_REG_XAX, GUM_REG_XSP, + -(GUM_RED_ZONE_SIZE + (1 * sizeof(gpointer)))); + +} + +static void instrument_cache_write_lookup(GumX86Writer *cw) { + + /* &map_base[GPOINTER_TO_SIZE(addr) & MAP_MASK]; */ + + gsize mask = (instrument_cache_size / sizeof(gpointer)) - 1; + gum_x86_writer_put_mov_reg_u64(cw, GUM_REG_XBX, mask); + gum_x86_writer_put_and_reg_reg(cw, GUM_REG_XAX, GUM_REG_XBX); + gum_x86_writer_put_shl_reg_u8(cw, GUM_REG_XAX, util_log2(sizeof(gpointer))); + gum_x86_writer_put_mov_reg_u64(cw, GUM_REG_XBX, GPOINTER_TO_SIZE(map_base)); + gum_x86_writer_put_add_reg_reg(cw, GUM_REG_XAX, GUM_REG_XBX); + + /* Read the return address lookup */ + gum_x86_writer_put_mov_reg_reg_ptr(cw, GUM_REG_XAX, GUM_REG_XAX); + +} + +void instrument_cache_jmp_call(const cs_insn *instr, GumStalkerOutput *output) { + + GumX86Writer *cw = output->writer.x86; + cs_x86 * x86 = &instr->detail->x86; + + if (x86->op_count != 1) { FFATAL("Unexpected operand count"); } + + if (x86->operands[0].type == X86_OP_IMM) { return; } + + gconstpointer null = cw->code; + + instrument_cache_write_push_frame(cw); + + /* + * We are about to re-write the CALL or JMP instruction, but replace the + * op-code with that for a MOV into RAX. Since we are keeping the operand from + * the JMP exactly the same, it is imperative that the target register state + * be exactly the same as how the target left it. Since `LAHF` spoils `RAX` we + * must restore it from the stack. We also must avoid adjusting `RSP`, so we + * use `MOV` instructions to store our context into the stack beyond the + * red-zone. + */ + gum_x86_writer_put_mov_reg_reg_offset_ptr( + cw, GUM_REG_XAX, GUM_REG_XSP, + -(GUM_RED_ZONE_SIZE + (1 * sizeof(gpointer)))); + + instrument_cache_rewrite_branch_insn(instr, output); + + instrument_cache_write_lookup(cw); + + /* Test if its set*/ + gum_x86_writer_put_cmp_reg_i32(cw, GUM_REG_XAX, INVALID); + gum_x86_writer_put_jcc_short_label(cw, X86_INS_JLE, null, GUM_UNLIKELY); + + /* If it's set, then stash the address beyond the red-zone */ + gum_x86_writer_put_mov_reg_offset_ptr_reg( + cw, GUM_REG_XSP, -(GUM_RED_ZONE_SIZE + (4 * sizeof(gpointer))), + GUM_REG_XAX); + + if (instr->id == X86_INS_JMP) { + + instrument_cache_write_pop_frame(cw); + gum_x86_writer_put_jmp_reg_offset_ptr( + cw, GUM_REG_XSP, -(GUM_RED_ZONE_SIZE + (4 * sizeof(gpointer)))); + + } else { + + gum_x86_writer_put_mov_reg_address( + cw, GUM_REG_XAX, GUM_ADDRESS(instr->address + instr->size)); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_XSP, + -sizeof(gpointer), GUM_REG_XAX); + + instrument_cache_write_pop_frame(cw); + + gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_XSP, GUM_REG_XSP, + -sizeof(gpointer)); + gum_x86_writer_put_jmp_reg_offset_ptr( + cw, GUM_REG_XSP, -(GUM_RED_ZONE_SIZE + ((4 - 1) * sizeof(gpointer)))); + + } + + /* Tidy up our mess and let FRIDA handle it */ + gum_x86_writer_put_label(cw, null); + instrument_cache_write_pop_frame(cw); + +} + +void instrument_cache_ret(const cs_insn *instr, GumStalkerOutput *output) { + + GumX86Writer *cw = output->writer.x86; + cs_x86 * x86 = &instr->detail->x86; + guint16 n = 0; + + if (x86->op_count != 0) { + + if (x86->operands[0].type != X86_OP_IMM) { + + FFATAL("Unexpected operand type"); + + } + + n = x86->operands[0].imm; + + } + + gconstpointer null = cw->code; + + instrument_cache_write_push_frame(cw); + + gum_x86_writer_put_mov_reg_reg_ptr(cw, GUM_REG_XAX, GUM_REG_XSP); + + instrument_cache_write_lookup(cw); + + /* Test if its set*/ + gum_x86_writer_put_cmp_reg_i32(cw, GUM_REG_XAX, INVALID); + gum_x86_writer_put_jcc_short_label(cw, X86_INS_JLE, null, GUM_UNLIKELY); + + /* If it's set, then overwrite our return address and return */ + gum_x86_writer_put_mov_reg_ptr_reg(cw, GUM_REG_XSP, GUM_REG_XAX); + instrument_cache_write_pop_frame(cw); + + if (n == 0) { + + gum_x86_writer_put_ret(cw); + + } else { + + gum_x86_writer_put_ret_imm(cw, n); + + } + + /* Tidy up our mess and let FRIDA handle it */ + gum_x86_writer_put_label(cw, null); + instrument_cache_write_pop_frame(cw); + +} + +void instrument_cache(const cs_insn *instr, GumStalkerOutput *output) { + + if (!instrument_cache_enabled) { return; } + + switch (instr->id) { + + case X86_INS_RET: + instrument_cache_ret(instr, output); + break; + + case X86_INS_CALL: + case X86_INS_JMP: + instrument_cache_jmp_call(instr, output); + break; + + default: + return; + + } + +} + +#endif + diff --git a/frida_mode/src/instrument/instrument_x86.c b/frida_mode/src/instrument/instrument_x86.c index 916cd0e2..6a899248 100644 --- a/frida_mode/src/instrument/instrument_x86.c +++ b/frida_mode/src/instrument/instrument_x86.c @@ -6,6 +6,9 @@ #if defined(__i386__) +gboolean instrument_cache_enabled = FALSE; +gsize instrument_cache_size = 0; + static GHashTable *coverage_blocks = NULL; #pragma pack(push, 1) @@ -242,5 +245,27 @@ gpointer instrument_cur(GumStalkerOutput *output) { } +void instrument_cache_config(void) { + +} + +void instrument_cache_init(void) { + +} + +void instrument_cache_insert(gpointer real_address, gpointer code_address) { + + UNUSED_PARAMETER(real_address); + UNUSED_PARAMETER(code_address); + +} + +void instrument_cache(const cs_insn *instr, GumStalkerOutput *output) { + + UNUSED_PARAMETER(instr); + UNUSED_PARAMETER(output); + +} + #endif diff --git a/frida_mode/src/js/api.js b/frida_mode/src/js/api.js index 82b8e63d..c1c9d36f 100644 --- a/frida_mode/src/js/api.js +++ b/frida_mode/src/js/api.js @@ -68,6 +68,12 @@ class Afl { static setBackpatchDisable() { Afl.jsApiSetBackpatchDisable(); } + /** + * See `AFL_FRIDA_INST_NO_CACHE`. + */ + static setCacheDisable() { + Afl.jsApiSetCacheDisable(); + } /** * See `AFL_FRIDA_DEBUG_MAPS`. */ @@ -91,6 +97,13 @@ class Afl { static setInMemoryFuzzing() { Afl.jsApiAflSharedMemFuzzing.writeInt(1); } + /** + * See `AFL_FRIDA_INST_CACHE_SIZE`. This function takes a single `number` + * as an argument. + */ + static setInstrumentCacheSize(size) { + Afl.jsApiSetInstrumentCacheSize(size); + } /** * See `AFL_FRIDA_INST_COVERAGE_FILE`. This function takes a single `string` * as an argument. @@ -299,8 +312,10 @@ Afl.jsApiAflSharedMemFuzzing = Afl.jsApiGetSymbol("__afl_sharedmem_fuzzing"); Afl.jsApiDone = Afl.jsApiGetFunction("js_api_done", "void", []); Afl.jsApiError = Afl.jsApiGetFunction("js_api_error", "void", ["pointer"]); Afl.jsApiSetBackpatchDisable = Afl.jsApiGetFunction("js_api_set_backpatch_disable", "void", []); +Afl.jsApiSetCacheDisable = Afl.jsApiGetFunction("js_api_set_cache_disable", "void", []); Afl.jsApiSetDebugMaps = Afl.jsApiGetFunction("js_api_set_debug_maps", "void", []); Afl.jsApiSetEntryPoint = Afl.jsApiGetFunction("js_api_set_entrypoint", "void", ["pointer"]); +Afl.jsApiSetInstrumentCacheSize = Afl.jsApiGetFunction("js_api_set_instrument_cache_size", "void", ["size_t"]); Afl.jsApiSetInstrumentCoverageFile = Afl.jsApiGetFunction("js_api_set_instrument_coverage_file", "void", ["pointer"]); Afl.jsApiSetInstrumentDebugFile = Afl.jsApiGetFunction("js_api_set_instrument_debug_file", "void", ["pointer"]); Afl.jsApiSetInstrumentInstructions = Afl.jsApiGetFunction("js_api_set_instrument_instructions", "void", []); diff --git a/frida_mode/src/js/js_api.c b/frida_mode/src/js/js_api.c index 89df7803..7cc8ffc7 100644 --- a/frida_mode/src/js/js_api.c +++ b/frida_mode/src/js/js_api.c @@ -262,6 +262,19 @@ __attribute__((visibility("default"))) void js_api_set_stalker_adjacent_blocks( } +__attribute__((visibility("default"))) void js_api_set_cache_disable(void) { + + instrument_cache_enabled = FALSE; + +} + +__attribute__((visibility("default"))) void js_api_set_instrument_cache_size( + gsize size) { + + instrument_cache_size = size; + +} + __attribute__((visibility("default"))) void js_api_set_js_main_hook( const js_main_hook_t hook) { diff --git a/frida_mode/test/cache/GNUmakefile b/frida_mode/test/cache/GNUmakefile new file mode 100644 index 00000000..12736a3f --- /dev/null +++ b/frida_mode/test/cache/GNUmakefile @@ -0,0 +1,97 @@ +PWD:=$(shell pwd)/ +ROOT:=$(PWD)../../../ +BUILD_DIR:=$(PWD)build/ + +TEST_CACHE_SRC:=$(PWD)cache.c +TEST_CACHE_OBJ:=$(BUILD_DIR)cache + +TEST_DATA_DIR:=$(BUILD_DIR)in/ +CACHE_INPUT:=$(TEST_DATA_DIR)in +QEMU_OUT:=$(BUILD_DIR)qemu-out +FRIDA_OUT:=$(BUILD_DIR)frida-out + +ADDR_BIN:=$(ROOT)frida_mode/build/addr +GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh + +AFLPP_FRIDA_DRIVER_HOOK_OBJ=$(ROOT)frida_mode/build/frida_hook.so + +AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN)) +AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_CACHE_OBJ) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR)) + +DUMMY_DATA_FILE:=$(BUILD_DIR)dummy.dat + +.PHONY: all 32 clean frida frida_noinst debug format + +all: $(TEST_CACHE_OBJ) + make -C $(ROOT)frida_mode/ + +32: + CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all + +$(BUILD_DIR): + mkdir -p $@ + +$(TEST_DATA_DIR): | $(BUILD_DIR) + mkdir -p $@ + +$(CACHE_INPUT): | $(TEST_DATA_DIR) + echo -n "ABC" > $@ + +$(TEST_CACHE_OBJ): $(TEST_CACHE_SRC) | $(BUILD_DIR) + $(CC) -g $(CFLAGS) $(LDFLAGS) $< -o $@ + +########## DUMMY ####### + +$(DUMMY_DATA_FILE): | $(BUILD_DIR) + dd if=/dev/zero bs=1048576 count=1 of=$@ + +frida: $(TEST_CACHE_OBJ) $(CACHE_INPUT) $(DUMMY_DATA_FILE) + AFL_FRIDA_INST_INSN=1 \ + 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 \ + -O \ + -i $(TEST_DATA_DIR) \ + -o $(FRIDA_OUT) \ + -Z \ + -t 10000+ \ + -- \ + $(TEST_CACHE_OBJ) $(DUMMY_DATA_FILE) + +frida_nocache: $(TEST_CACHE_OBJ) $(CACHE_INPUT) $(DUMMY_DATA_FILE) + AFL_FRIDA_INST_NO_CACHE=1 \ + 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 \ + -O \ + -i $(TEST_DATA_DIR) \ + -o $(FRIDA_OUT) \ + -Z \ + -- \ + $(TEST_CACHE_OBJ) $(DUMMY_DATA_FILE) + +debug: $(TEST_CACHE_OBJ) $(CACHE_INPUT) + gdb \ + --ex 'set environment LD_PRELOAD=$(ROOT)afl-frida-trace.so' \ + --ex 'set disassembly-flavor intel' \ + --ex 'r $(CACHE_INPUT)' \ + --args $(TEST_CACHE_OBJ) $(CACHE_INPUT) + +show: $(TEST_CACHE_OBJ) $(CACHE_INPUT) + gdb \ + --ex "set disassembly-flavor intel" \ + --ex "set confirm off" \ + --ex "symbol-file $(TEST_CACHE_OBJ)" \ + --ex "x/50i LLVMFuzzerTestOneInput" \ + --ex "r" \ + --args $(TEST_CACHE_OBJ) $(CACHE_INPUT) + +clean: + rm -rf $(BUILD_DIR) + +format: + cd $(ROOT) && echo $(TEST_CACHE_SRC) | xargs -L1 ./.custom-format.py -i diff --git a/frida_mode/test/cache/Makefile b/frida_mode/test/cache/Makefile new file mode 100644 index 00000000..961a284c --- /dev/null +++ b/frida_mode/test/cache/Makefile @@ -0,0 +1,22 @@ +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 + +frida: + @gmake frida + +frida_nocache: + @gmake frida_nocache + +debug: + @gmake debug + +clean: + @gmake clean + +format: + @gmake format diff --git a/frida_mode/test/cache/cache.c b/frida_mode/test/cache/cache.c new file mode 100644 index 00000000..b4102205 --- /dev/null +++ b/frida_mode/test/cache/cache.c @@ -0,0 +1,115 @@ +#include +#include +#include +#include +#include + +void LLVMFuzzerTestOneInput(char *buf, int len); + +__asm__ ( + "LLVMFuzzerTestOneInput:\n" + ".func LLVMFuzzerTestOneInput\n" + ".global LLVMFuzzerTestOneInput\n" + " jmpq *jmp_offset(%rip)\n" + " nop\n" + " nop\n" + "call_target:\n" + " ret\n" + " nop\n" + " nop\n" + "jmp_target:\n" + " callq *call_offset(%rip)\n" + " nop\n" + " nop\n" + " leaq rax_offset(%rip), %rax\n" + " jmp (%rax)\n" + " nop\n" + " ud2\n" + " nop\n" + "rax_target:\n" + " ret\n" + "\n" + "\n" + ".global jmp_offset\n" + ".p2align 3\n" + "jmp_offset:\n" + " .quad jmp_target\n" + "call_offset:\n" + " .quad call_target\n" + "rax_offset:\n" + " .quad rax_target\n" +); + +int main(int argc, char **argv) { + + char * file; + int fd = -1; + off_t len; + char * buf = NULL; + size_t n_read; + int result = -1; + + if (argc != 2) { return 1; } + + do { + + file = argv[1]; + + dprintf(STDERR_FILENO, "Running: %s\n", file); + + fd = open(file, O_RDONLY); + if (fd < 0) { + + perror("open"); + break; + + } + + len = lseek(fd, 0, SEEK_END); + if (len < 0) { + + perror("lseek (SEEK_END)"); + break; + + } + + if (lseek(fd, 0, SEEK_SET) != 0) { + + perror("lseek (SEEK_SET)"); + break; + + } + + buf = (char *)malloc(len); + if (buf == NULL) { + + perror("malloc"); + break; + + } + + n_read = read(fd, buf, len); + if (n_read != len) { + + perror("read"); + break; + + } + + dprintf(STDERR_FILENO, "Running: %s: (%zd bytes)\n", file, n_read); + + LLVMFuzzerTestOneInput(buf, len); + dprintf(STDERR_FILENO, "Done: %s: (%zd bytes)\n", file, n_read); + + result = 0; + + } while (false); + + if (buf != NULL) { free(buf); } + + if (fd != -1) { close(fd); } + + return result; + +} + diff --git a/frida_mode/test/vorbis/GNUmakefile b/frida_mode/test/vorbis/GNUmakefile index 9cce6c9e..4cb5d417 100644 --- a/frida_mode/test/vorbis/GNUmakefile +++ b/frida_mode/test/vorbis/GNUmakefile @@ -125,7 +125,7 @@ vorbis: $(VORBIS_LIB) ########## HARNESS ####### $(DECODE_SRC): - wget -O $@ $(DECODE_URL) + wget -O $@ $(DECODE_URL) || curl -L -o $@ $(DECODE_URL) $(DECODE_OBJ): $(DECODE_SRC) $(CXX) -o $@ -c $< -I$(VORBIS_DIR)include/ -I$(OGG_DIR)include/ @@ -135,7 +135,7 @@ decode: $(DECODE_OBJ) ########## HARNESS ####### $(HARNESS_SRC): - wget -O $@ $(HARNESS_URL) + wget -O $@ $(HARNESS_URL) || curl -L -o $@ $(HARNESS_URL) $(HARNESS_OBJ): $(HARNESS_SRC) $(CC) -o $@ -c $< @@ -165,8 +165,8 @@ $(AFLPP_DRIVER_DUMMY_INPUT): | $(BUILD_DIR) ###### TEST DATA ####### -$(TEST_DATA_FILE): $(TEST_DATA_DIR) - wget -O $@ $(TEST_DATA_SRC) +$(TEST_DATA_FILE): | $(TEST_DATA_DIR) + wget -O $@ $(TEST_DATA_SRC) || curl -L -o $@ $(TEST_DATA_SRC) clean: rm -rf $(BUILD_DIR) diff --git a/frida_mode/ts/lib/afl.ts b/frida_mode/ts/lib/afl.ts index 7999b661..a858f074 100644 --- a/frida_mode/ts/lib/afl.ts +++ b/frida_mode/ts/lib/afl.ts @@ -84,6 +84,13 @@ class Afl { Afl.jsApiSetBackpatchDisable(); } + /** + * See `AFL_FRIDA_INST_NO_CACHE`. + */ + public static setCacheDisable(): void { + Afl.jsApiSetCacheDisable(); + } + /** * See `AFL_FRIDA_DEBUG_MAPS`. */ @@ -110,6 +117,14 @@ class Afl { Afl.jsApiAflSharedMemFuzzing.writeInt(1); } + /** + * See `AFL_FRIDA_INST_CACHE_SIZE`. This function takes a single `number` + * as an argument. + */ + public static setInstrumentCacheSize(size: number): void { + Afl.jsApiSetInstrumentCacheSize(size); + } + /** * See `AFL_FRIDA_INST_COVERAGE_FILE`. This function takes a single `string` * as an argument. @@ -354,6 +369,11 @@ class Afl { "void", []); + private static readonly jsApiSetCacheDisable = Afl.jsApiGetFunction( + "js_api_set_cache_disable", + "void", + []); + private static readonly jsApiSetDebugMaps = Afl.jsApiGetFunction( "js_api_set_debug_maps", "void", @@ -364,6 +384,11 @@ class Afl { "void", ["pointer"]); + private static readonly jsApiSetInstrumentCacheSize = Afl.jsApiGetFunction( + "js_api_set_instrument_cache_size", + "void", + ["size_t"]); + private static readonly jsApiSetInstrumentCoverageFile = Afl.jsApiGetFunction( "js_api_set_instrument_coverage_file", "void", diff --git a/include/envs.h b/include/envs.h index 1f6d33e6..fc276f8f 100644 --- a/include/envs.h +++ b/include/envs.h @@ -57,10 +57,12 @@ static char *afl_environment_variables[] = { "AFL_FRIDA_DEBUG_MAPS", "AFL_FRIDA_DRIVER_NO_HOOK", "AFL_FRIDA_EXCLUDE_RANGES", + "AFL_FRIDA_INST_CACHE_SIZE", "AFL_FRIDA_INST_COVERAGE_FILE", "AFL_FRIDA_INST_DEBUG_FILE", "AFL_FRIDA_INST_INSN", "AFL_FRIDA_INST_JIT", + "AFL_FRIDA_INST_NO_CACHE", "AFL_FRIDA_INST_NO_OPTIMIZE", "AFL_FRIDA_INST_NO_PREFETCH", "AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH", -- cgit 1.4.1 From 51dbd0e9571db5404b7c74169965367800b093db Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Wed, 30 Mar 2022 20:46:57 +0200 Subject: ignore unused variable to let make DEBUG=1 distrib succeed --- frida_mode/src/instrument/instrument_x64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'frida_mode/src') diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c index 0bff3e02..d54c8353 100644 --- a/frida_mode/src/instrument/instrument_x64.c +++ b/frida_mode/src/instrument/instrument_x64.c @@ -336,7 +336,7 @@ void instrument_coverage_optimize(const cs_insn * instr, GumStalkerOutput *output) { GumX86Writer *cw = output->writer.x86; - guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address)); + /* guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address)); */ if (instrument_previous_pc_addr == NULL) { GumAddressSpec spec = {.near_address = cw->code, -- cgit 1.4.1 From 2d7ac5f69c6016af3f9c4c2bbd45816d6db2fc70 Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Thu, 31 Mar 2022 18:11:24 +0100 Subject: frida mode fix arm64 build --- frida_mode/src/instrument/instrument_arm64.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'frida_mode/src') diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c index eb736386..e6251cb4 100644 --- a/frida_mode/src/instrument/instrument_arm64.c +++ b/frida_mode/src/instrument/instrument_arm64.c @@ -18,6 +18,8 @@ #if defined(__aarch64__) +gboolean instrument_cache_enabled = FALSE; +gsize instrument_cache_size = 0; static GHashTable *coverage_blocks = NULL; __attribute__((aligned(0x1000))) static guint8 area_ptr_dummy[MAP_SIZE]; -- cgit 1.4.1