diff --git a/rEFIt_UEFI/Platform/kernel_patcher.cpp b/rEFIt_UEFI/Platform/kernel_patcher.cpp index fbd906472..4f20a3de2 100644 --- a/rEFIt_UEFI/Platform/kernel_patcher.cpp +++ b/rEFIt_UEFI/Platform/kernel_patcher.cpp @@ -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; } diff --git a/rEFIt_UEFI/Platform/kernel_patcher.h b/rEFIt_UEFI/Platform/kernel_patcher.h index 4d2299c40..1a73ee110 100644 --- a/rEFIt_UEFI/Platform/kernel_patcher.h +++ b/rEFIt_UEFI/Platform/kernel_patcher.h @@ -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 */ diff --git a/rEFIt_UEFI/Platform/kext_inject.cpp b/rEFIt_UEFI/Platform/kext_inject.cpp index ecfe75d3c..3295477c8 100644 --- a/rEFIt_UEFI/Platform/kext_inject.cpp +++ b/rEFIt_UEFI/Platform/kext_inject.cpp @@ -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 loadExecutable (10.11 - recent macOS) at %llx\n", procLocation); // for (UINTN j=procLocation+0x39; jchange 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)); diff --git a/rEFIt_UEFI/Platform/kext_patcher.cpp b/rEFIt_UEFI/Platform/kext_patcher.cpp index e0fabb1c7..712e14a40 100644 --- a/rEFIt_UEFI/Platform/kext_patcher.cpp +++ b/rEFIt_UEFI/Platform/kext_patcher.cpp @@ -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) { diff --git a/rEFIt_UEFI/gui/menu_items/menu_items.h b/rEFIt_UEFI/gui/menu_items/menu_items.h index 31ad86861..4b7104556 100644 --- a/rEFIt_UEFI/gui/menu_items/menu_items.h +++ b/rEFIt_UEFI/gui/menu_items/menu_items.h @@ -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();