diff --git a/Include/Acidanthera/Library/OcAppleKernelLib.h b/Include/Acidanthera/Library/OcAppleKernelLib.h index dea9036c..590ef570 100644 --- a/Include/Acidanthera/Library/OcAppleKernelLib.h +++ b/Include/Acidanthera/Library/OcAppleKernelLib.h @@ -1105,6 +1105,40 @@ PatcherGetSymbolAddress ( IN OUT UINT8 **Address ); +/** + Get local symbol value. + + @param[in,out] Context Patcher context. + @param[in] Name Symbol name. + @param[in,out] Value Returned original symbol value. + + @return EFI_SUCCESS on success. +**/ +EFI_STATUS +PatcherGetSymbolValue ( + IN OUT PATCHER_CONTEXT *Context, + IN CONST CHAR8 *Name, + IN OUT UINT64 *Value + ); + +/** + Get local symbol address and symbol value. + + @param[in,out] Context Patcher context. + @param[in] Name Symbol name. + @param[in,out] Address Returned symbol address in file. + @param[in,out] Value Returned original symbol value. + + @return EFI_SUCCESS on success. +**/ +EFI_STATUS +PatcherGetSymbolAddressValue ( + IN OUT PATCHER_CONTEXT *Context, + IN CONST CHAR8 *Name, + IN OUT UINT8 **Address, + IN OUT UINT64 *Value + ); + /** Apply generic patch. diff --git a/Library/OcAppleKernelLib/CpuidPatches.c b/Library/OcAppleKernelLib/CpuidPatches.c index 0758a5ab..8c41e6b5 100644 --- a/Library/OcAppleKernelLib/CpuidPatches.c +++ b/Library/OcAppleKernelLib/CpuidPatches.c @@ -1005,29 +1005,31 @@ STATIC UINT8 * PatchMovVar ( IN OUT UINT8 *Location, - IN UINT8 *Start, - IN MACH_SECTION_ANY *DataSection, - IN MACH_SECTION_ANY *TextSection, IN BOOLEAN Is32Bit, - IN UINT8 *Var, + IN OUT UINT64 *FuncAddr, + IN UINT64 VarSymAddr, IN UINT64 Value ) { + UINT8 *Start; INT32 Delta; - UINT64 LocationAddr; - UINT64 VarAddr64; UINT32 VarAddr32; UINT32 ValueLower; UINT32 ValueUpper; + Start = Location; + DEBUG ((DEBUG_VERBOSE, "OCAK: Current TSC func address: 0x%llX, variable address: 0x%llX\n", *FuncAddr, VarSymAddr)); + if (Is32Bit) { ValueLower = (UINT32)Value; ValueUpper = (UINT32)(Value >> 32); + // + // 32-bit uses absolute addressing // // mov [var], value lower // - VarAddr32 = (UINT32)((Var - Start) + DataSection->Section32.Address - DataSection->Section32.Offset); + VarAddr32 = (UINT32)(VarSymAddr); *Location++ = 0xC7; *Location++ = 0x05; CopyMem (Location, &VarAddr32, sizeof (VarAddr32)); @@ -1045,6 +1047,9 @@ PatchMovVar ( Location += sizeof (VarAddr32); CopyMem (Location, &ValueUpper, sizeof (ValueUpper)); Location += sizeof (ValueUpper); + + *FuncAddr += (Location - Start); + } else { // // mov rax, value @@ -1052,20 +1057,20 @@ PatchMovVar ( *Location++ = 0x48; *Location++ = 0xB8; CopyMem (Location, &Value, sizeof (Value)); - Location += sizeof (Value); - - LocationAddr = (Location - Start) + TextSection->Section64.Address - TextSection->Section64.Offset; - VarAddr64 = (Var - Start) + DataSection->Section64.Address - DataSection->Section64.Offset; + Location += sizeof (Value); + *FuncAddr += sizeof (Value) + 2; // // mov [var], rax // - Delta = (INT32)(VarAddr64 - (LocationAddr + 7)); + Delta = (INT32)(VarSymAddr - (*FuncAddr + 7)); + DEBUG ((DEBUG_VERBOSE, "OCAK: TSC func delta 0x%X\n", Delta)); *Location++ = 0x48; *Location++ = 0x89; *Location++ = 0x05; CopyMem (Location, &Delta, sizeof (Delta)); - Location += sizeof (Delta); + Location += sizeof (Delta); + *FuncAddr += sizeof (Delta) + 3; } return Location; @@ -1316,25 +1321,23 @@ PatchProvideCurrentCpuInfo ( { EFI_STATUS Status; - UINT8 *Start; - MACH_SECTION_ANY *DataSection; - MACH_SECTION_ANY *TextSection; - INT32 Delta; - UINT64 LocationAddr; - UINT64 VarAddr64; + UINT32 VarAddr32; + UINT32 ValueLower; + UINT32 ValueUpper; UINT8 *TscInitFunc; UINT8 *TmrCvtFunc; - UINT8 *BusFreq; - UINT8 *BusFCvtt2n; - UINT8 *BusFCvtn2t; - UINT8 *TscFreq; - UINT8 *TscFCvtt2n; - UINT8 *TscFCvtn2t; - UINT8 *TscGranularity; - UINT8 *Bus2Tsc; + UINT64 TscInitFuncSymAddr; + UINT64 BusFreqSymAddr; + UINT64 BusFCvtt2nSymAddr; + UINT64 BusFCvtn2tSymAddr; + UINT64 TscFreqSymAddr; + UINT64 TscFCvtt2nSymAddr; + UINT64 TscFCvtn2tSymAddr; + UINT64 TscGranularitySymAddr; + UINT64 Bus2TscSymAddr; UINT8 *TscLocation; @@ -1353,33 +1356,20 @@ PatchProvideCurrentCpuInfo ( Status = EFI_SUCCESS; Status |= PatchProvideCurrentCpuInfoMSR35h (Patcher, CpuInfo, KernelVersion); - Start = ((UINT8 *)MachoGetFileData (&Patcher->MachContext)); - - // - // 10.6 and below has variables in __DATA/__data instead of __DATA/__common - // - if (OcMatchDarwinVersion (KernelVersion, KERNEL_VERSION_LION_MIN, 0)) { - DataSection = MachoGetSegmentSectionByName (&Patcher->MachContext, "__DATA", "__common"); - } else { - DataSection = MachoGetSegmentSectionByName (&Patcher->MachContext, "__DATA", "__data"); - } - - TextSection = MachoGetSegmentSectionByName (&Patcher->MachContext, "__TEXT", "__text"); - // // Pull required symbols. // - Status |= PatcherGetSymbolAddress (Patcher, "_tsc_init", (UINT8 **)&TscInitFunc); + Status |= PatcherGetSymbolAddressValue (Patcher, "_tsc_init", (UINT8 **)&TscInitFunc, &TscInitFuncSymAddr); Status |= PatcherGetSymbolAddress (Patcher, "_tmrCvt", (UINT8 **)&TmrCvtFunc); - Status |= PatcherGetSymbolAddress (Patcher, "_busFreq", (UINT8 **)&BusFreq); - Status |= PatcherGetSymbolAddress (Patcher, "_busFCvtt2n", (UINT8 **)&BusFCvtt2n); - Status |= PatcherGetSymbolAddress (Patcher, "_busFCvtn2t", (UINT8 **)&BusFCvtn2t); - Status |= PatcherGetSymbolAddress (Patcher, "_tscFreq", (UINT8 **)&TscFreq); - Status |= PatcherGetSymbolAddress (Patcher, "_tscFCvtt2n", (UINT8 **)&TscFCvtt2n); - Status |= PatcherGetSymbolAddress (Patcher, "_tscFCvtn2t", (UINT8 **)&TscFCvtn2t); - Status |= PatcherGetSymbolAddress (Patcher, "_tscGranularity", (UINT8 **)&TscGranularity); - Status |= PatcherGetSymbolAddress (Patcher, "_bus2tsc", (UINT8 **)&Bus2Tsc); + Status |= PatcherGetSymbolValue (Patcher, "_busFreq", &BusFreqSymAddr); + Status |= PatcherGetSymbolValue (Patcher, "_busFCvtt2n", &BusFCvtt2nSymAddr); + Status |= PatcherGetSymbolValue (Patcher, "_busFCvtn2t", &BusFCvtn2tSymAddr); + Status |= PatcherGetSymbolValue (Patcher, "_tscFreq", &TscFreqSymAddr); + Status |= PatcherGetSymbolValue (Patcher, "_tscFCvtt2n", &TscFCvtt2nSymAddr); + Status |= PatcherGetSymbolValue (Patcher, "_tscFCvtn2t", &TscFCvtn2tSymAddr); + Status |= PatcherGetSymbolValue (Patcher, "_tscGranularity", &TscGranularitySymAddr); + Status |= PatcherGetSymbolValue (Patcher, "_bus2tsc", &Bus2TscSymAddr); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_WARN, "OCAK: Failed to locate one or more TSC symbols - %r\n", Status)); @@ -1407,48 +1397,145 @@ PatchProvideCurrentCpuInfo ( // TscLocation = TscInitFunc; - TscLocation = PatchMovVar (TscLocation, Start, DataSection, TextSection, Patcher->Is32Bit, BusFreq, busFreqValue); - TscLocation = PatchMovVar (TscLocation, Start, DataSection, TextSection, Patcher->Is32Bit, BusFCvtt2n, busFCvtt2nValue); - TscLocation = PatchMovVar (TscLocation, Start, DataSection, TextSection, Patcher->Is32Bit, BusFCvtn2t, busFCvtn2tValue); - TscLocation = PatchMovVar (TscLocation, Start, DataSection, TextSection, Patcher->Is32Bit, TscFreq, tscFreqValue); - TscLocation = PatchMovVar (TscLocation, Start, DataSection, TextSection, Patcher->Is32Bit, TscFCvtt2n, tscFCvtt2nValue); - TscLocation = PatchMovVar (TscLocation, Start, DataSection, TextSection, Patcher->Is32Bit, TscFCvtn2t, tscFCvtn2tValue); - TscLocation = PatchMovVar (TscLocation, Start, DataSection, TextSection, Patcher->Is32Bit, TscGranularity, tscGranularityValue); - TscLocation = PatchMovVar (TscLocation, Start, DataSection, TextSection, Patcher->Is32Bit, BusFreq, busFreqValue); + TscLocation = PatchMovVar (TscLocation, Patcher->Is32Bit, &TscInitFuncSymAddr, BusFreqSymAddr, busFreqValue); + TscLocation = PatchMovVar (TscLocation, Patcher->Is32Bit, &TscInitFuncSymAddr, BusFCvtt2nSymAddr, busFCvtt2nValue); + TscLocation = PatchMovVar (TscLocation, Patcher->Is32Bit, &TscInitFuncSymAddr, BusFCvtn2tSymAddr, busFCvtn2tValue); + TscLocation = PatchMovVar (TscLocation, Patcher->Is32Bit, &TscInitFuncSymAddr, TscFreqSymAddr, tscFreqValue); + TscLocation = PatchMovVar (TscLocation, Patcher->Is32Bit, &TscInitFuncSymAddr, TscFCvtt2nSymAddr, tscFCvtt2nValue); + TscLocation = PatchMovVar (TscLocation, Patcher->Is32Bit, &TscInitFuncSymAddr, TscFCvtn2tSymAddr, tscFCvtn2tValue); + TscLocation = PatchMovVar (TscLocation, Patcher->Is32Bit, &TscInitFuncSymAddr, TscGranularitySymAddr, tscGranularityValue); + TscLocation = PatchMovVar (TscLocation, Patcher->Is32Bit, &TscInitFuncSymAddr, BusFreqSymAddr, busFreqValue); if (Patcher->Is32Bit) { - // TODO - } else { // - // mov rdi, FSB freq + // push ebp + // move ebp, esp // - *TscLocation++ = 0x48; - *TscLocation++ = 0xBF; - CopyMem (TscLocation, &busFreqValue, sizeof (busFreqValue)); - TscLocation += sizeof (busFreqValue); + *TscLocation++ = 0x55; + *TscLocation++ = 0x89; + *TscLocation++ = 0xE5; + + ValueLower = (UINT32)busFreqValue; + ValueUpper = (UINT32)(busFreqValue >> 32); // - // mov rsi, TSC freq + // mov eax, FSB freq (lower) // - *TscLocation++ = 0x48; - *TscLocation++ = 0xBE; - CopyMem (TscLocation, &tscFreqValue, sizeof (tscFreqValue)); - TscLocation += sizeof (tscFreqValue); + *TscLocation++ = 0xB8; + CopyMem (TscLocation, &ValueLower, sizeof (ValueLower)); + TscLocation += sizeof (ValueLower); // - // call _tmrCvt + // push eax + // + *TscLocation++ = 0x50; + + // + // mov eax, FSB freq (higher) + // + *TscLocation++ = 0xB8; + CopyMem (TscLocation, &ValueUpper, sizeof (ValueUpper)); + TscLocation += sizeof (ValueUpper); + + // + // push eax + // + *TscLocation++ = 0x50; + + ValueLower = (UINT32)tscFreqValue; + ValueUpper = (UINT32)(tscFreqValue >> 32); + + // + // mov eax, TSC freq (lower) + // + *TscLocation++ = 0xB8; + CopyMem (TscLocation, &ValueLower, sizeof (ValueLower)); + TscLocation += sizeof (ValueLower); + + // + // push eax + // + *TscLocation++ = 0x50; + + // + // mov eax, TSC freq (higher) + // + *TscLocation++ = 0xB8; + CopyMem (TscLocation, &ValueUpper, sizeof (ValueUpper)); + TscLocation += sizeof (ValueUpper); + + // + // push eax + // + *TscLocation++ = 0x50; + + // + // call _tmrCvt(busFCvtt2n, tscFCvtn2t) // Delta = (INT32)(TmrCvtFunc - (TscLocation + 5)); *TscLocation++ = 0xE8; CopyMem (TscLocation, &Delta, sizeof (Delta)); TscLocation += sizeof (Delta); + // + // mov [_bus2tsc], eax + // + VarAddr32 = (UINT32)(Bus2TscSymAddr); + *TscLocation++ = 0xA3; + CopyMem (TscLocation, &VarAddr32, sizeof (VarAddr32)); + TscLocation += sizeof (VarAddr32); + + // + // mov [_bus2tsc+4], edx + // + VarAddr32 += sizeof (UINT32); + *TscLocation++ = 0x89; + *TscLocation++ = 0x15; + CopyMem (TscLocation, &VarAddr32, sizeof (VarAddr32)); + TscLocation += sizeof (VarAddr32); + + // + // pop eax (x4) + // leave + // + *TscLocation++ = 0x58; + *TscLocation++ = 0x58; + *TscLocation++ = 0x58; + *TscLocation++ = 0x58; + *TscLocation++ = 0xC9; + + } else { + // + // mov rdi, FSB freq + // + *TscLocation++ = 0x48; + *TscLocation++ = 0xBF; + CopyMem (TscLocation, &busFreqValue, sizeof (busFreqValue)); + TscLocation += sizeof (busFreqValue); + TscInitFuncSymAddr += sizeof (busFreqValue) + 2; + + // + // mov rsi, TSC freq + // + *TscLocation++ = 0x48; + *TscLocation++ = 0xBE; + CopyMem (TscLocation, &tscFreqValue, sizeof (tscFreqValue)); + TscLocation += sizeof (tscFreqValue); + TscInitFuncSymAddr += sizeof (tscFreqValue) + 2; + + // + // call _tmrCvt(busFCvtt2n, tscFCvtn2t) + // + Delta = (INT32)(TmrCvtFunc - (TscLocation + 5)); + *TscLocation++ = 0xE8; + CopyMem (TscLocation, &Delta, sizeof (Delta)); + TscLocation += sizeof (Delta); + TscInitFuncSymAddr += sizeof (Delta) + 1; + // // mov [_bus2tsc], rax // - LocationAddr = (TscLocation - Start) + TextSection->Section64.Address - TextSection->Section64.Offset; - VarAddr64 = (Bus2Tsc - Start) + DataSection->Section64.Address - DataSection->Section64.Offset; - Delta = (INT32)(VarAddr64 - (LocationAddr + 7)); + Delta = (INT32)(Bus2TscSymAddr - (TscInitFuncSymAddr + 7)); *TscLocation++ = 0x48; *TscLocation++ = 0x89; diff --git a/Library/OcAppleKernelLib/KextPatcher.c b/Library/OcAppleKernelLib/KextPatcher.c index 382d62d5..878ca499 100644 --- a/Library/OcAppleKernelLib/KextPatcher.c +++ b/Library/OcAppleKernelLib/KextPatcher.c @@ -216,6 +216,27 @@ PatcherGetSymbolAddress ( IN CONST CHAR8 *Name, IN OUT UINT8 **Address ) +{ + return PatcherGetSymbolAddressValue (Context, Name, Address, NULL); +} + +EFI_STATUS +PatcherGetSymbolValue ( + IN OUT PATCHER_CONTEXT *Context, + IN CONST CHAR8 *Name, + IN OUT UINT64 *Value + ) +{ + return PatcherGetSymbolAddressValue (Context, Name, NULL, Value); +} + +EFI_STATUS +PatcherGetSymbolAddressValue ( + IN OUT PATCHER_CONTEXT *Context, + IN CONST CHAR8 *Name, + IN OUT UINT8 **Address, + IN OUT UINT64 *Value + ) { MACH_NLIST_ANY *Symbol; CONST CHAR8 *SymbolName; @@ -273,7 +294,12 @@ PatcherGetSymbolAddress ( Index++; } - *Address = (UINT8 *)MachoGetFileData (&Context->MachContext) + Offset; + if (Address != NULL) { + *Address = (UINT8 *)MachoGetFileData (&Context->MachContext) + Offset; + } + if (Value != NULL) { + *Value = Context->Is32Bit ? Symbol->Symbol32.Value : Symbol->Symbol64.Value; + } return EFI_SUCCESS; }