iOS 真机 JS 注入 · 第 1 课
你要在 iPhone 里某个 App 的网页上,从你的 Mac 执行一行 JS。听起来像"打开控制台敲代码", 但你和那行 JS 之间隔着五层。真正的难点不是写 JS——是苹果从 iOS 17 起,把中间一层原本敞开的门锁上了。这一课只干一件事:让你能亲手画出这张图,并用手指点出门锁在哪。
把"从你的 Mac 到那行 JS"想象成一栋楼,你在楼顶,目标在地下室。每往下一层,就离目标近一步:
pymobiledevice3——一个纯 Python 写的、和 iPhone 对话的瑞士军刀。正常世界里,这五层是通的:Safari 桌面版点几下,就能远程调试 iPhone 里的网页。所以第一个反直觉的点是—— 难的不是第 5 层(写 JS),是第 2 层(把手伸进去)。
第 2 层原来的规矩叫 lockdownd / 锁定守护进程——iPhone 里一个老牌服务,负责"外部工具通过 USB 请求各种服务"。十几年来,调试工具都靠敲它的门办事。
从 iOS 17 起,苹果把开发者服务整体搬到了一套新协议
RemoteXPC 上。后果很直接:这些服务不再响应老的 lockdownd 直连请求了。
你还照老办法敲门,只会得到 InvalidServiceError / RSDRequired 这类"查无此服务"的回绝。[1]
新规矩有两条硬要求,正是它们让事情变难:
58783 端口上,负责告诉你"要的服务在哪"。[1]一句话记住这一课的核心:
iOS 17 之前,第 2 层是一扇虚掩的门,推开就进;iOS 17 之后,门换成了需要先修一条 IPv6 隧道、再过一道加密安检才能通过的关卡。我们后面所有的折腾,本质都是在"怎么合法地过这道关卡"上打转。
你现在能画出这张图、点出门锁在第 2 层了。第 2 课我们进"侦探现场":带着这张图去看, 我当时试的三条常规通道(iwdp、cdp、tunneld-session)分别死在哪、为什么死——每一次失败,都是这张图上的某一层没跟上 iOS 17 的变化。
📖 参考来源: DeepWiki — Remote Access & Tunneling (iOS 17+), 讲清了 lockdownd→RemoteXPC 的变化、RSD 与隧道的来龙去脉。