Root/
Source at commit 606 created 13 years 5 months ago. By meklort, Kext patcher update. Can now patch both the gma950 binary and plist in mem. Will add error detections and device id detection to determine if a patch is required | |
---|---|
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 "pci.h"␊ |
15 | #include "drivers.h"␊ |
16 | #include "mkext.h"␊ |
17 | #include "modules.h"␊ |
18 | #include "hex_editor.h"␊ |
19 | ␊ |
20 | ␊ |
21 | #ifndef DEBUG_KEXT_PATCHER␊ |
22 | #define DEBUG_KEXT_PATCHER 0␊ |
23 | #endif␊ |
24 | ␊ |
25 | #if DEBUG_KEXT_PATCHER␊ |
26 | #define DBG(x...)␉printf(x)␊ |
27 | #else␊ |
28 | #define DBG(x...)␊ |
29 | #endif␊ |
30 | bool patch_kext(TagPtr plist, char* plistbuffer, void* start);␊ |
31 | ␊ |
32 | static void * z_alloc(void *, u_int items, u_int size);␊ |
33 | static void z_free(void *, void *ptr);␊ |
34 | ␊ |
35 | typedef struct z_mem {␊ |
36 | uint32_t alloc_size;␊ |
37 | uint8_t data[0];␊ |
38 | } z_mem;␊ |
39 | ␊ |
40 | /*␊ |
41 | * Space allocation and freeing routines for use by zlib routines.␊ |
42 | */␊ |
43 | void *␊ |
44 | z_alloc(void * notused __unused, u_int num_items, u_int size)␊ |
45 | {␊ |
46 | void * result = NULL;␊ |
47 | z_mem * zmem = NULL;␊ |
48 | uint32_t total = num_items * size;␊ |
49 | uint32_t allocSize = total + sizeof(zmem);␊ |
50 | ␊ |
51 | zmem = (z_mem *)malloc(allocSize);␊ |
52 | if (!zmem) {␊ |
53 | goto finish;␊ |
54 | }␊ |
55 | zmem->alloc_size = allocSize;␊ |
56 | result = (void *)&(zmem->data);␊ |
57 | finish:␊ |
58 | return result;␊ |
59 | }␊ |
60 | ␊ |
61 | void␊ |
62 | z_free(void * notused __unused, void * ptr)␊ |
63 | {␊ |
64 | uint32_t * skipper = (uint32_t *)ptr - 1;␊ |
65 | z_mem * zmem = (z_mem *)skipper;␊ |
66 | free((void *)zmem);␊ |
67 | return;␊ |
68 | }␊ |
69 | ␊ |
70 | ␊ |
71 | unsigned long Mkext_Alder32( unsigned char * buffer, long length );␊ |
72 | ␊ |
73 | void KextPatcher_hook(void* current, void* arg2, void* arg3, void* arg4);␊ |
74 | ␊ |
75 | /**␊ |
76 | ** KextPatcher_start -> module start␊ |
77 | **␉␉Notified the module system that this module will hook into the ␊ |
78 | **␉␉LoadMatchedModules and LoadDriverMKext functions␊ |
79 | **/␊ |
80 | void KextPatcher_start()␊ |
81 | {␉␉␊ |
82 | ␉// Hooks into the following:␊ |
83 | ␉//␉execute_hook("LoadDriverMKext", (void*)package, (void*) length, NULL, NULL);␊ |
84 | ␉// execute_hook("LoadMatchedModules", module, &length, executableAddr, NULL);␊ |
85 | ␊ |
86 | ␉register_hook_callback("PCIDevice", &KextPatcher_hook);␊ |
87 | ␉//register_hook_callback("LoadMatchedModules", &kext_loaded); ␊ |
88 | ␉register_hook_callback("LoadDriverMKext", &mkext_loaded); ␊ |
89 | ␊ |
90 | }␊ |
91 | ␊ |
92 | /**␊ |
93 | ** kext_loaded -> Called whenever a kext is in read into memory␊ |
94 | **␉␉This function will be used to patch kexts ( eg AppleInteIntegratedFramebuffer)␊ |
95 | **␉␉and their plists when they are loaded into memmory␊ |
96 | **/␊ |
97 | void kext_loaded(void* moduletmp, void* lengthprt, void* executableAddr, void* arg3)␊ |
98 | {␊ |
99 | ␉␊ |
100 | ␉//ModulePtr module = moduletmp;␊ |
101 | ␉//long length = *(long*)lengthprt;␊ |
102 | ␉//long length2 = strlen(module->plistAddr);␊ |
103 | ␉// *(long*)lengthprt = length2 + 5 * 1024 * 1024;␊ |
104 | ␊ |
105 | ␉//printf("Loading %s, lenght is %d, executable is 0x%X\n", module->plistAddr, length, executableAddr);␊ |
106 | ␉//getc();␊ |
107 | }␊ |
108 | ␊ |
109 | /**␊ |
110 | ** mkext_loaded -> Called whenever an mkext is in read into memory␊ |
111 | **␉␉This function will be used to patch mkext. Matching kexts will be␊ |
112 | **␉␉Extracted, modified, and then compressed again. Note: I need to determine␊ |
113 | **␉␉what sort of slowdown this will cause and if it's worth implimenting.␊ |
114 | **/␊ |
115 | ␊ |
116 | void mkext_loaded(void* filespec, void* packagetmp, void* lengthtmp, void* arg3)␊ |
117 | {␊ |
118 | ␉int version = 0;␊ |
119 | ␉//int length = *((int*)lengthtmp);␊ |
120 | ␉mkext_basic_header* package = packagetmp;␊ |
121 | ␊ |
122 | ␉// Verify the MKext.␊ |
123 | if (( MKEXT_GET_MAGIC(package)␉␉!= MKEXT_MAGIC ) ||␊ |
124 | ( MKEXT_GET_SIGNATURE(package)␉!= MKEXT_SIGN ) ||␊ |
125 | ( MKEXT_GET_LENGTH(package)␉␉> kLoadSize )␉ ||␊ |
126 | ( MKEXT_GET_CHECKSUM(package) !=␊ |
127 | ␉␉ Mkext_Alder32((unsigned char *)&package->version, MKEXT_GET_LENGTH(package) - 0x10) ) )␊ |
128 | {␊ |
129 | return;␊ |
130 | ␉␉// Don't try to patch a b␊ |
131 | }␉␊ |
132 | ␉␊ |
133 | ␉/*␊ |
134 | ␉if(strcmp(filespec, "/System/Library/Caches/com.apple.kext.caches/Startup/Extensions.mkext") == 0)␊ |
135 | ␉{␊ |
136 | ␉␉printf("Invalidating mkext %s\n", filespec);␊ |
137 | ␉␉// 10.6 cache folder. Doesn't contain certain extensions we need, so invalidate it.␊ |
138 | ␉␉//package->adler32++;␊ |
139 | ␉␉// NOTE: double check that this is needed␊ |
140 | ␉␉package->magic = 0x00;␊ |
141 | ␉␉return;␊ |
142 | ␉}*/␊ |
143 | ␉␊ |
144 | ␉␊ |
145 | ␉version = MKEXT_GET_VERSION(package);␊ |
146 | ␉␊ |
147 | ␉if(version == 0x01008000) // mkext1␊ |
148 | ␉{␊ |
149 | ␉␉// mkext1 uses lzss␊ |
150 | ␉␉mkext1_header* package = packagetmp;␊ |
151 | ␉␉int i;␊ |
152 | ␉␉for(i = 0; i < MKEXT_GET_COUNT(package); i++)␊ |
153 | ␉␉{␊ |
154 | ␉␉␉DBG("Parsing kext %d\n", i);␊ |
155 | ␉␉␉//mkext_kext* kext = MKEXT1_GET_KEXT(package, i);␊ |
156 | ␉␉␉// uses decompress_lzss␊ |
157 | ␉␉␉// TODO: handle kext␊ |
158 | ␊ |
159 | ␉␉}␊ |
160 | ␉}␊ |
161 | ␉else if((version & 0xFFFF0000) == 0x02000000) // mkext2␊ |
162 | ␉{␊ |
163 | ␉␉DBG("Mkext2 package located at 0x%X\n", package);␊ |
164 | ␊ |
165 | ␉␉// mkext2 uses zlib␉␉␊ |
166 | ␉␉mkext2_header* package = packagetmp;␊ |
167 | ␉␉z_stream zstream;␊ |
168 | ␉␉bool zstream_inited = false;␊ |
169 | ␉␉int zlib_result;␊ |
170 | ␉␉int plist_offset = MKEXT2_GET_PLIST(package);␊ |
171 | ␉␉␊ |
172 | ␉␉char* plist = malloc(MKEXT2_GET_PLIST_FULLSIZE(package));␊ |
173 | ␉␉␊ |
174 | ␉␉bzero(&zstream, sizeof(zstream));␉␉␊ |
175 | ␉␉zstream.next_in = (UInt8*)((char*)package + plist_offset);␊ |
176 | ␉␉zstream.avail_in = MKEXT2_GET_PLIST_COMPSIZE(package);␊ |
177 | ␉␉␊ |
178 | ␉␉zstream.next_out = (UInt8*)plist;␊ |
179 | ␉␉zstream.avail_out = MKEXT2_GET_PLIST_FULLSIZE(package);␊ |
180 | ␉␉␊ |
181 | ␉␉zstream.zalloc = z_alloc;␊ |
182 | ␉␉zstream.zfree = z_free;␊ |
183 | ␉␉␉␉␊ |
184 | ␉␉zlib_result = inflateInit(&zstream);␊ |
185 | ␉␉if (Z_OK != zlib_result)␊ |
186 | ␉␉{␊ |
187 | ␉␉␉printf("ZLIB Error: %s\n", zstream.msg);␊ |
188 | ␉␉␉getc();␊ |
189 | ␉␉}␊ |
190 | ␉␉else ␊ |
191 | ␉␉{␊ |
192 | ␉␉␉zstream_inited = true;␊ |
193 | ␉␉}␊ |
194 | ␊ |
195 | ␉␉␊ |
196 | ␉␉zlib_result = inflate(&zstream, Z_FINISH);␊ |
197 | ␉␉if (zstream_inited) inflateEnd(&zstream);␊ |
198 | ␊ |
199 | ␉␉DBG("Inflated result is %d, in: %d bytes, out: %d bytes\n", zlib_result, zstream.total_in, zstream.total_out);␊ |
200 | ␉␉if (zlib_result == Z_STREAM_END || zlib_result == Z_OK)␊ |
201 | ␉␉{␉␉␉␊ |
202 | ␉␉␉config_file_t plistData;␊ |
203 | ␉␉␉config_file_t allDicts;␊ |
204 | ␉␉␉bzero(&plistData, sizeof(plistData));␊ |
205 | ␉␉␉bzero(&allDicts, sizeof(allDicts));␊ |
206 | ␉␉␉␊ |
207 | ␉␉␉XMLParseFile( plist, &plistData.dictionary );␊ |
208 | ␊ |
209 | ␉␉␉int count = 0;␊ |
210 | ␊ |
211 | ␉␉␉allDicts.dictionary = XMLGetProperty(plistData.dictionary, kMKEXTInfoDictionariesKey);␊ |
212 | ␉␉␉count = XMLTagCount(allDicts.dictionary);␊ |
213 | ␊ |
214 | ␉␉␉DBG("Plist contains %d kexts\n", count);␊ |
215 | ␉␉␉␊ |
216 | ␉␉␉␊ |
217 | ␉␉␉bool patched = false;␊ |
218 | ␉␉␉for(; count--; count > 0)␊ |
219 | ␉␉␉{␊ |
220 | ␉␉␉␉TagPtr kextEntry = XMLGetElement(allDicts.dictionary, count);␊ |
221 | ␉␉␉␉patched |= patch_kext(kextEntry, plist, package);␊ |
222 | ␉␉␉}␊ |
223 | ␉␉␉␊ |
224 | ␊ |
225 | ␉␉␉if(patched)␊ |
226 | ␉␉␉{␊ |
227 | ␉␉␉␉zstream_inited = false;␊ |
228 | ␉␉␉␉// Recompress the plist␊ |
229 | ␉␉␉␉bzero(&zstream, sizeof(zstream));␉␉␊ |
230 | ␉␉␉␉zstream.next_in = (UInt8*)plist;␊ |
231 | ␉␉␉␉zstream.next_out = (UInt8*)package + plist_offset;␊ |
232 | ␉␉␉␉zstream.avail_in = MKEXT2_GET_PLIST_FULLSIZE(package);␊ |
233 | ␉␉␉␉zstream.avail_out = MKEXT2_GET_PLIST_FULLSIZE(package)<<2;␉// Give us some extra free space, just in case␊ |
234 | ␉␉␉␉zstream.zalloc = Z_NULL;␊ |
235 | ␉␉␉␉zstream.zfree = Z_NULL;␊ |
236 | ␉␉␉␉zstream.opaque = Z_NULL;␊ |
237 | ␉␉␉␉␊ |
238 | ␉␉␉␉␊ |
239 | ␉␉␉␉zlib_result = deflateInit2(&zstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,15, 8 /* memLevel */, Z_DEFAULT_STRATEGY);␊ |
240 | ␉␉␉␉if (Z_OK != zlib_result) {␊ |
241 | ␉␉␉␉␉printf("ZLIB Deflate Error: %s\n", zstream.msg);␊ |
242 | ␉␉␉␉␉getc();␊ |
243 | ␉␉␉␉}␊ |
244 | ␉␉␉␉else ␊ |
245 | ␉␉␉␉{␊ |
246 | ␉␉␉␉␉zstream_inited = true;␊ |
247 | ␉␉␉␉}␊ |
248 | ␉␉␉␉␊ |
249 | ␉␉␉␉zlib_result = deflate(&zstream, Z_FINISH);␊ |
250 | ␉␉␉␉␊ |
251 | ␉␉␉␉if (zlib_result == Z_STREAM_END)␊ |
252 | ␉␉␉␉{␊ |
253 | ␉␉␉␉␉DBG("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));␊ |
254 | ␉␉␉␉} ␊ |
255 | ␉␉␉␉else if (zlib_result == Z_OK)␊ |
256 | ␉␉␉␉{␊ |
257 | ␉␉␉␉␉/* deflate filled output buffer, meaning the data doesn't compress.␊ |
258 | ␉␉␉␉␉ */␊ |
259 | ␉␉␉␉␉DBG("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));␊ |
260 | ␉␉␉␉␉␊ |
261 | ␉␉␉␉} ␊ |
262 | ␉␉␉␉else if (zlib_result != Z_STREAM_ERROR)␊ |
263 | ␉␉␉␉{␊ |
264 | ␉␉␉␉␉printf("ZLIB Deflate Error: %s\n", zstream.msg);␊ |
265 | ␉␉␉␉␉getc();␊ |
266 | ␉␉␉␉}␊ |
267 | ␉␉␉␉␊ |
268 | ␉␉␉␉if(zstream.total_out != MKEXT2_GET_PLIST_COMPSIZE(package))␊ |
269 | ␉␉␉␉{␊ |
270 | ␉␉␉␉␉// Update the mkext length␊ |
271 | ␉␉␉␉␉MKEXT2_HDR_CAST(package)->length = MKEXT_SWAP(MKEXT_GET_LENGTH(package) - MKEXT2_GET_PLIST_COMPSIZE(package) + zstream.total_out);␊ |
272 | ␉␉␉␉␉MKEXT2_HDR_CAST(package)->plist_compressed_size = MKEXT_SWAP(zstream.total_out);␊ |
273 | ␉␉␉␉␉*((int*)lengthtmp) -= MKEXT2_GET_PLIST_COMPSIZE(package);␊ |
274 | ␉␉␉␉␉*((int*)lengthtmp) += zstream.total_out;␊ |
275 | ␉␉␉␉}␊ |
276 | ␉␉␉␉␉␉␉␉␊ |
277 | ␉␉␉␉if (zstream_inited) deflateEnd(&zstream);␊ |
278 | ␉␉␉␉␊ |
279 | ␉␉␉␉␊ |
280 | ␉␉␉␉␊ |
281 | ␉␉␉␉// re alder32 the new mkext2 package␊ |
282 | ␉␉␉␉MKEXT_HDR_CAST(package)->adler32 = ␊ |
283 | ␉␉␉␉␉MKEXT_SWAP(Mkext_Alder32((unsigned char *)&package->version,␊ |
284 | ␉␉␉␉␉␉␉␉␉␉␉ MKEXT_GET_LENGTH(package) - 0x10));␊ |
285 | ␉␉␉}␊ |
286 | ␉␉}␊ |
287 | ␉␉else␊ |
288 | ␉␉{␊ |
289 | ␉␉␉printf("ZLIB Error: %s\n", zstream.msg);␊ |
290 | ␉␉␉getc();␊ |
291 | ␉␉}␊ |
292 | ␊ |
293 | ␉␉//config_file_t mkextPlist;␊ |
294 | ␉␉//ParseXMLFile((char*) plist, &mkextPlist.dictionary);␊ |
295 | ␉␉␊ |
296 | ␉␉␊ |
297 | ␉␉␊ |
298 | ␉␉␊ |
299 | ␉␉␊ |
300 | ␉␉/*␉␉int i;␊ |
301 | ␉␉for(i = 0; i < MKEXT_GET_COUNT(package); i++)␊ |
302 | ␉␉{␊ |
303 | ␉␉␉printf("Parsing kext %d\n", i);␊ |
304 | ␉␉}␊ |
305 | ␉␉*/␊ |
306 | ␉␉␊ |
307 | ␊ |
308 | ␉}␊ |
309 | ␊ |
310 | ␉␊ |
311 | ␉DBG("Loading %s, length %d, version 0x%x\n", filespec, length, version);␊ |
312 | ␉//getc();␊ |
313 | }␊ |
314 | ␊ |
315 | // FIXME: only handles mkext2 entries␊ |
316 | bool patch_kext(TagPtr plist, char* plistbuffer, void* start)␊ |
317 | {␊ |
318 | ␉int exeutable_offset;␊ |
319 | ␉mkext2_file_entry* kext;␊ |
320 | ␉char* bundleID;␊ |
321 | ␉int full_size, compressed_size;␊ |
322 | ␉void* compressed_data;␊ |
323 | ␉z_stream zstream;␊ |
324 | ␉bool zstream_inited = false;␊ |
325 | ␉int zlib_result;␊ |
326 | ␉TagPtr personality;␊ |
327 | ␉␊ |
328 | ␉if(XMLGetProperty(plist, kMKEXTExecutableKey) == NULL) return false;␉// Kext is a plist only kext, don't patch␊ |
329 | ␉␊ |
330 | ␉bundleID = XMLCastString(XMLGetProperty(plist, kPropCFBundleIdentifier));␊ |
331 | ␉exeutable_offset = XMLCastInteger(XMLGetProperty(plist, kMKEXTExecutableKey));␊ |
332 | ␉␊ |
333 | ␉␊ |
334 | ␉kext = (void*)((char*)start + exeutable_offset);␊ |
335 | ␊ |
336 | ␉full_size = MKEXT2_GET_ENTRY_FULLSIZE(kext);␊ |
337 | ␉compressed_size = MKEXT2_GET_ENTRY_COMPSIZE(kext);␊ |
338 | ␉compressed_data = MKEXT2_GET_ENTRY_DATA(kext);␊ |
339 | ␉␊ |
340 | ␉if(␉(strcmp(bundleID, "com.apple.driver.AppleIntelGMA950") == 0) ||␊ |
341 | ␉␉(strcmp(bundleID, "com.apple.driver.AppleIntelIntegratedFramebuffer") == 0))␊ |
342 | ␉{␊ |
343 | ␉␉␊ |
344 | ␉␉␊ |
345 | ␉␉personality =␉␉XMLCastDict(XMLGetProperty(plist, kPropIOKitPersonalities));␊ |
346 | ␉␉if(XMLGetProperty(personality, (const char*)"Intel915"))␊ |
347 | ␉␉{␊ |
348 | ␉␉␉personality =␉␉XMLGetProperty(personality, (const char*)"Intel915");␊ |
349 | ␉␉}␊ |
350 | ␉␉else␊ |
351 | ␉␉{␊ |
352 | ␉␉␉personality =␉␉XMLGetProperty(personality, (const char*)"AppleIntelIntegratedFramebuffer");␉␊ |
353 | ␉␉}␊ |
354 | #if DEBUG_KEXT_PATCHER␊ |
355 | ␉␉char* pcimatch =␉XMLCastString(XMLGetProperty(personality, (const char*)"IOPCIPrimaryMatch"));␊ |
356 | #endif␊ |
357 | ␉␉long offset =␉␉XMLCastStringOffset(XMLGetProperty(personality, (const char*)"IOPCIPrimaryMatch"));␊ |
358 | ␉␉␊ |
359 | ␉␉replace_string("0x27A28086", "0x27AE8086", plistbuffer + offset);␊ |
360 | ␉␉␉␉␉ ␊ |
361 | ␉␉DBG("Located kext %s\n", bundleID);␊ |
362 | ␉␉DBG("PCI Match offset = %d, string = %s\n", offset, pcimatch);␊ |
363 | ␉␉char* executable = malloc(full_size);␊ |
364 | ␉␉␊ |
365 | ␉␉bzero(&zstream, sizeof(zstream));␉␉␊ |
366 | ␉␉zstream.next_in = (UInt8*)compressed_data;␊ |
367 | ␉␉zstream.avail_in = compressed_size;␊ |
368 | ␉␉␊ |
369 | ␉␉zstream.next_out = (UInt8*)executable;␊ |
370 | ␉␉zstream.avail_out = full_size;␊ |
371 | ␉␉␊ |
372 | ␉␉zstream.zalloc = z_alloc;␊ |
373 | ␉␉zstream.zfree = z_free;␊ |
374 | ␉␉␊ |
375 | ␉␉zlib_result = inflateInit(&zstream);␊ |
376 | ␉␉if (Z_OK != zlib_result)␊ |
377 | ␉␉{␊ |
378 | ␉␉␉printf("ZLIB Inflate Error: %s\n", zstream.msg);␊ |
379 | ␉␉␉getc();␊ |
380 | ␉␉}␊ |
381 | ␉␉else ␊ |
382 | ␉␉{␊ |
383 | ␉␉␉zstream_inited = true;␊ |
384 | ␉␉}␊ |
385 | ␉␉␊ |
386 | ␉␉␊ |
387 | ␉␉zlib_result = inflate(&zstream, Z_FINISH);␊ |
388 | ␉␉␊ |
389 | ␉␉DBG("Inflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, full_size);␊ |
390 | ␊ |
391 | ␉␉replace_word(0x27A28086, 0x27AE8086, executable, zstream.total_out);␊ |
392 | ␉␉if (zstream_inited) inflateEnd(&zstream);␊ |
393 | ␊ |
394 | ␉␉␊ |
395 | ␉␉zstream.next_in = (UInt8*)executable;␊ |
396 | ␉␉//␉␉zstream.next_out = (UInt8*)((int)compressed_data<<1);␊ |
397 | ␉␉zstream.next_out = (UInt8*)compressed_data;␊ |
398 | ␊ |
399 | ␉␉zstream.avail_in = full_size;␊ |
400 | ␉␉zstream.avail_out = compressed_size;␊ |
401 | ␉␉zstream.zalloc = Z_NULL;␊ |
402 | ␉␉zstream.zfree = Z_NULL;␊ |
403 | ␉␉zstream.opaque = Z_NULL;␊ |
404 | ␉␉␊ |
405 | ␉␉␊ |
406 | ␉␉␊ |
407 | ␉␉// Recompress the eecutable␊ |
408 | ␉␉zlib_result = deflateInit2(&zstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,15, 8 /* memLevel */, Z_DEFAULT_STRATEGY);␊ |
409 | ␉␉if (Z_OK != zlib_result) {␊ |
410 | ␉␉␉printf("ZLIB Deflate Error: %s\n", zstream.msg);␊ |
411 | ␉␉␉getc();␊ |
412 | ␉␉}␊ |
413 | ␉␉else ␊ |
414 | ␉␉{␊ |
415 | ␉␉␉zstream_inited = true;␊ |
416 | ␉␉}␊ |
417 | ␉␉␊ |
418 | ␉␉zlib_result = deflate(&zstream, Z_FINISH);␊ |
419 | ␊ |
420 | ␉␉if (zlib_result == Z_STREAM_END)␊ |
421 | ␉␉{␊ |
422 | ␉␉␉DBG("Deflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, full_size);␊ |
423 | ␉␉} ␊ |
424 | ␉␉else if (zlib_result == Z_OK)␊ |
425 | ␉␉{␊ |
426 | ␉␉␉/* deflate filled output buffer, meaning the data doesn't compress.␊ |
427 | ␉␉␉ */␊ |
428 | ␉␉␉DBG("Deflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, full_size);␊ |
429 | ␊ |
430 | ␉␉} ␊ |
431 | ␉␉else if (zlib_result != Z_STREAM_ERROR)␊ |
432 | ␉␉{␊ |
433 | ␉␉␉printf("ZLIB Deflate Error: %s\n", zstream.msg);␊ |
434 | ␉␉␉getc();␊ |
435 | ␉␉}␊ |
436 | ␉␉␊ |
437 | ␉␉if (zstream_inited) deflateEnd(&zstream);␊ |
438 | ␊ |
439 | ␊ |
440 | ␉␉␊ |
441 | ␉␉␊ |
442 | ␊ |
443 | ␉␉free(executable);␊ |
444 | ␉␉␊ |
445 | ␉␉//printf("\n");␊ |
446 | ␉␉␊ |
447 | ␉␉//getc();␉␉␊ |
448 | ␉␉␊ |
449 | ␉␉return true;␊ |
450 | ␉}␊ |
451 | ␉return false;␊ |
452 | }␊ |
453 | ␊ |
454 | ␊ |
455 | void KextPatcher_hook(void* arg1, void* arg2, void* arg3, void* arg4)␊ |
456 | {␊ |
457 | ␉//pci_dt_t* current = arg1;␊ |
458 | } |