Skip to content

Commit aadc161

Browse files
authored
Merge pull request #87 from haolianfu/perfect_fix_crash_on_iOS15
Fixed the crash on iOS 15 perfectly: changing vm prot according to wh…
2 parents 8ef82f0 + 31e5182 commit aadc161

File tree

1 file changed

+37
-30
lines changed

1 file changed

+37
-30
lines changed

fishhook.c

+37-30
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,13 @@ static int prepend_rebindings(struct rebindings_entry **rebindings_head,
8181
return 0;
8282
}
8383

84-
static vm_prot_t get_protection(void *sectionStart) {
84+
#if 0
85+
static int get_protection(void *addr, vm_prot_t *prot, vm_prot_t *max_prot) {
8586
mach_port_t task = mach_task_self();
8687
vm_size_t size = 0;
87-
vm_address_t address = (vm_address_t)sectionStart;
88+
vm_address_t address = (vm_address_t)addr;
8889
memory_object_name_t object;
89-
#if __LP64__
90+
#ifdef __LP64__
9091
mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64;
9192
vm_region_basic_info_data_64_t info;
9293
kern_return_t info_ret = vm_region_64(
@@ -97,25 +98,28 @@ static vm_prot_t get_protection(void *sectionStart) {
9798
kern_return_t info_ret = vm_region(task, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)&info, &count, &object);
9899
#endif
99100
if (info_ret == KERN_SUCCESS) {
100-
return info.protection;
101-
} else {
102-
return VM_PROT_READ;
101+
if (prot != NULL)
102+
*prot = info.protection;
103+
104+
if (max_prot != NULL)
105+
*max_prot = info.max_protection;
106+
107+
return 0;
103108
}
109+
110+
return -1;
104111
}
112+
#endif
113+
105114
static void perform_rebinding_with_section(struct rebindings_entry *rebindings,
106115
section_t *section,
107116
intptr_t slide,
108117
nlist_t *symtab,
109118
char *strtab,
110119
uint32_t *indirect_symtab) {
111-
const bool isDataConst = strcmp(section->segname, SEG_DATA_CONST) == 0;
112120
uint32_t *indirect_symbol_indices = indirect_symtab + section->reserved1;
113121
void **indirect_symbol_bindings = (void **)((uintptr_t)slide + section->addr);
114-
vm_prot_t oldProtection = VM_PROT_READ;
115-
if (isDataConst) {
116-
oldProtection = get_protection(rebindings);
117-
mprotect(indirect_symbol_bindings, section->size, PROT_READ | PROT_WRITE);
118-
}
122+
119123
for (uint i = 0; i < section->size / sizeof(void *); i++) {
120124
uint32_t symtab_index = indirect_symbol_indices[i];
121125
if (symtab_index == INDIRECT_SYMBOL_ABS || symtab_index == INDIRECT_SYMBOL_LOCAL ||
@@ -128,33 +132,36 @@ static void perform_rebinding_with_section(struct rebindings_entry *rebindings,
128132
struct rebindings_entry *cur = rebindings;
129133
while (cur) {
130134
for (uint j = 0; j < cur->rebindings_nel; j++) {
131-
if (symbol_name_longer_than_1 &&
132-
strcmp(&symbol_name[1], cur->rebindings[j].name) == 0) {
133-
if (cur->rebindings[j].replaced != NULL &&
134-
indirect_symbol_bindings[i] != cur->rebindings[j].replacement) {
135+
if (symbol_name_longer_than_1 && strcmp(&symbol_name[1], cur->rebindings[j].name) == 0) {
136+
kern_return_t err;
137+
138+
if (cur->rebindings[j].replaced != NULL && indirect_symbol_bindings[i] != cur->rebindings[j].replacement)
135139
*(cur->rebindings[j].replaced) = indirect_symbol_bindings[i];
140+
141+
/**
142+
* 1. Moved the vm protection modifying codes to here to reduce the
143+
* changing scope.
144+
* 2. Adding VM_PROT_WRITE mode unconditionally because vm_region
145+
* API on some iOS/Mac reports mismatch vm protection attributes.
146+
* -- Lianfu Hao Jun 16th, 2021
147+
**/
148+
err = vm_protect (mach_task_self (), (uintptr_t)indirect_symbol_bindings, section->size, 0, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY);
149+
if (err == KERN_SUCCESS) {
150+
/**
151+
* Once we failed to change the vm protection, we
152+
* MUST NOT continue the following write actions!
153+
* iOS 15 has corrected the const segments prot.
154+
* -- Lionfore Hao Jun 11th, 2021
155+
**/
156+
indirect_symbol_bindings[i] = cur->rebindings[j].replacement;
136157
}
137-
indirect_symbol_bindings[i] = cur->rebindings[j].replacement;
138158
goto symbol_loop;
139159
}
140160
}
141161
cur = cur->next;
142162
}
143163
symbol_loop:;
144164
}
145-
if (isDataConst) {
146-
int protection = 0;
147-
if (oldProtection & VM_PROT_READ) {
148-
protection |= PROT_READ;
149-
}
150-
if (oldProtection & VM_PROT_WRITE) {
151-
protection |= PROT_WRITE;
152-
}
153-
if (oldProtection & VM_PROT_EXECUTE) {
154-
protection |= PROT_EXEC;
155-
}
156-
mprotect(indirect_symbol_bindings, section->size, protection);
157-
}
158165
}
159166

160167
static void rebind_symbols_for_image(struct rebindings_entry *rebindings,

0 commit comments

Comments
 (0)