aboutsummaryrefslogtreecommitdiff
path: root/frida_mode/src/instrument
diff options
context:
space:
mode:
Diffstat (limited to 'frida_mode/src/instrument')
-rw-r--r--frida_mode/src/instrument/instrument_x64.c344
1 files changed, 59 insertions, 285 deletions
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));