mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
OpenCore: Use direct PE loading for Secure Boot (#108)
Implement and integrate a PE image loader to circumvent UEFI Secure Boot when Apple Secure Boot is used.
This commit is contained in:
parent
ee7aaa37e1
commit
a97b74e83c
1
.gitignore
vendored
1
.gitignore
vendored
@ -24,6 +24,7 @@ Utilities/TestKextInject/Result.xml
|
||||
Utilities/TestMacho/Macho
|
||||
Utilities/TestRsaPreprocess/RsaPreprocess
|
||||
Utilities/TestSmbios/Smbios
|
||||
Utilities/TestPeCoff/PeCoff
|
||||
*.o
|
||||
*.exe
|
||||
DICT
|
||||
|
||||
722
Include/Acidanthera/IndustryStandard/OcPeImage.h
Normal file
722
Include/Acidanthera/IndustryStandard/OcPeImage.h
Normal file
@ -0,0 +1,722 @@
|
||||
/** @file
|
||||
EFI image format for PE32, PE32+ and TE. Please note some data structures are
|
||||
different for PE32 and PE32+. EFI_IMAGE_NT_HEADERS32 is for PE32 and
|
||||
EFI_IMAGE_NT_HEADERS64 is for PE32+.
|
||||
|
||||
This file is coded to the Visual Studio, Microsoft Portable Executable and
|
||||
Common Object File Format Specification, Revision 8.3 - February 6, 2013.
|
||||
This file also includes some definitions in PI Specification, Revision 1.0.
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||
Portions Copyright (c) 2016 - 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef OC_PE_IMAGE_H
|
||||
#define OC_PE_IMAGE_H
|
||||
|
||||
//
|
||||
// PE32+ Subsystem type for EFI images
|
||||
//
|
||||
#define EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION 10
|
||||
#define EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11
|
||||
#define EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12
|
||||
#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13 ///< defined PI Specification, 1.0
|
||||
|
||||
|
||||
//
|
||||
// PE32+ Machine type for EFI images
|
||||
//
|
||||
#define IMAGE_FILE_MACHINE_I386 0x014c
|
||||
#define IMAGE_FILE_MACHINE_IA64 0x0200
|
||||
#define IMAGE_FILE_MACHINE_EBC 0x0EBC
|
||||
#define IMAGE_FILE_MACHINE_X64 0x8664
|
||||
#define IMAGE_FILE_MACHINE_ARMTHUMB_MIXED 0x01c2
|
||||
#define IMAGE_FILE_MACHINE_ARM64 0xAA64
|
||||
|
||||
//
|
||||
// EXE file formats
|
||||
//
|
||||
#define EFI_IMAGE_DOS_SIGNATURE SIGNATURE_16('M', 'Z')
|
||||
#define EFI_IMAGE_OS2_SIGNATURE SIGNATURE_16('N', 'E')
|
||||
#define EFI_IMAGE_OS2_SIGNATURE_LE SIGNATURE_16('L', 'E')
|
||||
#define EFI_IMAGE_NT_SIGNATURE SIGNATURE_32('P', 'E', '\0', '\0')
|
||||
|
||||
///
|
||||
/// PE images can start with an optional DOS header, so if an image is run
|
||||
/// under DOS it can print an error message.
|
||||
///
|
||||
typedef struct {
|
||||
UINT16 e_magic; ///< Magic number.
|
||||
UINT16 e_cblp; ///< Bytes on last page of file.
|
||||
UINT16 e_cp; ///< Pages in file.
|
||||
UINT16 e_crlc; ///< Relocations.
|
||||
UINT16 e_cparhdr; ///< Size of header in paragraphs.
|
||||
UINT16 e_minalloc; ///< Minimum extra paragraphs needed.
|
||||
UINT16 e_maxalloc; ///< Maximum extra paragraphs needed.
|
||||
UINT16 e_ss; ///< Initial (relative) SS value.
|
||||
UINT16 e_sp; ///< Initial SP value.
|
||||
UINT16 e_csum; ///< Checksum.
|
||||
UINT16 e_ip; ///< Initial IP value.
|
||||
UINT16 e_cs; ///< Initial (relative) CS value.
|
||||
UINT16 e_lfarlc; ///< File address of relocation table.
|
||||
UINT16 e_ovno; ///< Overlay number.
|
||||
UINT16 e_res[4]; ///< Reserved words.
|
||||
UINT16 e_oemid; ///< OEM identifier (for e_oeminfo).
|
||||
UINT16 e_oeminfo; ///< OEM information; e_oemid specific.
|
||||
UINT16 e_res2[10]; ///< Reserved words.
|
||||
UINT32 e_lfanew; ///< File address of new exe header.
|
||||
} EFI_IMAGE_DOS_HEADER;
|
||||
|
||||
///
|
||||
/// COFF File Header (Object and Image).
|
||||
///
|
||||
typedef struct {
|
||||
UINT16 Machine;
|
||||
UINT16 NumberOfSections;
|
||||
UINT32 TimeDateStamp;
|
||||
UINT32 PointerToSymbolTable;
|
||||
UINT32 NumberOfSymbols;
|
||||
UINT16 SizeOfOptionalHeader;
|
||||
UINT16 Characteristics;
|
||||
} EFI_IMAGE_FILE_HEADER;
|
||||
|
||||
///
|
||||
/// Size of EFI_IMAGE_FILE_HEADER.
|
||||
///
|
||||
#define EFI_IMAGE_SIZEOF_FILE_HEADER 20
|
||||
|
||||
//
|
||||
// Characteristics
|
||||
//
|
||||
#define EFI_IMAGE_FILE_RELOCS_STRIPPED 1 ///< 0x0001 Relocation info stripped from file.
|
||||
|
||||
///
|
||||
/// Header Data Directories.
|
||||
///
|
||||
typedef struct {
|
||||
UINT32 VirtualAddress;
|
||||
UINT32 Size;
|
||||
} EFI_IMAGE_DATA_DIRECTORY;
|
||||
|
||||
//
|
||||
// Directory Entries
|
||||
//
|
||||
#define EFI_IMAGE_DIRECTORY_ENTRY_EXPORT 0
|
||||
#define EFI_IMAGE_DIRECTORY_ENTRY_IMPORT 1
|
||||
#define EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE 2
|
||||
#define EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION 3
|
||||
#define EFI_IMAGE_DIRECTORY_ENTRY_SECURITY 4
|
||||
#define EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC 5
|
||||
#define EFI_IMAGE_DIRECTORY_ENTRY_DEBUG 6
|
||||
#define EFI_IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7
|
||||
#define EFI_IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8
|
||||
#define EFI_IMAGE_DIRECTORY_ENTRY_TLS 9
|
||||
#define EFI_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10
|
||||
|
||||
#define EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES 16
|
||||
|
||||
///
|
||||
/// @attention
|
||||
/// EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC means PE32 and
|
||||
/// EFI_IMAGE_OPTIONAL_HEADER32 must be used. The data structures only vary
|
||||
/// after NT additional fields.
|
||||
///
|
||||
#define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
|
||||
|
||||
///
|
||||
/// @attention
|
||||
/// EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC means PE32+ and
|
||||
/// EFI_IMAGE_OPTIONAL_HEADER64 must be used. The data structures only vary
|
||||
/// after NT additional fields.
|
||||
///
|
||||
#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
|
||||
|
||||
|
||||
///
|
||||
/// @attention
|
||||
/// EFI_IMAGE_NT_HEADERS32 is for use ONLY by tools.
|
||||
///
|
||||
typedef struct {
|
||||
UINT32 Signature;
|
||||
EFI_IMAGE_FILE_HEADER FileHeader;
|
||||
} EFI_IMAGE_NT_HEADERS_COMMON_HDR;
|
||||
|
||||
STATIC_ASSERT (
|
||||
sizeof (EFI_IMAGE_NT_HEADERS_COMMON_HDR) == sizeof (UINT32) + sizeof (EFI_IMAGE_FILE_HEADER),
|
||||
"Unsupported padding."
|
||||
);
|
||||
|
||||
///
|
||||
/// @attention
|
||||
/// EFI_IMAGE_NT_HEADERS32 is for use ONLY by tools.
|
||||
///
|
||||
typedef struct {
|
||||
EFI_IMAGE_NT_HEADERS_COMMON_HDR CommonHeader;
|
||||
///
|
||||
/// Standard fields.
|
||||
///
|
||||
UINT16 Magic;
|
||||
UINT8 MajorLinkerVersion;
|
||||
UINT8 MinorLinkerVersion;
|
||||
UINT32 SizeOfCode;
|
||||
UINT32 SizeOfInitializedData;
|
||||
UINT32 SizeOfUninitializedData;
|
||||
UINT32 AddressOfEntryPoint;
|
||||
UINT32 BaseOfCode;
|
||||
UINT32 BaseOfData; ///< PE32 contains this additional field, which is absent in PE32+.
|
||||
///
|
||||
/// Optional Header Windows-Specific Fields.
|
||||
///
|
||||
UINT32 ImageBase;
|
||||
UINT32 SectionAlignment;
|
||||
UINT32 FileAlignment;
|
||||
UINT16 MajorOperatingSystemVersion;
|
||||
UINT16 MinorOperatingSystemVersion;
|
||||
UINT16 MajorImageVersion;
|
||||
UINT16 MinorImageVersion;
|
||||
UINT16 MajorSubsystemVersion;
|
||||
UINT16 MinorSubsystemVersion;
|
||||
UINT32 Win32VersionValue;
|
||||
UINT32 SizeOfImage;
|
||||
UINT32 SizeOfHeaders;
|
||||
UINT32 CheckSum;
|
||||
UINT16 Subsystem;
|
||||
UINT16 DllCharacteristics;
|
||||
UINT32 SizeOfStackReserve;
|
||||
UINT32 SizeOfStackCommit;
|
||||
UINT32 SizeOfHeapReserve;
|
||||
UINT32 SizeOfHeapCommit;
|
||||
UINT32 LoaderFlags;
|
||||
UINT32 NumberOfRvaAndSizes;
|
||||
EFI_IMAGE_DATA_DIRECTORY DataDirectory[];
|
||||
} EFI_IMAGE_NT_HEADERS32;
|
||||
|
||||
///
|
||||
/// @attention
|
||||
/// EFI_IMAGE_HEADERS64 is for use ONLY by tools.
|
||||
///
|
||||
typedef struct {
|
||||
EFI_IMAGE_NT_HEADERS_COMMON_HDR CommonHeader;
|
||||
///
|
||||
/// Standard fields.
|
||||
///
|
||||
UINT16 Magic;
|
||||
UINT8 MajorLinkerVersion;
|
||||
UINT8 MinorLinkerVersion;
|
||||
UINT32 SizeOfCode;
|
||||
UINT32 SizeOfInitializedData;
|
||||
UINT32 SizeOfUninitializedData;
|
||||
UINT32 AddressOfEntryPoint;
|
||||
UINT32 BaseOfCode;
|
||||
///
|
||||
/// Optional Header Windows-Specific Fields.
|
||||
///
|
||||
UINT64 ImageBase;
|
||||
UINT32 SectionAlignment;
|
||||
UINT32 FileAlignment;
|
||||
UINT16 MajorOperatingSystemVersion;
|
||||
UINT16 MinorOperatingSystemVersion;
|
||||
UINT16 MajorImageVersion;
|
||||
UINT16 MinorImageVersion;
|
||||
UINT16 MajorSubsystemVersion;
|
||||
UINT16 MinorSubsystemVersion;
|
||||
UINT32 Win32VersionValue;
|
||||
UINT32 SizeOfImage;
|
||||
UINT32 SizeOfHeaders;
|
||||
UINT32 CheckSum;
|
||||
UINT16 Subsystem;
|
||||
UINT16 DllCharacteristics;
|
||||
UINT64 SizeOfStackReserve;
|
||||
UINT64 SizeOfStackCommit;
|
||||
UINT64 SizeOfHeapReserve;
|
||||
UINT64 SizeOfHeapCommit;
|
||||
UINT32 LoaderFlags;
|
||||
UINT32 NumberOfRvaAndSizes;
|
||||
EFI_IMAGE_DATA_DIRECTORY DataDirectory[];
|
||||
} EFI_IMAGE_NT_HEADERS64;
|
||||
|
||||
//
|
||||
// Other Windows Subsystem Values
|
||||
//
|
||||
#define EFI_IMAGE_SUBSYSTEM_UNKNOWN 0
|
||||
#define EFI_IMAGE_SUBSYSTEM_NATIVE 1
|
||||
#define EFI_IMAGE_SUBSYSTEM_WINDOWS_GUI 2
|
||||
#define EFI_IMAGE_SUBSYSTEM_WINDOWS_CUI 3
|
||||
#define EFI_IMAGE_SUBSYSTEM_OS2_CUI 5
|
||||
#define EFI_IMAGE_SUBSYSTEM_POSIX_CUI 7
|
||||
|
||||
///
|
||||
/// Length of ShortName.
|
||||
///
|
||||
#define EFI_IMAGE_SIZEOF_SHORT_NAME 8
|
||||
|
||||
///
|
||||
/// Section Table. This table immediately follows the optional header.
|
||||
///
|
||||
typedef struct {
|
||||
UINT8 Name[EFI_IMAGE_SIZEOF_SHORT_NAME];
|
||||
UINT32 VirtualSize;
|
||||
UINT32 VirtualAddress;
|
||||
UINT32 SizeOfRawData;
|
||||
UINT32 PointerToRawData;
|
||||
UINT32 PointerToRelocations;
|
||||
UINT32 PointerToLinenumbers;
|
||||
UINT16 NumberOfRelocations;
|
||||
UINT16 NumberOfLinenumbers;
|
||||
UINT32 Characteristics;
|
||||
} EFI_IMAGE_SECTION_HEADER;
|
||||
|
||||
//
|
||||
// Section Flags Values
|
||||
//
|
||||
#define EFI_IMAGE_SCN_TYPE_NO_PAD BIT3 ///< 0x00000008 ///< Reserved.
|
||||
#define EFI_IMAGE_SCN_CNT_CODE BIT5 ///< 0x00000020
|
||||
#define EFI_IMAGE_SCN_CNT_INITIALIZED_DATA BIT6 ///< 0x00000040
|
||||
#define EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA BIT7 ///< 0x00000080
|
||||
|
||||
#define EFI_IMAGE_SCN_LNK_OTHER BIT8 ///< 0x00000100 ///< Reserved.
|
||||
#define EFI_IMAGE_SCN_LNK_INFO BIT9 ///< 0x00000200 ///< Section contains comments or some other type of information.
|
||||
#define EFI_IMAGE_SCN_LNK_REMOVE BIT11 ///< 0x00000800 ///< Section contents will not become part of image.
|
||||
#define EFI_IMAGE_SCN_LNK_COMDAT BIT12 ///< 0x00001000
|
||||
|
||||
#define EFI_IMAGE_SCN_ALIGN_1BYTES BIT20 ///< 0x00100000
|
||||
#define EFI_IMAGE_SCN_ALIGN_2BYTES BIT21 ///< 0x00200000
|
||||
#define EFI_IMAGE_SCN_ALIGN_4BYTES (BIT20|BIT21) ///< 0x00300000
|
||||
#define EFI_IMAGE_SCN_ALIGN_8BYTES BIT22 ///< 0x00400000
|
||||
#define EFI_IMAGE_SCN_ALIGN_16BYTES (BIT20|BIT22) ///< 0x00500000
|
||||
#define EFI_IMAGE_SCN_ALIGN_32BYTES (BIT21|BIT22) ///< 0x00600000
|
||||
#define EFI_IMAGE_SCN_ALIGN_64BYTES (BIT20|BIT21|BIT22) ///< 0x00700000
|
||||
|
||||
#define EFI_IMAGE_SCN_MEM_DISCARDABLE BIT25 ///< 0x02000000
|
||||
#define EFI_IMAGE_SCN_MEM_NOT_CACHED BIT26 ///< 0x04000000
|
||||
#define EFI_IMAGE_SCN_MEM_NOT_PAGED BIT27 ///< 0x08000000
|
||||
#define EFI_IMAGE_SCN_MEM_SHARED BIT28 ///< 0x10000000
|
||||
#define EFI_IMAGE_SCN_MEM_EXECUTE BIT29 ///< 0x20000000
|
||||
#define EFI_IMAGE_SCN_MEM_READ BIT30 ///< 0x40000000
|
||||
#define EFI_IMAGE_SCN_MEM_WRITE BIT31 ///< 0x80000000
|
||||
|
||||
///
|
||||
/// Size of a Symbol Table Record.
|
||||
///
|
||||
#define EFI_IMAGE_SIZEOF_SYMBOL 18
|
||||
|
||||
//
|
||||
// Symbols have a section number of the section in which they are
|
||||
// defined. Otherwise, section numbers have the following meanings:
|
||||
//
|
||||
#define EFI_IMAGE_SYM_UNDEFINED (UINT16) 0 ///< Symbol is undefined or is common.
|
||||
#define EFI_IMAGE_SYM_ABSOLUTE (UINT16) -1 ///< Symbol is an absolute value.
|
||||
#define EFI_IMAGE_SYM_DEBUG (UINT16) -2 ///< Symbol is a special debug item.
|
||||
|
||||
//
|
||||
// Symbol Type (fundamental) values.
|
||||
//
|
||||
#define EFI_IMAGE_SYM_TYPE_NULL 0 ///< no type.
|
||||
#define EFI_IMAGE_SYM_TYPE_VOID 1 ///< no valid type.
|
||||
#define EFI_IMAGE_SYM_TYPE_CHAR 2 ///< type character.
|
||||
#define EFI_IMAGE_SYM_TYPE_SHORT 3 ///< type short integer.
|
||||
#define EFI_IMAGE_SYM_TYPE_INT 4
|
||||
#define EFI_IMAGE_SYM_TYPE_LONG 5
|
||||
#define EFI_IMAGE_SYM_TYPE_FLOAT 6
|
||||
#define EFI_IMAGE_SYM_TYPE_DOUBLE 7
|
||||
#define EFI_IMAGE_SYM_TYPE_STRUCT 8
|
||||
#define EFI_IMAGE_SYM_TYPE_UNION 9
|
||||
#define EFI_IMAGE_SYM_TYPE_ENUM 10 ///< enumeration.
|
||||
#define EFI_IMAGE_SYM_TYPE_MOE 11 ///< member of enumeration.
|
||||
#define EFI_IMAGE_SYM_TYPE_BYTE 12
|
||||
#define EFI_IMAGE_SYM_TYPE_WORD 13
|
||||
#define EFI_IMAGE_SYM_TYPE_UINT 14
|
||||
#define EFI_IMAGE_SYM_TYPE_DWORD 15
|
||||
|
||||
//
|
||||
// Symbol Type (derived) values.
|
||||
//
|
||||
#define EFI_IMAGE_SYM_DTYPE_NULL 0 ///< no derived type.
|
||||
#define EFI_IMAGE_SYM_DTYPE_POINTER 1
|
||||
#define EFI_IMAGE_SYM_DTYPE_FUNCTION 2
|
||||
#define EFI_IMAGE_SYM_DTYPE_ARRAY 3
|
||||
|
||||
//
|
||||
// Storage classes.
|
||||
//
|
||||
#define EFI_IMAGE_SYM_CLASS_END_OF_FUNCTION ((UINT8) -1)
|
||||
#define EFI_IMAGE_SYM_CLASS_NULL 0
|
||||
#define EFI_IMAGE_SYM_CLASS_AUTOMATIC 1
|
||||
#define EFI_IMAGE_SYM_CLASS_EXTERNAL 2
|
||||
#define EFI_IMAGE_SYM_CLASS_STATIC 3
|
||||
#define EFI_IMAGE_SYM_CLASS_REGISTER 4
|
||||
#define EFI_IMAGE_SYM_CLASS_EXTERNAL_DEF 5
|
||||
#define EFI_IMAGE_SYM_CLASS_LABEL 6
|
||||
#define EFI_IMAGE_SYM_CLASS_UNDEFINED_LABEL 7
|
||||
#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8
|
||||
#define EFI_IMAGE_SYM_CLASS_ARGUMENT 9
|
||||
#define EFI_IMAGE_SYM_CLASS_STRUCT_TAG 10
|
||||
#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_UNION 11
|
||||
#define EFI_IMAGE_SYM_CLASS_UNION_TAG 12
|
||||
#define EFI_IMAGE_SYM_CLASS_TYPE_DEFINITION 13
|
||||
#define EFI_IMAGE_SYM_CLASS_UNDEFINED_STATIC 14
|
||||
#define EFI_IMAGE_SYM_CLASS_ENUM_TAG 15
|
||||
#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16
|
||||
#define EFI_IMAGE_SYM_CLASS_REGISTER_PARAM 17
|
||||
#define EFI_IMAGE_SYM_CLASS_BIT_FIELD 18
|
||||
#define EFI_IMAGE_SYM_CLASS_BLOCK 100
|
||||
#define EFI_IMAGE_SYM_CLASS_FUNCTION 101
|
||||
#define EFI_IMAGE_SYM_CLASS_END_OF_STRUCT 102
|
||||
#define EFI_IMAGE_SYM_CLASS_FILE 103
|
||||
#define EFI_IMAGE_SYM_CLASS_SECTION 104
|
||||
#define EFI_IMAGE_SYM_CLASS_WEAK_EXTERNAL 105
|
||||
|
||||
//
|
||||
// type packing constants
|
||||
//
|
||||
#define EFI_IMAGE_N_BTMASK 017
|
||||
#define EFI_IMAGE_N_TMASK 060
|
||||
#define EFI_IMAGE_N_TMASK1 0300
|
||||
#define EFI_IMAGE_N_TMASK2 0360
|
||||
#define EFI_IMAGE_N_BTSHFT 4
|
||||
#define EFI_IMAGE_N_TSHIFT 2
|
||||
|
||||
//
|
||||
// Communal selection types.
|
||||
//
|
||||
#define EFI_IMAGE_COMDAT_SELECT_NODUPLICATES 1
|
||||
#define EFI_IMAGE_COMDAT_SELECT_ANY 2
|
||||
#define EFI_IMAGE_COMDAT_SELECT_SAME_SIZE 3
|
||||
#define EFI_IMAGE_COMDAT_SELECT_EXACT_MATCH 4
|
||||
#define EFI_IMAGE_COMDAT_SELECT_ASSOCIATIVE 5
|
||||
|
||||
//
|
||||
// the following values only be referred in PeCoff, not defined in PECOFF.
|
||||
//
|
||||
#define EFI_IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1
|
||||
#define EFI_IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2
|
||||
#define EFI_IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3
|
||||
|
||||
///
|
||||
/// Relocation format.
|
||||
///
|
||||
typedef struct {
|
||||
UINT32 VirtualAddress;
|
||||
UINT32 SymbolTableIndex;
|
||||
UINT16 Type;
|
||||
} EFI_IMAGE_RELOCATION;
|
||||
|
||||
///
|
||||
/// Size of EFI_IMAGE_RELOCATION
|
||||
///
|
||||
#define EFI_IMAGE_SIZEOF_RELOCATION 10
|
||||
|
||||
//
|
||||
// I386 relocation types.
|
||||
//
|
||||
#define EFI_IMAGE_REL_I386_ABSOLUTE 0x0000 ///< Reference is absolute, no relocation is necessary.
|
||||
#define EFI_IMAGE_REL_I386_DIR16 0x0001 ///< Direct 16-bit reference to the symbols virtual address.
|
||||
#define EFI_IMAGE_REL_I386_REL16 0x0002 ///< PC-relative 16-bit reference to the symbols virtual address.
|
||||
#define EFI_IMAGE_REL_I386_DIR32 0x0006 ///< Direct 32-bit reference to the symbols virtual address.
|
||||
#define EFI_IMAGE_REL_I386_DIR32NB 0x0007 ///< Direct 32-bit reference to the symbols virtual address, base not included.
|
||||
#define EFI_IMAGE_REL_I386_SEG12 0x0009 ///< Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address.
|
||||
#define EFI_IMAGE_REL_I386_SECTION 0x000A
|
||||
#define EFI_IMAGE_REL_I386_SECREL 0x000B
|
||||
#define EFI_IMAGE_REL_I386_REL32 0x0014 ///< PC-relative 32-bit reference to the symbols virtual address.
|
||||
|
||||
//
|
||||
// x64 processor relocation types.
|
||||
//
|
||||
#define IMAGE_REL_AMD64_ABSOLUTE 0x0000
|
||||
#define IMAGE_REL_AMD64_ADDR64 0x0001
|
||||
#define IMAGE_REL_AMD64_ADDR32 0x0002
|
||||
#define IMAGE_REL_AMD64_ADDR32NB 0x0003
|
||||
#define IMAGE_REL_AMD64_REL32 0x0004
|
||||
#define IMAGE_REL_AMD64_REL32_1 0x0005
|
||||
#define IMAGE_REL_AMD64_REL32_2 0x0006
|
||||
#define IMAGE_REL_AMD64_REL32_3 0x0007
|
||||
#define IMAGE_REL_AMD64_REL32_4 0x0008
|
||||
#define IMAGE_REL_AMD64_REL32_5 0x0009
|
||||
#define IMAGE_REL_AMD64_SECTION 0x000A
|
||||
#define IMAGE_REL_AMD64_SECREL 0x000B
|
||||
#define IMAGE_REL_AMD64_SECREL7 0x000C
|
||||
#define IMAGE_REL_AMD64_TOKEN 0x000D
|
||||
#define IMAGE_REL_AMD64_SREL32 0x000E
|
||||
#define IMAGE_REL_AMD64_PAIR 0x000F
|
||||
#define IMAGE_REL_AMD64_SSPAN32 0x0010
|
||||
|
||||
///
|
||||
/// Based relocation format.
|
||||
///
|
||||
typedef struct {
|
||||
UINT32 VirtualAddress;
|
||||
UINT32 SizeOfBlock;
|
||||
UINT16 Relocations[];
|
||||
} EFI_IMAGE_BASE_RELOCATION;
|
||||
|
||||
///
|
||||
/// Size of EFI_IMAGE_BASE_RELOCATION.
|
||||
///
|
||||
#define EFI_IMAGE_SIZEOF_BASE_RELOCATION 8
|
||||
|
||||
//
|
||||
// Based relocation types.
|
||||
//
|
||||
#define EFI_IMAGE_REL_BASED_ABSOLUTE 0
|
||||
#define EFI_IMAGE_REL_BASED_HIGH 1
|
||||
#define EFI_IMAGE_REL_BASED_LOW 2
|
||||
#define EFI_IMAGE_REL_BASED_HIGHLOW 3
|
||||
#define EFI_IMAGE_REL_BASED_HIGHADJ 4
|
||||
#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5
|
||||
#define EFI_IMAGE_REL_BASED_ARM_MOV32A 5
|
||||
#define EFI_IMAGE_REL_BASED_ARM_MOV32T 7
|
||||
#define EFI_IMAGE_REL_BASED_IA64_IMM64 9
|
||||
#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR16 9
|
||||
#define EFI_IMAGE_REL_BASED_DIR64 10
|
||||
|
||||
///
|
||||
/// Line number format.
|
||||
///
|
||||
typedef struct {
|
||||
union {
|
||||
UINT32 SymbolTableIndex; ///< Symbol table index of function name if Linenumber is 0.
|
||||
UINT32 VirtualAddress; ///< Virtual address of line number.
|
||||
} Type;
|
||||
UINT16 Linenumber; ///< Line number.
|
||||
} EFI_IMAGE_LINENUMBER;
|
||||
|
||||
///
|
||||
/// Size of EFI_IMAGE_LINENUMBER.
|
||||
///
|
||||
#define EFI_IMAGE_SIZEOF_LINENUMBER 6
|
||||
|
||||
//
|
||||
// Archive format.
|
||||
//
|
||||
#define EFI_IMAGE_ARCHIVE_START_SIZE 8
|
||||
#define EFI_IMAGE_ARCHIVE_START "!<arch>\n"
|
||||
#define EFI_IMAGE_ARCHIVE_END "`\n"
|
||||
#define EFI_IMAGE_ARCHIVE_PAD "\n"
|
||||
#define EFI_IMAGE_ARCHIVE_LINKER_MEMBER "/ "
|
||||
#define EFI_IMAGE_ARCHIVE_LONGNAMES_MEMBER "// "
|
||||
|
||||
///
|
||||
/// Archive Member Headers
|
||||
///
|
||||
typedef struct {
|
||||
UINT8 Name[16]; ///< File member name - `/' terminated.
|
||||
UINT8 Date[12]; ///< File member date - decimal.
|
||||
UINT8 UserID[6]; ///< File member user id - decimal.
|
||||
UINT8 GroupID[6]; ///< File member group id - decimal.
|
||||
UINT8 Mode[8]; ///< File member mode - octal.
|
||||
UINT8 Size[10]; ///< File member size - decimal.
|
||||
UINT8 EndHeader[2]; ///< String to end header. (0x60 0x0A).
|
||||
} EFI_IMAGE_ARCHIVE_MEMBER_HEADER;
|
||||
|
||||
///
|
||||
/// Size of EFI_IMAGE_ARCHIVE_MEMBER_HEADER.
|
||||
///
|
||||
#define EFI_IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60
|
||||
|
||||
|
||||
//
|
||||
// DLL Support
|
||||
//
|
||||
|
||||
///
|
||||
/// Export Directory Table.
|
||||
///
|
||||
typedef struct {
|
||||
UINT32 Characteristics;
|
||||
UINT32 TimeDateStamp;
|
||||
UINT16 MajorVersion;
|
||||
UINT16 MinorVersion;
|
||||
UINT32 Name;
|
||||
UINT32 Base;
|
||||
UINT32 NumberOfFunctions;
|
||||
UINT32 NumberOfNames;
|
||||
UINT32 AddressOfFunctions;
|
||||
UINT32 AddressOfNames;
|
||||
UINT32 AddressOfNameOrdinals;
|
||||
} EFI_IMAGE_EXPORT_DIRECTORY;
|
||||
|
||||
///
|
||||
/// Hint/Name Table.
|
||||
///
|
||||
typedef struct {
|
||||
UINT16 Hint;
|
||||
UINT8 Name[1];
|
||||
} EFI_IMAGE_IMPORT_BY_NAME;
|
||||
|
||||
///
|
||||
/// Import Address Table RVA (Thunk Table).
|
||||
///
|
||||
typedef struct {
|
||||
union {
|
||||
UINT32 Function;
|
||||
UINT32 Ordinal;
|
||||
EFI_IMAGE_IMPORT_BY_NAME *AddressOfData;
|
||||
} u1;
|
||||
} EFI_IMAGE_THUNK_DATA;
|
||||
|
||||
#define EFI_IMAGE_ORDINAL_FLAG BIT31 ///< Flag for PE32.
|
||||
#define EFI_IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & EFI_IMAGE_ORDINAL_FLAG) != 0)
|
||||
#define EFI_IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff)
|
||||
|
||||
///
|
||||
/// Import Directory Table
|
||||
///
|
||||
typedef struct {
|
||||
UINT32 Characteristics;
|
||||
UINT32 TimeDateStamp;
|
||||
UINT32 ForwarderChain;
|
||||
UINT32 Name;
|
||||
EFI_IMAGE_THUNK_DATA *FirstThunk;
|
||||
} EFI_IMAGE_IMPORT_DESCRIPTOR;
|
||||
|
||||
|
||||
///
|
||||
/// Debug Directory Format.
|
||||
///
|
||||
typedef struct {
|
||||
UINT32 Characteristics;
|
||||
UINT32 TimeDateStamp;
|
||||
UINT16 MajorVersion;
|
||||
UINT16 MinorVersion;
|
||||
UINT32 Type;
|
||||
UINT32 SizeOfData;
|
||||
UINT32 RVA; ///< The address of the debug data when loaded, relative to the image base.
|
||||
UINT32 FileOffset; ///< The file pointer to the debug data.
|
||||
} EFI_IMAGE_DEBUG_DIRECTORY_ENTRY;
|
||||
|
||||
#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW 2 ///< The Visual C++ debug information.
|
||||
|
||||
///
|
||||
/// Debug Data Structure defined in Microsoft C++.
|
||||
///
|
||||
#define CODEVIEW_SIGNATURE_NB10 SIGNATURE_32('N', 'B', '1', '0')
|
||||
typedef struct {
|
||||
UINT32 Signature; ///< "NB10"
|
||||
UINT32 Unknown;
|
||||
UINT32 Unknown2;
|
||||
UINT32 Unknown3;
|
||||
//
|
||||
// Filename of .PDB goes here
|
||||
//
|
||||
} EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY;
|
||||
|
||||
///
|
||||
/// Debug Data Structure defined in Microsoft C++.
|
||||
///
|
||||
#define CODEVIEW_SIGNATURE_RSDS SIGNATURE_32('R', 'S', 'D', 'S')
|
||||
typedef struct {
|
||||
UINT32 Signature; ///< "RSDS".
|
||||
UINT32 Unknown;
|
||||
UINT32 Unknown2;
|
||||
UINT32 Unknown3;
|
||||
UINT32 Unknown4;
|
||||
UINT32 Unknown5;
|
||||
//
|
||||
// Filename of .PDB goes here
|
||||
//
|
||||
} EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY;
|
||||
|
||||
|
||||
///
|
||||
/// Debug Data Structure defined by Apple Mach-O to Coff utility.
|
||||
///
|
||||
#define CODEVIEW_SIGNATURE_MTOC SIGNATURE_32('M', 'T', 'O', 'C')
|
||||
typedef struct {
|
||||
UINT32 Signature; ///< "MTOC".
|
||||
UINT64 MachOUuid[2];
|
||||
//
|
||||
// Filename of .DLL (Mach-O with debug info) goes here
|
||||
//
|
||||
} EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY;
|
||||
|
||||
///
|
||||
/// Resource directory entry format.
|
||||
///
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
UINT32 NameOffset:31;
|
||||
UINT32 NameIsString:1;
|
||||
} s;
|
||||
UINT32 Id;
|
||||
} u1;
|
||||
union {
|
||||
UINT32 OffsetToData;
|
||||
struct {
|
||||
UINT32 OffsetToDirectory:31;
|
||||
UINT32 DataIsDirectory:1;
|
||||
} s;
|
||||
} u2;
|
||||
} EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY;
|
||||
|
||||
///
|
||||
/// Resource format.
|
||||
///
|
||||
typedef struct {
|
||||
UINT32 Characteristics;
|
||||
UINT32 TimeDateStamp;
|
||||
UINT16 MajorVersion;
|
||||
UINT16 MinorVersion;
|
||||
UINT16 NumberOfNamedEntries;
|
||||
UINT16 NumberOfIdEntries;
|
||||
EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY Entires[];
|
||||
} EFI_IMAGE_RESOURCE_DIRECTORY;
|
||||
|
||||
///
|
||||
/// Resource directory entry for string.
|
||||
///
|
||||
typedef struct {
|
||||
UINT16 Length;
|
||||
CHAR16 String[1];
|
||||
} EFI_IMAGE_RESOURCE_DIRECTORY_STRING;
|
||||
|
||||
///
|
||||
/// Resource directory entry for data array.
|
||||
///
|
||||
typedef struct {
|
||||
UINT32 OffsetToData;
|
||||
UINT32 Size;
|
||||
UINT32 CodePage;
|
||||
UINT32 Reserved;
|
||||
} EFI_IMAGE_RESOURCE_DATA_ENTRY;
|
||||
|
||||
///
|
||||
/// Header format for TE images, defined in the PI Specification, 1.0.
|
||||
///
|
||||
typedef struct {
|
||||
UINT16 Signature; ///< The signature for TE format = "VZ".
|
||||
UINT16 Machine; ///< From the original file header.
|
||||
UINT8 NumberOfSections; ///< From the original file header.
|
||||
UINT8 Subsystem; ///< From original optional header.
|
||||
UINT16 StrippedSize; ///< Number of bytes we removed from the header.
|
||||
UINT32 AddressOfEntryPoint; ///< Offset to entry point -- from original optional header.
|
||||
UINT32 BaseOfCode; ///< From original image -- required for ITP debug.
|
||||
UINT64 ImageBase; ///< From original file header.
|
||||
EFI_IMAGE_DATA_DIRECTORY DataDirectory[2]; ///< Only base relocation and debug directory.
|
||||
} EFI_TE_IMAGE_HEADER;
|
||||
|
||||
|
||||
#define EFI_TE_IMAGE_HEADER_SIGNATURE SIGNATURE_16('V', 'Z')
|
||||
|
||||
//
|
||||
// Data directory indexes in our TE image header
|
||||
//
|
||||
#define EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC 0
|
||||
#define EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG 1
|
||||
|
||||
|
||||
///
|
||||
/// Union of PE32, PE32+, and TE headers.
|
||||
///
|
||||
typedef union {
|
||||
EFI_IMAGE_NT_HEADERS_COMMON_HDR PeCommon;
|
||||
EFI_IMAGE_NT_HEADERS32 Pe32;
|
||||
EFI_IMAGE_NT_HEADERS64 Pe32Plus;
|
||||
EFI_TE_IMAGE_HEADER Te;
|
||||
} EFI_IMAGE_OPTIONAL_HEADER_UNION;
|
||||
|
||||
#endif // OC_PE_IMAGE_H
|
||||
@ -72,11 +72,13 @@ OcAppleSecureBootSetDmgLoading (
|
||||
/**
|
||||
Get DMG loading status on Apple Secure Boot protocol.
|
||||
|
||||
@param[out] RealPolicy Actual secure boot policy, optional.
|
||||
|
||||
@retval TRUE when loading DMG.
|
||||
**/
|
||||
BOOLEAN
|
||||
OcAppleSecureBootGetDmgLoading (
|
||||
VOID
|
||||
OUT UINT8 *RealPolicy OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@ -1238,4 +1238,43 @@ OcRegisterBootOption (
|
||||
IN CONST CHAR16 *FilePath
|
||||
);
|
||||
|
||||
/**
|
||||
Initialises custom Boot Services overrides to support direct images.
|
||||
**/
|
||||
VOID
|
||||
OcInitDirectImageLoader (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Make DirectImageLoader the default for Apple Secure Boot.
|
||||
**/
|
||||
VOID
|
||||
OcActivateDirectImageLoader (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Simplified load image routine, which bypasses UEFI and loads the image directly.
|
||||
|
||||
@param[in] BootPolicy Ignored.
|
||||
@param[in] ParentImageHandle The caller's image handle.
|
||||
@param[in] DevicePath Ignored.
|
||||
@param[in] SourceBuffer Pointer to the memory location containing image to be loaded.
|
||||
@param[in] SourceSize The size in bytes of SourceBuffer.
|
||||
@param[out] ImageHandle The pointer to the returned image handle created on success.
|
||||
|
||||
@retval EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
OcDirectLoadImage (
|
||||
IN BOOLEAN BootPolicy,
|
||||
IN EFI_HANDLE ParentImageHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
||||
IN VOID *SourceBuffer OPTIONAL,
|
||||
IN UINTN SourceSize,
|
||||
OUT EFI_HANDLE *ImageHandle
|
||||
);
|
||||
|
||||
#endif // OC_BOOT_MANAGEMENT_LIB_H
|
||||
|
||||
@ -109,6 +109,13 @@ OcOverflowMulAddU32 (
|
||||
UINT32 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
OcOverflowAlignUpU32 (
|
||||
UINT32 Value,
|
||||
UINT32 Alignment,
|
||||
UINT32 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
OcOverflowAddS32 (
|
||||
INT32 A,
|
||||
|
||||
198
Include/Acidanthera/Library/OcPeCoffLib.h
Normal file
198
Include/Acidanthera/Library/OcPeCoffLib.h
Normal file
@ -0,0 +1,198 @@
|
||||
/** @file
|
||||
Provides services to load and relocate a PE/COFF image.
|
||||
|
||||
The PE/COFF Loader Library abstracts the implementation of a PE/COFF loader for
|
||||
IA-32, x86, and EBC processor types. The library functions are memory-based
|
||||
and can be ported easily to any environment.
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef OC_PE_COFF_LIB_H
|
||||
#define OC_PE_COFF_LIB_H
|
||||
|
||||
#include <IndustryStandard/OcPeImage.h>
|
||||
|
||||
// TODO: move?
|
||||
/**
|
||||
Performs digest on a data buffer of the specified length. This function can
|
||||
be called multiple times to compute the digest of long or discontinuous data streams.
|
||||
|
||||
If HashContext is NULL, then ASSERT().
|
||||
|
||||
@param[in,out] HashContext Pointer to the MD5 context.
|
||||
@param[in] Data Pointer to the buffer containing the data to be hashed.
|
||||
@param[in] DataLength Length of Data buffer in bytes.
|
||||
|
||||
@retval TRUE HASH data digest succeeded.
|
||||
@retval FALSE Invalid HASH context. After HashFinal function has been called, the
|
||||
HASH context cannot be reused.
|
||||
|
||||
**/
|
||||
typedef
|
||||
BOOLEAN
|
||||
(EFIAPI *HASH_UPDATE)(
|
||||
IN OUT VOID *HashContext,
|
||||
IN CONST VOID *Data,
|
||||
IN UINTN DataLength
|
||||
);
|
||||
|
||||
//
|
||||
// Return status codes from the PE/COFF Loader services
|
||||
//
|
||||
#define IMAGE_ERROR_SUCCESS 0U
|
||||
#define IMAGE_ERROR_IMAGE_READ 1U
|
||||
#define IMAGE_ERROR_INVALID_PE_HEADER_SIGNATURE 2U
|
||||
#define IMAGE_ERROR_INVALID_MACHINE_TYPE 3U
|
||||
#define IMAGE_ERROR_INVALID_SUBSYSTEM 4U
|
||||
#define IMAGE_ERROR_INVALID_IMAGE_ADDRESS 5U
|
||||
#define IMAGE_ERROR_INVALID_IMAGE_SIZE 6U
|
||||
#define IMAGE_ERROR_INVALID_SECTION_ALIGNMENT 7U
|
||||
#define IMAGE_ERROR_SECTION_NOT_LOADED 8U
|
||||
#define IMAGE_ERROR_FAILED_RELOCATION 9U
|
||||
#define IMAGE_ERROR_FAILED_ICACHE_FLUSH 10U
|
||||
#define IMAGE_ERROR_UNSUPPORTED 11U
|
||||
|
||||
typedef UINTN IMAGE_STATUS;
|
||||
|
||||
typedef enum {
|
||||
ImageTypeTe,
|
||||
ImageTypePe32,
|
||||
ImageTypePe32Plus,
|
||||
ImageTypeMax
|
||||
} IMAGE_LOADER_IMAGE_TYPE;
|
||||
|
||||
///
|
||||
/// The context structure used while PE/COFF image is being loaded and relocated.
|
||||
///
|
||||
typedef struct {
|
||||
///
|
||||
/// Set by OcPeCoffLoaderInitializeContext() to the ImageBase in the PE/COFF header.
|
||||
///
|
||||
UINT64 ImageBase;
|
||||
//
|
||||
// Before LoadImage returns, a pointer to the raw file image.
|
||||
// After LoadImage returns, a pointer to the loaded image.
|
||||
//
|
||||
VOID *FileBuffer;
|
||||
///
|
||||
/// Set by OcPeCoffLoaderInitializeContext() to the SizeOfImage in the PE/COFF header.
|
||||
/// Image size includes the size of Debug Entry if it is present.
|
||||
///
|
||||
UINT32 SizeOfImage;
|
||||
UINT32 SectionAlignment;
|
||||
///
|
||||
/// Set by OcPeCoffLoaderInitializeContext() to offset to the PE/COFF header.
|
||||
/// If the PE/COFF image does not start with a DOS header, this value is zero.
|
||||
/// Otherwise, it's the offset to the PE/COFF header.
|
||||
///
|
||||
UINT32 ExeHdrOffset;
|
||||
///
|
||||
/// Is set by OcPeCoffLoaderInitializeContext() to the Section Alignment in the PE/COFF header.
|
||||
///
|
||||
UINT32 SizeOfHeaders;
|
||||
UINT32 AddressOfEntryPoint;
|
||||
///
|
||||
/// Set by OcPeCoffLoaderInitializeContext() to TRUE if the PE/COFF image does not contain
|
||||
/// relocation information.
|
||||
///
|
||||
BOOLEAN RelocsStripped;
|
||||
///
|
||||
/// Set by OcPeCoffLoaderInitializeContext() to TRUE if the image is a TE image.
|
||||
/// For a definition of the TE Image format, see the Platform Initialization Pre-EFI
|
||||
/// Initialization Core Interface Specification.
|
||||
///
|
||||
UINT8 ImageType;
|
||||
UINT16 Subsystem;
|
||||
UINT16 Machine;
|
||||
UINT32 TeStrippedOffset;
|
||||
|
||||
UINT32 RelocDirRva;
|
||||
UINT32 RelocDirSize;
|
||||
} PE_COFF_LOADER_IMAGE_CONTEXT;
|
||||
|
||||
/**
|
||||
Retrieves information about a PE/COFF image.
|
||||
|
||||
Computes the ExeHdrOffset, IsTeImage, ImageType, ImageAddress, ImageSize,
|
||||
DestinationAddress, RelocsStripped, SectionAlignment, SizeOfHeaders, and
|
||||
DebugDirectoryEntryRva fields of the ImageContext structure.
|
||||
If ImageContext is NULL, then return RETURN_INVALID_PARAMETER.
|
||||
If the PE/COFF image accessed through the ImageRead service in the ImageContext
|
||||
structure is not a supported PE/COFF image type, then return RETURN_UNSUPPORTED.
|
||||
If any errors occur while computing the fields of ImageContext,
|
||||
then the error status is returned in the ImageError field of ImageContext.
|
||||
If the image is a TE image, then SectionAlignment is set to 0.
|
||||
The ImageRead and Handle fields of ImageContext structure must be valid prior
|
||||
to invoking this service.
|
||||
|
||||
@param ImageContext The pointer to the image context structure that
|
||||
describes the PE/COFF image that needs to be
|
||||
examined by this function.
|
||||
|
||||
@retval RETURN_SUCCESS The information on the PE/COFF image was collected.
|
||||
@retval RETURN_INVALID_PARAMETER ImageContext is NULL.
|
||||
@retval RETURN_UNSUPPORTED The PE/COFF image is not supported.
|
||||
|
||||
**/
|
||||
IMAGE_STATUS
|
||||
OcPeCoffLoaderInitializeContext (
|
||||
OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context,
|
||||
IN CONST VOID *FileBuffer,
|
||||
IN UINTN FileSize
|
||||
);
|
||||
|
||||
/**
|
||||
Loads a PE/COFF image into memory.
|
||||
|
||||
Loads the PE/COFF image accessed through the ImageRead service of ImageContext into the buffer
|
||||
specified by the ImageAddress and ImageSize fields of ImageContext. The caller must allocate
|
||||
the load buffer and fill in the ImageAddress and ImageSize fields prior to calling this function.
|
||||
The EntryPoint, FixupDataSize, CodeView, PdbPointer and HiiResourceData fields of ImageContext are computed.
|
||||
The ImageRead, Handle, ExeHdrOffset, IsTeImage, Machine, ImageType, ImageAddress, ImageSize,
|
||||
DestinationAddress, RelocsStripped, SectionAlignment, SizeOfHeaders, and DebugDirectoryEntryRva
|
||||
fields of the ImageContext structure must be valid prior to invoking this service.
|
||||
|
||||
If ImageContext is NULL, then ASSERT().
|
||||
|
||||
Note that if the platform does not maintain coherency between the instruction cache(s) and the data
|
||||
cache(s) in hardware, then the caller is responsible for performing cache maintenance operations
|
||||
prior to transferring control to a PE/COFF image that is loaded using this library.
|
||||
|
||||
@param ImageContext The pointer to the image context structure that describes the PE/COFF
|
||||
image that is being loaded.
|
||||
|
||||
@retval RETURN_SUCCESS The PE/COFF image was loaded into the buffer specified by
|
||||
the ImageAddress and ImageSize fields of ImageContext.
|
||||
Extended status information is in the ImageError field of ImageContext.
|
||||
@retval RETURN_BUFFER_TOO_SMALL The caller did not provide a large enough buffer.
|
||||
Extended status information is in the ImageError field of ImageContext.
|
||||
@retval RETURN_LOAD_ERROR The PE/COFF image is an EFI Runtime image with no relocations.
|
||||
Extended status information is in the ImageError field of ImageContext.
|
||||
@retval RETURN_INVALID_PARAMETER The image address is invalid.
|
||||
Extended status information is in the ImageError field of ImageContext.
|
||||
|
||||
**/
|
||||
IMAGE_STATUS
|
||||
OcPeCoffLoaderLoadImage (
|
||||
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context,
|
||||
OUT VOID *Destination,
|
||||
IN UINT32 DestinationSize
|
||||
);
|
||||
|
||||
IMAGE_STATUS
|
||||
OcPeCoffLoaderRelocateImage (
|
||||
IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *Context,
|
||||
IN UINTN BaseAddress
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
OcPeCoffLoaderHashImage (
|
||||
IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *Context,
|
||||
IN HASH_UPDATE HashUpdate,
|
||||
IN OUT VOID *HashContext
|
||||
);
|
||||
|
||||
#endif // OC_PE_COFF_LIB_H
|
||||
@ -18,6 +18,7 @@
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/OcApfsLib.h>
|
||||
#include <Library/OcAppleImageVerificationLib.h>
|
||||
#include <Library/OcAppleSecureBootLib.h>
|
||||
#include <Library/OcBootManagementLib.h>
|
||||
#include <Library/OcConsoleLib.h>
|
||||
#include <Library/OcDriverConnectionLib.h>
|
||||
@ -239,6 +240,9 @@ ApfsStartDriver (
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||
EFI_HANDLE ImageHandle;
|
||||
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
|
||||
EFI_IMAGE_LOAD LoadImage;
|
||||
APPLE_SECURE_BOOT_PROTOCOL *SecureBoot;
|
||||
UINT8 Policy;
|
||||
|
||||
Status = VerifyApplePeImageSignature (
|
||||
DriverBuffer,
|
||||
@ -272,8 +276,26 @@ ApfsStartDriver (
|
||||
DevicePath = NULL;
|
||||
}
|
||||
|
||||
SecureBoot = OcAppleSecureBootGetProtocol ();
|
||||
ASSERT (SecureBoot != NULL);
|
||||
Status = SecureBoot->GetPolicy (
|
||||
SecureBoot,
|
||||
&Policy
|
||||
);
|
||||
//
|
||||
// Load directly when we have Apple Secure Boot.
|
||||
// - Either normal.
|
||||
// - Or during DMG loading.
|
||||
//
|
||||
if ((!EFI_ERROR (Status) && Policy != AppleImg4SbModeDisabled)
|
||||
|| (OcAppleSecureBootGetDmgLoading (&Policy) && Policy != AppleImg4SbModeDisabled)) {
|
||||
LoadImage = OcDirectLoadImage;
|
||||
} else {
|
||||
LoadImage = gBS->LoadImage;
|
||||
}
|
||||
|
||||
ImageHandle = NULL;
|
||||
Status = gBS->LoadImage (
|
||||
Status = LoadImage (
|
||||
FALSE,
|
||||
gImageHandle,
|
||||
DevicePath,
|
||||
|
||||
@ -37,6 +37,7 @@ STATIC APPLE_SECURE_BOOT_PROTOCOL *mSecureBoot;
|
||||
STATIC CHAR8 mSbHardwareModel[16];
|
||||
STATIC UINT64 mSbEcid;
|
||||
STATIC BOOLEAN mDmgLoading = FALSE;
|
||||
STATIC UINT8 mDmgLoadingPolicy = AppleImg4SbModeMedium;
|
||||
STATIC BOOLEAN mSbAvailable = TRUE;
|
||||
STATIC UINT8 mSbPolicy = AppleImg4SbModeMedium;
|
||||
STATIC UINT8 mSbWindowsPolicy = 1;
|
||||
@ -958,24 +959,33 @@ OcAppleSecureBootSetDmgLoading (
|
||||
IN BOOLEAN LoadingDmg
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
ASSERT (mSecureBoot != NULL);
|
||||
|
||||
mDmgLoading = LoadingDmg;
|
||||
|
||||
Status = mSecureBoot->GetPolicy (mSecureBoot, &mDmgLoadingPolicy);
|
||||
if (EFI_ERROR (Status)) {
|
||||
mDmgLoadingPolicy = AppleImg4SbModeMedium;
|
||||
}
|
||||
|
||||
if (LoadingDmg) {
|
||||
DEBUG ((DEBUG_INFO, "OCB: Disabling secure boot for Apple images\n"));
|
||||
DEBUG ((DEBUG_INFO, "OCSB: Disabling secure boot for Apple images\n"));
|
||||
mSecureBoot->SetAvailability (mSecureBoot, FALSE);
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCB: Reenabling secure boot after Apple images\n"));
|
||||
DEBUG ((DEBUG_INFO, "OCSB: Reenabling secure boot after Apple images\n"));
|
||||
mSecureBoot->SetAvailability (mSecureBoot, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
OcAppleSecureBootGetDmgLoading (
|
||||
VOID
|
||||
OUT UINT8 *RealPolicy OPTIONAL
|
||||
)
|
||||
{
|
||||
if (RealPolicy != NULL) {
|
||||
*RealPolicy = mDmgLoadingPolicy;
|
||||
}
|
||||
return mDmgLoading;
|
||||
}
|
||||
|
||||
@ -1015,7 +1025,8 @@ OcAppleSecureBootVerify (
|
||||
// they do not even have global manifests in DMG images.
|
||||
// Can consider checking boot.efi codesign integrity if we want.
|
||||
//
|
||||
if (Policy == AppleImg4SbModeDisabled && OcAppleSecureBootGetDmgLoading ()) {
|
||||
if (Policy == AppleImg4SbModeDisabled && OcAppleSecureBootGetDmgLoading (NULL)) {
|
||||
DEBUG ((DEBUG_INFO, "OCSB: Direct booting for DMG image\n"));
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1023,6 +1034,7 @@ OcAppleSecureBootVerify (
|
||||
// For everything else it is unsupported, meaning let the system decide.
|
||||
//
|
||||
if (Policy == AppleImg4SbModeDisabled) {
|
||||
DEBUG ((DEBUG_INFO, "OCSB: Secure boot is disabled, skipping\n"));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -1034,7 +1046,7 @@ OcAppleSecureBootVerify (
|
||||
&ManifestSize
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCB: No IMG4 found - %r\n", Status));
|
||||
DEBUG ((DEBUG_INFO, "OCSB: No IMG4 found - %r\n", Status));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -1055,18 +1067,12 @@ OcAppleSecureBootVerify (
|
||||
FALSE
|
||||
);
|
||||
|
||||
//
|
||||
// This is our signature, but the file is corrupted.
|
||||
//
|
||||
if (Status == EFI_SECURITY_VIOLATION) {
|
||||
DEBUG ((DEBUG_WARN, "OCB: IMG4 %08X verification gave secure violation\n"));
|
||||
return EFI_SECURITY_VIOLATION;
|
||||
}
|
||||
|
||||
//
|
||||
// We are successful.
|
||||
//
|
||||
if (!EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCSB: Verified IMG4 without issues\n"));
|
||||
FreePool (ManifestBuffer);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
@ -1074,5 +1080,7 @@ OcAppleSecureBootVerify (
|
||||
//
|
||||
// No suitable signature.
|
||||
//
|
||||
DEBUG ((DEBUG_INFO, "OCSB: No suitable signature - %r\n", Status));
|
||||
FreePool (ManifestBuffer);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -1841,7 +1841,7 @@ OcLoadBootEntry (
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = Context->StartImage (BootEntry, EntryHandle, NULL, NULL);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "OCB: StartImage failed - %r\n", Status));
|
||||
DEBUG ((DEBUG_WARN, "OCB: StartImage failed - %r\n", Status));
|
||||
//
|
||||
// Unload dmg if any.
|
||||
//
|
||||
|
||||
@ -176,14 +176,4 @@ InternalSystemActionResetNvram (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Initialises custom gBS->LoadImage override.
|
||||
|
||||
@retval EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
InternalInitImageLoader (
|
||||
VOID
|
||||
);
|
||||
|
||||
#endif // BOOT_MANAGEMENET_INTERNAL_H
|
||||
|
||||
@ -14,7 +14,10 @@
|
||||
|
||||
#include "BootManagementInternal.h"
|
||||
|
||||
#include <IndustryStandard/OcPeImage.h>
|
||||
|
||||
#include <Protocol/DevicePath.h>
|
||||
#include <Protocol/LoadedImage.h>
|
||||
#include <Protocol/SimpleFileSystem.h>
|
||||
|
||||
#include <Guid/AppleVariable.h>
|
||||
@ -33,12 +36,44 @@
|
||||
#include <Library/OcFileLib.h>
|
||||
#include <Library/OcMachoLib.h>
|
||||
#include <Library/OcStringLib.h>
|
||||
#include <Library/OcPeCoffLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
|
||||
STATIC EFI_IMAGE_LOAD mOriginalEfiLoadImage;
|
||||
#if defined(MDE_CPU_IA32)
|
||||
#define OC_IMAGE_FILE_MACHINE IMAGE_FILE_MACHINE_I386
|
||||
#elif defined(MDE_CPU_X64)
|
||||
#define OC_IMAGE_FILE_MACHINE IMAGE_FILE_MACHINE_X64
|
||||
#else
|
||||
#error Unsupported architecture.
|
||||
#endif
|
||||
|
||||
STATIC EFI_GUID mOcLoadedImageProtocolGuid = {
|
||||
0x1f3c963d, 0xf9dc, 0x4537, { 0xbb, 0x06, 0xd8, 0x08, 0x46, 0x4a, 0x85, 0x2e }
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
EFI_IMAGE_ENTRY_POINT EntryPoint;
|
||||
EFI_PHYSICAL_ADDRESS ImageArea;
|
||||
UINTN PageCount;
|
||||
EFI_STATUS Status;
|
||||
VOID *JumpBuffer;
|
||||
BASE_LIBRARY_JUMP_BUFFER *JumpContext;
|
||||
CHAR16 *ExitData;
|
||||
UINTN ExitDataSize;
|
||||
UINT16 Subsystem;
|
||||
BOOLEAN Started;
|
||||
EFI_LOADED_IMAGE_PROTOCOL LoadedImage;
|
||||
} OC_LOADED_IMAGE_PROTOCOL;
|
||||
|
||||
STATIC EFI_IMAGE_LOAD mOriginalEfiLoadImage;
|
||||
STATIC EFI_IMAGE_START mOriginalEfiStartImage;
|
||||
STATIC EFI_IMAGE_UNLOAD mOriginalEfiUnloadImage;
|
||||
STATIC EFI_EXIT mOriginalEfiExit;
|
||||
STATIC EFI_HANDLE mCurrentImageHandle;
|
||||
STATIC BOOLEAN mDirectImageLoaderEnabled;
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
@ -148,6 +183,409 @@ InternalUpdateLoadedImage (
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
OcDirectLoadImage (
|
||||
IN BOOLEAN BootPolicy,
|
||||
IN EFI_HANDLE ParentImageHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
||||
IN VOID *SourceBuffer OPTIONAL,
|
||||
IN UINTN SourceSize,
|
||||
OUT EFI_HANDLE *ImageHandle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
IMAGE_STATUS ImageStatus;
|
||||
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
|
||||
EFI_PHYSICAL_ADDRESS DestinationArea;
|
||||
VOID *DestinationBuffer;
|
||||
OC_LOADED_IMAGE_PROTOCOL *OcLoadedImage;
|
||||
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
|
||||
|
||||
ASSERT (SourceBuffer != NULL);
|
||||
|
||||
//
|
||||
// Initialize the image context.
|
||||
//
|
||||
ImageStatus = OcPeCoffLoaderInitializeContext (
|
||||
&ImageContext,
|
||||
SourceBuffer,
|
||||
SourceSize
|
||||
);
|
||||
if (ImageStatus != IMAGE_ERROR_SUCCESS) {
|
||||
DEBUG ((DEBUG_INFO, "OCB: PeCoff init failure - %d\n", ImageStatus));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
//
|
||||
// Reject images that are not meant for the platform's architecture.
|
||||
//
|
||||
if (ImageContext.Machine != OC_IMAGE_FILE_MACHINE) {
|
||||
DEBUG ((DEBUG_INFO, "OCB: PeCoff wrong machine - %x\n", ImageContext.Machine));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
//
|
||||
// Reject RT drivers for the moment.
|
||||
//
|
||||
if (ImageContext.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) {
|
||||
DEBUG ((DEBUG_INFO, "OCB: PeCoff no support for RT drivers\n"));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
//
|
||||
// Allocate the image destination memory.
|
||||
// FIXME: RT drivers require EfiRuntimeServicesCode.
|
||||
//
|
||||
Status = gBS->AllocatePages (
|
||||
AllocateAnyPages,
|
||||
ImageContext.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION
|
||||
? EfiLoaderCode : EfiBootServicesCode,
|
||||
EFI_SIZE_TO_PAGES (ImageContext.SizeOfImage),
|
||||
&DestinationArea
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
DestinationBuffer = (VOID *)(UINTN) DestinationArea;
|
||||
|
||||
//
|
||||
// Load SourceBuffer into DestinationBuffer.
|
||||
//
|
||||
ImageStatus = OcPeCoffLoaderLoadImage (
|
||||
&ImageContext,
|
||||
DestinationBuffer,
|
||||
ImageContext.SizeOfImage
|
||||
);
|
||||
if (ImageStatus != IMAGE_ERROR_SUCCESS) {
|
||||
DEBUG ((DEBUG_INFO, "OCB: PeCoff load image error - %d\n", ImageStatus));
|
||||
FreePages (DestinationBuffer, EFI_SIZE_TO_PAGES (ImageContext.SizeOfImage));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
//
|
||||
// Relocate the loaded image to the destination address.
|
||||
//
|
||||
ImageStatus = OcPeCoffLoaderRelocateImage (
|
||||
&ImageContext,
|
||||
(UINTN) DestinationBuffer
|
||||
);
|
||||
if (ImageStatus != IMAGE_ERROR_SUCCESS) {
|
||||
DEBUG ((DEBUG_INFO, "OCB: PeCoff relocate image error - %d\n", ImageStatus));
|
||||
FreePages (DestinationBuffer, EFI_SIZE_TO_PAGES (ImageContext.SizeOfImage));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
//
|
||||
// Construct a LoadedImage protocol for the image.
|
||||
//
|
||||
OcLoadedImage = AllocateZeroPool (sizeof (*OcLoadedImage));
|
||||
if (OcLoadedImage == NULL) {
|
||||
FreePages (DestinationBuffer, EFI_SIZE_TO_PAGES (ImageContext.SizeOfImage));
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
OcLoadedImage->EntryPoint = (EFI_IMAGE_ENTRY_POINT) ((UINTN) DestinationBuffer + ImageContext.AddressOfEntryPoint);
|
||||
OcLoadedImage->ImageArea = DestinationArea;
|
||||
OcLoadedImage->PageCount = EFI_SIZE_TO_PAGES (ImageContext.SizeOfImage);
|
||||
OcLoadedImage->Subsystem = ImageContext.Subsystem;
|
||||
|
||||
LoadedImage = &OcLoadedImage->LoadedImage;
|
||||
|
||||
LoadedImage->Revision = EFI_LOADED_IMAGE_INFORMATION_REVISION;
|
||||
LoadedImage->ParentHandle = ParentImageHandle;
|
||||
LoadedImage->SystemTable = gST;
|
||||
LoadedImage->ImageBase = DestinationBuffer;
|
||||
LoadedImage->ImageSize = ImageContext.SizeOfImage;
|
||||
//
|
||||
// FIXME: Support RT drivers.
|
||||
//
|
||||
if (ImageContext.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {
|
||||
LoadedImage->ImageCodeType = EfiLoaderCode;
|
||||
LoadedImage->ImageDataType = EfiLoaderData;
|
||||
} else {
|
||||
LoadedImage->ImageCodeType = EfiBootServicesCode;
|
||||
LoadedImage->ImageDataType = EfiBootServicesData;
|
||||
}
|
||||
//
|
||||
// Install LoadedImage and the image's entry point.
|
||||
//
|
||||
*ImageHandle = NULL;
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
ImageHandle,
|
||||
&gEfiLoadedImageProtocolGuid,
|
||||
LoadedImage,
|
||||
&mOcLoadedImageProtocolGuid,
|
||||
OcLoadedImage,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCB: PeCoff proto install error - %r\n", Status));
|
||||
FreePool (OcLoadedImage);
|
||||
FreePages (DestinationBuffer, EFI_SIZE_TO_PAGES (ImageContext.SizeOfImage));
|
||||
return Status;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_VERBOSE, "OCB: Loaded image at %p\n", *ImageHandle));
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Unload image routine for OcDirectLoadImage.
|
||||
|
||||
@param[in] OcLoadedImage Our loaded image instance.
|
||||
@param[in] ImageHandle Handle that identifies the image to be unloaded.
|
||||
|
||||
@retval EFI_SUCCESS The image has been unloaded.
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
InternalDirectUnloadImage (
|
||||
IN OC_LOADED_IMAGE_PROTOCOL *OcLoadedImage,
|
||||
IN EFI_HANDLE ImageHandle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
|
||||
|
||||
LoadedImage = &OcLoadedImage->LoadedImage;
|
||||
if (LoadedImage->Unload != NULL) {
|
||||
Status = LoadedImage->Unload (ImageHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
//
|
||||
// Do not allow to execute Unload multiple times.
|
||||
//
|
||||
LoadedImage->Unload = NULL;
|
||||
} else if (OcLoadedImage->Started) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Status = gBS->UninstallMultipleProtocolInterfaces (
|
||||
ImageHandle,
|
||||
&gEfiLoadedImageProtocolGuid,
|
||||
LoadedImage,
|
||||
&mOcLoadedImageProtocolGuid,
|
||||
OcLoadedImage,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
gBS->FreePages (OcLoadedImage->ImageArea, OcLoadedImage->PageCount);
|
||||
FreePool (OcLoadedImage);
|
||||
//
|
||||
// NOTE: Avoid EFI 1.10 extension of closing opened protocols.
|
||||
//
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Unload image routine for OcDirectLoadImage.
|
||||
|
||||
@param[in] OcLoadedImage Our loaded image instance.
|
||||
@param[in] ImageHandle Handle that identifies the image to be unloaded.
|
||||
@param[in] ExitStatus The image's exit code.
|
||||
@param[in] ExitDataSize The size, in bytes, of ExitData. Ignored if ExitStatus is EFI_SUCCESS.
|
||||
@param[in] ExitData The pointer to a data buffer that includes a Null-terminated string,
|
||||
optionally followed by additional binary data. The string is a
|
||||
description that the caller may use to further indicate the reason
|
||||
for the image's exit. ExitData is only valid if ExitStatus
|
||||
is something other than EFI_SUCCESS. The ExitData buffer
|
||||
must be allocated by calling AllocatePool().
|
||||
|
||||
@retval EFI_SUCCESS The image has been unloaded.
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
InternalDirectExit (
|
||||
IN OC_LOADED_IMAGE_PROTOCOL *OcLoadedImage,
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_STATUS ExitStatus,
|
||||
IN UINTN ExitDataSize,
|
||||
IN CHAR16 *ExitData OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
DEBUG ((
|
||||
DEBUG_VERBOSE, "OCB: Exit %p %p (%d) - %r\n",
|
||||
ImageHandle,
|
||||
mCurrentImageHandle,
|
||||
OcLoadedImage->Started,
|
||||
ExitStatus
|
||||
));
|
||||
|
||||
//
|
||||
// Prevent possible reentrance to this function for the same ImageHandle.
|
||||
//
|
||||
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
|
||||
|
||||
//
|
||||
// If the image has not been started just free its resources.
|
||||
// Should not happen normally.
|
||||
//
|
||||
if (!OcLoadedImage->Started) {
|
||||
InternalDirectUnloadImage (OcLoadedImage, ImageHandle);
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// If the image has been started, verify this image can exit.
|
||||
//
|
||||
if (ImageHandle != mCurrentImageHandle) {
|
||||
DEBUG ((DEBUG_LOAD|DEBUG_ERROR, "Exit: Image is not exitable image\n"));
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Set the return status.
|
||||
//
|
||||
OcLoadedImage->Status = ExitStatus;
|
||||
|
||||
//
|
||||
// If there's ExitData info provide it.
|
||||
//
|
||||
if (ExitData != NULL) {
|
||||
OcLoadedImage->ExitDataSize = ExitDataSize;
|
||||
OcLoadedImage->ExitData = AllocatePool (OcLoadedImage->ExitDataSize);
|
||||
if (OcLoadedImage->ExitData != NULL) {
|
||||
CopyMem (OcLoadedImage->ExitData, ExitData, OcLoadedImage->ExitDataSize);
|
||||
} else {
|
||||
OcLoadedImage->ExitDataSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// return to StartImage
|
||||
//
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
LongJump (OcLoadedImage->JumpContext, (UINTN)-1);
|
||||
|
||||
//
|
||||
// If we return from LongJump, then it is an error
|
||||
//
|
||||
ASSERT (FALSE);
|
||||
CpuDeadLoop ();
|
||||
return EFI_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Simplified start image routine for OcDirectLoadImage.
|
||||
|
||||
@param[in] OcLoadedImage Our loaded image instance.
|
||||
@param[in] ImageHandle Handle of image to be started.
|
||||
@param[out] ExitDataSize The pointer to the size, in bytes, of ExitData.
|
||||
@param[out] ExitData The pointer to a pointer to a data buffer that includes a Null-terminated
|
||||
string, optionally followed by additional binary data.
|
||||
|
||||
@retval EFI_SUCCESS on success.
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
InternalDirectStartImage (
|
||||
IN OC_LOADED_IMAGE_PROTOCOL *OcLoadedImage,
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
OUT UINTN *ExitDataSize,
|
||||
OUT CHAR16 **ExitData OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE LastImage;
|
||||
UINTN SetJumpFlag;
|
||||
|
||||
//
|
||||
// Push the current image.
|
||||
//
|
||||
LastImage = mCurrentImageHandle;
|
||||
mCurrentImageHandle = ImageHandle;
|
||||
|
||||
//
|
||||
// Set long jump for Exit() support
|
||||
// JumpContext must be aligned on a CPU specific boundary.
|
||||
// Overallocate the buffer and force the required alignment
|
||||
//
|
||||
OcLoadedImage->JumpBuffer = AllocatePool (
|
||||
sizeof (BASE_LIBRARY_JUMP_BUFFER) + BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT
|
||||
);
|
||||
if (OcLoadedImage->JumpBuffer == NULL) {
|
||||
//
|
||||
// Pop the current start image context
|
||||
//
|
||||
mCurrentImageHandle = LastImage;
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
OcLoadedImage->JumpContext = ALIGN_POINTER (
|
||||
OcLoadedImage->JumpBuffer, BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT
|
||||
);
|
||||
|
||||
SetJumpFlag = SetJump (OcLoadedImage->JumpContext);
|
||||
//
|
||||
// The initial call to SetJump() must always return 0.
|
||||
// Subsequent calls to LongJump() cause a non-zero value to be returned by SetJump().
|
||||
//
|
||||
if (SetJumpFlag == 0) {
|
||||
//
|
||||
// Invoke the manually loaded image entry point.
|
||||
//
|
||||
DEBUG ((DEBUG_VERBOSE, "OCB: Starting image %p\n", ImageHandle));
|
||||
OcLoadedImage->Started = TRUE;
|
||||
OcLoadedImage->Status = OcLoadedImage->EntryPoint (
|
||||
ImageHandle,
|
||||
OcLoadedImage->LoadedImage.SystemTable
|
||||
);
|
||||
//
|
||||
// If the image returns, exit it through Exit()
|
||||
//
|
||||
InternalDirectExit (OcLoadedImage, ImageHandle, OcLoadedImage->Status, 0, NULL);
|
||||
}
|
||||
|
||||
FreePool (OcLoadedImage->JumpBuffer);
|
||||
|
||||
//
|
||||
// Pop the current image.
|
||||
//
|
||||
mCurrentImageHandle = LastImage;
|
||||
|
||||
//
|
||||
// NOTE: EFI 1.10 is not supported, refer to
|
||||
// https://github.com/tianocore/edk2/blob/d8dd54f071cfd60a2dcf5426764a89cd91213420/MdeModulePkg/Core/Dxe/Image/Image.c#L1686-L1697
|
||||
//
|
||||
|
||||
//
|
||||
// Return the exit data to the caller
|
||||
//
|
||||
if (ExitData != NULL && ExitDataSize != NULL) {
|
||||
*ExitDataSize = OcLoadedImage->ExitDataSize;
|
||||
*ExitData = OcLoadedImage->ExitData;
|
||||
} else if (OcLoadedImage->ExitData != NULL) {
|
||||
//
|
||||
// Caller doesn't want the exit data, free it
|
||||
//
|
||||
FreePool (OcLoadedImage->ExitData);
|
||||
OcLoadedImage->ExitData = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Save the Status because Image will get destroyed if it is unloaded.
|
||||
//
|
||||
Status = OcLoadedImage->Status;
|
||||
|
||||
//
|
||||
// If the image returned an error, or if the image is an application
|
||||
// unload it
|
||||
//
|
||||
if (EFI_ERROR (OcLoadedImage->Status)
|
||||
|| OcLoadedImage->Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {
|
||||
InternalDirectUnloadImage (OcLoadedImage, ImageHandle);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
@ -198,7 +636,7 @@ InternalEfiLoadImage (
|
||||
}
|
||||
}
|
||||
|
||||
if (DevicePath != NULL && SourceBuffer != NULL) {
|
||||
if (DevicePath != NULL && SourceBuffer != NULL && mDirectImageLoaderEnabled) {
|
||||
SecureBootStatus = OcAppleSecureBootVerify (
|
||||
DevicePath,
|
||||
SourceBuffer,
|
||||
@ -226,6 +664,17 @@ InternalEfiLoadImage (
|
||||
#else
|
||||
Status = FatFilterArchitecture64 ((UINT8 **) &SourceBuffer, &RealSize);
|
||||
#endif
|
||||
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"OCB: Arch filtering %p(%u)->%p(%u) - %r\n",
|
||||
AllocatedBuffer,
|
||||
(UINT32) SourceSize,
|
||||
SourceBuffer,
|
||||
RealSize,
|
||||
Status
|
||||
));
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
SourceSize = RealSize;
|
||||
} else if (AllocatedBuffer != NULL) {
|
||||
@ -234,21 +683,37 @@ InternalEfiLoadImage (
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Load the image ourselves in secure boot mode.
|
||||
//
|
||||
if (SecureBootStatus == EFI_SUCCESS) {
|
||||
//
|
||||
// TODO: Here we should use a custom COFF loader!
|
||||
//
|
||||
if (SourceBuffer != NULL) {
|
||||
Status = OcDirectLoadImage (
|
||||
FALSE,
|
||||
ParentImageHandle,
|
||||
DevicePath,
|
||||
SourceBuffer,
|
||||
SourceSize,
|
||||
ImageHandle
|
||||
);
|
||||
} else {
|
||||
//
|
||||
// We verified the image, but contained garbage.
|
||||
// This should not happen, just abort.
|
||||
//
|
||||
Status = EFI_UNSUPPORTED;
|
||||
}
|
||||
} else {
|
||||
Status = mOriginalEfiLoadImage (
|
||||
BootPolicy,
|
||||
ParentImageHandle,
|
||||
DevicePath,
|
||||
SourceBuffer,
|
||||
SourceSize,
|
||||
ImageHandle
|
||||
);
|
||||
}
|
||||
|
||||
Status = mOriginalEfiLoadImage (
|
||||
BootPolicy,
|
||||
ParentImageHandle,
|
||||
DevicePath,
|
||||
SourceBuffer,
|
||||
SourceSize,
|
||||
ImageHandle
|
||||
);
|
||||
|
||||
if (AllocatedBuffer != NULL) {
|
||||
FreePool (AllocatedBuffer);
|
||||
}
|
||||
@ -264,15 +729,126 @@ InternalEfiLoadImage (
|
||||
return Status;
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
InternalInitImageLoader (
|
||||
EFIAPI
|
||||
InternalEfiStartImage (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
OUT UINTN *ExitDataSize,
|
||||
OUT CHAR16 **ExitData OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
OC_LOADED_IMAGE_PROTOCOL *OcLoadedImage;
|
||||
|
||||
//
|
||||
// If we loaded the image, invoke the entry point manually.
|
||||
//
|
||||
Status = gBS->HandleProtocol (
|
||||
ImageHandle,
|
||||
&mOcLoadedImageProtocolGuid,
|
||||
(VOID **) &OcLoadedImage
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
return InternalDirectStartImage (
|
||||
OcLoadedImage,
|
||||
ImageHandle,
|
||||
ExitDataSize,
|
||||
ExitData
|
||||
);
|
||||
}
|
||||
|
||||
return mOriginalEfiStartImage (ImageHandle, ExitDataSize, ExitData);
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InternalEfiUnloadImage (
|
||||
IN EFI_HANDLE ImageHandle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
OC_LOADED_IMAGE_PROTOCOL *OcLoadedImage;
|
||||
|
||||
//
|
||||
// If we loaded the image, do the unloading manually.
|
||||
//
|
||||
Status = gBS->HandleProtocol (
|
||||
ImageHandle,
|
||||
&mOcLoadedImageProtocolGuid,
|
||||
(VOID **) &OcLoadedImage
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
return InternalDirectUnloadImage (
|
||||
OcLoadedImage,
|
||||
ImageHandle
|
||||
);
|
||||
}
|
||||
|
||||
return mOriginalEfiUnloadImage (ImageHandle);
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InternalEfiExit (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_STATUS ExitStatus,
|
||||
IN UINTN ExitDataSize,
|
||||
IN CHAR16 *ExitData OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
OC_LOADED_IMAGE_PROTOCOL *OcLoadedImage;
|
||||
|
||||
//
|
||||
// If we loaded the image, do the exit manually.
|
||||
//
|
||||
Status = gBS->HandleProtocol (
|
||||
ImageHandle,
|
||||
&mOcLoadedImageProtocolGuid,
|
||||
(VOID **) &OcLoadedImage
|
||||
);
|
||||
|
||||
DEBUG ((DEBUG_VERBOSE, "OCB: InternalEfiExit %p - %r / %r\n", ImageHandle, ExitStatus, Status));
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
return InternalDirectExit (
|
||||
OcLoadedImage,
|
||||
ImageHandle,
|
||||
ExitStatus,
|
||||
ExitDataSize,
|
||||
ExitData
|
||||
);
|
||||
}
|
||||
|
||||
return mOriginalEfiExit (ImageHandle, ExitStatus, ExitDataSize, ExitData);
|
||||
}
|
||||
|
||||
VOID
|
||||
OcInitDirectImageLoader (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
mOriginalEfiLoadImage = gBS->LoadImage;
|
||||
gBS->LoadImage = InternalEfiLoadImage;
|
||||
mOriginalEfiLoadImage = gBS->LoadImage;
|
||||
mOriginalEfiStartImage = gBS->StartImage;
|
||||
mOriginalEfiUnloadImage = gBS->UnloadImage;
|
||||
mOriginalEfiExit = gBS->Exit;
|
||||
|
||||
gBS->LoadImage = InternalEfiLoadImage;
|
||||
gBS->StartImage = InternalEfiStartImage;
|
||||
gBS->UnloadImage = InternalEfiUnloadImage;
|
||||
gBS->Exit = InternalEfiExit;
|
||||
|
||||
gBS->Hdr.CRC32 = 0;
|
||||
gBS->CalculateCrc32 (gBS, gBS->Hdr.HeaderSize, &gBS->Hdr.CRC32);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
VOID
|
||||
OcActivateDirectImageLoader (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
mDirectImageLoaderEnabled = TRUE;
|
||||
}
|
||||
|
||||
@ -505,10 +505,7 @@ OcRunBootPicker (
|
||||
|
||||
SaidWelcome = FALSE;
|
||||
|
||||
Status = InternalInitImageLoader ();
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
OcActivateDirectImageLoader ();
|
||||
|
||||
//
|
||||
// Reset NVRAM right away if requested by a key combination.
|
||||
|
||||
@ -110,6 +110,7 @@
|
||||
OcGuardLib
|
||||
OcFileLib
|
||||
OcMachoLib
|
||||
OcPeCoffLib
|
||||
OcRtcLib
|
||||
OcXmlLib
|
||||
TimerLib
|
||||
|
||||
36
Library/OcGuardLib/Alignment.c
Normal file
36
Library/OcGuardLib/Alignment.c
Normal file
@ -0,0 +1,36 @@
|
||||
/** @file
|
||||
|
||||
OcGuardLib
|
||||
|
||||
Copyright (c) 2020, Download-Fritz
|
||||
|
||||
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/OcGuardLib.h>
|
||||
|
||||
BOOLEAN
|
||||
OcOverflowAlignUpU32 (
|
||||
UINT32 Value,
|
||||
UINT32 Alignment,
|
||||
UINT32 *Result
|
||||
)
|
||||
{
|
||||
BOOLEAN Status;
|
||||
|
||||
Status = OcOverflowAddU32 (Value, Alignment - 1U, Result);
|
||||
*Result &= ~(Alignment - 1U);
|
||||
|
||||
return Status;
|
||||
}
|
||||
@ -29,6 +29,7 @@
|
||||
#
|
||||
|
||||
[Sources]
|
||||
Alignment.c
|
||||
BitOverflow.c
|
||||
Canary.c
|
||||
NativeOverflow.c
|
||||
|
||||
1178
Library/OcPeCoffLib/OcPeCoffLib.c
Normal file
1178
Library/OcPeCoffLib/OcPeCoffLib.c
Normal file
File diff suppressed because it is too large
Load Diff
36
Library/OcPeCoffLib/OcPeCoffLib.inf
Normal file
36
Library/OcPeCoffLib/OcPeCoffLib.inf
Normal file
@ -0,0 +1,36 @@
|
||||
## @file
|
||||
# PE/COFF Loader Library implementation.
|
||||
#
|
||||
# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = OcPeCoffLib
|
||||
FILE_GUID = 556f5d10-7309-4af4-b80a-8196bd60946e
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = OcPeCoffLib
|
||||
|
||||
[Sources]
|
||||
OcPeCoffLib.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
OpenCorePkg/OpenCorePkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
MemoryAllocationLib
|
||||
OcGuardLib
|
||||
|
||||
[FixedPcd]
|
||||
gOpenCorePkgTokenSpaceGuid.PcdImageLoaderLoadHeader
|
||||
gOpenCorePkgTokenSpaceGuid.PcdImageLoaderHashProhibitOverlap
|
||||
@ -702,6 +702,9 @@
|
||||
## @Prompt Allow these signature hashing algorithms for cryptographic usage.
|
||||
gOpenCorePkgTokenSpaceGuid.PcdOcCryptoAllowedSigHashTypes|0x07|UINT16|0x00000501
|
||||
|
||||
gOpenCorePkgTokenSpaceGuid.PcdImageLoaderLoadHeader|TRUE|BOOLEAN|0x00000600
|
||||
gOpenCorePkgTokenSpaceGuid.PcdImageLoaderHashProhibitOverlap|TRUE|BOOLEAN|0x00000601
|
||||
|
||||
[LibraryClasses]
|
||||
## @libraryclass
|
||||
OcAcpiLib|Include/Acidanthera/Library/OcAcpiLib.h
|
||||
|
||||
@ -108,6 +108,7 @@
|
||||
OcUnicodeCollationEngLocalLib|OpenCorePkg/Library/OcUnicodeCollationEngLib/OcUnicodeCollationEngLocalLib.inf
|
||||
OcVirtualFsLib|OpenCorePkg/Library/OcVirtualFsLib/OcVirtualFsLib.inf
|
||||
OcXmlLib|OpenCorePkg/Library/OcXmlLib/OcXmlLib.inf
|
||||
OcPeCoffLib|OpenCorePkg/Library/OcPeCoffLib/OcPeCoffLib.inf
|
||||
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
|
||||
PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
|
||||
PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
|
||||
@ -225,6 +226,7 @@
|
||||
OpenCorePkg/Library/OcUnicodeCollationEngLib/OcUnicodeCollationEngLocalLib.inf
|
||||
OpenCorePkg/Library/OcVirtualFsLib/OcVirtualFsLib.inf
|
||||
OpenCorePkg/Library/OcXmlLib/OcXmlLib.inf
|
||||
OpenCorePkg/Library/OcPeCoffLib/OcPeCoffLib.inf
|
||||
OpenCorePkg/Platform/CrScreenshotDxe/CrScreenshotDxe.inf
|
||||
OpenCorePkg/Platform/OpenCanopy/OpenCanopy.inf
|
||||
OpenCorePkg/Platform/OpenCore/OpenCore.inf
|
||||
|
||||
@ -516,6 +516,8 @@ OcLoadUefiSupport (
|
||||
|
||||
OcReinstallProtocols (Config);
|
||||
|
||||
OcInitDirectImageLoader ();
|
||||
|
||||
OcLoadAppleSecureBoot (Config);
|
||||
|
||||
OcLoadUefiInputSupport (Config);
|
||||
|
||||
@ -24,6 +24,8 @@ extern UINT32 _gPcd_FixedAtBuild_PcdMaximumLinkedListLength;
|
||||
extern BOOLEAN _gPcd_FixedAtBuild_PcdVerifyNodeInList;
|
||||
extern UINT32 _gPcd_FixedAtBuild_PcdCpuNumberOfReservedVariableMtrrs;
|
||||
extern UINT32 _gPcd_FixedAtBuild_PcdMaximumDevicePathNodeCount;
|
||||
extern BOOLEAN _gPcd_FixedAtBuild_PcdImageLoaderHashProhibitOverlap;
|
||||
extern BOOLEAN _gPcd_FixedAtBuild_PcdImageLoaderLoadHeader;
|
||||
|
||||
#define _PCD_GET_MODE_32_PcdUefiLibMaxPrintBufferSize _gPcd_FixedAtBuild_PcdUefiLibMaxPrintBufferSize
|
||||
#define _PCD_GET_MODE_BOOL_PcdUgaConsumeSupport _gPcd_FixedAtBuild_PcdUgaConsumeSupport
|
||||
@ -42,5 +44,7 @@ extern UINT32 _gPcd_FixedAtBuild_PcdMaximumDevicePathNodeCount;
|
||||
// this will not be of any effect at userspace
|
||||
#define _PCD_GET_MODE_64_PcdPciExpressBaseAddress 0
|
||||
#define _PCD_GET_MODE_32_PcdMaximumDevicePathNodeCount _gPcd_FixedAtBuild_PcdMaximumDevicePathNodeCount
|
||||
#define _PCD_GET_MODE_BOOL_PcdImageLoaderHashProhibitOverlap _gPcd_FixedAtBuild_PcdImageLoaderHashProhibitOverlap
|
||||
#define _PCD_GET_MODE_BOOL_PcdImageLoaderLoadHeader _gPcd_FixedAtBuild_PcdImageLoaderLoadHeader
|
||||
|
||||
#endif // OC_USER_PCD_H
|
||||
|
||||
@ -17,6 +17,8 @@
|
||||
#define _PCD_VALUE_PcdVerifyNodeInList ((BOOLEAN)0U)
|
||||
#define _PCD_VALUE_PcdCpuNumberOfReservedVariableMtrrs 0x2U
|
||||
#define _PCD_VALUE_PcdMaximumDevicePathNodeCount 0U
|
||||
#define _PCD_VALUE_PcdImageLoaderHashProhibitOverlap 1U
|
||||
#define _PCD_VALUE_PcdImageLoaderLoadHeader 0U
|
||||
|
||||
UINT32 _gPcd_FixedAtBuild_PcdUefiLibMaxPrintBufferSize = _PCD_VALUE_PcdUefiLibMaxPrintBufferSize;
|
||||
BOOLEAN _gPcd_FixedAtBuild_PcdUgaConsumeSupport = _PCD_VALUE_PcdUgaConsumeSupport;
|
||||
@ -30,3 +32,5 @@ UINT32 _gPcd_FixedAtBuild_PcdMaximumLinkedListLength = _PCD_VALUE_PcdMaximumLink
|
||||
BOOLEAN _gPcd_FixedAtBuild_PcdVerifyNodeInList = _PCD_VALUE_PcdVerifyNodeInList;
|
||||
UINT32 _gPcd_FixedAtBuild_PcdCpuNumberOfReservedVariableMtrrs = _PCD_VALUE_PcdCpuNumberOfReservedVariableMtrrs;
|
||||
UINT32 _gPcd_FixedAtBuild_PcdMaximumDevicePathNodeCount = _PCD_VALUE_PcdMaximumDevicePathNodeCount;
|
||||
BOOLEAN _gPcd_FixedAtBuild_PcdImageLoaderHashProhibitOverlap = _PCD_VALUE_PcdImageLoaderHashProhibitOverlap;
|
||||
BOOLEAN _gPcd_FixedAtBuild_PcdImageLoaderLoadHeader = _PCD_VALUE_PcdImageLoaderLoadHeader;
|
||||
|
||||
@ -112,7 +112,7 @@ ifneq ($(STANDALONE),1)
|
||||
#
|
||||
# OcGuardLib targets.
|
||||
#
|
||||
OBJS += BitOverflow.o NativeOverflow.o TripleOverflow.o
|
||||
OBJS += BitOverflow.o NativeOverflow.o TripleOverflow.o Alignment.o
|
||||
#
|
||||
# OcSerializeLib targets.
|
||||
#
|
||||
|
||||
11
Utilities/TestPeCoff/Makefile
Normal file
11
Utilities/TestPeCoff/Makefile
Normal file
@ -0,0 +1,11 @@
|
||||
## @file
|
||||
# Copyright (c) 2020, vit9696. All rights reserved.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
##
|
||||
|
||||
PROJECT = PeCoff
|
||||
PRODUCT = $(PROJECT)$(SUFFIX)
|
||||
OBJS = $(PROJECT).o \
|
||||
OcPeCoffLib.o
|
||||
VPATH = ../../Library/OcPeCoffLib
|
||||
include ../../User/Makefile
|
||||
149
Utilities/TestPeCoff/PeCoff.c
Normal file
149
Utilities/TestPeCoff/PeCoff.c
Normal file
@ -0,0 +1,149 @@
|
||||
/** @file
|
||||
Copyright (c) 2018, vit9696. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
**/
|
||||
|
||||
#include "../Include/Uefi.h"
|
||||
|
||||
#include <Library/OcPeCoffLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <File.h>
|
||||
|
||||
/**
|
||||
|
||||
clang -g -fsanitize=undefined,address -Wno-incompatible-pointer-types-discards-qualifiers -fshort-wchar -I../Include -I../../Include -I../../../MdePkg/Include/ -I../../../EfiPkg/Include/ -include ../Include/Base.h DiskImage.c ../../Library/OcXmlLib/OcXmlLib.c ../../Library/OcTemplateLib/OcTemplateLib.c ../../Library/OcSerializeLib/OcSerializeLib.c ../../Library/OcMiscLib/Base64Decode.c ../../Library/OcStringLib/OcAsciiLib.c ../../Library/OcAppleDiskImageLib/OcAppleDiskImageLib.c ../../Library/OcAppleDiskImageLib/OcAppleDiskImageLibInternal.c ../../Library/OcMiscLib/DataPatcher.c ../../Library/OcCompressionLib/zlib/zlib_uefi.c ../../Library/OcCompressionLib/zlib/adler32.c ../../Library/OcCompressionLib/zlib/deflate.c ../../Library/OcCompressionLib/zlib/crc32.c ../../Library/OcCompressionLib/zlib/compress.c ../../Library/OcCompressionLib/zlib/infback.c ../../Library/OcCompressionLib/zlib/inffast.c ../../Library/OcCompressionLib/zlib/inflate.c ../../Library/OcCompressionLib/zlib/inftrees.c ../../Library/OcCompressionLib/zlib/trees.c ../../Library/OcCompressionLib/zlib/uncompr.c ../../Library/OcCryptoLib/Sha256.c ../../Library/OcCryptoLib/Rsa2048Sha256.c ../../Library/OcAppleKeysLib/OcAppleKeysLib.c ../../Library/OcAppleChunklistLib/OcAppleChunklistLib.c ../../Library/OcAppleRamDiskLib/OcAppleRamDiskLib.c ../../Library/OcFileLib/ReadFile.c ../../Library/OcFileLib/FileProtocol.c -o DiskImage
|
||||
|
||||
clang-mp-7.0 -DFUZZING_TEST=1 -g -fsanitize=undefined,address,fuzzer -Wno-incompatible-pointer-types-discards-qualifiers -fshort-wchar -I../Include -I../../Include -I../../../MdePkg/Include/ -I../../../EfiPkg/Include/ -include ../Include/Base.h DiskImage.c ../../Library/OcXmlLib/OcXmlLib.c ../../Library/OcTemplateLib/OcTemplateLib.c ../../Library/OcSerializeLib/OcSerializeLib.c ../../Library/OcMiscLib/Base64Decode.c ../../Library/OcStringLib/OcAsciiLib.c ../../Library/OcAppleDiskImageLib/OcAppleDiskImageLib.c ../../Library/OcAppleDiskImageLib/OcAppleDiskImageLibInternal.c ../../Library/OcMiscLib/DataPatcher.c ../../Library/OcCompressionLib/zlib/zlib_uefi.c ../../Library/OcCompressionLib/zlib/adler32.c ../../Library/OcCompressionLib/zlib/deflate.c ../../Library/OcCompressionLib/zlib/crc32.c ../../Library/OcCompressionLib/zlib/compress.c ../../Library/OcCompressionLib/zlib/infback.c ../../Library/OcCompressionLib/zlib/inffast.c ../../Library/OcCompressionLib/zlib/inflate.c ../../Library/OcCompressionLib/zlib/inftrees.c ../../Library/OcCompressionLib/zlib/trees.c ../../Library/OcCompressionLib/zlib/uncompr.c ../../Library/OcCryptoLib/Sha256.c ../../Library/OcCryptoLib/Rsa2048Sha256.c ../../Library/OcAppleKeysLib/OcAppleKeysLib.c ../../Library/OcAppleChunklistLib/OcAppleChunklistLib.c ../../Library/OcAppleRamDiskLib/OcAppleRamDiskLib.c../../Library/OcFileLib/ReadFile.c ../../Library/OcFileLib/FileProtocol.c -o DiskImage
|
||||
rm -rf DICT fuzz*.log ; mkdir DICT ; UBSAN_OPTIONS='halt_on_error=1' ./DiskImage -jobs=4 DICT -rss_limit_mb=4096
|
||||
|
||||
**/
|
||||
|
||||
#ifdef FUZZING_TEST
|
||||
#define main no_main
|
||||
#include <sanitizer/asan_interface.h>
|
||||
#else
|
||||
#define ASAN_POISON_MEMORY_REGION(addr, size)
|
||||
#define ASAN_UNPOISON_MEMORY_REGION(addr, size)
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#include <CommonCrypto/CommonDigest.h>
|
||||
#endif
|
||||
|
||||
EFI_STATUS
|
||||
TestImageLoad (
|
||||
IN VOID *SourceBuffer,
|
||||
IN UINTN SourceSize
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
IMAGE_STATUS ImageStatus;
|
||||
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
|
||||
EFI_PHYSICAL_ADDRESS DestinationArea;
|
||||
VOID *DestinationBuffer;
|
||||
|
||||
|
||||
//
|
||||
// Initialize the image context.
|
||||
//
|
||||
ImageStatus = OcPeCoffLoaderInitializeContext (
|
||||
&ImageContext,
|
||||
SourceBuffer,
|
||||
SourceSize
|
||||
);
|
||||
if (ImageStatus != IMAGE_ERROR_SUCCESS) {
|
||||
DEBUG ((DEBUG_INFO, "OCB: PeCoff init failure - %d\n", ImageStatus));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
//
|
||||
// Reject images that are not meant for the platform's architecture.
|
||||
//
|
||||
if (ImageContext.Machine != IMAGE_FILE_MACHINE_X64) {
|
||||
DEBUG ((DEBUG_INFO, "OCB: PeCoff wrong machine - %x\n", ImageContext.Machine));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
//
|
||||
// Reject RT drivers for the moment.
|
||||
//
|
||||
if (ImageContext.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) {
|
||||
DEBUG ((DEBUG_INFO, "OCB: PeCoff no support for RT drivers\n"));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
//
|
||||
// Allocate the image destination memory.
|
||||
// FIXME: RT drivers require EfiRuntimeServicesCode.
|
||||
//
|
||||
Status = gBS->AllocatePages (
|
||||
AllocateAnyPages,
|
||||
EfiBootServicesCode,
|
||||
EFI_SIZE_TO_PAGES (ImageContext.SizeOfImage),
|
||||
&DestinationArea
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
DestinationBuffer = (VOID *)(UINTN) DestinationArea;
|
||||
|
||||
//
|
||||
// Load SourceBuffer into DestinationBuffer.
|
||||
//
|
||||
ImageStatus = OcPeCoffLoaderLoadImage (
|
||||
&ImageContext,
|
||||
DestinationBuffer,
|
||||
ImageContext.SizeOfImage
|
||||
);
|
||||
if (ImageStatus != IMAGE_ERROR_SUCCESS) {
|
||||
DEBUG ((DEBUG_INFO, "OCB: PeCoff load image error - %d\n", ImageStatus));
|
||||
FreePages (DestinationBuffer, EFI_SIZE_TO_PAGES (ImageContext.SizeOfImage));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
//
|
||||
// Relocate the loaded image to the destination address.
|
||||
//
|
||||
ImageStatus = OcPeCoffLoaderRelocateImage (
|
||||
&ImageContext,
|
||||
(UINTN) DestinationBuffer
|
||||
);
|
||||
|
||||
FreePages (DestinationBuffer, EFI_SIZE_TO_PAGES (ImageContext.SizeOfImage));
|
||||
|
||||
if (ImageStatus != IMAGE_ERROR_SUCCESS) {
|
||||
DEBUG ((DEBUG_INFO, "OCB: PeCoff relocate image error - %d\n", ImageStatus));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[]) {
|
||||
if (argc < 2) {
|
||||
printf ("Please provide a valid PE image path\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
PcdGet32 (PcdFixedDebugPrintErrorLevel) |= DEBUG_INFO;
|
||||
PcdGet32 (PcdDebugPrintErrorLevel) |= DEBUG_INFO;
|
||||
|
||||
uint8_t *Image;
|
||||
uint32_t ImageSize;
|
||||
|
||||
if ((Image = readFile (argv[1], &ImageSize)) == NULL) {
|
||||
printf ("Read fail\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
EFI_STATUS Status = TestImageLoad (Image, ImageSize);
|
||||
free(Image);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -14,6 +14,7 @@ buildutil() {
|
||||
"TestImg4"
|
||||
"TestKextInject"
|
||||
"TestMacho"
|
||||
"TestPeCoff"
|
||||
"TestRsaPreprocess"
|
||||
"TestSmbios"
|
||||
)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user