patchRoutine_t* patches = NULL;␊ |
kernSymbols_t* kernelSymbols = NULL;␊ |
␊ |
void kernel_patcher_ignore_cache(void* arg1, void* arg2, void* arg3, void *arg4, void* arg5, void* arg6){}␊ |
␊ |
void KernelPatcher_start()␊ |
{␊ |
|
␉// NOTE: following is currently 32bit only␊ |
␉register_kernel_patch(patch_lapic_configure, KERNEL_32, CPUID_MODEL_ANY);␊ |
␊ |
␉␊ |
␉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_configure");␊ |
␉register_kernel_symbol(KERNEL_ANY, "_lapic_start");␊ |
␉register_kernel_symbol(KERNEL_ANY, "_lapic_interrupt_base");␊ |
␉␊ |
␊ |
␉// lapic_interrup symbols␊ |
␉//register_kernel_patch(patch_lapic_interrupt, KERNEL_ANY, CPUID_MODEL_ANY);␊ |
␉//register_kernel_symbol(KERNEL_ANY, "_lapic_interrupt");␊ |
␊ |
␊ |
␉␊ |
␉// TODO: register needed symbols␊ |
␉␊ |
␉␊ |
␊ |
␉register_hook_callback("ExecKernel", &patch_kernel); ␊ |
␉␊ |
␉replace_function("_getKernelCachePath", &kernel_patcher_ignore_cache);␊ |
}␊ |
␊ |
/*␊ |
|
␉␉␉{␊ |
␉␉␉␉switch(Platform->CPU.Model)␊ |
␉␉␉␉{␊ |
␉␉␉␉␉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:␊ |
␉␉␉␉␉case CPU_MODEL_PENTIUM_M:␊ |
␉␉␉␉␉case CPU_MODEL_YONAH:␊ |
␉␉␉␉␉case CPU_MODEL_MEROM:␊ |
␉␉␉␉␉case CPU_MODEL_PENRYN:␊ |
␉␉␉␉␉case CPU_MODEL_NEHALEM:␊ |
␉␉␉␉␉case CPU_MODEL_FIELDS:␊ |
␉␉␉␉␉case CPU_MODEL_DALES:␊ |
␉␉␉␉␉case CPU_MODEL_NEHALEM_EX:␊ |
␉␉␉␉␉␉// Known cpu's we don't want to add the patch␊ |
␉␉␉␉␉␉return;␊ |
␉␉␉␉␉␉break;␊ |
|
␉␉␉␉␉␉// CPU not in supported list, so we are going to add␊ |
␉␉␉␉␉␉// The patch will be applied␊ |
␉␉␉␉␉␉break;␊ |
␉␉␉␉␉␉␊ |
␉␉␉␉}␊ |
␉␉␉}␊ |
␉␉␉else␊ |
|
␉␉␉␉// Invalid cpuid for current cpu. Ignoring patch␊ |
␉␉␉␉return;␊ |
␉␉␉}␊ |
␊ |
␉␉}␊ |
␉}␊ |
␉␉␊ |
|
␉␉kernelSymbols->symbol = (char*)name;␊ |
␉␉kernelSymbols->addr = 0;␊ |
␉}␊ |
␉else {␊ |
␉else␊ |
␉{␊ |
␉␉kernSymbols_t *symbol = kernelSymbols;␊ |
␉␉while(symbol->next != NULL)␊ |
␉␉{␊ |
|
␉{␊ |
␉␉return symbol;␊ |
␉}␊ |
␊ |
}␊ |
␊ |
void patch_kernel(void* kernelData, void* arg2, void* arg3, void *arg4)␊ |
{␊ |
␉patchRoutine_t* entry = patches;␊ |
␊ |
␉␊ |
␉int arch = determineKernelArchitecture(kernelData);␊ |
␊ |
␉locate_symbols(kernelData);␊ |
|
␉{␊ |
␉␉return KERNEL_32;␊ |
␉}␊ |
␊ |
␉if(((struct mach_header*)kernelData)->magic == MH_MAGIC_64)␊ |
␉{␊ |
␉␉return KERNEL_64;␊ |
|
␉}␊ |
}␊ |
␊ |
␊ |
/**␊ |
**␉␉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)␊ |
{␊ |
␉char is64 = 1;␊ |
␉parse_mach(kernelData, NULL, symbol_handler);␊ |
␉parse_mach(kernelData, NULL, symbol_handler, NULL);␊ |
␉//handle_symtable((UInt32)kernelData, symtableData, &symbol_handler, determineKernelArchitecture(kernelData) == KERNEL_64);␊ |
␉return 1 << is64;␊ |
␉return 1ull << is64;␊ |
}␊ |
␊ |
long long symbol_handler(char* symbolName, long long addr, char is64)␊ |
|
␉return 0xFFFFFFFF; // fixme␊ |
}␊ |
␊ |
␊ |
/**␊ |
** 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.␊ |
|
{␊ |
␉switch(Platform->CPU.Model)␊ |
␉{␊ |
␉␉case CPUID_MODEL_ATOM:␊ |
␉␉case CPU_MODEL_ATOM:␊ |
␉␉␉if(determineKernelArchitecture(kernelData) == KERNEL_32)␊ |
␉␉␉{␊ |
␉␉␉␉patch_cpuid_set_info_32(kernelData, CPUFAMILY_INTEL_PENRYN, CPUID_MODEL_PENRYN); ␊ |
␉␉␉␉patch_cpuid_set_info_32(kernelData, CPUFAMILY_INTEL_PENRYN, CPU_MODEL_PENRYN);␊ |
␉␉␉}␊ |
␉␉␉else ␊ |
␉␉␉{␊ |
␉␉␉␉patch_cpuid_set_info_64(kernelData, CPUFAMILY_INTEL_PENRYN, CPUID_MODEL_PENRYN); ␊ |
␊ |
␉␉␉␉patch_cpuid_set_info_64(kernelData, CPUFAMILY_INTEL_PENRYN, CPU_MODEL_PENRYN);␊ |
␉␉␉}␊ |
␊ |
␉␉␉break;␊ |
␉␉␉␊ |
␊ |
␉␉default:␊ |
␉␉␉if(determineKernelArchitecture(kernelData) == KERNEL_32)␊ |
␉␉{␊ |
␉␉␉// AnV: Extra cpuid fix for spoofing Nehalem CPU for i5/i9␊ |
␉␉␉switch(Platform->CPU.Family)␊ |
␉␉␉{␊ |
␉␉␉␉patch_cpuid_set_info_32(kernelData, 0, 0);␊ |
␉␉␉␉case CPU_MODEL_FIELDS: /* Intel i5 */␊ |
␉␉␉␉case CPU_MODEL_WESTMERE: /* Intel i9 */␊ |
␉␉␉␉␉if(determineKernelArchitecture(kernelData) == KERNEL_32)␊ |
␉␉␉␉␉{␊ |
␉␉␉␉␉␉patch_cpuid_set_info_32(kernelData, CPUFAMILY_INTEL_NEHALEM, CPU_MODEL_NEHALEM);␊ |
␉␉␉␉␉}␊ |
␉␉␉␉␉else ␊ |
␉␉␉␉␉{␊ |
␉␉␉␉␉␉patch_cpuid_set_info_64(kernelData, CPUFAMILY_INTEL_NEHALEM, CPU_MODEL_NEHALEM);␊ |
␉␉␉␉␉}␊ |
␉␉␉␉␉␊ |
␉␉␉␉␉break;␊ |
␉␉␉␉␊ |
␉␉␉␉default:␊ |
␉␉␉␉␉if(determineKernelArchitecture(kernelData) == KERNEL_32)␊ |
␉␉␉␉␉{␊ |
␉␉␉␉␉␉patch_cpuid_set_info_32(kernelData, 0, 0);␊ |
␉␉␉␉␉}␊ |
␉␉␉␉␉else␊ |
␉␉␉␉␉{␊ |
␉␉␉␉␉␉patch_cpuid_set_info_64(kernelData, 0, 0);␊ |
␉␉␉␉␉}␉␉␉␉␉␊ |
␉␉␉␉␉break;␊ |
␉␉␉}␊ |
␉␉␉else␊ |
␉␉␉{␊ |
␉␉␉␉patch_cpuid_set_info_64(kernelData, 0, 0);␊ |
␉␉␉}␊ |
␊ |
␉␉␉break;␊ |
␉␉␉break;␉␉␉␊ |
␉␉}␊ |
␉}␊ |
}␊ |
␊ |
void patch_cpuid_set_info_64(void* kernelData, UInt32 impersonateFamily, UInt8 impersonateModel)␊ |
{␊ |
␉UInt8* bytes = (UInt8*)kernelData;␊ |
|
␉␊ |
␉UInt32 patchLocation = symbol ? symbol->addr - textAddress + textSection: 0; //␉(kernelSymbolAddresses[SYMBOL_CPUID_SET_INFO] - textAddress + textSection);␊ |
␉patchLocation -= (UInt32)kernelData;␉// Remove offset␊ |
␉␊ |
␉␊ |
␉␊ |
␊ |
␉//UInt32 jumpLocation = 0;␊ |
␉␊ |
␉␊ |
␊ |
␉if(symbol == 0 || symbol->addr == 0)␊ |
␉{␊ |
␉␉verbose("Unable to locate _cpuid_set_info\n");␊ |
␉␉return;␊ |
␉␉␊ |
␉}␊ |
␉␊ |
␉symbol = lookup_kernel_symbol("_panic");␊ |
␉UInt32 panicAddr = symbol ? symbol->addr - textAddress: 0; //kernelSymbolAddresses[SYMBOL_PANIC] - textAddress;␊ |
␉if(symbol == 0 || symbol->addr == 0)␊ |
␉{␊ |
␉␉verbose("Unable to locate _panic\n");␊ |
␉␉printf("Unable to locate _panic\n");␊ |
␉␉return;␊ |
␉}␊ |
␉panicAddr -= (UInt32)kernelData;␊ |
␉␊ |
␉␊ |
␉␊ |
␊ |
␉//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) ||␊ |
|
␉␉patchLocation++;␊ |
␉}␊ |
␉patchLocation--;␊ |
␉␊ |
␊ |
␉// Remove panic just in ca se␊ |
␉// The panic instruction is exactly 5 bytes long.␊ |
␉bytes[patchLocation + 0] = 0x90;␊ |
|
␉bytes[patchLocation + 2] = 0x90;␊ |
␉bytes[patchLocation + 3] = 0x90;␊ |
␉bytes[patchLocation + 4] = 0x90;␊ |
␉␊ |
␉␊ |
␉␊ |
␊ |
␉// Check for a 10.2.0+ kernel␊ |
␉if(bytes[patchLocation - 19] == 0xC7 && bytes[patchLocation - 18] == 0x05)␊ |
␉{␊ |
␉␉␊ |
␉␉UInt32 cpuid_cpufamily_addr =␉bytes[patchLocation - 17] << 0 |␊ |
␉␉␉␉␉␉␉␉␉␉bytes[patchLocation - 16] << 8 |␊ |
␉␉␉␉␉␉␉␉␉␉bytes[patchLocation - 15] << 16 |␊ |
|
␉␉␊ |
␉␉// NOTE: may change, determined based on cpuid_info struct␊ |
␉␉UInt32 cpuid_model_addr = cpuid_cpufamily_addr - 310; ␊ |
␉␉␊ |
␉␉␊ |
␊ |
␉␉//ffffff8000228b3b -> 0x00490e8b␊ |
␉␉//ffffff8000228c28 -> -237 -> 0x490D9E -> -310␊ |
␉␉␊ |
␉␉␊ |
␊ |
␉␉// The mov is 10 bytes␊ |
␉␉/*␊ |
␉␉ bytes[patchLocation - 19] = 0x90;␉// c7␊ |
|
␉␉bytes[patchLocation - 12] = (impersonateFamily & 0x0000FF00) >> 8;␊ |
␉␉bytes[patchLocation - 11] = (impersonateFamily & 0x00FF0000) >> 16;␉␊ |
␉␉bytes[patchLocation - 10] = (impersonateFamily & 0xFF000000) >> 24;␊ |
␉␉␊ |
␉␉␊ |
␊ |
␉␉// The lea (%rip),%rip is 7 bytes␊ |
␉␉bytes[patchLocation - 9] = 0xC7;␊ |
␉␉bytes[patchLocation - 8] = 0x05;␊ |
|
␉␉bytes[patchLocation - 5] = ((cpuid_model_addr -10) & 0x00FF0000) >> 16;␊ |
␉␉bytes[patchLocation - 4] = ((cpuid_model_addr -10) & 0xFF000000) >> 24;␊ |
␉␉bytes[patchLocation - 3] = impersonateModel;␉// cpuid_model␊ |
␉␉␊ |
␉␉ ␊ |
␉␉ ␊ |
␉␉ // The xor eax eax is 2 bytes␊ |
␊ |
␉␉// The xor eax eax is 2 bytes␊ |
␉␉bytes[patchLocation - 2] = 0x01;␉// cpuid_extmodel␊ |
␉␉bytes[patchLocation - 1] = 0x00;␉// cpuid_extfamily␊ |
␉␉␊ |
|
␉␉␊ |
␉␉// Total: 24 bytes␊ |
␉␉verbose("Running on a 10.2.0+ kernel\n");␊ |
␉␉getc();␊ |
␊ |
//␉␉getchar();␊ |
␉}␊ |
␉else {␊ |
␉␉verbose("Running on a 10.0.0 kernel, patch unsupported\n");␊ |
␉␉getc();␊ |
␉␉printf("Running on a 10.0.0 kernel, patch unsupported\n");␊ |
␉␉pause();␊ |
␉}␊ |
␊ |
␉␊ |
}␊ |
␊ |
␊ |
␊ |
␊ |
␊ |
void patch_cpuid_set_info_32(void* kernelData, UInt32 impersonateFamily, UInt8 impersonateModel)␊ |
{␊ |
{␉␊ |
␉UInt8* bytes = (UInt8*)kernelData;␊ |
␉␊ |
␉kernSymbols_t *symbol = lookup_kernel_symbol("_cpuid_set_info");␊ |
␊ |
␉UInt32 patchLocation = symbol ? symbol->addr - textAddress + textSection: 0; //␉(kernelSymbolAddresses[SYMBOL_CPUID_SET_INFO] - textAddress + textSection);␊ |
␉patchLocation -= (UInt32)kernelData;␉// Remove offset␊ |
␉UInt32 addrLocation = patchLocation;␊ |
␉␊ |
␊ |
␉UInt32 jumpLocation = 0;␊ |
␉␊ |
␉␊ |
␉UInt32 jumpLocation = 0;␉␊ |
␊ |
␉if(symbol == 0 || symbol->addr == 0)␊ |
␉{␊ |
␉␉verbose("Unable to locate _cpuid_set_info\n");␊ |
␉␉return;␊ |
␉␉␊ |
␉}␊ |
␊ |
␉symbol = lookup_kernel_symbol("_panic");␊ |
␉UInt32 panicAddr = symbol ? symbol->addr - textAddress: 0; //kernelSymbolAddresses[SYMBOL_PANIC] - textAddress;␊ |
␉if(symbol == 0 || symbol->addr == 0)␊ |
␉{␊ |
␉␉verbose("Unable to locate _panic\n");␊ |
␉␉printf("Unable to locate _panic\n");␊ |
␉␉return;␊ |
␉}␊ |
␉panicAddr -= (UInt32)kernelData;␊ |
␊ |
␉␊ |
␊ |
␉//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) ||␊ |
|
␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉bytes[patchLocation + 1] << 8 | ␊ |
␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉bytes[patchLocation + 2] << 16 |␊ |
␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉bytes[patchLocation + 3] << 24)))␊ |
␉␉ )␊ |
␉␉ )␊ |
␉{␊ |
␉␉patchLocation++;␊ |
␉}␊ |
|
␉bytes[patchLocation + 2] = 0x90;␊ |
␉bytes[patchLocation + 3] = 0x90;␊ |
␉bytes[patchLocation + 4] = 0x90;␊ |
␉␊ |
␉␊ |
␊ |
␉// Locate the jump call, so that 10 bytes can be reclamed.␊ |
␉// NOTE: This will *NOT* be located on pre 10.6.2 kernels␊ |
␉jumpLocation = patchLocation - 15;␊ |
␉while((bytes[jumpLocation - 1] != 0x77 ||␊ |
␉␉ bytes[jumpLocation] != (patchLocation - jumpLocation - 18)) &&␊ |
␉␉ bytes[jumpLocation] != (patchLocation - jumpLocation - -8)) &&␊ |
␉␉ (patchLocation - jumpLocation) < 0xF0)␊ |
␉{␊ |
␉␉jumpLocation--;␊ |
␉}␊ |
␉␊ |
␉// If found... AND we want to impersonate a specific cpumodel / family...␊ |
␉if(impersonateFamily && impersonateModel &&␊ |
␉if(impersonateFamily &&␊ |
␉ impersonateModel &&␊ |
␉ ((patchLocation - jumpLocation) < 0xF0))␊ |
␉{␊ |
␉␉␊ |
␉␉bytes[jumpLocation] -= 10;␉␉// sizeof(movl␉$0x6b5a4cd2,0x00872eb4) = 10bytes␊ |
␉␉␊ |
␉␉/* ␊ |
␉␉ * Inpersonate the specified CPU FAMILY and CPU Model␊ |
␉␉ */␊ |
␉␉//␉␉␉␉␉␉␉␉␉cpuid_cpufamily_addr, impersonateFamily␉␉␉␉␉␉␉␉␉cpuid_model_addr␉ impersonateModel␊ |
␉␉//char new_bytes[] = {0xC7, 0x05, 0x__, 0x__, 0x__, 0x__, 0x__, 0x__, 0x__, 0x__, 0x90, 0x90, 0xC7, 0x05, 0x__, 0x__, 0x__, 0x__, 0x__, 0x01, 0x00, 0x02};␊ |
␉␉␊ |
␉␉// 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;␊ |
␉␉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: TODO: read from binary␊ |
␉␉//UInt32 cpuid_model_addr = cpuid_cpufamily_addr - 295; ␊ |
␉␉␊ |
␉␉␊ |
␉␉// NOTE: may change, determined based on cpuid_info struct␊ |
␉␉UInt32 cpuid_model_addr = cpuid_cpufamily_addr - 299; ␊ |
␊ |
␉␉// cpufamily␊ |
␉␉bytes[patchLocation - 11] = (impersonateFamily & 0x000000FF) >> 0;␊ |
␉␉bytes[patchLocation - 10] = (impersonateFamily & 0x0000FF00) >> 8;␊ |
|
␉␉␊ |
␉␉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;␊ |
␉␉␊ |
␉␉// Locate cpuid_addr_addr -> first four bytes after 8b 45 d8 25 f0 00 00 00 c1 e8 04 a2␊ |
␉␉while(bytes[addrLocation -12] != 0x8B ||␊ |
␉␉␉ bytes[addrLocation -11] != 0x45 ||␊ |
␉␉␉ bytes[addrLocation -10] != 0xD8 ||␊ |
␉␉␉ bytes[addrLocation -9] != 0x25 ||␊ |
␉␉␉ bytes[addrLocation -8] != 0xF0 ||␊ |
␉␉␉ bytes[addrLocation -7] != 0x00 ||␊ |
␉␉␉ bytes[addrLocation -6] != 0x00 ||␊ |
␉␉␉ bytes[addrLocation -5] != 0x00 ||␊ |
␉␉␉ bytes[addrLocation -4] != 0xC1 ||␊ |
␉␉␉ bytes[addrLocation -3] != 0xE8 ||␊ |
␉␉␉ bytes[addrLocation -2] != 0x04 ||␊ |
␉␉␉ bytes[addrLocation -1] != 0xA2)␊ |
␉␉{␊ |
␉␉␉// TODO: break if location is too large␊ |
␉␉␉addrLocation++;␊ |
␉␉}␉␉␊ |
␉␉␊ |
␉␉bytes[patchLocation - 3] = bytes[addrLocation];␊ |
␉␉bytes[patchLocation - 2] = bytes[addrLocation+1];␉␊ |
␉␉bytes[patchLocation - 1] = bytes[addrLocation+2];␊ |
␉␉bytes[patchLocation - 0] = bytes[addrLocation+3];␊ |
␉␉␊ |
␉␉// 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] = impersonateModel;␉// cpuid_model␊ |
␉␉bytes[patchLocation + 2] = 0x01;␉// cpuid_extmodel␊ |
␉␉bytes[patchLocation + 3] = 0x00;␉// cpuid_extfamily␊ |
␉␉bytes[patchLocation + 4] = 0x02;␉// cpuid_stepping␉␉␊ |
␉␉bytes[patchLocation + 4] = 0x02;␉// cpuid_stepping␊ |
␉}␊ |
␉else if(impersonateFamily && impersonateModel)␊ |
␉{␊ |
␊ |
␉␉// pre 10.6.2 kernel␊ |
␉␉// Locate the jump to directly *after* the panic call,␊ |
␉␉jumpLocation = patchLocation - 4;␊ |
|
␉␉␉bytes[patchLocation + 2] = 0x01;␉// cpuid_extmodel␊ |
␉␉␉bytes[patchLocation + 3] = 0x00;␉// cpuid_extfamily␊ |
␉␉␉bytes[patchLocation + 4] = 0x02;␉// cpuid_stepping␊ |
␉␉␉␊ |
␉␉␉␊ |
␉␉␉␊ |
␉␉␉//patchLocation = jumpLocation;␊ |
␉␉␉// We now have 14 bytes available for a patch␊ |
␊ |
␉␉␉patchLocation = jumpLocation;␊ |
␉␉␉// We now have 14 bytes available for a patch␊ |
␉␉}␊ |
␉␉else ␊ |
␉␉{␊ |
|
␉}␊ |
}␊ |
␊ |
␊ |
/**␊ |
** SleepEnabler.kext replacement (for those that need it)␊ |
** Located the KERN_INVALID_ARGUMENT return and replace it with KERN_SUCCESS␊ |
|
␉␊ |
␉if(symbol == 0 || symbol->addr == 0)␊ |
␉{␊ |
␉␉verbose("Unable to locate _pmCPUExitHaltToOff\n");␊ |
␉␉printf("Unable to locate _pmCPUExitHaltToOff\n");␊ |
␉␉return;␊ |
␉}␊ |
␉␊ |
␉patchLocation -= (UInt32)kernelData;␉// Remove offset␊ |
␉␊ |
␉␊ |
␉␊ |
␊ |
␉while(bytes[patchLocation - 1]␉!= 0xB8 ||␊ |
␉␉ bytes[patchLocation]␉␉!= 0x04 ||␉// KERN_INVALID_ARGUMENT (0x00000004)␊ |
␉␉ bytes[patchLocation + 1]␉!= 0x00 ||␉// KERN_INVALID_ARGUMENT␊ |
|
␉UInt32 patchLocation = symbol ? symbol->addr - textAddress + textSection: 0; ␊ |
␉if(symbol == 0 || symbol->addr == 0)␊ |
␉{␊ |
␉␉verbose("Unable to locate %s\n", "_lapic_init");␊ |
␉␉printf("Unable to locate %s\n", "_lapic_init");␊ |
␉␉return;␊ |
␉␉␊ |
␉}␊ |
␉␊ |
␉symbol = lookup_kernel_symbol("_panic");␊ |
␉UInt32 panicAddr = symbol ? symbol->addr - textAddress: 0; ␊ |
␉if(symbol == 0 || symbol->addr == 0)␊ |
␉{␊ |
␉␉verbose("Unable to locate %s\n", "_panic");␊ |
␉␉printf("Unable to locate %s\n", "_panic");␊ |
␉␉return;␊ |
␉}␊ |
␉␊ |
␉patchLocation -= (UInt32)kernelData;␉// Remove offset␊ |
␉panicAddr -= (UInt32)kernelData;␉// Remove offset␊ |
␊ |
␉␊ |
␉␊ |
␉␊ |
␉// Locate the (panicIndex + 1) panic call␊ |
␉while(panicIndex < 3)␉// Find the third panic call␊ |
␉{␊ |
|
␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉bytes[patchLocation + 1] << 8 | ␊ |
␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉bytes[patchLocation + 2] << 16 |␊ |
␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉bytes[patchLocation + 3] << 24)))␊ |
␉␉␉ )␊ |
␉␉␉ )␊ |
␉␉{␊ |
␉␉␉patchLocation++;␊ |
␉␉}␊ |
|
␉bytes[++patchLocation] = 0x90;␊ |
␉bytes[++patchLocation] = 0x90;␊ |
␉bytes[++patchLocation] = 0x90;␊ |
␉␊ |
␉␊ |
}␊ |
␊ |
␊ |
void patch_commpage_stuff_routine(void* kernelData)␊ |
{␊ |
␉UInt8* bytes = (UInt8*)kernelData;␊ |
|
␉␊ |
␉UInt32 patchLocation = symbol->addr - textAddress + textSection; ␊ |
␊ |
␉␊ |
␉symbol = lookup_kernel_symbol("_panic");␊ |
␉if(symbol == 0 || symbol->addr == 0)␊ |
␉{␊ |
␉␉verbose("Unable to locate %s\n", "_panic");␊ |
␉␉printf("Unable to locate %s\n", "_panic");␊ |
␉␉return;␊ |
␉}␊ |
␉UInt32 panicAddr = symbol->addr - textAddress; ␊ |
|
␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉bytes[patchLocation + 1] << 8 | ␊ |
␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉bytes[patchLocation + 2] << 16 |␊ |
␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉bytes[patchLocation + 3] << 24)))␊ |
␉␉ )␊ |
␉␉ )␊ |
␉{␊ |
␉␉patchLocation++;␊ |
␉}␊ |
|
␉bytes[patchLocation + 2] = 0x90;␊ |
␉bytes[patchLocation + 3] = 0x90;␊ |
␉bytes[patchLocation + 4] = 0x90;␊ |
␉␊ |
␉␊ |
}␊ |
␊ |
void patch_lapic_interrupt(void* kernelData)␊ |
{␊ |
␉// NOTE: this is a hack untill I finish patch_lapic_configure␊ |
␉UInt8* bytes = (UInt8*)kernelData;␊ |
␉␊ |
␊ |
␉kernSymbols_t *symbol = lookup_kernel_symbol("_lapic_interrupt");␊ |
␉if(symbol == 0 || symbol->addr == 0)␊ |
␉{␊ |
␉␉verbose("Unable to locate %s\n", "_lapic_interrupt");␊ |
␉␉printf("Unable to locate %s\n", "_lapic_interrupt");␊ |
␉␉return;␊ |
␉␉␊ |
␉}␊ |
␉␊ |
␊ |
␉UInt32 patchLocation = symbol->addr - textAddress + textSection; ␊ |
␉␊ |
␉␊ |
␊ |
␉symbol = lookup_kernel_symbol("_panic");␊ |
␉if(symbol == 0 || symbol->addr == 0)␊ |
␉{␊ |
␉␉verbose("Unable to locate %s\n", "_panic");␊ |
␉␉printf("Unable to locate %s\n", "_panic");␊ |
␉␉return;␊ |
␉}␊ |
␉UInt32 panicAddr = symbol->addr - textAddress; ␊ |
|
␉bytes[patchLocation + 2] = 0x90;␊ |
␉bytes[patchLocation + 3] = 0x90;␊ |
␉bytes[patchLocation + 4] = 0x90;␊ |
␉␊ |
␉␊ |
}␊ |
␊ |
␊ |
void patch_lapic_configure(void* kernelData)␊ |
{␊ |
␉UInt8* bytes = (UInt8*)kernelData;␊ |
|
␉kernSymbols_t *symbol = lookup_kernel_symbol("_lapic_configure");␊ |
␉if(symbol == 0 || symbol->addr == 0)␊ |
␉{␊ |
␉␉verbose("Unable to locate %s\n", "_lapic_configure");␊ |
␉␉printf("Unable to locate %s\n", "_lapic_configure");␊ |
␉␉return;␊ |
␉}␊ |
␉patchLocation = symbol->addr - textAddress + textSection; ␊ |
|
␉symbol = lookup_kernel_symbol("_lapic_start");␊ |
␉if(symbol == 0 || symbol->addr == 0)␊ |
␉{␊ |
␉␉verbose("Unable to locate %s\n", "_lapic_start");␊ |
␉␉printf("Unable to locate %s\n", "_lapic_start");␊ |
␉␉return;␊ |
␉}␊ |
␉lapicStart = symbol->addr; ␊ |
␊ |
␊ |
␉symbol = lookup_kernel_symbol("_lapic_interrupt_base");␊ |
␉if(symbol == 0 || symbol->addr == 0)␊ |
␉{␊ |
␉␉verbose("Unable to locate %s\n", "_lapic_interrupt_base");␊ |
␉␉printf("Unable to locate %s\n", "_lapic_interrupt_base");␊ |
␉␉return;␊ |
␉}␊ |
␉lapicInterruptBase = symbol->addr;␊ |
|
␉lapicStart -= (UInt32)kernelData;␊ |
␉lapicInterruptBase -= (UInt32)kernelData;␊ |
␉␊ |
␉␊ |
␉// Looking for the following:␊ |
␉//movl _lapic_start,%e_x␊ |
␉//addl $0x00000320,%e_x␊ |
|
␉␉␉␉␉␉␉␉␉ bytes[patchLocation + 3] << 24␊ |
␉␉␉␉␉␉␉␉␉)␊ |
␉␉␉␉␉␉␉␉ )␊ |
␉␉ ) || ␊ |
␉␉ ) || ␊ |
␉␉ (bytes[patchLocation + 4 ] != 0x81) ||␊ |
␉␉ //(bytes[patchLocation + 5 ] != 0Cx2) ||␉// register␊ |
␉␉ (bytes[patchLocation + 6 ] != 0x20) ||␊ |
|
␉bytes[patchLocation++];// = 0x00;␊ |
␉bytes[patchLocation++];// = 0x00;␊ |
␉*/␊ |
␉ patchLocation += 3;␊ |
␉patchLocation += 3;␊ |
␊ |
␉// c7 02 00 04 00 00 -> movl␉␉ $0x00000400,(%edx)␊ |
␉bytes[patchLocation++] = 0xC7;␊ |
|
␊ |
␉// Replace remaining with nops␊ |
␊ |
␊ |
␉bytes[patchLocation++] = 0x90;␊ |
␉bytes[patchLocation++] = 0x90;␊ |
␉bytes[patchLocation++] = 0x90;␊ |