Root/
Source at commit 355 created 13 years 8 months ago. By meklort, Fixed the rebase + bind code, now works properly. Removed a few ugly hacks. KernelPatcher now loads properly (no more reboots). | |
---|---|
1 | /*␊ |
2 | * Copyright 2009 Evan Lojewski. All rights reserved.␊ |
3 | *␊ |
4 | */␊ |
5 | ␊ |
6 | #include "boot.h"␊ |
7 | #include "bootstruct.h"␊ |
8 | #include "multiboot.h"␊ |
9 | #include "modules.h"␊ |
10 | ␊ |
11 | ␊ |
12 | moduleList_t* loadedModules = NULL;␊ |
13 | symbolList_t* moduleSymbols = NULL;␊ |
14 | unsigned int (*lookup_symbol)(const char*) = NULL;␊ |
15 | ␊ |
16 | ␊ |
17 | void rebase_macho(void* base, char* rebase_stream, UInt32 size);␊ |
18 | void bind_macho(void* base, char* bind_stream, UInt32 size);␊ |
19 | ␊ |
20 | /*␊ |
21 | * Load a module file in /Extra/modules␊ |
22 | * TODO: verify version number of module␊ |
23 | */␊ |
24 | int load_module(const char* module)␊ |
25 | {␊ |
26 | ␉// Check to see if the module has already been loaded␊ |
27 | ␉if(is_module_laoded(module))␊ |
28 | ␉{␊ |
29 | ␉␉return 1;␊ |
30 | ␉}␊ |
31 | ␉␊ |
32 | ␉char modString[128];␊ |
33 | ␉int fh = -1;␊ |
34 | ␉sprintf(modString, "/Extra/modules/%s.dylib", module);␊ |
35 | ␉fh = open(modString, 0);␊ |
36 | ␉if(fh < 0)␊ |
37 | ␉{␊ |
38 | ␉␉printf("Unable to locate module %s\n", modString);␊ |
39 | ␉␉getc();␊ |
40 | ␉␉return ERROR;␊ |
41 | ␉}␊ |
42 | ␉␊ |
43 | ␉unsigned int moduleSize = file_size(fh);␊ |
44 | ␉char* module_base = (char*) malloc(moduleSize);␊ |
45 | ␉if (read(fh, module_base, moduleSize) == moduleSize)␊ |
46 | ␉{␊ |
47 | ␉␉void (*module_start)(void) = NULL;␊ |
48 | ␊ |
49 | ␉␉printf("Module %s read in.\n", modString);␊ |
50 | ␊ |
51 | ␉␉// Module loaded into memory, parse it␊ |
52 | ␉␉module_start = parse_mach(module_base);␊ |
53 | ␊ |
54 | ␉␉if(module_start)␊ |
55 | ␉␉{␊ |
56 | ␉␉␉(*module_start)();␉// Start the module␊ |
57 | ␉␉␉printf("Module started\n");␊ |
58 | ␉␉}␊ |
59 | ␉␉else {␊ |
60 | ␉␉␉printf("Unabel to locate module start\n");␊ |
61 | ␉␉}␊ |
62 | ␊ |
63 | ␉␉␊ |
64 | ␉␉getc();␊ |
65 | ␉␉␊ |
66 | ␉␉// TODO: Add module to loaded list if loaded successfuly␊ |
67 | ␉␉␊ |
68 | ␉}␊ |
69 | ␉else␊ |
70 | ␉{␊ |
71 | ␉␉printf("Unable to read in module %s.dylib\n.", module);␊ |
72 | ␉␉getc();␊ |
73 | ␉}␊ |
74 | ␉return 1;␊ |
75 | }␊ |
76 | ␊ |
77 | ␊ |
78 | void* parse_mach(void* binary)␊ |
79 | {␊ |
80 | ␉void (*module_start)(void) = NULL;␊ |
81 | ␊ |
82 | ␊ |
83 | ␉char* moduleName = NULL;␊ |
84 | ␉UInt32 moduleVersion = 0;␊ |
85 | ␉UInt32 moduleCompat = 0;␊ |
86 | ␉␊ |
87 | ␉char* symbolStub = NULL;␊ |
88 | ␉char* nonlazy = NULL;␊ |
89 | ␉//char* nonlazy_variables = NULL;␊ |
90 | ␊ |
91 | ␉// TODO convert all of the structs a union␊ |
92 | ␉struct load_command *loadCommand = NULL;␊ |
93 | ␉struct dylib_command* dylibCommand = NULL;␊ |
94 | ␉struct dyld_info_command* dyldInfoCommand = NULL;␊ |
95 | ␉struct symtab_command* symtabCommand = NULL;␊ |
96 | ␉struct segment_command* segmentCommand = NULL;␊ |
97 | ␉struct dysymtab_command* dysymtabCommand = NULL;␊ |
98 | ␉struct section* section = NULL;␊ |
99 | ␉UInt32 binaryIndex = sizeof(struct mach_header);␊ |
100 | ␉UInt16 cmd = 0;␊ |
101 | ␊ |
102 | ␉// Parse hthrough th eload commands␊ |
103 | ␉if(((struct mach_header*)binary)->magic != MH_MAGIC)␊ |
104 | ␉{␊ |
105 | ␉␉printf("Module is not 32bit\n");␊ |
106 | ␉␉return NULL;␉// 32bit only␊ |
107 | ␉}␊ |
108 | ␉␊ |
109 | ␉if(((struct mach_header*)binary)->filetype != MH_DYLIB)␊ |
110 | ␉{␊ |
111 | ␉␉printf("Module is not a dylib. Unable to load.\n");␊ |
112 | ␉␉return NULL; // Module is in the incorrect format␊ |
113 | ␉}␊ |
114 | ␉␊ |
115 | ␉while(cmd < ((struct mach_header*)binary)->ncmds)␉// TODO: for loop instead␊ |
116 | ␉{␊ |
117 | ␉␉cmd++;␊ |
118 | ␉␉␊ |
119 | ␉␉loadCommand = binary + binaryIndex;␊ |
120 | ␉␉UInt32 cmdSize = loadCommand->cmdsize;␊ |
121 | ␊ |
122 | ␉␉␊ |
123 | ␉␉switch ((loadCommand->cmd & 0x7FFFFFFF))␊ |
124 | ␉␉{␊ |
125 | ␉␉␉case LC_SYMTAB:␊ |
126 | ␉␉␉␉symtabCommand = binary + binaryIndex;␊ |
127 | ␉␉␉␉break;␊ |
128 | ␉␉␉case LC_SEGMENT:␊ |
129 | ␉␉␉␉segmentCommand = binary + binaryIndex;␊ |
130 | ␊ |
131 | ␉␉␉␉UInt32 sections = segmentCommand->nsects;␊ |
132 | ␉␉␉␉section = binary + binaryIndex + sizeof(struct segment_command);␊ |
133 | ␉␉␉␉while(sections)␊ |
134 | ␉␉␉␉{␊ |
135 | ␉␉␉␉␉// Look for the __symbol_stub section␊ |
136 | ␉␉␉␉␉if(strcmp(section->sectname, SECT_NON_LAZY_SYMBOL_PTR) == 0)␊ |
137 | ␉␉␉␉␉{␊ |
138 | ␉␉␉␉␉␉/*printf("\tSection non lazy pointers at 0x%X, %d symbols\n",␊ |
139 | ␉␉␉␉␉␉␉ section->offset, ␊ |
140 | ␉␉␉␉␉␉␉ section->size / 4);␊ |
141 | ␉␉␉␉␉␉*/␊ |
142 | ␉␉␉␉␉␉switch(section->flags)␊ |
143 | ␉␉␉␉␉␉{␊ |
144 | ␉␉␉␉␉␉␉case S_NON_LAZY_SYMBOL_POINTERS:␊ |
145 | ␉␉␉␉␉␉␉␉//printf("%s S_NON_LAZY_SYMBOL_POINTERS section\n", SECT_NON_LAZY_SYMBOL_PTR);␊ |
146 | ␊ |
147 | ␉␉␉␉␉␉␉␉//nonlazy_variables = binary + section->offset;␊ |
148 | ␉␉␉␉␉␉␉␉nonlazy = binary + section->offset;␊ |
149 | ␉␉␉␉␉␉␉␉break;␊ |
150 | ␉␉␉␉␉␉␉␉␊ |
151 | ␉␉␉␉␉␉␉case S_LAZY_SYMBOL_POINTERS:␊ |
152 | ␉␉␉␉␉␉␉␉//nonlazy = binary + section->offset;␊ |
153 | ␉␉␉␉␉␉␉␉//printf("%s S_LAZY_SYMBOL_POINTERS section, 0x%X\n", SECT_NON_LAZY_SYMBOL_PTR, nonlazy);␊ |
154 | ␉␉␉␉␉␉␉␉// Fucntions␊ |
155 | ␉␉␉␉␉␉␉␉break;␊ |
156 | ␉␉␉␉␉␉␉␉␊ |
157 | ␉␉␉␉␉␉␉default:␊ |
158 | ␉␉␉␉␉␉␉␉//printf("Unhandled %s section\n", SECT_NON_LAZY_SYMBOL_PTR);␊ |
159 | ␉␉␉␉␉␉␉␉//getc();␊ |
160 | ␉␉␉␉␉␉␉␉break;␊ |
161 | ␉␉␉␉␉␉}␊ |
162 | ␉␉␉␉␉␉//getc();␊ |
163 | ␉␉␉␉␉}␊ |
164 | ␉␉␉␉␉else if(strcmp(section->sectname, SECT_SYMBOL_STUBS) == 0)␊ |
165 | ␉␉␉␉␉{␊ |
166 | ␉␉␉␉␉␉/*printf("\tSection __symbol_stub at 0x%X (0x%X), %d symbols\n",␊ |
167 | ␉␉␉␉␉␉␉ section->offset, ␊ |
168 | ␉␉␉␉␉␉␉ section->size / 6);*/␊ |
169 | ␉␉␉␉␉␉symbolStub = binary + section->offset;␊ |
170 | ␉␉␉␉␉␉//getc();␊ |
171 | ␉␉␉␉␉}␊ |
172 | ␉␉␉␉␉else ␊ |
173 | ␉␉␉␉␉{␊ |
174 | ␉␉␉␉␉␉//printf("Unhandled section %s\n", section->sectname);␊ |
175 | ␉␉␉␉␉}␊ |
176 | ␊ |
177 | ␊ |
178 | ␉␉␉␉␉␊ |
179 | ␉␉␉␉␉sections--;␊ |
180 | ␉␉␉␉␉section++;␊ |
181 | ␉␉␉␉}␊ |
182 | ␉␉␉␉␉␉ ␊ |
183 | ␉␉␉␉␊ |
184 | ␉␉␉␉break;␊ |
185 | ␉␉␉␉␊ |
186 | ␉␉␉case LC_DYSYMTAB:␊ |
187 | ␉␉␉␉dysymtabCommand = binary + binaryIndex;␊ |
188 | ␉␉␉␉//printf("Unhandled loadcommand LC_DYSYMTAB\n");␊ |
189 | ␉␉␉␉break;␊ |
190 | ␉␉␉␉␊ |
191 | ␉␉␉case LC_LOAD_DYLIB:␊ |
192 | ␉␉␉case LC_LOAD_WEAK_DYLIB ^ LC_REQ_DYLD:␊ |
193 | ␉␉␉␉dylibCommand = binary + binaryIndex;␊ |
194 | ␉␉␉␉char* module = binary + binaryIndex + ((UInt32)*((UInt32*)&dylibCommand->dylib.name));␊ |
195 | ␉␉␉␉// =␉dylibCommand->dylib.current_version;␊ |
196 | ␉␉␉␉// =␉dylibCommand->dylib.compatibility_version;␊ |
197 | ␊ |
198 | ␉␉␉␉load_module(module);␊ |
199 | ␉␉␉␉break;␊ |
200 | ␉␉␉␉␊ |
201 | ␉␉␉case LC_ID_DYLIB:␊ |
202 | ␉␉␉␉dylibCommand = binary + binaryIndex;␊ |
203 | ␉␉␉␉moduleName =␉binary + binaryIndex + ((UInt32)*((UInt32*)&dylibCommand->dylib.name));␊ |
204 | ␉␉␉␉moduleVersion =␉dylibCommand->dylib.current_version;␊ |
205 | ␉␉␉␉moduleCompat =␉dylibCommand->dylib.compatibility_version;␊ |
206 | ␉␉␉␉break;␊ |
207 | ␊ |
208 | ␉␉␉case LC_DYLD_INFO:␊ |
209 | ␉␉␉␉dyldInfoCommand = binary + binaryIndex;␊ |
210 | ␉␉␉␉/*␊ |
211 | ␉␉␉␉ printf("LC_DYLD_INFO:\n"␊ |
212 | ␉␉␉␉␉ "\tRebase Offset: 0x%X\n"␊ |
213 | ␉␉␉␉␉ "\tBind Offset: 0x%X\n"␊ |
214 | ␉␉␉␉␉ "\tWeak Bind Offset: 0x%X\n"␊ |
215 | ␉␉␉␉␉ "\tLazy Bind Offset: 0x%X\n"␊ |
216 | ␉␉␉␉␉ "\tExport Offset: 0x%X\n",␊ |
217 | ␉␉␉␉␉ dyldInfoCommand->rebase_off,␊ |
218 | ␉␉␉␉␉ dyldInfoCommand->bind_off,␊ |
219 | ␉␉␉␉␉ dyldInfoCommand->weak_bind_off,␊ |
220 | ␉␉␉␉␉ dyldInfoCommand->lazy_bind_off,␊ |
221 | ␉␉␉␉␉ dyldInfoCommand->export_off);␊ |
222 | ␉␉␉␉*/␊ |
223 | ␉␉␉␉␊ |
224 | ␉␉␉␉␊ |
225 | ␉␉␉␉break;␊ |
226 | ␉␉␉␉␊ |
227 | ␉␉␉case LC_UUID:␊ |
228 | ␉␉␉␉// We don't care about the UUID at the moment␊ |
229 | ␉␉␉␉break;␊ |
230 | ␉␉␉␉␊ |
231 | ␉␉␉default:␊ |
232 | ␉␉␉␉printf("Unhandled loadcommand 0x%X\n", loadCommand->cmd & 0x7FFFFFFF);␊ |
233 | ␉␉␉␉break;␊ |
234 | ␉␉␊ |
235 | ␉␉}␊ |
236 | ␊ |
237 | ␉␉binaryIndex += cmdSize;␊ |
238 | ␉}␊ |
239 | ␉if(!moduleName) return NULL;␊ |
240 | ␉␉␊ |
241 | ␊ |
242 | ␉// bind_macho uses the symbols added in for some reason...␊ |
243 | ␉module_start = (void*)handle_symtable((UInt32)binary, symtabCommand, symbolStub, (UInt32)nonlazy);␊ |
244 | ␊ |
245 | ␉␊ |
246 | ␉if(dyldInfoCommand && dyldInfoCommand->rebase_off)␊ |
247 | ␉{␊ |
248 | ␉␉rebase_macho(binary, (char*)dyldInfoCommand->rebase_off, dyldInfoCommand->rebase_size);␊ |
249 | ␉}␊ |
250 | ␉␊ |
251 | ␉if(dyldInfoCommand && dyldInfoCommand->bind_off)␊ |
252 | ␉{␊ |
253 | ␉␉bind_macho(binary, (char*)dyldInfoCommand->bind_off, dyldInfoCommand->bind_size);␊ |
254 | ␉}␊ |
255 | ␉␊ |
256 | ␉if(dyldInfoCommand && dyldInfoCommand->weak_bind_off)␊ |
257 | ␉{␊ |
258 | ␉␉bind_macho(binary, (char*)dyldInfoCommand->weak_bind_off, dyldInfoCommand->weak_bind_size);␊ |
259 | ␉}␊ |
260 | ␉␊ |
261 | ␉if(dyldInfoCommand && dyldInfoCommand->lazy_bind_off)␊ |
262 | ␉{␊ |
263 | ␉␉bind_macho(binary, (char*)dyldInfoCommand->lazy_bind_off, dyldInfoCommand->lazy_bind_size);␊ |
264 | ␉}␊ |
265 | ␉␊ |
266 | ␊ |
267 | ␉␊ |
268 | ␊ |
269 | ␉␊ |
270 | ␉// To satisfy cicular deps, the module_loaded command shoudl be run before the module init();␊ |
271 | ␉module_loaded(moduleName, moduleVersion, moduleCompat);␊ |
272 | ␉␊ |
273 | ␉return module_start;␊ |
274 | ␉␊ |
275 | }␊ |
276 | ␊ |
277 | ␊ |
278 | // Based on code from dylibinfo.cpp and ImageLoaderMachOCompressed.cpp␊ |
279 | void rebase_macho(void* base, char* rebase_stream, UInt32 size)␊ |
280 | {␊ |
281 | ␉rebase_stream += (UInt32)base;␊ |
282 | ␉␊ |
283 | ␉UInt8 immediate = 0;␊ |
284 | ␉UInt8 opcode = 0;␊ |
285 | ␉UInt8 type = 0;␊ |
286 | ␉␊ |
287 | ␉UInt32 segmentAddress = 0;␊ |
288 | ␉UInt32 address = 0;␊ |
289 | ␉␊ |
290 | ␉␊ |
291 | ␉␊ |
292 | ␉UInt32 tmp = 0;␊ |
293 | ␉UInt32 tmp2 = 0;␊ |
294 | ␉UInt8 bits = 0;␊ |
295 | ␉int index = 0;␊ |
296 | ␉␊ |
297 | ␉int done = 0;␊ |
298 | ␉unsigned int i = 0;␊ |
299 | ␉␊ |
300 | ␉while(/*!done &&*/ i < size)␊ |
301 | ␉{␊ |
302 | ␉␉immediate = rebase_stream[i] & REBASE_IMMEDIATE_MASK;␊ |
303 | ␉␉opcode = rebase_stream[i] & REBASE_OPCODE_MASK;␊ |
304 | ␊ |
305 | ␉␉␊ |
306 | ␉␉switch(opcode)␊ |
307 | ␉␉{␊ |
308 | ␉␉␉case REBASE_OPCODE_DONE:␊ |
309 | ␉␉␉␉// Rebase complete.␊ |
310 | ␉␉␉␉done = 1;␊ |
311 | ␉␉␉␉break;␊ |
312 | ␉␉␉␉␊ |
313 | ␉␉␉case REBASE_OPCODE_SET_TYPE_IMM:␊ |
314 | ␉␉␉␉// Set rebase type (pointer, absolute32, pcrel32)␊ |
315 | ␉␉␉␉//printf("Rebase type = 0x%X\n", immediate);␊ |
316 | ␉␉␉␉// NOTE: This is currently NOT used␊ |
317 | ␉␉␉␉type = immediate;␊ |
318 | ␉␉␉␉break;␊ |
319 | ␉␉␉␉␊ |
320 | ␉␉␉case REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:␊ |
321 | ␉␉␉␉// Locate address to begin rebasing␊ |
322 | ␉␉␉␉segmentAddress = 0;␊ |
323 | ␊ |
324 | ␉␉␉␉struct segment_command* segCommand = NULL;␊ |
325 | ␉␉␉␉␊ |
326 | ␉␉␉␉unsigned int binIndex = 0;␊ |
327 | ␉␉␉␉index = 0;␊ |
328 | ␉␉␉␉do␊ |
329 | ␉␉␉␉{␊ |
330 | ␉␉␉␉␉segCommand = base + sizeof(struct mach_header) + binIndex;␊ |
331 | ␉␉␉␉␉␊ |
332 | ␉␉␉␉␉␊ |
333 | ␉␉␉␉␉binIndex += segCommand->cmdsize;␊ |
334 | ␉␉␉␉␉index++;␊ |
335 | ␉␉␉␉}␊ |
336 | ␉␉␉␉while(index <= immediate);␊ |
337 | ␊ |
338 | ␊ |
339 | ␉␉␉␉segmentAddress = segCommand->fileoff;␊ |
340 | ␉␉␉␉␊ |
341 | ␉␉␉␉tmp = 0;␊ |
342 | ␉␉␉␉bits = 0;␊ |
343 | ␉␉␉␉do␊ |
344 | ␉␉␉␉{␊ |
345 | ␉␉␉␉␉tmp |= (rebase_stream[++i] & 0x7f) << bits;␊ |
346 | ␉␉␉␉␉bits += 7;␊ |
347 | ␉␉␉␉}␊ |
348 | ␉␉␉␉while(rebase_stream[i] & 0x80);␊ |
349 | ␉␉␉␉␊ |
350 | ␉␉␉␉segmentAddress += tmp;␊ |
351 | ␉␉␉␉␊ |
352 | ␉␉␉␉//printf("Address = 0x%X\n", segmentAddress);␊ |
353 | ␉␉␉␉break;␊ |
354 | ␉␉␉␉␊ |
355 | ␉␉␉case REBASE_OPCODE_ADD_ADDR_ULEB:␊ |
356 | ␉␉␉␉// Add value to rebase address␊ |
357 | ␉␉␉␉tmp = 0;␊ |
358 | ␉␉␉␉bits = 0;␊ |
359 | ␉␉␉␉do␊ |
360 | ␉␉␉␉{␊ |
361 | ␉␉␉␉␉tmp <<= bits;␊ |
362 | ␉␉␉␉␉tmp |= rebase_stream[++i] & 0x7f;␊ |
363 | ␉␉␉␉␉bits += 7;␊ |
364 | ␉␉␉␉}␊ |
365 | ␉␉␉␉while(rebase_stream[i] & 0x80);␊ |
366 | ␉␉␉␉␊ |
367 | ␉␉␉␉address +=␉tmp; ␊ |
368 | ␉␉␉␉//printf("Address (add) = 0x%X\n", address);␊ |
369 | ␉␉␉␉break;␊ |
370 | ␉␉␉␉␊ |
371 | ␉␉␉case REBASE_OPCODE_ADD_ADDR_IMM_SCALED:␊ |
372 | ␉␉␉␉address += immediate * sizeof(void*);␊ |
373 | ␉␉␉␉//printf("Address (immscaled) = 0x%X\n", address);␊ |
374 | ␊ |
375 | ␉␉␉␉break;␊ |
376 | ␉␉␉␉␊ |
377 | ␉␉␉case REBASE_OPCODE_DO_REBASE_IMM_TIMES:␊ |
378 | ␉␉␉␉//printf("Rebase %d time(s)\n", immediate);␊ |
379 | ␉␉␉␉index = 0;␊ |
380 | ␉␉␉␉for (index = 0; index < immediate; ++index) {␊ |
381 | ␉␉␉␉␉//printf("\tRebasing 0x%X\n", segmentAddress);␊ |
382 | ␉␉␉␉␉␊ |
383 | ␉␉␉␉␉UInt32* addr = base + segmentAddress;␊ |
384 | ␉␉␉␉␉addr[0] += (UInt32)base;␊ |
385 | ␉␉␉␉␉//if(type != REBASE_TYPE_POINTER) addr[0] -= 8;␊ |
386 | ␉␉␉␉␉␊ |
387 | ␉␉␉␉␉segmentAddress += sizeof(void*);␊ |
388 | ␉␉␉␉}␊ |
389 | ␉␉␉␉break;␊ |
390 | ␉␉␉␉␊ |
391 | ␉␉␉case REBASE_OPCODE_DO_REBASE_ULEB_TIMES:␊ |
392 | ␉␉␉␉tmp = 0;␊ |
393 | ␉␉␉␉bits = 0;␊ |
394 | ␉␉␉␉do␊ |
395 | ␉␉␉␉{␊ |
396 | ␉␉␉␉␉tmp |= (rebase_stream[++i] & 0x7f) << bits;␊ |
397 | ␉␉␉␉␉bits += 7;␊ |
398 | ␉␉␉␉}␊ |
399 | ␉␉␉␉while(rebase_stream[i] & 0x80);␊ |
400 | ␉␉␉␉␊ |
401 | ␉␉␉␉//printf("Rebase %d time(s)\n", tmp);␊ |
402 | ␉␉␉␉␊ |
403 | ␉␉␉␉index = 0;␊ |
404 | ␉␉␉␉for (index = 0; index < tmp; ++index) {␊ |
405 | ␉␉␉␉␉//printf("\tRebasing 0x%X\n", segmentAddress);␊ |
406 | ␉␉␉␉␉␊ |
407 | ␉␉␉␉␉UInt32* addr = base + segmentAddress;␊ |
408 | ␉␉␉␉␉addr[0] += (UInt32)base;␊ |
409 | ␊ |
410 | ␉␉␉␉␉//if(type != REBASE_TYPE_POINTER) addr[0] -= 8;␊ |
411 | ␉␉␉␉␉␊ |
412 | ␉␉␉␉␉segmentAddress += sizeof(void*);␊ |
413 | ␉␉␉␉}␊ |
414 | ␉␉␉␉break;␊ |
415 | ␉␉␉␉␊ |
416 | ␉␉␉case REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:␊ |
417 | ␉␉␉␉tmp = 0;␊ |
418 | ␉␉␉␉bits = 0;␊ |
419 | ␉␉␉␉do␊ |
420 | ␉␉␉␉{␊ |
421 | ␉␉␉␉␉tmp |= (rebase_stream[++i] & 0x7f) << bits;␊ |
422 | ␉␉␉␉␉bits += 7;␊ |
423 | ␉␉␉␉}␊ |
424 | ␉␉␉␉while(rebase_stream[i] & 0x80);␊ |
425 | ␉␉␉␉␊ |
426 | ␉␉␉␉␊ |
427 | ␉␉␉␉//printf("Rebase and add 0x%X\n", tmp);␊ |
428 | ␉␉␉␉//printf("\tRebasing 0x%X\n", segmentAddress);␊ |
429 | ␉␉␉␉UInt32* addr = base + segmentAddress;␊ |
430 | ␉␉␉␉addr[0] += (UInt32)base;␊ |
431 | ␊ |
432 | ␉␉␉␉//if(type != REBASE_TYPE_POINTER) addr[0] -= 8;␊ |
433 | ␉␉␉␉␊ |
434 | ␉␉␉␉segmentAddress += tmp + sizeof(void*);␊ |
435 | ␉␉␉␉break;␊ |
436 | ␉␉␉␉␊ |
437 | ␉␉␉case REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:␊ |
438 | ␉␉␉␉tmp = 0;␊ |
439 | ␉␉␉␉bits = 0;␊ |
440 | ␉␉␉␉do␊ |
441 | ␉␉␉␉{␊ |
442 | ␉␉␉␉␉tmp |= (rebase_stream[++i] & 0x7f) << bits;␊ |
443 | ␉␉␉␉␉bits += 7;␊ |
444 | ␉␉␉␉}␊ |
445 | ␉␉␉␉while(rebase_stream[i] & 0x80);␊ |
446 | ␉␉␉␉␊ |
447 | ␉␉␉␉␊ |
448 | ␉␉␉␉tmp2 = 0;␊ |
449 | ␉␉␉␉bits = 0;␊ |
450 | ␉␉␉␉do␊ |
451 | ␉␉␉␉{␊ |
452 | ␉␉␉␉␉tmp2 |= (rebase_stream[++i] & 0x7f) << bits;␊ |
453 | ␉␉␉␉␉bits += 7;␊ |
454 | ␉␉␉␉}␊ |
455 | ␉␉␉␉while(rebase_stream[i] & 0x80);␊ |
456 | ␉␉␉␉␊ |
457 | ␉␉␉␉//printf("Rebase 0x%X times, skiping 0x%X\n",tmp, tmp2);␊ |
458 | ␉␉␉␉index = 0;␊ |
459 | ␉␉␉␉for (index = 0; index < tmp; ++index) {␊ |
460 | ␉␉␉␉␉//printf("\tRebasing 0x%X\n", segmentAddress);␊ |
461 | ␊ |
462 | ␉␉␉␉␉UInt32* addr = base + segmentAddress;␊ |
463 | ␉␉␉␉␉addr[0] += (UInt32)base;␊ |
464 | ␊ |
465 | ␉␉␉␉␉//if(type != REBASE_TYPE_POINTER) addr[0] -= 8;␊ |
466 | ␊ |
467 | ␉␉␉␉␉␊ |
468 | ␉␉␉␉␉segmentAddress += tmp2 + sizeof(void*);␊ |
469 | ␉␉␉␉}␊ |
470 | ␉␉␉␉break;␊ |
471 | ␉␉}␊ |
472 | ␉␉i++;␊ |
473 | ␉}␊ |
474 | }␊ |
475 | ␊ |
476 | // Based on code from dylibinfo.cpp and ImageLoaderMachOCompressed.cpp␊ |
477 | // NOTE: this uses 32bit values, and not 64bit values. ␊ |
478 | // There is apossibility that this could cause issues,␊ |
479 | // however the macho file is 32 bit, so it shouldn't matter too much␊ |
480 | void bind_macho(void* base, char* bind_stream, UInt32 size)␊ |
481 | {␉␊ |
482 | ␉bind_stream += (UInt32)base;␊ |
483 | ␉␊ |
484 | ␉UInt8 immediate = 0;␊ |
485 | ␉UInt8 opcode = 0;␊ |
486 | ␉UInt8 type = 0;␊ |
487 | ␉␊ |
488 | ␉UInt32 segmentAddress = 0;␊ |
489 | ␉␊ |
490 | ␉UInt32 address = 0;␊ |
491 | ␉␊ |
492 | ␉SInt32 addend = 0;␉␉␉// TODO: handle this␊ |
493 | ␉SInt32 libraryOrdinal = 0;␊ |
494 | ␊ |
495 | ␉const char* symbolName = NULL;␊ |
496 | ␉UInt8 symboFlags = 0;␊ |
497 | ␉UInt32 symbolAddr = 0xFFFFFFFF;␊ |
498 | ␉␊ |
499 | ␉// Temperary variables␊ |
500 | ␉UInt8 bits = 0;␊ |
501 | ␉UInt32 tmp = 0;␊ |
502 | ␉UInt32 tmp2 = 0;␊ |
503 | ␉␊ |
504 | ␉UInt32 index = 0;␊ |
505 | ␉int done = 0;␊ |
506 | ␉unsigned int i = 0;␊ |
507 | ␉␊ |
508 | ␉while(/*!done &&*/ i < size)␊ |
509 | ␉{␊ |
510 | ␉␉immediate = bind_stream[i] & BIND_IMMEDIATE_MASK;␊ |
511 | ␉␉opcode = bind_stream[i] & BIND_OPCODE_MASK;␊ |
512 | ␉␉␊ |
513 | ␉␉␊ |
514 | ␉␉switch(opcode)␊ |
515 | ␉␉{␊ |
516 | ␉␉␉case BIND_OPCODE_DONE:␊ |
517 | ␉␉␉␉done = 1; ␊ |
518 | ␉␉␉␉break;␊ |
519 | ␉␉␉␉␊ |
520 | ␉␉␉case BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:␊ |
521 | ␉␉␉␉libraryOrdinal = immediate;␊ |
522 | ␉␉␉␉//printf("BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: %d\n", libraryOrdinal);␊ |
523 | ␉␉␉␉break;␊ |
524 | ␉␉␉␉␊ |
525 | ␉␉␉case BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:␊ |
526 | ␉␉␉␉libraryOrdinal = 0;␊ |
527 | ␉␉␉␉bits = 0;␊ |
528 | ␉␉␉␉do␊ |
529 | ␉␉␉␉{␊ |
530 | ␉␉␉␉␉libraryOrdinal |= (bind_stream[++i] & 0x7f) << bits;␊ |
531 | ␉␉␉␉␉bits += 7;␊ |
532 | ␉␉␉␉}␊ |
533 | ␉␉␉␉while(bind_stream[i] & 0x80);␊ |
534 | ␉␉␉␉␊ |
535 | ␉␉␉␉//printf("BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: %d\n", libraryOrdinal);␊ |
536 | ␊ |
537 | ␉␉␉␉break;␊ |
538 | ␉␉␉␉␊ |
539 | ␉␉␉case BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:␊ |
540 | ␉␉␉␉// NOTE: this is wrong, fortunately we don't use it␊ |
541 | ␉␉␉␉libraryOrdinal = -immediate;␊ |
542 | ␉␉␉␉//printf("BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: %d\n", libraryOrdinal);␊ |
543 | ␊ |
544 | ␉␉␉␉break;␊ |
545 | ␉␉␉␉␊ |
546 | ␉␉␉case BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:␊ |
547 | ␉␉␉␉symboFlags = immediate;␊ |
548 | ␉␉␉␉symbolName = (char*)&bind_stream[++i];␊ |
549 | ␉␉␉␉i += strlen((char*)&bind_stream[i]);␊ |
550 | ␉␉␉␉//printf("BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: %s, 0x%X\n", symbolName, symboFlags);␊ |
551 | ␊ |
552 | ␉␉␉␉symbolAddr = lookup_all_symbols(symbolName);␊ |
553 | ␊ |
554 | ␉␉␉␉break;␊ |
555 | ␉␉␉␉␊ |
556 | ␉␉␉case BIND_OPCODE_SET_TYPE_IMM:␊ |
557 | ␉␉␉␉// Set bind type (pointer, absolute32, pcrel32)␊ |
558 | ␉␉␉␉type = immediate;␊ |
559 | ␉␉␉␉//printf("BIND_OPCODE_SET_TYPE_IMM: %d\n", type);␊ |
560 | ␊ |
561 | ␉␉␉␉break;␊ |
562 | ␉␉␉␉␊ |
563 | ␉␉␉case BIND_OPCODE_SET_ADDEND_SLEB:␊ |
564 | ␉␉␉␉addend = 0;␊ |
565 | ␉␉␉␉bits = 0;␊ |
566 | ␉␉␉␉do␊ |
567 | ␉␉␉␉{␊ |
568 | ␉␉␉␉␉addend |= (bind_stream[++i] & 0x7f) << bits;␊ |
569 | ␉␉␉␉␉bits += 7;␊ |
570 | ␉␉␉␉}␊ |
571 | ␉␉␉␉while(bind_stream[i] & 0x80);␊ |
572 | ␉␉␉␉␊ |
573 | ␉␉␉␉if(!(bind_stream[i-1] & 0x40)) addend *= -1;␊ |
574 | ␉␉␉␉␊ |
575 | ␉␉␉␉//printf("BIND_OPCODE_SET_ADDEND_SLEB: %d\n", addend);␊ |
576 | ␉␉␉␉break;␊ |
577 | ␉␉␉␉␊ |
578 | ␉␉␉case BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:␊ |
579 | ␉␉␉␉segmentAddress = 0;␊ |
580 | ␊ |
581 | ␉␉␉␉// Locate address␊ |
582 | ␉␉␉␉struct segment_command* segCommand = NULL;␊ |
583 | ␉␉␉␉␊ |
584 | ␉␉␉␉unsigned int binIndex = 0;␊ |
585 | ␉␉␉␉index = 0;␊ |
586 | ␉␉␉␉do␊ |
587 | ␉␉␉␉{␊ |
588 | ␉␉␉␉␉segCommand = base + sizeof(struct mach_header) + binIndex;␊ |
589 | ␉␉␉␉␉binIndex += segCommand->cmdsize;␊ |
590 | ␉␉␉␉␉index++;␊ |
591 | ␉␉␉␉}␊ |
592 | ␉␉␉␉while(index <= immediate);␊ |
593 | ␉␉␉␉␊ |
594 | ␉␉␉␉segmentAddress = segCommand->fileoff;␊ |
595 | ␉␉␉␉␊ |
596 | ␉␉␉␉// Read in offset␊ |
597 | ␉␉␉␉tmp = 0;␊ |
598 | ␉␉␉␉bits = 0;␊ |
599 | ␉␉␉␉do␊ |
600 | ␉␉␉␉{␊ |
601 | ␉␉␉␉␉tmp |= (bind_stream[++i] & 0x7f) << bits;␊ |
602 | ␉␉␉␉␉bits += 7;␊ |
603 | ␉␉␉␉}␊ |
604 | ␉␉␉␉while(bind_stream[i] & 0x80);␊ |
605 | ␉␉␉␉␊ |
606 | ␉␉␉␉segmentAddress += tmp;␊ |
607 | ␉␉␉␉␊ |
608 | ␉␉␉␉//printf("BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: 0x%X\n", segmentAddress);␊ |
609 | ␉␉␉␉break;␊ |
610 | ␉␉␉␉␊ |
611 | ␉␉␉case BIND_OPCODE_ADD_ADDR_ULEB:␊ |
612 | ␉␉␉␉// Read in offset␊ |
613 | ␉␉␉␉tmp = 0;␊ |
614 | ␉␉␉␉bits = 0;␊ |
615 | ␉␉␉␉do␊ |
616 | ␉␉␉␉{␊ |
617 | ␉␉␉␉␉tmp |= (bind_stream[++i] & 0x7f) << bits;␊ |
618 | ␉␉␉␉␉bits += 7;␊ |
619 | ␉␉␉␉}␊ |
620 | ␉␉␉␉while(bind_stream[i] & 0x80);␊ |
621 | ␉␉␉␉␊ |
622 | ␉␉␉␉segmentAddress += tmp;␊ |
623 | ␉␉␉␉//printf("BIND_OPCODE_ADD_ADDR_ULEB: 0x%X\n", segmentAddress);␊ |
624 | ␉␉␉␉break;␊ |
625 | ␉␉␉␉␊ |
626 | ␉␉␉case BIND_OPCODE_DO_BIND:␊ |
627 | ␉␉␉␉//printf("BIND_OPCODE_DO_BIND\n");␊ |
628 | ␉␉␉␉if(symbolAddr != 0xFFFFFFFF)␊ |
629 | ␉␉␉␉{␊ |
630 | ␉␉␉␉␉address = segmentAddress + (UInt32)base;␊ |
631 | ␊ |
632 | ␉␉␉␉␉((char*)address)[0] = (symbolAddr & 0x000000FF) >> 0;␊ |
633 | ␉␉␉␉␉((char*)address)[1] = (symbolAddr & 0x0000FF00) >> 8;␊ |
634 | ␉␉␉␉␉((char*)address)[2] = (symbolAddr & 0x00FF0000) >> 16;␊ |
635 | ␉␉␉␉␉((char*)address)[3] = (symbolAddr & 0xFF000000) >> 24;␊ |
636 | ␉␉␉␉}␊ |
637 | ␉␉␉␉else if(strcmp(symbolName, SYMBOL_DYLD_STUB_BINDER) != 0)␊ |
638 | ␉␉␉␉{␊ |
639 | ␉␉␉␉␉printf("Unable to bind symbol %s\n", symbolName);␊ |
640 | ␉␉␉␉}␊ |
641 | ␉␉␉␉␊ |
642 | ␉␉␉␉segmentAddress += sizeof(void*);␊ |
643 | ␉␉␉␉break;␊ |
644 | ␉␉␉␉␊ |
645 | ␉␉␉case BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:␊ |
646 | ␉␉␉␉//printf("BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB\n");␊ |
647 | ␉␉␉␉␊ |
648 | ␉␉␉␉␊ |
649 | ␉␉␉␉// Read in offset␊ |
650 | ␉␉␉␉tmp = 0;␊ |
651 | ␉␉␉␉bits = 0;␊ |
652 | ␉␉␉␉do␊ |
653 | ␉␉␉␉{␊ |
654 | ␉␉␉␉␉tmp |= (bind_stream[++i] & 0x7f) << bits;␊ |
655 | ␉␉␉␉␉bits += 7;␊ |
656 | ␉␉␉␉}␊ |
657 | ␉␉␉␉while(bind_stream[i] & 0x80);␊ |
658 | ␉␉␉␉␊ |
659 | ␉␉␉␉␊ |
660 | ␉␉␉␉␊ |
661 | ␉␉␉␉if(symbolAddr != 0xFFFFFFFF)␊ |
662 | ␉␉␉␉{␊ |
663 | ␉␉␉␉␉address = segmentAddress + (UInt32)base;␊ |
664 | ␉␉␉␉␉␊ |
665 | ␉␉␉␉␉((char*)address)[0] = (symbolAddr & 0x000000FF) >> 0;␊ |
666 | ␉␉␉␉␉((char*)address)[1] = (symbolAddr & 0x0000FF00) >> 8;␊ |
667 | ␉␉␉␉␉((char*)address)[2] = (symbolAddr & 0x00FF0000) >> 16;␊ |
668 | ␉␉␉␉␉((char*)address)[3] = (symbolAddr & 0xFF000000) >> 24;␊ |
669 | ␉␉␉␉}␊ |
670 | ␉␉␉␉else if(strcmp(symbolName, SYMBOL_DYLD_STUB_BINDER) != 0)␊ |
671 | ␉␉␉␉{␊ |
672 | ␉␉␉␉␉printf("Unable to bind symbol %s\n", symbolName);␊ |
673 | ␉␉␉␉}␊ |
674 | ␉␉␉␉segmentAddress += tmp + sizeof(void*);␊ |
675 | ␊ |
676 | ␉␉␉␉␊ |
677 | ␉␉␉␉break;␊ |
678 | ␉␉␉␉␊ |
679 | ␉␉␉case BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:␊ |
680 | ␉␉␉␉//printf("BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED\n");␊ |
681 | ␉␉␉␉␊ |
682 | ␉␉␉␉if(symbolAddr != 0xFFFFFFFF)␊ |
683 | ␉␉␉␉{␊ |
684 | ␉␉␉␉␉address = segmentAddress + (UInt32)base;␊ |
685 | ␉␉␉␉␉␊ |
686 | ␉␉␉␉␉((char*)address)[0] = (symbolAddr & 0x000000FF) >> 0;␊ |
687 | ␉␉␉␉␉((char*)address)[1] = (symbolAddr & 0x0000FF00) >> 8;␊ |
688 | ␉␉␉␉␉((char*)address)[2] = (symbolAddr & 0x00FF0000) >> 16;␊ |
689 | ␉␉␉␉␉((char*)address)[3] = (symbolAddr & 0xFF000000) >> 24;␊ |
690 | ␉␉␉␉}␊ |
691 | ␉␉␉␉else if(strcmp(symbolName, SYMBOL_DYLD_STUB_BINDER) != 0)␊ |
692 | ␉␉␉␉{␊ |
693 | ␉␉␉␉␉printf("Unable to bind symbol %s\n", symbolName);␊ |
694 | ␉␉␉␉}␊ |
695 | ␉␉␉␉segmentAddress += (immediate * sizeof(void*)) + sizeof(void*);␊ |
696 | ␊ |
697 | ␉␉␉␉␊ |
698 | ␉␉␉␉break;␊ |
699 | ␉␉␉␉␊ |
700 | ␉␉␉case BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:␊ |
701 | ␊ |
702 | ␉␉␉␉tmp = 0;␊ |
703 | ␉␉␉␉bits = 0;␊ |
704 | ␉␉␉␉do␊ |
705 | ␉␉␉␉{␊ |
706 | ␉␉␉␉␉tmp |= (bind_stream[++i] & 0x7f) << bits;␊ |
707 | ␉␉␉␉␉bits += 7;␊ |
708 | ␉␉␉␉}␊ |
709 | ␉␉␉␉while(bind_stream[i] & 0x80);␊ |
710 | ␊ |
711 | ␉␉␉␉␊ |
712 | ␉␉␉␉tmp2 = 0;␊ |
713 | ␉␉␉␉bits = 0;␊ |
714 | ␉␉␉␉do␊ |
715 | ␉␉␉␉{␊ |
716 | ␉␉␉␉␉tmp2 |= (bind_stream[++i] & 0x7f) << bits;␊ |
717 | ␉␉␉␉␉bits += 7;␊ |
718 | ␉␉␉␉}␊ |
719 | ␉␉␉␉while(bind_stream[i] & 0x80);␊ |
720 | ␉␉␉␉␊ |
721 | ␉␉␉␉␊ |
722 | ␉␉␉␉//printf("BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB 0x%X 0x%X\n", tmp, tmp2);␊ |
723 | ␊ |
724 | ␉␉␉␉␊ |
725 | ␉␉␉␉if(symbolAddr != 0xFFFFFFFF)␊ |
726 | ␉␉␉␉{␊ |
727 | ␉␉␉␉␉for(index = 0; index < tmp; index++)␊ |
728 | ␉␉␉␉␉{␊ |
729 | ␉␉␉␉␉␉␊ |
730 | ␉␉␉␉␉␉address = segmentAddress + (UInt32)base;␊ |
731 | ␉␉␉␉␉␉␊ |
732 | ␉␉␉␉␉␉((char*)address)[0] = (symbolAddr & 0x000000FF) >> 0;␊ |
733 | ␉␉␉␉␉␉((char*)address)[1] = (symbolAddr & 0x0000FF00) >> 8;␊ |
734 | ␉␉␉␉␉␉((char*)address)[2] = (symbolAddr & 0x00FF0000) >> 16;␊ |
735 | ␉␉␉␉␉␉((char*)address)[3] = (symbolAddr & 0xFF000000) >> 24;␊ |
736 | ␉␉␉␉␉␉␊ |
737 | ␉␉␉␉␉␉segmentAddress += tmp2 + sizeof(void*);␊ |
738 | ␉␉␉␉␉}␊ |
739 | ␉␉␉␉}␊ |
740 | ␉␉␉␉else if(strcmp(symbolName, SYMBOL_DYLD_STUB_BINDER) != 0)␊ |
741 | ␉␉␉␉{␊ |
742 | ␉␉␉␉␉printf("Unable to bind symbol %s\n", symbolName);␊ |
743 | ␉␉␉␉}␊ |
744 | ␉␉␉␉␊ |
745 | ␉␉␉␉␊ |
746 | ␉␉␉␉break;␊ |
747 | ␉␉␉␉␊ |
748 | ␉␉}␊ |
749 | ␉␉i++;␊ |
750 | ␉}␊ |
751 | }␊ |
752 | ␊ |
753 | /*␊ |
754 | * add_symbol␊ |
755 | * This function adds a symbol from a module to the list of known symbols ␊ |
756 | * TODO: actualy do something... ␊ |
757 | * possibly change to a pointer and add this to the Symbol module␊ |
758 | */␊ |
759 | void add_symbol(char* symbol, void* addr)␊ |
760 | {␊ |
761 | ␉//printf("Adding symbol %s at 0x%X\n", symbol, addr);␊ |
762 | ␉␊ |
763 | ␉if(!moduleSymbols)␊ |
764 | ␉{␊ |
765 | ␉␉moduleSymbols = malloc(sizeof(symbolList_t));␊ |
766 | ␉␉moduleSymbols->next = NULL;␊ |
767 | ␉␉moduleSymbols->addr = (unsigned int)addr;␊ |
768 | ␉␉moduleSymbols->symbol = symbol;␊ |
769 | ␉}␊ |
770 | ␉else␊ |
771 | ␉{␊ |
772 | ␉␉symbolList_t* entry = moduleSymbols;␊ |
773 | ␉␉while(entry->next)␊ |
774 | ␉␉{␊ |
775 | ␉␉␉entry = entry->next;␊ |
776 | ␉␉}␊ |
777 | ␉␉␊ |
778 | ␉␉entry->next = malloc(sizeof(symbolList_t));␊ |
779 | ␉␉entry = entry->next;␊ |
780 | ␉␉␊ |
781 | ␉␉entry->next = NULL;␊ |
782 | ␉␉entry->addr = (unsigned int)addr;␊ |
783 | ␉␉entry->symbol = symbol;␊ |
784 | ␉␉␊ |
785 | ␉}␊ |
786 | ␉␉␉␉␉␉␉ ␊ |
787 | ␊ |
788 | }␊ |
789 | ␊ |
790 | ␊ |
791 | /*␊ |
792 | * print out the information about the loaded module␊ |
793 | ␊ |
794 | */␊ |
795 | void module_loaded(char* name, UInt32 version, UInt32 compat)␊ |
796 | {␊ |
797 | ␉/*␊ |
798 | ␉printf("\%s.dylib Version %d.%d.%d loaded\n"␊ |
799 | ␉␉ "\tCompatibility Version: %d.%d.%d\n",␊ |
800 | ␉␉ name,␊ |
801 | ␉␉ (version >> 16) & 0xFFFF,␊ |
802 | ␉␉ (version >> 8) & 0x00FF,␊ |
803 | ␉␉ (version >> 0) & 0x00FF,␊ |
804 | ␉␉ (compat >> 16) & 0xFFFF,␊ |
805 | ␉␉ (compat >> 8) & 0x00FF,␊ |
806 | ␉␉ (compat >> 0) & 0x00FF);␉␊ |
807 | ␉*/␊ |
808 | ␉if(loadedModules == NULL)␊ |
809 | ␉{␊ |
810 | ␉␉loadedModules = malloc(sizeof(moduleList_t));␊ |
811 | ␉␉loadedModules->next = NULL;␊ |
812 | ␉␉loadedModules->module = name;␊ |
813 | ␉␉loadedModules->version = version;␊ |
814 | ␉␉loadedModules->compat = compat;␊ |
815 | ␉}␊ |
816 | ␉else␊ |
817 | ␉{␊ |
818 | ␉␉moduleList_t* entry = loadedModules;␊ |
819 | ␉␉while(entry->next)␊ |
820 | ␉␉{␊ |
821 | ␉␉␉entry = entry->next;␊ |
822 | ␉␉}␊ |
823 | ␉␉␊ |
824 | ␉␉entry->next = malloc(sizeof(moduleList_t));␊ |
825 | ␉␉entry = entry->next;␊ |
826 | ␉␉␊ |
827 | ␉␉entry->next = NULL;␊ |
828 | ␉␉entry->module = name;␊ |
829 | ␉␉entry->version = version;␊ |
830 | ␉␉entry->compat = compat;␊ |
831 | ␉}␊ |
832 | ␊ |
833 | ␉␊ |
834 | }␊ |
835 | ␊ |
836 | int is_module_laoded(const char* name)␊ |
837 | {␊ |
838 | ␉moduleList_t* entry = loadedModules;␊ |
839 | ␉while(entry)␊ |
840 | ␉{␊ |
841 | ␉␉if(strcmp(entry->module, name) == 0)␊ |
842 | ␉␉{␊ |
843 | ␉␉␉return 1;␊ |
844 | ␉␉}␊ |
845 | ␉␉else␊ |
846 | ␉␉{␊ |
847 | ␉␉␉entry = entry->next;␊ |
848 | ␉␉}␊ |
849 | ␊ |
850 | ␉}␊ |
851 | ␉return 0;␊ |
852 | }␊ |
853 | ␊ |
854 | // Look for symbols using the Smbols moduel function.␊ |
855 | // If non are found, look through the list of module symbols␊ |
856 | unsigned int lookup_all_symbols(const char* name)␊ |
857 | {␊ |
858 | ␉unsigned int addr = 0xFFFFFFFF;␊ |
859 | ␉if(lookup_symbol)␊ |
860 | ␉{␊ |
861 | ␉␉addr = lookup_symbol(name);␊ |
862 | ␉␉if(addr != 0xFFFFFFFF)␊ |
863 | ␉␉{␊ |
864 | ␉␉␉//printf("Internal symbol %s located at 0x%X\n", name, addr);␊ |
865 | ␉␉␉return addr;␊ |
866 | ␉␉}␊ |
867 | ␉}␊ |
868 | ␊ |
869 | ␉␊ |
870 | ␉symbolList_t* entry = moduleSymbols;␊ |
871 | ␉while(entry)␊ |
872 | ␉{␊ |
873 | ␉␉if(strcmp(entry->symbol, name) == 0)␊ |
874 | ␉␉{␊ |
875 | ␉␉␉//printf("External symbol %s located at 0x%X\n", name, entry->addr);␊ |
876 | ␉␉␉return entry->addr;␊ |
877 | ␉␉}␊ |
878 | ␉␉else␊ |
879 | ␉␉{␊ |
880 | ␉␉␉entry = entry->next;␊ |
881 | ␉␉}␊ |
882 | ␊ |
883 | ␉}␊ |
884 | ␉if(strcmp(name, SYMBOL_DYLD_STUB_BINDER) != 0)␊ |
885 | ␉{␊ |
886 | ␉␉printf("Unable to locate symbol %s\n", name);␊ |
887 | ␉}␊ |
888 | ␉return 0xFFFFFFFF;␊ |
889 | }␊ |
890 | ␊ |
891 | ␊ |
892 | /*␊ |
893 | * parse the symbol table␊ |
894 | * Lookup any undefined symbols␊ |
895 | */␊ |
896 | ␊ |
897 | unsigned int handle_symtable(UInt32 base, struct symtab_command* symtabCommand, char* symbolStub, UInt32 nonlazy)␊ |
898 | {␊ |
899 | ␉unsigned int module_start = 0xFFFFFFFF;␊ |
900 | ␉␊ |
901 | ␉UInt32 symbolIndex = 0;␊ |
902 | ␉char* symbolString = base + (char*)symtabCommand->stroff;␊ |
903 | ␉//char* symbolTable = base + symtabCommand->symoff;␊ |
904 | ␉␊ |
905 | ␉while(symbolIndex < symtabCommand->nsyms)␊ |
906 | ␉{␊ |
907 | ␉␉␊ |
908 | ␉␉struct nlist* symbolEntry = (void*)base + symtabCommand->symoff + (symbolIndex * sizeof(struct nlist));␊ |
909 | ␉␉␊ |
910 | ␉␉// If the symbol is exported by this module␊ |
911 | ␉␉if(symbolEntry->n_value)␊ |
912 | ␉␉{␊ |
913 | ␉␉␉if(strcmp(symbolString + symbolEntry->n_un.n_strx, "start") == 0)␊ |
914 | ␉␉␉{␊ |
915 | ␉␉␉␉// Module start located. Start is an alias so don't register it␊ |
916 | ␉␉␉␉module_start = base + symbolEntry->n_value;␊ |
917 | ␉␉␉}␊ |
918 | ␉␉␉else␊ |
919 | ␉␉␉{␊ |
920 | ␉␉␉␉add_symbol(symbolString + symbolEntry->n_un.n_strx, (void*)base + symbolEntry->n_value); ␊ |
921 | ␉␉␉}␊ |
922 | ␉␉}␊ |
923 | ␉␉␊ |
924 | ␉␉symbolEntry+= sizeof(struct nlist);␊ |
925 | ␉␉symbolIndex++;␉// TODO remove␊ |
926 | ␉}␊ |
927 | ␉␊ |
928 | ␉return module_start;␊ |
929 | ␉␊ |
930 | } |