加载dict_iOS Jailbreak Principles 0x03 Prelinked AMFI.kext 的注册和加载

本文深入探讨了iOS中AppleMobileFileIntegrity.kext(AMFI)的加载和注册过程,包括从kernelcache中分离kext、分析PRELINK_INFO、AMFI.kext的注册到IOKit,以及加载逻辑。文章详细阐述了Pre-Linking机制,kext的Info.plist解析,以及AMFI启动和初始化过程中libkern C++环境的设置。
摘要由CSDN通过智能技术生成

系列文章

  1. iOS Jailbreak Principles 0x01 - rootfs remount r/w 原理
  2. iOS Jailbreak Principles 0x02 - codesign and amfid bypass

前言

在上一篇文章中我们介绍了 amfid 的 codesign 机制及其绕过,amfid 是 codesign 逻辑在 user mode 的一个 daemon,代表了 C/S 架构中的 Server。本文将介绍 kernel mode 的 amfi.kext,它是 amfid 的 Client,以 Kernel Extension 的形式被加载和注册到 Kernel 中。

Kernel Extension

定义

XNU 是一个功能丰富的内核,包含了调度, 内存管理, I/O 等必要的服务,但它依然难以直接适配浩如烟海的硬件和外设,即使是宏内核也无法完全做到这一点[1]。

就像是 user mode application 中常常包含 dylib,在 kernel mode 也有 kernel modules 作为扩展,在 XNU 中被称为 kernel extensions,简称为 kext[1]。

Pre-Linking

以常规视角而言,操作系统应当是先 boot kernel,随后 load kexts。在 iOS 中,kernel 和它的扩展不是以分离的文件形式存在,而是将 kernel 和 kexts 合并成一个 kernelcache 文件直接被 boot loader 加载。

kernelcache 带来了两个好处,其一是 kexts 不必再像 dylib 那样进行动态链接,省去了外部符号地址解析的过程,加快了加载速度;其二是 kernelcache 可以被完整的签名以降低 kext 被篡改的风险[1]。

分析 AppleMobileFileIntegrity.kext

从 kernelcache 中分离

由于 amfi.kext 被 prelink 到 kernelcache 中,因此其 Info.plist 和 binary 都直接包含在了庞大的 kernelcache 中,为了便于分析我们可以将它们从 kernelcache 中分离出来。

通过 joker 分离 kext binary

使用 joker (http://www.newosxbook.com/tools/joker.html) 可以分离出 kext 和进行部分符号化:

# 指定输出目录
> cd /tmp/kext
> export JOKER_DIR=/tmp/kext

# 准备好 kernelcache
> ls .
kernelcache

# 分离 amfi.kext
> joker -K com.apple.driver.AppleMobileFileIntegrity kernelcache
Writing kext out to /tmp/kext/com.apple.driver.AppleMobileFileIntegrity.kext
Symbolicated stubs to /tmp/kext/com.apple.driver.AppleMobileFileIntegrity.kext.ARM64.E815A4DD-90E7-3A38-A4BA-EFA2425BC543

# 查看产物
> ls .
com.apple.driver.AppleMobileFileIntegrity.kext
com.apple.driver.AppleMobileFileIntegrity.kext.ARM64.E815A4DD-90E7-3A38-A4BA-EFA2425BC543
kernelcache

可以看到我们得到了 kext 的 binary 和一份符号表,由于 kext 是从内核中分离的,与从 dyld_shared_cache 分离出 dylib 类似,有大量的外部地址无法正常解析,通过符号表或是在 kernelcache 中定位都可以帮助判断这些地址的含义和内容。

使用 jtool 分离 PRELINK_INFO

与 App 通过 Info.plist 描述关键信息类似,kext 也有其 Info.plist 来描述 kext 的各种信息,其中包含了标识符、加载地址等关键信息,为了方便分析,我们还需要从 kernelcache 中分离出 amfi 的 Info.plist。这里我们使用 jtool (http://www.newosxbook.com/tools/jtool.html) 来完成分离:

# 指定输出目录
export JTOOLDIR=/tmp/kext

# 分离 PRELINK_INFO
> jtool -e __PRELINK_INFO kernelcache
Requested segment found at offset 1e10000!
Extracting __PRELINK_INFO at 31522816, 2342912 (23c000) bytes into kernelcache.__PRELINK_INFO

# 查看产物
> ls .
com.apple.driver.AppleMobileFileIntegrity.kext
com.apple.driver.AppleMobileFileIntegrity.kext.ARM64.E815A4DD-90E7-3A38-A4BA-EFA2425BC543
kernelcache
kernelcache.__PRELINK_INFO

打开 kernelcache.__PRELINK_INFO 可以看到这里包含了大量被 prelink 到 kernelcache 中的 kext 的信息,在其中还混入了大量被 base64 编码的 Data Blob。

在 PRELINK_INFO 中查找关键信息

kernelcache.__PRELINK_INFO 中搜索 _PrelinkBundlePath/System/Library/Extensions/AppleMobileFileIntegrity.kext 可以定位到 amfi.kext 的 Info.plist,这里包含了 amfi.kext 的一些关键信息:

<dict>
  <key>BuildMachineOSBuildkey>
  <string>18A391011string>
  <key>_PrelinkExecutableLoadAddrkey>
  <integer ID="32" size="64">0xfffffff005ab1980integer>
  <key>CFBundlePackageTypekey>
  <string>KEXTstring>
  <key>_PrelinkExecutableSourceAddrkey>
  <integer IDREF="32"/>
  <key>CFBundleDevelopmentRegionkey>
  <string>Englishstring>
  <key>MinimumOSVersionkey>
  <string>13.1string>
  <key>CFBundleVersionkey>
  <string>1.0.5string>
  <key>DTXcodeBuildkey>
  <string>11L374mstring>
  <key>DTPlatformBuildkey>
  <string ID="33"/>
  <key>_PrelinkBundlePathkey>
  <string>/System/Library/Extensions/AppleMobileFileIntegrity.kextstring>
  <key>_PrelinkExecutableSizekey>
  <integer size="64">0x5211integer>
  <key>_PrelinkKmodInfokey>
  <integer size="64">0xfffffff0077e51c8integer>
  <key>UIDeviceFamilykey>
  <array>
    <integer IDREF="10"/>
  array>
  <key>OSBundleRequiredkey>
  <string>Rootstring>
  <key>CFBundleIdentifierkey>
  <string>com.apple.driver.AppleMobileFileIntegritystring>
  <key>DTXcodekey>
  <string>1100string>
  <key>CFBundleExecutablekey>
  <string IDREF="31"/>
dict>

其中以 _Prelink 开头的字段非常重要:

<dict>
  <key>_PrelinkExecutableLoadAddrkey>
  <integer ID="32" size="64">0xfffffff005ab1980integer>
  <key>_PrelinkExecutableSourceAddrkey>
  <integer ID="32" size="64">0xfffffff005ab1980integer>
  <key>_PrelinkBundlePathkey>
  <string>/System/Library/Extensions/AppleMobileFileIntegrity.kextstring>
  <key>_PrelinkExecutableSizekey>
  <integer size="64">0x5211integer>
  <key>_PrelinkKmodInfokey>
  <integer size="64">0xfffffff0077e51c8integer>
  <key>CFBundleIdentifierkey>
  <string>com.apple.driver.AppleMobileFileIntegritystring>
dict>

这些字段的含义如下[1]:

  • _PrelinkExecutableSourceAddr: kext 的起始地址,即 kext 的 Mach-O Header 地址;
  • _PrelinkExecutableLoadAddr: kext 在内存中的加载地址,对于 prelink kext 这个值一般等于 _PrelinkExecutableSourceAddr;
  • _PrelinkKmodInfo: kext 在 Mach layer 的对象模型。

下面我们大致看一下这些地址的内容,首先

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值