Chameleon

Chameleon Svn Source Tree

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

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

Archive Download this file

Revision: 647