提交 d8ace476 编写于 作者: V vit9696

OcAppleKernelLib: Fix patching KC vtables with imports from kexts

上级 9e166de9
......@@ -1805,7 +1805,7 @@ typedef struct {
Key : 2,
Next : 12, ///< 1 or 4-byte stide
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
typedef struct {
......
......@@ -444,11 +444,11 @@ InternalKcConvertRelocToFixup (
UINT16 NewFixupPage;
UINT16 NewFixupPageOffset;
MACH_DYKD_CHAINED_PTR_64_KERNEL_CACHE_REBASE NewFixup;
MACH_DYLD_CHAINED_PTR_64_KERNEL_CACHE_REBASE NewFixup;
UINT16 IterFixupPageOffset;
VOID *IterFixupData;
MACH_DYKD_CHAINED_PTR_64_KERNEL_CACHE_REBASE IterFixup;
MACH_DYLD_CHAINED_PTR_64_KERNEL_CACHE_REBASE IterFixup;
UINT16 NextIterFixupPageOffset;
UINT16 FixupDelta;
......@@ -488,7 +488,7 @@ InternalKcConvertRelocToFixup (
// This 1MB here is a bit of a hack. I think it is just the same thing
// 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);
NewFixupPageOffset = (UINT16) (RelocOffsetInSeg % MACHO_PAGE_SIZE);
......
......@@ -1405,10 +1405,11 @@ InternalPrelinkKext64 (
//
// Undefined symbols are solved via their name.
//
SymbolName = MachoGetSymbolName64 (MachoContext, Symbol);
Result = InternalSolveSymbol64 (
Context,
Kext,
MachoGetSymbolName64 (MachoContext, Symbol),
SymbolName,
Symbol,
&WeakTestValue,
UndefinedSymtab,
......
......@@ -257,6 +257,10 @@ InternalConnectExternalSymtab (
#define VTABLE_HEADER_LEN_64 2U
#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 {
struct {
UINT32 Major : 14;
......
......@@ -96,10 +96,11 @@ InternalConstructVtablePrelinked64 (
OUT PRELINKED_VTABLE *Vtable
)
{
CONST UINT64 *VtableData;
UINT64 Value;
UINT32 Index;
CONST PRELINKED_KEXT_SYMBOL *Symbol;
CONST UINT64 *VtableData;
UINT64 Value;
UINT32 Index;
CONST PRELINKED_KEXT_SYMBOL *Symbol;
MACH_DYLD_CHAINED_PTR_64_KERNEL_CACHE_REBASE *Rebase;
ASSERT (Kext != NULL);
ASSERT (VtableLookup != NULL);
......@@ -123,6 +124,32 @@ InternalConstructVtablePrelinked64 (
(Value = VtableData[Index + VTABLE_HEADER_LEN_64]) != 0;
++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
// defined inline. There's not much I can do about this; it just means
......@@ -205,6 +232,7 @@ InternalPrepareCreateVtablesPrelinked64 (
// __ZTV20IOACPIPlatformDevice
//
if (Symbol->Value == 0) {
DEBUG ((DEBUG_VERBOSE, "OCAK: Skipping %a with NULL value\n", Symbol->Name));
continue;
}
......
......@@ -446,6 +446,10 @@ GetFileSize (
}
int wrap_main(int argc, char** argv) {
PcdGet32 (PcdFixedDebugPrintErrorLevel) |= DEBUG_INFO;
PcdGet32 (PcdDebugPrintErrorLevel) |= DEBUG_INFO;
UINT32 AllocSize;
PRELINKED_CONTEXT Context;
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.
先完成此消息的编辑!
想要评论请 注册