Skip to content

Commit 87b4e64

Browse files
committed
OcMachoLib: Treat container Mach-O as reference file, by mhaeuser
Signed-off-by: SergeySlice <sergey.slice@gmail.com>
1 parent 1a1bdaf commit 87b4e64

16 files changed

Lines changed: 246 additions & 186 deletions

File tree

Include/Acidanthera/Library/OcAppleKernelLib.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,16 +1004,18 @@ KcGetKextSize (
10041004
/**
10051005
Apply the delta from KC header to the file's offsets.
10061006
1007-
@param[in,out] Context The context of the KEXT to rebase.
1008-
@param[in] Delta The offset from KC header the KEXT starts at.
1007+
@param[in] PrelinkedContext Prelinked context.
1008+
@param[in,out] Context The context of the KEXT to rebase.
1009+
@param[in] Delta The offset from KC header the KEXT starts at.
10091010
10101011
@retval EFI_SUCCESS The file has beem rebased successfully.
10111012
@retval other An error has occured.
10121013
**/
10131014
EFI_STATUS
10141015
KcKextApplyFileDelta (
1015-
IN OUT OC_MACHO_CONTEXT *Context,
1016-
IN UINT32 Delta
1016+
IN PRELINKED_CONTEXT *PrelinkedContext,
1017+
IN OUT OC_MACHO_CONTEXT *Context,
1018+
IN UINT32 Delta
10171019
);
10181020

10191021
/**

Include/Acidanthera/Library/OcMachoLib.h

Lines changed: 50 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
3232
/// only. Members are not guaranteed to be sane.
3333
///
3434
typedef struct {
35-
MACH_HEADER_ANY *MachHeader;
35+
VOID *FileData;
3636
UINT32 FileSize;
3737

38-
UINT32 ContainerOffset;
38+
MACH_HEADER_ANY *MachHeader;
39+
UINT32 InnerSize;
3940
MACH_SYMTAB_COMMAND *Symtab;
4041
MACH_NLIST_ANY *SymbolTable;
4142
CHAR8 *StringTable;
@@ -50,11 +51,12 @@ typedef struct {
5051
/**
5152
Initializes a 32-bit Mach-O Context.
5253
53-
@param[out] Context Mach-O Context to initialize.
54-
@param[in] FileData Pointer to the file's expected Mach-O header.
55-
@param[in] FileSize File size of FileData.
56-
@param[in] ContainerOffset The amount of Bytes the Mach-O header is offset
57-
from the base (container, e.g. KC) of the file.
54+
@param[out] Context Mach-O Context to initialize.
55+
@param[in] FileData Pointer to the file's expected Mach-O header.
56+
@param[in] FileSize File size of FileData.
57+
@param[in] HeaderOffset The amount of Bytes the Mach-O header is offset from
58+
the base (container, e.g. KC) of the file.
59+
@param[in] InnerSize The size, in Bytes, of the inner Mach-O file.
5860
5961
@return Whether Context has been initialized successfully.
6062
@@ -64,17 +66,19 @@ MachoInitializeContext32 (
6466
OUT OC_MACHO_CONTEXT *Context,
6567
IN VOID *FileData,
6668
IN UINT32 FileSize,
67-
IN UINT32 ContainerOffset
69+
IN UINT32 HeaderOffset,
70+
IN UINT32 InnerSize
6871
);
6972

7073
/**
7174
Initializes a 64-bit Mach-O Context.
7275
73-
@param[out] Context Mach-O Context to initialize.
74-
@param[in] FileData Pointer to the file's expected Mach-O header.
75-
@param[in] FileSize File size of FileData.
76-
@param[in] ContainerOffset The amount of Bytes the Mach-O header is offset
77-
from the base (container, e.g. KC) of the file.
76+
@param[out] Context Mach-O Context to initialize.
77+
@param[in] FileData Pointer to the file's expected Mach-O header.
78+
@param[in] FileSize File size of FileData.
79+
@param[in] HeaderOffset The amount of Bytes the Mach-O header is offset from
80+
the base (container, e.g. KC) of the file.
81+
@param[in] InnerSize The size, in Bytes, of the inner Mach-O file.
7882
7983
@return Whether Context has been initialized successfully.
8084
@@ -84,18 +88,20 @@ MachoInitializeContext64 (
8488
OUT OC_MACHO_CONTEXT *Context,
8589
IN VOID *FileData,
8690
IN UINT32 FileSize,
87-
IN UINT32 ContainerOffset
91+
IN UINT32 HeaderOffset,
92+
IN UINT32 InnerSize
8893
);
8994

9095
/**
9196
Initializes a Mach-O Context.
9297
93-
@param[out] Context Mach-O Context to initialize.
94-
@param[in] FileData Pointer to the file's expected Mach-O header.
95-
@param[in] FileSize File size of FileData.
96-
@param[in] ContainerOffset The amount of Bytes the Mach-O header is offset
97-
from the base (container, e.g. KC) of the file.
98-
@param[in] Is32Bit TRUE if Mach-O is 32-bit.
98+
@param[out] Context Mach-O Context to initialize.
99+
@param[in] FileData Pointer to the file's expected Mach-O header.
100+
@param[in] FileSize File size of FileData.
101+
@param[in] HeaderOffset The amount of Bytes the Mach-O header is offset from
102+
the base (container, e.g. KC) of the file.
103+
@param[in] InnerSize The size, in Bytes, of the inner Mach-O file.
104+
@param[in] Is32Bit TRUE if Mach-O is 32-bit.
99105
100106
@return Whether Context has been initialized successfully.
101107
@@ -105,7 +111,8 @@ MachoInitializeContext (
105111
OUT OC_MACHO_CONTEXT *Context,
106112
IN VOID *FileData,
107113
IN UINT32 FileSize,
108-
IN UINT32 ContainerOffset,
114+
IN UINT32 HeaderOffset,
115+
IN UINT32 InnerSize,
109116
IN BOOLEAN Is32Bit
110117
);
111118

@@ -120,6 +127,17 @@ MachoGetMachHeader (
120127
IN OUT OC_MACHO_CONTEXT *Context
121128
);
122129

130+
/**
131+
Returns the size of the inner Mach-O file (otherwise, the file size).
132+
133+
@param[in,out] Context Context of the Mach-O.
134+
135+
**/
136+
UINT32
137+
MachoGetInnerSize (
138+
IN OUT OC_MACHO_CONTEXT *Context
139+
);
140+
123141
/**
124142
Returns the 32-bit Mach-O Header structure.
125143
@@ -142,6 +160,17 @@ MachoGetMachHeader64 (
142160
IN OUT OC_MACHO_CONTEXT *Context
143161
);
144162

163+
/**
164+
Returns the file data of the Mach-O.
165+
166+
@param[in,out] Context Context of the Mach-O.
167+
168+
**/
169+
VOID *
170+
MachoGetFileData (
171+
IN OUT OC_MACHO_CONTEXT *Context
172+
);
173+
145174
/**
146175
Returns the Mach-O's file size.
147176

Library/OcAppleKernelLib/CommonPatches.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ PatchAppleCpuPmCfgLock (
6969

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

7474
//
7575
// Thanks to Clover developers for the approach.
@@ -243,7 +243,7 @@ PatchAppleXcpmCfgLock (
243243
}
244244

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

248248
Replacements = 0;
249249

@@ -367,7 +367,7 @@ PatchAppleXcpmExtraMsrs (
367367
}
368368

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

372372
Replacements = 0;
373373

@@ -492,7 +492,7 @@ PatchAppleXcpmForceBoost (
492492
}
493493

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

@@ -1144,7 +1144,7 @@ PatchCustomPciSerialPmio (
11441144

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

11491149
while (Walker < WalkerEnd) {
11501150
if ( (Walker[0] == mSerialDevicePmioFind[0])
@@ -1328,7 +1328,7 @@ PatchPanicKextDump (
13281328
}
13291329

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

13331333
//
13341334
// This should work on 10.15 and all debug kernels.
@@ -1740,7 +1740,7 @@ PatchSegmentJettison (
17401740
}
17411741

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

17451745
Status = PatcherGetSymbolAddress (Patcher, "__ZN6OSKext19removeKextBootstrapEv", (UINT8 **)&RemoveBs);
17461746
if (EFI_ERROR (Status) || (RemoveBs > Last)) {
@@ -1978,7 +1978,7 @@ PatchLegacyCommpage (
19781978
ASSERT (Patcher != NULL);
19791979

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

19831983
//
19841984
// This is a table of pointers to commpage entries.
@@ -2211,7 +2211,7 @@ PatchForceSecureBootScheme (
22112211
//
22122212

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

22162216
Status = PatcherGetSymbolAddress (Patcher, "_img4_chip_select_effective_ap", &SelectAp);
22172217
if (EFI_ERROR (Status) || (SelectAp > Last)) {

Library/OcAppleKernelLib/CpuidPatches.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,7 @@ PatchKernelCpuId (
815815
);
816816

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

820820
//
821821
// Do legacy patching for 32-bit 10.7, and 10.6 and older.

Library/OcAppleKernelLib/KernelCollection.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,7 @@ KcKextIndexFixups (
565565
CONST MACH_SEGMENT_COMMAND_64 *FirstSegment;
566566
MACH_HEADER_64 *MachHeader;
567567
CONST MACH_RELOCATION_INFO *Relocations;
568+
VOID *FileData;
568569
UINT32 RelocIndex;
569570

570571
ASSERT (Context != NULL);
@@ -616,8 +617,9 @@ KcKextIndexFixups (
616617
//
617618
// Convert all relocations to fixups.
618619
//
620+
FileData = MachoGetFileData (MachContext);
619621
Relocations = (MACH_RELOCATION_INFO *)(
620-
(UINTN)MachHeader + DySymtab->LocalRelocationsOffset
622+
(UINTN)FileData + DySymtab->LocalRelocationsOffset
621623
);
622624

623625
DEBUG ((
@@ -643,14 +645,11 @@ KcGetKextSize (
643645
IN UINT64 SourceAddress
644646
)
645647
{
646-
MACH_HEADER_64 *KcHeader;
647648
MACH_SEGMENT_COMMAND_64 *Segment;
648649

649650
ASSERT (Context != NULL);
650651
ASSERT (Context->IsKernelCollection);
651652

652-
KcHeader = MachoGetMachHeader64 (&Context->PrelinkedMachContext);
653-
ASSERT (KcHeader != NULL);
654653
//
655654
// Find the KC segment that contains the KEXT at SourceAddress.
656655
//
@@ -683,8 +682,9 @@ KcGetKextSize (
683682

684683
EFI_STATUS
685684
KcKextApplyFileDelta (
686-
IN OUT OC_MACHO_CONTEXT *Context,
687-
IN UINT32 Delta
685+
IN PRELINKED_CONTEXT *PrelinkedContext,
686+
IN OUT OC_MACHO_CONTEXT *Context,
687+
IN UINT32 Delta
688688
)
689689
{
690690
MACH_HEADER_64 *KextHeader;
@@ -695,6 +695,7 @@ KcKextApplyFileDelta (
695695
MACH_DYSYMTAB_COMMAND *DySymtab;
696696
UINT32 SectIndex;
697697

698+
ASSERT (PrelinkedContext != NULL);
698699
ASSERT (Context != NULL);
699700
ASSERT (Delta > 0);
700701

@@ -786,9 +787,11 @@ KcKextApplyFileDelta (
786787

787788
//
788789
// Update the container offset to make sure we can link against this
789-
// kext later as well.
790+
// kext later as well. Context->InnerSize remains unchanged and is the actual
791+
// size of the kext.
790792
//
791-
Context->ContainerOffset = Delta;
793+
Context->FileData = PrelinkedContext->Prelinked;
794+
Context->FileSize = PrelinkedContext->PrelinkedSize;
792795

793796
return EFI_SUCCESS;
794797
}

Library/OcAppleKernelLib/KextPatcher.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ PatcherInitContextFromBuffer (
155155
// and request PRELINK_KERNEL_IDENTIFIER.
156156
//
157157

158-
if (!MachoInitializeContext (&Context->MachContext, Buffer, BufferSize, 0, Is32Bit)) {
158+
if (!MachoInitializeContext (&Context->MachContext, Buffer, BufferSize, 0, BufferSize, Is32Bit)) {
159159
DEBUG ((
160160
DEBUG_INFO,
161161
"OCAK: %a-bit patcher init from buffer %p %u has unsupported mach-o\n",
@@ -279,7 +279,7 @@ PatcherGetSymbolAddress (
279279
Index++;
280280
}
281281

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

@@ -295,7 +295,7 @@ PatcherApplyGenericPatch (
295295
UINT32 ReplaceCount;
296296

297297
Base = (UINT8 *)MachoGetMachHeader (&Context->MachContext);
298-
Size = MachoGetFileSize (&Context->MachContext);
298+
Size = MachoGetInnerSize (&Context->MachContext);
299299
if (Patch->Base != NULL) {
300300
Status = PatcherGetSymbolAddress (Context, Patch->Base, &Base);
301301
if (EFI_ERROR (Status)) {
@@ -526,7 +526,7 @@ PatcherBlockKext (
526526
}
527527

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

531531
//
532532
// Determine offset of kmod within file.

0 commit comments

Comments
 (0)