Featured image of post 我和 ChatGPT 把 iPhone X 降回 iOS 15.6:从无法激活到真正可用

我和 ChatGPT 把 iPhone X 降回 iOS 15.6:从无法激活到真正可用

为什么想降级、这条路线难在哪里、激活是怎样补上的,以及 Face ID 和锁屏密码带来的真实代价。

成功那晚,我在朋友圈里写了一句“有可能是全世界第一个成功的”。那时已经折腾了很久,看到熟悉的 iOS 15 锁屏,确实有点上头。

冷静下来以后,我不打算把这句话当成结论。有没有别人更早走通过类似路线,我没有办法证明。这篇文章只记录能被日志、设备状态和实机画面证明的部分:我的 iPhone X 确实从 iOS 16.7.16 降到了 iOS 15.6,完成了激活,完整重启后仍然能被 Mac 读到 Activated

已经回到 iOS 15.6 并完成激活的 iPhone X

先说结果

这次实测的设备和结果如下。

项目 实测值
设备 iPhone X Global,A11,iPhone10,3 / d22ap
起点 iOS 16.7.16,Build 20H392
目标 iOS 15.6,Build 19G71
电脑 Apple Silicon Mac
必要票据 这台设备自己的 iOS 15.6 SHSH2
最终状态 ProductVersion=15.6BuildVersion=19G71ActivationState=Activated

从使用感受来说,它确实像“复活”了。动画轻快了不少,滑动和打开应用不再像 iOS 16 上那样拖着走。我还找回了自己一直很喜欢的旧版实况壁纸。

不过,流畅是我这台机器上的主观感受,不是跑分结论。电池、存储占用和硬件状态不同,结果当然可能不一样。Face ID 也没有随系统一起回来,这个限制后面会细说。

为什么要折腾一台已经很老的 iPhone X

iOS 16 上的 iPhone X 不是完全不能用,只是每次拿起来,我都能感到它慢了一点。切换应用、拉通知中心、打开设置,这些细小的停顿累积起来,很容易让人失去继续用它的兴趣。

我又偏偏很喜欢 iOS 15 的手感。它离 iPhone X 的年代更近,旧版壁纸也还在。于是一个很直接的念头冒了出来:既然我以前保存过这台手机的 iOS 15.6 SHSH2,能不能真的把它降回去?

这张 SHSH2 当年保存下来时,我并不知道它以后有没有用。更像是顺手给未来留一扇门。几年以后,它变成了这次降级最重要、也最没办法补办的东西。

Apple 目前已经把 iPhone X 列入全球“停产产品”名单。对我来说,这反而让这次实机记录更有意义。它不是为了证明老设备应该永远服役,只是想看看,在条件刚好齐全的情况下,这台手机还能不能回到一个更舒服的状态。Apple 的产品服务分类说明在这里

开始之前,先把风险讲清楚

这不是 Finder 里点一下“恢复”就能完成的官方流程,也不是一条万能脚本。完整恢复会抹掉手机上的数据,而且外部条件随时可能变化。

如果你只是想照着做,先确认下面几件事:

  • 手机是你自己的测试设备,不是主力机,里面没有重要数据。
  • 你持有这台设备自己的目标版本 SHSH2。别人的票据不能替代。
  • 降级前能让同一台设备在可正常激活的系统上完成官方激活,并完整备份同机激活材料。
  • 有稳定的数据线、可用的恢复路线,以及失败后回到仍可恢复系统的准备。
  • 能接受 Face ID 不可用,以及短信、iMessage、VPN、侧载和其他 SEP 相关功能可能异常。

激活材料、SHSH2、ECID、序列号、UDID、IMEI 和原始日志都不能公开。本文不会提供我的文件,也不会展示设备唯一标识。这里讨论的始终是同一台、已经合法激活过的设备,不涉及绕过 Activation Lock。

为什么 iPhone X 比同代 iPhone 8 麻烦

开始前,我看到最多的一种说法是:A11 的 iPhone 8 还能降,iPhone X 不行,因为新版 SEP 和旧版 iOS 不兼容。

这个判断有现实依据。通用的 futurerestore 流程不足以让 iPhone X 直接回到 iOS 15.6。恢复 Ramdisk、restored_external、KernelCache 和后面的激活都需要额外处理。即使系统成功启动,新版 SEP 和 iOS 15.6 也不是原生组合,Face ID 这类功能不会自动恢复。

真正需要闭合的是两件不同的事:

  1. 让 iOS 15.6 真的写进去,并且成功启动。
  2. 让启动后的系统完成激活,重启后仍然可用。

只完成第一件,手机可能停在激活界面。只准备好激活文件,却没有跑通恢复链,也一样没用。

我准备了什么

这次用到的核心工具是 Legacy iOS Kitfuturerestorepalera1n。底层能力来自这些开源项目和相关研究者,我和 ChatGPT/Codex 做的是把零散的方法拼成一条适合这台实机的路线,再一段一段验证。

本次关键输入包括:

  • iPhone X 对应的 iOS 15.6 原版 IPSW,Build 19G71
  • 这台手机自己的 iOS 15.6 SHSH2。
  • 当时可恢复并能正常激活的 iOS 16.7.16,Build 20H392
  • 当前签名固件提供的 SEP、Baseband 和其他恢复组件。
  • Apple Silicon Mac,以及确认能传数据的 USB-A 转 Lightning 线。

这里最容易被忽略的是最后一项。后面很多看起来像软件的问题,最后都和 USB 连接有关。

整条路线,先看一遍

最后跑通的流程可以压缩成下面这条线:

恢复 iOS 16.7.16
  -> 完成 Apple 官方激活
  -> 用 palera1n 临时取得 root SSH
  -> 备份并校验同一台设备的完整激活材料
  -> 进入 DFU 和 pwnDFU
  -> 用 iPhone X 专用恢复补丁降到 iOS 15.6
  -> 再次临时取得 root SSH
  -> 找到新生成的 System 容器
  -> 写回同机激活材料并恢复权限
  -> 完整重启
  -> 验证 15.6 / 19G71 / Activated

看起来只是一串箭头,真正做起来,每一段都可能把人拦住。

第一步:先回到 16.7.16,不是多此一举

一开始我手里只有激活服务器返回的 activation_record.plist 和响应头。我以为这应该够了,实际在 iOS 15.6 上尝试安装时,激活请求直接失败。

最后确认,想让降级后的系统恢复到同机已激活状态,需要从这台手机正常激活的系统中备份四类材料:

  • activation_record.plist
  • data_ark.plist
  • 完整的 FairPlay 目录,其中必须有非空的 IC-Info.sisv
  • com.apple.commcenter.device_specific_nobackup.plist

所以我先把手机完整恢复到 iOS 16.7.16,在手机上走完正常的联网激活,再用 palera1n 临时引导,拿到 root SSH 后把这些材料备份到 Mac。

这一步不能猜路径。每次完整恢复以后,System 数据容器的 UUID 都可能变化。我们实际搜索到当前容器,再核对文件是否齐全、plist 能否解析、文件是否非空,最后离线保存哈希。材料只留在本机,没有上传到 GitHub,也没有放进聊天记录。

我负责看手机和按键,Codex 在 Mac 上分析恢复状态

第二步:还没刷机,先卡在 firmwares.json

恢复 16.7.16 时,流程曾经在真正写入手机之前失败。日志里出现了:

failed to download ... firmwares.json ... CURLcode=28
[TSSC] parsing firmware.json failed

检查后发现,tsschecker 在 nocache 状态下会强制重新下载 firmware index。即使本地已经有一份完整、能解析的缓存,它也会被忽略。网络稍慢,内置超时就把整个流程打断。

我们对 main 和 dev 两套 futurerestore 源码里的对应判断做了一个很窄的本地修补,让缓存存在时优先使用缓存,然后分别重新编译。之所以两套都要改,是因为中转系统 16.7.16 和目标系统 15.6 实际走的不是同一个 futurerestore 分支。

这个改动只解决本次环境里的可靠性问题,不代表上游已经采用,也不能把“忽略 nocache”当成永远正确的通用修复。公开仓库里保留的是小型源码补丁和说明,没有放自定义二进制。

第三步:分支和 BuildIdentity 也踩了坑

Legacy iOS Kit 原来的分支选择逻辑在这条路线里并不合适。iPhone X 的 iOS 15 目标需要走 main 分支上的专用恢复路径,iOS 16 中转恢复则使用 dev 分支。

第一次准备 15.6 恢复包时,还发现 BuildIdentity 选错了。我的 Global iPhone X 对应 d22ap,不是另一个身份。好在当时仍处于准备阶段,还没有写手机。确认设备身份、目标 Build、SHSH 和恢复组件完全对应以后,才继续下一步。

这也是我后来反复强调“每次都重新读设备”的原因。工具能跑起来,不代表它选中的对象一定正确。

第四步:DFU 成功了,iBEC 后又停住

真正开始降级前,我进入 DFU,使用 checkm8 和 pwnDFU 引导 iPhone X 的恢复链。屏幕全黑,Mac 能正确识别设备,恢复端也开始处理自定义 Ramdisk 和 Kernel。

自定义恢复环境运行在 iPhone X 上

第一次尝试在 iBEC 之后报错:

Getting ApNonce failed
ERROR: Device is in an invalid state

这时我先忍住了立刻再刷一次的冲动,转头确认手机有没有开始写系统。日志显示失败发生在文件系统写入前,设备只是停在 Recovery,原来的 16.7.16 还在。

我重新进入 DFU,并加上 --no-cache 强制重新生成这次使用的启动组件。第二次恢复终于继续往下走。

恢复过程中的白苹果和进度条

第五步:看到 Restore Finished,还不能庆祝

恢复日志里陆续出现了几个关键标志:

Patched decompressReferenceFrames
1337 CUSTOM RAMDISK!
1337 CUSTOM KERNEL!
Status: Restore Finished
Done: restoring succeeded!

手机也真的启动到了 iOS 15.6。按理说这已经是最让人兴奋的时刻,但它还不能算完成,因为系统停在了激活阶段。

刷入 iOS 15.6 后,系统仍然提示无法激活

普通联网激活在当前 SEP 和 iOS 15.6 的组合下失败了。只写回一份 activation record 也没有用。那一刻很直观地说明了一个问题:能启动和能使用,是两道不同的门。

第六步:把激活闭环补上

我再次用 palera1n 临时引导 iOS 15.6,取得 root SSH。完整恢复已经生成了新的 System 容器 UUID,所以不能沿用 16.7.16 上的旧路径。

我们重新定位容器,先把四类同机激活材料传到临时目录,核对大小和哈希,再按新系统里实际读取到的属主与权限写回。网上有些旧教程会统一执行 chmod 755,但这次没有照抄。文件权限并不是越宽越好,应该恢复到实机原始状态。

写回完成以后,我做了完整重启。Mac 端分别读取三项状态:

ideviceinfo -k ProductVersion
ideviceinfo -k BuildVersion
ideviceinfo -k ActivationState

最终结果是:

15.6
19G71
Activated

到这里,才算真正完成。不是“屏幕亮了”,也不是“看见桌面了”,而是恢复端成功、设备能启动、重启后激活状态仍然成立。

“关于本机”显示 iOS 15.6,序列号已做不可逆遮挡

最后正常亮屏的 iOS 15.6 锁屏

中间还有一个很隐蔽的坑:数据线

这次折腾让我重新认识了“线能充电”和“线能稳定跑 checkm8”之间的差别。

我试过 USB-C 转 USB-A 适配器,也试过一根看起来正常的 A 口线。结果有时卡在 SPRAY,有时出现 e0004051,有时 Mac 干脆不枚举设备。软件日志看起来很吓人,换回一根原生、确认能传数据的 USB-A 转 Lightning 线以后,后面的 Recovery 和 DFU 路径明显稳定了。

除此之外,残留的 palera1n 进程、多个工具同时占用 USB,以及 macOS 把 USB 配件分配给虚拟环境,都可能造成“设备忙”或突然断开。碰到这类问题,继续重试命令往往没有用,先把 USB 占用关系清干净更重要。

成功以后,我又把自己折腾回去了

最初成功激活后,我还想继续研究 Face ID。系统能够看到 TrueDepth/Pearl 能力,相机会话也能建立,但凭据设置始终失败,日志指向 SEP 侧的 credential manager 和本地密钥更新错误。

后来我尝试设置锁屏密码,手机重启后重新变成 UnactivatedBrickState 也变成了 true。再次用 palera1n 引导时,还遇到了 SEP Panic

这次没有重刷 15.6。确认目标系统仍然完整以后,我通过 SSHRD 做了一次原地数据重置,再用 palera1n 临时取得 root,重新写回同一台设备的激活材料。恢复后再次完整重启,最终状态回到了:

iOS 15.6 / 19G71 / Activated / BrickState false

这段插曲留下了一个非常具体的结论:在我这台 iPhone X 的 iOS 15.6 加当前 iOS 16 SEP 组合上,不要设置锁屏密码,不要尝试 Face ID,也不要配置 Apple Pay。否则可能再次破坏激活和启动路径。

现在到底哪些能用,哪些不能用

已经确认的部分:

  • iOS 15.6 能完整启动。
  • 重启后仍然是 Activated
  • 基本触控、Wi-Fi、蜂窝网络显示和日常界面正常。
  • 实际操作比原来的 iOS 16.7.16 流畅很多。
  • 旧版实况壁纸恢复了,这也是我最直观的满足感来源。

明确不正常或不建议碰的部分:

  • Face ID 不可用。
  • 不建议设置锁屏密码。
  • 不建议尝试 Apple Pay。
  • 短信、iMessage、VPN、侧载和其他 SEP 依赖功能没有做完备测试。
  • 不能因为 ActivationState=Activated 就声称所有硬件功能正常。

所以它适合当测试机、收藏机或者离线体验设备,不适合直接拿来当主力机。

这次我和 ChatGPT/Codex 是怎么配合的

很多时候,我真的只负责按键。

我确认手机里没有重要数据,授权每次完整恢复,按照提示进入 DFU,盯着屏幕有没有苹果标志、进度条和报错。ChatGPT/Codex 负责在 Mac 上读设备状态、分析日志、查上游资料、修改并编译工具、控制恢复流程,以及最后整理脱敏教程。

这并不等于 AI 发明了这套降级技术。checkm8、Legacy iOS Kit、futurerestore、palera1n 和 iPhone X 的底层补丁都来自社区项目和研究者。AI 在这次过程里更像一个一直在线的排错搭档:它能接住我每一次“现在手机黑屏了怎么办”,也能在恢复真正开始前停下来核对设备和文件。

我原本以为最消耗配额的会是写代码,最后发现真正费时间的是那些边界状态:手机现在是 DFU、Recovery 还是正常模式,失败有没有写入文件系统,哪一个进程占用了 USB,旧容器 UUID 还能不能用。全程大概用掉了我当周八成左右的 Plus 配额,但相比把一台手机刷成真正无法恢复的砖,这些检查很值得。

想复现的话,去看完整项目

我把脱敏后的完整中文和英文教程、版本记录、复现检查表、两个小型源码补丁,以及预检和隐私检查脚本都整理到了 GitHub:

brucewong666/iphone-x-ios15-downgrade

仓库写得比这篇博客更技术化,包含具体命令、成功标志和失败判断。动手前请从头读完,不要只复制其中一条命令。

这条路线证明的范围很窄:一台符合条件的 iPhone X,在 2026 年 8 月当时的签名状态、工具版本、Mac 和 USB 环境下,成功完成了 16.7.16 -> 15.6,并在重启后验证为 Activated。它不保证所有 iPhone X、所有目标版本或未来环境都能复现。

对我来说,“刷成功”只是一个结果。更实在的变化是,这台本来已经很少拿起的 iPhone X,现在又愿意让我多用一会儿。代价也很清楚:没有 Face ID,不能设密码,还要接受它只适合作为一台实验设备。这个结果不完美,但它是真的。