iOS 真机 JS 注入 · 第 1 课

这座山有多高:五层地图,和 iOS 把梯子撤在哪一层

你要在 iPhone 里某个 App 的网页上,从你的 Mac 执行一行 JS。听起来像"打开控制台敲代码", 但你和那行 JS 之间隔着五层。真正的难点不是写 JS——是苹果从 iOS 17 起,把中间一层原本敞开的门锁上了。这一课只干一件事:让你能亲手画出这张图,并用手指点出门锁在哪。

先建立一个画面:五层

把"从你的 Mac 到那行 JS"想象成一栋楼,你在楼顶,目标在地下室。每往下一层,就离目标近一步:

1
你的 Mac(调试端) 你敲命令的地方。工具:pymobiledevice3——一个纯 Python 写的、和 iPhone 对话的瑞士军刀。
2
USB ↔ iPhone 的"信使通道" 🔒 门就锁在这一层。Mac 的命令要先坐上这条通道才能进手机。iOS 17 起,这条通道的规矩全变了(下节详解)。
3
webinspectord(苹果的调试守护进程) 手机里常驻的"调试接待员"。它掌管着"哪些网页可以被外部调试"。前置:设备上要开着 Web Inspector 开关。
4
App 里的 WKWebView(网页容器) 飞书/妙记/豆包这些 App 内嵌的浏览器窗口。我们的网页就跑在这里面。一个 App 可能同时开好几个。
5
网页里的 JS 运行时 ← 终点 我们最终要在这里执行代码。再往里还有一层"桥"(JSBridge),是网页和 App 原生互相喊话的对讲机——第 5 课的主角。

正常世界里,这五层是通的:Safari 桌面版点几下,就能远程调试 iPhone 里的网页。所以第一个反直觉的点是—— 难的不是第 5 层(写 JS),是第 2 层(把手伸进去)。

门锁在哪:iOS 17 的那次"改朝换代"

第 2 层原来的规矩叫 lockdownd / 锁定守护进程——iPhone 里一个老牌服务,负责"外部工具通过 USB 请求各种服务"。十几年来,调试工具都靠敲它的门办事。

关键变化

iOS 17 起,苹果把开发者服务整体搬到了一套新协议 RemoteXPC 上。后果很直接:这些服务不再响应老的 lockdownd 直连请求了。 你还照老办法敲门,只会得到 InvalidServiceError / RSDRequired 这类"查无此服务"的回绝。[1]

新规矩有两条硬要求,正是它们让事情变难:

一句话记住这一课的核心:

iOS 17 之前,第 2 层是一扇虚掩的门,推开就进;iOS 17 之后,门换成了需要先修一条 IPv6 隧道、再过一道加密安检才能通过的关卡。我们后面所有的折腾,本质都是在"怎么合法地过这道关卡"上打转。

接下来

你现在能画出这张图、点出门锁在第 2 层了。第 2 课我们进"侦探现场":带着这张图去看, 我当时试的三条常规通道(iwdp、cdp、tunneld-session)分别死在哪、为什么死——每一次失败,都是这张图上的某一层没跟上 iOS 17 的变化。

📖 参考来源DeepWiki — Remote Access & Tunneling (iOS 17+), 讲清了 lockdownd→RemoteXPC 的变化、RSD 与隧道的来龙去脉。


第 1 课 / 共 6 课 · 课程:iOS 真机 JS 注入 · 来源标注见正文 [1]