Chameleon

Chameleon Svn Source Tree

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

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

Archive Download this file

Revision: 726