Chameleon

Chameleon Commit Details

Date:2010-09-06 02:55:41 (13 years 7 months ago)
Author:Azimutz
Commit:497
Parents: 496
Message:Adding initial 64 bit support for Kernel Patcher module, revs 491 /4/6. Related doc and comment edit.
Changes:
M/branches/azimutz/Chazi/doc-azi/CHANGES.txt
M/branches/azimutz/Chazi/doc-azi/Modules.txt
M/branches/azimutz/Chazi/i386/boot2/modules.h
M/branches/azimutz/Chazi/i386/modules/KernelPatcher/kernel_patcher.c
M/branches/azimutz/Chazi/i386/libsaio/saio_types.h
M/branches/azimutz/Chazi/i386/boot2/boot.c
M/branches/azimutz/Chazi/i386/modules/KernelPatcher/Makefile
M/branches/azimutz/Chazi/i386/Makefile
M/branches/azimutz/Chazi/i386/modules/Symbols/Makefile
M/branches/azimutz/Chazi/i386/boot2/modules.c

File differences

branches/azimutz/Chazi/doc-azi/CHANGES.txt
288288
289289
290290
291
291
292292
293293
294294
......
300300
301301
302302
303
304
305
306
307
303
308304
309
305
310306
311
307
312308
313
309
314310
315311
316312
AutoResolution=y enables the patch.
Note: Obviously, it only works in Graphics Mode (Gui). Disabled by default.
Note: Obviously, it only works in Graphics Mode (Gui).
Note: resolution set on theme.plist is overriding the native one set by AutoResolution. For now the
possible solutions are, remove the boot resolution (boot_width, boot_height) from theme.plist
---------------//---------------//---------------
- (starting at rev 480)
Change: Added Meklort's Modules support, plus Kernel Patcher (Kptchr) module.
Check Modules.txt for more info.
Some talk here: http://forum.voodooprojects.org/index.php/topic,1556.0.html
here: http://forum.voodooprojects.org/index.php/topic,1153.0.html
and here: http://forum.voodooprojects.org/index.php/topic,1565.0.html
Change: added Meklort's Modules support, plus Kernel Patcher (Kpatcher) module.
PatchKernel=n disables Kernel Patcher. "Temporarily" enabled by default!!
PatchKernel=y enables Kernel Patcher.
Note: Only i386 arch is supported at the moment; x86_64 support being added...
Note: Check Modules.txt for more info.
Motif: ... as if, booting vanilla kernel, is not reason enough!?
Motif: Testing Modules support.
---------------//---------------//---------------
branches/azimutz/Chazi/doc-azi/Modules.txt
2121
2222
2323
24
25
24
25
2626
2727
2828
......
3030
3131
3232
33
34
33
34
3535
3636
3737
38
39
38
4039
41
40
4241
43
44
45
46
47
48
42
43
4944
50
45
46
47
5148
49
50
51
52
53
54
55
56
57
5258
53
5459
60
61
62
63
64
5565
5666
5767
......
6272
6373
6474
65
66
75
6776
6877
6978
79
80
81
82
7083
84
85
86
87
7188
7289
7390
- good question! Well, can't add much on the "geek" side... need to study the stuff so
i don't start dumping bs. The easy answer is they are like plugins, adding/replacing
booter functionality. For instance: the Kernel Patcher (Kptchr) is around for some time,
integrated on boot file like any other Chameleon function; with Modules support Kptchr
booter functionality. For instance: the Kernel Patcher (Kpatcher) is around for some time,
integrated on boot file like any other Chameleon function; with Modules support Kpatcher
can now live as a module, freeing the space it occupied on boot file
(one of module's advantages).
Featured modules:
- Symbols.dylib: always needed to load other modules! It's the first one to load and no
other module will work if this one fails to load. The booter will still perform as
usual, if it fails to load.
other module will work if this one fails. The booter will still perform as usual,
if it fails to load.
- KernelPatcher.dylib:
- "will" need PatchKernel=y to be enabled.
Note:*** this is still under consideration/testing so, for now the patcher is enabled by default***
- needs key to be enabled:
- features cpuid_set, commpage_stuff and lapic_init patches (atm).
PatchKernel=yat boot prompt or,
- as it is, Kptchr allows my Pentium D 925 to boot vanilla kernel, with the help of
-legacy flag; to enter x86_64 world i still need to patch the kernel, as the 925 has
no Supplemental SSE3 instructions. I assume that, the great majority of the
legacy/unsupported processors with at least SSE3 instructions,
will benefit of the same treatment!
Let's just say that the only patch needed by the 925 on Legacy Mode(*) is cpuid_set!
<key>PatchKernel</key>on Boot.plist.
<string>Yes</string>
- HelloWorld.dylib: just a notifier (not needed).
- featured patches: cpuid_set - 32/64 bit
commpage_stuff - 32/64 bit
lapic_init - 32 bit only.
Note on functionality: as it is, Kpatcher allows my Pentium D 925 to load vanilla(*)
kernel, with the help of -legacy flag; to enter x86_64 world i still need to patch
the kernel sources, as the 925 has no Supplemental SSE3 instructions and there's
no patch to fix this on Kpatcher atm (don't even know if is possible?!).
I assume that, the great majority of the legacy/unsupported processors with at least
SSE3 instructions, will benefit of the same treatment!
Let's just say that the only patch needed by the 925 on Legacy Mode(**) is cpuid_set!
- HelloWorld.dylib: just a notifier (not mandatory).
(*) For those who "missed" the lesson, Legacy Mode is the mode 32 bit only cpu's run on OS X.
(*) In this context, "vanilla" means the use of a non pre-patched kernel; what we do here is
patch the kernel on the fly, in memory.
(**) For those who "missed" the lesson, Legacy Mode is the mode 32 bit only cpu's run on OS X.
---------------//---------------//---------------
Issues:
- the Kernel Patcher can stop working due to changes on the kernel code, though that can be
"previewed" to some extent. Just so you know what to expect.
- this is work in progress; i will add updates as Meklort commits and only if they are in
functional state.
- this is work in progress; i will add updates as Meklort commits.
---------------//---------------//---------------
Some talk here: http://forum.voodooprojects.org/index.php/topic,1556.0.html
here: http://forum.voodooprojects.org/index.php/topic,1153.0.html
and here: http://forum.voodooprojects.org/index.php/topic,1565.0.html
---------------//---------------//---------------
Smith@@'s news :D
« Sent to: Azimutz on: Fri 03/09/2010 at 05:55:08 »
branches/azimutz/Chazi/i386/libsaio/saio_types.h
242242
243243
244244
245
245
246246
247247
248248
enum {
kNetworkDeviceType = kBIOSDevTypeNetwork,
kBlockDeviceType = kBIOSDevTypeHardDrive
};// gBootFileType_t; //Kptchr module, rev 307
};// gBootFileType_t; - Kpatcher
enum {
kCursorTypeHidden = 0x0100,
branches/azimutz/Chazi/i386/boot2/boot.c
396396
397397
398398
399
399
400400
401401
402402
bool tryresume;
bool tryresumedefault;
bool forceresume;
bool patchKernel = true; //Kptchr - temporarely set to true, ude to testing!
bool patchKernel = false; //Kpatcher - default value.
// additional variable for testing alternate kernel image locations on boot helper partitions.
char bootFileSpec[512];
branches/azimutz/Chazi/i386/boot2/modules.c
33
44
55
6
7
6
7
8
9
810
911
1012
......
1921
2022
2123
24
25
26
2227
2328
2429
......
2631
2732
2833
29
30
3134
3235
3336
......
8083
8184
8285
83
84
85
86
8786
8887
8988
9089
9190
92
91
92
93
94
9395
96
97
98
99
100
94101
95102
96103
......
99106
100107
101108
102
109
103110
104111
105112
106113
107114
108115
116
109117
110118
111119
112120
113121
114
115
116122
117123
118124
......
131137
132138
133139
134
140
135141
136142
137143
144
145
138146
139147
140148
......
290298
291299
292300
293
301
294302
295303
296304
297305
298306
299
307
300308
301309
302
310
303311
304312
305313
306314
307315
308316
309
317
318
319
310320
311
321
312322
313323
314324
315325
316326
317327
328
318329
319
330
320331
332
321333
334
322335
323336
324337
......
329342
330343
331344
332
345
333346
334347
335348
336349
337
350
338351
339352
340353
......
349362
350363
351364
352
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
353395
396
397
354398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
355429
356430
357431
......
363437
364438
365439
366
440
367441
368442
369443
......
372446
373447
374448
375
449
376450
377451
452
378453
379454
380455
......
385460
386461
387462
463
464
465
388466
389467
390468
......
393471
394472
395473
396
474
397475
398476
399477
400
478
401479
402480
403481
......
422500
423501
424502
425
426503
427
428
429
430
431
432504
433505
434506
......
9391011
9401012
9411013
942
1014
9431015
9441016
9451017
......
9691041
9701042
9711043
972
973
974
1044
1045
1046
9751047
9761048
9771049
......
9811053
9821054
9831055
1056
9841057
9851058
1059
9861060
9871061
9881062
......
9911065
9921066
9931067
1068
1069
9941070
9951071
9961072
......
10501126
10511127
10521128
1053
1129
10541130
10551131
1056
1057
1058
10591132
10601133
10611134
......
10651138
10661139
10671140
1068
1141
10691142
10701143
10711144
10721145
10731146
1074
1147
1148
10751149
10761150
10771151
1078
10791152
10801153
10811154
......
10861159
10871160
10881161
1089
1162
10901163
10911164
10921165
*
*/
#include "libsa.h" // replaced boot.h
#include "saio_internal.h" //---//
//#include "boot.h"
#include "libsa.h"
#include "saio_internal.h"
//---
#include "bootstruct.h"
#include "multiboot.h"
#include "modules.h"
#define DBG(x...)
#endif
// NOTE: Global so that modules can link with this
unsigned long long textAddress = 0;
unsigned long long textSection = 0;
moduleHook_t* moduleCallbacks = NULL;
moduleList_t* loadedModules = NULL;
unsigned int (*lookup_symbol)(const char*) = NULL;
void rebase_macho(void* base, char* rebase_stream, UInt32 size);
void bind_macho(void* base, char* bind_stream, UInt32 size);
char* name;
long flags;
long time;
//Azi: this path is resolving to bt(0,0) instead of selected volume; a perfect
// example of what made me gave up on /Extra path. Confirmed on MBR/boot0hfs only.
// Looking further into this...
struct dirstuff* moduleDir = opendir("/Extra/modules/");
while(readdir(moduleDir, (const char**)&name, &flags, &time) >= 0)
{
if(strcmp(&name[strlen(name) - sizeof("dylib")], ".dylib") == 0)
{
load_module(name);
char* tmp = malloc(strlen(name) + 1); // TODO: look into this
strcpy(tmp, name);
DBG("Attempting to load %s\n", tmp);
load_module(tmp);
}
else
{
DBG("Ignoring %s\n", name);
}
}
}
* Load a module file in /Extra/modules
* TODO: verify version number of module
*/
int load_module(const char* module)
int load_module(char* module)
{
// Check to see if the module has already been loaded
if(is_module_laoded(module))
{
// NOTE: Symbols.dylib tries to load twice, this catches it as well
// as when a module links with an already loaded module
DBG("Module %s already loaded\n", module);
return 1;
}
char modString[128];
int fh = -1;
//Azi: same as #84
sprintf(modString, "/Extra/modules/%s", module);
fh = open(modString, 0);
if(fh < 0)
//printf("Module %s read in.\n", modString);
// Module loaded into memory, parse it
module_start = parse_mach(module_base);
module_start = parse_mach(module_base, &load_module, &add_symbol);
if(module_start && module_start != (void*)0xFFFFFFFF)
{
// Notify the system that it was laoded
module_loaded(module/*moduleName, moduleVersion, moduleCompat*/);
(*module_start)();// Start the module
DBG("Module %s Loaded.\n", module);
}
* symbols will still be available (TODO: fix this). This should not
* happen as all dependencies are verified before the sybols are read in.
*/
void* parse_mach(void* binary)// TODO: add param to specify valid archs
void* parse_mach(void* binary, int(*dylib_loader)(char*), long long(*symbol_handler)(char*, long long, char))// TODO: add param to specify valid archs
{
char is64 = false;
void (*module_start)(void) = NULL;
// Module info
char* moduleName = NULL;
/*char* moduleName = NULL;
UInt32 moduleVersion = 0;
UInt32 moduleCompat = 0;
*/
// TODO convert all of the structs to a union
struct load_command *loadCommand = NULL;
struct dylib_command* dylibCommand = NULL;
struct dyld_info_command* dyldInfoCommand = NULL;
struct symtab_command* symtabCommand = NULL;
struct segment_command *segCommand = NULL;
struct segment_command_64 *segCommand64 = NULL;
//struct dysymtab_command* dysymtabCommand = NULL;
UInt32 binaryIndex = sizeof(struct mach_header);
UInt32 binaryIndex = 0;
UInt16 cmd = 0;
// Parse through the load commands
if(((struct mach_header*)binary)->magic == MH_MAGIC)
{
is64 = 0;
binaryIndex += sizeof(struct mach_header);
}
else if(((struct mach_header_64*)binary)->magic != MH_MAGIC_64)
else if(((struct mach_header_64*)binary)->magic == MH_MAGIC_64)
{
// NOTE: modules cannot be 64bit...
is64 = 1;
binaryIndex += sizeof(struct mach_header_64);
}
else
{
if(((struct mach_header*)binary)->filetype != MH_DYLIB)
/*if(((struct mach_header*)binary)->filetype != MH_DYLIB)
{
printf("Module is not a dylib. Unable to load.\n");
getc();
return NULL; // Module is in the incorrect format
}
}*/
while(cmd < ((struct mach_header*)binary)->ncmds)// TODO: for loop instead
{
case LC_SYMTAB:
symtabCommand = binary + binaryIndex;
break;
case LC_SEGMENT:
case LC_SEGMENT: // 32bit macho
segCommand = binary + binaryIndex;
//printf("Segment name is %s\n", segCommand->segname);
if(strcmp("__TEXT", segCommand->segname) == 0)
{
UInt32 sectionIndex;
sectionIndex = sizeof(struct segment_command);
struct section *sect;
while(sectionIndex < segCommand->cmdsize)
{
sect = binary + binaryIndex + sectionIndex;
sectionIndex += sizeof(struct section);
if(strcmp("__text", sect->sectname) == 0)
{
// __TEXT,__text found, save the offset and address for when looking for the calls.
textSection = sect->offset;
textAddress = sect->addr;
break;
}
}
}
break;
case LC_SEGMENT_64:// 64bit macho's
segCommand64 = binary + binaryIndex;
//printf("Segment name is %s\n", segCommand->segname);
if(strcmp("__TEXT", segCommand64->segname) == 0)
{
UInt32 sectionIndex;
sectionIndex = sizeof(struct segment_command_64);
struct section_64 *sect;
while(sectionIndex < segCommand64->cmdsize)
{
sect = binary + binaryIndex + sectionIndex;
sectionIndex += sizeof(struct section_64);
if(strcmp("__text", sect->sectname) == 0)
{
// __TEXT,__text found, save the offset and address for when looking for the calls.
textSection = sect->offset;
textAddress = sect->addr;
break;
}
}
}
break;
case LC_DYSYMTAB:
break;
// =dylibCommand->dylib.current_version;
// =dylibCommand->dylib.compatibility_version;
if(!load_module(module))
if(dylib_loader && !dylib_loader(module))
{
// Unable to load dependancy
return NULL;
case LC_ID_DYLIB:
dylibCommand = binary + binaryIndex;
moduleName =binary + binaryIndex + ((UInt32)*((UInt32*)&dylibCommand->dylib.name));
/*moduleName =binary + binaryIndex + ((UInt32)*((UInt32*)&dylibCommand->dylib.name));
moduleVersion =dylibCommand->dylib.current_version;
moduleCompat =dylibCommand->dylib.compatibility_version;
*/
break;
case LC_DYLD_INFO:
case LC_UUID:
break;
case LC_UNIXTHREAD:
break;
default:
DBG("Unhandled loadcommand 0x%X\n", loadCommand->cmd & 0x7FFFFFFF);
break;
binaryIndex += cmdSize;
}
if(!moduleName) return NULL;
//if(!moduleName) return NULL;
// bind_macho uses the symbols.
module_start = (void*)handle_symtable((UInt32)binary, symtabCommand, &add_symbol, is64);
module_start = (void*)handle_symtable((UInt32)binary, symtabCommand, symbol_handler, is64);
// Rebase the module before binding it.
if(dyldInfoCommand && dyldInfoCommand->rebase_off)
// This should be changed to bind when a symbol is referened at runtime instead.
bind_macho(binary, (char*)dyldInfoCommand->lazy_bind_off, dyldInfoCommand->lazy_bind_size);
}
// Notify the system that it was laoded
module_loaded(moduleName, moduleVersion, moduleCompat);
return module_start;
}
* print out the information about the loaded module
*/
void module_loaded(char* name, UInt32 version, UInt32 compat)
void module_loaded(const char* name/*, UInt32 version, UInt32 compat*/)
{
moduleList_t* entry;
/*
}
entry->next = NULL;
entry->module = name;
entry->version = version;
entry->compat = compat;
entry->module = (char*)name;
entry->version = 0; //version;
entry->compat = 0; //compat;
}
moduleList_t* entry = loadedModules;
while(entry)
{
DBG("Comparing %s with %s\n", name, entry->module);
if(strcmp(entry->module, name) == 0)
{
DBG("Located module %s\n", name);
return 1;
}
else
}
}
DBG("Module %s not found\n", name);
return 0;
}
//char* symbolTable = base + symtabCommand->symoff;
if(!is64)
{
struct nlist* symbolEntry = (void*)base + symtabCommand->symoff;
while(symbolIndex < symtabCommand->nsyms)
{
struct nlist* symbolEntry = (void*)base + symtabCommand->symoff + (symbolIndex * sizeof(struct nlist));
// If the symbol is exported by this module
if(symbolEntry->n_value &&
symbol_handler(symbolString + symbolEntry->n_un.n_strx, (long long)base + symbolEntry->n_value, is64) != 0xFFFFFFFF)
module_start = base + symbolEntry->n_value;
}
symbolEntry+= sizeof(struct nlist);
symbolEntry++;
symbolIndex++;// TODO remove
}
}
else
{
struct nlist_64* symbolEntry = (void*)base + symtabCommand->symoff;
// NOTE First entry is *not* correct, but we can ignore it (i'm getting radar:// right now)
while(symbolIndex < symtabCommand->nsyms)
{
struct nlist_64* symbolEntry = (void*)base + symtabCommand->symoff + (symbolIndex * sizeof(struct nlist_64));
// If the symbol is exported by this module
if(symbolEntry->n_value &&
module_start = base + symbolEntry->n_value;
}
symbolEntry+= sizeof(struct nlist);
symbolEntry++;
symbolIndex++;// TODO remove
}
}
branches/azimutz/Chazi/i386/boot2/modules.h
1010
1111
1212
13
14
1315
16
1417
1518
1619
......
6770
6871
6972
73
74
7075
71
76
7277
73
78
7479
7580
7681
77
82
83
84
85
7886
7987
8088
#ifndef __BOOT_MODULES_H
#define __BOOT_MODULES_H
extern unsigned long long textAddress;
extern unsigned long long textSection;
typedef struct symbolList_t
{
char* symbol;
void register_hook_callback(const char* name, void(*callback)(void*, void*, void*, void*));
inline void rebase_location(UInt32* location, char* base);
void rebase_macho(void* base, char* rebase_stream, UInt32 size);
void bind_macho(void* base, char* bind_stream, UInt32 size);
int load_module(const char* module);
int load_module(char* module);
int is_module_laoded(const char* name);
void module_loaded(char* name, UInt32 version, UInt32 compat);
void module_loaded(const char* name/*, UInt32 version, UInt32 compat*/);
long long add_symbol(char* symbol, long long addr, char is64);
void* parse_mach(void* binary);
void* parse_mach(void* binary,
int(*dylib_loader)(char*),
long long(*symbol_handler)(char*, long long, char)
);
unsigned int handle_symtable(UInt32 base,
struct symtab_command* symtabCommand,
branches/azimutz/Chazi/i386/modules/KernelPatcher/kernel_patcher.c
1
1
22
33
44
......
1616
1717
1818
19
20
21
22
2319
2420
2521
2622
27
23
2824
29
25
3026
31
27
3228
29
3330
34
3531
3632
37
38
39
40
41
33
34
35
36
37
4238
4339
44
45
40
4641
47
48
42
43
44
45
46
47
4948
49
5050
5151
5252
......
178178
179179
180180
181
182181
183182
184183
......
216215
217216
218217
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
218
219
220
221
294222
295223
296224
......
299227
300228
301229
230
302231
303232
233
234
235
236
304237
305238
306239
......
326259
327260
328261
329
262
330263
331264
332265
266
333267
268
334269
270
271
335272
336273
337274
......
349286
350287
351288
352
353
354289
355290
356
357291
358292
359
360293
361294
362295
......
370303
371304
372305
306
307
373308
374309
375310
376311
377312
378313
314
315
316
379317
380
381318
382319
320
383321
384322
385323
......
441379
442380
443381
444
445
446
447
448
449
382
383
384
385
386
387
388
450389
451390
452391
453
454
455392
456
457
458
459393
460
394
461395
462
463
464
465
466
467
468
469
470
471
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
472412
473
474
475
476
477
478
413
414
415
479416
480
481
482
483
484
485
486
487
488
489
490
491
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
492450
493
451
494452
453
454
495455
496
456
497457
498458
499459
/*
/*
* Copyright (c) 2009-2010 Evan Lojewski. All rights reserved.
*
*/
kernSymbols_t* kernelSymbols = NULL;
UInt32 textSection = 0;
UInt32 textAddress = 0;
void KernelPatcher_start()
{
//register_kernel_patch(patch_cpuid_set_info, KERNEL_32, CPUID_MODEL_ATOM);// TODO: CPUFAMILY_INTEL_PENRYN, CPUID_MODEL_PENRYN
//register_kernel_patch(patch_cpuid_set_info, KERNEL_32, CPUID_MODEL_UNKNOWN);// 0, 0
register_kernel_patch(patch_cpuid_set_info_all, KERNEL_32, CPUID_MODEL_UNKNOWN);
register_kernel_patch(patch_cpuid_set_info_all, KERNEL_ANY, CPUID_MODEL_UNKNOWN);
register_kernel_patch(patch_commpage_stuff_routine, KERNEL_32, CPUID_MODEL_ANY);
register_kernel_patch(patch_commpage_stuff_routine, KERNEL_ANY, CPUID_MODEL_ANY);
register_kernel_patch(patch_lapic_init, KERNEL_32, CPUID_MODEL_ANY);
register_kernel_patch(patch_lapic_init, KERNEL_ANY, CPUID_MODEL_ANY);
// NOTE: following is currently 32bit only
register_kernel_patch(patch_lapic_configure, KERNEL_32, CPUID_MODEL_ANY);
//register_kernel_patch(patch_lapic_interrupt, KERNEL_32, CPUID_MODEL_ANY);
register_kernel_symbol(KERNEL_32, "_panic");
register_kernel_symbol(KERNEL_32, "_cpuid_set_info");
register_kernel_symbol(KERNEL_32, "_pmCPUExitHaltToOff");
register_kernel_symbol(KERNEL_32, "_lapic_init");
register_kernel_symbol(KERNEL_32, "_commpage_stuff_routine");
register_kernel_symbol(KERNEL_ANY, "_panic");
register_kernel_symbol(KERNEL_ANY, "_cpuid_set_info");
register_kernel_symbol(KERNEL_ANY, "_pmCPUExitHaltToOff");
register_kernel_symbol(KERNEL_ANY, "_lapic_init");
register_kernel_symbol(KERNEL_ANY, "_commpage_stuff_routine");
// LAPIC configure symbols
register_kernel_symbol(KERNEL_32, "_lapic_configure");
register_kernel_symbol(KERNEL_32, "_lapic_interrupt");
register_kernel_symbol(KERNEL_ANY, "_lapic_configure");
register_kernel_symbol(KERNEL_32, "_lapic_start");
register_kernel_symbol(KERNEL_32, "_lapic_interrupt_base");
register_kernel_symbol(KERNEL_ANY, "_lapic_start");
register_kernel_symbol(KERNEL_ANY, "_lapic_interrupt_base");
//register_kernel_patch(patch_lapic_interrupt, KERNEL_ANY, CPUID_MODEL_ANY);
//register_kernel_symbol(KERNEL_ANY, "_lapic_interrupt");
// TODO: register needed symbols
locate_symbols(kernelData);
if(patches != NULL)
{
while(entry)
**/
int locate_symbols(void* kernelData)
{
struct load_command *loadCommand;
struct symtab_command *symtableData = 0; //Azi:warning
//struct nlist *symbolEntry;
char* symbolString;
UInt32 kernelIndex = 0;
kernelIndex += sizeof(struct mach_header);
if(((struct mach_header*)kernelData)->magic != MH_MAGIC) return KERNEL_64;
int cmd = 0;
while(cmd < ((struct mach_header*)kernelData)->ncmds)// TODO: for loop instead
{
cmd++;
loadCommand = kernelData + kernelIndex;
UInt cmdSize = loadCommand->cmdsize;
if((loadCommand->cmd & 0x7FFFFFFF) == LC_SYMTAB)// We only care about the symtab segment
{
//printf("Located symtable, length is 0x%X, 0x%X\n", (unsigned int)loadCommand->cmdsize, (unsigned int)sizeof(symtableData));
symtableData = kernelData + kernelIndex;
kernelIndex += sizeof(struct symtab_command);
symbolString = kernelData + symtableData->stroff;
}
else if((loadCommand->cmd & 0x7FFFFFFF) == LC_SEGMENT)// We only care about the __TEXT segment, any other load command can be ignored
{
struct segment_command *segCommand;
segCommand = kernelData + kernelIndex;
//printf("Segment name is %s\n", segCommand->segname);
if(strcmp("__TEXT", segCommand->segname) == 0)
{
UInt32 sectionIndex;
sectionIndex = sizeof(struct segment_command);
struct section *sect;
while(sectionIndex < segCommand->cmdsize)
{
sect = kernelData + kernelIndex + sectionIndex;
sectionIndex += sizeof(struct section);
if(strcmp("__text", sect->sectname) == 0)
{
// __TEXT,__text found, save the offset and address for when looking for the calls.
textSection = sect->offset;
textAddress = sect->addr;
break;
}
}
}
kernelIndex += cmdSize;
} else {
kernelIndex += cmdSize;
}
}
return handle_symtable((UInt32)kernelData, symtableData, &symbol_handler,
determineKernelArchitecture(kernelData) == KERNEL_64);
char is64 = 1;
parse_mach(kernelData, NULL, symbol_handler);
//handle_symtable((UInt32)kernelData, symtableData, &symbol_handler, determineKernelArchitecture(kernelData) == KERNEL_64);
return 1 << is64;
}
long long symbol_handler(char* symbolName, long long addr, char is64)
kernSymbols_t *symbol = lookup_kernel_symbol(symbolName);
if(symbol)
{
//printf("Located %sbit symbol %s at 0x%lX\n", is64 ? "64" : "32", symbolName, addr);
//getc();
symbol->addr = addr;
}
return 0xFFFFFFFF; // fixme
}
void patch_cpuid_set_info(void* kernelData, UInt32 impersonateFamily, UInt8 impersonateModel)
{
{
UInt8* bytes = (UInt8*)kernelData;
kernSymbols_t *symbol = lookup_kernel_symbol("_cpuid_set_info");
UInt32 patchLocation = symbol ? symbol->addr - textAddress + textSection: 0; //(kernelSymbolAddresses[SYMBOL_CPUID_SET_INFO] - textAddress + textSection);
patchLocation -= (UInt32)kernelData;// Remove offset
UInt32 jumpLocation = 0;
printf("Unable to locate _panic\n");
return;
}
patchLocation -= (UInt32)kernelData;// Remove offset
panicAddr -= (UInt32)kernelData;
//TODO: don't assume it'll always work (Look for *next* function address in symtab and fail once it's been reached)
while(
(bytes[patchLocation -1] != 0xE8) ||
}
patchLocation--;
printf("0x%X 0x%X 0x%X 0x%X 0x%X\n", bytes[patchLocation ], bytes[patchLocation +1], bytes[patchLocation +2], bytes[patchLocation +3], bytes[patchLocation +4]);
// Remove panic call, just in case the following patch routines fail
bytes[patchLocation + 0] = 0x90;
bytes[patchLocation + 1] = 0x90;
bytes[patchLocation + 2] = 0x90;
bytes[patchLocation + 3] = 0x90;
bytes[patchLocation + 4] = 0x90;
printf("0x%X 0x%X 0x%X 0x%X 0x%X\n", bytes[patchLocation ], bytes[patchLocation +1], bytes[patchLocation +2], bytes[patchLocation +3], bytes[patchLocation +4]);
getc();
// Locate the jump call, so that 10 bytes can be reclamed.
// NOTE: This will *NOT* be located on pre 10.6.2 kernels
// NOTE: This will work on a *32* bit kernel and *not* on a 64 bit ont
jumpLocation = patchLocation - 15;
while((bytes[jumpLocation - 1] != 0x77 ||
bytes[jumpLocation] != (patchLocation - jumpLocation - -8)) &&
}
else if(impersonateFamily && impersonateModel)
{
// pre 10.6.2 kernel
// Locate the jump to directly *after* the panic call,
jumpLocation = patchLocation - 4;
while((bytes[jumpLocation - 1] != 0x77 ||
bytes[jumpLocation] != (patchLocation - jumpLocation + 4)) &&
(patchLocation - jumpLocation) < 0x20)
// Eitehr a 64bit kernel *or* a pre 10.6.2 kernel
// Look for
jumpLocation = patchLocation - 15;
while((bytes[jumpLocation - 2] != 0x0F ||
bytes[jumpLocation - 1] != 0x87 ||
bytes[jumpLocation] != (patchLocation - jumpLocation - -31)) &&
(patchLocation - jumpLocation) < 0x200)
{
jumpLocation--;
}
// NOTE above isn't needed (I was going to use it, but I'm not, so instead,
// I'll just leave it to verify the binary stucture.
// NOTE: the cpumodel_familt data is not set in _cpuid_set_info
// so we don't need to set it here, I'll get set later based on the model
// we set now.
if((patchLocation - jumpLocation) < 0x20)
if((patchLocation - jumpLocation) < 0x200)
{
UInt32 cpuid_model_addr =(bytes[patchLocation - 14] << 0 |
bytes[patchLocation - 13] << 8 |
bytes[patchLocation - 12] << 16 |
bytes[patchLocation - 11] << 24);
// Remove jump
bytes[patchLocation - 9] = 0x90;/// Was a jump if supported cpu
bytes[patchLocation - 8] = 0x90;// jumped past the panic call, we want to override the panic
bytes[patchLocation - 7] = 0x90;
bytes[patchLocation - 6] = 0x90;
// 64 bit kernel, 10.6.2+
}
else
{// 32 bit kernel
// pre 10.6.2 kernel
// Locate the jump to directly *after* the panic call,
jumpLocation = patchLocation - 4;
while((bytes[jumpLocation - 1] != 0x77 ||
bytes[jumpLocation] != (patchLocation - jumpLocation + 4)) &&
(patchLocation - jumpLocation) < 0x20)
{
jumpLocation--;
}
// NOTE above isn't needed (I was going to use it, but I'm not, so instead,
// I'll just leave it to verify the binary stucture.
bytes[patchLocation - 5] = 0xC7;
bytes[patchLocation - 4] = 0x05;
bytes[patchLocation - 3] = (cpuid_model_addr & 0x000000FF) >> 0;
bytes[patchLocation - 2] = (cpuid_model_addr & 0x0000FF00) >> 8;
bytes[patchLocation - 1] = (cpuid_model_addr & 0x00FF0000) >> 16;
bytes[patchLocation - 0] = (cpuid_model_addr & 0xFF000000) >> 24;
// NOTE: the cpumodel_family data is not set in _cpuid_set_info
// so we don't need to set it here, I'll get set later based on the model
// we set now.
// Note: I could have just copied the 8bit cpuid_model in and saved about 4 bytes
// so if this function need a different patch it's still possible. Also, about ten bytes previous can be freed.
bytes[patchLocation + 1] = impersonateModel;// cpuid_model
bytes[patchLocation + 2] = 0x01;// cpuid_extmodel
bytes[patchLocation + 3] = 0x00;// cpuid_extfamily
bytes[patchLocation + 4] = 0x02;// cpuid_stepping
patchLocation = jumpLocation;
// We now have 14 bytes available for a patch
if((patchLocation - jumpLocation) < 0x20)
{
UInt32 cpuid_model_addr =(bytes[patchLocation - 14] << 0 |
bytes[patchLocation - 13] << 8 |
bytes[patchLocation - 12] << 16 |
bytes[patchLocation - 11] << 24);
// Remove jump
bytes[patchLocation - 9] = 0x90;/// Was a jump if supported cpu
bytes[patchLocation - 8] = 0x90;// jumped past the panic call, we want to override the panic
bytes[patchLocation - 7] = 0x90;
bytes[patchLocation - 6] = 0x90;
bytes[patchLocation - 5] = 0xC7;
bytes[patchLocation - 4] = 0x05;
bytes[patchLocation - 3] = (cpuid_model_addr & 0x000000FF) >> 0;
bytes[patchLocation - 2] = (cpuid_model_addr & 0x0000FF00) >> 8;
bytes[patchLocation - 1] = (cpuid_model_addr & 0x00FF0000) >> 16;
bytes[patchLocation - 0] = (cpuid_model_addr & 0xFF000000) >> 24;
// Note: I could have just copied the 8bit cpuid_model in and saved about 4 bytes
// so if this function need a different patch it's still possible. Also, about ten bytes previous can be freed.
bytes[patchLocation + 1] = impersonateModel;// cpuid_model
bytes[patchLocation + 2] = 0x01;// cpuid_extmodel
bytes[patchLocation + 3] = 0x00;// cpuid_extfamily
bytes[patchLocation + 4] = 0x02;// cpuid_stepping
patchLocation = jumpLocation;
// We now have 14 bytes available for a patch
}
}
else
/*else
{
// Check for 64bit kernel.
// Patching failed, using NOP replacement done initialy
}
}*/
}
else
{
branches/azimutz/Chazi/i386/modules/KernelPatcher/Makefile
2121
2222
2323
24
24
2525
2626
2727
INSTALLDIR = $(DSTROOT)/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/standalone
OPTIM = -Os -Oz
OPTIM = -O3
DEBUG = -DNOTHING
#DEBUG = -DDEBUG_HELLO_WORLD=1
CFLAGS= $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost \
branches/azimutz/Chazi/i386/modules/Symbols/Makefile
11
22
33
4
45
56
67
......
6364
6465
6566
66
67
6768
6869
6970
MODULE_NAME = Symbols
MODULE_VERSION = "1.0.0"
MODULE_COMPAT_VERSION = `ls ../../.svn &> /dev/null && (svn info ../../ | grep Revision | awk '{print $$2}') || echo 0`
MODULE_START = _$(MODULE_NAME)_start
MODULE_DEPENDENCIES =
DIR = HelloWorld
-S -x -dead_strip_dylibs \
-no_uuid \
-bind_at_load \
-current_version $(MODULE_VERSION) -compatibility_version `svn info ../../ | grep Revision | awk '{print $$2}'` \
-current_version $(MODULE_VERSION) -compatibility_version $(MODULE_COMPAT_VERSION) \
-final_output $(MODULE_NAME) \
$(OBJROOT)/Symbols.o -o $(SYMROOT)/$(MODULE_NAME).dylib \
branches/azimutz/Chazi/i386/Makefile
4444
4545
4646
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
4763
4864
) || exit $$?; \
done
modules:
@for i in "modules"; \
do \
echo ================= make $@ for $$i =================; \
( cd $$i; ${MAKE} \
"OBJROOT=$(OBJROOT)/$$i" \
"SYMROOT=$(SYMROOT)" \
"DSTROOT=$(DSTROOT)" \
"SRCROOT=$(SRCROOT)" \
"RC_ARCHS=$(RC_ARCHS)" \
"RC_KANJI=$(RC_KANJI)" \
"JAPANESE=$(JAPANESE)" \
"RC_CFLAGS=$(RC_CFLAGS)" $@ \
) || exit $$?; \
done
installsrc:
tar cf - . | (cd ${SRCROOT}; tar xfBp -)

Archive Download the corresponding diff file

Revision: 497