From 5bee8dcbbbd3882118cf47d4dddced9b2aac205a Mon Sep 17 00:00:00 2001 From: Huang-Libo Date: Sun, 12 Sep 2021 00:45:10 +0800 Subject: [PATCH] Merge https://github.com/facebook/fishhook/pull/87 --- fishhook.c | 67 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/fishhook.c b/fishhook.c index 026a5c0..fb41e8e 100644 --- a/fishhook.c +++ b/fishhook.c @@ -81,12 +81,13 @@ static int prepend_rebindings(struct rebindings_entry **rebindings_head, return 0; } -static vm_prot_t get_protection(void *sectionStart) { +#if 0 +static int get_protection(void *addr, vm_prot_t *prot, vm_prot_t *max_prot) { mach_port_t task = mach_task_self(); vm_size_t size = 0; - vm_address_t address = (vm_address_t)sectionStart; + vm_address_t address = (vm_address_t)addr; memory_object_name_t object; -#if __LP64__ +#ifdef __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( @@ -97,25 +98,28 @@ static vm_prot_t get_protection(void *sectionStart) { kern_return_t info_ret = vm_region(task, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)&info, &count, &object); #endif if (info_ret == KERN_SUCCESS) { - return info.protection; - } else { - return VM_PROT_READ; + if (prot != NULL) + *prot = info.protection; + + if (max_prot != NULL) + *max_prot = info.max_protection; + + return 0; } + + return -1; } +#endif + 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 || @@ -128,13 +132,29 @@ static void perform_rebinding_with_section(struct rebindings_entry *rebindings, struct rebindings_entry *cur = rebindings; while (cur) { for (uint j = 0; j < cur->rebindings_nel; j++) { - if (symbol_name_longer_than_1 && - strcmp(&symbol_name[1], cur->rebindings[j].name) == 0) { - if (cur->rebindings[j].replaced != NULL && - indirect_symbol_bindings[i] != cur->rebindings[j].replacement) { + if (symbol_name_longer_than_1 && strcmp(&symbol_name[1], cur->rebindings[j].name) == 0) { + kern_return_t err; + + if (cur->rebindings[j].replaced != NULL && indirect_symbol_bindings[i] != cur->rebindings[j].replacement) *(cur->rebindings[j].replaced) = indirect_symbol_bindings[i]; + + /** + * 1. Moved the vm protection modifying codes to here to reduce the + * changing scope. + * 2. Adding VM_PROT_WRITE mode unconditionally because vm_region + * API on some iOS/Mac reports mismatch vm protection attributes. + * -- Lianfu Hao Jun 16th, 2021 + **/ + err = vm_protect (mach_task_self (), (uintptr_t)indirect_symbol_bindings, section->size, 0, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY); + if (err == KERN_SUCCESS) { + /** + * Once we failed to change the vm protection, we + * MUST NOT continue the following write actions! + * iOS 15 has corrected the const segments prot. + * -- Lionfore Hao Jun 11th, 2021 + **/ + indirect_symbol_bindings[i] = cur->rebindings[j].replacement; } - indirect_symbol_bindings[i] = cur->rebindings[j].replacement; goto symbol_loop; } } @@ -142,19 +162,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,