mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2026-02-01 15:59:39 +00:00
OcMachoLib: Support KC Mach-Os
This commit is contained in:
parent
6fdd4a2834
commit
07b697d28d
@ -34,6 +34,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
typedef struct {
|
||||
MACH_HEADER_64 *MachHeader;
|
||||
UINT32 FileSize;
|
||||
UINT32 ContainerOffset;
|
||||
MACH_SYMTAB_COMMAND *Symtab;
|
||||
MACH_NLIST_64 *SymbolTable;
|
||||
CHAR8 *StringTable;
|
||||
@ -46,9 +47,11 @@ typedef struct {
|
||||
/**
|
||||
Initializes a Mach-O Context.
|
||||
|
||||
@param[out] Context Mach-O Context to initialize.
|
||||
@param[in] FileData Pointer to the file's data.
|
||||
@param[in] FileSize File size of FileData.
|
||||
@param[out] Context Mach-O Context to initialize.
|
||||
@param[in] FileData Pointer to the file's expected Mach-O header.
|
||||
@param[in] FileSize File size of FileData.
|
||||
@param[in] ContainerOffset The amount of Bytes the Mach-O header is offset
|
||||
from the base (container, e.g. KC) of the file.
|
||||
|
||||
@return Whether Context has been initialized successfully.
|
||||
|
||||
@ -57,7 +60,8 @@ BOOLEAN
|
||||
MachoInitializeContext (
|
||||
OUT OC_MACHO_CONTEXT *Context,
|
||||
IN VOID *FileData,
|
||||
IN UINT32 FileSize
|
||||
IN UINT32 FileSize,
|
||||
IN UINT32 ContainerOffset
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@ -642,7 +642,8 @@ KcGetKextSize (
|
||||
Result = MachoInitializeContext (
|
||||
&KextContext,
|
||||
Context->Prelinked + KextOffset,
|
||||
Context->PrelinkedSize - KextOffset
|
||||
Context->PrelinkedSize - KextOffset,
|
||||
KextOffset
|
||||
);
|
||||
if (!Result) {
|
||||
return 0;
|
||||
|
||||
@ -64,7 +64,7 @@ PatcherInitContextFromBuffer (
|
||||
// and request PRELINK_KERNEL_IDENTIFIER.
|
||||
//
|
||||
|
||||
if (!MachoInitializeContext (&Context->MachContext, Buffer, BufferSize)) {
|
||||
if (!MachoInitializeContext (&Context->MachContext, Buffer, BufferSize, 0)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
||||
@ -1644,7 +1644,7 @@ InternalPrelinkKext64 (
|
||||
// Reinitialize the Mach-O context to account for the changed __LINKEDIT
|
||||
// segment and file size.
|
||||
//
|
||||
if (!MachoInitializeContext (MachoContext, MachHeader, (SegmentOffset + SegmentSize))) {
|
||||
if (!MachoInitializeContext (MachoContext, MachHeader, (SegmentOffset + SegmentSize), MachoContext->ContainerOffset)) {
|
||||
//
|
||||
// This should never failed under normal and abnormal conditions.
|
||||
//
|
||||
|
||||
@ -224,7 +224,7 @@ PrelinkedContextInit (
|
||||
//
|
||||
// Initialise primary context.
|
||||
//
|
||||
if (!MachoInitializeContext (&Context->PrelinkedMachContext, Prelinked, PrelinkedSize)) {
|
||||
if (!MachoInitializeContext (&Context->PrelinkedMachContext, Prelinked, PrelinkedSize, 0)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
@ -249,7 +249,8 @@ PrelinkedContextInit (
|
||||
if (!MachoInitializeContext (
|
||||
&Context->InnerMachContext,
|
||||
&Context->Prelinked[Segment->FileOffset],
|
||||
(UINT32) (Context->PrelinkedSize - Segment->FileOffset))) {
|
||||
(UINT32) (Context->PrelinkedSize - Segment->FileOffset),
|
||||
(UINT32) Segment->FileOffset)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
@ -679,7 +680,7 @@ PrelinkedReserveKextSize (
|
||||
|
||||
if (Executable != NULL) {
|
||||
ASSERT (ExecutableSize > 0);
|
||||
if (!MachoInitializeContext (&Context, Executable, ExecutableSize)) {
|
||||
if (!MachoInitializeContext (&Context, Executable, ExecutableSize, 0)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
@ -747,7 +748,7 @@ PrelinkedInjectKext (
|
||||
//
|
||||
if (Executable != NULL) {
|
||||
ASSERT (ExecutableSize > 0);
|
||||
if (!MachoInitializeContext (&ExecutableContext, (UINT8 *)Executable, ExecutableSize)) {
|
||||
if (!MachoInitializeContext (&ExecutableContext, (UINT8 *)Executable, ExecutableSize, 0)) {
|
||||
DEBUG ((DEBUG_INFO, "OCAK: Injected kext %a/%a is not a supported executable\n", BundlePath, ExecutablePath));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
@ -776,7 +777,7 @@ PrelinkedInjectKext (
|
||||
AlignedExecutableSize - ExecutableSize
|
||||
);
|
||||
|
||||
if (!MachoInitializeContext (&ExecutableContext, &Context->Prelinked[KextOffset], ExecutableSize)) {
|
||||
if (!MachoInitializeContext (&ExecutableContext, &Context->Prelinked[KextOffset], ExecutableSize, 0)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
||||
@ -56,6 +56,7 @@ InternalCreatePrelinkedKext (
|
||||
UINT64 SourceSize;
|
||||
UINT64 SourceEnd;
|
||||
BOOLEAN Found;
|
||||
UINT32 ContainerOffset;
|
||||
|
||||
KextIdentifier = NULL;
|
||||
BundleLibraries = NULL;
|
||||
@ -155,6 +156,11 @@ InternalCreatePrelinkedKext (
|
||||
SourceEnd > Prelinked->PrelinkedSize) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ContainerOffset = 0;
|
||||
if (Prelinked->IsKernelCollection) {
|
||||
ContainerOffset = (UINT32) SourceBase;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
@ -166,7 +172,7 @@ InternalCreatePrelinkedKext (
|
||||
}
|
||||
|
||||
if (Prelinked != NULL
|
||||
&& !MachoInitializeContext (&NewKext->Context.MachContext, &Prelinked->Prelinked[SourceBase], (UINT32)SourceSize)) {
|
||||
&& !MachoInitializeContext (&NewKext->Context.MachContext, &Prelinked->Prelinked[SourceBase], (UINT32)SourceSize, ContainerOffset)) {
|
||||
FreePool (NewKext);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -187,7 +187,8 @@ BOOLEAN
|
||||
MachoInitializeContext (
|
||||
OUT OC_MACHO_CONTEXT *Context,
|
||||
IN VOID *FileData,
|
||||
IN UINT32 FileSize
|
||||
IN UINT32 FileSize,
|
||||
IN UINT32 ContainerOffset
|
||||
)
|
||||
{
|
||||
MACH_HEADER_64 *MachHeader;
|
||||
@ -272,8 +273,9 @@ MachoInitializeContext (
|
||||
|
||||
ZeroMem (Context, sizeof (*Context));
|
||||
|
||||
Context->MachHeader = MachHeader;
|
||||
Context->FileSize = FileSize;
|
||||
Context->MachHeader = MachHeader;
|
||||
Context->FileSize = FileSize;
|
||||
Context->ContainerOffset = ContainerOffset;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -485,10 +487,15 @@ InternalSectionIsSane (
|
||||
}
|
||||
|
||||
if (Section->NumRelocations != 0) {
|
||||
Result = OcOverflowMulAddU32 (
|
||||
Result = OcOverflowSubU32 (
|
||||
Section->RelocationsOffset,
|
||||
Context->ContainerOffset,
|
||||
&TopOffset32
|
||||
);
|
||||
Result |= OcOverflowMulAddU32 (
|
||||
Section->NumRelocations,
|
||||
sizeof (MACH_RELOCATION_INFO),
|
||||
Section->RelocationsOffset,
|
||||
TopOffset32,
|
||||
&TopOffset32
|
||||
);
|
||||
if (Result || (TopOffset32 > Context->FileSize)) {
|
||||
@ -642,11 +649,16 @@ MachoGetNextSegment64 (
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Result = OcOverflowAddU64 (
|
||||
Result = OcOverflowSubU64 (
|
||||
NextSegment->FileOffset,
|
||||
NextSegment->FileSize,
|
||||
Context->ContainerOffset,
|
||||
&TopOfSegment
|
||||
);
|
||||
Result |= OcOverflowAddU64 (
|
||||
TopOfSegment,
|
||||
NextSegment->FileSize,
|
||||
&TopOfSegment
|
||||
);
|
||||
if (Result || (TopOfSegment > Context->FileSize)) {
|
||||
return NULL;
|
||||
}
|
||||
@ -821,9 +833,14 @@ InternalInitialiseSymtabs64 (
|
||||
UINTN MachoAddress;
|
||||
CHAR8 *StringTable;
|
||||
UINT32 FileSize;
|
||||
UINT32 SymbolsOffset;
|
||||
UINT32 StringsOffset;
|
||||
UINT32 OffsetTop;
|
||||
BOOLEAN Result;
|
||||
|
||||
UINT32 IndirectSymbolsOffset;
|
||||
UINT32 LocalRelocationsOffset;
|
||||
UINT32 ExternalRelocationsOffset;
|
||||
MACH_NLIST_64 *SymbolTable;
|
||||
MACH_NLIST_64 *IndirectSymtab;
|
||||
MACH_RELOCATION_INFO *LocalRelocations;
|
||||
@ -838,33 +855,43 @@ InternalInitialiseSymtabs64 (
|
||||
|
||||
FileSize = Context->FileSize;
|
||||
|
||||
Result = OcOverflowMulAddU32 (
|
||||
Symtab->NumSymbols,
|
||||
sizeof (MACH_NLIST_64),
|
||||
Result = OcOverflowSubU32 (
|
||||
Symtab->SymbolsOffset,
|
||||
&OffsetTop
|
||||
Context->ContainerOffset,
|
||||
&SymbolsOffset
|
||||
);
|
||||
Result |= OcOverflowMulAddU32 (
|
||||
Symtab->NumSymbols,
|
||||
sizeof (MACH_NLIST_64),
|
||||
SymbolsOffset,
|
||||
&OffsetTop
|
||||
);
|
||||
if (Result || (OffsetTop > FileSize)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Result = OcOverflowAddU32 (
|
||||
Result = OcOverflowSubU32 (
|
||||
Symtab->StringsOffset,
|
||||
Symtab->StringsSize,
|
||||
&OffsetTop
|
||||
Context->ContainerOffset,
|
||||
&StringsOffset
|
||||
);
|
||||
Result |= OcOverflowAddU32 (
|
||||
StringsOffset,
|
||||
Symtab->StringsSize,
|
||||
&OffsetTop
|
||||
);
|
||||
if (Result || (OffsetTop > FileSize)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
MachoAddress = (UINTN)Context->MachHeader;
|
||||
StringTable = (CHAR8 *)(MachoAddress + Symtab->StringsOffset);
|
||||
StringTable = (CHAR8 *)(MachoAddress + StringsOffset);
|
||||
|
||||
if (Symtab->StringsSize == 0 || StringTable[Symtab->StringsSize - 1] != '\0') {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Tmp = (VOID *)(MachoAddress + Symtab->SymbolsOffset);
|
||||
Tmp = (VOID *)(MachoAddress + SymbolsOffset);
|
||||
if (!OC_TYPE_ALIGNED (MACH_NLIST_64, Tmp)) {
|
||||
return FALSE;
|
||||
}
|
||||
@ -902,49 +929,64 @@ InternalInitialiseSymtabs64 (
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Result = OcOverflowMulAddU32 (
|
||||
DySymtab->NumIndirectSymbols,
|
||||
sizeof (MACH_NLIST_64),
|
||||
Result = OcOverflowSubU32 (
|
||||
DySymtab->IndirectSymbolsOffset,
|
||||
&OffsetTop
|
||||
Context->ContainerOffset,
|
||||
&IndirectSymbolsOffset
|
||||
);
|
||||
Result |= OcOverflowMulAddU32 (
|
||||
DySymtab->NumIndirectSymbols,
|
||||
sizeof (MACH_NLIST_64),
|
||||
IndirectSymbolsOffset,
|
||||
&OffsetTop
|
||||
);
|
||||
if (Result || (OffsetTop > FileSize)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Result = OcOverflowMulAddU32 (
|
||||
DySymtab->NumOfLocalRelocations,
|
||||
sizeof (MACH_RELOCATION_INFO),
|
||||
Result = OcOverflowSubU32 (
|
||||
DySymtab->LocalRelocationsOffset,
|
||||
&OffsetTop
|
||||
Context->ContainerOffset,
|
||||
&LocalRelocationsOffset
|
||||
);
|
||||
Result |= OcOverflowMulAddU32 (
|
||||
DySymtab->NumOfLocalRelocations,
|
||||
sizeof (MACH_RELOCATION_INFO),
|
||||
LocalRelocationsOffset,
|
||||
&OffsetTop
|
||||
);
|
||||
if (Result || (OffsetTop > FileSize)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Result = OcOverflowMulAddU32 (
|
||||
DySymtab->NumExternalRelocations,
|
||||
sizeof (MACH_RELOCATION_INFO),
|
||||
Result = OcOverflowSubU32 (
|
||||
DySymtab->ExternalRelocationsOffset,
|
||||
&OffsetTop
|
||||
Context->ContainerOffset,
|
||||
&ExternalRelocationsOffset
|
||||
);
|
||||
Result |= OcOverflowMulAddU32 (
|
||||
DySymtab->NumExternalRelocations,
|
||||
sizeof (MACH_RELOCATION_INFO),
|
||||
ExternalRelocationsOffset,
|
||||
&OffsetTop
|
||||
);
|
||||
if (Result || (OffsetTop > FileSize)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Tmp = (VOID *)(MachoAddress + DySymtab->IndirectSymbolsOffset);
|
||||
Tmp = (VOID *)(MachoAddress + IndirectSymbolsOffset);
|
||||
if (!OC_TYPE_ALIGNED (MACH_NLIST_64, Tmp)) {
|
||||
return FALSE;
|
||||
}
|
||||
IndirectSymtab = (MACH_NLIST_64 *)Tmp;
|
||||
|
||||
Tmp = (VOID *)(MachoAddress + DySymtab->LocalRelocationsOffset);
|
||||
Tmp = (VOID *)(MachoAddress + LocalRelocationsOffset);
|
||||
if (!OC_TYPE_ALIGNED (MACH_RELOCATION_INFO, Tmp)) {
|
||||
return FALSE;
|
||||
}
|
||||
LocalRelocations = (MACH_RELOCATION_INFO *)Tmp;
|
||||
|
||||
Tmp = (VOID *)(MachoAddress + DySymtab->ExternalRelocationsOffset);
|
||||
Tmp = (VOID *)(MachoAddress + ExternalRelocationsOffset);
|
||||
if (!OC_TYPE_ALIGNED (MACH_RELOCATION_INFO, Tmp)) {
|
||||
return FALSE;
|
||||
}
|
||||
@ -1176,7 +1218,7 @@ MachoGetFilePointerByAddress64 (
|
||||
*MaxSize = (UINT32)(Segment->Size - Offset);
|
||||
}
|
||||
|
||||
Offset += Segment->FileOffset;
|
||||
Offset += Segment->FileOffset - Context->ContainerOffset;
|
||||
return (VOID *)((UINTN)Context->MachHeader + (UINTN)Offset);
|
||||
}
|
||||
}
|
||||
@ -1322,7 +1364,7 @@ MachoExpandImage64 (
|
||||
//
|
||||
// Do not overwrite header.
|
||||
//
|
||||
CopyFileOffset = Segment->FileOffset;
|
||||
CopyFileOffset = Segment->FileOffset - Context->ContainerOffset;
|
||||
CopyFileSize = Segment->FileSize;
|
||||
CopyVmSize = Segment->Size;
|
||||
if (CopyFileOffset <= HeaderSize) {
|
||||
@ -1359,7 +1401,7 @@ MachoExpandImage64 (
|
||||
DstSegment->FileOffset += CurrentDelta;
|
||||
DstSegment->FileSize = DstSegment->Size;
|
||||
|
||||
if (DstSegment->VirtualAddress - DstSegment->FileOffset != FirstSegment->VirtualAddress) {
|
||||
if (DstSegment->VirtualAddress - (DstSegment->FileOffset - Context->ContainerOffset) != FirstSegment->VirtualAddress) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -662,7 +662,7 @@ MachoSymbolGetFileOffset64 (
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*FileOffset = (Section->Offset + (UINT32)Offset);
|
||||
*FileOffset = (Section->Offset - Context->ContainerOffset + (UINT32)Offset);
|
||||
|
||||
if (MaxSize != NULL) {
|
||||
*MaxSize = (UINT32)(Section->Size - Offset);
|
||||
|
||||
@ -49,7 +49,7 @@ extern UINT32 VsmcKextInfoPlistDataSize;
|
||||
|
||||
static int FeedMacho(void *file, uint32_t size) {
|
||||
OC_MACHO_CONTEXT Context;
|
||||
if (!MachoInitializeContext (&Context, file, size)) {
|
||||
if (!MachoInitializeContext (&Context, file, size, 0)) {
|
||||
DEBUG ((DEBUG_WARN, "MachoInitializeContext failure\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ MACH_UUID_COMMAND Uuid;
|
||||
|
||||
static int FeedMacho(void *file, uint32_t size) {
|
||||
OC_MACHO_CONTEXT Context;
|
||||
if (!MachoInitializeContext (&Context, file, size)) {
|
||||
if (!MachoInitializeContext (&Context, file, size, 0)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user