mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
Implement kernel interception code
This commit is contained in:
parent
1a505b7f23
commit
eb6b186fee
41
Include/Library/OcAppleKernelLib.h
Normal file
41
Include/Library/OcAppleKernelLib.h
Normal file
@ -0,0 +1,41 @@
|
||||
/** @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.
|
||||
**/
|
||||
|
||||
#ifndef OC_APPLE_KERNEL_LIB_H
|
||||
#define OC_APPLE_KERNEL_LIB_H
|
||||
|
||||
#include <Library/OcMachoLib.h>
|
||||
#include <Protocol/SimpleFileSystem.h>
|
||||
|
||||
/**
|
||||
Read Apple kernel for target architecture (possibly decompressing)
|
||||
into pool allocated buffer.
|
||||
|
||||
@param[in] File File handle instance.
|
||||
@param[in, out] Kernel Resulting non-fat kernel buffer from pool.
|
||||
@param[out] KernelSize Actual kernel size.
|
||||
@param[out] AllocatedSize Allocated kernel size (AllocatedSize >= KernelSize).
|
||||
|
||||
@return EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
ReadAppleKernel (
|
||||
IN EFI_FILE_PROTOCOL *File,
|
||||
IN OUT UINT8 **Kernel,
|
||||
OUT UINT32 *KernelSize,
|
||||
OUT UINT32 *AllocatedSize
|
||||
);
|
||||
|
||||
#endif // OC_APPLE_KERNEL_LIB_H
|
||||
|
||||
@ -50,7 +50,8 @@ GetVolumeLabel (
|
||||
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem
|
||||
);
|
||||
|
||||
/** Read file from device path with implicit double (2 byte) null termination.
|
||||
/**
|
||||
Read file from device path with implicit double (2 byte) null termination.
|
||||
Null termination does not affect the returned file size.
|
||||
Depending on the implementation 0 byte files may return null.
|
||||
|
||||
@ -67,4 +68,36 @@ ReadFile (
|
||||
OUT UINTN *FileSize OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Read exact amount of bytes from EFI_FILE_PROTOCOL at specified position.
|
||||
|
||||
@param[in] File A pointer to the file protocol.
|
||||
@param[in] Position Position to read data from.
|
||||
@param[in] Size The size of the data read.
|
||||
@param[out] Buffer A pointer to previously allocated buffer to read data to.
|
||||
|
||||
@retval EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
ReadFileData (
|
||||
IN EFI_FILE_PROTOCOL *File,
|
||||
IN UINT32 Position,
|
||||
IN UINT32 Size,
|
||||
OUT UINT8 *Buffer
|
||||
);
|
||||
|
||||
/**
|
||||
Determine file size if it is less than 4 GB.
|
||||
|
||||
@param[in] File A pointer to the file protocol.
|
||||
@param[out] Size 32-bit file size.
|
||||
|
||||
@retval EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
ReadFileSize (
|
||||
IN EFI_FILE_PROTOCOL *File,
|
||||
OUT UINT32 *Size
|
||||
);
|
||||
|
||||
#endif // OC_FILE_LIB_H_
|
||||
|
||||
45
Library/OcAppleKernelLib/OcAppleKernelLib.inf
Normal file
45
Library/OcAppleKernelLib/OcAppleKernelLib.inf
Normal file
@ -0,0 +1,45 @@
|
||||
## @file
|
||||
# OcAppleKernelLib
|
||||
#
|
||||
# Copyright (c) 2019, vit9696
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = OcAppleKernelLib
|
||||
FILE_GUID = 9CFA01EA-9A9B-450C-B672-E108CA30DC3F
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = OcAppleKernelLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER SMM_CORE UEFI_APPLICATION UEFI_DRIVER
|
||||
|
||||
|
||||
#
|
||||
# VALID_ARCHITECTURES = X64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
ReadAppleKernel.c
|
||||
|
||||
[Packages]
|
||||
EfiPkg/EfiPkg.dec
|
||||
MdePkg/MdePkg.dec
|
||||
OcSupportPkg/OcSupportPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
MemoryAllocationLib
|
||||
OcCompressionLib
|
||||
OcFileLib
|
||||
OcMachoLib
|
||||
337
Library/OcAppleKernelLib/ReadAppleKernel.c
Normal file
337
Library/OcAppleKernelLib/ReadAppleKernel.c
Normal file
@ -0,0 +1,337 @@
|
||||
/** @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 <IndustryStandard/AppleFatBinaryImage.h>
|
||||
#include <IndustryStandard/AppleCompressedBinaryImage.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/OcAppleKernelLib.h>
|
||||
#include <Library/OcCompressionLib.h>
|
||||
#include <Library/OcFileLib.h>
|
||||
#include <Library/OcMachoLib.h>
|
||||
#include <Library/OcGuardLib.h>
|
||||
|
||||
//
|
||||
// Pick a reasonable maximum to fit.
|
||||
//
|
||||
#define KERNEL_HEADER_SIZE (EFI_PAGE_SIZE*2)
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
ReplaceBuffer (
|
||||
IN UINT32 TargetSize,
|
||||
IN OUT UINT8 **Buffer,
|
||||
OUT UINT32 *AllocatedSize
|
||||
)
|
||||
{
|
||||
UINT8 *TmpBuffer;
|
||||
|
||||
if (*AllocatedSize >= TargetSize) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
TmpBuffer = AllocatePool (TargetSize);
|
||||
if (TmpBuffer == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
FreePool (*Buffer);
|
||||
*Buffer = TmpBuffer;
|
||||
*AllocatedSize = TargetSize;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
STATIC
|
||||
UINT32
|
||||
ParseFatArchitecture (
|
||||
IN EFI_FILE_PROTOCOL *File,
|
||||
IN OUT UINT8 **Buffer,
|
||||
IN OUT UINT32 *Offset
|
||||
)
|
||||
{
|
||||
BOOLEAN SwapBytes;
|
||||
MACH_FAT_HEADER *FatHeader;
|
||||
UINT32 NumberOfFatArch;
|
||||
MACH_CPU_TYPE CpuType;
|
||||
UINT32 TmpSize;
|
||||
UINT32 Index;
|
||||
UINT32 Size;
|
||||
|
||||
FatHeader = (MACH_FAT_HEADER *) *Buffer;
|
||||
SwapBytes = FatHeader->Signature == MACH_FAT_BINARY_INVERT_SIGNATURE;
|
||||
NumberOfFatArch = FatHeader->NumberOfFatArch;
|
||||
if (SwapBytes) {
|
||||
NumberOfFatArch = SwapBytes32 (NumberOfFatArch);
|
||||
}
|
||||
|
||||
if (OcOverflowMulAddU32 (NumberOfFatArch, sizeof (MACH_FAT_ARCH), sizeof (MACH_FAT_HEADER), &TmpSize)
|
||||
|| TmpSize > KERNEL_HEADER_SIZE) {
|
||||
DEBUG ((DEBUG_INFO, "Fat kernel invalid arch count %u\n", NumberOfFatArch));
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// TODO: Currently there are no kernels with MachCpuSubtypeX8664H, but we should support them.
|
||||
//
|
||||
for (Index = 0; Index < NumberOfFatArch; Index++) {
|
||||
CpuType = FatHeader->FatArch[Index].CpuType;
|
||||
if (SwapBytes) {
|
||||
CpuType = SwapBytes32 (CpuType);
|
||||
}
|
||||
if (CpuType == MachCpuTypeX8664) {
|
||||
*Offset = FatHeader->FatArch[Index].Offset;
|
||||
Size = FatHeader->FatArch[Index].Size;
|
||||
if (SwapBytes) {
|
||||
*Offset = SwapBytes32 (*Offset);
|
||||
Size = SwapBytes32 (Size);
|
||||
}
|
||||
|
||||
if (*Offset == 0) {
|
||||
DEBUG ((DEBUG_INFO, "Fat kernel has 0 offset\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (OcOverflowAddU32 (*Offset, Size, &TmpSize)) {
|
||||
DEBUG ((DEBUG_INFO, "Fat kernel invalid size %u\n", Size));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Size;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "Fat kernel has no x86_64 arch\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC
|
||||
UINT32
|
||||
ParseCompressedHeader (
|
||||
IN EFI_FILE_PROTOCOL *File,
|
||||
IN OUT UINT8 **Buffer,
|
||||
IN UINT32 *Offset,
|
||||
OUT UINT32 *AllocatedSize
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
UINT32 KernelSize;
|
||||
MACH_COMP_HEADER *CompHeader;
|
||||
UINT8 *CompressedBuffer;
|
||||
UINT32 CompressionType;
|
||||
UINT32 CompressedSize;
|
||||
UINT32 DecompressedSize;
|
||||
UINT32 DecompressedHash;
|
||||
|
||||
CompHeader = (MACH_COMP_HEADER *) *Buffer;
|
||||
CompressionType = CompHeader->Compression;
|
||||
CompressedSize = SwapBytes32 (CompHeader->Compressed);
|
||||
DecompressedSize = SwapBytes32 (CompHeader->Decompressed);
|
||||
DecompressedHash = SwapBytes32 (CompHeader->Hash);
|
||||
|
||||
KernelSize = 0;
|
||||
|
||||
if (CompressedSize > OC_COMPRESSION_MAX_LENGTH
|
||||
|| CompressedSize == 0
|
||||
|| DecompressedSize > OC_COMPRESSION_MAX_LENGTH
|
||||
|| DecompressedSize < KERNEL_HEADER_SIZE) {
|
||||
DEBUG ((DEBUG_INFO, "Comp kernel invalid comp %u or decomp %u at %08X\n", CompressedSize, DecompressedSize, *Offset));
|
||||
return KernelSize;
|
||||
}
|
||||
|
||||
Status = ReplaceBuffer (DecompressedSize, Buffer, AllocatedSize);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "Decomp kernel (%u bytes) cannot be allocated at %08X\n", DecompressedSize, *Offset));
|
||||
return KernelSize;
|
||||
}
|
||||
|
||||
CompressedBuffer = AllocatePool (CompressedSize);
|
||||
if (CompressedBuffer == NULL) {
|
||||
DEBUG ((DEBUG_INFO, "Comp kernel (%u bytes) cannot be allocated at %08X\n", CompressedSize, *Offset));
|
||||
return KernelSize;
|
||||
}
|
||||
|
||||
Status = ReadFileData (File, *Offset + sizeof (MACH_COMP_HEADER), CompressedSize, CompressedBuffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "Comp kernel (%u bytes) cannot be read at %08X\n", CompressedSize, *Offset));
|
||||
FreePool (CompressedBuffer);
|
||||
return KernelSize;
|
||||
}
|
||||
|
||||
if (CompressionType == MACH_COMPRESSED_BINARY_INVERT_LZVN) {
|
||||
KernelSize = (UINT32) DecompressLZVN (*Buffer, DecompressedSize, CompressedBuffer, CompressedSize);
|
||||
} else if (CompressionType == MACH_COMPRESSED_BINARY_INVERT_LZSS) {
|
||||
KernelSize = (UINT32) DecompressLZSS (*Buffer, DecompressedSize, CompressedBuffer, CompressedSize);
|
||||
}
|
||||
|
||||
if (KernelSize != DecompressedSize) {
|
||||
KernelSize = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// TODO: implement adler32 hash verification.
|
||||
//
|
||||
|
||||
FreePool (CompressedBuffer);
|
||||
|
||||
return KernelSize;
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
ReadAppleKernelImage (
|
||||
IN EFI_FILE_PROTOCOL *File,
|
||||
IN OUT UINT8 **Buffer,
|
||||
OUT UINT32 *KernelSize,
|
||||
OUT UINT32 *AllocatedSize,
|
||||
IN UINT32 Offset
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 *MagicPtr;
|
||||
BOOLEAN ForbidFat;
|
||||
BOOLEAN Compressed;
|
||||
|
||||
Status = ReadFileData (File, Offset, KERNEL_HEADER_SIZE, *Buffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Do not allow FAT architectures with Offset > 0 (recursion).
|
||||
//
|
||||
ForbidFat = Offset > 0;
|
||||
Compressed = FALSE;
|
||||
|
||||
while (TRUE) {
|
||||
MagicPtr = (UINT32 *) *Buffer;
|
||||
if (!OC_ALIGNED (MagicPtr)) {
|
||||
DEBUG ((DEBUG_INFO, "Misaligned kernel header %p at %08X\n", MagicPtr, Offset));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
switch (*MagicPtr) {
|
||||
case MACH_HEADER_64_SIGNATURE:
|
||||
DEBUG ((DEBUG_VERBOSE, "Found Mach-O compressed %d offset %u size %u\n", Compressed, Offset, *KernelSize));
|
||||
|
||||
//
|
||||
// This is just a valid (formerly) compressed image.
|
||||
//
|
||||
if (Compressed) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// This is an uncompressed image, just fully read it.
|
||||
//
|
||||
|
||||
if (Offset == 0) {
|
||||
//
|
||||
// Figure out size for a non fat image.
|
||||
//
|
||||
Status = ReadFileSize (File, KernelSize);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "Kernel size cannot be determined - %r\n", Status));
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
}
|
||||
|
||||
Status = ReplaceBuffer (*KernelSize, Buffer, AllocatedSize);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "Kernel (%u bytes) cannot be allocated at %08X\n", *KernelSize, Offset));
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = ReadFileData (File, Offset, *KernelSize, *Buffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "Kernel (%u bytes) cannot be read at %08X\n", *KernelSize, Offset));
|
||||
}
|
||||
|
||||
return Status;
|
||||
case MACH_FAT_BINARY_SIGNATURE:
|
||||
case MACH_FAT_BINARY_INVERT_SIGNATURE: {
|
||||
if (ForbidFat) {
|
||||
DEBUG ((DEBUG_INFO, "Fat kernel recursion %p at %08X\n", MagicPtr, Offset));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*KernelSize = ParseFatArchitecture (File, Buffer, &Offset);
|
||||
if (*KernelSize != 0) {
|
||||
return ReadAppleKernelImage (File, Buffer, KernelSize, AllocatedSize, Offset);
|
||||
}
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
case MACH_COMPRESSED_BINARY_INVERT_SIGNATURE: {
|
||||
if (Compressed) {
|
||||
DEBUG ((DEBUG_INFO, "Compression recursion %p at %08X\n", MagicPtr, Offset));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// No FAT or Comp is allowed after compressed.
|
||||
//
|
||||
ForbidFat = Compressed = TRUE;
|
||||
|
||||
//
|
||||
// Loop into updated image in Buffer.
|
||||
//
|
||||
*KernelSize = ParseCompressedHeader (File, Buffer, &Offset, AllocatedSize);
|
||||
if (*KernelSize != 0) {
|
||||
DEBUG ((DEBUG_VERBOSE, "Compressed result has %08X magic\n", *(UINT32 *) Buffer));
|
||||
continue;
|
||||
}
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
default:
|
||||
DEBUG ((Offset > 0 ? DEBUG_INFO : DEBUG_VERBOSE, "Invalid kernel magic %08X at %08X\n", *MagicPtr, Offset));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
ReadAppleKernel (
|
||||
IN EFI_FILE_PROTOCOL *File,
|
||||
IN OUT UINT8 **Kernel,
|
||||
OUT UINT32 *KernelSize,
|
||||
OUT UINT32 *AllocatedSize
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
*KernelSize = 0;
|
||||
*AllocatedSize = KERNEL_HEADER_SIZE;
|
||||
*Kernel = AllocatePool (KERNEL_HEADER_SIZE);
|
||||
|
||||
if (*Kernel == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = ReadAppleKernelImage (
|
||||
File,
|
||||
Kernel,
|
||||
KernelSize,
|
||||
AllocatedSize,
|
||||
0
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreePool (*Kernel);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
@ -40,3 +40,5 @@
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
MemoryAllocationLib
|
||||
|
||||
72
Library/OcFileLib/FileProtocol.c
Normal file
72
Library/OcFileLib/FileProtocol.c
Normal file
@ -0,0 +1,72 @@
|
||||
/** @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 <Uefi.h>
|
||||
#include <Guid/FileInfo.h>
|
||||
#include <Protocol/SimpleFileSystem.h>
|
||||
|
||||
EFI_STATUS
|
||||
ReadFileData (
|
||||
IN EFI_FILE_PROTOCOL *File,
|
||||
IN UINT32 Position,
|
||||
IN UINT32 Size,
|
||||
OUT UINT8 *Buffer
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN ReadSize;
|
||||
|
||||
Status = File->SetPosition (File, Position);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
ReadSize = Size;
|
||||
Status = File->Read (File, &ReadSize, Buffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (ReadSize != Size) {
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
ReadFileSize (
|
||||
IN EFI_FILE_PROTOCOL *File,
|
||||
OUT UINT32 *Size
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT64 Position;
|
||||
|
||||
Status = File->SetPosition (File, 0xFFFFFFFFFFFFFFFFULL);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = File->GetPosition (File, &Position);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if ((UINT32) Position != Position) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
@ -27,6 +27,7 @@
|
||||
# VALID_ARCHITECTURES = IA32 X64
|
||||
|
||||
[Sources]
|
||||
FileProtocol.c
|
||||
GetFileInfo.c
|
||||
GetVolumeLabel.c
|
||||
ReadFile.c
|
||||
|
||||
@ -100,7 +100,7 @@ EFIAPI
|
||||
VirtualFileRead (
|
||||
IN EFI_FILE_PROTOCOL *This,
|
||||
IN OUT UINTN *BufferSize,
|
||||
OUT VOID *Buffer
|
||||
OUT VOID *Buffer
|
||||
)
|
||||
{
|
||||
VIRTUAL_FILE_DATA *Data;
|
||||
|
||||
@ -59,6 +59,9 @@
|
||||
## @libraryclass
|
||||
OcAppleImageVerificationLib|Include/Library/OcAppleImageVerificationLib.h
|
||||
|
||||
## @libraryclass
|
||||
OcAppleKernelLib|Include/Library/OcAppleKernelLib.h
|
||||
|
||||
## @libraryclass
|
||||
OcCompressionLib|Include/Library/OcCompressionLib.h
|
||||
|
||||
|
||||
@ -51,6 +51,7 @@
|
||||
OcAppleBootPolicyLib|OcSupportPkg/Library/OcAppleBootPolicyLib/OcAppleBootPolicyLib.inf
|
||||
OcAppleChunklistLib|OcSupportPkg/Library/OcAppleChunklistLib/OcAppleChunklistLib.inf
|
||||
OcAppleImageVerificationLib|OcSupportPkg/Library/OcAppleImageVerificationLib/OcAppleImageVerificationLib.inf
|
||||
OcAppleKernelLib|OcSupportPkg/Library/OcAppleKernelLib/OcAppleKernelLib.inf
|
||||
OcCpuLib|OcSupportPkg/Library/OcCpuLib/OcCpuLib.inf
|
||||
OcCryptoLib|OcSupportPkg/Library/OcCryptoLib/OcCryptoLib.inf
|
||||
OcCompressionLib|OcSupportPkg/Library/OcCompressionLib/OcCompressionLib.inf
|
||||
@ -78,6 +79,7 @@
|
||||
OcSupportPkg/Library/OcAppleBootPolicyLib/OcAppleBootPolicyLib.inf
|
||||
OcSupportPkg/Library/OcAppleChunklistLib/OcAppleChunklistLib.inf
|
||||
OcSupportPkg/Library/OcAppleImageVerificationLib/OcAppleImageVerificationLib.inf
|
||||
OcSupportPkg/Library/OcAppleKernelLib/OcAppleKernelLib.inf
|
||||
OcSupportPkg/Library/OcCpuLib/OcCpuLib.inf
|
||||
OcSupportPkg/Library/OcCryptoLib/OcCryptoLib.inf
|
||||
OcSupportPkg/Library/OcCompressionLib/OcCompressionLib.inf
|
||||
|
||||
@ -17,6 +17,12 @@ listed here.
|
||||
**Issues**:
|
||||
1. No proper interface for OS detection.
|
||||
1. No dmg boot detection.
|
||||
* OcAppleKernelLib
|
||||
**Status**: functional
|
||||
**Issues**: none
|
||||
* OcCompressionLib
|
||||
**Status**: functional
|
||||
**Issues**: none
|
||||
* OcAppleChunklistLib
|
||||
**Status**: in progress
|
||||
**Issues**:
|
||||
|
||||
@ -28,7 +28,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#include <Library/OcAppleBootPolicyLib.h>
|
||||
#include <Library/OcSmbiosLib.h>
|
||||
#include <Library/OcCpuLib.h>
|
||||
#include <Library/OcStringLib.h>
|
||||
#include <Library/OcVirtualFsLib.h>
|
||||
#include <Library/OcAppleKernelLib.h>
|
||||
|
||||
#include <Protocol/AppleBootPolicy.h>
|
||||
#include <Protocol/DevicePathPropertyDatabase.h>
|
||||
@ -55,11 +57,68 @@ TestFileOpen (
|
||||
IN UINT64 Attributes
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_STATUS Status;
|
||||
UINT8 *Kernel;
|
||||
UINT32 KernelSize;
|
||||
UINT32 AllocatedSize;
|
||||
CHAR16 *FileNameCopy;
|
||||
EFI_FILE_PROTOCOL *VirtualFileHandle;
|
||||
|
||||
Status = This->Open (This, NewHandle, FileName, OpenMode, Attributes);
|
||||
|
||||
Print (L"[FS %p] %s in %X/%X - %r\n", This, FileName, OpenMode, Attributes, Status);
|
||||
if (!EFI_ERROR (Status)
|
||||
&& OpenMode == EFI_FILE_MODE_READ
|
||||
&& StrStr (FileName, L"kernel") != NULL) {
|
||||
Print (L"Trying XNU hook on %s\n", FileName);
|
||||
Status = ReadAppleKernel (*NewHandle, &Kernel, &KernelSize, &AllocatedSize);
|
||||
Print (L"Result of XNU hook on %s is %r\n", FileName, Status);
|
||||
|
||||
//
|
||||
// This is not Apple kernel, just return the original file.
|
||||
//
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// TODO: patches, dropping, and injection here.
|
||||
//
|
||||
|
||||
ApplyPatch (
|
||||
(UINT8 *) "Darwin Kernel Version",
|
||||
NULL,
|
||||
L_STR_LEN ("Darwin Kernel Version"),
|
||||
(UINT8 *) "OpenCore Boot Version",
|
||||
Kernel,
|
||||
KernelSize,
|
||||
1,
|
||||
0
|
||||
);
|
||||
|
||||
//
|
||||
// This was our file, yet firmware is dying.
|
||||
//
|
||||
FileNameCopy = AllocateCopyPool (StrSize (FileName), FileName);
|
||||
if (FileNameCopy == NULL) {
|
||||
DEBUG ((DEBUG_WARN, "Failed to allocate kernel name (%a) copy\n", FileName));
|
||||
FreePool (Kernel);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Status = CreateVirtualFile (FileNameCopy, Kernel, KernelSize, &VirtualFileHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_WARN, "Failed to virtualise kernel file (%a)\n", FileName));
|
||||
FreePool (Kernel);
|
||||
FreePool (FileNameCopy);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Return our handle.
|
||||
//
|
||||
(*NewHandle)->Close(*NewHandle);
|
||||
*NewHandle = VirtualFileHandle;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
@ -62,6 +62,7 @@
|
||||
OcMiscLib
|
||||
OcProtocolLib
|
||||
OcAppleBootPolicyLib
|
||||
OcAppleKernelLib
|
||||
OcSmbiosLib
|
||||
OcDataHubLib
|
||||
OcVirtualFsLib
|
||||
|
||||
@ -61,4 +61,6 @@
|
||||
OcAppleBootPolicyLib
|
||||
OcSmbiosLib
|
||||
OcDataHubLib
|
||||
OcAppleKernelLib
|
||||
OcCompressionLib
|
||||
OcVirtualFsLib
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user