Skip to content

Commit 0e9f87a

Browse files
author
ChasonTang
authored
fix(iOS): fishhook crash (#926)
1 parent c1c4f25 commit 0e9f87a

File tree

1 file changed

+31
-14
lines changed

1 file changed

+31
-14
lines changed

iOS/DoraemonKit/Src/Core/Util/fishhook/doraemon_fishhook.c

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include "doraemon_fishhook.h"
99

10+
#include <assert.h>
1011
#include <dlfcn.h>
1112
#include <stdbool.h>
1213
#include <stdlib.h>
@@ -96,10 +97,35 @@ static void doraemon_perform_rebinding_with_section(struct doraemon_rebindings_e
9697
const bool isDataConst = strcmp(section->segname, "__DATA_CONST") == 0;
9798
uint32_t *indirect_symbol_indices = indirect_symtab + section->reserved1;
9899
void **indirect_symbol_bindings = (void **)((uintptr_t)slide + section->addr);
99-
vm_prot_t oldProtection = VM_PROT_READ;
100+
vm_prot_t oldProtection = VM_PROT_NONE;
101+
vm_address_t vmAddress = (vm_address_t)indirect_symbol_bindings;
102+
// https://opensource.apple.com/source/xnu/xnu-7195.141.2/osfmk/vm/vm_user.c.auto.html
103+
// OUT argument, but init with zero to eliminate `Variable 'vmSize' may be uninitialized when used here` warning
104+
vm_size_t vmSize = 0;
100105
if (isDataConst) {
101-
oldProtection = doraemon_get_protection(rebindings);
102-
mprotect(indirect_symbol_bindings, section->size, PROT_READ | PROT_WRITE);
106+
memory_object_name_t object;
107+
#ifdef __LP64__
108+
mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64;
109+
vm_region_basic_info_data_64_t vmRegionBasicInfoData;
110+
kern_return_t kernelReturn = vm_region_64(mach_task_self(), &vmAddress, &vmSize, VM_REGION_BASIC_INFO_64, (vm_region_info_t)&vmRegionBasicInfoData, &count, &object);
111+
#else
112+
mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT;
113+
vm_region_basic_info_data_t vmRegionBasicInfoData;
114+
kern_return_t kernelReturn = vm_region(mach_task_self(), &vmAddress, &vmSize, VM_REGION_BASIC_INFO, (vm_region_info_t)&vmRegionBasicInfoData, &count, object);
115+
#endif
116+
if (__builtin_expect(kernelReturn == KERN_SUCCESS, true)) {
117+
oldProtection = vmRegionBasicInfoData.protection;
118+
} else {
119+
assert(false && "vm_region() failure.");
120+
121+
return;
122+
}
123+
kernelReturn = vm_protect(mach_task_self(), vmAddress, vmSize, false, oldProtection | VM_PROT_WRITE);
124+
if (__builtin_expect(kernelReturn != KERN_SUCCESS, false)) {
125+
assert(false && "vm_protect() failure.");
126+
127+
return;
128+
}
103129
}
104130
for (uint i = 0; i < section->size / sizeof(void *); i++) {
105131
uint32_t symtab_index = indirect_symbol_indices[i];
@@ -128,17 +154,8 @@ static void doraemon_perform_rebinding_with_section(struct doraemon_rebindings_e
128154
symbol_loop:;
129155
}
130156
if (isDataConst) {
131-
int protection = 0;
132-
if (oldProtection & VM_PROT_READ) {
133-
protection |= PROT_READ;
134-
}
135-
if (oldProtection & VM_PROT_WRITE) {
136-
protection |= PROT_WRITE;
137-
}
138-
if (oldProtection & VM_PROT_EXECUTE) {
139-
protection |= PROT_EXEC;
140-
}
141-
mprotect(indirect_symbol_bindings, section->size, protection);
157+
kern_return_t kernelReturn = vm_protect(mach_task_self(), vmAddress, vmSize, false, oldProtection);
158+
assert(kernelReturn == KERN_SUCCESS && "vm_protect() failure.");
142159
}
143160
}
144161

0 commit comments

Comments
 (0)