Chameleon

Chameleon Commit Details

Date:2010-10-24 22:30:17 (8 years 11 months ago)
Author:Evan Lojewski
Commit:610
Parents: 609
Message:Added HDA patching capabilities. Currently disabled untill I add a way for either detection of a codec, or a way for users to specify the coedc
Changes:
M/branches/meklort/i386/modules/KextPatcher/hex_editor.c
M/branches/meklort/i386/modules/KextPatcher/hex_editor.h
M/branches/meklort/i386/modules/KextPatcher/kext_patcher.c

File differences

branches/meklort/i386/modules/KextPatcher/hex_editor.h
1212
1313
1414
15
15
1616
1717
int replace_patern(char* pattern, char* repalcement, char* buffer, long buffer_size);
int replace_word(uint32_t pattern, uint32_t repalcement, char* buffer, long buffer_size);
void replace_string(char* find, char* replace, char* string);
void replace_string(char* find, char* replace, char* string, int length);
#endif /* H_HEX_EDITOR */
branches/meklort/i386/modules/KextPatcher/kext_patcher.c
3030
3131
3232
33
34
3335
3436
3537
3638
3739
3840
41
42
3943
40
44
4145
4246
4347
......
345349
346350
347351
352
353
354
355
356
357
358
359
360
361
362
363
348364
349365
350366
......
372388
373389
374390
391
392
393
394
395
396
397
398
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
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
375541
376542
377543
......
403569
404570
405571
406
572
407573
408574
409575
......
440606
441607
442608
443
609
444610
445611
446612
bool patch_kext(TagPtr plist, char* plistbuffer, void* start);
bool patch_gma_kexts(TagPtr plist, char* plistbuffer, void* start);
bool patch_bcm_kext(TagPtr plist, char* plistbuffer, void* start);
bool patch_hda_kext(TagPtr plist, char* plistbuffer, void* start);
bool patch_hda_controller(TagPtr plist, char* plistbuffer, void* start);
static void * z_alloc(void *, u_int items, u_int size);
static void z_free(void *, void *ptr);
uint16_t patch_gma_deviceid = 0;
uint16_t patch_bcm_deviceid = 0;
// TODO: add detection code / a method for users to enter the id
uint16_t patch_hda_codec = 0;
#define NEEDS_PATCHING(patch_bcm_deviceid || patch_gma_deviceid)
#define NEEDS_PATCHING(patch_bcm_deviceid || patch_gma_deviceid | patch_hda_codec)
typedef struct z_mem {
uint32_t alloc_size;
return patch_bcm_kext(plist, plistbuffer, start);
}
else if(patch_hda_codec && strcmp(bundleID, "com.apple.driver.AppleHDA") == 0)
{
return patch_hda_kext(plist, plistbuffer, start);
}
/*
else if(patch_hda_codec && strcmp(bundleID, "com.apple.driver.AppleHDAController") == 0)
{
return patch_hda_controller(plist, plistbuffer, start);
}
*/
return false;
}
}
}
bool patch_hda_controller(TagPtr plist, char* plistbuffer, void* start)
{
return false;
// change the PCI class code to match to. Note: A LegacyHDA plist should do this on it's own
// As such, it's disabled
// TODO: read class code
TagPtr personality;
personality =XMLCastDict(XMLGetProperty(plist, kPropIOKitPersonalities));
personality =XMLGetProperty(personality, (const char*)"BuiltInHDA");
TagPtr match_class =XMLCastArray(XMLGetProperty(personality, (const char*)"IOPCIClassMatch"));
char* new_str = malloc(strlen("0xXXXX000&0xFFFE0000")+1);
sprintf(new_str, "0x04030000&0xFFFE0000"); // todo, pass in actual class id
char* orig_string = "0x04020000&0xFFFE0000"; //XMLCastString(match_class);
DBG("Attemting to replace '%s' with '%s'\n", orig_string, new_str);
// TODO: verify string doesn't exist first.
replace_string(orig_string, new_str, plistbuffer + XMLCastStringOffset(match_class), 1024);
return true;
}
bool patch_hda_kext(TagPtr plist, char* plistbuffer, void* start)
{
uint16_t find_codec = 0;
int full_size, compressed_size, executable_offset;
void* compressed_data;
mkext2_file_entry* kext;
int zlib_result;
z_stream zstream;
bool zstream_inited = false;
switch(0xFF00 & patch_hda_codec)
{
case 0x0200:
find_codec = 0x0262;
break;
case 0x0800:
find_codec = 0x0885;
break;
case 0x0600:// specificaly the 662
find_codec = 0x0885;
break;
}
if(!find_codec) return false;// notify caller that we aren't patching the kext
executable_offset = XMLCastInteger(XMLGetProperty(plist, kMKEXTExecutableKey));
kext = (void*)((char*)start + executable_offset);
full_size = MKEXT2_GET_ENTRY_FULLSIZE(kext);
compressed_size = MKEXT2_GET_ENTRY_COMPSIZE(kext);
compressed_data = MKEXT2_GET_ENTRY_DATA(kext);
executable_offset = XMLCastInteger(XMLGetProperty(plist, kMKEXTExecutableKey));
char* executable = malloc(full_size);
bzero(&zstream, sizeof(zstream));
zstream.next_in = (UInt8*)compressed_data;
zstream.avail_in = compressed_size;
zstream.next_out = (UInt8*)executable;
zstream.avail_out = full_size;
zstream.zalloc = z_alloc;
zstream.zfree = z_free;
zlib_result = inflateInit(&zstream);
if (Z_OK != zlib_result)
{
printf("ZLIB Inflate Error: %s\n", zstream.msg);
getc();
}
else
{
zstream_inited = true;
}
zlib_result = inflate(&zstream, Z_FINISH);
DBG("Inflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, full_size);
replace_word(0x10EC | (find_codec << 8), 0xE10EC | (patch_hda_codec << 8), executable, zstream.total_out);
if (zstream_inited) inflateEnd(&zstream);
zstream.next_in = (UInt8*)executable;
zstream.next_out = (UInt8*)compressed_data;
zstream.avail_in = full_size;
zstream.avail_out = compressed_size;
zstream.zalloc = Z_NULL;
zstream.zfree = Z_NULL;
zstream.opaque = Z_NULL;
// Recompress the eecutable
zlib_result = deflateInit2(&zstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,15, 8 /* memLevel */, Z_DEFAULT_STRATEGY);
if (Z_OK != zlib_result) {
printf("ZLIB Deflate Error: %s\n", zstream.msg);
getc();
}
else
{
zstream_inited = true;
}
zlib_result = deflate(&zstream, Z_FINISH);
if (zlib_result == Z_STREAM_END)
{
DBG("Deflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, full_size);
}
else if (zlib_result == Z_OK)
{
/* deflate filled output buffer, meaning the data doesn't compress.
*/
DBG("Deflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, full_size);
}
else if (zlib_result != Z_STREAM_ERROR)
{
printf("ZLIB Deflate Error: %s\n", zstream.msg);
getc();
}
if (zstream_inited) deflateEnd(&zstream);
free(executable);
return true;
}
bool patch_bcm_kext(TagPtr plist, char* plistbuffer, void* start)
{
TagPtr personality;
// TODO: verify string doesn't exist first.
replace_string(orig_string, new_str, plistbuffer + XMLCastStringOffset(replace));
replace_string(orig_string, new_str, plistbuffer + XMLCastStringOffset(replace), 1024);
return true;
}
#endif
offset =XMLCastStringOffset(XMLGetProperty(personality, (const char*)"IOPCIPrimaryMatch"));
replace_string("0x27A28086", "0x27AE8086", plistbuffer + offset);
replace_string("0x27A28086", "0x27AE8086", plistbuffer + offset, 1024);
DBG("Located kext %s\n", bundleID);
DBG("PCI Match offset = %d, string = %s\n", offset, pcimatch);
branches/meklort/i386/modules/KextPatcher/hex_editor.c
7575
7676
7777
78
78
7979
8080
8181
8282
83
8384
8485
8586
86
87
8788
89
8890
8991
9092
return num_replaced;
}
void replace_string(char* find, char* replace, char* string)
void replace_string(char* find, char* replace, char* string, int length)
{
if(!find ||
!replace ||
!string ||
!length ||
strlen(find) != strlen(replace)) return;
char* str = string;
while(strncmp(str, find, strlen(find)-1))
while(length && strncmp(str, find, strlen(find)-1))
{
length--;
str++;
}
strncpy(str, replace, strlen(replace) - 1);// don't copy the null char

Archive Download the corresponding diff file

Revision: 610