
1. 为什么要在Windows上用USB过Charles抓包做移动端开发或者接口联调的朋友大概率都用过Charles抓包工具。它在Windows上配合手机抓HTTPS请求常规思路是让手机和电脑连同一个WiFi然后把手机WiFi代理指到电脑IP和8888端口。这个方案本身没毛病也挺稳但真正落地的时候你会发现一堆烦心事公司办公网络开了AP隔离手机和电脑虽然在同一个WiFi下但根本不通会议室、工厂车间这些地方网络信号差WiFi代理经常断测试手机是那种只能插SIM卡上网的机型压根连不上公司WiFi还有一部分Android设备在部分系统版本下对WiFi代理支持不友好配置完代理后发现应用不走代理通道。这个场景我碰到的次数多到数不清。每次临时在客户现场要抓个包核对问题第一反应就是找WiFi找不到就特别被动。后来才把思路转过来USB数据线就插在电脑上既然adb能把数据从手机通过USB通道转发到电脑那Charles的代理服务能不能也走这条USB物理通道答案是可以的而且这种方式比WiFi稳定得多。简单说这个方案的核心思路是电脑上Charles照常监听8888端口但手机不走WiFi代理而是通过adb反向代理机制把手机上发往127.0.0.1:8888的流量沿着USB数据线直接转发到电脑的8888端口。应用侧只需要把所有请求指向127.0.0.1:8888Charles就能完整看到从应用发出的每一个HTTPS请求。整个过程不依赖局域网不依赖网段也不依赖WiFi信号强弱物理链路就是那根USB线想断都难。这篇文章写给谁写给在Windows电脑上开发调试Android应用的工程师、做小程序前端联调的同学、需要排查第三方SDK网络请求的测试人员还有那些跟我一样被WiFi代理折腾到没脾气的人。下面我按完整流程把原理、配置、实操、常见坑都走一遍照做基本几分钟就能把环境搭起来。2. 先搞清楚USB通道抓包到底是怎么工作的2.1 Charles替你做的那点事Charles本质上就是一个HTTP中间人代理。手机上的应用发HTTPS请求时Charles会把自己伪装成目标服务器用自己生成的证书跟应用完成TLS握手然后应用实际上是跟Charles建立的安全连接。与此同时Charles再作为客户端去跟真正的服务器建立另一条TLS连接。这样两条连接都由Charles中转它自然能看到明文内容。这也就是为什么你必须把Charles的CA根证书安装到手机的“系统受信任凭据”里——因为应用的TLS握手验证的是证书链如果根证书不被信任应用会直接拒绝连接。在这个机制里面代理地址指到哪儿是核心问题。WiFi方式下代理地址填的是电脑在局域网里的IP比如192.168.1.100。USB方式下没有局域网IP的概念手机和电脑之间只有一条USB虚拟网卡链路普通情况下应用没法直连电脑的8888端口。adb reverse正好补上这个空白。2.2 adb reverse到底做了什么Android调试桥(adb)自带一个反向转发功能命令格式很直白adb reverse tcp:8888 tcp:8888这条命令的意思是把手机上所有访问127.0.0.1:8888的TCP连接通过USB线转发到电脑本机的8888端口。注意这个转发是在adb服务层面完成的adb服务跑在电脑上数据经过USB物理通道完全不经过手机WiFi网卡也不经过局域网。所以整个链路就是App - 127.0.0.1:8888手机侧 - adb reverse转发 - USB线缆 - adbd进程 - Charles监听端口8888电脑侧这个机制在Android 5.0以上的所有版本都支持也不需要root权限唯一的前提是手机开USB调试并且授权了这台电脑的调试指纹。所以从技术门槛来说比WiFi代理更容易搞定因为不用在手机上敲IP、不用反复确认是否连上同一个WiFi。2.3 为什么USB方式比WiFi稳定WiFi代理不稳定大多数情况下不是Charles的问题而是数据链路的问题。手机走WiFi发出的每个请求都经过无线AP再由AP转发到电脑网卡。这中间只要AP有信号波动、信道干扰、漫游切换TCP连接就会中断或者超时。而USB线是点对点的物理链路不存在无线干扰问题单位时间内的吞吐量稳定得多。另外一个痛点Windows用户应该深有体会电脑开热点给手机用的时候Windows自带的移动热点功能偶尔会抽风连上之后手机上不了网或者DNS解析卡死。USB方式完全绕开这个环节手机自身的移动网络或者WiFi该上网还正常上网只是代理流量走了USB线两件事互不干扰。这在排查SDK问题时是巨大的效率提升因为你可以一边开着手机流量跑业务一边在电脑上看每个请求的具体内容和时序不会因为代理导致整个网络环境变动。3. Windows环境准备与Charles基础设置3.1 按部就班装好Charles并注册Charles官方下载地址是charlesproxy.com当前主版本是4.x支持Windows 10和Windows 11。安装包很小按默认路径安装就行装完桌面上出现Charles图标第一次启动会让你填注册码。网上流传的注册码很多都失效了与其去找注册机不如用最朴素的思路官方给试用期每次启动会有30秒的等待窗口——但只需要在弹窗出现后手动关掉功能上只是限制会话保存时长调试抓包完全不影响。如果你需要长期使用请支持正版个人许可大概几百块人民币对日常开发来说不算贵。这里多说一句不要用什么Charles注册码生成器之类的东西来路不明的工具往往掺杂了不干净的东西装进电脑得不偿失。3.2 打开SSL Proxying并配置端口Charles安装之后默认就开了HTTP代理监听端口是8888在菜单栏Proxy - Proxy Settings里能看到。SSL Proxying默认是关闭的必须手动打开才能解密HTTPS流量。这一步经常有人忘记结果抓到的全是加密的乱码或者直接看不到App发出的HTTPS请求。配置方法如下Proxy - SSL Proxying Settings 勾选 Enable SSL Proxying 点击 AddHost填 *Port填 *Host和Port填通配符的意思是无论请求目标是哪个域名、哪个端口都尝试解密。这种配置在开发调试阶段最省事。要是只关心特定接口也可以只填域名比如api.example.com端口443但建议一开始全放开避免漏看。3.3 在Windows上安装Charles根证书Charles的解密能力依赖它自己的根证书。Charles首次启动时会自动生成一个CA证书你需要把它安装到Windows的“受信任的根证书颁发机构”否则你的Windows本地程序比如某些桌面应用走的代理会报证书错误浏览器也可能拦截。操作路径是Help - SSL Proxying - Install Charles Root Certificate点击之后会弹出证书安装向导注意安装位置必须选“本地计算机”存储位置选“受信任的根证书颁发机构”。装完之后在浏览器里访问一下任意HTTPS网站地址栏没有飘红就说明Windows侧信任没问题。Windows上还有个容易忽略的细节Charles根证书是有有效期的默认大概十年。过期之后需要重新安装否则部分应用会突然开始拒绝连接排查半天最后发现是证书过期很气但也没办法先把时间维度查一遍。4. USB抓包实操全流程从手机设置到看包4.1 手机端开启USB调试不同品牌的手机开启USB调试的入口不太一样但大逻辑一致设置 - 关于手机 - 连点7次“版本号” - 进入开发者模式 设置 - 开发者选项 - 打开USB调试华为、小米、OPPO、vivo这些主流机型有的还需要在开发者选项里额外打开“USB安装”和“USB调试安全设置”。第一次插USB线时手机会弹窗询问“是否允许USB调试”勾选“始终允许”然后点确定。注意有一个坑部分手机在插上USB线后会默认进入“仅充电”模式这样adb设备列表里看不到设备。解决办法是下拉通知栏把USB连接模式改成“传输文件(MTP)”或者“传输照片(PTP)”只要不是纯充电就行。这个我踩过不止一次每次换一台新手机插上去adb devices半天没反应结果就是USB模式没切对。4.2 让电脑识别到手机Windows上安装adb工具最简单的方式是下载Android SDK Platform-Tools解压之后把platform-tools目录加入PATH或者直接在命令行里切到该目录操作。验证手机连接状态的命令是adb devices正常情况下输出List of devices attached 1234567890abcdef device如果显示的是unauthorized说明手机端的授权弹窗没有点允许如果显示offline大概率是USB线质量差或者端口供电不足换一根原装线或者换一个USB口试一下。这里强烈建议优先用电脑主机后面板的USB口前置面板或者扩展坞的USB口在传输稳定性上确实要差一些。4.3 执行adb reverse并验证链路确认设备在线之后执行adb reverse tcp:8888 tcp:8888没有任何输出就代表成功。想确认转发是否生效可以在手机上看一看。但更直观的验证方式是电脑上先开一个本地HTTP服务比如Python临时服务python -m http.server 8888然后在手机浏览器里访问http://127.0.0.1:8888如果能看到Python服务返回的目录列表就说明整条USB转发链路是通的。这个验证法我每次都做可以彻底排除“以为是Charles的问题其实是转发没生效”的迷惑。验证完把Python临时服务停掉接着在Charles的Proxy Settings里确认勾选了HTTP代理的Enable Transparent HTTP Proxying因为Charles默认开着透明代理手机流量到达8888端口后Charles才会真正介入处理。4.4 手机安装Charles根证书并设置为系统信任USB通道上的流量走到了Charles但Android应用是否信任Charles证书是决定能不能看到明文的关键。Android 7.0API 24开始系统默认不再信任用户CA证书只信任系统CA证书。这意味着你从手机浏览器下载安装的Charles证书只对配置了“信任用户证书”的应用有效。针对这个问题分两条路方案A如果你的应用本身允许用户证书大多数debug包默认信任直接通过手机浏览器访问http://chls.pro/ssl下载charles-proxy-ssl-proxying-certificate.pem然后到系统设置里安装。路径一般是设置 - 安全 - 更多安全设置 - 加密与凭据 - 安装证书 - CA证书安装完成后在“信任的凭据”里的“用户”标签页能看到Charles证书。方案B应用不信任用户证书时这个最典型的是release包或者某些加固过的SDK只认系统证书。处理办法是把Charles证书导入到Android系统CA目录。具体操作需要手机能解锁system分区或者使用Magisk模块方式。这一步需要root或者刷机权限属于进阶玩法日常纯开发调试并不一定需要。我的经验是对于调试阶段的应用可以在AndroidManifest里显式声明networkSecurityConfig允许信任用户证书这是最省事的方式。如果产品走得是正规release流程那配合测试包单独处理即可没必要在实际场景中纠结系统证书的问题。4.5 开始抓包并解析内容全部配置完毕Charles界面里就能看到源源不断的请求。按请求列表从上到下依次看每个条目可以展开看Headers、JSON Body、Timing。常用操作有几个Filter栏输入域名或关键词快速过滤 双击任意请求查看完整请求/响应体 右键某个请求Save Response保存响应内容手机上的App发出的请求大部分是JSON格式Charles可以格式化显示中文也不会乱码比在服务器日志那边翻半天方便多了。还有一点要强调USB方式并不能让App自己把请求指向127.0.0.1:8888它依赖的是网络代理配置。所以应用内请求如果走的是OkHttp默认配置它会自动读取系统代理设置。问题是Android系统代理设置的是WiFi的HTTP代理USB adb reverse完全绕开了系统代理配置——应用不知道自己走的是代理它认为自己在直连127.0.0.1:8888。这就好理解了大多数App在代码里写死了直连或者用了自定义的OkHttpClient没有调用proxy设置如果你关了Charles或者没有执行adb reverse应用一直连不上127.0.0.1:8888表现是网络请求直接超时失败。这个行为正好能用来反向确认转发是否生效——如果断掉转发后应用网络马上出错说明转发链路之前是通的。5. 常见报错与排查技巧实录5.1 手机死活连不上电脑的adb插上USB线adb devices里什么都看不到。这个问题的概率在Windows上偏高主要原因是Windows的通用ADB驱动不识别某些手机。解决办法下载手机品牌官方的USB驱动或者从设备管理器里手动更新驱动Windows 10以上系统一般能自动匹配但一些冷门品牌的手机没有内置驱动需要去官网找。另外手机锁屏状态下可能不会正常连接adb先解锁屏幕再插线。有的手机还有“USB调试”和“仅充电模式下允许USB调试”这两个开关都要打开。5.2 执行adb reverse报错报错信息大概是error: device not found或者more than one device。前者是设备没在线后者是连了多台手机需要在命令里指定序列号adb -s 1234567890abcdef reverse tcp:8888 tcp:8888还有一种特殊情况一些定制ROM在系统层面对adb reverse做了限制比如部分老版本的MIUI或者Flyme会遇到reverse执行成功但流量不通的情况。建议换设备或者升级系统版本再试这个问题跟应用本身没关系。5.3 Charles上能看到请求但内容全是乱码能看到请求条目说明链路是通的但内容不可读。原因基本就两个一是SSL Proxying没开抓到的只是TCP握手和加密数据二是手机的Charles证书没有成功安装到用户或系统信任区。先检查SSL Proxying设置再看手机设置里的证书列表两个都对上了但还乱码重启一下Charles和手机连接。5.4 部分App完全不走代理抓不到包这种App多半是做了网络安全策略或者代码里通过NetworkSecurityPolicy.isCleartextTrafficPermitted()限制了HTTPS代理。解法只能从代码层面入手把networkSecurityConfig的trust-anchors里加上user证书具体字符如下network-security-config base-config cleartextTrafficPermittedtrue trust-anchors certificates srcuser / /trust-anchors /base-config /network-security-config放在App的res/xml目录下然后在AndroidManifest的application标签里引用android:networkSecurityConfigxml/network_security_config。如果是已经上线的release包只能通过修改服务器白名单或者抓包机的方式来处理。5.5 Windows防火墙拦截了Charles代理Charles启动后第一次作为代理服务接收流量时Windows防火墙经常会弹窗提示是否允许。如果不小心点了“取消”之后所有到8888端口的流量都会被防火墙拦掉表现为Charles界面里什么请求都没有。处理路径控制面板 - Windows Defender防火墙 - 允许应用通过防火墙 找到Charles - 勾选专用和公用 如果列表里没有手动添加Charles.exe6. 进阶把USB抓包扩展到其他场景6.1 抓微信小程序或H5页面的请求微信开发者工具调试小程序时可以直接在工具里设置代理。但如果你想抓手机上运行的微信小程序USB模式同样适用。场景是微信本身会遵循系统代理但Android 7限制用户证书信任而微信属于比较严格的一类默认不信任用户CA证书。有两种主流解决思路思路一手机root后把Charles证书移到系统证书目录 思路二使用LSPosed加JustTrustMe模块绕过证书校验这两个方案都有一定门槛不适合普通开发用户。如果是自己的微信小程序在调试阶段更好的方式是直接用微信开发者工具内置的抓包面板没必要动真机证书。而如果是排查线上小程序的接口问题那确实只能靠上述方案。6.2 同时抓多个设备adb reverse支持多个设备并行每个设备执行一次reverse命令指向同一个8888端口就行。实际用下来Charles能同时显示多台设备的请求每条请求的Source IP能区分来源。但要注意多个设备同时跑的时候Charles界面的请求会混在一起建议打开Filter或者使用Charles的Recording Settings按设备维度做一层过滤。6.3 抓HTTPS/2的流量Charles 4.x默认支持HTTP/2的解码不用额外配置。部分新版OkHttp默认开启HTTP/2这在USB抓包时完全透明直接看请求头里的HTTP/2.0标记即可。唯一注意点是老版本Charles 3.x对HTTP/2支持不好建议统一用4.x。7. 实操心得USB抓包模式的使用习惯我个人在实际项目中已经默认把USB模式当作首选抓包方式WiFi代理反而变成备用方案了。原因很简单稳定干净不依赖办公室的网络环境。加上现在移动端开发越来越频繁地需要看第三方SDK到底发了什么请求、参数怎么拼的USB模式可以让我在电脑屏幕前从容地一条一条核对不用弯腰看手机屏幕上那一小条日志。有几个使用习惯建议你养出来第一每次插上手机准备抓包先跑一遍adb reverse不要想着上一次配过就一直有效。手机重启、adb服务重启、USB线拔插都会导致reverse规则失效。把它当成每次抓包的固定前置动作。第二抓到问题包之后及时在Charles里导出会话文件或者保存响应内容。会话文件可以归档复盘也方便发给同事分析。文件菜单下File - Export Session可以导出为.chls文件。第三不要把Charles跟Windows上的系统代理混在一起。Charles装完后它有可能会自动修改系统代理设置让你电脑上浏览器的流量也走它代理。如果你不想让电脑全局流量经过Charles记得在Proxy Settings里取消勾选Windows Proxy。这个设置项位置很显眼但很多人忽略了。第四真正排查线上问题的时候建议同时把Charles的请求时间戳和手机端logcat日志对照看因为有些问题表面上是“请求发失败了”实际上可能是发起时间、重试策略、缓存策略交织在一起。抓包只能看网络层配合应用日志才能还原完整链路。USB模式下Charles的Session列表里会有大量由系统组件发出的请求有的应用还会在启动时连一些统计域名这些噪音请求务必学会用Filter栏过滤。我通常的做法是先什么都不过滤看两分钟搞清楚流量结构然后迅速锁定目标域名再针对性地过滤。这样既有全局感又不会淹死在噪音里。这个技巧最终帮助我在客户现场用一根USB线不依赖客户公司的任何网络策略半小时内定位到了SDK因为HTTP响应头解析异常导致的内存问题。如果不是USB通道抓包WiFi方案在那种严格隔离的办公网络里大概率连握手都完成不了。Windows上的USB抓包模式确实值得每一个Android开发者在工具列表里常驻。