OSX/iOS 抓包工具 Charles 入门
本篇博客中所使用的环境为:macOS Sierra 10.12,Charles 4.0.1,iPod Touch 5。

在 iOS 开发中,我们常常要涉及到网络编程,而网络编程中的调试往往令人头痛。此外,我们也有时也会需要抓取一些 App 的网络包,以便了解它网络请求的API。本篇要介绍的 Charles 就是一款非常好用的网络调试工具,它可以轻松地满足我们的上述需求。
准备工作
启动 Charles
Charles 的下载安装这里就不再赘述。启动 Charles 后,我们可以看到 Charles 的主界面。

窗口的左侧是抓取到的网络包,通常 Charles 启动后我们就可以看到 Mac 上的一些网络包开始出现在这里。
窗口右侧是选中的网络包的详细信息,如 URL、状态码等。
窗口上方是一些常用的工具。鼠标经过时就会有相应的提示,后面再细说。
右下角是 Charles 当前的状态。可以显示 Recording、BreakPoints、Rewrite 等功能是否启用。
连接设备
要抓取 iOS 设备上的网络包,首先要将 iOS 设备和装有 Charles 的电脑连接到同一个局域网下,并将 Charles 设置为 iOS 的 HTTP 代理,这样 Charles 就可以捕捉到所有进出 iOS 的网络包。设置的步骤如下:
- 确保装有 Charles 的 mac 和等待调试的 iOS 设备在同一局域网内;
- 查找 mac 的 IP 地址(可以在 Charles 菜单栏的 Help -> Local IP Address 直接查看);

- 在 iOS 设备上的 设置 -> Wi-Fi 中,点击已连接 WiFi 右侧的 详细按钮(蓝色),将 WiFi 详情页底部的 HTTP 代理 设为手动,并在 服务器 一栏填入上一步中 mac 的 IP 地址,在 端口 一栏填入 Charles 的默认代理端口 8888,然后退出设置;

- 此时如果网络正常的话,Charles 会提示有设备企图连接,同意连接,便完成了代理的设置。

注意:许多公司的内部局域网会限制设备间的互相访问,这可能会导致 Charles 抓取不到网络包,这种情况下可以尝试自己创建一个热点。
连接完成后,窗口左侧开始出现 Charles 抓到的包,说明进展顺利。
抓包
捕获
Charles 启动后,就处于 Recording 状态,会自动捕捉网络包,点击窗口上方工具栏的第二个按钮可以停止捕捉。
在窗口左侧的选择上方的 Structure 或 Sequence 可以切换网络包的显示方式。
- Structure 是根据主机名以树状显示,便于查看同一主机名的网络包,每当有新的请求到达时,相应的主机名就会用黄色高亮闪烁。我们通常都是采用这个方式。
- Sequence 则是根据网络请求的时间顺序依次显示,在这个模式下,整个窗口的布局也会有所变化。
选中某个网络包后,右侧就会显示该网络包的详细信息。

开始抓包之后,我们会发现,只有 HTTP 的包被成功解析了,HTTPS 的包都处于加密状态。要想查看 HTTPS 的包内容,可以查看本文中 SSL 代理的小节。
过滤
开始抓包后,随着时间的推移,抓取到的网络包越来越多,这是我们可以使用过滤功能,来过滤出我们想要的网络请求。
在 Proxy -> Recording Settings 中可以设置网络包的过滤选项。

过滤选项中有 Include 和 Exclude 两种选项。只有当 Include 为空时,Exclude 中的设置才会生效。过滤条件支持通配符。
修改网络包
修改历史请求
可以将历史的请求修改后,再次发送。
只需选中某个请求,点击上方工具栏中的蓝色钢笔按钮(第四个),就可以进行修改。完成修改后,点击下方的 Execute 执行请求。

断点
窗口上方的工具栏中,第四个按钮就是 Enable BreakPoints,用来启用或禁用断点。也可以在 Proxy -> BreakPoints Setting 中设置更多具体内容。
在 Charles 中可以像调试程序一样添加断点。方法是右键点击左侧窗口的某个请求,选择 BreakPoints 添加断点。这样当这个请求发出或者收到 response 的时候,就会先被 Charles 拦截下来,并触发断点。

触发断点后,可以对断点的网络包进行各种编辑,然后再继续。点击 Execute 就可以继续。
同时,也可以在 Proxy -> BreakPoints Setting 设置断点的各种规则。例如,是在 request 的时候触发还是 response 的时候。

由于设置断点时,Charles 是先拦截下整个网络包,再触发断点,当网络包比较大的时候,常常会导致应用超时,触发网络错误的警告,因此,自动地根据规则修改网络包有时显得尤为重要。这就是下面要说的篡改。
篡改(Rewrite)
Rewrite 是按照一组事先设置的规则,篡改特定的网络包中的数据。
在 Tools -> Rewrite 中,选中 Enable Rewrite 来开启 Rewrite。

勾选 Debug in Error Log 选项,就能在 Charles 控制台中看到 Rewrite 的记录。
首先要在右侧的规则列表中添加一个新规则。在新规则中添加要 Rewrite 的 Location,然后再下方添加具体的篡改规则。规则中可以使用通配符。

这样稍后匹配条件的网络包到达的时候,Charles 就会自动将其中的内容按规则篡改。
映射
Charles提供的映射功能可以将本地文件或者远程的服务器作为某个请求的 Response。可以方便地进行一些特殊的测试。
1、Map Local
本地映射,在 Tools -> Map Local。可以选择一个本地文件作为某个请求的 Response,并且 Charles 会帮你封装好 Response。

2、Remote Remote
远程映射和本地映射的功能类似,只是将数据源换成了远程服务器。相当于将请求交给另一个服务器处理
网络环境模拟
Charles 还可以模拟不同网速环境,可以很方便地测试应用在网络差的情况下的 bug。
在 Proxy -> Throttle Settings 中勾选 Enable Throttling,或者直接点击窗口上方的工具栏中的乌龟🐢按钮就可以启用,这个按钮十分形象。
在 Proxy -> Throttle Settings 中,添加要针对的 Locations,如果选中了 Only for selected hosts,并且Locations中有数据,则只有 Locations 列表中的请求会被限速,否则会对全局限速。在 Throttle Configuration 中可以对网络环境进行十分详细的配置,包括网络的稳定程度、网速、环境等。

SSL 代理
在使用 Charles 的过程中,我们会发现,只有未加密的 Http 请求才能被 Charles 正确的解析出数据,其余的 Https 请求都处于加锁的状态,但我们不可避免的需要抓取 Https 的包。SSL 代理就可以完美解决这个问题。
要启用 SSL 代理,先要在 Proxy -> SSL Proxying Settings 中勾选 Enable SSL Proxying,然后配置要代理的 Location,一般可以直接填星号,以匹配所有请求。

接下来还要安装 Charles 的证书。
Charles 中的 HTTPS 代理的原理是,Charles 充当一个中间人,针对目标服务器动态地生成一个使用 Charles 根证书(Charles CA Certificate)签名的证书;请求发生的时候, Charles 会接收 web 服务器的证书,而把自己生成的证书给客户端看。
因此在在使用 Charles 作为 HTTPS 代理时,客户端在请求 HTTPS 接口的时候会弹出安全警告,提示 Charles 根证书不被信任。我们需要添加 Charles 根证书为信任证书中。
方法如下:
1、点击 Help -> SSL Proxying,根据被抓包设备的类型,来选择对应的安装选项(如果是 OSX 就直接选择 Install Charles Root Certificate);
2、如果是iOS真机,则会弹出下面的提示,此时不用按上面的提示来配置代理,只要按照上文的步骤配置过代理了就可以了。然后在 Safari 中打开 chls.pro/ssl 安装 Charles 的证书,就 OK 了。

设置好 SSL 代理后,HTTPS 请求就统统解锁啦!

-
注意:iOS9以上系统要使用 Charles 作为 SSL 代理的话要关闭 APP Transport Security ,关闭方法为在APP的info.plist文件添加以下key:
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>
Charles 是一个强大的抓包调试工具,它的功能远不止这些,但本篇作为一篇入门的博客,就先介绍这么多啦,更多功能等待大家探索~
套餐
Postman
Postman 是一个测试 API 的利器。

Charles 搭配 Postman 更好用噢~
Postman 是 Chrome 浏览器中的一个小应用,可以在 Chrome 应用商城中找到。是居家旅行测试 Web API 的好帮手!