From 70fea56ee4ae5a22c3f82ef988058547f86dec3e Mon Sep 17 00:00:00 2001 From: SergeySlice Date: Sun, 3 May 2020 20:16:50 +0300 Subject: [PATCH] change a way to find symbols in kexts Signed-off-by: SergeySlice --- rEFIt_UEFI/Platform/kernel_patcher.cpp | 60 +++++++++++++++++++++++++- rEFIt_UEFI/Platform/kernel_patcher.h | 1 + rEFIt_UEFI/Platform/kext_patcher.cpp | 51 ++++++++++++++-------- rEFIt_UEFI/gui/menu_items/menu_items.h | 1 + 4 files changed, 94 insertions(+), 19 deletions(-) diff --git a/rEFIt_UEFI/Platform/kernel_patcher.cpp b/rEFIt_UEFI/Platform/kernel_patcher.cpp index 4470c45eb..0ba8d85cb 100644 --- a/rEFIt_UEFI/Platform/kernel_patcher.cpp +++ b/rEFIt_UEFI/Platform/kernel_patcher.cpp @@ -110,6 +110,64 @@ EFI_STATUS LOADER_ENTRY::getVTable(UINT8 * kernel) return EFI_SUCCESS; } +UINTN LOADER_ENTRY::searchProcInDriver(UINT8 * driver, UINT32 driverLen, const char *procedure) +{ + if (!procedure) { + return 0; + } + INT32 LinkAdr = FindBin(driver, driverLen, (const UINT8 *)kLinkEditSegment, (UINT32)strlen(kLinkEditSegment)); + if (LinkAdr == -1) { + return 0; + } + SEGMENT *LinkSeg = (SEGMENT*)&driver[LinkAdr]; +// INT32 lAddrVtable = LinkSeg->AddrVtable; + INT32 lSizeVtable = LinkSeg->SizeVtable; +// INT32 lNamesTable = LinkSeg->AddrNames; + const char* Names = (const char*)(&driver[LinkSeg->AddrNames]); + VTABLE * vArray = (VTABLE*)(&driver[LinkSeg->AddrVtable]); + + INT32 i; + bool found = false; + for (i = 0; i < lSizeVtable; ++i) { + size_t Offset = vArray[i].NameOffset; + if (strstr(&Names[Offset], procedure)) { + found = true; + break; + } + } + if (!found) { + DBG_RT("%s not found\n", procedure); + return 0; + } + + size_t SegVAddr; + switch (vArray[i].Seg) { + case ID_SEG_DATA: + SegVAddr = FindBin(driver, 0x1600, (const UINT8 *)kDataSegment, (UINT32)strlen(kDataSegment)); + break; + case ID_SEG_DATA_CONST: + SegVAddr = FindBin(driver, 0x1600, (const UINT8 *)kDataConstSegment, (UINT32)strlen(kDataConstSegment)); + break; + case ID_SEG_KLD: + case ID_SEG_KLD2: + SegVAddr = FindBin(driver, 0x2000, (const UINT8 *)kKldSegment, (UINT32)strlen(kKldSegment)); + break; + case ID_SEG_TEXT: + default: + SegVAddr = FindBin(driver, 0x600, (const UINT8 *)kTextSegment, (UINT32)strlen(kTextSegment)); + break; + } + if (SegVAddr == 0) { + SegVAddr = 0x38; + } + SEGMENT *TextSeg = (SEGMENT*)&driver[SegVAddr]; + UINT64 Absolut = TextSeg->SegAddress; + UINT64 FileOff = TextSeg->fileoff; + UINTN procAddr = vArray[i].ProcAddr - Absolut + FileOff; + + return procAddr; +} + //search a procedure by Name and return its offset in the kernel UINTN LOADER_ENTRY::searchProc(UINT8 * kernel, const char *procedure, UINTN *procLen) { @@ -1974,7 +2032,7 @@ LOADER_ENTRY::BooterPatch(IN UINT8 *BooterData, IN UINT64 BooterSize) KernelAndKextPatches->BootPatches[i].StartPatternLen)) { DBG_RT( " StartPattern found\n"); - Num = SearchAndReplaceMask(BooterData, + Num = SearchAndReplaceMask(curs, KernelAndKextPatches->BootPatches[i].SearchLen, (const UINT8*)KernelAndKextPatches->BootPatches[i].Data, (const UINT8*)KernelAndKextPatches->BootPatches[i].MaskFind, diff --git a/rEFIt_UEFI/Platform/kernel_patcher.h b/rEFIt_UEFI/Platform/kernel_patcher.h index 954cc45f2..4d2299c40 100644 --- a/rEFIt_UEFI/Platform/kernel_patcher.h +++ b/rEFIt_UEFI/Platform/kernel_patcher.h @@ -40,6 +40,7 @@ const char kDataSegment[] = "__DATA"; const char kDataConstSegment[] = "__DATA_CONST"; const char kKldSegment[] = "__KLD"; +#define ID_SEG_STEXT 0x010e #define ID_SEG_TEXT 0x010f #define ID_SEG_DATA 0x0f0f #define ID_SEG_DATA_CONST 0x110f diff --git a/rEFIt_UEFI/Platform/kext_patcher.cpp b/rEFIt_UEFI/Platform/kext_patcher.cpp index 72517c189..6ecd66c51 100644 --- a/rEFIt_UEFI/Platform/kext_patcher.cpp +++ b/rEFIt_UEFI/Platform/kext_patcher.cpp @@ -121,9 +121,9 @@ VOID CopyMemMask(UINT8 *Dest, const UINT8 *Replace, const UINT8 *Mask, UINTN Sea // 0 if not found UINTN FindRelative32(const UINT8 *Source, UINTN Start, UINTN SourceSize, UINTN taskLocation) { - UINTN Offset; + INT32 Offset; //can be negative, so 0xFFFFFFFF == -1 for (UINTN i = Start; i < Start + SourceSize - 4; ++i) { - Offset = Source[i] + (Source[i+1]<<8) + (Source[i+2]<<16) + (Source[i+3]<<24); //should not use *(UINT32*) because of alignment + Offset = (INT32)((UINT32)Source[i] + ((UINT32)Source[i+1]<<8) + ((UINT32)Source[i+2]<<16) + ((UINT32)Source[i+3]<<24)); //should not use *(UINT32*) because of alignment if (taskLocation == i + Offset + 4) { return (i+4); } @@ -575,15 +575,33 @@ VOID LOADER_ENTRY::AppleRTCPatch(UINT8 *Driver, UINT32 DriverSize, CHAR8 *InfoPl } #else //RodionS - UINTN procLen = DriverSize; - UINTN procLocation = searchProc(Driver, "updateChecksum", &procLen); - DBG_RT("AppleRTC:"); + + UINTN procLocation = searchProcInDriver(Driver, DriverSize, "updateChecksum"); if (procLocation != 0) { Driver[procLocation] = 0xC3; - DBG_RT(" patched\n"); + DBG_RT("AppleRTC: patched\n"); } else { - DBG_RT(" failed\n"); + DBG_RT("AppleRTC: not patched\n"); } + + /* + UINTN writeCmos = searchProc(Driver, "rtcWrite", &procLen); + UINTN patchLocation2 = FindRelative32(Driver, procLocation, 0x100, writeCmos); + DBG_RT("AppleRTC:"); + if (patchLocation2 != 0) { + Driver[patchLocation2 - 5] = 0xEB; + Driver[patchLocation2 - 4] = 0x03; + DBG_RT(" patched 1\n"); + UINTN patchLocation3 = FindRelative32(Driver, patchLocation2, 0x20, writeCmos); + if (patchLocation3 != 0) { + Driver[patchLocation3 - 5] = 0xEB; + Driver[patchLocation3 - 4] = 0x03; + DBG_RT(" patched 2\n"); + } + } else { + DBG_RT(" not patched\n"); + } + */ #endif Stall(5000000); @@ -999,14 +1017,13 @@ VOID LOADER_ENTRY::AnyKextPatch(UINT8 *Driver, UINT32 DriverSize, CHAR8 *InfoPli { UINTN Num = 0; INTN Ind; - - DBG_RT("\nAnyKextPatch %d: driverAddr = %s, driverSize = %x\nAnyKext = %s\n", - N, Driver, DriverSize, KernelAndKextPatches->KextPatches[N].Label); if (!KernelAndKextPatches->KextPatches[N].MenuItem.BValue) { - DBG_RT("==> DISABLED!\n"); return; } + + DBG_RT("\nAnyKextPatch %d: driverAddr = %llx, driverSize = %x\nAnyKext = %s\n", + N, (UINTN)Driver, DriverSize, KernelAndKextPatches->KextPatches[N].Label); if (!KernelAndKextPatches->KextPatches[N].SearchLen || (KernelAndKextPatches->KextPatches[N].SearchLen > DriverSize)) { @@ -1024,18 +1041,16 @@ VOID LOADER_ENTRY::AnyKextPatch(UINT8 *Driver, UINT32 DriverSize, CHAR8 *InfoPli DBG_RT("Binary patch\n"); bool once = false; UINTN procLen = 0; - UINTN procAddr = searchProc(Driver, KernelAndKextPatches->KextPatches[N].ProcedureName, &procLen); + UINTN procAddr = searchProcInDriver(Driver, DriverSize, KernelAndKextPatches->KextPatches[N].ProcedureName); if (KernelAndKextPatches->KextPatches[N].SearchLen == 0) { KernelAndKextPatches->KextPatches[N].SearchLen = DriverSize; - if (procLen > DriverSize) { - procLen = DriverSize - procAddr; - once = true; - } + procLen = DriverSize - procAddr; + once = true; } else { procLen = KernelAndKextPatches->KextPatches[N].SearchLen; } - const UINT8 * curs = &Driver[procAddr]; + UINT8 * curs = &Driver[procAddr]; UINTN j = 0; while (j < DriverSize) { if (!KernelAndKextPatches->KextPatches[N].StartPattern || //old behavior @@ -1046,7 +1061,7 @@ VOID LOADER_ENTRY::AnyKextPatch(UINT8 *Driver, UINT32 DriverSize, CHAR8 *InfoPli KernelAndKextPatches->KextPatches[N].StartPatternLen)) { DBG_RT(" StartPattern found\n"); - Num = SearchAndReplaceMask(Driver, + Num = SearchAndReplaceMask(curs, procLen, (const UINT8*)KernelAndKextPatches->KextPatches[N].Data, (const UINT8*)KernelAndKextPatches->KextPatches[N].MaskFind, diff --git a/rEFIt_UEFI/gui/menu_items/menu_items.h b/rEFIt_UEFI/gui/menu_items/menu_items.h index f6f148b80..31ad86861 100644 --- a/rEFIt_UEFI/gui/menu_items/menu_items.h +++ b/rEFIt_UEFI/gui/menu_items/menu_items.h @@ -373,6 +373,7 @@ class REFIT_ABSTRACT_MENU_ENTRY VOID FindBootArgs(); EFI_STATUS getVTable(UINT8* kernel); UINTN searchProc(UINT8 * kernel, const char *procedure, UINTN *procLen); + UINTN searchProcInDriver(UINT8 * driver, UINT32 driverLen, const char *procedure); VOID KernelAndKextsPatcherStart(); VOID KernelAndKextPatcherInit(); BOOLEAN KernelUserPatch(UINT8 * kernel);