Chameleon

Chameleon Svn Source Tree

Root/branches/slice/old749m/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 0
28#endif
29
30#if DEBUG_KEXT_PATCHER
31#define DBG(x...)verbose(x)
32#else
33#define DBG(x...)
34#endif
35
36
37bool patch_kext(TagPtr plist, char* plistbuffer, void* start);
38bool patch_gma_kexts(TagPtr plist, char* plistbuffer, void* start);
39bool patch_bcm_kext(TagPtr plist, char* plistbuffer, void* start);
40bool patch_hda_kext(TagPtr plist, char* plistbuffer, void* start);
41bool patch_hda_controller(TagPtr plist, char* plistbuffer, void* start);
42
43int chartohex(char c);
44
45static void * z_alloc(void *, u_int items, u_int size);
46static void z_free(void *, void *ptr);
47
48uint16_t patch_gma_deviceid = 0;
49uint16_t patch_bcm_deviceid = 0;
50
51// TODO: add detection code
52uint16_t patch_hda_codec = 0x00;
53
54#define NEEDS_PATCHING(patch_bcm_deviceid || patch_gma_deviceid || patch_hda_codec)
55
56typedef struct z_mem {
57 uint32_t alloc_size;
58 uint8_t data[0];
59} z_mem;
60
61/*
62 * Space allocation and freeing routines for use by zlib routines.
63 */
64void *
65z_alloc(void * notused __unused, u_int num_items, u_int size)
66{
67 void * result = NULL;
68 z_mem * zmem = NULL;
69 uint32_t total = num_items * size;
70 uint32_t allocSize = total + sizeof(zmem);
71
72 zmem = (z_mem *)malloc(allocSize);
73 if (!zmem) {
74 goto finish;
75 }
76 zmem->alloc_size = allocSize;
77 result = (void *)&(zmem->data);
78finish:
79 return result;
80}
81
82void
83z_free(void * notused __unused, void * ptr)
84{
85 uint32_t * skipper = (uint32_t *)ptr - 1;
86 z_mem * zmem = (z_mem *)skipper;
87 free((void *)zmem);
88 return;
89}
90
91
92//unsigned long Adler32( unsigned char * buffer, long length );
93
94void KextPatcher_hook(void* current, void* arg2, void* arg3, void* arg4);
95
96/**
97 ** KextPatcher_start -> module start
98 **Notified the module system that this module will hook into the
99 **LoadMatchedModules and LoadDriverMKext functions
100 **/
101void KextPatcher_start()
102{
103// Hooks into the following:
104//execute_hook("LoadDriverMKext", (void*)package, (void*) length, NULL, NULL);
105// execute_hook("LoadMatchedModules", module, &length, executableAddr, NULL);
106
107register_hook_callback("PCIDevice", &KextPatcher_hook);
108//register_hook_callback("LoadMatchedModules", &kext_loaded);
109register_hook_callback("LoadDriverMKext", &mkext_loaded);
110
111}
112
113/**
114 ** kext_loaded -> Called whenever a kext is in read into memory
115 **This function will be used to patch kexts ( eg AppleInteIntegratedFramebuffer)
116 **and their plists when they are loaded into memmory
117 **/
118void kext_loaded(void* moduletmp, void* lengthprt, void* executableAddr, void* arg3)
119{
120
121//ModulePtr module = moduletmp;
122//long length = *(long*)lengthprt;
123//long length2 = strlen(module->plistAddr);
124// *(long*)lengthprt = length2 + 5 * 1024 * 1024;
125
126//printf("Loading %s, lenght is %d, executable is 0x%X\n", module->plistAddr, length, executableAddr);
127//getc();
128}
129
130/**
131 ** mkext_loaded -> Called whenever an mkext is in read into memory
132 **This function will be used to patch mkext. Matching kexts will be
133 **Extracted, modified, and then compressed again. Note: I need to determine
134 **what sort of slowdown this will cause and if it's worth implimenting.
135 **/
136
137void mkext_loaded(void* filespec, void* packagetmp, void* lengthtmp, void* arg3)
138{
139const char* hda_codec;
140int len = 0;
141if (getValueForKey(kHDACodec, &hda_codec, &len, &bootInfo->bootConfig))
142{
143patch_hda_codec = 0;
144int index = 0;
145while(len--)
146{
147patch_hda_codec <<= 4;
148patch_hda_codec |= chartohex(hda_codec[index]);
149index++;
150}
151}
152
153if(!NEEDS_PATCHING) return;// No need to apply a patch, hardware doesn't need it
154
155int version = 0;
156//int length = *((int*)lengthtmp);
157mkext_basic_header* package = packagetmp;
158
159// Verify the MKext.
160 if (( MKEXT_GET_MAGIC(package)!= MKEXT_MAGIC ) ||
161 ( MKEXT_GET_SIGNATURE(package)!= MKEXT_SIGN ) ||
162 ( MKEXT_GET_LENGTH(package)> kLoadSize ) ||
163 ( MKEXT_GET_CHECKSUM(package) !=
164 Adler32((unsigned char *)&package->version, MKEXT_GET_LENGTH(package) - 0x10) ) )
165 {
166msglog("mkext verification failed, do not patch\n");
167 return;
168// Don't try to patch a b
169 }
170
171/*
172if(strcmp(filespec, "/System/Library/Caches/com.apple.kext.caches/Startup/Extensions.mkext") == 0)
173{
174printf("Invalidating mkext %s\n", filespec);
175// 10.6 cache folder. Doesn't contain certain extensions we need, so invalidate it.
176//package->adler32++;
177// NOTE: double check that this is needed
178package->magic = 0x00;
179return;
180}*/
181
182
183version = MKEXT_GET_VERSION(package);
184
185if(version == 0x01008000) // mkext1
186{
187// mkext1 uses lzss
188mkext1_header* package = packagetmp;
189int i;
190for(i = 0; i < MKEXT_GET_COUNT(package); i++)
191{
192DBG("Parsing kext %d\n", i);
193//mkext_kext* kext = MKEXT1_GET_KEXT(package, i);
194// uses decompress_lzss
195// TODO: handle kext
196
197}
198}
199else if((version & 0xFFFF0000) == 0x02000000) // mkext2
200{
201DBG("Mkext2 package located at 0x%X\n", package);
202
203// mkext2 uses zlib
204mkext2_header* package = packagetmp;
205z_stream zstream;
206bool zstream_inited = false;
207int zlib_result;
208int plist_offset = MKEXT2_GET_PLIST(package);
209
210char* plist = malloc(MKEXT2_GET_PLIST_FULLSIZE(package));
211
212bzero(&zstream, sizeof(zstream));
213zstream.next_in = (UInt8*)((char*)package + plist_offset);
214zstream.avail_in = MKEXT2_GET_PLIST_COMPSIZE(package);
215
216zstream.next_out = (UInt8*)plist;
217zstream.avail_out = MKEXT2_GET_PLIST_FULLSIZE(package);
218
219zstream.zalloc = z_alloc;
220zstream.zfree = z_free;
221
222zlib_result = inflateInit(&zstream);
223if (Z_OK != zlib_result)
224{
225printf("ZLIB Error: %s\n", zstream.msg);
226getc();
227}
228else
229{
230zstream_inited = true;
231}
232
233
234zlib_result = inflate(&zstream, Z_FINISH);
235if (zstream_inited) inflateEnd(&zstream);
236
237DBG("Inflated result is %d, in: %d bytes, out: %d bytes\n", zlib_result, zstream.total_in, zstream.total_out);
238if (zlib_result == Z_STREAM_END || zlib_result == Z_OK)
239{
240config_file_t plistData;
241config_file_t allDicts;
242bzero(&plistData, sizeof(plistData));
243bzero(&allDicts, sizeof(allDicts));
244
245XMLParseFile( plist, &plistData.dictionary );
246
247int count = 0;
248
249allDicts.dictionary = XMLGetProperty(plistData.dictionary, kMKEXTInfoDictionariesKey);
250//count = XMLTagCount(allDicts.dictionary);
251
252//DBG("Plist contains %d kexts\n", count);
253
254
255bool patched = false;
256for(count = XMLTagCount(allDicts.dictionary);
257count > 0;
258count--)
259{
260TagPtr kextEntry = XMLGetElement(allDicts.dictionary, count);
261patched |= patch_kext(kextEntry, plist, package);
262}
263
264
265if(patched)
266{
267zstream_inited = false;
268// Recompress the plist
269bzero(&zstream, sizeof(zstream));
270zstream.next_in = (UInt8*)plist;
271zstream.next_out = (UInt8*)package + plist_offset;
272zstream.avail_in = MKEXT2_GET_PLIST_FULLSIZE(package);
273zstream.avail_out = MKEXT2_GET_PLIST_FULLSIZE(package)<<2;// Give us some extra free space, just in case
274zstream.zalloc = Z_NULL;
275zstream.zfree = Z_NULL;
276zstream.opaque = Z_NULL;
277
278
279zlib_result = deflateInit2(&zstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,15, 8 /* memLevel */, Z_DEFAULT_STRATEGY);
280if (Z_OK != zlib_result) {
281printf("ZLIB Deflate Error: %s\n", zstream.msg);
282getc();
283}
284else
285{
286zstream_inited = true;
287}
288
289zlib_result = deflate(&zstream, Z_FINISH);
290
291if (zlib_result == Z_STREAM_END)
292{
293DBG("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));
294}
295else if (zlib_result == Z_OK)
296{
297/* deflate filled output buffer, meaning the data doesn't compress.
298 */
299DBG("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));
300
301}
302else if (zlib_result != Z_STREAM_ERROR)
303{
304printf("ZLIB Deflate Error: %s\n", zstream.msg);
305getc();
306}
307
308if(zstream.total_out != MKEXT2_GET_PLIST_COMPSIZE(package))
309{
310// Update the mkext length
311MKEXT2_HDR_CAST(package)->length = MKEXT_SWAP(MKEXT_GET_LENGTH(package) - MKEXT2_GET_PLIST_COMPSIZE(package) + zstream.total_out);
312MKEXT2_HDR_CAST(package)->plist_compressed_size = MKEXT_SWAP(zstream.total_out);
313*((int*)lengthtmp) -= MKEXT2_GET_PLIST_COMPSIZE(package);
314*((int*)lengthtmp) += zstream.total_out;
315}
316
317if (zstream_inited) deflateEnd(&zstream);
318
319
320
321// re adler32 the new mkext2 package
322MKEXT_HDR_CAST(package)->adler32 =
323MKEXT_SWAP(Adler32((unsigned char *)&package->version,
324 MKEXT_GET_LENGTH(package) - 0x10));
325}
326}
327else
328{
329printf("ZLIB Error: %s\n", zstream.msg);
330getc();
331}
332
333//config_file_t mkextPlist;
334//ParseXMLFile((char*) plist, &mkextPlist.dictionary);
335
336
337
338
339
340/*int i;
341for(i = 0; i < MKEXT_GET_COUNT(package); i++)
342{
343printf("Parsing kext %d\n", i);
344}
345*/
346
347
348}
349
350
351DBG("Loading %s, version 0x%x\n", filespec, version);
352//getc();
353}
354
355// FIXME: only handles mkext2 entries
356bool patch_kext(TagPtr plist, char* plistbuffer, void* start)
357{
358char* bundleID;
359
360if(XMLGetProperty(plist, kMKEXTExecutableKey) == NULL) return false;// Kext is a plist only kext, don't patch
361
362bundleID = XMLCastString(XMLGetProperty(plist, kPropCFBundleIdentifier));
363
364
365if(patch_gma_deviceid &&
366 (
367(strcmp(bundleID, "com.apple.driver.AppleIntelGMA950") == 0) ||
368(strcmp(bundleID, "com.apple.driver.AppleIntelIntegratedFramebuffer") == 0)
369 )
370 )
371{
372if(strcmp(bundleID, "com.apple.driver.AppleIntelIntegratedFramebuffer") == 0 || patch_gma_deviceid == 0x27ae)
373{
374return patch_gma_kexts(plist, plistbuffer, start);
375}
376else
377{
378return patch_gma_kexts(plist, plistbuffer, start);
379}
380
381}
382else if(patch_bcm_deviceid && (strcmp(bundleID, "com.apple.driver.AirPortBrcm43xx") == 0))
383{
384return patch_bcm_kext(plist, plistbuffer, start);
385
386}
387else if(patch_hda_codec && strcmp(bundleID, "com.apple.driver.AppleHDA") == 0)
388{
389return patch_hda_kext(plist, plistbuffer, start);
390
391}
392
393else if(patch_hda_codec && strcmp(bundleID, "com.apple.driver.AppleHDAController") == 0)
394{
395return patch_hda_controller(plist, plistbuffer, start);
396
397}
398
399return false;
400}
401
402void KextPatcher_hook(void* arg1, void* arg2, void* arg3, void* arg4)
403{
404pci_dt_t* current = arg1;
405if(current)
406{
407switch(current->class_id)
408{
409case PCI_CLASS_DISPLAY_VGA:
410if(current->vendor_id == 0x8086 &&
411 (
412current->device_id == 0x27AE ||
413current->device_id == 0xA001 ||
414current->device_id == 0xA002 ||
415current->device_id == 0xA011 ||
416current->device_id == 0xA012
417
418)
419 )
420{
421patch_gma_deviceid = current->device_id;
422}
423break;
424
425case PCI_CLASS_NETWORK_OTHER:
426
427// Patch BCM43xx
428if(current->vendor_id == 0x14E4 && ((current->device_id & 0xFF00) == 0x4300))
429{
430patch_bcm_deviceid = current->device_id;
431}
432break;
433}
434}
435}
436
437
438bool patch_hda_controller(TagPtr plist, char* plistbuffer, void* start)
439{
440return false;
441// change the PCI class code to match to. Note: A LegacyHDA plist should do this on it's own
442// As such, it's disabled
443
444// TODO: read class code
445TagPtr personality;
446personality =XMLCastDict(XMLGetProperty(plist, kPropIOKitPersonalities));
447personality =XMLGetProperty(personality, (const char*)"BuiltInHDA");
448TagPtr match_class =XMLCastArray(XMLGetProperty(personality, (const char*)"IOPCIClassMatch"));
449
450
451char* new_str = malloc(sizeof("0xXXXX000&0xFFFE0000"));
452sprintf(new_str, "0x04030000&amp;0xFFFE0000"); // todo, pass in actual class id
453
454
455char* orig_string = "0x04020000&amp;0xFFFE0000"; //XMLCastString(match_class);
456
457verbose("Attemting to replace '%s' with '%s'\n", orig_string, new_str);
458
459// TODO: verify string doesn't exist first.
460
461replace_string(orig_string, new_str, plistbuffer + XMLCastStringOffset(match_class), 1024);
462
463return true;
464
465}
466
467
468bool patch_hda_kext(TagPtr plist, char* plistbuffer, void* start)
469{
470uint16_t find_codec = 0;
471int full_size, compressed_size, executable_offset;
472void* compressed_data;
473mkext2_file_entry* kext;
474int zlib_result;
475z_stream zstream;
476bool zstream_inited = false;
477
478switch(patch_hda_codec & 0xFF00)
479{
480case 0x0200:
481find_codec = 0x0262;
482break;
483
484case 0x0800:
485find_codec = 0x0885;
486break;
487
488case 0x0600:// specificaly the 662
489find_codec = 0x0885;
490break;
491}
492if(!find_codec) return false;// notify caller that we aren't patching the kext
493
494executable_offset = XMLCastInteger(XMLGetProperty(plist, kMKEXTExecutableKey));
495kext = (void*)((char*)start + executable_offset);
496
497full_size = MKEXT2_GET_ENTRY_FULLSIZE(kext);
498compressed_size = MKEXT2_GET_ENTRY_COMPSIZE(kext);
499compressed_data = MKEXT2_GET_ENTRY_DATA(kext);
500executable_offset = XMLCastInteger(XMLGetProperty(plist, kMKEXTExecutableKey));
501
502
503char* executable = malloc(full_size);
504
505bzero(&zstream, sizeof(zstream));
506zstream.next_in = (UInt8*)compressed_data;
507zstream.avail_in = compressed_size;
508
509zstream.next_out = (UInt8*)executable;
510zstream.avail_out = full_size;
511
512zstream.zalloc = z_alloc;
513zstream.zfree = z_free;
514
515zlib_result = inflateInit(&zstream);
516if (Z_OK != zlib_result)
517{
518printf("ZLIB Inflate Error: %s\n", zstream.msg);
519getc();
520}
521else
522{
523zstream_inited = true;
524}
525
526
527zlib_result = inflate(&zstream, Z_FINISH);
528
529DBG("Inflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, full_size);
530
531//int times =
532replace_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 executable
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: 1174