提交 d8ace476 编写于 作者: V vit9696

OcAppleKernelLib: Fix patching KC vtables with imports from kexts

上级 9e166de9
...@@ -1805,7 +1805,7 @@ typedef struct { ...@@ -1805,7 +1805,7 @@ typedef struct {
Key : 2, Key : 2,
Next : 12, ///< 1 or 4-byte stide Next : 12, ///< 1 or 4-byte stide
IsAuth : 1; ///< 0 -> not authenticated. 1 -> authenticated IsAuth : 1; ///< 0 -> not authenticated. 1 -> authenticated
} MACH_DYKD_CHAINED_PTR_64_KERNEL_CACHE_REBASE; } MACH_DYLD_CHAINED_PTR_64_KERNEL_CACHE_REBASE;
// header of the LC_DYLD_CHAINED_FIXUPS payload // header of the LC_DYLD_CHAINED_FIXUPS payload
typedef struct { typedef struct {
......
...@@ -444,11 +444,11 @@ InternalKcConvertRelocToFixup ( ...@@ -444,11 +444,11 @@ InternalKcConvertRelocToFixup (
UINT16 NewFixupPage; UINT16 NewFixupPage;
UINT16 NewFixupPageOffset; UINT16 NewFixupPageOffset;
MACH_DYKD_CHAINED_PTR_64_KERNEL_CACHE_REBASE NewFixup; MACH_DYLD_CHAINED_PTR_64_KERNEL_CACHE_REBASE NewFixup;
UINT16 IterFixupPageOffset; UINT16 IterFixupPageOffset;
VOID *IterFixupData; VOID *IterFixupData;
MACH_DYKD_CHAINED_PTR_64_KERNEL_CACHE_REBASE IterFixup; MACH_DYLD_CHAINED_PTR_64_KERNEL_CACHE_REBASE IterFixup;
UINT16 NextIterFixupPageOffset; UINT16 NextIterFixupPageOffset;
UINT16 FixupDelta; UINT16 FixupDelta;
...@@ -488,7 +488,7 @@ InternalKcConvertRelocToFixup ( ...@@ -488,7 +488,7 @@ InternalKcConvertRelocToFixup (
// This 1MB here is a bit of a hack. I think it is just the same thing // This 1MB here is a bit of a hack. I think it is just the same thing
// as KERNEL_BASE_PADDR in OcAfterBootCompatLib. // as KERNEL_BASE_PADDR in OcAfterBootCompatLib.
// //
NewFixup.Target = ReadUnaligned64 (RelocDest) - BASE_1MB; NewFixup.Target = ReadUnaligned64 (RelocDest) - KERNEL_FIXUP_OFFSET;
NewFixupPage = (UINT16) (RelocOffsetInSeg / MACHO_PAGE_SIZE); NewFixupPage = (UINT16) (RelocOffsetInSeg / MACHO_PAGE_SIZE);
NewFixupPageOffset = (UINT16) (RelocOffsetInSeg % MACHO_PAGE_SIZE); NewFixupPageOffset = (UINT16) (RelocOffsetInSeg % MACHO_PAGE_SIZE);
......
...@@ -1405,10 +1405,11 @@ InternalPrelinkKext64 ( ...@@ -1405,10 +1405,11 @@ InternalPrelinkKext64 (
// //
// Undefined symbols are solved via their name. // Undefined symbols are solved via their name.
// //
SymbolName = MachoGetSymbolName64 (MachoContext, Symbol);
Result = InternalSolveSymbol64 ( Result = InternalSolveSymbol64 (
Context, Context,
Kext, Kext,
MachoGetSymbolName64 (MachoContext, Symbol), SymbolName,
Symbol, Symbol,
&WeakTestValue, &WeakTestValue,
UndefinedSymtab, UndefinedSymtab,
......
...@@ -257,6 +257,10 @@ InternalConnectExternalSymtab ( ...@@ -257,6 +257,10 @@ InternalConnectExternalSymtab (
#define VTABLE_HEADER_LEN_64 2U #define VTABLE_HEADER_LEN_64 2U
#define VTABLE_HEADER_SIZE_64 (VTABLE_HEADER_LEN_64 * VTABLE_ENTRY_SIZE_64) #define VTABLE_HEADER_SIZE_64 (VTABLE_HEADER_LEN_64 * VTABLE_ENTRY_SIZE_64)
#define KERNEL_ADDRESS_MASK 0xFFFFFFFF00000000ULL
#define KERNEL_ADDRESS_BASE 0xFFFFFF8000000000ULL
#define KERNEL_FIXUP_OFFSET BASE_1MB
typedef union { typedef union {
struct { struct {
UINT32 Major : 14; UINT32 Major : 14;
......
...@@ -96,10 +96,11 @@ InternalConstructVtablePrelinked64 ( ...@@ -96,10 +96,11 @@ InternalConstructVtablePrelinked64 (
OUT PRELINKED_VTABLE *Vtable OUT PRELINKED_VTABLE *Vtable
) )
{ {
CONST UINT64 *VtableData; CONST UINT64 *VtableData;
UINT64 Value; UINT64 Value;
UINT32 Index; UINT32 Index;
CONST PRELINKED_KEXT_SYMBOL *Symbol; CONST PRELINKED_KEXT_SYMBOL *Symbol;
MACH_DYLD_CHAINED_PTR_64_KERNEL_CACHE_REBASE *Rebase;
ASSERT (Kext != NULL); ASSERT (Kext != NULL);
ASSERT (VtableLookup != NULL); ASSERT (VtableLookup != NULL);
...@@ -123,6 +124,32 @@ InternalConstructVtablePrelinked64 ( ...@@ -123,6 +124,32 @@ InternalConstructVtablePrelinked64 (
(Value = VtableData[Index + VTABLE_HEADER_LEN_64]) != 0; (Value = VtableData[Index + VTABLE_HEADER_LEN_64]) != 0;
++Index ++Index
) { ) {
//
// For all non-kernel (which uses own relocation) virtual tables
// all virtual tables will contain fixups exclusively.
// For now we will just detect them by the kernel address
// as it is faster than compare Kext->Identifier and Context->IsKernelCollection.
//
if ((Value & KERNEL_ADDRESS_MASK) != KERNEL_ADDRESS_BASE) {
//
// FIXME: This needs a bit more love with aliasing and alignment.
// Some day, when Intel rewrites EDK II.
//
Rebase = (MACH_DYLD_CHAINED_PTR_64_KERNEL_CACHE_REBASE *)(UINTN) &Value;
DEBUG_CODE_BEGIN ();
if (Rebase->CacheLevel != 0
|| Rebase->Diversity != 0
|| Rebase->AddrDiv != 0
|| Rebase->Key != 0
|| Rebase->IsAuth != 0) {
DEBUG ((DEBUG_INFO, "OCAK: Invalid fixup %Lx in %a for %a\n", Value, Vtable->Name, Kext->Identifier));
}
DEBUG_CODE_END ();
Value = Rebase->Target + KERNEL_FIXUP_OFFSET + KERNEL_ADDRESS_BASE;
}
// //
// If we can't find the symbol, it means that the virtual function was // If we can't find the symbol, it means that the virtual function was
// defined inline. There's not much I can do about this; it just means // defined inline. There's not much I can do about this; it just means
...@@ -205,6 +232,7 @@ InternalPrepareCreateVtablesPrelinked64 ( ...@@ -205,6 +232,7 @@ InternalPrepareCreateVtablesPrelinked64 (
// __ZTV20IOACPIPlatformDevice // __ZTV20IOACPIPlatformDevice
// //
if (Symbol->Value == 0) { if (Symbol->Value == 0) {
DEBUG ((DEBUG_VERBOSE, "OCAK: Skipping %a with NULL value\n", Symbol->Name));
continue; continue;
} }
......
...@@ -446,6 +446,10 @@ GetFileSize ( ...@@ -446,6 +446,10 @@ GetFileSize (
} }
int wrap_main(int argc, char** argv) { int wrap_main(int argc, char** argv) {
PcdGet32 (PcdFixedDebugPrintErrorLevel) |= DEBUG_INFO;
PcdGet32 (PcdDebugPrintErrorLevel) |= DEBUG_INFO;
UINT32 AllocSize; UINT32 AllocSize;
PRELINKED_CONTEXT Context; PRELINKED_CONTEXT Context;
const char *name = argc > 1 ? argv[1] : "/System/Library/PrelinkedKernels/prelinkedkernel"; const char *name = argc > 1 ? argv[1] : "/System/Library/PrelinkedKernels/prelinkedkernel";
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册