Index: branches/azimutz/Chazi/doc-azi/Modules.txt =================================================================== --- branches/azimutz/Chazi/doc-azi/Modules.txt (revision 505) +++ branches/azimutz/Chazi/doc-azi/Modules.txt (revision 506) @@ -74,6 +74,8 @@ and so i did it. Of course the problem is still there and needs to be fixed, at least if one wants to be able to load modules from selected volume. + - compiling modules under Leo (XCode 3.1.4) is not possible at the moment. + ---------------//---------------//--------------- Index: branches/azimutz/Chazi/i386/modules/KernelPatcher/kernel_patcher.c =================================================================== --- branches/azimutz/Chazi/i386/modules/KernelPatcher/kernel_patcher.c (revision 505) +++ branches/azimutz/Chazi/i386/modules/KernelPatcher/kernel_patcher.c (revision 506) @@ -1,4 +1,4 @@ - /* +/* * Copyright (c) 2009-2010 Evan Lojewski. All rights reserved. * */ @@ -18,8 +18,6 @@ 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_ANY, CPUID_MODEL_UNKNOWN); register_kernel_patch(patch_commpage_stuff_routine, KERNEL_ANY, CPUID_MODEL_ANY); @@ -36,13 +34,12 @@ register_kernel_symbol(KERNEL_ANY, "_lapic_init"); register_kernel_symbol(KERNEL_ANY, "_commpage_stuff_routine"); - // LAPIC configure symbols + // lapic_configure symbols 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"); @@ -174,14 +171,14 @@ bool patchKernel = false; //Kpatcher - default value. patchRoutine_t* entry = patches; + int arch = determineKernelArchitecture(kernelData); + + locate_symbols(kernelData); + // check if kernel patcher is requested by user. getBoolForKey(kKPatcherKey, &patchKernel, &bootInfo->bootConfig); - - int arch = determineKernelArchitecture(kernelData); - locate_symbols(kernelData); - - if (patches != NULL && patchKernel) + if (patches != NULL && patchKernel == true) { while(entry) { @@ -251,21 +248,166 @@ switch(Platform.CPU.Model) { case CPUID_MODEL_ATOM: - patch_cpuid_set_info(kernelData, CPUFAMILY_INTEL_PENRYN, CPUID_MODEL_PENRYN); + if(determineKernelArchitecture(kernelData) == KERNEL_32) + { + patch_cpuid_set_info_32(kernelData, CPUFAMILY_INTEL_PENRYN, CPUID_MODEL_PENRYN); + } + else + { + patch_cpuid_set_info_64(kernelData, CPUFAMILY_INTEL_PENRYN, CPUID_MODEL_PENRYN); + + } + break; default: - patch_cpuid_set_info(kernelData, 0, 0); + if(determineKernelArchitecture(kernelData) == KERNEL_32) + { + patch_cpuid_set_info_32(kernelData, 0, 0); + } + else + { + patch_cpuid_set_info_64(kernelData, 0, 0); + } + break; } } -void patch_cpuid_set_info(void* kernelData, UInt32 impersonateFamily, UInt8 impersonateModel) +void patch_cpuid_set_info_64(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 jumpLocation = 0; + + + if(symbol == 0 || symbol->addr == 0) + { + printf("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) + { + 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) || + ( ( (UInt32)(panicAddr - patchLocation - 4) + textSection ) != (UInt32)((bytes[patchLocation + 0] << 0 | + bytes[patchLocation + 1] << 8 | + bytes[patchLocation + 2] << 16 | + bytes[patchLocation + 3] << 24))) + ) + { + patchLocation++; + } + patchLocation--; + + verbose("0x%X 0x%X 0x%X 0x%X 0x%X\n", bytes[patchLocation ], bytes[patchLocation +1], bytes[patchLocation +2], bytes[patchLocation +3], bytes[patchLocation +4]); + + // Remove panic just in case + // The panic instruction is exactly 5 bytes long. + bytes[patchLocation + 0] = 0x90; + bytes[patchLocation + 1] = 0x90; + bytes[patchLocation + 2] = 0x90; + bytes[patchLocation + 3] = 0x90; + bytes[patchLocation + 4] = 0x90; + verbose("0x%X 0x%X 0x%X 0x%X 0x%X\n", bytes[patchLocation ], bytes[patchLocation +1], bytes[patchLocation +2], bytes[patchLocation +3], bytes[patchLocation +4]); + + // 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 | + bytes[patchLocation - 14] << 24; + + // 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 - 18] = 0x90; // 05 + bytes[patchLocation - 17] = 0x90; // family location + bytes[patchLocation - 16] = 0x90; // family location + bytes[patchLocation - 15] = 0x90; // family location + bytes[patchLocation - 14] = 0x90; // family location + */ + bytes[patchLocation - 13] = (impersonateFamily & 0x000000FF) >> 0; + 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 - 7] = ((cpuid_model_addr -10) & 0x000000FF) >> 0; // NOTE: this opcode is relative in 64bit mode, subtract offset + bytes[patchLocation - 6] = ((cpuid_model_addr -10) & 0x0000FF00) >> 8; + 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 + bytes[patchLocation - 2] = 0x01; // cpuid_extmodel + bytes[patchLocation - 1] = 0x00; // cpuid_extfamily + + // The panic instruction is exactly 5 bytes long. + bytes[patchLocation - 0] = 0x02; // cpuid_stepping + /*bytes[patchLocation + 1] = 0x90; + bytes[patchLocation + 2] = 0x90; + bytes[patchLocation + 3] = 0x90; + bytes[patchLocation + 4] = 0x90; + */ + + // Panic call has been removed. + // Override the CPUID now. This requires ~ 10 bytes on 10.0.0 kernels + // On 10.2.0+ kernels, this requires ~16 bytes + + // Total: 24 bytes + printf("Running on a 10.2.0+ kernel\n"); + getc(); + } + else { + printf("Running on a 10.0.0 kernel, patch unsupported\n"); + getc(); + } + + +} + +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 @@ -305,21 +447,19 @@ } patchLocation--; - printf("0x%X 0x%X 0x%X 0x%X 0x%X\n", bytes[patchLocation ], bytes[patchLocation +1], bytes[patchLocation +2], bytes[patchLocation +3], bytes[patchLocation +4]); - + verbose("0x%X 0x%X 0x%X 0x%X 0x%X\n", bytes[patchLocation ], bytes[patchLocation +1], bytes[patchLocation +2], bytes[patchLocation +3], bytes[patchLocation +4]); + // Remove panic call, just in case the following patch routines fail bytes[patchLocation + 0] = 0x90; bytes[patchLocation + 1] = 0x90; bytes[patchLocation + 2] = 0x90; bytes[patchLocation + 3] = 0x90; bytes[patchLocation + 4] = 0x90; - printf("0x%X 0x%X 0x%X 0x%X 0x%X\n", bytes[patchLocation ], bytes[patchLocation +1], bytes[patchLocation +2], bytes[patchLocation +3], bytes[patchLocation +4]); - - //getc(); + verbose("0x%X 0x%X 0x%X 0x%X 0x%X\n", bytes[patchLocation ], bytes[patchLocation +1], bytes[patchLocation +2], bytes[patchLocation +3], bytes[patchLocation +4]); + // Locate the jump call, so that 10 bytes can be reclamed. // NOTE: This will *NOT* be located on pre 10.6.2 kernels - // NOTE: This will work on a *32* bit kernel and *not* on a 64 bit ont jumpLocation = patchLocation - 15; while((bytes[jumpLocation - 1] != 0x77 || bytes[jumpLocation] != (patchLocation - jumpLocation - -8)) && @@ -339,19 +479,19 @@ /* * Inpersonate the specified CPU FAMILY and CPU Model */ - + // 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; + 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 + // cpufamily bytes[patchLocation - 11] = (impersonateFamily & 0x000000FF) >> 0; bytes[patchLocation - 10] = (impersonateFamily & 0x0000FF00) >> 8; bytes[patchLocation - 9] = (impersonateFamily & 0x00FF0000) >> 16; @@ -381,81 +521,59 @@ } else if(impersonateFamily && impersonateModel) { - // Eitehr a 64bit kernel *or* a pre 10.6.2 kernel - // Look for - jumpLocation = patchLocation - 15; - while((bytes[jumpLocation - 2] != 0x0F || - bytes[jumpLocation - 1] != 0x87 || - bytes[jumpLocation] != (patchLocation - jumpLocation - -31)) && - (patchLocation - jumpLocation) < 0x200) + // pre 10.6.2 kernel + // Locate the jump to directly *after* the panic call, + jumpLocation = patchLocation - 4; + while((bytes[jumpLocation - 1] != 0x77 || + bytes[jumpLocation] != (patchLocation - jumpLocation + 4)) && + (patchLocation - jumpLocation) < 0x20) { jumpLocation--; } + // NOTE above isn't needed (I was going to use it, but I'm not, so instead, + // I'll just leave it to verify the binary stucture. + // NOTE: the cpumodel_familt data is not set in _cpuid_set_info + // so we don't need to set it here, I'll get set later based on the model + // we set now. - if((patchLocation - jumpLocation) < 0x200) + if((patchLocation - jumpLocation) < 0x20) { - // 64 bit kernel, 10.6.2+ - } - else - { // 32 bit kernel - - // pre 10.6.2 kernel - // Locate the jump to directly *after* the panic call, - jumpLocation = patchLocation - 4; - while((bytes[jumpLocation - 1] != 0x77 || - bytes[jumpLocation] != (patchLocation - jumpLocation + 4)) && - (patchLocation - jumpLocation) < 0x20) - { - jumpLocation--; - } - // NOTE above isn't needed (I was going to use it, but I'm not, so instead, - // I'll just leave it to verify the binary stucture. + UInt32 cpuid_model_addr = (bytes[patchLocation - 14] << 0 | + bytes[patchLocation - 13] << 8 | + bytes[patchLocation - 12] << 16 | + bytes[patchLocation - 11] << 24); + // Remove jump + bytes[patchLocation - 9] = 0x90; /// Was a jump if supported cpu + bytes[patchLocation - 8] = 0x90; // jumped past the panic call, we want to override the panic - // NOTE: the cpumodel_family data is not set in _cpuid_set_info - // so we don't need to set it here, I'll get set later based on the model - // we set now. + bytes[patchLocation - 7] = 0x90; + bytes[patchLocation - 6] = 0x90; - if((patchLocation - jumpLocation) < 0x20) - { - UInt32 cpuid_model_addr = (bytes[patchLocation - 14] << 0 | - bytes[patchLocation - 13] << 8 | - bytes[patchLocation - 12] << 16 | - bytes[patchLocation - 11] << 24); - // Remove jump - bytes[patchLocation - 9] = 0x90; /// Was a jump if supported cpu - bytes[patchLocation - 8] = 0x90; // jumped past the panic call, we want to override the panic - - 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] = impersonateModel; // cpuid_model - 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 - - } + 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] = impersonateModel; // cpuid_model + 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 + } - /*else + else { - // Check for 64bit kernel. - // Patching failed, using NOP replacement done initialy - }*/ + } } else { @@ -564,7 +682,7 @@ kernSymbols_t *symbol = lookup_kernel_symbol("_commpage_stuff_routine"); if(symbol == 0 || symbol->addr == 0) { - printf("Unable to locate %s\n", "_commpage_stuff_routine"); + verbose("Unable to locate %s\n", "_commpage_stuff_routine"); return; } Index: branches/azimutz/Chazi/i386/modules/KernelPatcher/kernel_patcher.h =================================================================== --- branches/azimutz/Chazi/i386/modules/KernelPatcher/kernel_patcher.h (revision 505) +++ branches/azimutz/Chazi/i386/modules/KernelPatcher/kernel_patcher.h (revision 506) @@ -57,7 +57,9 @@ * Internal patches provided by this module. */ void patch_cpuid_set_info_all(void* kernelData); -void patch_cpuid_set_info(void* kernelData, UInt32 impersonateFamily, UInt8 impersonateModel); +void patch_cpuid_set_info_32(void* kernelData, UInt32 impersonateFamily, UInt8 impersonateModel); +void patch_cpuid_set_info_64(void* kernelData, UInt32 impersonateFamily, UInt8 impersonateModel); + void patch_pmCPUExitHaltToOff(void* kernelData); void patch_lapic_init(void* kernelData); void patch_commpage_stuff_routine(void* kernelData); Index: branches/azimutz/Chazi/i386/modules/HelloWorld/HelloWorld.c =================================================================== --- branches/azimutz/Chazi/i386/modules/HelloWorld/HelloWorld.c (revision 505) +++ branches/azimutz/Chazi/i386/modules/HelloWorld/HelloWorld.c (revision 506) @@ -12,8 +12,8 @@ void helloWorld(void* binary, void* arg2, void* arg3, void* arg4) { - printf("Hello world from ExecKernel hook. Binary located at 0x%X\n", binary); - getc(); + verbose("Hello world from ExecKernel hook. Binary located at 0x%X\n", binary); + //getc(); }