From c7810b6736d2f53cd0535c5fb1107cdd30e32c3a Mon Sep 17 00:00:00 2001 From: wangzinong Date: Fri, 5 Feb 2021 18:50:01 +0800 Subject: [PATCH 1/2] fix the code indentation --- fishhook.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/fishhook.c b/fishhook.c index 026a5c0..2b642b8 100644 --- a/fishhook.c +++ b/fishhook.c @@ -89,8 +89,7 @@ static vm_prot_t get_protection(void *sectionStart) { #if __LP64__ mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64; vm_region_basic_info_data_64_t info; - kern_return_t info_ret = vm_region_64( - task, &address, &size, VM_REGION_BASIC_INFO_64, (vm_region_info_64_t)&info, &count, &object); + kern_return_t info_ret = vm_region_64(task, &address, &size, VM_REGION_BASIC_INFO_64, (vm_region_info_64_t)&info, &count, &object); #else mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT; vm_region_basic_info_data_t info; @@ -119,7 +118,7 @@ static void perform_rebinding_with_section(struct rebindings_entry *rebindings, for (uint i = 0; i < section->size / sizeof(void *); i++) { uint32_t symtab_index = indirect_symbol_indices[i]; if (symtab_index == INDIRECT_SYMBOL_ABS || symtab_index == INDIRECT_SYMBOL_LOCAL || - symtab_index == (INDIRECT_SYMBOL_LOCAL | INDIRECT_SYMBOL_ABS)) { + symtab_index == (INDIRECT_SYMBOL_LOCAL | INDIRECT_SYMBOL_ABS)) { continue; } uint32_t strtab_offset = symtab[symtab_index].n_un.n_strx; @@ -221,21 +220,21 @@ static void rebind_symbols_for_image(struct rebindings_entry *rebindings, static void _rebind_symbols_for_image(const struct mach_header *header, intptr_t slide) { - rebind_symbols_for_image(_rebindings_head, header, slide); + rebind_symbols_for_image(_rebindings_head, header, slide); } int rebind_symbols_image(void *header, intptr_t slide, struct rebinding rebindings[], size_t rebindings_nel) { - struct rebindings_entry *rebindings_head = NULL; - int retval = prepend_rebindings(&rebindings_head, rebindings, rebindings_nel); - rebind_symbols_for_image(rebindings_head, (const struct mach_header *) header, slide); - if (rebindings_head) { - free(rebindings_head->rebindings); - } - free(rebindings_head); - return retval; + struct rebindings_entry *rebindings_head = NULL; + int retval = prepend_rebindings(&rebindings_head, rebindings, rebindings_nel); + rebind_symbols_for_image(rebindings_head, (const struct mach_header *) header, slide); + if (rebindings_head) { + free(rebindings_head->rebindings); + } + free(rebindings_head); + return retval; } int rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel) { From e1f8e9b5410e13770b0aed7783d4e7e404b16810 Mon Sep 17 00:00:00 2001 From: wangzinong Date: Fri, 5 Feb 2021 18:59:37 +0800 Subject: [PATCH 2/2] add write protection when writing data section --- fishhook.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/fishhook.c b/fishhook.c index 2b642b8..3121d1e 100644 --- a/fishhook.c +++ b/fishhook.c @@ -54,6 +54,10 @@ typedef struct nlist nlist_t; #define SEG_DATA_CONST "__DATA_CONST" #endif +#ifndef SEG_AUTH_CONST +#define SEG_AUTH_CONST "__AUTH_CONST" +#endif + struct rebindings_entry { struct rebinding *rebindings; size_t rebindings_nel; @@ -101,20 +105,15 @@ static vm_prot_t get_protection(void *sectionStart) { return VM_PROT_READ; } } + static void perform_rebinding_with_section(struct rebindings_entry *rebindings, section_t *section, intptr_t slide, nlist_t *symtab, char *strtab, uint32_t *indirect_symtab) { - const bool isDataConst = strcmp(section->segname, SEG_DATA_CONST) == 0; uint32_t *indirect_symbol_indices = indirect_symtab + section->reserved1; void **indirect_symbol_bindings = (void **)((uintptr_t)slide + section->addr); - vm_prot_t oldProtection = VM_PROT_READ; - if (isDataConst) { - oldProtection = get_protection(rebindings); - mprotect(indirect_symbol_bindings, section->size, PROT_READ | PROT_WRITE); - } for (uint i = 0; i < section->size / sizeof(void *); i++) { uint32_t symtab_index = indirect_symbol_indices[i]; if (symtab_index == INDIRECT_SYMBOL_ABS || symtab_index == INDIRECT_SYMBOL_LOCAL || @@ -133,7 +132,20 @@ static void perform_rebinding_with_section(struct rebindings_entry *rebindings, indirect_symbol_bindings[i] != cur->rebindings[j].replacement) { *(cur->rebindings[j].replaced) = indirect_symbol_bindings[i]; } + bool is_prot_changed = false; + void **address_to_write = indirect_symbol_bindings + i; + vm_prot_t prot = get_protection(address_to_write); + if ((prot & VM_PROT_WRITE) == 0) { + is_prot_changed = true; + kern_return_t success = vm_protect(mach_task_self(), (vm_address_t)address_to_write, sizeof(void *), false, prot | VM_PROT_WRITE); + if (success != KERN_SUCCESS) { + goto symbol_loop; + } + } indirect_symbol_bindings[i] = cur->rebindings[j].replacement; + if (is_prot_changed) { + vm_protect(mach_task_self(), (vm_address_t)address_to_write, sizeof(void *), false, prot); + } goto symbol_loop; } } @@ -141,19 +153,6 @@ static void perform_rebinding_with_section(struct rebindings_entry *rebindings, } symbol_loop:; } - if (isDataConst) { - int protection = 0; - if (oldProtection & VM_PROT_READ) { - protection |= PROT_READ; - } - if (oldProtection & VM_PROT_WRITE) { - protection |= PROT_WRITE; - } - if (oldProtection & VM_PROT_EXECUTE) { - protection |= PROT_EXEC; - } - mprotect(indirect_symbol_bindings, section->size, protection); - } } static void rebind_symbols_for_image(struct rebindings_entry *rebindings, @@ -201,7 +200,8 @@ static void rebind_symbols_for_image(struct rebindings_entry *rebindings, cur_seg_cmd = (segment_command_t *)cur; if (cur_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { if (strcmp(cur_seg_cmd->segname, SEG_DATA) != 0 && - strcmp(cur_seg_cmd->segname, SEG_DATA_CONST) != 0) { + strcmp(cur_seg_cmd->segname, SEG_DATA_CONST) != 0 && + strcmp(cur_seg_cmd->segname, SEG_AUTH_CONST) != 0) { continue; } for (uint j = 0; j < cur_seg_cmd->nsects; j++) {