Chameleon

Chameleon Commit Details

Date:2010-09-08 04:30:36 (13 years 6 months ago)
Author:Evan Lojewski
Commit:502
Parents: 501
Message:Typo fix, current status of kernel patcher. NOTE: 64bit doesn't work fully yet. This is just a placeholder untill I sync with trunk.
Changes:
M/branches/meklort/i386/modules/KernelPatcher/kernel_patcher.c
M/branches/meklort/i386/modules/KernelPatcher/kernel_patcher.h
M/branches/meklort/i386/boot2/modules.c
M/branches/meklort/i386/boot2/modules.h

File differences

branches/meklort/i386/boot2/modules.c
106106
107107
108108
109
109
110110
111111
112112
......
10451045
10461046
10471047
1048
1048
10491049
10501050
10511051
int load_module(char* module)
{
// Check to see if the module has already been loaded
if(is_module_laoded(module))
if(is_module_loaded(module))
{
// NOTE: Symbols.dylib tries to load twice, this catches it as well
// as when a module links with an already loaded module
}
int is_module_laoded(const char* name)
int is_module_loaded(const char* name)
{
moduleList_t* entry = loadedModules;
while(entry)
branches/meklort/i386/boot2/modules.h
7474
7575
7676
77
77
7878
7979
8080
void bind_macho(void* base, char* bind_stream, UInt32 size);
int load_module(char* module);
int is_module_laoded(const char* name);
int is_module_loaded(const char* name);
void module_loaded(const char* name/*, UInt32 version, UInt32 compat*/);
long long add_symbol(char* symbol, long long addr, char is64);
branches/meklort/i386/modules/KernelPatcher/kernel_patcher.c
1515
1616
1717
18
19
2018
2119
2220
......
3331
3432
3533
36
34
3735
38
3936
4037
4138
42
39
4340
4441
4542
......
246243
247244
248245
249
246
247
248
249
250
251
252
253
254
255
250256
251257
252258
253
259
260
261
262
263
264
265
266
267
254268
255269
256270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
257388
258
389
390
391
392
393
394
395
396
397
398
399
400
401
402
259403
260404
261405
......
300444
301445
302446
303
304
305447
306448
307449
308450
309451
310452
311
312
313
314453
454
315455
316456
317
318457
319458
320459
......
334473
335474
336475
337
476
338477
339478
340479
341
342
343
480
481
482
344483
345484
346485
347486
348487
349
488
350489
351490
352491
......
376515
377516
378517
379
380
381
382
383
384
385
518
519
520
521
522
523
386524
387525
388526
527
528
389529
530
531
532
390533
391
534
392535
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
536
537
538
539
540
541
542
409543
410
411
412
544
545
413546
414
415
416
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
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
447566
448
567
449568
450
451
452569
453
570
454571
455572
456573
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_ANY, CPUID_MODEL_UNKNOWN);
register_kernel_patch(patch_commpage_stuff_routine, KERNEL_ANY, CPUID_MODEL_ANY);
register_kernel_symbol(KERNEL_ANY, "_lapic_init");
register_kernel_symbol(KERNEL_ANY, "_commpage_stuff_routine");
// LAPIC configure symbols
// lapic_configure symbols
register_kernel_symbol(KERNEL_ANY, "_lapic_configure");
register_kernel_symbol(KERNEL_ANY, "_lapic_start");
register_kernel_symbol(KERNEL_ANY, "_lapic_interrupt_base");
// lapic_interrup symbols
//register_kernel_patch(patch_lapic_interrupt, KERNEL_ANY, CPUID_MODEL_ANY);
//register_kernel_symbol(KERNEL_ANY, "_lapic_interrupt");
switch(Platform.CPU.Model)
{
case CPUID_MODEL_ATOM:
patch_cpuid_set_info(kernelData, CPUFAMILY_INTEL_PENRYN, CPUID_MODEL_PENRYN);
if(determineKernelArchitecture(kernelData) == KERNEL_32)
{
patch_cpuid_set_info_32(kernelData, CPUFAMILY_INTEL_PENRYN, CPUID_MODEL_PENRYN);
}
else
{
patch_cpuid_set_info_64(kernelData, CPUFAMILY_INTEL_PENRYN, CPUID_MODEL_PENRYN);
}
break;
default:
patch_cpuid_set_info(kernelData, 0, 0);
if(determineKernelArchitecture(kernelData) == KERNEL_32)
{
patch_cpuid_set_info_32(kernelData, 0, 0);
}
else
{
patch_cpuid_set_info_64(kernelData, 0, 0);
}
break;
}
}
void patch_cpuid_set_info_64(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;
if(symbol == 0 || symbol->addr == 0)
{
printf("Unable to locate _cpuid_set_info\n");
return;
}
symbol = lookup_kernel_symbol("_panic");
UInt32 panicAddr = symbol ? symbol->addr - textAddress: 0; //kernelSymbolAddresses[SYMBOL_PANIC] - textAddress;
if(symbol == 0 || symbol->addr == 0)
{
printf("Unable to locate _panic\n");
return;
}
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) ||
( ( (UInt32)(panicAddr - patchLocation - 4) + textSection ) != (UInt32)((bytes[patchLocation + 0] << 0 |
bytes[patchLocation + 1] << 8 |
bytes[patchLocation + 2] << 16 |
bytes[patchLocation + 3] << 24)))
)
{
patchLocation++;
}
patchLocation--;
// Remove panic just in ca se
// The panic instruction is exactly 5 bytes long.
bytes[patchLocation + 0] = 0x90;
bytes[patchLocation + 1] = 0x90;
bytes[patchLocation + 2] = 0x90;
bytes[patchLocation + 3] = 0x90;
bytes[patchLocation + 4] = 0x90;
// Check for a 10.2.0+ kernel
if(bytes[patchLocation - 19] == 0xC7 && bytes[patchLocation - 18] == 0x05)
{
UInt32 cpuid_cpufamily_addr =bytes[patchLocation - 17] << 0 |
bytes[patchLocation - 16] << 8 |
bytes[patchLocation - 15] << 16 |
bytes[patchLocation - 14] << 24;
// NOTE: may change, determined based on cpuid_info struct
UInt32 cpuid_model_addr = cpuid_cpufamily_addr - 310;
//ffffff8000228b3b -> 0x00490e8b
//ffffff8000228c28 -> -237 -> 0x490D9E -> -310
// The mov is 10 bytes
/*
bytes[patchLocation - 19] = 0x90;// c7
bytes[patchLocation - 18] = 0x90;// 05
bytes[patchLocation - 17] = 0x90;// family location
bytes[patchLocation - 16] = 0x90;// family location
bytes[patchLocation - 15] = 0x90;// family location
bytes[patchLocation - 14] = 0x90;// family location
*/
bytes[patchLocation - 13] = (impersonateFamily & 0x000000FF) >> 0;
bytes[patchLocation - 12] = (impersonateFamily & 0x0000FF00) >> 8;
bytes[patchLocation - 11] = (impersonateFamily & 0x00FF0000) >> 16;
bytes[patchLocation - 10] = (impersonateFamily & 0xFF000000) >> 24;
// The lea (%rip),%rip is 7 bytes
bytes[patchLocation - 9] = 0xC7;
bytes[patchLocation - 8] = 0x05;
bytes[patchLocation - 7] = ((cpuid_model_addr -10) & 0x000000FF) >> 0;// NOTE: this opcode is relative in 64bit mode, subtract offset
bytes[patchLocation - 6] = ((cpuid_model_addr -10) & 0x0000FF00) >> 8;
bytes[patchLocation - 5] = ((cpuid_model_addr -10) & 0x00FF0000) >> 16;
bytes[patchLocation - 4] = ((cpuid_model_addr -10) & 0xFF000000) >> 24;
bytes[patchLocation - 3] = impersonateModel;// cpuid_model
// The xor eax eax is 2 bytes
bytes[patchLocation - 2] = 0x01;// cpuid_extmodel
bytes[patchLocation - 1] = 0x00;// cpuid_extfamily
// The panic instruction is exactly 5 bytes long.
bytes[patchLocation - 0] = 0x02;// cpuid_stepping
/*bytes[patchLocation + 1] = 0x90;
bytes[patchLocation + 2] = 0x90;
bytes[patchLocation + 3] = 0x90;
bytes[patchLocation + 4] = 0x90;
*/
// Panic call has been removed.
// Override the CPUID now. This requires ~ 10 bytes on 10.0.0 kernels
// On 10.2.0+ kernels, this requires ~16 bytes
// Total: 24 bytes
printf("Running on a 10.2.0+ kernel\n");
getc();
void patch_cpuid_set_info(void* kernelData, UInt32 impersonateFamily, UInt8 impersonateModel)
}
else {
printf("Running on a 10.0.0 kernel, patch unsupported\n");
getc();
}
}
void patch_cpuid_set_info_32(void* kernelData, UInt32 impersonateFamily, UInt8 impersonateModel)
{
UInt8* bytes = (UInt8*)kernelData;
}
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)) &&
/*
* Inpersonate the specified CPU FAMILY and CPU Model
*/
// bytes[patchLocation - 17] = 0xC7;// already here... not needed to be done
// bytes[patchLocation - 16] = 0x05;// see above
UInt32 cpuid_cpufamily_addr =bytes[patchLocation - 15] << 0 |
bytes[patchLocation - 14] << 8 |
bytes[patchLocation - 13] << 16 |
bytes[patchLocation - 12] << 24;
bytes[patchLocation - 14] << 8 |
bytes[patchLocation - 13] << 16 |
bytes[patchLocation - 12] << 24;
// NOTE: may change, determined based on cpuid_info struct
UInt32 cpuid_model_addr = cpuid_cpufamily_addr - 299;
// cpufamily = CPUFAMILY_INTEL_PENRYN
// cpufamily
bytes[patchLocation - 11] = (impersonateFamily & 0x000000FF) >> 0;
bytes[patchLocation - 10] = (impersonateFamily & 0x0000FF00) >> 8;
bytes[patchLocation - 9] = (impersonateFamily & 0x00FF0000) >> 16;
}
else if(impersonateFamily && impersonateModel)
{
// 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)
// 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.
// 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) < 0x200)
if((patchLocation - jumpLocation) < 0x20)
{
// 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.
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
// 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.
bytes[patchLocation - 7] = 0x90;
bytes[patchLocation - 6] = 0x90;
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
}
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/meklort/i386/modules/KernelPatcher/kernel_patcher.h
5757
5858
5959
60
60
61
62
6163
6264
6365
* Internal patches provided by this module.
*/
void patch_cpuid_set_info_all(void* kernelData);
void patch_cpuid_set_info(void* kernelData, UInt32 impersonateFamily, UInt8 impersonateModel);
void patch_cpuid_set_info_32(void* kernelData, UInt32 impersonateFamily, UInt8 impersonateModel);
void patch_cpuid_set_info_64(void* kernelData, UInt32 impersonateFamily, UInt8 impersonateModel);
void patch_pmCPUExitHaltToOff(void* kernelData);
void patch_lapic_init(void* kernelData);
void patch_commpage_stuff_routine(void* kernelData);

Archive Download the corresponding diff file

Revision: 502