提交 70c55e03 编写于 作者: V vit9696

OcAppleKernelLib: Implement CPUID patching for 10.6 64-bit

上级 b5dcbd32
......@@ -42,6 +42,11 @@ prelinkedkernel.unpack
*.dmg
*.chunklist
*.pyc
*.id0
*.id1
*.id2
*.nam
*.til
Debug/QemuRun
Doxy
Legacy/BinDrivers/X64
......
......@@ -86,6 +86,11 @@
//
#define PLIST_EXPANSION_SIZE 512
//
// Make integral kernel version.
//
#define KERNEL_VERSION(A, B, C) ((A) * 10000 + (B) * 100 + (C))
//
// Prelinked context used for kernel modification.
//
......@@ -420,6 +425,50 @@ ReadAppleKernel (
OUT UINT8 *Digest OPTIONAL
);
/**
Create Apple kernel version in integer format.
See KERNEL_VERSION on how to build it from integers.
@param[in] String Apple kernel version.
@returns Kernel version or 0.
**/
UINT32
OcParseDarwinVersion (
IN CONST CHAR8 *String
);
/**
Read Apple kernel version in integer format.
@param[in] Kernel Apple kernel binary.
@param[in] KernelSize Apple kernel size.
@returns Kernel version or 0.
**/
UINT32
OcKernelReadDarwinVersion (
IN CONST UINT8 *Kernel,
IN UINT32 KernelSize
);
/**
Check whether min <= current <= max is true.
When current or max are 0 they are considered infinite.
@param[in] CurrentVersion Current kernel version.
@param[in] MinVersion Minimal kernel version.
@param[in] MaxVersion Maximum kernel version.
@returns TRUE on match.
**/
BOOLEAN
OcMatchDarwinVersion (
IN UINT32 CurrentVersion OPTIONAL,
IN UINT32 MinVersion OPTIONAL,
IN UINT32 MaxVersion OPTIONAL
);
/**
Construct prelinked context for later modification.
Must be freed with PrelinkedContextFree on success.
......
......@@ -983,13 +983,28 @@ PatchIncreasePciBarSize (
STATIC
CONST UINT8
mKernelCpuIdFindRelNew[] = {
0xB9, 0x8B, 0x00, 0x00, 0x00, 0x31, 0xC0, 0x31, 0xD2, 0x0F, 0x30, 0xB8, 0x01, 0x00, 0x00, 0x00, 0x31, 0xDB, 0x31, 0xC9, 0x31, 0xD2, 0x0F, 0xA2
0xB9, 0x8B, 0x00, 0x00, 0x00, ///< mov ecx, 8Bh
0x31, 0xC0, ///< xor eax, eax
0x31, 0xD2, ///< xor edx, edx
0x0F, 0x30, ///< wrmsr
0xB8, 0x01, 0x00, 0x00, 0x00, ///< mov eax, 1
0x31, 0xDB, ///< xor ebx, ebx
0x31, 0xC9, ///< xor ecx, ecx
0x31, 0xD2, ///< xor edx, edx
0x0F, 0xA2 ///< cpuid
};
STATIC
CONST UINT8
mKernelCpuIdFindRelOld[] = {
0xB9, 0x8B, 0x00, 0x00, 0x00, 0x31, 0xD2, 0x0F, 0x30, 0xB8, 0x01, 0x00, 0x00, 0x00, 0x31, 0xDB, 0x31, 0xC9, 0x31, 0xD2, 0x0F, 0xA2
0xB9, 0x8B, 0x00, 0x00, 0x00, ///< mov ecx, 8Bh
0x31, 0xD2, ///< xor edx, edx
0x0F, 0x30, ///< wrmsr
0xB8, 0x01, 0x00, 0x00, 0x00, ///< mov eax, 1
0x31, 0xDB, ///< xor ebx, ebx
0x31, 0xC9, ///< xor ecx, ecx
0x31, 0xD2, ///< xor edx, edx
0x0F, 0xA2 ///< cpuid
};
STATIC
......@@ -1073,6 +1088,197 @@ typedef struct {
#pragma pack(pop)
STATIC
EFI_STATUS
PatchKernelCpuIdLegacy (
IN OUT PATCHER_CONTEXT *Patcher,
IN OC_CPU_INFO *CpuInfo,
IN UINT32 *Data,
IN UINT32 *DataMask,
IN UINT8 *Record
)
{
UINT8 *StartPointer;
UINT8 *EndPointer;
UINT8 *Location;
UINT32 Signature[3];
UINT32 Index;
UINT32 MaxExt;
INT32 Delta;
INTERNAL_CPUID_PATCH Patch;
STATIC CONST UINT8 mKernelCpuidFindLegacyStart[8] = {
0xBA, 0x04, 0x00, 0x00, 0x00, ///< mov edx, 4
0x48, 0x8D, 0x35 ///< lea rsi from lea rsi, byte_FFFFFF80006C5900
};
for (Index = 0; Index < EFI_PAGE_SIZE; ++Index, ++Record) {
if (Record[0] == mKernelCpuidFindLegacyStart[0]
&& Record[1] == mKernelCpuidFindLegacyStart[1]
&& Record[2] == mKernelCpuidFindLegacyStart[2]
&& Record[3] == mKernelCpuidFindLegacyStart[3]
&& Record[4] == mKernelCpuidFindLegacyStart[4]
&& Record[5] == mKernelCpuidFindLegacyStart[5]
&& Record[6] == mKernelCpuidFindLegacyStart[6]
&& Record[7] == mKernelCpuidFindLegacyStart[7]) {
break;
}
}
if (Index >= EFI_PAGE_SIZE) {
return EFI_NOT_FOUND;
}
StartPointer = Record + sizeof (mKernelCpuidFindLegacyStart) + sizeof (UINT32);
STATIC CONST UINT8 mKernelCpuidFindLegacyEnd[9] = {
0x00, ///< 0 from mov cs:byte_FFFFFF80006C590C, 0
0xB8, 0x00, 0x00, 0x00, 0x80, ///< mov eax, 80000000h
0x0F, 0xA2, ///< cpuid
0x89 ///< mov prefix from mov [rbp+var_40], eax
};
for (; Index < EFI_PAGE_SIZE; ++Index, ++Record) {
if (Record[0] == mKernelCpuidFindLegacyEnd[0]
&& Record[1] == mKernelCpuidFindLegacyEnd[1]
&& Record[2] == mKernelCpuidFindLegacyEnd[2]
&& Record[3] == mKernelCpuidFindLegacyEnd[3]
&& Record[4] == mKernelCpuidFindLegacyEnd[4]
&& Record[5] == mKernelCpuidFindLegacyEnd[5]
&& Record[6] == mKernelCpuidFindLegacyEnd[6]
&& Record[7] == mKernelCpuidFindLegacyEnd[7]
&& Record[8] == mKernelCpuidFindLegacyEnd[8]) {
break;
}
}
if (Index >= EFI_PAGE_SIZE) {
return EFI_NOT_FOUND;
}
EndPointer = Record + 1;
STATIC CONST UINT8 mKernelCpuidFindLegacyLoc[8] = {
0xB8, 0x01, 0x00, 0x00, 0x00, ///< mov eax, 1
0x0F, 0xA2, ///< cpuid
0x89 ///< mov prefix from mov [rbp+var_40], eax
};
for (; Index < EFI_PAGE_SIZE; ++Index, ++Record) {
if (Record[0] == mKernelCpuidFindLegacyLoc[0]
&& Record[1] == mKernelCpuidFindLegacyLoc[1]
&& Record[2] == mKernelCpuidFindLegacyLoc[2]
&& Record[3] == mKernelCpuidFindLegacyLoc[3]
&& Record[4] == mKernelCpuidFindLegacyLoc[4]
&& Record[5] == mKernelCpuidFindLegacyLoc[5]
&& Record[6] == mKernelCpuidFindLegacyLoc[6]
&& Record[7] == mKernelCpuidFindLegacyLoc[7]) {
break;
}
}
if (Index >= EFI_PAGE_SIZE) {
return EFI_NOT_FOUND;
}
Location = Record;
//
// Free 2 more bytes in the end by assigning EAX directly.
//
AsmCpuid (0x80000000, &MaxExt, NULL, NULL, NULL);
EndPointer += 2;
EndPointer[0] = 0xB8;
CopyMem (&EndPointer[1], &MaxExt, sizeof (MaxExt));
//
// Short-write CPU signature at RSI save space.
//
AsmCpuid (0, NULL, &Signature[0], &Signature[2], &Signature[1]);
for (Index = 0; Index < 3; ++Index) {
//
// mov eax, <signature>
//
*StartPointer++ = 0xB8;
CopyMem (StartPointer, &Signature[Index], sizeof (Signature[0]));
StartPointer += sizeof (Signature[0]);
//
// mov [rsi], eax
//
*StartPointer++ = 0x89;
*StartPointer++ = 0x06;
if (Index < 2) {
//
// add rsi, 4
//
*StartPointer++ = 0x48;
*StartPointer++ = 0x83;
*StartPointer++ = 0xC6;
*StartPointer++ = 0x04;
}
}
//
// Ensure that we still have room, which is within 2-byte jmp (127)
// and has at least 2-byte jmp and patch + 5-byte jmp area.
// Should have around 25 bytes here.
//
if (StartPointer >= EndPointer
|| EndPointer - StartPointer > 128
|| (UINTN) (EndPointer - StartPointer) < sizeof (INTERNAL_CPUID_PATCH) + 7) {
return EFI_OUT_OF_RESOURCES;
}
//
// Short jmp to EndPointer
//
StartPointer[0] = 0xEB;
StartPointer[1] = (UINT8) (EndPointer - StartPointer - 2);
StartPointer += 2;
//
// Workaround incorrect OSXSAVE handling, see below.
//
if (CpuInfo->CpuidVerEcx.Bits.XSAVE != 0
&& CpuInfo->CpuidVerEcx.Bits.OSXSAVE == 0
&& CpuInfo->CpuidVerEcx.Bits.AVX != 0) {
CpuInfo->CpuidVerEcx.Bits.OSXSAVE = 1;
}
//
// Jump from location to patch area.
//
Delta = (INT32) (StartPointer - (Location + 5));
*Location++ = 0xE9;
CopyMem (Location, &Delta, sizeof (Delta));
Location += sizeof (Delta);
*Location++ = 0x90;
*Location++ = 0x90;
//
// Write virtualised CPUID.
//
Patch.EaxCmd = 0xB8;
Patch.EaxVal = (Data[0] & DataMask[0]) | (CpuInfo->CpuidVerEax.Uint32 & ~DataMask[0]);
Patch.EbxCmd = 0xBB;
Patch.EbxVal = (Data[1] & DataMask[1]) | (CpuInfo->CpuidVerEbx.Uint32 & ~DataMask[1]);
Patch.EcxCmd = 0xB9;
Patch.EcxVal = (Data[2] & DataMask[2]) | (CpuInfo->CpuidVerEcx.Uint32 & ~DataMask[2]);
Patch.EdxCmd = 0xBA;
Patch.EdxVal = (Data[3] & DataMask[3]) | (CpuInfo->CpuidVerEdx.Uint32 & ~DataMask[3]);
CopyMem (StartPointer, &Patch, sizeof (Patch));
StartPointer += sizeof (Patch);
//
// Jump to the end of location (5-byte mov + 2-byte cpuid).
//
Delta = (INT32) (Location - (StartPointer + 5));
*StartPointer++ = 0xE9;
CopyMem (StartPointer, &Delta, sizeof (Delta));
return EFI_SUCCESS;
}
EFI_STATUS
PatchKernelCpuId (
IN OUT PATCHER_CONTEXT *Patcher,
......@@ -1082,6 +1288,7 @@ PatchKernelCpuId (
)
{
EFI_STATUS Status;
UINT8 *CpuidSetInfo;
UINT8 *Record;
UINT8 *Last;
UINT32 Index;
......@@ -1109,12 +1316,13 @@ PatchKernelCpuId (
Last = ((UINT8 *) MachoGetMachHeader64 (&Patcher->MachContext)
+ MachoGetFileSize (&Patcher->MachContext) - EFI_PAGE_SIZE*2 - sizeof (mKernelCpuIdFindRelNew));
Status = PatcherGetSymbolAddress (Patcher, "_cpuid_set_info", (UINT8 **) &Record);
if (EFI_ERROR (Status) || Record >= Last) {
DEBUG ((DEBUG_WARN, "OCAK: Failed to locate _cpuid_set_info (%p) - %r\n", Record, Status));
Status = PatcherGetSymbolAddress (Patcher, "_cpuid_set_info", (UINT8 **) &CpuidSetInfo);
if (EFI_ERROR (Status) || CpuidSetInfo >= Last) {
DEBUG ((DEBUG_WARN, "OCAK: Failed to locate _cpuid_set_info (%p) - %r\n", CpuidSetInfo, Status));
return EFI_NOT_FOUND;
}
Record = CpuidSetInfo;
FoundSize = 0;
for (Index = 0; Index < EFI_PAGE_SIZE; ++Index, ++Record) {
......@@ -1135,6 +1343,13 @@ PatchKernelCpuId (
FoundReleaseKernel = FoundSize > 0;
if (!FoundReleaseKernel) {
Status = PatchKernelCpuIdLegacy (Patcher, CpuInfo, Data, DataMask, CpuidSetInfo);
if (!EFI_ERROR (Status)) {
return EFI_SUCCESS;
}
}
//
// When patching the release kernel we do not allow reevaluating CPUID information,
// which is used to report OSXSAVE availability. This causes issues with some programs,
......
/** @file
Copyright (C) 2019, vit9696. All rights reserved.
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <Base.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/OcAppleKernelLib.h>
#include <Library/OcMiscLib.h>
#include <Library/OcStringLib.h>
#include "PrelinkedInternal.h"
UINT32
OcParseDarwinVersion (
IN CONST CHAR8 *String
)
{
UINT32 Version;
UINT32 VersionPart;
UINT32 Index;
UINT32 Index2;
if (*String == '\0' || *String < '0' || *String > '9') {
return 0;
}
Version = 0;
for (Index = 0; Index < 3; ++Index) {
Version *= 100;
VersionPart = 0;
for (Index2 = 0; Index2 < 2; ++Index2) {
//
// Handle single digit parts, i.e. parse 1.2.3 as 010203.
//
if (*String != '.' && *String != '\0') {
VersionPart *= 10;
}
if (*String >= '0' && *String <= '9') {
VersionPart += *String++ - '0';
} else if (*String != '.' && *String != '\0') {
return 0;
}
}
Version += VersionPart;
if (*String == '.') {
++String;
}
}
return Version;
}
BOOLEAN
OcMatchDarwinVersion (
IN UINT32 CurrentVersion OPTIONAL,
IN UINT32 MinVersion OPTIONAL,
IN UINT32 MaxVersion OPTIONAL
)
{
//
// Check against min <= curr <= max.
// curr=0 -> curr=inf, max=0 -> max=inf
//
//
// Replace max inf with max known version.
//
if (MaxVersion == 0) {
MaxVersion = CurrentVersion;
}
//
// Handle curr=inf <= max=inf(?) case.
//
if (CurrentVersion == 0) {
return MaxVersion == 0;
}
//
// Handle curr=num > max=num case.
//
if (CurrentVersion > MaxVersion) {
return FALSE;
}
//
// Handle min=num > curr=num case.
//
if (CurrentVersion < MinVersion) {
return FALSE;
}
return TRUE;
}
UINT32
OcKernelReadDarwinVersion (
IN CONST UINT8 *Kernel,
IN UINT32 KernelSize
)
{
INT32 Offset;
UINT32 Index;
CHAR8 DarwinVersion[32];
UINT32 DarwinVersionInteger;
Offset = FindPattern (
(CONST UINT8 *) "Darwin Kernel Version ",
NULL,
L_STR_LEN ("Darwin Kernel Version "),
Kernel,
KernelSize,
0
);
if (Offset < 0) {
DEBUG ((DEBUG_WARN, "OCAK: Failed to determine kernel version\n"));
return 0;
}
Offset += L_STR_LEN ("Darwin Kernel Version ");
for (Index = 0; Index < ARRAY_SIZE (DarwinVersion) - 1; ++Index, ++Offset) {
if ((UINT32) Offset >= KernelSize || Kernel[Offset] == ':') {
break;
}
DarwinVersion[Index] = (CHAR8) Kernel[Offset];
}
DarwinVersion[Index] = '\0';
DarwinVersionInteger = OcParseDarwinVersion (DarwinVersion);
DEBUG ((
DEBUG_INFO,
"OCAK: Read kernel version %a (%u)\n",
DarwinVersion,
DarwinVersionInteger
));
return DarwinVersionInteger;
}
......@@ -34,6 +34,7 @@
Link.c
CommonPatches.c
KernelCollection.c
KernelVersion.c
KxldState.c
PrelinkedContext.c
PrelinkedInternal.h
......
......@@ -45,145 +45,6 @@ typedef enum KERNEL_CACHE_TYPE_ {
CacheTypePrelinked
} KERNEL_CACHE_TYPE;
STATIC
UINT32
OcParseDarwinVersion (
IN CONST CHAR8 *String
)
{
UINT32 Version;
UINT32 VersionPart;
UINT32 Index;
UINT32 Index2;
if (*String == '\0' || *String < '0' || *String > '9') {
return 0;
}
Version = 0;
for (Index = 0; Index < 3; ++Index) {
Version *= 100;
VersionPart = 0;
for (Index2 = 0; Index2 < 2; ++Index2) {
//
// Handle single digit parts, i.e. parse 1.2.3 as 010203.
//
if (*String != '.' && *String != '\0') {
VersionPart *= 10;
}
if (*String >= '0' && *String <= '9') {
VersionPart += *String++ - '0';
} else if (*String != '.' && *String != '\0') {
return 0;
}
}
Version += VersionPart;
if (*String == '.') {
++String;
}
}
return Version;
}
STATIC
BOOLEAN
OcMatchDarwinVersion (
IN UINT32 CurrentVersion,
IN UINT32 MinVersion,
IN UINT32 MaxVersion
)
{
//
// Check against min <= curr <= max.
// curr=0 -> curr=inf, max=0 -> max=inf
//
//
// Replace max inf with max known version.
//
if (MaxVersion == 0) {
MaxVersion = CurrentVersion;
}
//
// Handle curr=inf <= max=inf(?) case.
//
if (CurrentVersion == 0) {
return MaxVersion == 0;
}
//
// Handle curr=num > max=num case.
//
if (CurrentVersion > MaxVersion) {
return FALSE;
}
//
// Handle min=num > curr=num case.
//
if (CurrentVersion < MinVersion) {
return FALSE;
}
return TRUE;
}
STATIC
UINT32
OcKernelReadDarwinVersion (
IN CONST UINT8 *Kernel,
IN UINT32 KernelSize
)
{
INT32 Offset;
UINT32 Index;
CHAR8 DarwinVersion[32];
UINT32 DarwinVersionInteger;
Offset = FindPattern (
(CONST UINT8 *) "Darwin Kernel Version ",
NULL,
L_STR_LEN ("Darwin Kernel Version "),
Kernel,
KernelSize,
0
);
if (Offset < 0) {
DEBUG ((DEBUG_WARN, "OC: Failed to determine kernel version\n"));
return 0;
}
Offset += L_STR_LEN ("Darwin Kernel Version ");
for (Index = 0; Index < ARRAY_SIZE (DarwinVersion) - 1; ++Index, ++Offset) {
if ((UINT32) Offset >= KernelSize || Kernel[Offset] == ':') {
break;
}
DarwinVersion[Index] = (CHAR8) Kernel[Offset];
}
DarwinVersion[Index] = '\0';
DarwinVersionInteger = OcParseDarwinVersion (DarwinVersion);
DEBUG ((
DEBUG_INFO,
"OC: Read kernel version %a (%u)\n",
DarwinVersion,
DarwinVersionInteger
));
return DarwinVersionInteger;
}
STATIC
EFI_STATUS
OcKernelLoadKextsAndReserve (
......
......@@ -38,6 +38,9 @@
/[^\n]+\nPassed.kext injected - 0x8[^\n]+
*/
STATIC BOOLEAN FailedToProcess = FALSE;
STATIC UINT32 KernelVersion = 0;
STATIC CHAR8 KextInfoPlistData[] = {
0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65,
0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31,
......@@ -190,15 +193,6 @@ STATIC CHAR8 KextInfoPlistData[] = {
0x6C, 0x69, 0x73, 0x74, 0x3E
};
extern UINT8 LiluKextData[];
extern UINT32 LiluKextDataSize;
extern CHAR8 LiluKextInfoPlistData[];
extern UINT32 LiluKextInfoPlistDataSize;
extern UINT8 VsmcKextData[];
extern UINT32 VsmcKextDataSize;
extern CHAR8 VsmcKextInfoPlistData[];
extern UINT32 VsmcKextInfoPlistDataSize;
long long current_timestamp() {
struct timeval te;
gettimeofday(&te, NULL); // get current time
......@@ -207,80 +201,24 @@ long long current_timestamp() {
return milliseconds;
}
#if 0
STATIC
UINT8
IOAHCIBlockStoragePatchFind[] = {
0x41, 0x50, 0x50, 0x4C, 0x45, 0x20, 0x53, 0x53, 0x44, 0x00
};
STATIC
UINT8
IOAHCIBlockStoragePatchReplace[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
STATIC
PATCHER_GENERIC_PATCH
IOAHCIBlockStoragePatch = {
.Base = NULL, // Symbolic patch
.Find = IOAHCIBlockStoragePatchFind,
.Mask = NULL,
.Replace = IOAHCIBlockStoragePatchReplace,
.ReplaceMask = NULL,
.Size = sizeof (IOAHCIBlockStoragePatchFind),
.Count = 1,
.Skip = 0
};
#endif
#if 0
STATIC
UINT8
IOAHCIPortPatchFind[] = {
0x45, 0x78, 0x74, 0x65, 0x72, 0x6E, 0x61, 0x6C
};
STATIC
UINT8
IOAHCIPortPatchReplace[] = {
0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x61, 0x6C
};
STATIC
PATCHER_GENERIC_PATCH
IOAHCIPortPatch = {
.Base = NULL, // For symbolic patch
.Find = IOAHCIPortPatchFind,
.Mask = NULL,
.Replace = IOAHCIPortPatchReplace,
.ReplaceMask = NULL,
.Size = sizeof (IOAHCIPortPatchFind),
.Count = 1,
.Skip = 0
};
#endif
#if 0
STATIC
UINT8
DisableAppleHDAPatchReplace[] = {
DisableIOAHCIPatchReplace[] = {
0x31, 0xC0, 0xC3 // xor eax, eax ; ret
};
STATIC
PATCHER_GENERIC_PATCH
DisableAppleHDAPatch = {
.Base = "__ZN20AppleHDACodecGeneric5probeEP9IOServicePi",
DisableIOAHCIPatch = {
.Base = "__ZN10IOAHCIPort5startEP9IOService",
.Find = NULL,
.Mask = NULL,
.Replace = DisableAppleHDAPatchReplace,
.Replace = DisableIOAHCIPatchReplace,
.ReplaceMask = NULL,
.Size = sizeof (DisableAppleHDAPatchReplace),
.Size = sizeof (DisableIOAHCIPatchReplace),
.Count = 1,
.Skip = 0
};
#endif
STATIC
UINT8
......@@ -290,7 +228,7 @@ DisableKernelLog[] = {
STATIC
PATCHER_GENERIC_PATCH
KernelPatch = {
DisableIoLogPatch = {
.Base = "_IOLog",
.Find = NULL,
.Mask = NULL,
......@@ -306,78 +244,46 @@ ApplyKextPatches (
PRELINKED_CONTEXT *Context
)
{
#if 0
EFI_STATUS Status;
PATCHER_CONTEXT Patcher;
Status = PatcherInitContextFromPrelinked (
&Patcher,
Context,
"com.apple.iokit.IOAHCIBlockStorage"
);
if (!EFI_ERROR (Status)) {
Status = PatcherApplyGenericPatch (&Patcher, &IOAHCIBlockStoragePatch);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "Failed to apply patch com.apple.iokit.IOAHCIBlockStorage - %r\n", Status));
} else {
DEBUG ((DEBUG_WARN, "Patch success com.apple.iokit.IOAHCIBlockStorage\n"));
}
} else {
DEBUG ((DEBUG_WARN, "Failed to find com.apple.iokit.IOAHCIBlockStorage - %r\n", Status));
}
Status = PatcherInitContextFromPrelinked (
&Patcher,
Context,
"com.apple.driver.AppleAHCIPort"
);
if (!EFI_ERROR (Status)) {
Status = PatcherApplyGenericPatch (&Patcher, &IOAHCIPortPatch);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "Failed to apply patch com.apple.driver.AppleAHCIPort - %r\n", Status));
} else {
DEBUG ((DEBUG_WARN, "Patch success com.apple.driver.AppleAHCIPort\n"));
}
} else {
DEBUG ((DEBUG_WARN, "Failed to find com.apple.driver.AppleAHCIPort - %r\n", Status));
}
Status = PatcherInitContextFromPrelinked (
&Patcher,
Context,
"com.apple.driver.AppleHDA"
"com.apple.iokit.IOAHCIFamily"
);
if (!EFI_ERROR (Status)) {
Status = PatcherApplyGenericPatch (&Patcher, &DisableAppleHDAPatch);
Status = PatcherApplyGenericPatch (&Patcher, &DisableIOAHCIPatch);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "Failed to apply patch com.apple.driver.AppleHDA - %r\n", Status));
DEBUG ((DEBUG_WARN, "[FAIL] Failed to apply patch com.apple.iokit.IOAHCIFamily - %r\n", Status));
FailedToProcess = TRUE;
} else {
DEBUG ((DEBUG_WARN, "Patch success com.apple.driver.AppleHDA\n"));
DEBUG ((DEBUG_WARN, "[OK] Patch success com.apple.iokit.IOAHCIFamily\n"));
}
} else {
DEBUG ((DEBUG_WARN, "Failed to find com.apple.driver.AppleHDA - %r\n", Status));
DEBUG ((DEBUG_WARN, "[FAIL] Failed to find com.apple.iokit.IOAHCIFamily - %r\n", Status));
FailedToProcess = TRUE;
}
Status = PatcherInitContextFromPrelinked (
&Patcher,
Context,
"com.apple.driver.AppleHDAController"
"com.apple.iokit.IOHIDFamily"
);
if (!EFI_ERROR (Status)) {
Status = PatcherBlockKext (&Patcher);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "Failed to block com.apple.driver.AppleHDAController - %r\n", Status));
DEBUG ((DEBUG_WARN, "[FAIL] Failed to block com.apple.iokit.IOHIDFamily - %r\n", Status));
FailedToProcess = TRUE;
} else {
DEBUG ((DEBUG_WARN, "Block success com.apple.driver.AppleHDAController\n"));
DEBUG ((DEBUG_WARN, "[OK] Block success com.apple.iokit.IOHIDFamily\n"));
}
} else {
DEBUG ((DEBUG_WARN, "Failed to find com.apple.driver.AppleHDAController - %r\n", Status));
DEBUG ((DEBUG_WARN, "[FAIL] Failed to find com.apple.iokit.IOHIDFamily - %r\n", Status));
FailedToProcess = TRUE;
}
#endif
}
VOID
......@@ -396,14 +302,34 @@ ApplyKernelPatches (
);
if (!EFI_ERROR (Status)) {
Status = PatcherApplyGenericPatch (&Patcher, &KernelPatch);
Status = PatcherApplyGenericPatch (&Patcher, &DisableIoLogPatch);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "[FAIL] DisableIoLogPatch kernel patch - %r\n", Status));
FailedToProcess = TRUE;
} else {
DEBUG ((DEBUG_WARN, "[OK] DisableIoLogPatch kernel patch\n"));
}
UINT32 VirtualCpuid[4] = {0, 0, 0, 0};
UINT32 VirtualCpuidMask[4] = {0xFFFFFFFF, 0, 0, 0};
OC_CPU_INFO CpuInfo;
memset(&CpuInfo, 0, sizeof(CpuInfo));
Status = PatchKernelCpuId (
&Patcher,
&CpuInfo,
VirtualCpuid,
VirtualCpuidMask
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "Failed to apply patch kernel - %r\n", Status));
DEBUG ((DEBUG_WARN, "[FAIL] CPUID kernel patch - %r\n", Status));
FailedToProcess = TRUE;
} else {
DEBUG ((DEBUG_WARN, "Patch success kernel\n"));
DEBUG ((DEBUG_WARN, "[OK] CPUID kernel patch\n"));
}
} else {
DEBUG ((DEBUG_WARN, "Failed to find kernel - %r\n", Status));
FailedToProcess = TRUE;
}
}
......@@ -449,7 +375,6 @@ 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";
......@@ -462,10 +387,10 @@ int wrap_main(int argc, char** argv) {
UINT32 ReservedExeSize = 0;
for (int argi = 0; argc - argi > 2; argi += 2) {
UINT8 *TestData = LiluKextData;
UINT32 TestDataSize = LiluKextDataSize;
CHAR8 *TestPlist = LiluKextInfoPlistData;
UINT32 TestPlistSize = LiluKextInfoPlistDataSize;
UINT8 *TestData = NULL;
UINT32 TestDataSize = 0;
CHAR8 *TestPlist = NULL;
UINT32 TestPlistSize = 0;
if (argc - argi > 2) {
if (argv[argi + 2][0] == 'n' && argv[argi + 2][1] == 0) {
......@@ -508,11 +433,13 @@ int wrap_main(int argc, char** argv) {
"OC: Failed to fit kext %s\n",
argv[argi + 2]
);
FailedToProcess = TRUE;
}
}
UINT32 LinkedExpansion = KcGetSegmentFixupChainsSize (ReservedExeSize);
if (LinkedExpansion == 0) {
FailedToProcess = TRUE;
return -1;
}
......@@ -532,15 +459,23 @@ int wrap_main(int argc, char** argv) {
free(Prelinked);
Prelinked = NewPrelinked;
PrelinkedSize = NewPrelinkedSize;
printf("Sha384 is %02X%02X%02X%02X\n", Sha384[0], Sha384[1], Sha384[2], Sha384[3]);
DEBUG ((DEBUG_WARN, "[OK] Sha384 is %02X%02X%02X%02X\n", Sha384[0], Sha384[1], Sha384[2], Sha384[3]));
} else {
printf("Unpack fail\n");
DEBUG ((DEBUG_WARN, "[FAIL] Kernel unpack failure - %r\n", Status));
FailedToProcess = TRUE;
return -1;
}
#if 0
KernelVersion = OcKernelReadDarwinVersion (Prelinked, PrelinkedSize);
if (KernelVersion != 0) {
DEBUG ((DEBUG_WARN, "[OK] Got version %u\n", KernelVersion));
} else {
DEBUG ((DEBUG_WARN, "[FAIL] Failed to detect version\n"));
FailedToProcess = TRUE;
}
ApplyKernelPatches (Prelinked, PrelinkedSize);
#endif
PATCHER_CONTEXT Patcher;
Status = PatcherInitContextFromBuffer (
......@@ -548,7 +483,12 @@ int wrap_main(int argc, char** argv) {
Prelinked,
PrelinkedSize
);
DEBUG ((DEBUG_ERROR, "Patcher init status %r\n", Status));
if (!EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "[OK] Patcher init success\n"));
} else {
DEBUG ((DEBUG_WARN, "[FAIL] Patcher init failure - %r\n", Status));
FailedToProcess = TRUE;
}
Status = PrelinkedContextInit (&Context, Prelinked, PrelinkedSize, AllocSize);
......@@ -557,14 +497,14 @@ int wrap_main(int argc, char** argv) {
Status = PrelinkedInjectPrepare (&Context, LinkedExpansion, ReservedExeSize);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "Prelink inject prepare error %r\n", Status));
DEBUG ((DEBUG_WARN, "[FAIL] Prelink inject prepare error %r\n", Status));
FailedToProcess = TRUE;
return -1;
}
#ifndef TEST_SLE
Status = PrelinkedInjectKext (
&Context,
"/Library/Extensions/TestDriver.kext",
"/Library/Extensions/PlistKext.kext",
KextInfoPlistData,
sizeof (KextInfoPlistData),
NULL,
......@@ -572,16 +512,20 @@ int wrap_main(int argc, char** argv) {
0
);
DEBUG ((DEBUG_WARN, "TestDriver.kext injected - %r\n", Status));
#endif
if (!EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "[OK] PlistKext.kext injected - %r\n", Status));
} else {
DEBUG ((DEBUG_WARN, "[FAIL] PlistKext.kext injected - %r\n", Status));
FailedToProcess = TRUE;
}
int c = 0;
while (argc > 2) {
UINT8 *TestData = LiluKextData;
UINT32 TestDataSize = LiluKextDataSize;
CHAR8 *TestPlist = LiluKextInfoPlistData;
UINT32 TestPlistSize = LiluKextInfoPlistDataSize;
UINT8 *TestData = NULL;
UINT32 TestDataSize = 0;
CHAR8 *TestPlist = NULL;
UINT32 TestPlistSize = 0;
if (argc > 2) {
if (argv[2][0] == 'n' && argv[2][1] == 0) {
......@@ -619,7 +563,12 @@ int wrap_main(int argc, char** argv) {
TestDataSize
);
DEBUG ((DEBUG_WARN, "%a injected - %r\n", argc > 2 ? "Passed.kext" : "Lilu.kext", Status));
if (!EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "[OK] %a injected - %r\n", argv[2], Status));
} else {
DEBUG ((DEBUG_WARN, "[FAIL] %a injected - %r\n", argv[2], Status));
FailedToProcess = TRUE;
}
if (argc > 2) free(TestData);
if (argc > 3) free(TestPlist);
......@@ -630,37 +579,22 @@ int wrap_main(int argc, char** argv) {
}
ASSERT (Context.PrelinkedSize - Context.KextsFileOffset <= ReservedExeSize);
#ifndef TEST_SLE
if (argc <= 2) {
Status = PrelinkedInjectKext (
&Context,
"/Library/Extensions/VirtualSMC.kext",
VsmcKextInfoPlistData,
VsmcKextInfoPlistDataSize,
"Contents/MacOS/VirtualSMC",
VsmcKextData,
VsmcKextDataSize
);
DEBUG ((DEBUG_WARN, "VirtualSMC.kext injected - %r\n", Status));
}
Status = PrelinkedInjectComplete (&Context);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "Prelink inject complete error %r\n", Status));
}
writeFile("out.bin", Prelinked, Context.PrelinkedSize);
if (!EFI_ERROR (Status)) {
printf("All good\n");
DEBUG ((DEBUG_WARN, "[OK] Prelink inject complete success\n"));
} else {
printf("Inject error\n");
DEBUG ((DEBUG_WARN, "[FAIL] Prelink inject complete error %r\n", Status));
FailedToProcess = TRUE;
}
#endif
PrelinkedContextFree (&Context);
} else {
DEBUG ((DEBUG_WARN, "Context creation error %r\n", Status));
DEBUG ((DEBUG_WARN, "[FAIL] Context creation error %r\n", Status));
FailedToProcess = TRUE;
}
free(Prelinked);
......@@ -708,8 +642,8 @@ INT32 LLVMFuzzerTestOneInput(CONST UINT8 *Data, UINTN Size) {
Status = PrelinkedInjectKext (
&Context,
"/Library/Extensions/Lilu.kext",
LiluKextInfoPlistData,
LiluKextInfoPlistDataSize,
KextInfoPlistData, ///< FIXME: has no executable
sizeof (KextInfoPlistData),
"Contents/MacOS/Lilu",
Data,
Size
......@@ -723,8 +657,9 @@ INT32 LLVMFuzzerTestOneInput(CONST UINT8 *Data, UINTN Size) {
}
int main(int argc, char *argv[]) {
for (size_t i = 0; i < 1; i++) {
wrap_main(argc, argv);
int code = wrap_main(argc, argv);
if (FailedToProcess) {
code = -1;
}
return 0;
return code;
}
此差异已折叠。
......@@ -6,8 +6,8 @@
PROJECT = KextInject
PRODUCT = $(PROJECT)$(SUFFIX)
OBJS = $(PROJECT).o \
Lilu.o \
Vsmc.o \
CommonPatches.o \
KernelVersion.o \
KextPatcher.o \
KxldState.o \
PrelinkedKext.o \
......
此差异已折叠。
#!/bin/bash
abort() {
echo "$1"
exit 1
}
if [ ! -x "KextInject" ]; then
abort "Please compile KextInject"
fi
if [ ! -d "$1" ]; then
abort "Please pass a directory with caches!"
fi
ARCH=x86_64
DIR="$1"
CODE=0
shift
for dir in "${DIR}"/*/ ; do
for file in kernelcache prelinkedkernel immutablekernel BootKernelExtensions.kc; do
for resulting in ${file} ${file}_unpack ${file}_${ARCH} ${file}_${ARCH}_unpack; do
if [ ! -f "${dir}${resulting}" ]; then
continue
fi
printf "%s%s - " "${dir}" "${resulting}"
ok=true
echo "./KextInject ${dir}${resulting} ${*}" > "${dir}${resulting}.log"
./KextInject "${dir}${resulting}" "${@}" >> "${dir}${resulting}.log" || ok=false
if $ok; then
echo "OK"
else
echo "FAIL"
CODE=-1
fi
done
done
done
exit $CODE
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册