Chameleon

Chameleon Commit Details

Date:2010-05-09 06:18:50 (9 years 1 month ago)
Author:Evan Lojewski
Commit:146
Parents: 145
Message:Updated kernel patch for unknown cpuid's. Now sets the cpuid_model and cpuidfamily variables to Penryn, TODO: make configurable
Changes:
M/branches/meklort/i386/boot2/kernel_patcher.c

File differences

branches/meklort/i386/boot2/kernel_patcher.c
220220
221221
222222
223
223224
224225
225226
......
236237
237238
238239
239
240
240
241
241242
242
243
244
243
245244
246245
247
248246
249247
248
250249
251
252
253
250
251
252
253
254
254255
255256
256257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
257315
258316
259317
{
UInt8* bytes = (UInt8*)kernelData;
UInt32 patchLocation = (kernelSymbolAddresses[SYMBOL_CPUID_SET_INFO] - textAddress + textSection);
UInt32 jumpLocation = 0;
UInt32 panidAddr = kernelSymbolAddresses[SYMBOL_PANIC] - textAddress;
if(kernelSymbolAddresses[SYMBOL_CPUID_SET_INFO] == 0)
{
//TODO: don't assume it'll always work (Look for *next* function address in symtab and fail once it's been reached)
while(
(bytes[patchLocation -1] != 0xE8) ||
( ( (UInt32)(panidAddr - patchLocation - 4) + textSection ) != (UInt32)((bytes[patchLocation] |
bytes[patchLocation + 1] << 8 |
( ( (UInt32)(panidAddr - patchLocation - 4) + textSection ) != (UInt32)((bytes[patchLocation + 0] << 0 |
bytes[patchLocation + 1] << 8 |
bytes[patchLocation + 2] << 16 |
bytes[patchLocation + 3] << 24))) //&&
// (patchLocation < maxLocation)// max location is not known... assuming there is a panic call somewhere after cpuid_set_info
bytes[patchLocation + 3] << 24)))
)
{
//printf("Looking at 0x%X\n", patchLocation);
patchLocation++;
}
patchLocation--;
// repace with nops
bytes[patchLocation - 1] = 0x90;
bytes[patchLocation ] = 0x90;
/*
// repace with nops to disable the panic call
Old patch, nolonger used. This is a safer patch than before, however
the new patch allows the native pm kext to load without any extra kexts
bytes[patchLocation] = 0x90;
bytes[patchLocation + 1] = 0x90;
bytes[patchLocation + 2] = 0x90;
bytes[patchLocation + 3] = 0x90;
bytes[patchLocation + 4] = 0x90;
*/
// Locate a JMP to patchLocation - sizeof(mov) + 2 (aka 8)
// ... NOTE: can *ONLY* be up to 0xFF - 8 bytes aways
jumpLocation = patchLocation - 15;
while((bytes[jumpLocation - 1] != 0x77 ||
bytes[jumpLocation] != (patchLocation - jumpLocation - -8)) &&
(patchLocation - jumpLocation) < 0xEF)
{
jumpLocation--;
}
// If found... (not the end of the world if it isn't found, the panic is removed either way.
// But if it isn't found, then IntelCPUPM.kext might panic if an unknown cpu (atom)
// Jump to patchLocation - 17
if((patchLocation - jumpLocation) < 0xEF) bytes[jumpLocation] -= 10; // sizeof(movl$0x6b5a4cd2,0x00872eb4)
// bytes[patchLocation - 17] = 0xC7;// already here... not needed to be done
// bytes[patchLocation - 16] = 0x05;// see above
UInt32 cpuid_cpufamily_addr =bytes[patchLocation - 15] << 0 |
bytes[patchLocation - 14] << 8 |
bytes[patchLocation - 13] << 16 |
bytes[patchLocation - 12] << 24;
// NOTE: may change, determined based on cpuid_info struct
UInt32 cpuid_model_addr = cpuid_cpufamily_addr - 299;
// cpufamily = CPUFAMILY_INTEL_PENRYN
bytes[patchLocation - 11] = (CPUFAMILY_INTEL_PENRYN & 0x000000FF) >> 0;
bytes[patchLocation - 10] = (CPUFAMILY_INTEL_PENRYN & 0x0000FF00) >> 8;
bytes[patchLocation - 9] = (CPUFAMILY_INTEL_PENRYN & 0x00FF0000) >> 16;
bytes[patchLocation - 8] = (CPUFAMILY_INTEL_PENRYN & 0xFF000000) >> 24;
// NOPS, just in case if the jmp call wasn't patched, we'll jump to a
// nop and continue with the rest of the patch
// Yay two free bytes :), 10 more can be reclamed if needed, as well as a few
// from the above code (only cpuid_model needs to be set.
bytes[patchLocation - 7] = 0x90;
bytes[patchLocation - 6] = 0x90;
bytes[patchLocation - 5] = 0xC7;
bytes[patchLocation - 4] = 0x05;
bytes[patchLocation - 3] = (cpuid_model_addr & 0x000000FF) >> 0;
bytes[patchLocation - 2] = (cpuid_model_addr & 0x0000FF00) >> 8;
bytes[patchLocation - 1] = (cpuid_model_addr & 0x00FF0000) >> 16;
bytes[patchLocation - 0] = (cpuid_model_addr & 0xFF000000) >> 24;
// Note: I could have just copied the 8bit cpuid_model in and saved about 4 bytes
// so if this function need a different patch it's still possible. Also, about ten bytes previous can be freed.
bytes[patchLocation + 1] = 0x17;// cpuid_model
bytes[patchLocation + 2] = 0x01;// cpuid_extmodel
bytes[patchLocation + 3] = 0x00;// cpuid_extfamily
bytes[patchLocation + 4] = 0x02;// cpuid_stepping
}

Archive Download the corresponding diff file

Revision: 146