iOS 真机 JS 注入 · 第 2 课
带着第 1 课那张五层地图,我去敲三扇最常见的门:iwdp、webinspector cdp、
inspector_session。三扇全是死的。但它们死的原因分成两类——分清这两类,
就等于把"接下来该找什么样的工具"这道题从大海捞针缩小成了一句话。
因为呈现一个调试结论时,"我一上来就找到了正确方案"是不可信的;"我试了 A、B、C,各自死在哪、于是排除了什么"才是可信的。 失败不是流水账,是逐步缩小搜索范围的过程。下面每一扇门,我都用第 1 课的层号标出它死在哪一层。
iwdp ios-webkit-debug-proxy 是很多人第一反应会用的经典工具: 它把 iPhone 的网页调试能力"翻译"成 Chrome 开发者工具能连的形式。教程满天飞,理应最稳。
直接连不上,死在第 2 层。原因正是第 1 课那个总根源:iwdp 依赖的是 老的 lockdownd 那扇门。iOS 17 起苹果把门换成了 RemoteXPC,iwdp 没跟上—— 它敲的那扇门物理上已经不存在了。
👉 这类失败的本质:「架构变了,老工具没跟上」。不是你用错了,是工具本身在新系统上作废了。
pymobiledevice3 webinspector cdp 是我们主力工具自带的命令,思路对:它面向 iOS 17 的新世界,
想把网页调试暴露成标准的 CDP Chrome DevTools Protocol 接口给你连。
命令起不来,卡在工具自身的 asyncio(Python 异步框架)报错上。
这次不是架构的问题——门是对的,是工具这段代码本身有 bug,还没打磨好。
👉 这类失败的本质:「新工具还不成熟」。方向没错,实现有坑。这和第一类是完全不同的墙—— 第一类要换工具,第二类可能只要换命令、换版本、绕开那段坏代码。
inspector_session(走开发者隧道 tunneld 的那套会话)在原理上是最"正统"的:
它按第 1 课说的规矩,先建 IPv6 隧道、过 RSD,再开调试会话。
会话挂住、拉不起来,卡在第 2~3 层的隧道/会话建立环节。 正统路要求那条隧道全程稳、RSD 全程配合;真机环境里它没能稳定拉起来(隧道/守护进程争用等),于是整条会话就吊在那。
👉 仍属第二类偏环境:「路子对,但链路太重、太脆」。步骤越多、依赖越重,真机上越容易某一环掉链子。
这才是这一课真正的产出——一张"死因分类表":
于是"接下来找什么"就从模糊变清晰了:我要的,是一个既面向 iOS 17 新世界(排除 A)、
又足够轻量稳定、不依赖那条脆隧道会话(避开 B)的执行 JS 的口子。——这句话,直接把第 3 课的主角
js-shell --userspace 给"框"出来了。
第 3 课:登场的 js-shell --userspace 为什么正好满足这两个条件——
--userspace(用户态隧道)如何绕开"要 root、要重隧道"的负担,以及它靠 WebKit Inspector Protocol
把 JS 送进第 5 层。
📖 参考来源:pymobiledevice3 Discussion #450 — How to work with webinspector?, 社区里对这些命令各自适用场景的真实讨论,写文档时是很好的旁证。