Chameleon

Chameleon Svn Source Tree

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

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

Archive Download this file

Revision: 2044