如何从 Kext 访问未导出的符号?

问题描述

我尝试在运行 11.4 Beta (20F5046g) Big Sur 的 M1 机器上加载 kext 模块,但在加载 kext 模块时遇到一些绑定错误消息。

访问从 Apple kext 模块导出的内核符号

首先,为了访问从苹果的 kext 模块 com.apple.kpi.unsupported 导出的内核函数,我使用了下面的 extern 声明。

extern int  cpu_number(void);

另外,我在 info.plist 上添加了 com.apple.kpi.unsupported

    <key>OSBundleLibraries</key>
    <dict>
            <key>com.apple.kpi.libkern</key>
            <string>20.5</string>
            <key>com.apple.kpi.unsupported</key>
            <string>20.5.0</string>
    </dict>

编译不会引发任何错误,但是当我尝试加载模块时,它会打印以下消息。

Error Domain=KMErrorDomain Code=31 "Error occurred while building a collection: 
    1: One or more binaries has an error which prevented linking.  See other errors.
    2: Could not use 'kext' because: Failed to bind '_cpu_number' in 'kext' (at offset 0x0 in __DATA_CONST,__got) as Could not find a kext which exports this symbol
kext specific: 
    1: Failed to bind '_cpu_number' in 'kext' (at offset 0x0 in __DATA_CONST,__got) as Could not find a kext which exports this symbol
" UserInfo={NSLocalizedDescription=Error occurred while building a collection: 
    1: One or more binaries has an error which prevented linking.  See other errors.
    2: Could not use 'kext' because: Failed to bind '_cpu_number' in 'kext' (at offset 0x0 in __DATA_CONST,__got) as Could not find a kext which exports this symbol

我可以访问内核符号列表中指定的内核符号但不是从苹果的kext模块导出的吗?

我还想访问名为 SecureDtinitEntryIterator 的内核函数。我发现这个符号列在位于 /System/Library/Kernels/kernel.conf 的内核符号上。但是, $kextfind -defines-symbol _SecureDTIterateEntries 不会返回任何相应的 kext 模块名称

作为IOS新手,我猜这个符号不是从任何苹果的kexy模块中导出的。有什么办法可以从我的 kext 模块访问这个功能吗?我想我可以使用函数原型将符号位于内核空间内的地址进行类型转换,但我正在寻找一种系统的方法(如果存在)。

解决方法

我刚刚检查过,关键的细节似乎是您试图在 arm64/aarch64 上访问此功能。事实证明,它在 x86_64 的“不受支持的”KPI 中导出,但不在 arm64 上:

没有直接的方法来访问未导出的符号。如果您知道正在运行的内核的确切版本中符号的偏移量,您应该能够通过从已知函数地址偏移来计算地址;至少,这适用于 x86-64。由于 PAC(指针身份验证),arm64 可能需要额外的努力。

由于这违反了 Apple 的政策,我不建议在运输产品中使用这种技术。