Chameleon

Chameleon Svn Source Tree

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

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

Archive Download this file

Revision: 728