Chameleon

Chameleon Svn Source Tree

Root/branches/meklort/i386/modules/KextPatcher/kext_patcher.c

Source at commit 735 created 10 years 22 days ago.
By meklort, GUI module bugfixes. Kext Patcher additions.
1/*
2 * Copyright (c) 2010 Evan Lojewski. All rights reserved.
3 *
4 *KextPather
5 *This is an experimental module that I'm looking into implimenting.
6 *The main purpose is to replace the need for programs such as
7 * NetbookInstaller's kext patching routines. THis way, Apple's kexts can be
8 * patched whe loaded instead. (eg: GMA950 kext, Bluetooth + Wifi kexts)
9 */
10
11#include "libsaio.h"
12#include "zlib.h"
13#include "kext_patcher.h"
14#include "boot.h"
15#include "bootstruct.h"
16#include "pci.h"
17#include "drivers.h"
18#include "mkext.h"
19#include "modules.h"
20#include "hex_editor.h"
21
22
23unsigned long Adler32( unsigned char * buffer, long length );
24
25
26#define kHDACodec"HDACodec"
27
28
29#ifndef DEBUG_KEXT_PATCHER
30#define DEBUG_KEXT_PATCHER 0
31#endif
32
33#if DEBUG_KEXT_PATCHER
34#define DBG(x...)printf(x)
35#else
36#define DBG(x...)
37#endif
38
39
40bool patch_kext(TagPtr plist, char* plistbuffer, void* start);
41bool patch_gma_kexts(TagPtr plist, char* plistbuffer, void* start);
42bool patch_bcm_kext(TagPtr plist, char* plistbuffer, void* start);
43bool patch_atheros_kext(TagPtr plist, char* plistbuffer, void* start);
44bool patch_hda_kext(TagPtr plist, char* plistbuffer, void* start);
45bool patch_hda_controller(TagPtr plist, char* plistbuffer, void* start);
46
47int chartohex(char c);
48
49static void * z_alloc(void *, u_int items, u_int size);
50static void z_free(void *, void *ptr);
51
52uint16_t patch_gma_deviceid = 0;
53uint16_t patch_bcm_deviceid = 0;
54uint16_t patch_atheros_deviceid = 0;
55
56// TODO: add detection code
57uint16_t patch_hda_codec = 0x00;
58
59#define NEEDS_PATCHING(patch_bcm_deviceid || patch_gma_deviceid || patch_hda_codec || patch_atheros_deviceid)
60
61typedef struct z_mem {
62 uint32_t alloc_size;
63 uint8_t data[0];
64} z_mem;
65
66/*
67 * Space allocation and freeing routines for use by zlib routines.
68 */
69void *
70z_alloc(void * notused __unused, u_int num_items, u_int size)
71{
72 void * result = NULL;
73 z_mem * zmem = NULL;
74 uint32_t total = num_items * size;
75 uint32_t allocSize = total + sizeof(zmem);
76
77 zmem = (z_mem *)malloc(allocSize);
78 if (!zmem) {
79 goto finish;
80 }
81 zmem->alloc_size = allocSize;
82 result = (void *)&(zmem->data);
83finish:
84 return result;
85}
86
87void
88z_free(void * notused __unused, void * ptr)
89{
90 uint32_t * skipper = (uint32_t *)ptr - 1;
91 z_mem * zmem = (z_mem *)skipper;
92 free((void *)zmem);
93 return;
94}
95
96
97
98void KextPatcher_hook(void* current, void* arg2, void* arg3, void* arg4);
99
100/**
101 ** KextPatcher_start -> module start
102 **Notified the module system that this module will hook into the
103 **LoadMatchedModules and LoadDriverMKext functions
104 **/
105void KextPatcher_start()
106{
107// Hooks into the following:
108//execute_hook("LoadDriverMKext", (void*)package, (void*) length, NULL, NULL);
109// execute_hook("LoadMatchedModules", module, &length, executableAddr, NULL);
110
111register_hook_callback("PCIDevice", &KextPatcher_hook);
112//register_hook_callback("LoadMatchedModules", &kext_loaded);
113register_hook_callback("LoadDriverMKext", &mkext_loaded);
114
115}
116
117/**
118 ** kext_loaded -> Called whenever a kext is in read into memory
119 **This function will be used to patch kexts ( eg AppleInteIntegratedFramebuffer)
120 **and their plists when they are loaded into memmory
121 **/
122void kext_loaded(void* moduletmp, void* lengthprt, void* executableAddr, void* arg3)
123{
124
125//ModulePtr module = moduletmp;
126//long length = *(long*)lengthprt;
127//long length2 = strlen(module->plistAddr);
128// *(long*)lengthprt = length2 + 5 * 1024 * 1024;
129
130//printf("Loading %s, lenght is %d, executable is 0x%X\n", module->plistAddr, length, executableAddr);
131//getc();
132}
133
134/**
135 ** mkext_loaded -> Called whenever an mkext is in read into memory
136 **This function will be used to patch mkext. Matching kexts will be
137 **Extracted, modified, and then compressed again. Note: I need to determine
138 **what sort of slowdown this will cause and if it's worth implimenting.
139 **/
140
141void mkext_loaded(void* filespec, void* packagetmp, void* lengthtmp, void* arg3)
142{
143const char* hda_codec;
144int len = 0;
145if (getValueForKey(kHDACodec, &hda_codec, &len, &bootInfo->bootConfig))
146{
147patch_hda_codec = 0;
148int index = 0;
149while(len--)
150{
151patch_hda_codec <<= 4;
152patch_hda_codec |= chartohex(hda_codec[index]);
153index++;
154}
155}
156
157if(!NEEDS_PATCHING) return;// No need to apply a patch, hardware doesn't need it
158
159int version = 0;
160//int length = *((int*)lengthtmp);
161mkext_basic_header* package = packagetmp;
162
163// Verify the MKext.
164 if (( MKEXT_GET_MAGIC(package)!= MKEXT_MAGIC ) ||
165 ( MKEXT_GET_SIGNATURE(package)!= MKEXT_SIGN ) ||
166 ( MKEXT_GET_LENGTH(package)> kLoadSize ) ||
167 ( MKEXT_GET_CHECKSUM(package) !=
168 Adler32((unsigned char *)&package->version, MKEXT_GET_LENGTH(package) - 0x10) ) )
169 {
170 return;
171// Don't try to patch a b
172 }
173
174/*
175if(strcmp(filespec, "/System/Library/Caches/com.apple.kext.caches/Startup/Extensions.mkext") == 0)
176{
177printf("Invalidating mkext %s\n", filespec);
178// 10.6 cache folder. Doesn't contain certain extensions we need, so invalidate it.
179//package->adler32++;
180// NOTE: double check that this is needed
181package->magic = 0x00;
182return;
183}*/
184
185
186version = MKEXT_GET_VERSION(package);
187
188if(version == 0x01008000) // mkext1
189{
190// mkext1 uses lzss
191mkext1_header* package = packagetmp;
192int i;
193for(i = 0; i < MKEXT_GET_COUNT(package); i++)
194{
195DBG("Parsing kext %d\n", i);
196//mkext_kext* kext = MKEXT1_GET_KEXT(package, i);
197// uses decompress_lzss
198// TODO: handle kext
199
200}
201}
202else if((version & 0xFFFF0000) == 0x02000000) // mkext2
203{
204DBG("Mkext2 package located at 0x%X\n", package);
205
206// mkext2 uses zlib
207mkext2_header* package = packagetmp;
208z_stream zstream;
209bool zstream_inited = false;
210int zlib_result;
211int plist_offset = MKEXT2_GET_PLIST(package);
212
213char* plist = malloc(MKEXT2_GET_PLIST_FULLSIZE(package));
214
215bzero(&zstream, sizeof(zstream));
216zstream.next_in = (UInt8*)((char*)package + plist_offset);
217zstream.avail_in = MKEXT2_GET_PLIST_COMPSIZE(package);
218
219zstream.next_out = (UInt8*)plist;
220zstream.avail_out = MKEXT2_GET_PLIST_FULLSIZE(package);
221
222zstream.zalloc = z_alloc;
223zstream.zfree = z_free;
224
225zlib_result = inflateInit(&zstream);
226if (Z_OK != zlib_result)
227{
228printf("ZLIB Error: %s\n", zstream.msg);
229getc();
230}
231else
232{
233zstream_inited = true;
234}
235
236
237zlib_result = inflate(&zstream, Z_FINISH);
238if (zstream_inited) inflateEnd(&zstream);
239
240DBG("Inflated result is %d, in: %d bytes, out: %d bytes\n", zlib_result, zstream.total_in, zstream.total_out);
241if (zlib_result == Z_STREAM_END || zlib_result == Z_OK)
242{
243config_file_t plistData;
244config_file_t allDicts;
245bzero(&plistData, sizeof(plistData));
246bzero(&allDicts, sizeof(allDicts));
247
248XMLParseFile( plist, &plistData.dictionary );
249
250int count;
251
252allDicts.dictionary = XMLGetProperty(plistData.dictionary, kMKEXTInfoDictionariesKey);
253//count = XMLTagCount(allDicts.dictionary);
254
255//DBG("Plist contains %d kexts\n", count);
256
257
258bool patched = false;
259for(count = XMLTagCount(allDicts.dictionary);
260count > 0;
261count--)
262{
263TagPtr kextEntry = XMLGetElement(allDicts.dictionary, count);
264patched |= patch_kext(kextEntry, plist, package);
265}
266
267
268if(patched)
269{
270zstream_inited = false;
271// Recompress the plist
272bzero(&zstream, sizeof(zstream));
273zstream.next_in = (UInt8*)plist;
274zstream.next_out = (UInt8*)package + plist_offset;
275zstream.avail_in = MKEXT2_GET_PLIST_FULLSIZE(package);
276zstream.avail_out = MKEXT2_GET_PLIST_FULLSIZE(package)<<2;// Give us some extra free space, just in case
277zstream.zalloc = Z_NULL;
278zstream.zfree = Z_NULL;
279zstream.opaque = Z_NULL;
280
281
282zlib_result = deflateInit2(&zstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,15, 8 /* memLevel */, Z_DEFAULT_STRATEGY);
283if (Z_OK != zlib_result) {
284printf("ZLIB Deflate Error: %s\n", zstream.msg);
285getc();
286}
287else
288{
289zstream_inited = true;
290}
291
292zlib_result = deflate(&zstream, Z_FINISH);
293
294if (zlib_result == Z_STREAM_END)
295{
296DBG("Deflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, MKEXT2_GET_PLIST_FULLSIZE(package));
297}
298else if (zlib_result == Z_OK)
299{
300/* deflate filled output buffer, meaning the data doesn't compress.
301 */
302DBG("Deflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, MKEXT2_GET_PLIST_FULLSIZE(package));
303
304}
305else if (zlib_result != Z_STREAM_ERROR)
306{
307printf("ZLIB Deflate Error: %s\n", zstream.msg);
308getc();
309}
310
311if(zstream.total_out != MKEXT2_GET_PLIST_COMPSIZE(package))
312{
313// Update the mkext length
314MKEXT2_HDR_CAST(package)->length = MKEXT_SWAP(MKEXT_GET_LENGTH(package) - MKEXT2_GET_PLIST_COMPSIZE(package) + zstream.total_out);
315MKEXT2_HDR_CAST(package)->plist_compressed_size = MKEXT_SWAP(zstream.total_out);
316*((int*)lengthtmp) -= MKEXT2_GET_PLIST_COMPSIZE(package);
317*((int*)lengthtmp) += zstream.total_out;
318}
319
320if (zstream_inited) deflateEnd(&zstream);
321
322
323
324// re adler32 the new mkext2 package
325MKEXT_HDR_CAST(package)->adler32 =
326MKEXT_SWAP(Adler32((unsigned char *)&package->version,
327 MKEXT_GET_LENGTH(package) - 0x10));
328}
329}
330else
331{
332printf("ZLIB Error: %s\n", zstream.msg);
333getc();
334}
335
336//config_file_t mkextPlist;
337//ParseXMLFile((char*) plist, &mkextPlist.dictionary);
338
339
340
341
342
343/*int i;
344for(i = 0; i < MKEXT_GET_COUNT(package); i++)
345{
346printf("Parsing kext %d\n", i);
347}
348*/
349
350
351}
352
353
354DBG("Loading %s, version 0x%x\n", filespec, version);
355//getc();
356}
357
358// FIXME: only handles mkext2 entries
359bool patch_kext(TagPtr plist, char* plistbuffer, void* start)
360{
361char* bundleID;
362
363if(XMLGetProperty(plist, kMKEXTExecutableKey) == NULL) return false;// Kext is a plist only kext, don't patch
364
365bundleID = XMLCastString(XMLGetProperty(plist, kPropCFBundleIdentifier));
366
367
368if(patch_gma_deviceid &&
369 (
370(strcmp(bundleID, "com.apple.driver.AppleIntelGMA950") == 0) ||
371(strcmp(bundleID, "com.apple.driver.AppleIntelIntegratedFramebuffer") == 0)
372 )
373 )
374{
375if(strcmp(bundleID, "com.apple.driver.AppleIntelIntegratedFramebuffer") == 0 || patch_gma_deviceid == 0x27ae)
376{
377return patch_gma_kexts(plist, plistbuffer, start);
378}
379else
380{
381return patch_gma_kexts(plist, plistbuffer, start);
382}
383
384}
385else if(patch_bcm_deviceid && (strcmp(bundleID, "com.apple.driver.AirPortBrcm43xx") == 0))
386{
387return patch_bcm_kext(plist, plistbuffer, start);
388
389}
390else if(patch_hda_codec && strcmp(bundleID, "com.apple.driver.AppleHDA") == 0)
391{
392return patch_hda_kext(plist, plistbuffer, start);
393
394}
395
396else if(patch_hda_codec && strcmp(bundleID, "com.apple.driver.AppleHDAController") == 0)
397{
398return patch_hda_controller(plist, plistbuffer, start);
399
400}
401else if(patch_atheros_deviceid && strcmp(bundleID, "com.apple.driver.AirPort.Atheros21") == 0)
402{
403return patch_atheros_kext(plist, plistbuffer, start);
404}
405
406return false;
407}
408
409void KextPatcher_hook(void* arg1, void* arg2, void* arg3, void* arg4)
410{
411pci_dt_t* current = arg1;
412if(current)
413{
414switch(current->class_id)
415{
416case PCI_CLASS_DISPLAY_VGA:
417if(current->vendor_id == 0x8086 &&
418 (
419current->device_id == 0x27AE ||
420current->device_id == 0xA001 ||
421current->device_id == 0xA002 ||
422current->device_id == 0xA011 ||
423current->device_id == 0xA012
424
425)
426 )
427{
428patch_gma_deviceid = current->device_id;
429}
430break;
431
432case PCI_CLASS_NETWORK_OTHER:
433
434// Patch BCM43xx
435if(current->vendor_id == 0x14E4 && ((current->device_id & 0xFFD0) == 0x4300))
436{
437patch_bcm_deviceid = current->device_id;
438}
439else if(current->vendor_id == 0x168C && current->device_id == 0x002B)
440{
441patch_atheros_deviceid = current->device_id;
442}
443break;
444}
445}
446}
447
448
449bool patch_hda_controller(TagPtr plist, char* plistbuffer, void* start)
450{
451return false;
452// change the PCI class code to match to. Note: A LegacyHDA plist should do this on it's own
453// As such, it's disabled
454
455// TODO: read class code
456TagPtr personality;
457personality =XMLCastDict(XMLGetProperty(plist, kPropIOKitPersonalities));
458personality =XMLGetProperty(personality, (const char*)"BuiltInHDA");
459TagPtr match_class =XMLCastArray(XMLGetProperty(personality, (const char*)"IOPCIClassMatch"));
460
461
462char* new_str = malloc(sizeof("0xXXXX000&0xFFFE0000"));
463sprintf(new_str, "0x04030000&amp;0xFFFE0000"); // todo, pass in actual class id
464
465
466char* orig_string = "0x04020000&amp;0xFFFE0000"; //XMLCastString(match_class);
467
468printf("Attemting to replace '%s' with '%s'\n", orig_string, new_str);
469
470// TODO: verify string doesn't exist first.
471
472replace_string(orig_string, new_str, plistbuffer + XMLCastStringOffset(match_class), 1024);
473
474return true;
475
476}
477
478
479bool patch_hda_kext(TagPtr plist, char* plistbuffer, void* start)
480{
481uint16_t find_codec = 0;
482int full_size, compressed_size, executable_offset;
483void* compressed_data;
484mkext2_file_entry* kext;
485int zlib_result;
486z_stream zstream;
487bool zstream_inited = false;
488
489switch(patch_hda_codec & 0xFF00)
490{
491case 0x0200:
492find_codec = 0x0262;
493break;
494
495case 0x0800:
496find_codec = 0x0885;
497break;
498
499case 0x0600:// specificaly the 662
500find_codec = 0x0885;
501break;
502}
503if(!find_codec) return false;// notify caller that we aren't patching the kext
504
505executable_offset = XMLCastInteger(XMLGetProperty(plist, kMKEXTExecutableKey));
506kext = (void*)((char*)start + executable_offset);
507
508full_size = MKEXT2_GET_ENTRY_FULLSIZE(kext);
509compressed_size = MKEXT2_GET_ENTRY_COMPSIZE(kext);
510compressed_data = MKEXT2_GET_ENTRY_DATA(kext);
511executable_offset = XMLCastInteger(XMLGetProperty(plist, kMKEXTExecutableKey));
512
513
514char* executable = malloc(full_size);
515
516bzero(&zstream, sizeof(zstream));
517zstream.next_in = (UInt8*)compressed_data;
518zstream.avail_in = compressed_size;
519
520zstream.next_out = (UInt8*)executable;
521zstream.avail_out = full_size;
522
523zstream.zalloc = z_alloc;
524zstream.zfree = z_free;
525
526zlib_result = inflateInit(&zstream);
527if (Z_OK != zlib_result)
528{
529printf("ZLIB Inflate Error: %s\n", zstream.msg);
530getc();
531}
532else
533{
534zstream_inited = true;
535}
536
537
538zlib_result = inflate(&zstream, Z_FINISH);
539
540DBG("Inflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, full_size);
541
542/*int times = */replace_word(0x10EC0000 | (find_codec), 0x10EC0000 | (patch_hda_codec), executable, zstream.total_out);
543if (zstream_inited) inflateEnd(&zstream);
544
545
546zstream.next_in = (UInt8*)executable;
547zstream.next_out = (UInt8*)compressed_data;
548
549zstream.avail_in = full_size;
550zstream.avail_out = compressed_size<<1;
551zstream.zalloc = Z_NULL;
552zstream.zfree = Z_NULL;
553zstream.opaque = Z_NULL;
554
555
556
557// Recompress the eecutable
558zlib_result = deflateInit2(&zstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,15, 8 /* memLevel */, Z_DEFAULT_STRATEGY);
559if (Z_OK != zlib_result) {
560printf("ZLIB Deflate Error: %s\n", zstream.msg);
561getc();
562}
563else
564{
565zstream_inited = true;
566}
567
568zlib_result = deflate(&zstream, Z_FINISH);
569
570if (zlib_result == Z_STREAM_END)
571{
572DBG("Deflated result is %d, avail: %d bytes, out: %d bytes, full: %d\n", zlib_result, compressed_size, zstream.total_out, full_size);
573}
574else if (zlib_result == Z_OK)
575{
576/* deflate filled output buffer, meaning the data doesn't compress.
577 */
578DBG("Buffer FULL: deflated result is %d, avail: %d bytes, out: %d bytes, full: %d\n", zlib_result, compressed_size, zstream.total_out, full_size);
579printf("Unable to patch AppleHDA\n");
580
581}
582else if (zlib_result != Z_STREAM_ERROR)
583{
584printf("AppleHDA: ZLIB Deflate Error: %s\n", zstream.msg);
585getc();
586}
587
588if (zstream_inited) deflateEnd(&zstream);
589
590if(zstream.total_out < compressed_size) kext->compressed_size = MKEXT_SWAP(zstream.total_out);
591
592
593free(executable);
594
595return true;
596
597}
598bool patch_atheros_kext(TagPtr plist, char* plistbuffer, void* start)
599{
600TagPtr personality;
601personality =XMLCastDict(XMLGetProperty(plist, kPropIOKitPersonalities));
602personality =XMLGetProperty(personality, (const char*)"Atheros Wireless LAN PCI");
603TagPtr match_names =XMLCastArray(XMLGetProperty(personality, (const char*)"IONameMatch"));
604
605char* new_str = malloc(sizeof("pci168c,xxxx"));
606sprintf(new_str, "pci168c,%02x", patch_atheros_deviceid);
607
608// Check to see if we *really* need to modify the plist, if not, return false
609// so that *if* this were going ot be the only modified kext, the repacking code
610// won't need to be executed.
611int count = XMLTagCount(match_names);
612while(count)
613{
614count--;
615TagPtr replace =XMLGetElement(match_names, count);// Modify the second entry
616char* orig_string = XMLCastString(replace);
617if(strcmp(orig_string, new_str) == 0) return false;
618}
619
620
621
622TagPtr replace =XMLGetElement(match_names, 0);// Modify the second entry
623char* orig_string = XMLCastString(replace);
624
625verbose("Patching AirPortAtheros21.kext, replacing %s with %s\n", orig_string, new_str);
626
627// TODO: verify string doesn't exist first.
628
629replace_string(orig_string, new_str, plistbuffer + XMLCastStringOffset(replace), 10240);
630return true;
631
632}
633
634
635bool patch_bcm_kext(TagPtr plist, char* plistbuffer, void* start)
636{
637TagPtr personality;
638personality =XMLCastDict(XMLGetProperty(plist, kPropIOKitPersonalities));
639personality =XMLGetProperty(personality, (const char*)"Broadcom 802.11 PCI");
640TagPtr match_names =XMLCastArray(XMLGetProperty(personality, (const char*)"IONameMatch"));
641
642
643char* new_str = malloc(sizeof("pci14e4,xxxx"));
644sprintf(new_str, "pci14e4,%02x", patch_bcm_deviceid);
645
646// Check to see if we *really* need to modify the plist, if not, return false
647// so that *if* this were going ot be the only modified kext, the repacking code
648// won't need to be executed.
649int count = XMLTagCount(match_names);
650while(count)
651{
652count--;
653TagPtr replace =XMLGetElement(match_names, count);// Modify the second entry
654char* orig_string = XMLCastString(replace);
655if(strcmp(orig_string, new_str) == 0) return false;
656}
657
658verbose("Patching AppleAirPortBrcm4311.kext with %s\n", new_str);
659
660TagPtr replace =XMLGetElement(match_names, 1);// Modify the second entry
661char* orig_string = XMLCastString(replace);
662
663
664// TODO: verify string doesn't exist first.
665
666replace_string(orig_string, new_str, plistbuffer + XMLCastStringOffset(replace), 10240);
667
668return true;
669}
670
671bool patch_gma_kexts(TagPtr plist, char* plistbuffer, void* start)
672{
673// TODO: clean up this function / split into two / etc
674int exeutable_offset, full_size, compressed_size;
675TagPtr personality;
676long offset;
677int zlib_result;
678z_stream zstream;
679bool zstream_inited = false;
680mkext2_file_entry* kext;
681void* compressed_data;
682
683exeutable_offset = XMLCastInteger(XMLGetProperty(plist, kMKEXTExecutableKey));
684kext = (void*)((char*)start + exeutable_offset);
685
686full_size = MKEXT2_GET_ENTRY_FULLSIZE(kext);
687compressed_size = MKEXT2_GET_ENTRY_COMPSIZE(kext);
688compressed_data = MKEXT2_GET_ENTRY_DATA(kext);
689
690personality =XMLCastDict(XMLGetProperty(plist, kPropIOKitPersonalities));
691
692
693
694char* executable = malloc(full_size);
695
696bzero(&zstream, sizeof(zstream));
697zstream.next_in = (UInt8*)compressed_data;
698zstream.avail_in = compressed_size;
699
700zstream.next_out = (UInt8*)executable;
701zstream.avail_out = full_size;
702
703zstream.zalloc = z_alloc;
704zstream.zfree = z_free;
705
706zlib_result = inflateInit(&zstream);
707if (Z_OK != zlib_result)
708{
709printf("ZLIB Inflate Error: %s\n", zstream.msg);
710getc();
711}
712else
713{
714zstream_inited = true;
715}
716
717
718zlib_result = inflate(&zstream, Z_FINISH);
719
720DBG("Inflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, full_size);
721
722char* newstring = malloc(sizeof("0x00008086"));
723sprintf(newstring, "0x%04x", 0x8086 | (patch_gma_deviceid << 16));
724
725
726if(XMLGetProperty(personality, (const char*)"Intel915"))
727{
728if((patch_gma_deviceid & 0xFF00) != 0xA000)// GMA3150
729{
730verbose("Patching AppleIntelGMA950.kext\n");
731//getc();
732
733personality =XMLGetProperty(personality, (const char*)"Intel915"); // IOAccelerator kext
734
735offset =XMLCastStringOffset(XMLGetProperty(personality, (const char*)"IOPCIPrimaryMatch"));
736replace_string("0x27A28086", newstring, plistbuffer + offset, 10240);
737replace_word(0x27A28086, 0x8086 | (patch_gma_deviceid << 16), executable, zstream.total_out);
738}
739
740}
741else if(XMLGetProperty(personality, (const char*)"AppleIntelIntegratedFramebuffer"))
742{
743verbose("Patching AppleIntelIntegratedFramebuffer\n");
744//getc();
745
746personality =XMLGetProperty(personality, (const char*)"AppleIntelIntegratedFramebuffer");
747// Framebuffer Kext
748
749if((patch_gma_deviceid & 0xFF00) == 0xA000)// GMA3150
750{
751// Cursor corruption fix.
752// This patch changes the cursor address from
753// a physical address (used in the gma950) to an offset (used in the gma3150).
754//s{0x8b, 0x55, 0x08, 0x83, 0xba, 0xb0, 0x00, 0x00, 0x00, 0x01, 0x7e, 0x36, 0x89, 0x04, 0x24, 0xe8, 0x6b, 0xbc, 0xff, 0xff};
755char find_bytes[] = {0x8b, 0x55, 0x08, 0x83, 0xba, 0xb0, 0x00, 0x00, 0x00, 0x01, 0x7e, 0x36, 0x89, 0x04, 0x24, 0xe8/*, 0x32, 0xbb, 0xff, 0xff*/};// getPhysicalAddress() and more
756char new_bytes[] = {0xb8, 0x00, 0x00, 0x00, 0x02, 0xEB, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};// jump past getPhysicalAddress binding. NOTE: last six bytes are unusable
757replace_bytes(find_bytes, sizeof(find_bytes), new_bytes, sizeof(new_bytes), executable, zstream.total_out);
758
759
760}
761offset =XMLCastStringOffset(XMLGetProperty(personality, (const char*)"IOPCIPrimaryMatch"));
762replace_string("0x27A28086", newstring, plistbuffer + offset, 10240);
763replace_word(0x27A28086, 0x8086 | (patch_gma_deviceid << 16), executable, zstream.total_out);
764
765}
766else if(XMLGetProperty(personality, (const char*)"Intel965"))
767{
768verbose("Patching AppleIntelGMAX3100.kext\n");
769
770personality =XMLGetProperty(personality, (const char*)"Intel965");
771
772offset =XMLCastStringOffset(XMLGetProperty(personality, (const char*)"IOPCIPrimaryMatch"));
773
774//printf("Intel965\n");
775//printf("Replacing %c%c%c%c\n", (plistbuffer + offset)[0], (plistbuffer + offset)[1], (plistbuffer + offset)[2], (plistbuffer + offset)[3]);
776//getc();
777
778
779//return true;
780
781replace_string("0x2a028086", newstring, plistbuffer + offset, 10240);
782//replace_word(0x2A028086, 0x8086 | (patch_gma_deviceid << 16), executable, zstream.total_out);
783}
784else if(XMLGetProperty(personality, (const char*)"AppleIntelGMAX3100FB"))
785{
786verbose("Patching AppleIntelGMAX3100FB.kext\n");
787//getc();
788personality =XMLGetProperty(personality, (const char*)"AppleIntelGMAX3100FB");
789
790offset =XMLCastStringOffset(XMLGetProperty(personality, (const char*)"IOPCIPrimaryMatch"));
791replace_string("0x2A028086", newstring, plistbuffer + offset, 10240);
792replace_word(0x2A028086, 0x8086 | (patch_gma_deviceid << 16), executable, zstream.total_out);
793}
794else
795{
796return false;
797}
798
799
800if (zstream_inited) inflateEnd(&zstream);
801
802
803zstream.next_in = (UInt8*)executable;
804zstream.next_out = (UInt8*)compressed_data;
805
806zstream.avail_in = full_size;
807zstream.avail_out = compressed_size;
808zstream.zalloc = Z_NULL;
809zstream.zfree = Z_NULL;
810zstream.opaque = Z_NULL;
811
812
813
814// Recompress the eecutable
815zlib_result = deflateInit2(&zstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,15, 8 /* memLevel */, Z_DEFAULT_STRATEGY);
816if (Z_OK != zlib_result) {
817printf("ZLIB Deflate Error: %s\n", zstream.msg);
818getc();
819}
820else
821{
822zstream_inited = true;
823}
824
825zlib_result = deflate(&zstream, Z_FINISH);
826
827if (zlib_result == Z_STREAM_END)
828{
829DBG("Deflated result is %d, avail: %d bytes, out: %d bytes, full: %d\n", zlib_result, compressed_size, zstream.total_out, full_size);
830}
831else if (zlib_result == Z_OK)
832{
833/* deflate filled output buffer, meaning the data doesn't compress.
834 */
835printf("Deflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, full_size);
836printf("ERROR: Unable to compress patched kext, not enough room.\n");
837pause();
838
839}
840else if (zlib_result != Z_STREAM_ERROR)
841{
842printf("ZLIB Deflate Error: %s\n", zstream.msg);
843getc();
844}
845if(zstream.total_out < compressed_size) kext->compressed_size = MKEXT_SWAP(zstream.total_out);
846
847
848
849
850if (zstream_inited) deflateEnd(&zstream);
851
852free(executable);
853
854return true;
855}
856
857int chartohex(char c)
858{
859if(c <= '9' && c >= '0')
860{
861return c - '0';// c is between 0 and 9
862}
863else if(c <= 'F' && c >= 'A')
864{
865return c - 'A' + 10; // c = 10 - 15;
866}
867else if(c <= 'f' && c >= 'a')
868{
869return c - 'a' + 10; // c = 10 - 15;
870}
871return 0;
872}

Archive Download this file

Revision: 735