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