Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
btwise
OpenCorePKG_MOD
提交
7e965893
O
OpenCorePKG_MOD
项目概览
btwise
/
OpenCorePKG_MOD
通知
26
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
OpenCorePKG_MOD
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
7e965893
编写于
8月 08, 2020
作者:
V
vit9696
提交者:
GitHub
8月 08, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
OcAppleKernelLib: Implement 64-bit cacheless kext injection (#96)
references acidanthera/bugtracker#358
上级
6f4f7623
变更
8
展开全部
隐藏空白更改
内联
并排
Showing
8 changed file
with
1702 addition
and
7 deletion
+1702
-7
Include/Acidanthera/Library/OcAppleKernelLib.h
Include/Acidanthera/Library/OcAppleKernelLib.h
+131
-0
Include/Acidanthera/Library/OcStringLib.h
Include/Acidanthera/Library/OcStringLib.h
+30
-0
Library/OcAppleKernelLib/CachelessContext.c
Library/OcAppleKernelLib/CachelessContext.c
+1157
-0
Library/OcAppleKernelLib/CachelessInternal.h
Library/OcAppleKernelLib/CachelessInternal.h
+187
-0
Library/OcAppleKernelLib/OcAppleKernelLib.inf
Library/OcAppleKernelLib/OcAppleKernelLib.inf
+1
-0
Library/OcStringLib/OcAsciiLib.c
Library/OcStringLib/OcAsciiLib.c
+20
-0
Library/OcStringLib/OcUnicodeLib.c
Library/OcStringLib/OcUnicodeLib.c
+20
-0
Platform/OpenCore/OpenCoreKernel.c
Platform/OpenCore/OpenCoreKernel.c
+156
-7
未找到文件。
Include/Acidanthera/Library/OcAppleKernelLib.h
浏览文件 @
7e965893
...
...
@@ -42,6 +42,10 @@
#define INFO_BUNDLE_LIBRARIES_64_KEY "OSBundleLibraries_x86_64"
#define INFO_BUNDLE_VERSION_KEY "CFBundleVersion"
#define INFO_BUNDLE_COMPATIBLE_VERSION_KEY "OSBundleCompatibleVersion"
#define INFO_BUNDLE_OS_BUNDLE_REQUIRED_KEY "OSBundleRequired"
#define OS_BUNDLE_REQUIRED_ROOT "Root"
#define OS_BUNDLE_REQUIRED_SAFE_BOOT "Safe Boot"
#define PRELINK_INFO_INTEGER_ATTRIBUTES "size=\"64\""
...
...
@@ -251,6 +255,36 @@ typedef struct {
UINT32
Limit
;
}
PATCHER_GENERIC_PATCH
;
//
// Context for cacheless boot (S/L/E).
//
typedef
struct
{
//
// Extensions directory EFI_FILE_PROTOCOL instance.
//
EFI_FILE_PROTOCOL
*
ExtensionsDir
;
//
// Extensions directory filename. This is freed by the caller.
//
CONST
CHAR16
*
ExtensionsDirFileName
;
//
// Injected kext list.
//
LIST_ENTRY
InjectedKexts
;
//
// Dependency bundle list for injected kexts.
//
LIST_ENTRY
InjectedDependencies
;
//
// List of built-in shipping kexts.
//
LIST_ENTRY
BuiltInKexts
;
//
// Flag to indicate if above list is valid. List is built during the first read from SLE.
//
BOOLEAN
BuiltInKextsValid
;
}
CACHELESS_CONTEXT
;
/**
Read Apple kernel for target architecture (possibly decompressing)
into pool allocated buffer.
...
...
@@ -741,4 +775,101 @@ PatchAppleRtcChecksum (
IN
OUT
PRELINKED_CONTEXT
*
Context
);
/**
Initializes cacheless context for later modification.
Must be freed with CachelessContextFree on success.
@param[in,out] Context Cacheless context.
@param[in] FileName Extensions directory filename.
@param[in] ExtensionsDir Extensions directory EFI_FILE_PROTOCOL.
@return EFI_SUCCESS on success.
**/
EFI_STATUS
CachelessContextInit
(
IN
OUT
CACHELESS_CONTEXT
*
Context
,
IN
CONST
CHAR16
*
FileName
,
IN
EFI_FILE_PROTOCOL
*
ExtensionsDir
);
/**
Frees cacheless context.
@param[in,out] Context Cacheless context.
@return EFI_SUCCESS on success.
**/
VOID
CachelessContextFree
(
IN
OUT
CACHELESS_CONTEXT
*
Context
);
/**
Add kext to cacheless context to be injected later on.
@param[in,out] Context Cacheless context.
@param[in] InfoPlist Kext Info.plist.
@param[in] InfoPlistSize Kext Info.plist size.
@param[in] Executable Kext executable, optional.
@param[in] ExecutableSize Kext executable size, optional.
@return EFI_SUCCESS on success.
**/
EFI_STATUS
CachelessContextAddKext
(
IN
OUT
CACHELESS_CONTEXT
*
Context
,
IN
CONST
CHAR8
*
InfoPlist
,
IN
UINT32
InfoPlistSize
,
IN
CONST
UINT8
*
Executable
OPTIONAL
,
IN
UINT32
ExecutableSize
OPTIONAL
);
/**
Creates virtual directory overlay EFI_FILE_PROTOCOL from cacheless context.
@param[in,out] Context Cacheless context.
@param[out] File The virtual directory instance.
@return EFI_SUCCESS on success.
**/
EFI_STATUS
CachelessContextOverlayExtensionsDir
(
IN
OUT
CACHELESS_CONTEXT
*
Context
,
OUT
EFI_FILE_PROTOCOL
**
File
);
/**
Perform kext injection.
@param[in,out] Context Prelinked context.
@param[in] FileName Filename of kext file to be injected.
@param[out] VirtualFile Newly created virtualised EFI_FILE_PROTOCOL instance.
@return EFI_SUCCESS on success.
**/
EFI_STATUS
CachelessContextPerformInject
(
IN
OUT
CACHELESS_CONTEXT
*
Context
,
IN
CONST
CHAR16
*
FileName
,
OUT
EFI_FILE_PROTOCOL
**
VirtualFile
);
/**
Apply patches to built-in kexts.
@param[in,out] Context Prelinked context.
@param[in] FileName Filename of kext file to be injected.
@param[in] File EFI_FILE_PROTOCOL instance of kext file.
@param[out] VirtualFile Newly created virtualised EFI_FILE_PROTOCOL instance.
@return EFI_SUCCESS on success. If no patches are applicable, VirtualFile will be NULL.
**/
EFI_STATUS
CachelessContextHookBuiltin
(
IN
OUT
CACHELESS_CONTEXT
*
Context
,
IN
CONST
CHAR16
*
FileName
,
IN
EFI_FILE_PROTOCOL
*
File
,
OUT
EFI_FILE_PROTOCOL
**
VirtualFile
);
#endif // OC_APPLE_KERNEL_LIB_H
Include/Acidanthera/Library/OcStringLib.h
浏览文件 @
7e965893
...
...
@@ -114,6 +114,21 @@ OcAsciiSafeSPrint (
...
);
/** Check if ASCII string ends with another ASCII string.
@param[in] String A pointer to a Null-terminated ASCII string.
@param[in] SearchString A pointer to a Null-terminated ASCII string
to compare against String.
@retval TRUE if String ends with SearchString.
**/
BOOLEAN
EFIAPI
OcAsciiEndsWith
(
IN
CONST
CHAR8
*
String
,
IN
CONST
CHAR8
*
SearchString
);
/**
Performs a case insensitive comparison of two Null-terminated Unicode strings,
and returns the difference between the first mismatched Unicode characters.
...
...
@@ -269,6 +284,21 @@ OcUnicodeSafeSPrint (
...
);
/** Check if Unicode string ends with another Unicode string.
@param[in] String A pointer to a Null-terminated Unicode string.
@param[in] SearchString A pointer to a Null-terminated Unicode string
to compare against String.
@retval TRUE if String ends with SearchString.
**/
BOOLEAN
EFIAPI
OcUnicodeEndsWith
(
IN
CONST
CHAR16
*
String
,
IN
CONST
CHAR16
*
SearchString
);
/**
Convert path with mixed slashes to UEFI slashes (\\).
...
...
Library/OcAppleKernelLib/CachelessContext.c
0 → 100644
浏览文件 @
7e965893
此差异已折叠。
点击以展开。
Library/OcAppleKernelLib/CachelessInternal.h
0 → 100644
浏览文件 @
7e965893
/** @file
Cacheless boot (S/L/E) support.
Copyright (c) 2020, Goldfish64. 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 CACHELESS_INTERNAL_H
#define CACHELESS_INTERNAL_H
#include <Library/OcAppleKernelLib.h>
//
// Names are of format OcXXXXXXXX.kext, where XXXXXXXX is a 32-bit hexadecimal number.
//
#define KEXT_BUNDLE_NAME L"OcXXXXXXXX.kext"
#define KEXT_BUNDLE_NAME_SIZE (L_STR_SIZE (KEXT_BUNDLE_NAME))
#define KEXT_BUNDLE_NAME_LEN (L_STR_LEN (KEXT_BUNDLE_NAME))
#define KEXT_BUNDLE_INFO_SIZE (SIZE_OF_EFI_FILE_INFO + KEXT_BUNDLE_NAME_SIZE)
enum
{
KEXT_OSBUNDLE_REQUIRED_NONE
=
0
,
KEXT_OSBUNDLE_REQUIRED_INVALID
,
KEXT_OSBUNDLE_REQUIRED_VALID
};
//
// Kext dependency.
//
typedef
struct
{
//
// Signature.
//
UINT32
Signature
;
//
// Link for global list.
//
LIST_ENTRY
Link
;
//
// Bundle ID.
//
CHAR8
*
BundleId
;
}
DEPEND_KEXT
;
//
// Cacheless kext.
//
typedef
struct
{
//
// Signature.
//
UINT32
Signature
;
//
// Link for global list (CACHELESS_CONTEXT -> InjectedKexts).
//
LIST_ENTRY
Link
;
//
// Bundle filename used during S/L/E overlay creation.
//
CHAR16
BundleFileName
[
KEXT_BUNDLE_NAME_LEN
+
1
];
//
// Plist data.
//
CHAR8
*
PlistData
;
//
// Plist data size.
//
UINT32
PlistDataSize
;
//
// Binary data.
//
UINT8
*
BinaryData
;
//
// Binary data size.
//
UINT32
BinaryDataSize
;
//
// Binary file name.
//
CHAR16
*
BinaryFileName
;
}
CACHELESS_KEXT
;
//
// Built-in kexts in SLE.
//
typedef
struct
{
//
// Signature.
//
UINT32
Signature
;
//
// Link for global list (CACHELESS_CONTEXT -> BuiltInKexts).
//
LIST_ENTRY
Link
;
//
// Plist path.
//
CHAR16
*
PlistPath
;
//
// Bundle ID.
//
CHAR8
*
BundleId
;
//
// Binary file name.
//
CHAR16
*
BinaryFileName
;
//
// Dependencies.
//
LIST_ENTRY
Dependencies
;
//
// OSBundleRequired is valid?
//
UINT8
OSBundleRequiredValue
;
//
// Needs OSBundleRequired override for dependency injection?
//
BOOLEAN
PatchValidOSBundleRequired
;
//
// Needs patches or blocks?
//
BOOLEAN
PatchKext
;
}
BUILTIN_KEXT
;
//
// DEPEND_KEXT signature for list identification.
//
#define DEPEND_KEXT_SIGNATURE SIGNATURE_32 ('S', 'l', 'e', 'D')
/**
Gets the next element in list of DEPEND_KEXT.
@param[in] This The current ListEntry.
**/
#define GET_DEPEND_KEXT_FROM_LINK(This) \
(CR ( \
(This), \
DEPEND_KEXT, \
Link, \
DEPEND_KEXT_SIGNATURE \
))
//
// CACHELESS_KEXT signature for list identification.
//
#define CACHELESS_KEXT_SIGNATURE SIGNATURE_32 ('S', 'l', 'e', 'X')
/**
Gets the next element in InjectedKexts list of CACHELESS_KEXT.
@param[in] This The current ListEntry.
**/
#define GET_CACHELESS_KEXT_FROM_LINK(This) \
(CR ( \
(This), \
CACHELESS_KEXT, \
Link, \
CACHELESS_KEXT_SIGNATURE \
))
//
// BUILTIN_KEXT signature for list identification.
//
#define BUILTIN_KEXT_SIGNATURE SIGNATURE_32 ('S', 'l', 'e', 'B')
/**
Gets the next element in BuiltInKexts list of CACHELESS_KEXT.
@param[in] This The current ListEntry.
**/
#define GET_BUILTIN_KEXT_FROM_LINK(This) \
(CR ( \
(This), \
BUILTIN_KEXT, \
Link, \
BUILTIN_KEXT_SIGNATURE \
))
#endif
Library/OcAppleKernelLib/OcAppleKernelLib.inf
浏览文件 @
7e965893
...
...
@@ -38,6 +38,7 @@
PrelinkedInternal.h
PrelinkedKext.c
Vtables.c
CachelessContext.c
[Packages]
MdePkg/MdePkg.dec
...
...
Library/OcStringLib/OcAsciiLib.c
浏览文件 @
7e965893
...
...
@@ -166,3 +166,23 @@ OcAsciiSafeSPrint (
return
Status
;
}
BOOLEAN
EFIAPI
OcAsciiEndsWith
(
IN
CONST
CHAR8
*
String
,
IN
CONST
CHAR8
*
SearchString
)
{
UINTN
StringLength
;
UINTN
SearchStringLength
;
ASSERT
(
String
!=
NULL
);
ASSERT
(
SearchString
!=
NULL
);
StringLength
=
AsciiStrLen
(
String
);
SearchStringLength
=
AsciiStrLen
(
SearchString
);
return
StringLength
>=
SearchStringLength
&&
AsciiStrnCmp
(
&
String
[
StringLength
-
SearchStringLength
],
SearchString
,
SearchStringLength
)
==
0
;
}
Library/OcStringLib/OcUnicodeLib.c
浏览文件 @
7e965893
...
...
@@ -271,3 +271,23 @@ OcUnicodeSafeSPrint (
return
Status
;
}
BOOLEAN
EFIAPI
OcUnicodeEndsWith
(
IN
CONST
CHAR16
*
String
,
IN
CONST
CHAR16
*
SearchString
)
{
UINTN
StringLength
;
UINTN
SearchStringLength
;
ASSERT
(
String
!=
NULL
);
ASSERT
(
SearchString
!=
NULL
);
StringLength
=
StrLen
(
String
);
SearchStringLength
=
StrLen
(
SearchString
);
return
StringLength
>=
SearchStringLength
&&
StrnCmp
(
&
String
[
StringLength
-
SearchStringLength
],
SearchString
,
SearchStringLength
)
==
0
;
}
Platform/OpenCore/OpenCoreKernel.c
浏览文件 @
7e965893
...
...
@@ -29,6 +29,11 @@ STATIC OC_STORAGE_CONTEXT *mOcStorage;
STATIC
OC_GLOBAL_CONFIG
*
mOcConfiguration
;
STATIC
OC_CPU_INFO
*
mOcCpuInfo
;
STATIC
UINT32
mOcDarwinVersion
;
STATIC
CACHELESS_CONTEXT
mOcCachelessContext
;
STATIC
BOOLEAN
mOcCachelessInProgress
;
STATIC
UINT32
OcParseDarwinVersion
(
...
...
@@ -720,6 +725,76 @@ OcKernelProcessPrelinked (
return
Status
;
}
STATIC
EFI_STATUS
OcKernelInitCacheless
(
IN
OC_GLOBAL_CONFIG
*
Config
,
IN
CACHELESS_CONTEXT
*
Context
,
IN
UINT32
DarwinVersion
,
IN
CHAR16
*
FileName
,
IN
EFI_FILE_PROTOCOL
*
ExtensionsDir
,
OUT
EFI_FILE_PROTOCOL
**
File
)
{
EFI_STATUS
Status
;
UINT32
Index
;
OC_KERNEL_ADD_ENTRY
*
Kext
;
CHAR8
*
BundlePath
;
CHAR8
*
Comment
;
UINT32
MaxKernel
;
UINT32
MinKernel
;
Status
=
CachelessContextInit
(
Context
,
FileName
,
ExtensionsDir
);
if
(
EFI_ERROR
(
Status
))
{
return
Status
;
}
//
// Add kexts into cacheless context.
//
for
(
Index
=
0
;
Index
<
Config
->
Kernel
.
Add
.
Count
;
Index
++
)
{
Kext
=
Config
->
Kernel
.
Add
.
Values
[
Index
];
if
(
!
Kext
->
Enabled
||
Kext
->
PlistDataSize
==
0
)
{
continue
;
}
BundlePath
=
OC_BLOB_GET
(
&
Kext
->
BundlePath
);
Comment
=
OC_BLOB_GET
(
&
Kext
->
Comment
);
MaxKernel
=
OcParseDarwinVersion
(
OC_BLOB_GET
(
&
Kext
->
MaxKernel
));
MinKernel
=
OcParseDarwinVersion
(
OC_BLOB_GET
(
&
Kext
->
MinKernel
));
if
(
!
OcMatchDarwinVersion
(
DarwinVersion
,
MinKernel
,
MaxKernel
))
{
DEBUG
((
DEBUG_INFO
,
"OC: Cacheless injection skips %a (%a) kext at %u due to version %u <= %u <= %u
\n
"
,
BundlePath
,
Comment
,
Index
,
MinKernel
,
DarwinVersion
,
MaxKernel
));
continue
;
}
Status
=
CachelessContextAddKext
(
Context
,
Kext
->
PlistData
,
Kext
->
PlistDataSize
,
Kext
->
ImageData
,
Kext
->
ImageDataSize
);
if
(
EFI_ERROR
(
Status
))
{
CachelessContextFree
(
Context
);
return
Status
;
}
}
return
CachelessContextOverlayExtensionsDir
(
Context
,
File
);
}
STATIC
EFI_STATUS
EFIAPI
...
...
@@ -740,12 +815,29 @@ OcKernelFileOpen (
EFI_FILE_PROTOCOL
*
VirtualFileHandle
;
EFI_STATUS
PrelinkedStatus
;
EFI_TIME
ModificationTime
;
UINT32
DarwinVersion
;
UINT32
ReservedInfoSize
;
UINT32
ReservedExeSize
;
UINT32
LinkedExpansion
;
UINT32
ReservedFullSize
;
//
// Hook injected OcXXXXXXXX.kext reads from /S/L/E.
//
if
(
mOcCachelessInProgress
&&
OpenMode
==
EFI_FILE_MODE_READ
&&
StrnCmp
(
FileName
,
L"System
\\
Library
\\
Extensions
\\
Oc"
,
L_STR_LEN
(
L"System
\\
Library
\\
Extensions
\\
Oc"
))
==
0
)
{
Status
=
CachelessContextPerformInject
(
&
mOcCachelessContext
,
FileName
,
NewHandle
);
DEBUG
((
DEBUG_INFO
,
"OC: Hooking SLE injected file %s with %u mode gave - %r
\n
"
,
FileName
,
(
UINT32
)
OpenMode
,
Status
));
return
Status
;
}
Status
=
SafeFileOpen
(
This
,
NewHandle
,
FileName
,
OpenMode
,
Attributes
);
DEBUG
((
...
...
@@ -802,12 +894,12 @@ OcKernelFileOpen (
DEBUG
((
DEBUG_INFO
,
"OC: Result of XNU hook on %s is %r
\n
"
,
FileName
,
Status
));
if
(
!
EFI_ERROR
(
Status
))
{
DarwinVersion
=
OcKernelReadDarwinVersion
(
Kernel
,
KernelSize
);
OcKernelApplyPatches
(
mOcConfiguration
,
DarwinVersion
,
NULL
,
Kernel
,
KernelSize
);
mOc
DarwinVersion
=
OcKernelReadDarwinVersion
(
Kernel
,
KernelSize
);
OcKernelApplyPatches
(
mOcConfiguration
,
mOc
DarwinVersion
,
NULL
,
Kernel
,
KernelSize
);
PrelinkedStatus
=
OcKernelProcessPrelinked
(
mOcConfiguration
,
DarwinVersion
,
mOc
DarwinVersion
,
Kernel
,
&
KernelSize
,
AllocatedSize
,
...
...
@@ -850,6 +942,61 @@ OcKernelFileOpen (
}
}
//
// Hook /S/L/E for cacheless boots.
//
if
(
OpenMode
==
EFI_FILE_MODE_READ
&&
StrCmp
(
FileName
,
L"System
\\
Library
\\
Extensions"
)
==
0
)
{
mOcCachelessInProgress
=
FALSE
;
OcKernelLoadKextsAndReserve
(
mOcStorage
,
mOcConfiguration
,
&
ReservedExeSize
,
&
ReservedInfoSize
);
//
// Initialize Extensions directory overlay for cacheless injection.
//
Status
=
OcKernelInitCacheless
(
mOcConfiguration
,
&
mOcCachelessContext
,
mOcDarwinVersion
,
FileName
,
*
NewHandle
,
&
VirtualFileHandle
);
DEBUG
((
DEBUG_INFO
,
"OC: Result of SLE hook on %s is %r
\n
"
,
FileName
,
Status
));
if
(
!
EFI_ERROR
(
Status
))
{
mOcCachelessInProgress
=
TRUE
;
*
NewHandle
=
VirtualFileHandle
;
return
EFI_SUCCESS
;
}
}
//
// Hook /S/L/E contents for processing during cacheless boots.
//
if
(
mOcCachelessInProgress
&&
OpenMode
==
EFI_FILE_MODE_READ
&&
StrnCmp
(
FileName
,
L"System
\\
Library
\\
Extensions
\\
"
,
L_STR_LEN
(
L"System
\\
Library
\\
Extensions
\\
"
))
==
0
)
{
Status
=
CachelessContextHookBuiltin
(
&
mOcCachelessContext
,
FileName
,
*
NewHandle
,
&
VirtualFileHandle
);
if
(
!
EFI_ERROR
(
Status
)
&&
VirtualFileHandle
!=
NULL
)
{
*
NewHandle
=
VirtualFileHandle
;
return
EFI_SUCCESS
;
}
}
//
// This is not Apple kernel, just return the original file.
// We recurse the filtering to additionally catch com.apple.boot.[RPS] directories.
...
...
@@ -869,9 +1016,11 @@ OcLoadKernelSupport (
Status
=
EnableVirtualFs
(
gBS
,
OcKernelFileOpen
);
if
(
!
EFI_ERROR
(
Status
))
{
mOcStorage
=
Storage
;
mOcConfiguration
=
Config
;
mOcCpuInfo
=
CpuInfo
;
mOcStorage
=
Storage
;
mOcConfiguration
=
Config
;
mOcCpuInfo
=
CpuInfo
;
mOcDarwinVersion
=
0
;
mOcCachelessInProgress
=
FALSE
;
}
else
{
DEBUG
((
DEBUG_ERROR
,
"OC: Failed to enable vfs - %r
\n
"
,
Status
));
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录