Chameleon

Chameleon Commit Details

Date:2010-09-09 03:33:47 (13 years 7 months ago)
Author:Azimutz
Commit:506
Parents: 505
Message:Adding latest changes to Kernel Patcher module, rev 502. Keeping some removed verbose messages for now.
Changes:
M/branches/azimutz/Chazi/doc-azi/Modules.txt
M/branches/azimutz/Chazi/i386/modules/KernelPatcher/kernel_patcher.c
M/branches/azimutz/Chazi/i386/modules/KernelPatcher/kernel_patcher.h
M/branches/azimutz/Chazi/i386/modules/HelloWorld/HelloWorld.c

File differences

branches/azimutz/Chazi/doc-azi/Modules.txt
7474
7575
7676
77
78
7779
7880
7981
and so i did it. Of course the problem is still there and needs to be fixed, at least if
one wants to be able to load modules from selected volume.
- compiling modules under Leo (XCode 3.1.4) is not possible at the moment.
---------------//---------------//---------------
branches/azimutz/Chazi/i386/modules/KernelPatcher/kernel_patcher.c
1
1
22
33
44
......
1818
1919
2020
21
22
2321
2422
2523
......
3634
3735
3836
39
37
4038
41
4239
4340
4441
45
42
4643
4744
4845
......
174171
175172
176173
174
175
176
177
177178
178179
179
180
181180
182
183
184
181
185182
186183
187184
......
251248
252249
253250
254
251
252
253
254
255
256
257
258
259
260
255261
256262
257263
258
264
265
266
267
268
269
270
271
272
259273
260274
261275
262276
263
277
264278
265279
266280
267281
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
388
389
390
391
392
393
394
268395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
269411
270412
271413
......
305447
306448
307449
308
309
450
451
310452
311453
312454
313455
314456
315457
316
317
318
458
319459
460
320461
321462
322
323463
324464
325465
......
339479
340480
341481
342
482
343483
344484
345485
346
347
348
486
487
488
349489
350490
351491
352492
353493
354
494
355495
356496
357497
......
381521
382522
383523
384
385
386
387
388
389
390
524
525
526
527
528
529
391530
392531
393532
533
534
394535
536
537
538
395539
396
540
397541
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
542
543
544
545
546
547
548
414549
415
416
417
550
551
418552
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
450
451
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
452572
453
573
454574
455
456
457575
458
576
459577
460578
461579
......
564682
565683
566684
567
685
568686
569687
570688
/*
/*
* Copyright (c) 2009-2010 Evan Lojewski. All rights reserved.
*
*/
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");
boolpatchKernel = false; //Kpatcher - default value.
patchRoutine_t* entry = patches;
int arch = determineKernelArchitecture(kernelData);
locate_symbols(kernelData);
// check if kernel patcher is requested by user.
getBoolForKey(kKPatcherKey, &patchKernel, &bootInfo->bootConfig);
int arch = determineKernelArchitecture(kernelData);
locate_symbols(kernelData);
if (patches != NULL && patchKernel)
if (patches != NULL && patchKernel == true)
{
while(entry)
{
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(void* kernelData, UInt32 impersonateFamily, UInt8 impersonateModel)
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--;
verbose("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 just in case
// 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;
verbose("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]);
// 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();
}
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;
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
}
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]);
verbose("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();
verbose("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]);
// 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
{
kernSymbols_t *symbol = lookup_kernel_symbol("_commpage_stuff_routine");
if(symbol == 0 || symbol->addr == 0)
{
printf("Unable to locate %s\n", "_commpage_stuff_routine");
verbose("Unable to locate %s\n", "_commpage_stuff_routine");
return;
}
branches/azimutz/Chazi/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);
branches/azimutz/Chazi/i386/modules/HelloWorld/HelloWorld.c
1212
1313
1414
15
16
15
16
1717
1818
1919
void helloWorld(void* binary, void* arg2, void* arg3, void* arg4)
{
printf("Hello world from ExecKernel hook. Binary located at 0x%X\n", binary);
getc();
verbose("Hello world from ExecKernel hook. Binary located at 0x%X\n", binary);
//getc();
}

Archive Download the corresponding diff file

Revision: 506