iOS 调试线上 app 中 WebView 的方法

0x1、要解决的问题

工作中时常遇到需要对自己已上线 app 中的 WebView 网页进行一些调试验证的情况,以排查 bug,解决问题。

但是已经在线上的 app 如何能够在不依赖其它代码级 Hook 工具的情况下,进行简单的调试呢?

0x2、解决方案

利用 HTTP 抓包工具 的『断点调试』功能向 WebView 注入调试脚本。这里以 iOS 上的抓包应用 Thor HTTP Sniffer 为例。理论上电脑平台的抓包工具只要支持断点调试(修改 HTTP 响应的能力)都能达成同样的效果。

0x3、技术原理及流程

a. 截获本机请求:利用 HTTP MiTM 截取目标 WebView 的请求,在修改响应消息体后再回传。

b. 修改响应消息体:向目标网页的 HTML 响应中的 body 标签注入调试脚本(文本正则替换)。

c. 修改响应头:去掉响应头中 "Content-Security-Policy" 字段,以保证本机注入的调试脚本能正常执行。

0x4、WebView 调试示例 app

PPHub For Github (by jkpang): GitHub 第三方 iOS 客户端

0x5、用到的工具

第一步:在 Thor 中设置过滤器断点

0x1、打开 Thor, 创建一个过滤器,取名为:”WebView 注入调试”,并添加一个断点进入编辑

0x2、因为需要对 WebView 的响应 HTML 内容进行注入,所以选择在 请求阶段 > 响应消息体回传前 > 新建匹配规则

匹配规则

» 选择『响应 body 前』

响应 body 前

0x3、在匹配规则中加入表达式进行替换,以注入 vConsole 工具

因为对 HTML body 标签注入 js 脚本后可能不会总是生效,所以这里选择优先对 title 标签进行替换

加入判断条件:判断是否包含 title 标签

@rsp.bodyText CONTAINS[cd] "</title>"

当有 title 标签时,执行以下表达式

^@rsp.bodyText "<\/title>" "</title><script type='text/javascript' src='https://coding.net/u/Tumblr/p/thor-lib/git/raw/master/vconsole/3.2.0/vconsole.min.js'></script><script>new VConsole();</script>"

没有 title 标签,则找 body 标签替换

^@rsp.bodyText "<\/body>" "<script type='text/javascript' src='https://coding.net/u/Tumblr/p/thor-lib/git/raw/master/vconsole/3.2.0/vconsole.min.js'></script><script>new VConsole();</script></body>"
  • 考虑加载速度的原因,没有直接使用 github 上的 vConsole 原地址,而是 dump 了一份到 coding.net 仓库里,所以上面用的是 codeing.net 的脚本地址

» vConsole 注入设置如图

同理,再新建一个断点,完成 Eruda 工具的注入(其实可以不用两个调试脚本都注入,这里只是演示效果)

第二步:在 PPHub 中找一个 WebView 界面进行尝试

0x1、打开 Thor > 选择 “WebView 注入调试” 过滤器,并启动

» 启动抓包

0x2、打开 PPHub

» 并找到一个 WebView, 等待加载完成 (直到出现调试工具入口)

» vConsole 调试效果

» Eruda 调试效果

参考资料 (排名不分先后)

Thor 20 天免费试用 TestFlight 申请

0x1、Thor 的详细介绍

0x2、TestFlight 申请问卷填写

0x3、过滤器 “WebView 注入调试” 后期优化版下载(下载后直接用 Thor 打开,安装)