Skip to content

Commit

Permalink
OcMachoLib: Treat container Mach-O as reference file
Browse files Browse the repository at this point in the history
  • Loading branch information
mhaeuser committed Jul 7, 2022
1 parent 1b24da4 commit 7dfca8e
Show file tree
Hide file tree
Showing 16 changed files with 223 additions and 171 deletions.
10 changes: 6 additions & 4 deletions Include/Acidanthera/Library/OcAppleKernelLib.h
Expand Up @@ -1004,16 +1004,18 @@ KcGetKextSize (
/**
Apply the delta from KC header to the file's offsets.
@param[in,out] Context The context of the KEXT to rebase.
@param[in] Delta The offset from KC header the KEXT starts at.
@param[in] PrelinkedContext Prelinked context.
@param[in,out] Context The context of the KEXT to rebase.
@param[in] Delta The offset from KC header the KEXT starts at.
@retval EFI_SUCCESS The file has beem rebased successfully.
@retval other An error has occured.
**/
EFI_STATUS
KcKextApplyFileDelta (
IN OUT OC_MACHO_CONTEXT *Context,
IN UINT32 Delta
IN PRELINKED_CONTEXT *PrelinkedContext,
IN OUT OC_MACHO_CONTEXT *Context,
IN UINT32 Delta
);

/**
Expand Down
71 changes: 50 additions & 21 deletions Include/Acidanthera/Library/OcMachoLib.h
Expand Up @@ -32,10 +32,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
/// only. Members are not guaranteed to be sane.
///
typedef struct {
MACH_HEADER_ANY *MachHeader;
VOID *FileData;
UINT32 FileSize;

UINT32 ContainerOffset;
MACH_HEADER_ANY *MachHeader;
UINT32 InnerSize;
MACH_SYMTAB_COMMAND *Symtab;
MACH_NLIST_ANY *SymbolTable;
CHAR8 *StringTable;
Expand All @@ -50,11 +51,12 @@ typedef struct {
/**
Initializes a 32-bit Mach-O Context.
@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.
@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] HeaderOffset The amount of Bytes the Mach-O header is offset from
the base (container, e.g. KC) of the file.
@param[in] InnerSize The size, in Bytes, of the inner Mach-O file.
@return Whether Context has been initialized successfully.
Expand All @@ -64,17 +66,19 @@ MachoInitializeContext32 (
OUT OC_MACHO_CONTEXT *Context,
IN VOID *FileData,
IN UINT32 FileSize,
IN UINT32 ContainerOffset
IN UINT32 HeaderOffset,
IN UINT32 InnerSize
);

/**
Initializes a 64-bit Mach-O Context.
@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.
@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] HeaderOffset The amount of Bytes the Mach-O header is offset from
the base (container, e.g. KC) of the file.
@param[in] InnerSize The size, in Bytes, of the inner Mach-O file.
@return Whether Context has been initialized successfully.
Expand All @@ -84,18 +88,20 @@ MachoInitializeContext64 (
OUT OC_MACHO_CONTEXT *Context,
IN VOID *FileData,
IN UINT32 FileSize,
IN UINT32 ContainerOffset
IN UINT32 HeaderOffset,
IN UINT32 InnerSize
);

/**
Initializes a Mach-O Context.
@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.
@param[in] Is32Bit TRUE if Mach-O is 32-bit.
@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] HeaderOffset The amount of Bytes the Mach-O header is offset from
the base (container, e.g. KC) of the file.
@param[in] InnerSize The size, in Bytes, of the inner Mach-O file.
@param[in] Is32Bit TRUE if Mach-O is 32-bit.
@return Whether Context has been initialized successfully.
Expand All @@ -105,7 +111,8 @@ MachoInitializeContext (
OUT OC_MACHO_CONTEXT *Context,
IN VOID *FileData,
IN UINT32 FileSize,
IN UINT32 ContainerOffset,
IN UINT32 HeaderOffset,
IN UINT32 InnerSize,
IN BOOLEAN Is32Bit
);

Expand All @@ -120,6 +127,17 @@ MachoGetMachHeader (
IN OUT OC_MACHO_CONTEXT *Context
);

/**
Returns the size of the inner Mach-O file (otherwise, the file size).
@param[in,out] Context Context of the Mach-O.
**/
UINT32
MachoGetInnerSize (
IN OUT OC_MACHO_CONTEXT *Context
);

/**
Returns the 32-bit Mach-O Header structure.
Expand All @@ -142,6 +160,17 @@ MachoGetMachHeader64 (
IN OUT OC_MACHO_CONTEXT *Context
);

/**
Returns the file data of the Mach-O.
@param[in,out] Context Context of the Mach-O.
**/
VOID *
MachoGetFileData (
IN OUT OC_MACHO_CONTEXT *Context
);

/**
Returns the Mach-O's file size.
Expand Down
18 changes: 9 additions & 9 deletions Library/OcAppleKernelLib/CommonPatches.c
Expand Up @@ -77,7 +77,7 @@ PatchAppleCpuPmCfgLock (

Count = 0;
Walker = (UINT8 *)MachoGetMachHeader (&Patcher->MachContext);
WalkerEnd = Walker + MachoGetFileSize (&Patcher->MachContext) - mWrmsrMaxDistance;
WalkerEnd = Walker + MachoGetInnerSize (&Patcher->MachContext) - mWrmsrMaxDistance;

//
// Thanks to Clover developers for the approach.
Expand Down Expand Up @@ -254,7 +254,7 @@ PatchAppleXcpmCfgLock (
}

Last = (XCPM_MSR_RECORD *)((UINT8 *)MachoGetMachHeader (&Patcher->MachContext)
+ MachoGetFileSize (&Patcher->MachContext) - sizeof (XCPM_MSR_RECORD));
+ MachoGetInnerSize (&Patcher->MachContext) - sizeof (XCPM_MSR_RECORD));

Replacements = 0;

Expand Down Expand Up @@ -381,7 +381,7 @@ PatchAppleXcpmExtraMsrs (
}

Last = (XCPM_MSR_RECORD *)((UINT8 *)MachoGetMachHeader (&Patcher->MachContext)
+ MachoGetFileSize (&Patcher->MachContext) - sizeof (XCPM_MSR_RECORD));
+ MachoGetInnerSize (&Patcher->MachContext) - sizeof (XCPM_MSR_RECORD));

Replacements = 0;

Expand Down Expand Up @@ -509,7 +509,7 @@ PatchAppleXcpmForceBoost (
}

Start = (UINT8 *)MachoGetMachHeader (&Patcher->MachContext);
Last = Start + MachoGetFileSize (&Patcher->MachContext) - EFI_PAGE_SIZE * 2;
Last = Start + MachoGetInnerSize (&Patcher->MachContext) - EFI_PAGE_SIZE * 2;
Start += EFI_PAGE_SIZE;
Current = Start;

Expand Down Expand Up @@ -1190,7 +1190,7 @@ PatchCustomPciSerialPmio (

Count = 0;
Walker = (UINT8 *)MachoGetMachHeader (&Patcher->MachContext);
WalkerEnd = Walker + MachoGetFileSize (&Patcher->MachContext) - mInOutMaxDistance;
WalkerEnd = Walker + MachoGetInnerSize (&Patcher->MachContext) - mInOutMaxDistance;

while (Walker < WalkerEnd) {
if ( (Walker[0] == mSerialDevicePmioFind[0])
Expand Down Expand Up @@ -1385,7 +1385,7 @@ PatchPanicKextDump (
}

Last = ((UINT8 *)MachoGetMachHeader (&Patcher->MachContext)
+ MachoGetFileSize (&Patcher->MachContext) - EFI_PAGE_SIZE);
+ MachoGetInnerSize (&Patcher->MachContext) - EFI_PAGE_SIZE);

//
// This should work on 10.15 and all debug kernels.
Expand Down Expand Up @@ -1811,7 +1811,7 @@ PatchSegmentJettison (
}

Last = (UINT8 *)MachoGetMachHeader (&Patcher->MachContext)
+ MachoGetFileSize (&Patcher->MachContext) - sizeof (EFI_PAGE_SIZE) * 2;
+ MachoGetInnerSize (&Patcher->MachContext) - sizeof (EFI_PAGE_SIZE) * 2;

Status = PatcherGetSymbolAddress (Patcher, "__ZN6OSKext19removeKextBootstrapEv", (UINT8 **)&RemoveBs);
if (EFI_ERROR (Status) || (RemoveBs > Last)) {
Expand Down Expand Up @@ -2055,7 +2055,7 @@ PatchLegacyCommpage (
ASSERT (Patcher != NULL);

Start = ((UINT8 *)MachoGetMachHeader (&Patcher->MachContext));
Last = Start + MachoGetFileSize (&Patcher->MachContext) - EFI_PAGE_SIZE * 2 - (Patcher->Is32Bit ? sizeof (COMMPAGE_DESCRIPTOR) : sizeof (COMMPAGE_DESCRIPTOR_64));
Last = Start + MachoGetInnerSize (&Patcher->MachContext) - EFI_PAGE_SIZE * 2 - (Patcher->Is32Bit ? sizeof (COMMPAGE_DESCRIPTOR) : sizeof (COMMPAGE_DESCRIPTOR_64));

//
// This is a table of pointers to commpage entries.
Expand Down Expand Up @@ -2294,7 +2294,7 @@ PatchForceSecureBootScheme (
//

Last = ((UINT8 *)MachoGetMachHeader (&Patcher->MachContext)
+ MachoGetFileSize (&Patcher->MachContext) - 64);
+ MachoGetInnerSize (&Patcher->MachContext) - 64);

Status = PatcherGetSymbolAddress (Patcher, "_img4_chip_select_effective_ap", &SelectAp);
if (EFI_ERROR (Status) || (SelectAp > Last)) {
Expand Down
2 changes: 1 addition & 1 deletion Library/OcAppleKernelLib/CpuidPatches.c
Expand Up @@ -815,7 +815,7 @@ PatchKernelCpuId (
);

Start = ((UINT8 *)MachoGetMachHeader (&Patcher->MachContext));
Last = Start + MachoGetFileSize (&Patcher->MachContext) - EFI_PAGE_SIZE * 2 - sizeof (mKernelCpuIdFindRelNew);
Last = Start + MachoGetInnerSize (&Patcher->MachContext) - EFI_PAGE_SIZE * 2 - sizeof (mKernelCpuIdFindRelNew);

//
// Do legacy patching for 32-bit 10.7, and 10.6 and older.
Expand Down
19 changes: 11 additions & 8 deletions Library/OcAppleKernelLib/KernelCollection.c
Expand Up @@ -565,6 +565,7 @@ KcKextIndexFixups (
CONST MACH_SEGMENT_COMMAND_64 *FirstSegment;
MACH_HEADER_64 *MachHeader;
CONST MACH_RELOCATION_INFO *Relocations;
VOID *FileData;
UINT32 RelocIndex;

ASSERT (Context != NULL);
Expand Down Expand Up @@ -616,8 +617,9 @@ KcKextIndexFixups (
//
// Convert all relocations to fixups.
//
FileData = MachoGetFileData (MachContext);
Relocations = (MACH_RELOCATION_INFO *)(
(UINTN)MachHeader + DySymtab->LocalRelocationsOffset
(UINTN)FileData + DySymtab->LocalRelocationsOffset
);

DEBUG ((
Expand All @@ -643,14 +645,11 @@ KcGetKextSize (
IN UINT64 SourceAddress
)
{
MACH_HEADER_64 *KcHeader;
MACH_SEGMENT_COMMAND_64 *Segment;

ASSERT (Context != NULL);
ASSERT (Context->IsKernelCollection);

KcHeader = MachoGetMachHeader64 (&Context->PrelinkedMachContext);
ASSERT (KcHeader != NULL);
//
// Find the KC segment that contains the KEXT at SourceAddress.
//
Expand Down Expand Up @@ -683,8 +682,9 @@ KcGetKextSize (

EFI_STATUS
KcKextApplyFileDelta (
IN OUT OC_MACHO_CONTEXT *Context,
IN UINT32 Delta
IN PRELINKED_CONTEXT *PrelinkedContext,
IN OUT OC_MACHO_CONTEXT *Context,
IN UINT32 Delta
)
{
MACH_HEADER_64 *KextHeader;
Expand All @@ -695,6 +695,7 @@ KcKextApplyFileDelta (
MACH_DYSYMTAB_COMMAND *DySymtab;
UINT32 SectIndex;

ASSERT (PrelinkedContext != NULL);
ASSERT (Context != NULL);
ASSERT (Delta > 0);

Expand Down Expand Up @@ -786,9 +787,11 @@ KcKextApplyFileDelta (

//
// Update the container offset to make sure we can link against this
// kext later as well.
// kext later as well. Context->InnerSize remains unchanged and is the actual
// size of the kext.
//
Context->ContainerOffset = Delta;
Context->FileData = PrelinkedContext->Prelinked;
Context->FileSize = PrelinkedContext->PrelinkedSize;

return EFI_SUCCESS;
}
Expand Down
8 changes: 4 additions & 4 deletions Library/OcAppleKernelLib/KextPatcher.c
Expand Up @@ -155,7 +155,7 @@ PatcherInitContextFromBuffer (
// and request PRELINK_KERNEL_IDENTIFIER.
//

if (!MachoInitializeContext (&Context->MachContext, Buffer, BufferSize, 0, Is32Bit)) {
if (!MachoInitializeContext (&Context->MachContext, Buffer, BufferSize, 0, BufferSize, Is32Bit)) {
DEBUG ((
DEBUG_INFO,
"OCAK: %a-bit patcher init from buffer %p %u has unsupported mach-o\n",
Expand Down Expand Up @@ -273,7 +273,7 @@ PatcherGetSymbolAddress (
Index++;
}

*Address = (UINT8 *)MachoGetMachHeader (&Context->MachContext) + Offset;
*Address = (UINT8 *)MachoGetFileData (&Context->MachContext) + Offset;
return EFI_SUCCESS;
}

Expand All @@ -289,7 +289,7 @@ PatcherApplyGenericPatch (
UINT32 ReplaceCount;

Base = (UINT8 *)MachoGetMachHeader (&Context->MachContext);
Size = MachoGetFileSize (&Context->MachContext);
Size = MachoGetInnerSize (&Context->MachContext);
if (Patch->Base != NULL) {
Status = PatcherGetSymbolAddress (Context, Patch->Base, &Base);
if (EFI_ERROR (Status)) {
Expand Down Expand Up @@ -520,7 +520,7 @@ PatcherBlockKext (
}

MachBase = (UINT8 *)MachoGetMachHeader (&Context->MachContext);
MachSize = MachoGetFileSize (&Context->MachContext);
MachSize = MachoGetInnerSize (&Context->MachContext);

//
// Determine offset of kmod within file.
Expand Down

0 comments on commit 7dfca8e

Please sign in to comment.