Chameleon

Chameleon Commit Details

Date:2010-10-23 20:49:56 (13 years 6 months ago)
Author:Evan Lojewski
Commit:606
Parents: 605
Message: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
Changes:
M/branches/meklort/i386/modules/KextPatcher/hex_editor.c
M/branches/meklort/i386/libsaio/saio_types.h
M/branches/meklort/i386/boot2/boot.c
M/branches/meklort/i386/modules/KextPatcher/hex_editor.h
M/branches/meklort/i386/modules/KextPatcher/kext_patcher.c
M/branches/meklort/i386/boot2/boot.h
M/branches/meklort/i386/boot2/modules.c
M/branches/meklort/i386/libsa/zalloc.c
M/branches/meklort/i386/boot2/drivers.c

File differences

branches/meklort/i386/libsaio/saio_types.h
5656
5757
5858
59
5960
6061
6162
struct Tag {
long type;
char *string;
long offset;
struct Tag *tag;
struct Tag *tagNext;
};
branches/meklort/i386/boot2/boot.c
7474
7575
7676
77
7778
7879
7980
bool gScanSingleDrive;
#endif
int bvCount = 0;
//intmenucount = 0;
int gDeviceCount = 0;
branches/meklort/i386/boot2/modules.c
846846
847847
848848
849
849850
850851
851852
......
876877
877878
878879
880
879881
880882
881883
......
894896
895897
896898
899
897900
898901
899902
......
940943
941944
942945
946
943947
944948
945949
......
11211125
11221126
11231127
1124
1128
11251129
11261130
11271131
else if(strcmp(symbolName, SYMBOL_DYLD_STUB_BINDER) != 0)
{
printf("Unable to bind symbol %s\n", symbolName);
getc();
}
segmentAddress += sizeof(void*);
else if(strcmp(symbolName, SYMBOL_DYLD_STUB_BINDER) != 0)
{
printf("Unable to bind symbol %s\n", symbolName);
getc();
}
segmentAddress += tmp + sizeof(void*);
else if(strcmp(symbolName, SYMBOL_DYLD_STUB_BINDER) != 0)
{
printf("Unable to bind symbol %s\n", symbolName);
getc();
}
segmentAddress += (immediate * sizeof(void*)) + sizeof(void*);
else if(strcmp(symbolName, SYMBOL_DYLD_STUB_BINDER) != 0)
{
printf("Unable to bind symbol %s\n", symbolName);
getc();
}
if(strcmp(name, SYMBOL_DYLD_STUB_BINDER) != 0)
{
verbose("Unable to locate symbol %s\n", name);
//getc();
getc();
}
#endif
return 0xFFFFFFFF;
branches/meklort/i386/boot2/boot.h
156156
157157
158158
159
159160
160
161
162
163
164
165161
166162
167163
extern void initialize_runtime();
extern void common_boot(int biosdev);
extern char* updateBooter;
/*
* usb.c
*/
extern int usb_loop();
/*
* graphics.c
*/
extern void printVBEModeInfo();
branches/meklort/i386/boot2/drivers.c
4747
4848
4949
50
50
5151
5252
5353
......
7373
7474
7575
76
77
76
77
7878
7979
8080
......
376376
377377
378378
379
379
380380
381381
382382
......
384384
385385
386386
387
387
388388
389389
390390
391391
392
393392
394393
395394
......
785784
786785
787786
788
787
789788
790789
791790
long (*LoadExtraDrivers_p)(FileLoadDrivers_t FileLoadDrivers_p);
#endif
static unsigned long Alder32( unsigned char * buffer, long length );
unsigned long Mkext_Alder32( unsigned char * buffer, long length );
long FileLoadDrivers(char *dirSpec, long plugin);
#ifndef OPTION_ROM
char * gTempSpec;
char * gFileName;
static unsigned long
Alder32( unsigned char * buffer, long length )
unsigned long
Mkext_Alder32( unsigned char * buffer, long length )
{
long cnt;
unsigned long result, lowHalf, highHalf;
if (length < sizeof (DriversPackage)) return -1;
// call hook to notify modules that the mkext has been loaded
execute_hook("LoadDriverMKext", (void*)fileSpec, (void*)package, (void*) length, NULL);
execute_hook("LoadDriverMKext", (void*)fileSpec, (void*)package, (void*) &length, NULL);
// Verify the MKext.
( GetPackageElement(signature2) != kDriverPackageSignature2) ||
( GetPackageElement(length) > kLoadSize ) ||
( GetPackageElement(alder32) !=
Alder32((unsigned char *)&package->version, GetPackageElement(length) - 0x10) ) )
Mkext_Alder32((unsigned char *)&package->version, GetPackageElement(length) - 0x10) ) )
{
return -1;
}
// Make space for the MKext.
driversLength = GetPackageElement(length);
driversAddr = AllocateKernelMemory(driversLength);
return -1;
}
if (OSSwapBigToHostInt32(kernel_header->adler32) !=
Alder32(binary, uncompressed_size)) {
Mkext_Alder32(binary, uncompressed_size)) {
printf("adler mismatch\n");
return -1;
}
branches/meklort/i386/modules/KextPatcher/hex_editor.h
1212
1313
1414
15
1516
16
1717
int replace_patern(char* pattern, char* repalcement, char* buffer, long buffer_size);
int replace_word(uint32_t pattern, uint32_t repalcement, char* buffer, long buffer_size);
void replace_string(char* find, char* replace, char* string);
#endif /* H_HEX_EDITOR */
branches/meklort/i386/modules/KextPatcher/kext_patcher.c
1717
1818
1919
20
2120
21
22
23
24
25
26
27
28
29
30
31
2232
2333
2434
......
106116
107117
108118
109
119
110120
111121
112122
......
141151
142152
143153
144
154
145155
146156
147157
......
150160
151161
152162
153
163
154164
155165
156166
......
184194
185195
186196
187
197
198
199
188200
189
190
191
201
192202
193203
194204
195205
196206
197
198
199
207
200208
201209
202210
203
204
205
206
207
208
209
210211
211212
212
213
214
215
216
213
214
217215
218216
219217
220218
221219
222220
223
221
224222
225223
224
226225
227226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
228281
229282
230283
231284
232
233285
234
235
236
237
238286
239287
240288
......
256304
257305
258306
259
260307
261308
262309
263310
264
265
311
312
266313
267314
268
269
315
316
270317
271318
272319
......
276323
277324
278325
326
279327
280328
281329
282330
283331
332
333
284334
285335
286336
......
290340
291341
292342
293
294
295343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
296363
297364
298365
......
319386
320387
321388
322
389
323390
324
325
391
326392
327393
328394
329395
396
330397
398
331399
332400
333401
......
351419
352420
353421
354
422
355423
356424
357425
358426
359427
360
428
361429
362430
363431
......
366434
367435
368436
369
370
371
372437
373438
374439
......
379444
380445
381446
382
447
383448
384449
385450
#include "modules.h"
#include "hex_editor.h"
bool patch_kext(TagPtr plist, void* start);
#ifndef DEBUG_KEXT_PATCHER
#define DEBUG_KEXT_PATCHER 0
#endif
#if DEBUG_KEXT_PATCHER
#define DBG(x...)printf(x)
#else
#define DBG(x...)
#endif
bool patch_kext(TagPtr plist, char* plistbuffer, void* start);
static void * z_alloc(void *, u_int items, u_int size);
static void z_free(void *, void *ptr);
void mkext_loaded(void* filespec, void* packagetmp, void* lengthtmp, void* arg3)
{
int version = 0;
int length = (int) lengthtmp;
//int length = *((int*)lengthtmp);
mkext_basic_header* package = packagetmp;
// Verify the MKext.
int i;
for(i = 0; i < MKEXT_GET_COUNT(package); i++)
{
printf("Parsing kext %d\n", i);
DBG("Parsing kext %d\n", i);
//mkext_kext* kext = MKEXT1_GET_KEXT(package, i);
// uses decompress_lzss
// TODO: handle kext
}
else if((version & 0xFFFF0000) == 0x02000000) // mkext2
{
printf("Mkext2 package located at 0x%X\n", package);
DBG("Mkext2 package located at 0x%X\n", package);
// mkext2 uses zlib
mkext2_header* package = packagetmp;
zlib_result = inflate(&zstream, Z_FINISH);
printf("Inflated result is %d, in: %d bytes, out: %d bytes\n", zlib_result, zstream.total_in, zstream.total_out);
if (zstream_inited) inflateEnd(&zstream);
DBG("Inflated result is %d, in: %d bytes, out: %d bytes\n", zlib_result, zstream.total_in, zstream.total_out);
if (zlib_result == Z_STREAM_END || zlib_result == Z_OK)
{
//printf("Plist contains %s\n", plist);
{
config_file_t plistData;
config_file_t allDicts;
bzero(&plistData, sizeof(plistData));
bzero(&allDicts, sizeof(allDicts));
//plist += strlen("<dict><key>_MKEXTInfoDictionaries</key><array>");// Skip kMKEXTInfoDictionariesKey. Causes issues
// NOTE: there will be an extra </array></dict> at the end
/*int len =*/ XMLParseFile( plist, &plistData.dictionary );
XMLParseFile( plist, &plistData.dictionary );
int count = 0;
count = XMLTagCount(plistData.dictionary);
if(count != 1)
{
error("Mkext has more than one entry, unable to patch.");
getc();
return;
}
allDicts.dictionary = XMLGetProperty(plistData.dictionary, kMKEXTInfoDictionariesKey);
count = XMLTagCount(allDicts.dictionary);
/*printf("Element type: %d\n", allDicts.dictionary->type);
printf("Element tag: %d\n", allDicts.dictionary->tag);
printf("Element tagNext: %d\n", allDicts.dictionary->tagNext);
*/
printf("Plist contains %d kexts\n", count);
DBG("Plist contains %d kexts\n", count);
bool patched = false;
for(; count--; count > 0)
{
TagPtr kextEntry = XMLGetElement(allDicts.dictionary, count);
patched |= patch_kext(kextEntry, package);
patched |= patch_kext(kextEntry, plist, package);
}
if(patched)
{
zstream_inited = false;
// Recompress the plist
bzero(&zstream, sizeof(zstream));
zstream.next_in = (UInt8*)plist;
zstream.next_out = (UInt8*)package + plist_offset;
zstream.avail_in = MKEXT2_GET_PLIST_FULLSIZE(package);
zstream.avail_out = MKEXT2_GET_PLIST_FULLSIZE(package)<<2;// Give us some extra free space, just in case
zstream.zalloc = Z_NULL;
zstream.zfree = Z_NULL;
zstream.opaque = Z_NULL;
zlib_result = deflateInit2(&zstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,15, 8 /* memLevel */, Z_DEFAULT_STRATEGY);
if (Z_OK != zlib_result) {
printf("ZLIB Deflate Error: %s\n", zstream.msg);
getc();
}
else
{
zstream_inited = true;
}
zlib_result = deflate(&zstream, Z_FINISH);
if (zlib_result == Z_STREAM_END)
{
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));
}
else if (zlib_result == Z_OK)
{
/* deflate filled output buffer, meaning the data doesn't compress.
*/
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));
}
else if (zlib_result != Z_STREAM_ERROR)
{
printf("ZLIB Deflate Error: %s\n", zstream.msg);
getc();
}
if(zstream.total_out != MKEXT2_GET_PLIST_COMPSIZE(package))
{
// Update the mkext length
MKEXT2_HDR_CAST(package)->length = MKEXT_SWAP(MKEXT_GET_LENGTH(package) - MKEXT2_GET_PLIST_COMPSIZE(package) + zstream.total_out);
MKEXT2_HDR_CAST(package)->plist_compressed_size = MKEXT_SWAP(zstream.total_out);
*((int*)lengthtmp) -= MKEXT2_GET_PLIST_COMPSIZE(package);
*((int*)lengthtmp) += zstream.total_out;
}
if (zstream_inited) deflateEnd(&zstream);
// re alder32 the new mkext2 package
MKEXT_HDR_CAST(package)->adler32 =
MKEXT_SWAP(Mkext_Alder32((unsigned char *)&package->version,
MKEXT_GET_LENGTH(package) - 0x10));
}
printf("kexts parsed\n");
}
else
{
}
*/
if (zstream_inited) inflateEnd(&zstream);
}
printf("Loading %s, length %d, version 0x%x\n", filespec, length, version);
getc();
DBG("Loading %s, length %d, version 0x%x\n", filespec, length, version);
//getc();
}
// TODO: only handles mkext2 entries
bool patch_kext(TagPtr plist, void* start)
// FIXME: only handles mkext2 entries
bool patch_kext(TagPtr plist, char* plistbuffer, void* start)
{
int exeutable_offset;
mkext2_file_entry* kext;
z_stream zstream;
bool zstream_inited = false;
int zlib_result;
TagPtr personality;
if(XMLGetProperty(plist, kMKEXTExecutableKey) == NULL) return false;// Kext is a plist only kext, don't patch
bundleID = XMLCastString(XMLGetProperty(plist, kPropCFBundleIdentifier));
exeutable_offset = XMLCastInteger(XMLGetProperty(plist, kMKEXTExecutableKey));
kext = (void*)((char*)start + exeutable_offset);
full_size = MKEXT2_GET_ENTRY_FULLSIZE(kext);
if((strcmp(bundleID, "com.apple.driver.AppleIntelGMA950") == 0) ||
(strcmp(bundleID, "com.apple.driver.AppleIntelIntegratedFramebuffer") == 0))
{
printf("Located kext %s\n", bundleID);
printf("offset is 0x%x\n", exeutable_offset);
personality =XMLCastDict(XMLGetProperty(plist, kPropIOKitPersonalities));
if(XMLGetProperty(personality, (const char*)"Intel915"))
{
personality =XMLGetProperty(personality, (const char*)"Intel915");
}
else
{
personality =XMLGetProperty(personality, (const char*)"AppleIntelIntegratedFramebuffer");
}
#if DEBUG_KEXT_PATCHER
char* pcimatch =XMLCastString(XMLGetProperty(personality, (const char*)"IOPCIPrimaryMatch"));
#endif
long offset =XMLCastStringOffset(XMLGetProperty(personality, (const char*)"IOPCIPrimaryMatch"));
replace_string("0x27A28086", "0x27AE8086", plistbuffer + offset);
DBG("Located kext %s\n", bundleID);
DBG("PCI Match offset = %d, string = %s\n", offset, pcimatch);
char* executable = malloc(full_size);
bzero(&zstream, sizeof(zstream));
zlib_result = inflate(&zstream, Z_FINISH);
printf("Inflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, full_size);
DBG("Inflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, full_size);
printf("Replaced 0x27A28086 %d times.\n",
replace_word(0x27A28086, 0x27AE8086, executable, zstream.total_out));
replace_word(0x27A28086, 0x27AE8086, executable, zstream.total_out);
if (zstream_inited) inflateEnd(&zstream);
zstream.next_in = (UInt8*)executable;
//zstream.next_out = (UInt8*)((int)compressed_data<<1);
zstream.next_out = (UInt8*)compressed_data;
zstream.avail_in = full_size;
zstream.avail_out = compressed_size;
zstream.zalloc = Z_NULL;
if (zlib_result == Z_STREAM_END)
{
printf("Deflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, full_size);
DBG("Deflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, full_size);
}
else if (zlib_result == Z_OK)
{
/* deflate filled output buffer, meaning the data doesn't compress.
*/
printf("Deflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, full_size);
DBG("Deflated result is %d, in: %d bytes, out: %d bytes, full: %d\n", zlib_result, zstream.total_in, zstream.total_out, full_size);
}
else if (zlib_result != Z_STREAM_ERROR)
getc();
}
/* TODO: Only accept the compression if it actually shrinks the file.
*/
if (zstream_inited) deflateEnd(&zstream);
//printf("\n");
getc();
//getc();
return true;
}
branches/meklort/i386/modules/KextPatcher/hex_editor.c
7474
7575
7676
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
return num_replaced;
}
void replace_string(char* find, char* replace, char* string)
{
if(!find ||
!replace ||
!string ||
strlen(find) != strlen(replace)) return;
char* str = string;
while(strncmp(str, find, strlen(find)-1))
{
str++;
}
strncpy(str, replace, strlen(replace) - 1);// don't copy the null char
}
branches/meklort/i386/libsa/zalloc.c
250250
251251
252252
253
253
254254
255255
256256
return;
}
static void
void
zallocate(char * start,int size)
{
#if ZDEBUG

Archive Download the corresponding diff file

Revision: 606