Chameleon

Chameleon Commit Details

Date:2010-08-28 21:18:03 (13 years 7 months ago)
Author:Evan Lojewski
Commit:439
Parents: 438
Message:Kernel patcher update, closer to working again, not done yet.
Changes:
M/branches/meklort/i386/modules/KernelPatcher/kernel_patcher.c
M/branches/meklort/i386/modules/KernelPatcher/kernel_patcher.h

File differences

branches/meklort/i386/modules/KernelPatcher/kernel_patcher.c
66
77
88
9
910
1011
1112
1213
1314
1415
15
1616
1717
1818
1919
2020
2121
22
23
24
22
23
24
2525
2626
2727
2828
29
30
31
32
33
34
35
2936
3037
3138
32
39
3340
3441
3542
3643
37
3844
3945
4046
......
4349
4450
4551
52
53
4654
4755
4856
......
5967
6068
6169
70
71
6272
6373
6474
65
66
75
76
77
6778
6879
6980
7081
7182
72
83
7384
7485
7586
7687
7788
78
79
80
81
89
8290
8391
8492
......
101109
102110
103111
104
112
105113
106
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
107135
108136
109
110
137
111138
112
113
114
115
139
140
141
116142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
117160
118161
119
120
121
122
123
124
125
126
162
127163
128
129
164
130165
131
166
167
168
169
132170
133
171
172
173
174
175
176
134177
135
178
179
180
181
182
183
184
185
186
136187
137
138
188
189
190
191
192
139193
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
194
163195
196
197
198
199
200
201
202
203
164204
165205
166206
167207
168
208
169209
170210
171211
......
183223
184224
185225
186
187
188
189
190226
191227
192228
......
197233
198234
199235
200
201
202236
203237
204238
205239
206240
207241
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
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
242
243
244
245
261246
262247
263248
......
298283
299284
300285
301
286
287
288
302289
303290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
304305
306
305307
306308
307309
308310
309
311
310312
313
314
315
316
317
311318
312
313
314
319
320
321
322
315323
316
317
324
325
326
318327
319328
320329
......
482491
483492
484493
494
495
485496
486
487497
488
498
499
489500
490501
491502
......
507518
508519
509520
521
522
523
510524
511525
512
513
526
527
528
529
530
531
532
533
514534
515
535
516536
517
537
518538
519539
520540
521
541
522542
523
543
524544
525545
526546
......
556576
557577
558578
579
580
581
559582
560
561
583
584
585
562586
587
588
589
590
591
592
563593
564594
565595
#include "libsaio.h"
#include "kernel_patcher.h"
#include "platform.h"
#include "modules.h"
extern PlatformInfo_t Platform;
patchRoutine_t* patches = NULL;
kernSymbols_t* kernelSymbols = NULL;
UInt32 textSection = 0;
UInt32 textAddress = 0;
void KernelPatcher_start()
{
register_kernel_patch(patch_cpuid_set_info, KERNEL_32, CPUID_MODEL_ATOM);
register_kernel_patch(patch_cpuid_set_info, KERNEL_32, CPUID_MODEL_UNKNOWN);
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_commpage_stuff_routine, KERNEL_32, CPUID_MODEL_ANY);
register_kernel_patch(patch_lapic_init, 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");
// TODO: register needed symbols
// TODO: Hook main kernel patcher loop into chameleon
register_hook_callback("ExecKernel", &patch_kernel);
}
/*
* Register a kerenl patch
* TODO: chang efunction prototype to include patch argument
*/
void register_kernel_patch(void* patch, int arch, int cpus)
{
patchRoutine_t* entry;
// TODO: verify Platform.CPU.Model is populated this early in bootup
// Check to ensure that the patch is valid on this machine
// If it is not, exit early form this function
if(cpus != Platform.CPU.Model)
{
if(cpus != CPUID_MODEL_ANY)
case CPUID_MODEL_FIELDS:
case CPUID_MODEL_DALES:
case CPUID_MODEL_NEHALEM_EX:
// Known cpu's we don't want to add the patch
return;
break;
default:
// CPU not in supported list.s
return;
// CPU not in supported list, so we are going to add
// The patch will be applied
break;
}
}
else
{
// Incalid cpuid for current cpu. Ignoring patch
// Invalid cpuid for current cpu. Ignoring patch
return;
}
}
}
// Check arch
if(patches == NULL)
{
patches = entry = malloc(sizeof(patchRoutine_t));
entry->validCpu = cpus;
}
void* lookup_kernel_symbol(const char* name)
void register_kernel_symbol(int kernelType, const char* name)
{
return NULL;
if(kernelSymbols == NULL)
{
kernelSymbols = malloc(sizeof(kernSymbols_t));
kernelSymbols->next = NULL;
kernelSymbols->symbol = (char*)name;
kernelSymbols->addr = 0;
}
else {
kernSymbols_t *symbol = kernelSymbols;
while(symbol->next != NULL)
{
symbol = symbol->next;
}
symbol->next = malloc(sizeof(kernSymbols_t));
symbol = symbol->next;
symbol->next = NULL;
symbol->symbol = (char*)name;
symbol->addr = 0;
}
}
void patch_kernel(void* kernelData)
kernSymbols_t* lookup_kernel_symbol(const char* name)
{
switch (locate_symbols((void*)kernelData)) {
case KERNEL_32:
patch_kernel_32((void*)kernelData);
break;
if(kernelSymbols == NULL)
{
return NULL;
}
kernSymbols_t *symbol = kernelSymbols;
while(symbol && strcmp(symbol->symbol, name) !=0)
{
symbol = symbol->next;
}
if(!symbol)
{
return NULL;
}
else
{
return symbol;
}
}
/**
** patch_kernel_32
**patches kernel based on cpu info determined earlier in the boot process.
**It the machine is vmware, remove the artificial lapic panic
**If the CPU is not supported, remove the cpuid_set_info panic
**If the CPU is and Intel Atom, inject the penryn cpuid info.
**/
void patch_kernel_32(void* kernelData)
void patch_kernel(void* kernelData, void* arg2, void* arg3, void *arg4)
{
// Remove panic in commpage
patch_commpage_stuff_routine(kernelData);
patchRoutine_t* entry = patches;
//patch_pmCPUExitHaltToOff(kernelData);// Not working as intended, disabled for now
printf("Patching kernel located at 0x%X\n", kernelData);
locate_symbols(kernelData);
printf("Symbols located\n", kernelData);
getc();
//if(vmware_detected)
int arch = determineKernelArchitecture(kernelData);
// TODO:locate all symbols
if(patches != NULL)
{
patch_lapic_init(kernelData);
while(entry->next)
{
if(entry->validArchs == KERNEL_ANY || arch == entry->validArchs)
{
entry->patchRoutine(kernelData);
}
entry = entry->next;
}
}
switch(13)//Platform.CPU.Model)
}
int determineKernelArchitecture(void* kernelData)
{
if(((struct mach_header*)kernelData)->magic == MH_MAGIC)
{
// Known good CPU's, no reason to patch kernel
case 13:
case CPUID_MODEL_YONAH:
case CPUID_MODEL_MEROM:
case CPUID_MODEL_PENRYN:
case CPUID_MODEL_NEHALEM:
case CPUID_MODEL_FIELDS:
case CPUID_MODEL_DALES:
case CPUID_MODEL_NEHALEM_EX:
break;
// Known unsuported CPU's
case CPUID_MODEL_ATOM:
// TODO: Impersonate CPU based on user selection
patch_cpuid_set_info(kernelData, CPUFAMILY_INTEL_PENRYN, CPUID_MODEL_PENRYN);// Impersonate Penryn CPU
break;
// Unknown CPU's
default:
// TODO: Impersonate CPU based on user selection
patch_cpuid_set_info(kernelData, 0, 0);// Remove Panic Call
break;
return KERNEL_32;
}
if(((struct mach_header*)kernelData)->magic == MH_MAGIC_64)
{
return KERNEL_64;
}
else
{
return KERNEL_ERR;
}
}
/**
**This functions located the kernelSymbols[i] symbols in the mach-o header.
**This functions located the requested symbols in the mach-o file.
**as well as determines the start of the __TEXT segment and __TEXT,__text sections
**/
int locate_symbols(void* kernelData)
if(((struct mach_header*)kernelData)->magic != MH_MAGIC) return KERNEL_64;
//printf("%d load commands beginning at 0x%X\n", (unsigned int)header->ncmds, (unsigned int)kernelIndex);
//printf("Commands take up %d bytes\n", header->sizeofcmds);
int cmd = 0;
while(cmd < ((struct mach_header*)kernelData)->ncmds)// TODO: for loop instead
{
UInt cmdSize = loadCommand->cmdsize;
// Locate start of _panic and _cpuid_set_info in the symbol tabe.
// Load commands should be anded with 0x7FFFFFFF to ignore theLC_REQ_DYLD flag
if((loadCommand->cmd & 0x7FFFFFFF) == LC_SYMTAB)// We only care about the symtab segment
{
//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);
cmdSize -= sizeof(struct symtab_command);
// Loop through symbol table untill all of the symbols have been found
symbolString = kernelData + symtableData->stroff;
//UInt16 symbolIndex = 0;
//UInt8 numSymbolsFound = 0;
/*while(symbolIndex < symtableData->nsyms && numSymbolsFound < NUM_SYMBOLS)// TODO: for loop
{
int i = 0;
while(i < NUM_SYMBOLS)
{
if(strcmp(symbolString, kernelSymbols[i]) == 0)
{
symbolIndexes[i] = symbolIndex;
numSymbolsFound++;
}
i++;
}
symbolString += strlen(symbolString) + 1;
symbolIndex++;
}
// loop again
symbolIndex = 0;
numSymbolsFound = 0;
while(symbolIndex < symtableData->nsyms && numSymbolsFound < NUM_SYMBOLS)// TODO: for loop
{
symbolEntry = kernelData + symtableData->symoff + (symbolIndex * sizeof(struct nlist));
int i = 0;
while(i < NUM_SYMBOLS)
{
if(symbolIndex == (symbolIndexes[i] - 4))
{
kernelSymbolAddresses[i] = (UInt32)symbolEntry->n_value;
numSymbolsFound++;
}
i++;
}
symbolIndex ++;
}
*/
// Load commands should be anded with 0x7FFFFFFF to ignore theLC_REQ_DYLD flag
} else if((loadCommand->cmd & 0x7FFFFFFF) == LC_SEGMENT)// We only care about the __TEXT segment, any other load command can be ignored
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;
}
}
return KERNEL_32;
printf("Parseing symtabl.\n");
handle_symtable((UInt32)kernelData, symtableData, &symbol_handler);
getc();
}
void* symbol_handler(char* symbolName, void* addr)
{
// Locate the symbol in the list, if it exists, update it's address
kernSymbols_t *symbol = lookup_kernel_symbol(symbolName);
if(symbol)
{
printf("Located registered symbol %s at 0x%X\n", symbolName, addr);
getc();
symbol->addr = (UInt32)addr;
}
return (void*)0xFFFFFFFF;
}
/**
** Locate the fisrt instance of _panic inside of _cpuid_set_info, and either remove it
** Or replace it so that the cpuid is set to a valid value.
**/
void patch_cpuid_set_info(void* kernelData, UInt32 impersonateFamily, UInt8 impersonateModel)
void patch_cpuid_set_info(void* kernelData/*, UInt32 impersonateFamily, UInt8 impersonateModel*/)
{
printf("patch_cpuid_set_info\n");
getc();
UInt32 impersonateFamily = 0;
UInt8 impersonateModel = 0;
UInt8* bytes = (UInt8*)kernelData;
UInt32 patchLocation = (UInt32)lookup_kernel_symbol("_cpuid_set_info");
//(kernelSymbolAddresses[SYMBOL_CPUID_SET_INFO] - textAddress + textSection);
kernSymbols_t *symbol = lookup_kernel_symbol("_cpuid_set_info");
UInt32 patchLocation = symbol ? symbol->addr : 0; //(kernelSymbolAddresses[SYMBOL_CPUID_SET_INFO] - textAddress + textSection);
UInt32 jumpLocation = 0;
UInt32 panicAddr = (UInt32)lookup_kernel_symbol("_panic");
//kernelSymbolAddresses[SYMBOL_PANIC] - textAddress;
symbol = lookup_kernel_symbol("_panic");
UInt32 panicAddr = symbol ? symbol->addr : 0; //kernelSymbolAddresses[SYMBOL_PANIC] - textAddress;
if(patchLocation == 0)
{
printf("Unable to locate _cpuid_set_info\n");
**/
void patch_pmCPUExitHaltToOff(void* kernelData)
{
printf("patch_pmCPUExitHaltToOff\n");
getc();
UInt8* bytes = (UInt8*)kernelData;
UInt32 patchLocation = lookup_kernel_symbol("_PmCpuExitHaltToOff"); // verify
//(kernelSymbolAddresses[SYMBOL_PMCPUEXITHALTTOOFF] - textAddress + textSection);
kernSymbols_t *symbol = lookup_kernel_symbol("_PmCpuExitHaltToOff");
UInt32 patchLocation = symbol ? symbol->addr : 0; //(kernelSymbolAddresses[SYMBOL_PMCPUEXITHALTTOOFF] - textAddress + textSection);
if(patchLocation == 0)
{
void patch_lapic_init(void* kernelData)
{
printf("patch_lapic_init\n");
getc();
UInt8 panicIndex = 0;
UInt8* bytes = (UInt8*)kernelData;
UInt32 patchLocation = 0x00; // (kernelSymbolAddresses[SYMBOL_LAPIC_INIT] - textAddress + textSection);
UInt32 panicAddr = 0x00; //kernelSymbolAddresses[SYMBOL_PANIC] - textAddress;
kernSymbols_t *symbol = lookup_kernel_symbol("_lapic_init");
UInt32 patchLocation = symbol ? symbol->addr : 0;
// (kernelSymbolAddresses[SYMBOL_LAPIC_INIT] - textAddress + textSection);
// kernelSymbolAddresses[SYMBOL_PANIC] - textAddress;
symbol = lookup_kernel_symbol("_panic");
UInt32 panicAddr = symbol ? symbol->addr : 0;
//if(kernelSymbolAddresses[SYMBOL_LAPIC_INIT] == 0)
if(patchLocation == 0)
{
//printf("Unable to locate %s\n", SYMBOL_LAPIC_INIT_STRING);
printf("Unable to locate %s\n", "_lapic_init");
return;
}
//if(kernelSymbolAddresses[SYMBOL_PANIC] == 0)
if(panicAddr == 0)
{
//printf("Unable to locate %s\n", SYMBOL_PANIC_STRING);
printf("Unable to locate %s\n", "_panic");
return;
}
void patch_commpage_stuff_routine(void* kernelData)
{
printf("patch_commpage_stuff_routine\n");
getc();
UInt8* bytes = (UInt8*)kernelData;
UInt32 patchLocation = 0x00; // (kernelSymbolAddresses[SYMBOL_COMMPAGE_STUFF_ROUTINE] - textAddress + textSection);
UInt32 panicAddr = 0x00;// kernelSymbolAddresses[SYMBOL_PANIC] - textAddress;
kernSymbols_t *symbol = lookup_kernel_symbol("_commpage_stuff_routine");
UInt32 patchLocation = symbol ? symbol->addr : 0;
// (kernelSymbolAddresses[SYMBOL_COMMPAGE_STUFF_ROUTINE] - textAddress + textSection);
// kernelSymbolAddresses[SYMBOL_PANIC] - textAddress;
symbol = lookup_kernel_symbol("_panic");
UInt32 panicAddr = symbol ? symbol->addr : 0;
//if(kernelSymbolAddresses[SYMBOL_COMMPAGE_STUFF_ROUTINE] == 0)
{
//printf("Unable to locate %s\n", SYMBOL_COMMPAGE_STUFF_ROUTINE_STRING);
branches/meklort/i386/modules/KernelPatcher/kernel_patcher.h
2424
2525
2626
27
2728
28
2929
3030
31
31
3232
3333
3434
......
3838
3939
4040
41
41
4242
4343
4444
45
45
46
4647
47
48
49
4850
4951
5052
5153
52
54
5355
54
55
56
56
57
58
59
5760
5861
5962
#define KERNEL_ANY0x00
#define KERNEL_640x01
#define KERNEL_320x02
#define KERNEL_ERR0xFF
typedef struct patchRoutine_t
{
void* patchRoutine;
void(*patchRoutine)(void*);
int validArchs;
int validCpu;
struct patchRoutine_t* next;
typedef struct kernSymbols_t
{
char* symbol;
void* symbolAddress;
UInt64 addr;
struct kernSymbols_t* next;
} kernSymbols_t;
void* lookup_kernel_symbol(const char* name);
kernSymbols_t* lookup_kernel_symbol(const char* name);
void register_kernel_symbol(int kernelType, const char* name);
void patch_kernel(void* kernelData);
void* symbol_handler(char* symbol, void* addr);
void patch_kernel(void* kernelData, void* arg2, void* arg3, void *arg4);
void register_kernel_patch(void* patch, int arch, int cpus);
int locate_symbols(void* kernelData);
void patch_kernel_32(void* kernelData);
int determineKernelArchitecture(void* kernelData);
void patch_cpuid_set_info(void* kernelData, UInt32 impersonateFamily, UInt8 inpersonateModel);
/*
* Internal patches provided by this module.
*/
void patch_cpuid_set_info(void* kernelData);
void patch_pmCPUExitHaltToOff(void* kernelData);
void patch_lapic_init(void* kernelData);
void patch_commpage_stuff_routine(void* kernelData);

Archive Download the corresponding diff file

Revision: 439