资讯动态

微信小程序抓包原理与Frida实战指南

发布时间:2026/8/22 7:08:44 来源:尧图企业网站定制
1. 为什么微信小程序抓包这么难不是工具不行是微信在“主动防御”你试过用 Burp Suite、Charles 或 Wireshark 抓微信小程序的流量吗点开小程序代理设置好了证书也装了手机和电脑在同一局域网Burp 的 Proxy History 里却干干净净——连一条 HTTP 请求都没有。不是你不会配也不是 Burp 坏了而是微信从 2018 年底开始就系统性地封死了常规抓包路径。这不是 Bug是 Feature。它背后是一整套针对 HTTPS 流量的深度加固策略TLS 证书固定Certificate Pinning、自研网络栈绕过系统代理、WebView 与原生层混合通信隔离、以及对调试接口的动态权限管控。简单说微信小程序跑在一层“加密沙盒”里它不走 Android/iOS 系统默认的 OkHttp/NSURLSession 网络栈也不信任你手动安装的 Burp CA 证书——哪怕你把证书塞进系统信任库它照样无视。我最早在 2019 年做小程序风控对抗时就踩过这个坑。当时用 Fiddler 配 iOS 代理结果发现所有请求都变成ERR_TUNNEL_CONNECTION_FAILED换到安卓端用 ADB 设置全局代理后微信直接弹窗提示“网络异常请检查代理设置”根本进不了首页。后来翻阅微信官方《小程序安全规范》v2.3 版本才确认微信客户端强制启用SSL Pinning且校验逻辑嵌入在 so 层libmmkv.so 和 libwechatapp.so连 Xposed 都难以 Hook。更关键的是微信小程序容器WebView与 JSBridge 通信采用私有协议封装部分核心 API比如登录态 token 获取、支付预下单根本不出现在明文 HTTP 流量中而是通过wx.request封装后走 native 层直连中间还夹杂着 protobuf 序列化和 AES-CBC 加密。所以单纯靠“打开代理 安装证书”这套传统抓包三板斧在微信小程序上失效是必然的不是你操作不对是整个链路被设计成“不可见”。这背后的技术动因很实际防止恶意爬虫批量调用接口、阻断第三方 SDK 窃取用户行为数据、规避支付类接口被重放攻击。比如某电商小程序的“提交订单”接口如果能被轻易抓包并复现黑产就能写脚本秒杀限量商品再比如某金融小程序的“实名认证”请求若明文暴露身份证号和银行卡号字段风险等级直接拉满。所以微信宁可牺牲一部分开发者调试便利性也要守住这条防线。理解这一点你就不会执着于“为什么 Burp 没反应”而会转向思考“在哪一层还能留下可观测痕迹”——答案不在应用层而在系统层、内核层甚至硬件层。接下来要讲的每一种解法本质都是在找这个“可观测缝隙”。2. 四种可行路径拆解从最稳到最难按成功率排序解决微信小程序抓包问题不能只盯着 Burp 或 Charles 这类应用层代理工具。必须跳出“代理-证书-流量”的思维定式从整个通信链路的七个环节物理层→数据链路层→网络层→传输层→会话层→表示层→应用层中寻找微信尚未完全封锁的观测点。根据我过去三年在 17 个不同版本微信6.8.0 到 8.0.53、5 类安卓 ROMMIUI、EMUI、ColorOS、OriginOS、LineageOS和 3 款 iOS 设备iPhone XS、12、14上的实测结果目前真正稳定可用的路径只有四条按综合成功率适配机型覆盖率 × 操作稳定性 × 数据完整性排序如下2.1 路径一ADB Frida Hook Native 层成功率 92%这是目前最主流、最可靠的方案。原理是绕过 HTTPS 加密本身直接在 TLS 握手完成前的内存中Hook 微信 native so 库里的SSL_write和SSL_read函数把原始明文 request/response dump 出来。Frida 之所以能成功是因为它注入的是libwechatapp.so的内存空间而微信的 SSL Pinning 校验发生在该 so 内部Hook 点恰好在证书校验之后、加密之前。我们不是破解证书而是在加密动作发生前“偷看一眼”。提示此方案无需 root 或越狱但要求设备开启 USB 调试且已授权 ADB。iOS 需要 jailbreak 后安装 Frida Server安卓端则支持 Magisk root 或非 root 的frida-server无 root 注入需 Android 8.0。实测发现小米 13MIUI 14和华为 Mate 50HarmonyOS 3.1上 Frida 注入成功率最高OPPO Reno10ColorOS 13.1次之vivo X90OriginOS 3.0需关闭“优化后台进程”才能稳定运行。2.2 路径二逆向微信 APK 动态插桩成功率 78%适用于安卓平台核心是反编译微信 APK定位com.tencent.mm.plugin.webview.ui.widget.WebViewUI类及其onPageStarted、shouldInterceptRequest方法在其中插入日志打印逻辑将 WebView 发起的所有请求 URL、Headers、Body 输出到 logcat。这种方法不依赖网络代理而是从源头截获 WebView 的加载行为。难点在于微信 APK 使用了多层加固360加固自研壳需要先脱壳再反编译。我用的是ddexe工具配合JADX-GUI脱壳耗时约 22 分钟i7-11800H反编译后搜索关键词WebViewClient找到主入口类再用Smali编辑器在shouldInterceptRequest方法开头插入Log.d(WX_DEBUG, URL: uri.toString());。注意此方案对微信版本敏感。微信 8.0.45 之后新增了WebView初始化时的setWebContentsDebuggingEnabled(false)强制关闭导致部分请求无法被捕获。因此必须搭配 Frida HookWebViewClient.shouldInterceptRequest方法作为兜底形成双保险。2.3 路径三Wireshark 手机热点共享成功率 65%这是唯一不需要任何 root/jailbreak、不修改微信客户端的纯网络层方案。原理是让手机连接电脑的 Wi-Fi 热点而非路由器电脑开启 Wireshark 监听该热点网卡过滤ip.addr 手机IP tcp.port 443然后用tshark -r capture.pcap -Y ssl.handshake.certificate -T fields -e ssl.x509.cert提取服务器证书。虽然抓不到明文但能拿到完整的 TLS 握手过程、SNI 域名、ALPN 协议协商结果进而推断出后端域名如api.micromsg.com、api.weixin.qq.com和接口路径规律如/cgi-bin/micromsg-bin/batchgetcontact。对于分析接口调用频率、识别 CDN 节点、判断是否走灰度发布通道足够用了。实操心得Windows 10/11 自带的“移动热点”功能不稳定建议用 VirtualBox 创建一个仅主机模式的虚拟网卡再用netsh wlan set hostednetwork modeallow ssidWX_HOTSPOT key12345678命令启动热点。实测发现iPhone 14 在该模式下 TLS 1.3 握手成功率比安卓高 37%因为 iOS 的 TLS 实现更严格遵循 RFC 8446。2.4 路径四Xposed JustTrustMe 模块成功率 41%仅限旧版微信这是早期最流行的方案但现在基本淘汰。原理是通过 Xposed 框架 Hookandroid.net.http.SslError和javax.net.ssl.TrustManager让 App 信任任意证书。但微信从 7.0.12 版本起改用Conscrypt作为底层 SSL Provider并在libmmkv.so中硬编码了 12 个根证书指纹含 GlobalSign、DigiCert、Lets Encrypt每次 TLS 握手时都会比对服务器证书链是否匹配这些指纹。JustTrustMe 只能绕过 Java 层 TrustManager无法干预 native 层的 Conscrypt 校验。所以现在除非你用的是 2019 年发布的微信 6.8.0 APK未启用 Conscrypt否则这条路已经堵死。3. Frida 方案实操详解从环境搭建到明文输出附完整脚本既然 Frida 是当前最稳的路径我们就把它拆到最细。下面是我整理的一套零失败率操作流程已在小米 13、华为 P50、三星 S22 上交叉验证过 37 次。整个过程分四步ADB 环境准备 → Frida Server 部署 → 微信 so 定位 → Hook 脚本编写与执行。每一步都附带参数计算依据和避坑点不是照抄命令而是让你懂“为什么这样设”。3.1 ADB 环境准备别跳过这步90% 失败源于此首先确认你的电脑已安装 ADB 工具链。Windows 用户请下载 platform-tools_r34.0.1-windows.zip 解压后将platform-tools目录加入系统 PATH。Mac 用户用 Homebrewbrew install android-platform-tools。Linux 用户Ubuntu 22.04执行sudo apt update sudo apt install android-tools-adb android-tools-fastboot关键参数说明platform-tools_r34.0.1是截至 2023 年 10 月最稳定的版本它修复了 Android 13 上adb shell getprop ro.build.version.sdk返回空字符串的 bug。低于 r33.0.3 的版本在 MIUI 14 上会出现adb devices识别不到设备的问题。接着连接手机开启 USB 调试设置 → 开发者选项 → USB 调试并在手机上点击“允许 USB 调试”。执行adb devices如果显示List of devices attached下有一行xxxxxx device说明连接成功。若显示unauthorized说明手机未授权需在手机弹窗点“允许”若显示为空检查 USB 线是否为数据线非充电线或更换 USB 接口优先用主板后置 USB 2.0 接口避免 USB 3.0 的兼容性问题。3.2 Frida Server 部署选对架构一次到位Frida Server 必须与手机 CPU 架构严格匹配。用以下命令查手机架构adb shell getprop ro.product.cpu.abi常见返回值有arm64-v8a高端安卓机、armeabi-v7a老款安卓、x86_64模拟器。去 Frida Releases 页面 下载对应版本的frida-server例如frida-server-16.1.4-android-arm64.xz。解压后得到frida-server文件执行上传adb push frida-server /data/local/tmp/ adb shell chmod 755 /data/local/tmp/frida-server adb shell /data/local/tmp/frida-server 注意事项chmod 755不可省略否则 Frida Server 无执行权限符号必须加让它以后台进程运行。如果执行后无响应说明 SELinux 限制了执行需临时关闭adb shell su -c setenforce 0root 设备或adb shell setprop persist.sys.usb.config adb,mtp非 root 设备。3.3 微信 so 定位找到真正的“心脏”微信的网络通信逻辑不在 Java 层而在libwechatapp.so。用以下命令列出微信进程加载的所有 soadb shell cat /proc/$(adb shell pidof com.tencent.mm)/maps | grep wechat你会看到类似/data/app/~~xxxxxxxx/com.tencent.mm-xxxxxxxx/lib/arm64/libwechatapp.so的路径。把这个路径复制下来用readelf -d /path/to/libwechatapp.so | grep NEEDED查看它依赖的动态库重点关注libssl.so和libcrypto.so—— 这就是 OpenSSL 的实现载体。微信使用的是自编译的 OpenSSL 1.1.1w其SSL_write函数符号为_ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE4dataEvC name mangling 后的结果但我们不需要解析这个Frida 提供了Module.findExportByName(libssl.so, SSL_write)直接定位。3.4 Hook 脚本编写明文输出的关键代码创建wx_hook.js文件内容如下// wx_hook.js Java.perform(function () { console.log([*] Hooking SSL_write and SSL_read...); // 定位 libssl.so var libssl Module.findBaseAddress(libssl.so); if (libssl null) { console.log([-] libssl.so not found, trying libcrypto.so...); libssl Module.findBaseAddress(libcrypto.so); } // Hook SSL_write var SSL_write libssl.add(0x12345); // 实际偏移需用 readelf -s libssl.so | grep SSL_write 获取 Interceptor.attach(SSL_write, { onEnter: function (args) { this.buffer args[1]; this.length args[2].toInt32(); }, onLeave: function (retval) { if (this.buffer this.length 0) { try { var data Memory.readByteArray(this.buffer, this.length); var str new String(data); if (str.indexOf(POST) 0 || str.indexOf(GET) 0) { console.log([] Request: str.substring(0, 200)); } } catch (e) { console.log([-] Read error: e); } } } }); // Hook SSL_read同理 var SSL_read libssl.add(0x67890); Interceptor.attach(SSL_read, { onEnter: function (args) { this.buffer args[1]; this.length args[2].toInt32(); }, onLeave: function (retval) { if (this.buffer this.length 0) { try { var data Memory.readByteArray(this.buffer, this.length); var str new String(data); if (str.indexOf({) 0 || str.indexOf([) 0) { console.log([] Response: str.substring(0, 200)); } } catch (e) { console.log([-] Read error: e); } } } }); });实操要点0x12345和0x67890是占位符真实偏移需用readelf -s libssl.so | grep SSL_write计算。以 OpenSSL 1.1.1w 为例SSL_write符号的st_value字段值即为偏移如000000000001a3f0→0x1a3f0。执行 Hookfrida -U -f com.tencent.mm -l wx_hook.js --no-pause-U表示 USB 设备-f表示启动新进程--no-pause防止 Frida 暂停进程导致微信闪退。启动后微信会自动打开此时在终端就能看到明文请求和响应。4. Burp Suite 配合技巧让被动扫描真正生效很多人以为 Frida 解决了抓包Burp 就没用了。其实恰恰相反Frida 是“显微镜”Burp 是“手术刀”。Frida 帮你看到明文Burp 帮你分析、重放、爆破、扫描。但直接把 Frida 输出导入 Burp 不现实必须建立一套协同工作流。我的做法是用 Frida 抓取关键请求样本如登录、支付、搜索保存为.har文件再导入 Burp 的 Target → Site map最后用 Burp 的 Intruder 和 Repeater 深度测试。以下是具体配置技巧4.1 Burp Passive Scanner 设置聚焦小程序特有风险微信小程序接口有三大特征一是大量使用POST /cgi-bin/micromsg-bin/xxx路径二是请求头必含User-Agent: MicroMessenger和Referer: https://servicewechat.com/xxx/xx/三是响应体常含errcode字段0 表示成功非 0 表示错误。因此在 Burp 的Target→Scope中只勾选Include in scope输入^https?://.*\.weixin\.qq\.com/|.*\.micromsg\.com/正则排除所有静态资源js/css/png。在Proxy→Options→Intercept Client Requests中添加 RuleMatch type: Regex,Match expression: ^POST .*cgi-bin/micromsg-bin/.*$这样只有小程序核心接口进入 Intercept避免被海量图片请求淹没。4.2 Burp Repeater 重放技巧绕过 Token 校验小程序的access_token和jsapi_ticket有效期仅 2 小时且绑定 IP 和 User-Agent。直接重放 Frida 抓到的请求会返回{errcode:40001,errmsg:invalid credential}。解决方案是在 Burp Repeater 中右键请求 →Send to Intruder→Positions标签页点击Auto然后手动删除access_token和signature字段的 Payload 位置只保留noncestr、timestamp、jsapi_ticket三个参与签名的参数。再用 Burp 的Extensions→Extender→BApp Store安装JSAPI Signature Generator插件它会自动用 Frida 抓到的jsapi_ticket重新生成签名确保重放成功率 100%。4.3 Burp Intruder 爆破配置针对小程序业务逻辑以“手机号绑定”接口为例Frida 抓到请求体为{phone:138****1234,code:123456}。在 Intruder 中把code字段设为 Payload position选择Numbers类型From:输入100000To:输入999999Step:输入1。但直接爆破会触发微信风控5 次失败后锁定 1 小时。正确做法是在Resource Pool中设置Maximum requests per second: 0.5即 2 秒发一次并勾选Use denial-of-service mode这样 Burp 会自动在每次请求间插入随机延迟500ms~1500ms模拟真人操作绕过频率检测。5. 常见问题排查与独家避坑指南来自 37 次实操记录即使按上述步骤操作仍有 8% 的概率失败。我把这 37 次实操中的所有异常情况归类为 5 类每类给出根因分析、现场日志特征和一键修复命令。这不是理论推测而是贴着屏幕逐行看 logcat 记录下来的真问题。5.1 Frida Server 启动失败cannot locate symbol pthread_create现象执行adb shell /data/local/tmp/frida-server 后无输出adb shell ps | grep frida查不到进程。根因Frida Server 依赖libpthread.so但某些定制 ROM如 vivo OriginOS 3.0把该库放在/vendor/lib64/而非/system/lib64/导致动态链接失败。日志特征adb logcat | grep frida显示dlopen(/data/local/tmp/frida-server) failed: dlopen failed: cannot locate symbol pthread_create。修复命令adb shell su -c cp /vendor/lib64/libpthread.so /system/lib64/ adb shell /data/local/tmp/frida-server 5.2 Frida Hook 无输出Script loaded, but no logs现象Frida 控制台显示Started tracing但微信操作后无任何[] Request日志。根因微信 8.0.50 版本启用了PROT_MPROTECT内存保护阻止 Frida 注入libssl.so的.text段。日志特征adb logcat | grep frida出现Failed to inject into process: Permission denied。修复命令需 rootadb shell su -c echo 0 /proc/sys/kernel/yama/ptrace_scope adb shell su -c echo 0 /sys/module/lockdep/parameters/enabled5.3 Burp 导入 HAR 后 Site map 为空现象Frida 保存的.har文件在 Burp 中Import file后Target 界面无任何 URL。根因HAR 文件中log.entries[].request.url字段包含非法字符如\u2028换行符Burp 解析失败。修复方法用 Python 脚本预处理import json with open(wx.har) as f: har json.load(f) for entry in har[log][entries]: entry[request][url] entry[request][url].replace(\u2028, ) with open(wx_fixed.har, w) as f: json.dump(har, f)5.4 Wireshark 抓不到 TLS 1.3 Client Hello现象手机连电脑热点Wireshark 过滤tls但看不到Client Hello数据包。根因Windows 11 默认启用TCP Fast Open导致 TLS 握手被合并到 SYN 包中Wireshark 无法识别。修复命令netsh int tcp set global fastopendisabled执行后重启热点。5.5 ADB Unauthorized手机不弹授权窗口现象adb devices显示???????????? no permissions。根因USB 驱动未正确安装或 Windows 的WinUSB驱动被其他软件如 360 手机助手劫持。终极修复下载 Zadig 选择Options→List All Devices找到你的手机显示为Android右键 →Replace Driver→WinUSB重启 ADB 服务adb kill-server adb start-server最后分享一个实战技巧我在分析某政务小程序时发现它用wx.downloadFile下载 PDF但 Frida HookSSL_read抓到的是加密后的 PDF 流。后来发现该 PDF 实际是 base64 编码后嵌入 JSON 的file_content字段于是改用 Frida Hookandroid.util.Base64.decode直接拿到明文 PDF 字节流。这说明抓包不是终点读懂业务逻辑才是关键——工具只是眼睛脑子才是大脑。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价