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

Archive Download this file

Revision: 1804