@@ -81,12 +81,13 @@ static int prepend_rebindings(struct rebindings_entry **rebindings_head,
81
81
return 0 ;
82
82
}
83
83
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 ) {
85
86
mach_port_t task = mach_task_self ();
86
87
vm_size_t size = 0 ;
87
- vm_address_t address = (vm_address_t )sectionStart ;
88
+ vm_address_t address = (vm_address_t )addr ;
88
89
memory_object_name_t object ;
89
- #if __LP64__
90
+ #ifdef __LP64__
90
91
mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64 ;
91
92
vm_region_basic_info_data_64_t info ;
92
93
kern_return_t info_ret = vm_region_64 (
@@ -97,25 +98,28 @@ static vm_prot_t get_protection(void *sectionStart) {
97
98
kern_return_t info_ret = vm_region (task , & address , & size , VM_REGION_BASIC_INFO , (vm_region_info_t )& info , & count , & object );
98
99
#endif
99
100
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 ;
103
108
}
109
+
110
+ return -1 ;
104
111
}
112
+ #endif
113
+
105
114
static void perform_rebinding_with_section (struct rebindings_entry * rebindings ,
106
115
section_t * section ,
107
116
intptr_t slide ,
108
117
nlist_t * symtab ,
109
118
char * strtab ,
110
119
uint32_t * indirect_symtab ) {
111
- const bool isDataConst = strcmp (section -> segname , SEG_DATA_CONST ) == 0 ;
112
120
uint32_t * indirect_symbol_indices = indirect_symtab + section -> reserved1 ;
113
121
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
+
119
123
for (uint i = 0 ; i < section -> size / sizeof (void * ); i ++ ) {
120
124
uint32_t symtab_index = indirect_symbol_indices [i ];
121
125
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,
128
132
struct rebindings_entry * cur = rebindings ;
129
133
while (cur ) {
130
134
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 )
135
139
* (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 ;
136
157
}
137
- indirect_symbol_bindings [i ] = cur -> rebindings [j ].replacement ;
138
158
goto symbol_loop ;
139
159
}
140
160
}
141
161
cur = cur -> next ;
142
162
}
143
163
symbol_loop :;
144
164
}
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
- }
158
165
}
159
166
160
167
static void rebind_symbols_for_image (struct rebindings_entry * rebindings ,
0 commit comments