Chameleon

Chameleon Svn Source Tree

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

Source at commit 738 created 13 years 2 months ago.
By meklort, Kext Patcher cleanup.
1/*
2 * Copyright (c) 2010 Evan Lojewski. All rights reserved.
3 *
4 *KextPather
5 *The main purpose of this moduleis to replace the need for programs such as
6 * NetbookInstaller's kext patching routines. This way, Apple's kexts can be
7 * patched whe loaded instead. (eg: GMA950 kext, Bluetooth + Wifi kexts)
8 */
9#ifndef DEBUG_KEXT_PATCHER
10#define DEBUG_KEXT_PATCHER 0
11#endif
12
13#if DEBUG_KEXT_PATCHER
14#define DBG(x...)printf(x)
15#else
16#define DBG(x...)
17#endif
18
19
20#include "libsaio.h"
21#include "zlib.h"
22#include "kext_patcher.h"
23#include "boot.h"
24#include "bootstruct.h"
25#include "pci.h"
26#include "drivers.h"
27#include "mkext.h"
28#include "modules.h"
29#include "hex_editor.h"
30
31
32uint16_t patch_gma_deviceid = 0;
33uint16_t patch_bcm_deviceid = 0;
34uint16_t patch_atheros_deviceid = 0;
35uint16_t patch_hda_codec = 0x00;// TODO; detect proper codec
36
37
38/*
39 * Space allocation and freeing routines for use by zlib routines.
40 */
41void *
42z_alloc(void * notused __unused, u_int num_items, u_int size)
43{
44 void * result = NULL;
45 z_mem * zmem = NULL;
46 uint32_t total = num_items * size;
47 uint32_t allocSize = total + sizeof(zmem);
48
49 zmem = (z_mem *)malloc(allocSize);
50 if (!zmem) {
51 goto finish;
52 }
53 zmem->alloc_size = allocSize;
54 result = (void *)&(zmem->data);
55finish:
56 return result;
57}
58
59void
60z_free(void * notused __unused, void * ptr)
61{
62 uint32_t * skipper = (uint32_t *)ptr - 1;
63 z_mem * zmem = (z_mem *)skipper;
64 free((void *)zmem);
65 return;
66}
67
68
69
70
71/**
72 ** KextPatcher_start -> module start
73 **Notified the module system that this module will hook into the
74 **LoadMatchedModules and LoadDriverMKext functions
75 **/
76void KextPatcher_start()
77{
78// Hooks into the following:
79//execute_hook("LoadDriverMKext", (void*)package, (void*) length, NULL, NULL);
80// execute_hook("LoadMatchedModules", module, &length, executableAddr, NULL);
81
82register_hook_callback("PCIDevice", &KextPatcher_hook);
83//register_hook_callback("LoadMatchedModules", &kext_loaded);
84register_hook_callback("LoadDriverMKext", &mkext_loaded);
85
86}
87
88
89/**
90 ** kext_loaded -> Called whenever a kext is read into memory
91 **This function will be used to patch kexts ( eg AppleInteIntegratedFramebuffer)
92 **and their plists when they are loaded into memmory
93 **/
94void kext_loaded(void* moduletmp, void* lengthprt, void* executableAddr, void* arg3)
95{
96//ModulePtr module = moduletmp;
97//long length = *(long*)lengthprt;
98//long length2 = strlen(module->plistAddr);
99// *(long*)lengthprt = length2 + 5 * 1024 * 1024;
100
101//printf("Loading %s, lenght is %d, executable is 0x%X\n", module->plistAddr, length, executableAddr);
102//getc();
103}
104
105
106/**
107 ** mkext_loaded -> Called whenever an mkext is in read into memory
108 **This function will be used to patch mkext. Matching kexts will be
109 **Extracted, modified, and then compressed again. Note: I need to determine
110 **what sort of slowdown this will cause and if it's worth implimenting.
111 **/
112void mkext_loaded(void* filespec, void* packagetmp, void* lengthtmp, void* arg3)
113{
114const char* hda_codec= 0;
115int len= 0;
116mkext_basic_header* package = packagetmp;
117int version= MKEXT_GET_VERSION(package);
118
119if (getValueForKey(kHDACodec, &hda_codec, &len, &bootInfo->bootConfig))
120{
121patch_hda_codec = 0;
122int index = 0;
123while(len--)
124{
125patch_hda_codec <<= 4;
126patch_hda_codec |= chartohex(hda_codec[index]);
127index++;
128}
129}
130
131if(!NEEDS_PATCHING) return;// No need to apply a patch, hardware doesn't need it
132
133
134
135// Verify the MKext.
136 if (( MKEXT_GET_MAGIC(package)!= MKEXT_MAGIC ) ||
137 ( MKEXT_GET_SIGNATURE(package)!= MKEXT_SIGN ) ||
138 ( MKEXT_GET_LENGTH(package)> kLoadSize ) ||
139 ( MKEXT_GET_CHECKSUM(package) !=
140 Adler32((unsigned char *)&package->version, MKEXT_GET_LENGTH(package) - 0x10) ) )
141 {
142 return; // Don't try to patch a bad mkext
143 }
144
145
146if(version == 0x01008000) // mkext1
147{
148// mkext1 uses lzss
149mkext1_header* package = packagetmp;
150int i;
151for(i = 0; i < MKEXT_GET_COUNT(package); i++)
152{
153DBG("Parsing kext %d\n", i);
154//mkext_kext* kext = MKEXT1_GET_KEXT(package, i);
155// uses decompress_lzss
156// TODO: handle kext
157}
158}
159else if((version & 0xFFFF0000) == 0x02000000) // mkext2
160{
161DBG("Mkext2 package located at 0x%X\n", package);
162
163// mkext2 uses zlib
164mkext2_header*package = packagetmp;
165z_streamzstream;
166boolzstream_inited = false;
167intzlib_result;
168intplist_offset = MKEXT2_GET_PLIST(package);
169
170char* plist = malloc(MKEXT2_GET_PLIST_FULLSIZE(package));
171
172bzero(&zstream, sizeof(zstream));
173zstream.next_in = (UInt8*)((char*)package + plist_offset);
174zstream.avail_in = MKEXT2_GET_PLIST_COMPSIZE(package);
175
176zstream.next_out = (UInt8*)plist;
177zstream.avail_out = MKEXT2_GET_PLIST_FULLSIZE(package);
178
179zstream.zalloc = z_alloc;
180zstream.zfree = z_free;
181
182zlib_result = inflateInit(&zstream);
183if (Z_OK != zlib_result)
184{
185printf("ZLIB Error: %s\n", zstream.msg);
186getc();
187}
188else
189{
190zstream_inited = true;
191}
192
193
194zlib_result = inflate(&zstream, Z_FINISH);
195if (zstream_inited) inflateEnd(&zstream);
196
197DBG("Inflated result is %d, in: %d bytes, out: %d bytes\n", zlib_result, zstream.total_in, zstream.total_out);
198if (zlib_result == Z_STREAM_END || zlib_result == Z_OK)
199{
200TagPtr plistData;
201TagPtr allDicts;
202bzero(&plistData, sizeof(plistData));
203bzero(&allDicts, sizeof(allDicts));
204
205XMLParseFile( plist, &plistData );
206
207int count;
208
209allDicts = XMLGetProperty(plistData, kMKEXTInfoDictionariesKey);
210
211bool patched = false;
212for(count = XMLTagCount(allDicts);
213count > 0;
214count--)
215{
216TagPtr kextEntry = XMLGetElement(allDicts, count);
217patched |= patch_kext(kextEntry, plist, package);
218}
219
220
221if(patched)
222{
223zstream_inited = false;
224// Recompress the plist
225bzero(&zstream, sizeof(zstream));
226zstream.next_in = (UInt8*)plist;
227zstream.next_out = (UInt8*)package + plist_offset;
228zstream.avail_in = MKEXT2_GET_PLIST_FULLSIZE(package);
229zstream.avail_out = MKEXT2_GET_PLIST_FULLSIZE(package)<<2;// Give us some extra free space, just in case
230zstream.zalloc = Z_NULL;
231zstream.zfree = Z_NULL;
232zstream.opaque = Z_NULL;
233
234
235zlib_result = deflateInit2(&zstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,15, 8 /* memLevel */, Z_DEFAULT_STRATEGY);
236if (Z_OK != zlib_result) {
237printf("ZLIB Deflate Error: %s\n", zstream.msg);
238getc();
239}
240else
241{
242zstream_inited = true;
243}
244
245zlib_result = deflate(&zstream, Z_FINISH);
246
247if (zlib_result == Z_STREAM_END)
248{
249DBG("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));
250}
251else if (zlib_result == Z_OK)
252{
253/* deflate filled output buffer, meaning the data doesn't compress.
254 */
255DBG("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));
256
257}
258else if (zlib_result != Z_STREAM_ERROR)
259{
260printf("ZLIB Deflate Error: %s\n", zstream.msg);
261getc();
262}
263
264if(zstream.total_out != MKEXT2_GET_PLIST_COMPSIZE(package))
265{
266// Update the mkext length
267MKEXT2_HDR_CAST(package)->length = MKEXT_SWAP(MKEXT_GET_LENGTH(package) - MKEXT2_GET_PLIST_COMPSIZE(package) + zstream.total_out);
268MKEXT2_HDR_CAST(package)->plist_compressed_size = MKEXT_SWAP(zstream.total_out);
269*((int*)lengthtmp) -= MKEXT2_GET_PLIST_COMPSIZE(package);
270*((int*)lengthtmp) += zstream.total_out;
271}
272
273if (zstream_inited) deflateEnd(&zstream);
274
275
276
277// re adler32 the new mkext2 package
278MKEXT_HDR_CAST(package)->adler32 = MKEXT_SWAP(Adler32((unsigned char *)&package->version,
279 MKEXT_GET_LENGTH(package) - 0x10));
280}
281}
282else
283{
284printf("ZLIB Error: %s\n", zstream.msg);
285getc();
286}
287}
288}
289
290// FIXME: only handles mkext2 entries
291bool patch_kext(TagPtr plist, char* plistbuffer, void* start)
292{
293char* bundleID;
294
295if(XMLGetProperty(plist, kMKEXTExecutableKey) == NULL) return false;// Kext is a plist only kext, don't patch
296
297bundleID = XMLCastString(XMLGetProperty(plist, kPropCFBundleIdentifier));
298
299
300if(patch_gma_deviceid &&
301 ((strcmp(bundleID, "com.apple.driver.AppleIntelGMA950") == 0) ||
302 (strcmp(bundleID, "com.apple.driver.AppleIntelIntegratedFramebuffer") == 0)))
303{
304return patch_gma_kexts(plist, plistbuffer, start);
305}
306else if(patch_bcm_deviceid && (strcmp(bundleID, "com.apple.driver.AirPortBrcm43xx") == 0))
307{
308return patch_bcm_kext(plist, plistbuffer, start);
309}
310else if(patch_hda_codec && strcmp(bundleID, "com.apple.driver.AppleHDA") == 0)
311{
312return patch_hda_kext(plist, plistbuffer, start);
313}
314else if(patch_hda_codec && strcmp(bundleID, "com.apple.driver.AppleHDAController") == 0)
315{
316return patch_hda_controller(plist, plistbuffer, start);
317}
318else if(patch_atheros_deviceid && strcmp(bundleID, "com.apple.driver.AirPort.Atheros21") == 0)
319{
320return patch_atheros_kext(plist, plistbuffer, start);
321}
322
323return false;
324}
325
326void KextPatcher_hook(void* arg1, void* arg2, void* arg3, void* arg4)
327{
328pci_dt_t* current = arg1;
329if(current)
330{
331switch(current->class_id)
332{
333case PCI_CLASS_DISPLAY_VGA:
334if(current->vendor_id == 0x8086 &&
335 (
336current->device_id == 0x27AE ||
337current->device_id == 0xA001 ||
338current->device_id == 0xA002 ||
339current->device_id == 0xA011 ||
340current->device_id == 0xA012
341
342)
343 )
344{
345patch_gma_deviceid = current->device_id;
346}
347break;
348
349case PCI_CLASS_NETWORK_OTHER:
350
351// Patch BCM43xx
352if(current->vendor_id == 0x14E4 && ((current->device_id & 0xFFD0) == 0x4300))
353{
354patch_bcm_deviceid = current->device_id;
355}
356else if(current->vendor_id == 0x168C && current->device_id == 0x002B)
357{
358patch_atheros_deviceid = current->device_id;
359}
360break;
361}
362}
363}
364
365
366bool patch_hda_controller(TagPtr plist, char* plistbuffer, void* start)
367{
368return false;
369// change the PCI class code to match to. Note: A LegacyHDA plist should do this on it's own
370// As such, it's disabled
371
372// TODO: read class code
373TagPtr personality;
374personality =XMLCastDict(XMLGetProperty(plist, kPropIOKitPersonalities));
375personality =XMLGetProperty(personality, (const char*)"BuiltInHDA");
376TagPtr match_class =XMLCastArray(XMLGetProperty(personality, (const char*)"IOPCIClassMatch"));
377
378
379char* new_str = malloc(sizeof("0xXXXX000&0xFFFE0000"));
380sprintf(new_str, "0x04030000&amp;0xFFFE0000"); // todo, pass in actual class id
381
382
383char* orig_string = "0x04020000&amp;0xFFFE0000"; //XMLCastString(match_class);
384
385printf("Attemting to replace '%s' with '%s'\n", orig_string, new_str);
386
387// TODO: verify string doesn't exist first.
388
389replace_string(orig_string, new_str, plistbuffer + XMLCastStringOffset(match_class), 1024);
390
391return true;
392
393}
394
395
396bool patch_hda_kext(TagPtr plist, char* plistbuffer, void* start)
397{
398uint16_t find_codec= 0;
399int full_size, compressed_size, executable_offset;
400void* compressed_data;
401mkext2_file_entry* kext;
402int zlib_result;
403z_stream zstream;
404bool zstream_inited = false;
405
406switch(patch_hda_codec & 0xFF00)
407{
408case 0x0200:
409find_codec = 0x0262;
410break;
411
412case 0x0800:
413find_codec = 0x0885;
414break;
415
416case 0x0600:// specificaly the 662
417find_codec = 0x0885;
418break;
419}
420if(!find_codec) return false;// notify caller that we aren't patching the kext
421
422executable_offset= XMLCastInteger(XMLGetProperty(plist, kMKEXTExecutableKey));
423kext= (void*)((char*)start + executable_offset);
424full_size= MKEXT2_GET_ENTRY_FULLSIZE(kext);
425compressed_size= MKEXT2_GET_ENTRY_COMPSIZE(kext);
426compressed_data= MKEXT2_GET_ENTRY_DATA(kext);
427executable_offset= XMLCastInteger(XMLGetProperty(plist, kMKEXTExecutableKey));
428
429
430char* executable = malloc(full_size);
431
432bzero(&zstream, sizeof(zstream));
433zstream.next_in = (UInt8*)compressed_data;
434zstream.avail_in = compressed_size;
435
436zstream.next_out = (UInt8*)executable;
437zstream.avail_out = full_size;
438
439zstream.zalloc = z_alloc;
440zstream.zfree = z_free;
441
442zlib_result = inflateInit(&zstream);
443if (Z_OK != zlib_result)
444{
445printf("ZLIB Inflate Error: %s\n", zstream.msg);
446getc();
447}
448else
449{
450zstream_inited = true;
451}
452
453
454zlib_result = inflate(&zstream, Z_FINISH);
455
456DBG("Inflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, full_size);
457
458/*int times = */replace_word(0x10EC0000 | (find_codec), 0x10EC0000 | (patch_hda_codec), executable, zstream.total_out);
459if (zstream_inited) inflateEnd(&zstream);
460
461
462zstream.next_in = (UInt8*)executable;
463zstream.next_out = (UInt8*)compressed_data;
464
465zstream.avail_in = full_size;
466zstream.avail_out = compressed_size<<1;
467zstream.zalloc = Z_NULL;
468zstream.zfree = Z_NULL;
469zstream.opaque = Z_NULL;
470
471
472
473// Recompress the eecutable
474zlib_result = deflateInit2(&zstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,15, 8 /* memLevel */, Z_DEFAULT_STRATEGY);
475if (Z_OK != zlib_result) {
476printf("ZLIB Deflate Error: %s\n", zstream.msg);
477getc();
478}
479else
480{
481zstream_inited = true;
482}
483
484zlib_result = deflate(&zstream, Z_FINISH);
485
486if (zlib_result == Z_STREAM_END)
487{
488DBG("Deflated result is %d, avail: %d bytes, out: %d bytes, full: %d\n", zlib_result, compressed_size, zstream.total_out, full_size);
489}
490else if (zlib_result == Z_OK)
491{
492/* deflate filled output buffer, meaning the data doesn't compress.
493 */
494DBG("Buffer FULL: deflated result is %d, avail: %d bytes, out: %d bytes, full: %d\n", zlib_result, compressed_size, zstream.total_out, full_size);
495printf("Unable to patch AppleHDA\n");
496
497}
498else if (zlib_result != Z_STREAM_ERROR)
499{
500printf("AppleHDA: ZLIB Deflate Error: %s\n", zstream.msg);
501getc();
502}
503
504if (zstream_inited) deflateEnd(&zstream);
505
506if(zstream.total_out < compressed_size) kext->compressed_size = MKEXT_SWAP(zstream.total_out);
507
508
509free(executable);
510
511return true;
512
513}
514
515
516/** Patches an array element within a personality. NOTE: string sizes should match **/
517bool patch_plist_entry(TagPtr plist, char* plistbuffer, const char* personalityName, const char* propertyName, const char* nameMatch)
518{
519TagPtr personality= XMLGetProperty(XMLCastDict(XMLGetProperty(plist, kPropIOKitPersonalities)), personalityName);
520TagPtr match_names= XMLCastArray(XMLGetProperty(personality, propertyName));
521TagPtr replace= XMLGetElement(match_names, 0);// Modify the first entry
522int count= XMLTagCount(match_names);
523
524while(count)
525{
526char* orig_string= XMLCastString(XMLGetElement(match_names, --count));
527if(strcmp(orig_string, nameMatch) == 0) return false;// Entry already exists, no need tmo modify plist + recompress
528}
529
530char* orig_string= XMLCastString(replace);
531verbose("Patching %s, replacing %s with %s\n", personalityName, orig_string, nameMatch);
532replace_string(orig_string, new_str, plistbuffer + XMLCastStringOffset(replace), 10240);
533
534}
535
536bool patch_bcm_kext(TagPtr plist, char* plistbuffer, void* start)
537{
538char* new_str= malloc(sizeof("pci14e4,xxxx"));
539sprintf(new_str, "pci14e4,%02x", patch_bcm_deviceid);
540return patch_plist_entry(plist, plistbuffer, "Broadcom 802.11 PCI", "IONameMatch", new_str);
541}
542
543bool patch_atheros_kext(TagPtr plist, char* plistbuffer, void* start)
544{
545char* new_str= malloc(sizeof("pci14e4,xxxx"));
546sprintf(new_str, "pci168c,%02x", patch_atheros_deviceid);
547return patch_plist_entry(plist, plistbuffer, "Atheros Wireless LAN PCI", "IONameMatch", new_str);
548}
549
550bool patch_gma_kexts(TagPtr plist, char* plistbuffer, void* start)
551{
552TagPtr personality= XMLCastDict(XMLGetProperty(plist, kPropIOKitPersonalities));
553int exeutable_offset= XMLCastInteger(XMLGetProperty(plist, kMKEXTExecutableKey));
554mkext2_file_entry* kext= (void*)((char*)start + exeutable_offset);
555int full_size= MKEXT2_GET_ENTRY_FULLSIZE(kext);
556int compressed_size= MKEXT2_GET_ENTRY_COMPSIZE(kext);
557void* compressed_data= MKEXT2_GET_ENTRY_DATA(kext);
558char* executable= malloc(full_size);
559int zlib_result= Z_OK;
560long offset;
561z_stream zstream;
562
563bzero(&zstream, sizeof(zstream));
564zstream.next_in = (UInt8*)compressed_data;
565zstream.avail_in = compressed_size;
566
567zstream.next_out = (UInt8*)executable;
568zstream.avail_out = full_size;
569
570zstream.zalloc = z_alloc;
571zstream.zfree = z_free;
572
573zlib_result = inflateInit(&zstream);
574if (Z_OK != zlib_result)
575{
576printf("ZLIB Inflate Error: %s\n", zstream.msg);
577getc();
578}
579else
580{
581zlib_result = inflate(&zstream, Z_FINISH);
582
583DBG("Inflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, full_size);
584
585char* newstring = malloc(sizeof("0x00008086"));
586sprintf(newstring, "0x%04x", 0x8086 | (patch_gma_deviceid << 16));
587
588
589if(XMLGetProperty(personality, (const char*)"Intel915"))
590{
591if((patch_gma_deviceid & 0xFF00) != 0xA000)// not GMA3150
592{
593verbose("Patching AppleIntelGMA950.kext\n");
594personality =XMLGetProperty(personality, (const char*)"Intel915"); // IOAccelerator kext
595offset =XMLCastStringOffset(XMLGetProperty(personality, (const char*)"IOPCIPrimaryMatch"));
596
597replace_string("0x27A28086", newstring, plistbuffer + offset, 10240);
598replace_word(0x27A28086, 0x8086 | (patch_gma_deviceid << 16), executable, zstream.total_out);
599}
600}
601else if(XMLGetProperty(personality, (const char*)"AppleIntelIntegratedFramebuffer"))
602{
603verbose("Patching AppleIntelIntegratedFramebuffer\n");
604personality =XMLGetProperty(personality, (const char*)"AppleIntelIntegratedFramebuffer");
605offset =XMLCastStringOffset(XMLGetProperty(personality, (const char*)"IOPCIPrimaryMatch"));
606
607if((patch_gma_deviceid & 0xFF00) == 0xA000)// GMA3150
608{
609// Cursor corruption fix.
610// This patch changes the cursor address from
611// a physical address (used in the gma950) to an offset (used in the gma3150).
612//{0x8b, 0x55, 0x08, 0x83, 0xba, 0xb0, 0x00, 0x00, 0x00, 0x01, 0x7e, 0x36, 0x89, 0x04, 0x24, 0xe8, 0x6b, 0xbc, 0xff, 0xff};
613char 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
614char 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, set to 0 for compression
615replace_bytes(find_bytes, sizeof(find_bytes), new_bytes, sizeof(new_bytes), executable, zstream.total_out);
616}
617replace_string("0x27A28086", newstring, plistbuffer + offset, 10240);
618replace_word(0x27A28086, 0x8086 | (patch_gma_deviceid << 16), executable, zstream.total_out);
619
620}
621else if(XMLGetProperty(personality, (const char*)"Intel965"))
622{
623verbose("Patching AppleIntelGMAX3100.kext\n");
624personality =XMLGetProperty(personality, (const char*)"Intel965");
625offset =XMLCastStringOffset(XMLGetProperty(personality, (const char*)"IOPCIPrimaryMatch"));
626
627replace_string("0x2a028086", newstring, plistbuffer + offset, 10240);
628}
629else if(XMLGetProperty(personality, (const char*)"AppleIntelGMAX3100FB"))
630{
631verbose("Patching AppleIntelGMAX3100FB.kext\n");
632personality =XMLGetProperty(personality, (const char*)"AppleIntelGMAX3100FB");
633
634offset =XMLCastStringOffset(XMLGetProperty(personality, (const char*)"IOPCIPrimaryMatch"));
635replace_string("0x2A028086", newstring, plistbuffer + offset, 10240);
636replace_word(0x2A028086, 0x8086 | (patch_gma_deviceid << 16), executable, zstream.total_out);
637}
638else
639{
640return false;
641}
642
643
644inflateEnd(&zstream);
645
646// Recompress the executable
647zstream.next_in = (UInt8*)executable;
648zstream.next_out = (UInt8*)compressed_data;
649
650zstream.avail_in = full_size;
651zstream.avail_out = compressed_size;
652zstream.zalloc = Z_NULL;
653zstream.zfree = Z_NULL;
654zstream.opaque = Z_NULL;
655
656zlib_result = deflateInit2(&zstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,15, 8 /* memLevel */, Z_DEFAULT_STRATEGY);
657if (Z_OK != zlib_result) {
658printf("ZLIB Deflate Error: %s\n", zstream.msg);
659getc();
660}
661else
662{
663zlib_result = deflate(&zstream, Z_FINISH);
664
665if (zlib_result == Z_STREAM_END)
666{
667DBG("Deflated result is %d, avail: %d bytes, out: %d bytes, full: %d\n", zlib_result, compressed_size, zstream.total_out, full_size);
668}
669else if (zlib_result == Z_OK)
670{
671/* deflate filled output buffer, meaning the data doesn't compress.
672 */
673printf("Deflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, full_size);
674printf("ERROR: Unable to compress patched kext, not enough room.\n");
675pause();
676
677}
678else if (zlib_result != Z_STREAM_ERROR)
679{
680printf("ZLIB Deflate Error: %s\n", zstream.msg);
681getc();
682}
683if(zstream.total_out < compressed_size) kext->compressed_size = MKEXT_SWAP(zstream.total_out);
684
685
686deflateEnd(&zstream);
687}
688}
689
690free(executable);
691
692return true;
693}
694
695int chartohex(char c)
696{
697if(c <= '9' && c >= '0')return c - '0';// c is between 0 and 9
698else if(c <= 'F' && c >= 'A')return c - 'A' + 10; // c = 10 - 15;
699else if(c <= 'f' && c >= 'a')return c - 'a' + 10; // c = 10 - 15;
700
701return 0;
702}

Archive Download this file

Revision: 738