new lapic patch, simplify searchProc

Signed-off-by: SergeySlice <sergey.slice@gmail.com>
This commit is contained in:
SergeySlice 2020-05-05 22:15:59 +03:00
parent 6a4d892667
commit 1a3081dc27
5 changed files with 53 additions and 32 deletions

View File

@ -169,7 +169,7 @@ UINTN LOADER_ENTRY::searchProcInDriver(UINT8 * driver, UINT32 driverLen, const c
}
//search a procedure by Name and return its offset in the kernel
UINTN LOADER_ENTRY::searchProc(UINT8 * kernel, const char *procedure, UINTN *procLen)
UINTN LOADER_ENTRY::searchProc(UINT8 * kernel, const char *procedure)
{
if (!procedure) {
return 0;
@ -220,7 +220,7 @@ UINTN LOADER_ENTRY::searchProc(UINT8 * kernel, const char *procedure, UINTN *pro
UINT64 Absolut = TextSeg->SegAddress; //KLD=C70000
UINT64 FileOff = TextSeg->fileoff; //950000
UINT64 procAddr = vArray[i].ProcAddr - Absolut + FileOff;
/*
UINT64 prevAddr;
if (i == 0) {
prevAddr = Absolut;
@ -228,6 +228,7 @@ UINTN LOADER_ENTRY::searchProc(UINT8 * kernel, const char *procedure, UINTN *pro
prevAddr = vArray[i-1].ProcAddr;
}
*procLen = vArray[i].ProcAddr - prevAddr; //never worked
*/
return procAddr;
}
@ -763,8 +764,8 @@ BOOLEAN LOADER_ENTRY::KernelPatchPm(VOID *kernelData)
//1. procedure xcpm_idle
// wrmsr 0xe2 twice
// B9E2000000 0F30 replace to eb05
UINTN procLen = 0;
UINTN procLocation = searchProc(Kernel, "xcpm_idle", &procLen);
// UINTN procLen = 0;
UINTN procLocation = searchProc(Kernel, "xcpm_idle");
const UINT8 findJmp[] = {0xB9, 0xE2, 0x00, 0x00, 0x00, 0x0F, 0x30};
const UINT8 patchJmp[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
DBG_RT("==> xcpm_idle at %llx\n", procLocation);
@ -772,14 +773,14 @@ BOOLEAN LOADER_ENTRY::KernelPatchPm(VOID *kernelData)
DBG_RT("==> found %lld patterns\n", Num);
//2. procedure xcpm_init
// indirect call to _xcpm_core_scope_msrs
// 488D3DDA317600 lea rdi, qword [ds:_xcpm_SMT_scope_msrs]
// 488D3DDA317600 lea rdi, qword [ds:_xcpm_core_scope_msrs]
// BE0B000000 mov esi, 0xb => replace to eb0a
// 31D2 xor edx, edx
// E87EFCFFFF call sub_ffffff80004fa610 => check e8?
// there are other occurence of _xcpm_SMT_scope_msrs so check 488D3D or E8 at .+7
// there are other occurence of _xcpm_core_scope_msrs so check 488D3D or E8 at .+7
// or restrict len = 0x200
procLocation = searchProc(Kernel, "xcpm_init", &procLen);
UINTN symbol1 = searchProc(Kernel, "xcpm_core_scope_msrs", &procLen);
procLocation = searchProc(Kernel, "xcpm_init");
UINTN symbol1 = searchProc(Kernel, "xcpm_core_scope_msrs");
UINTN patchLocation1 = FindRelative32(Kernel, procLocation, 0x200, symbol1);
if (patchLocation1 != 0) {
DBG_RT("=> xcpm_core_scope_msrs found at %llx\n", patchLocation1);
@ -884,6 +885,24 @@ BOOLEAN LOADER_ENTRY::KernelLapicPatch_64(VOID *kernelData)
UINT32 i, y;
DBG_RT( "Looking for Lapic panic call (64-bit) Start\n");
//Slice - symbolic method
//start at lapic_interrupt ffffff80004e4950 => @2e4950
// found pattern: 1
// address: 002e4a2f
// bytes:658b04251c0000003b058bb97b00
// call _panic -> change to nop {90,90,90,90,90}
if (AsciiOSVersionToUint64(OSVersion) >= AsciiOSVersionToUint64("10.10")) {
UINTN procAddr = searchProc(bytes, "lapic_interrupt");
patchLocation1 = searchProc(bytes, "_panic");
patchLocation2 = FindRelative32(bytes, procAddr, 0x140, patchLocation1);
if (patchLocation2 != 0) {
bytes[patchLocation2 - 5] = 0xEB;
bytes[patchLocation2 - 4] = 0x03;
DBG_RT( "Lapic panic patched\n");
return true;
}
}
//else old method
for (i = 0; i < 0x1000000; i++) {
if (bytes[i+0] == 0x65 && bytes[i+1] == 0x8B && bytes[i+2] == 0x04 && bytes[i+3] == 0x25 &&
@ -935,7 +954,7 @@ BOOLEAN LOADER_ENTRY::KernelLapicPatch_64(VOID *kernelData)
DBG_RT( "Can't find Lapic panic, kernel patch aborted.\n");
return FALSE;
}
// Already patched? May be running a non-vanilla kernel already?
if (bytes[patchLocation1 + 0] == 0x90 && bytes[patchLocation1 + 1] == 0x90 &&
bytes[patchLocation1 + 2] == 0x90 && bytes[patchLocation1 + 3] == 0x90 &&
@ -2010,14 +2029,12 @@ LOADER_ENTRY::KernelUserPatch(IN UINT8 *UKernelData)
}
bool once = false;
UINTN procLen = 0;
UINTN procAddr = searchProc(UKernelData, KernelAndKextPatches->KernelPatches[i].ProcedureName, &procLen);
UINTN procAddr = searchProc(UKernelData, KernelAndKextPatches->KernelPatches[i].ProcedureName);
DBG_RT("procedure %s found at 0x%llx\n", KernelAndKextPatches->KernelPatches[i].ProcedureName, procAddr);
if (SearchLen == 0) {
SearchLen = KERNEL_MAX_SIZE;
if (procLen > KERNEL_MAX_SIZE) {
procLen = KERNEL_MAX_SIZE - procAddr;
once = true;
}
procLen = KERNEL_MAX_SIZE - procAddr;
once = true;
} else {
procLen = SearchLen;
}

View File

@ -192,6 +192,6 @@ UINTN SearchAndReplace(UINT8 *Source, UINT64 SourceSize, const UINT8 *Search, UI
UINTN SearchAndReplaceMask(UINT8 *Source, UINT64 SourceSize, const UINT8 *Search, const UINT8 *MaskSearch, UINTN SearchSize,
const UINT8 *Replace, const UINT8 *MaskReplace, INTN MaxReplaces);
//UINTN searchProc(LOADER_ENTRY *Entry, unsigned char * kernel, const char *procedure, UINTN *procLen);
//UINTN searchProc(LOADER_ENTRY *Entry, unsigned char * kernel, const char *procedure);
#endif /* !__LIBSAIO_KERNEL_PATCHER_H */

View File

@ -995,17 +995,16 @@ VOID EFIAPI LOADER_ENTRY::KernelBooterExtensionsPatch(IN UINT8 *Kernel)
// address: 0095098b
// bytes:eb05
UINTN procLen = 0x100;
UINTN procLocation = searchProc(Kernel, "readStartupExtensions", &procLen);
UINTN procLocation = searchProc(Kernel, "readStartupExtensions");
const UINT8 findJmp[] = {0xEB, 0x05};
const UINT8 patchJmp[] = {0x90, 0x90};
// DBG_RT("==> readStartupExtensions at %llx\n", procLocation);
if (!SearchAndReplace(&Kernel[procLocation], 0x100, findJmp, 2, patchJmp, 1)) {
DBG_RT("load kexts not patched\n");
for (UINTN j=procLocation+0x3b; j<procLocation+0x4b; ++j) {
DBG_RT("%02x", Kernel[j]);
}
DBG_RT("\n");
// for (UINTN j=procLocation+0x3b; j<procLocation+0x4b; ++j) {
// DBG_RT("%02x", Kernel[j]);
// }
// DBG_RT("\n");
// Stall(10000000);
} else {
DBG_RT("load kexts patched\n");
@ -1075,7 +1074,7 @@ VOID EFIAPI LOADER_ENTRY::KernelBooterExtensionsPatch(IN UINT8 *Kernel)
}
#else
// bool otherSys = false;
// UINTN procLocation = searchProc(Kernel, "IOTaskHasEntitlement", &procLen);
// UINTN procLocation = searchProc(Kernel, "IOTaskHasEntitlement");
//Catalina
// const UINT8 find2[] = {0x45, 0x31, 0xF6, 0x48, 0x85, 0xC0 };
// const UINT8 mask2[] = {0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF };
@ -1095,7 +1094,7 @@ VOID EFIAPI LOADER_ENTRY::KernelBooterExtensionsPatch(IN UINT8 *Kernel)
*/
/*
procLocation = searchProc(Kernel, "loadExecutable", &procLen);
procLocation = searchProc(Kernel, "loadExecutable");
//check
DBG_RT("==> loadExecutable (10.11 - recent macOS) at %llx\n", procLocation);
// for (UINTN j=procLocation+0x39; j<procLocation+0x50; ++j) {
@ -1111,7 +1110,7 @@ VOID EFIAPI LOADER_ENTRY::KernelBooterExtensionsPatch(IN UINT8 *Kernel)
patchLocation2 = FindMemMask(&Kernel[procLocation], 0x1000, find2, sizeof(find2), mask2, sizeof(mask2));
if (patchLocation2 == KERNEL_MAX_SIZE) {
//Mojave
procLocation = searchProc(Kernel, "IOTaskHasEntitlement", &procLen);
procLocation = searchProc(Kernel, "IOTaskHasEntitlement");
const UINT8 find4[] = {0x48, 0x85, 0xC0, 0x74, 0x00, 00, 00};
const UINT8 mask4[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 00, 00};
patchLocation2 = FindMemMask(&Kernel[procLocation], 0x100, find3, sizeof(find3), mask3, sizeof(mask3));
@ -1173,8 +1172,8 @@ VOID EFIAPI LOADER_ENTRY::KernelBooterExtensionsPatch(IN UINT8 *Kernel)
//ffffff80009a2273 85C0 test eax, eax =>change to eb06 -> jmp .+6
//ffffff80009a2275 0F843C010000 je 0xffffff80009a23b7
//ffffff80009a227b
UINTN taskLocation = searchProc(Kernel, "IOTaskHasEntitlement", &procLen);
procLocation = searchProc(Kernel, "loadExecutable", &procLen);
UINTN taskLocation = searchProc(Kernel, "IOTaskHasEntitlement");
procLocation = searchProc(Kernel, "loadExecutable");
patchLocation2 = FindMemMask(&Kernel[procLocation], 0x500, find3, sizeof(find3), mask3, sizeof(mask3));
if (patchLocation2 != KERNEL_MAX_SIZE) {
DBG_RT("=> patch SIP applied\n");
@ -1233,7 +1232,7 @@ VOID EFIAPI LOADER_ENTRY::KernelBooterExtensionsPatch(IN UINT8 *Kernel)
//Slice - hope this patch useful for some system that I have no.
// KxldUnmap by vit9696
// Avoid race condition in OSKext::removeKextBootstrap when using booter kexts without keepsyms=1.
procLocation = searchProc(Kernel, "removeKextBootstrap", &procLen);
procLocation = searchProc(Kernel, "removeKextBootstrap");
const UINT8 find5[] = {0x00, 0x0F, 0x85, 00, 00, 0x00, 0x00, 0x48 };
const UINT8 mask5[] = {0xFF, 0xFF, 0xFF, 00, 00, 0xFF, 0xFF, 0xFF };
patchLocation3 = FindMemMask(&Kernel[procLocation], 0x1000, find5, sizeof(find5), mask5, sizeof(mask5));

View File

@ -439,8 +439,13 @@ VOID LOADER_ENTRY::AppleIntelCPUPMPatch(UINT8 *Driver, UINT32 DriverSize, CHAR8
}
DBG_RT("Kext: %s\n", gKextBundleIdentifier);
//TODO: we should scan only __text __TEXT
for (Index1 = 0; Index1 < DriverSize; Index1++) {
// we should scan only __text __TEXT | Slice -> do this
UINTN textName = FindMem(Driver, DriverSize, kPrelinkTextSection, sizeof(kPrelinkTextSection));
SEGMENT *textSeg = (SEGMENT *)&Driver[textName];
UINTN Start = textSeg->fileoff;
UINTN Size = textSeg->filesize;
for (Index1 = Start; Index1 < Start + Size; Index1++) {
// search for MovlE2ToEcx
if (CompareMem(Driver + Index1, MovlE2ToEcx, sizeof(MovlE2ToEcx)) == 0) {
// search for wrmsr in next few bytes
@ -469,7 +474,7 @@ VOID LOADER_ENTRY::AppleIntelCPUPMPatch(UINT8 *Driver, UINT32 DriverSize, CHAR8
Count++;
Driver[Index2] = 0x90;
Driver[Index2 + 1] = 0x90;
DBG_RT(" %llu. patched at 0x%llx\n", Count, Index2);
DBG_RT(" %llu. patched CX at 0x%llx\n", Count, Index2);
break;
} else if ((Driver[Index2] == 0xC9 && Driver[Index2 + 1] == 0xC3) ||
(Driver[Index2] == 0x5D && Driver[Index2 + 1] == 0xC3) ||
@ -585,7 +590,7 @@ VOID LOADER_ENTRY::AppleRTCPatch(UINT8 *Driver, UINT32 DriverSize, CHAR8 *InfoPl
}
/*
UINTN writeCmos = searchProc(Driver, "rtcWrite", &procLen);
UINTN writeCmos = searchProc(Driver, "rtcWrite");
UINTN patchLocation2 = FindRelative32(Driver, procLocation, 0x100, writeCmos);
DBG_RT("AppleRTC:");
if (patchLocation2 != 0) {

View File

@ -372,7 +372,7 @@ class REFIT_ABSTRACT_MENU_ENTRY
VOID FindBootArgs();
EFI_STATUS getVTable(UINT8* kernel);
UINTN searchProc(UINT8 * kernel, const char *procedure, UINTN *procLen);
UINTN searchProc(UINT8 * kernel, const char *procedure);
UINTN searchProcInDriver(UINT8 * driver, UINT32 driverLen, const char *procedure);
VOID KernelAndKextsPatcherStart();
VOID KernelAndKextPatcherInit();