Chameleon

Chameleon Commit Details

Date:2010-09-04 20:21:17 (13 years 7 months ago)
Author:Evan Lojewski
Commit:491
Parents: 490
Message:Initial 64bit support. lapic_configure patch is currently 32bit only, however the rest of the patches should work fine on a 64bit kernel. I haven't teted this extensivly, so it may or may not work for everyone.
Changes:
M/branches/meklort/i386/modules/KernelPatcher/kernel_patcher.c
M/branches/meklort/i386/modules/KernelPatcher/Makefile
M/branches/meklort/i386/Makefile
M/branches/meklort/i386/boot2/modules.c
M/branches/meklort/i386/modules/HelloWorld/HelloWorld.c

File differences

branches/meklort/i386/boot2/modules.c
301301
302302
303303
304
304
305305
306306
307307
308308
309309
310310
311
311312
312
313
313314
315
314316
317
315318
316319
317320
......
342345
343346
344347
348
345349
350
346351
347352
348353
......
10431048
10441049
10451050
1046
1051
10471052
10481053
1049
1050
1051
10521054
10531055
10541056
......
10581060
10591061
10601062
1061
1063
10621064
10631065
10641066
10651067
10661068
1067
1069
1070
10681071
10691072
10701073
1071
10721074
10731075
10741076
......
10791081
10801082
10811083
1082
1084
10831085
10841086
10851087
struct symtab_command* symtabCommand = NULL;
//struct dysymtab_command* dysymtabCommand = NULL;
UInt32 binaryIndex = sizeof(struct mach_header);
UInt32 binaryIndex = 0;
UInt16 cmd = 0;
// Parse through the load commands
if(((struct mach_header*)binary)->magic == MH_MAGIC)
{
is64 = 0;
binaryIndex += sizeof(struct mach_header);
}
else if(((struct mach_header_64*)binary)->magic != MH_MAGIC_64)
else if(((struct mach_header_64*)binary)->magic == MH_MAGIC_64)
{
// NOTE: modules cannot be 64bit...
is64 = 1;
binaryIndex += sizeof(struct mach_header_64);
}
else
{
case LC_SYMTAB:
symtabCommand = binary + binaryIndex;
break;
case LC_SEGMENT:
case LC_SEGMENT_64:
break;
case LC_DYSYMTAB:
//char* symbolTable = base + symtabCommand->symoff;
if(!is64)
{
struct nlist* symbolEntry = (void*)base + symtabCommand->symoff;
while(symbolIndex < symtabCommand->nsyms)
{
struct nlist* symbolEntry = (void*)base + symtabCommand->symoff + (symbolIndex * sizeof(struct nlist));
// If the symbol is exported by this module
if(symbolEntry->n_value &&
symbol_handler(symbolString + symbolEntry->n_un.n_strx, (long long)base + symbolEntry->n_value, is64) != 0xFFFFFFFF)
module_start = base + symbolEntry->n_value;
}
symbolEntry+= sizeof(struct nlist);
symbolEntry++;
symbolIndex++;// TODO remove
}
}
else
{
struct nlist_64* symbolEntry = (void*)base + symtabCommand->symoff;
// NOTE First entry is *not* correct, but we can ignore it (i'm getting radar:// right now)
while(symbolIndex < symtabCommand->nsyms)
{
struct nlist_64* symbolEntry = (void*)base + symtabCommand->symoff + (symbolIndex * sizeof(struct nlist_64));
// If the symbol is exported by this module
if(symbolEntry->n_value &&
module_start = base + symbolEntry->n_value;
}
symbolEntry+= sizeof(struct nlist);
symbolEntry++;
symbolIndex++;// TODO remove
}
}
branches/meklort/i386/modules/KernelPatcher/kernel_patcher.c
1212
1313
1414
15
16
17
1518
16
17
18
19
2019
2120
2221
2322
24
23
2524
26
25
2726
28
27
2928
29
3030
31
3231
3332
34
35
36
37
38
33
34
35
36
37
3938
4039
41
42
40
4341
44
45
42
43
44
45
46
47
4648
49
4750
4851
4952
......
213216
214217
215218
216
219
217220
218
219
220
221
221
222
223
222224
223225
224
225226
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
227245
228246
229247
......
235253
236254
237255
238
239
256
240257
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
258
259
260
261
260262
261
263
264
262265
263
266
264267
265
268
266269
267
270
268271
269
272
270273
274
271275
272
276
273277
274
275
276
277
278
278
279
280
281
282
283
284
285
286
287
288
289
290
279291
280
281
282
283
284
285
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
286329
330
287331
288
289332
333
290334
291335
292336
......
295339
296340
297341
342
298343
299344
345
346
347
348
300349
301350
302351
patchRoutine_t* patches = NULL;
kernSymbols_t* kernelSymbols = NULL;
unsigned long long textAddress = 0;
unsigned long long textSection = 0;
//UInt64 vmaddr = 0;
UInt32 textSection = 0;
UInt32 textAddress = 0;
void KernelPatcher_start()
{
//register_kernel_patch(patch_cpuid_set_info, KERNEL_32, CPUID_MODEL_ATOM);// TODO: CPUFAMILY_INTEL_PENRYN, CPUID_MODEL_PENRYN
//register_kernel_patch(patch_cpuid_set_info, KERNEL_32, CPUID_MODEL_UNKNOWN);// 0, 0
register_kernel_patch(patch_cpuid_set_info_all, KERNEL_32, CPUID_MODEL_UNKNOWN);
register_kernel_patch(patch_cpuid_set_info_all, KERNEL_ANY, CPUID_MODEL_UNKNOWN);
register_kernel_patch(patch_commpage_stuff_routine, KERNEL_32, CPUID_MODEL_ANY);
register_kernel_patch(patch_commpage_stuff_routine, KERNEL_ANY, CPUID_MODEL_ANY);
register_kernel_patch(patch_lapic_init, KERNEL_32, CPUID_MODEL_ANY);
register_kernel_patch(patch_lapic_init, KERNEL_ANY, CPUID_MODEL_ANY);
// NOTE: following is currently 32bit only
register_kernel_patch(patch_lapic_configure, KERNEL_32, CPUID_MODEL_ANY);
//register_kernel_patch(patch_lapic_interrupt, KERNEL_32, CPUID_MODEL_ANY);
register_kernel_symbol(KERNEL_32, "_panic");
register_kernel_symbol(KERNEL_32, "_cpuid_set_info");
register_kernel_symbol(KERNEL_32, "_pmCPUExitHaltToOff");
register_kernel_symbol(KERNEL_32, "_lapic_init");
register_kernel_symbol(KERNEL_32, "_commpage_stuff_routine");
register_kernel_symbol(KERNEL_ANY, "_panic");
register_kernel_symbol(KERNEL_ANY, "_cpuid_set_info");
register_kernel_symbol(KERNEL_ANY, "_pmCPUExitHaltToOff");
register_kernel_symbol(KERNEL_ANY, "_lapic_init");
register_kernel_symbol(KERNEL_ANY, "_commpage_stuff_routine");
// LAPIC configure symbols
register_kernel_symbol(KERNEL_32, "_lapic_configure");
register_kernel_symbol(KERNEL_32, "_lapic_interrupt");
register_kernel_symbol(KERNEL_ANY, "_lapic_configure");
register_kernel_symbol(KERNEL_32, "_lapic_start");
register_kernel_symbol(KERNEL_32, "_lapic_interrupt_base");
register_kernel_symbol(KERNEL_ANY, "_lapic_start");
register_kernel_symbol(KERNEL_ANY, "_lapic_interrupt_base");
//register_kernel_patch(patch_lapic_interrupt, KERNEL_ANY, CPUID_MODEL_ANY);
//register_kernel_symbol(KERNEL_ANY, "_lapic_interrupt");
// TODO: register needed symbols
**/
int locate_symbols(void* kernelData)
{
char is64;
struct load_command *loadCommand;
struct symtab_command *symtableData;
//struct nlist *symbolEntry;
char* symbolString;
struct symtab_command *symtableData = NULL;
struct segment_command *segCommand = NULL;
struct segment_command_64 *segCommand64 = NULL;
UInt32 kernelIndex = 0;
kernelIndex += sizeof(struct mach_header);
if(((struct mach_header*)kernelData)->magic != MH_MAGIC) return KERNEL_64;
if(((struct mach_header*)kernelData)->magic == MH_MAGIC)
{
is64 = 0;
kernelIndex += sizeof(struct mach_header);
}
else if(((struct mach_header_64*)kernelData)->magic == MH_MAGIC_64)
{
is64 = 1;
kernelIndex += sizeof(struct mach_header_64);
}
else
{
printf("Invalid mach magic 0x%X\n", ((struct mach_header*)kernelData)->magic);
getc();
return KERNEL_ERR;
}
int cmd = 0;
UInt cmdSize = loadCommand->cmdsize;
if((loadCommand->cmd & 0x7FFFFFFF) == LC_SYMTAB)// We only care about the symtab segment
switch ((loadCommand->cmd & 0x7FFFFFFF))
{
//printf("Located symtable, length is 0x%X, 0x%X\n", (unsigned int)loadCommand->cmdsize, (unsigned int)sizeof(symtableData));
symtableData = kernelData + kernelIndex;
kernelIndex += sizeof(struct symtab_command);
symbolString = kernelData + symtableData->stroff;
}
else if((loadCommand->cmd & 0x7FFFFFFF) == LC_SEGMENT)// We only care about the __TEXT segment, any other load command can be ignored
{
struct segment_command *segCommand;
segCommand = kernelData + kernelIndex;
//printf("Segment name is %s\n", segCommand->segname);
if(strcmp("__TEXT", segCommand->segname) == 0)
{
UInt32 sectionIndex;
case LC_SYMTAB:
//printf("Located symtable, length is 0x%X, 0x%X\n", (unsigned int)loadCommand->cmdsize, (unsigned int)sizeof(symtableData));
symtableData = kernelData + kernelIndex;
break;
sectionIndex = sizeof(struct segment_command);
case LC_SEGMENT: // 32bit macho
segCommand = kernelData + kernelIndex;
struct section *sect;
//printf("Segment name is %s\n", segCommand->segname);
while(sectionIndex < segCommand->cmdsize)
if(strcmp("__TEXT", segCommand->segname) == 0)
{
sect = kernelData + kernelIndex + sectionIndex;
UInt32 sectionIndex;
sectionIndex += sizeof(struct section);
sectionIndex = sizeof(struct segment_command);
struct section *sect;
if(strcmp("__text", sect->sectname) == 0)
while(sectionIndex < segCommand->cmdsize)
{
// __TEXT,__text found, save the offset and address for when looking for the calls.
textSection = sect->offset;
textAddress = sect->addr;
break;
}
sect = kernelData + kernelIndex + sectionIndex;
sectionIndex += sizeof(struct section);
if(strcmp("__text", sect->sectname) == 0)
{
// __TEXT,__text found, save the offset and address for when looking for the calls.
textSection = sect->offset;
textAddress = sect->addr;
break;
}
}
}
}
kernelIndex += cmdSize;
} else {
kernelIndex += cmdSize;
break;
case LC_SEGMENT_64:// 64bit macho's
segCommand64 = kernelData + kernelIndex;
//printf("Segment name is %s\n", segCommand->segname);
if(strcmp("__TEXT", segCommand64->segname) == 0)
{
UInt32 sectionIndex;
sectionIndex = sizeof(struct segment_command_64);
struct section_64 *sect;
while(sectionIndex < segCommand64->cmdsize)
{
sect = kernelData + kernelIndex + sectionIndex;
sectionIndex += sizeof(struct section_64);
if(strcmp("__text", sect->sectname) == 0)
{
// __TEXT,__text found, save the offset and address for when looking for the calls.
textSection = sect->offset;
textAddress = sect->addr;
break;
}
}
}
break;
default:
break;
}
kernelIndex += cmdSize;
}
handle_symtable((UInt32)kernelData, symtableData, &symbol_handler, determineKernelArchitecture(kernelData) == KERNEL_64);
return 1 << is64;
}
long long symbol_handler(char* symbolName, long long addr, char is64)
kernSymbols_t *symbol = lookup_kernel_symbol(symbolName);
if(symbol)
{
//printf("Located %sbit symbol %s at 0x%lX\n", is64 ? "64" : "32", symbolName, addr);
//getc();
symbol->addr = addr;
}
return 0xFFFFFFFF; // fixme
branches/meklort/i386/modules/KernelPatcher/Makefile
2121
2222
2323
24
24
2525
2626
2727
INSTALLDIR = $(DSTROOT)/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/standalone
OPTIM = -Os -Oz
OPTIM = -O3
DEBUG = -DNOTHING
#DEBUG = -DDEBUG_HELLO_WORLD=1
CFLAGS= $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost \
branches/meklort/i386/modules/HelloWorld/HelloWorld.c
44
55
66
7
78
8
99
1010
1111
*/
#include "libsaio.h"
#include "modules.h"
void helloWorld(void* binary, void* arg2, void* arg3, void* arg4)
{
printf("Hello world from ExecKernel hook. Binary located at 0x%X\n", binary);
branches/meklort/i386/Makefile
4444
4545
4646
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
4764
4865
) || exit $$?; \
done
modules:
@for i in "modules"; \
do \
echo ================= make $@ for $$i =================; \
( cd $$i; ${MAKE} \
"OBJROOT=$(OBJROOT)/$$i" \
"SYMROOT=$(SYMROOT)" \
"DSTROOT=$(DSTROOT)" \
"SRCROOT=$(SRCROOT)" \
"RC_ARCHS=$(RC_ARCHS)" \
"RC_KANJI=$(RC_KANJI)" \
"JAPANESE=$(JAPANESE)" \
"RC_CFLAGS=$(RC_CFLAGS)" $@ \
) || exit $$?; \
done
installsrc:
tar cf - . | (cd ${SRCROOT}; tar xfBp -)

Archive Download the corresponding diff file

Revision: 491