Chameleon

Chameleon Svn Source Tree

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

Source at commit 628 created 13 years 5 months ago.
By meklort, Kext patcher update. Supports patching the GMA950 FB kext for use on the GMA3150, only tested on 10.6.5
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// TODO: add detection code / a method for users to enter the id
51uint16_t patch_hda_codec = 0;
52
53#define NEEDS_PATCHING(patch_bcm_deviceid || patch_gma_deviceid || patch_hda_codec)
54
55typedef struct z_mem {
56 uint32_t alloc_size;
57 uint8_t data[0];
58} z_mem;
59
60/*
61 * Space allocation and freeing routines for use by zlib routines.
62 */
63void *
64z_alloc(void * notused __unused, u_int num_items, u_int size)
65{
66 void * result = NULL;
67 z_mem * zmem = NULL;
68 uint32_t total = num_items * size;
69 uint32_t allocSize = total + sizeof(zmem);
70
71 zmem = (z_mem *)malloc(allocSize);
72 if (!zmem) {
73 goto finish;
74 }
75 zmem->alloc_size = allocSize;
76 result = (void *)&(zmem->data);
77finish:
78 return result;
79}
80
81void
82z_free(void * notused __unused, void * ptr)
83{
84 uint32_t * skipper = (uint32_t *)ptr - 1;
85 z_mem * zmem = (z_mem *)skipper;
86 free((void *)zmem);
87 return;
88}
89
90
91unsigned long Mkext_Alder32( unsigned char * buffer, long length );
92
93void KextPatcher_hook(void* current, void* arg2, void* arg3, void* arg4);
94
95/**
96 ** KextPatcher_start -> module start
97 **Notified the module system that this module will hook into the
98 **LoadMatchedModules and LoadDriverMKext functions
99 **/
100void KextPatcher_start()
101{
102// Hooks into the following:
103//execute_hook("LoadDriverMKext", (void*)package, (void*) length, NULL, NULL);
104// execute_hook("LoadMatchedModules", module, &length, executableAddr, NULL);
105
106register_hook_callback("PCIDevice", &KextPatcher_hook);
107//register_hook_callback("LoadMatchedModules", &kext_loaded);
108register_hook_callback("LoadDriverMKext", &mkext_loaded);
109
110}
111
112/**
113 ** kext_loaded -> Called whenever a kext is in read into memory
114 **This function will be used to patch kexts ( eg AppleInteIntegratedFramebuffer)
115 **and their plists when they are loaded into memmory
116 **/
117void kext_loaded(void* moduletmp, void* lengthprt, void* executableAddr, void* arg3)
118{
119
120//ModulePtr module = moduletmp;
121//long length = *(long*)lengthprt;
122//long length2 = strlen(module->plistAddr);
123// *(long*)lengthprt = length2 + 5 * 1024 * 1024;
124
125//printf("Loading %s, lenght is %d, executable is 0x%X\n", module->plistAddr, length, executableAddr);
126//getc();
127}
128
129/**
130 ** mkext_loaded -> Called whenever an mkext is in read into memory
131 **This function will be used to patch mkext. Matching kexts will be
132 **Extracted, modified, and then compressed again. Note: I need to determine
133 **what sort of slowdown this will cause and if it's worth implimenting.
134 **/
135
136void mkext_loaded(void* filespec, void* packagetmp, void* lengthtmp, void* arg3)
137{
138const char* hda_codec;
139int len = 0;
140
141if (getValueForKey(kHDACodec, &hda_codec, &len, &bootInfo->bootConfig))
142{
143int index = 0;
144while(len)
145{
146patch_hda_codec <<= 4;
147patch_hda_codec |= chartohex(hda_codec[index]);
148len--;
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
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{
386//return 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
454DBG("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), 10240);
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(0xFF00 & patch_hda_codec)
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}
489
490if(!find_codec) return false;// notify caller that we aren't patching the kext
491
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
530replace_word(0x10EC | (find_codec << 16), 0xE10EC | (patch_hda_codec << 16), executable, zstream.total_out);
531
532if (zstream_inited) inflateEnd(&zstream);
533
534
535zstream.next_in = (UInt8*)executable;
536zstream.next_out = (UInt8*)compressed_data;
537
538zstream.avail_in = full_size;
539zstream.avail_out = compressed_size;
540zstream.zalloc = Z_NULL;
541zstream.zfree = Z_NULL;
542zstream.opaque = Z_NULL;
543
544
545
546// Recompress the eecutable
547zlib_result = deflateInit2(&zstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,15, 8 /* memLevel */, Z_DEFAULT_STRATEGY);
548if (Z_OK != zlib_result) {
549printf("ZLIB Deflate Error: %s\n", zstream.msg);
550getc();
551}
552else
553{
554zstream_inited = true;
555}
556
557zlib_result = deflate(&zstream, Z_FINISH);
558
559if (zlib_result == Z_STREAM_END)
560{
561DBG("Deflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, full_size);
562}
563else if (zlib_result == Z_OK)
564{
565/* deflate filled output buffer, meaning the data doesn't compress.
566 */
567DBG("Deflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, full_size);
568
569}
570else if (zlib_result != Z_STREAM_ERROR)
571{
572printf("ZLIB Deflate Error: %s\n", zstream.msg);
573getc();
574}
575
576if (zstream_inited) deflateEnd(&zstream);
577
578free(executable);
579
580return true;
581
582}
583
584bool patch_bcm_kext(TagPtr plist, char* plistbuffer, void* start)
585{
586TagPtr personality;
587personality =XMLCastDict(XMLGetProperty(plist, kPropIOKitPersonalities));
588personality =XMLGetProperty(personality, (const char*)"Broadcom 802.11 PCI");
589TagPtr match_names =XMLCastArray(XMLGetProperty(personality, (const char*)"IONameMatch"));
590
591
592char* new_str = malloc(strlen("pci14e4,xxxx")+1);
593sprintf(new_str, "pci14e4,%02x", patch_bcm_deviceid);
594
595// Check to see if we *really* need to modify the plist, if not, return false
596// so that *if* this were going ot be the only modified kext, the repacking code
597// won't need to be executed.
598int count = XMLTagCount(match_names);
599while(count)
600{
601count--;
602TagPtr replace =XMLGetElement(match_names, count);// Modify the second entry
603char* orig_string = XMLCastString(replace);
604if(strcmp(orig_string, new_str) == 0) return false;
605}
606
607
608TagPtr replace =XMLGetElement(match_names, 1);// Modify the second entry
609char* orig_string = XMLCastString(replace);
610
611
612// TODO: verify string doesn't exist first.
613
614replace_string(orig_string, new_str, plistbuffer + XMLCastStringOffset(replace), 10240);
615
616return true;
617}
618
619bool patch_gma_kexts(TagPtr plist, char* plistbuffer, void* start)
620{
621int exeutable_offset, full_size, compressed_size;
622TagPtr personality;
623long offset;
624int zlib_result;
625z_stream zstream;
626bool zstream_inited = false;
627mkext2_file_entry* kext;
628void* compressed_data;
629
630exeutable_offset = XMLCastInteger(XMLGetProperty(plist, kMKEXTExecutableKey));
631kext = (void*)((char*)start + exeutable_offset);
632
633full_size = MKEXT2_GET_ENTRY_FULLSIZE(kext);
634compressed_size = MKEXT2_GET_ENTRY_COMPSIZE(kext);
635compressed_data = MKEXT2_GET_ENTRY_DATA(kext);
636
637personality =XMLCastDict(XMLGetProperty(plist, kPropIOKitPersonalities));
638if(XMLGetProperty(personality, (const char*)"Intel915"))
639{
640personality =XMLGetProperty(personality, (const char*)"Intel915");
641}
642else
643{
644personality =XMLGetProperty(personality, (const char*)"AppleIntelIntegratedFramebuffer");
645}
646#if DEBUG_KEXT_PATCHER
647char* pcimatch =XMLCastString(XMLGetProperty(personality, (const char*)"IOPCIPrimaryMatch"));
648#endif
649offset =XMLCastStringOffset(XMLGetProperty(personality, (const char*)"IOPCIPrimaryMatch"));
650
651char* newstring = malloc(strlen("0x27A28086") + 1);
652sprintf(newstring, "0x%04x", 0x8086 | (patch_gma_deviceid << 16));
653
654DBG("Replacing %s with %s\n", "0x27A28086", newstring);
655replace_string("0x27A28086", newstring, plistbuffer + offset, 10240);
656
657char* executable = malloc(full_size);
658
659bzero(&zstream, sizeof(zstream));
660zstream.next_in = (UInt8*)compressed_data;
661zstream.avail_in = compressed_size;
662
663zstream.next_out = (UInt8*)executable;
664zstream.avail_out = full_size;
665
666zstream.zalloc = z_alloc;
667zstream.zfree = z_free;
668
669zlib_result = inflateInit(&zstream);
670if (Z_OK != zlib_result)
671{
672printf("ZLIB Inflate Error: %s\n", zstream.msg);
673getc();
674}
675else
676{
677zstream_inited = true;
678}
679
680
681zlib_result = inflate(&zstream, Z_FINISH);
682
683printf("Inflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, full_size);
684
685replace_word(0x27A28086, 0x8086 | (patch_gma_deviceid << 16), executable, zstream.total_out);
686
687
688if(patch_gma_deviceid & 0xFF00 == 0xA000)// GMA3150
689{
690// Cursor corruption fix.
691// This patch changes the cursor address from
692// a physical address (used in the gma950) to an offset (used in the gma3150).
693
694char 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
695char new_bytes[] = {0xb8, 0x00, 0x00, 0x00, 0x02, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0xEB, 0x04, 0x00, 0x00, 0x00, 0x00};// jump past getPhysicalAddress binding. NOTE: last six bytes are unusable
696replace_bytes(find_bytes, sizeof(find_bytes), new_bytes, sizeof(new_bytes), executable, zstream.total_out);
697}
698
699if (zstream_inited) inflateEnd(&zstream);
700
701
702zstream.next_in = (UInt8*)executable;
703zstream.next_out = (UInt8*)compressed_data;
704
705zstream.avail_in = full_size;
706zstream.avail_out = compressed_size;
707zstream.zalloc = Z_NULL;
708zstream.zfree = Z_NULL;
709zstream.opaque = Z_NULL;
710
711
712
713// Recompress the eecutable
714zlib_result = deflateInit2(&zstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,15, 8 /* memLevel */, Z_DEFAULT_STRATEGY);
715if (Z_OK != zlib_result) {
716printf("ZLIB Deflate Error: %s\n", zstream.msg);
717getc();
718}
719else
720{
721zstream_inited = true;
722}
723
724zlib_result = deflate(&zstream, Z_FINISH);
725
726if (zlib_result == Z_STREAM_END)
727{
728DBG("Deflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, full_size);
729}
730else if (zlib_result == Z_OK)
731{
732/* deflate filled output buffer, meaning the data doesn't compress.
733 */
734printf("Deflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, full_size);
735prinff("ERROR: Unable to compress patched kext, not enough room.\n");
736pause();
737
738}
739else if (zlib_result != Z_STREAM_ERROR)
740{
741printf("ZLIB Deflate Error: %s\n", zstream.msg);
742getc();
743}
744//kext->compressed_size = MKEXT_SWAP(zstream.total_out);
745
746
747
748
749if (zstream_inited) deflateEnd(&zstream);
750
751free(executable);
752
753return true;
754}
755
756int chartohex(char c)
757{
758if(c <= '9' && c >= '0')
759{
760return c - '0';// c is between 0 and 9
761}
762else if(c <= 'F' && c >= 'A')
763{
764return c - 'A' + 10; // c = 10 - 15;
765}
766else if(c <= 'f' && c >= 'a')
767{
768return c - 'a' + 10; // c = 10 - 15;
769}
770return 0;
771}

Archive Download this file

Revision: 628