# 潮谷街 App 抓包逆向分析文档 > 记录日期:2026/07/03 ## 1. 目标信息 - **App**:潮谷街(吃谷商城) - **包名**:`com.chaogujie.cgjec` - **版本**:1.0.15(versionCode 17,minSdk 21,targetSdk 34) - **技术栈**:**Flutter**(`libflutter.so` + `libapp.so`,14MB Dart AOT 产物) - **测试设备**:Pixel 5(redfin)/ Android 11 / arm64-v8a,已 root(Magisk + LSPosed) - **抓包工具**:Reqable - **反爬 / 安全措施**(apk native 库暴露): - `libturingmfa.so` —— 腾讯天御 MFA 风控(设备指纹 / 防注入 / 防 root) - `libzxprotect.so` —— 加固 / 保护壳 - `libYTCommonLiveness.so` / `libkyctoolkit.so` —— 活体检测 / KYC 实名 - `libImSDK.so` / `libliteavsdk.so` —— 腾讯 IM + 直播 - `libBugly_Native.so` —— 崩溃上报 ## 2. 分析过程 ### 现象 用 Reqable 抓包时,潮谷街一打开抓包就提示「网络请求失败,请稍后重试」,Reqable 里对应请求状态为 `Aborted`,详情显示 **「客户端 SSL 握手失败」**。同一环境下另一个测试 App 可以正常抓包。 已尝试但无效的操作:安装并勾选 JustTrustMePro(LSPosed 模块)、重启手机——抓包一开 App 就网络异常。 ### 定位技术栈 拉取 apk 后扫描 native 库,锁定关键证据: ```bash unzip -l 潮谷街_1.0.15.apk | grep -iE "lib/arm64-v8a/" # lib/arm64-v8a/libflutter.so ← Flutter 引擎 # lib/arm64-v8a/libapp.so (14MB) ← Flutter 业务代码(Dart AOT) # lib/arm64-v8a/libdart_native_imsdk.so ``` **确认是 Flutter 应用** —— 这是整个排查的分水岭。 ### 逐层验证证书链 1. 检查用户 CA store:`/data/misc/user/0/cacerts-added/` —— **空**。 2. 检查系统 CA store:`mount | grep cacerts` —— 已被 Magisk 以 tmpfs 挂载(装了证书模块)。 3. 检查设备已启用 Magisk 模块:`movecert`、`reqable-magisk`、`zygisk_shamiko`、`zygisk_lsposed`、`zygiskfrida`。 4. 解析系统 CA 里的 Reqable 证书 `aa381f31.0`: ``` CN = Reqable CA (Dec 18, 2025) 有效期 = 2025-12-18 ~ 2033-05-31(有效) SHA1 = 7C:E8:1E:44:8F:77:88:21:36:FC:64:6E:F7:CE:EB:97:CF:03:EA:43 ``` 5. 与 PC 端当前 CA(`AppData/Roaming/Reqable/certificate/reqable-root.crt`)指纹对比 —— **完全一致**。 结论:证书装进了系统 CA、指纹匹配、在有效期内,普通 App 也能抓 HTTPS,证书链本身没问题。 ## 3. 逆向思路 关键认知:**Flutter 的网络请求走它自己打包在 `libflutter.so` 里的 BoringSSL,TLS 握手与证书校验全在 native 层完成,完全不经过 Java 层的 `javax.net.ssl` / OkHttp / WebView。** 由此推导: - 任何 **Java 层的 unpinning 插件**(JustTrustMe / JustTrustMePro / LSPosed 证书类模块)对 Flutter **一律无效** —— 这就解释了为什么怎么勾选、重启都不生效。 - Flutter(Dart `HttpClient`)在 Android 上只信任**系统 CA store**,不读用户证书。所以证书必须装到系统级。 中途一度怀疑是 Flutter 的额外 native pinning(需要 Frida hook `libflutter.so`),并已排查设备的 Frida 环境(客户端 17.9.1、`zygiskfrida` 模块在位)。但最终发现真正原因更简单,见踩坑记录。 ## 4. 解决方案 **升级 Reqable 证书 Magisk 模块**:旧版(0.1)→ 新版(1.2)。升级后 Flutter 立刻能读到系统 CA 里的 Reqable 证书,抓包恢复正常。 抓到的接口域名: | 域名 | 用途 | |---|---| | `cgj.chaogujieapp.com` | 主 API | | `cgjsj.chaogujieapp.com` | 数据 / 实时接口 | | `5fdc92.chaogujieapp.com` | 疑似 CDN / 资源 | | `license.vod2.myqcloud.com` | 腾讯云点播 license(直播) | | `android.bugly.qq.com` | 崩溃上报(可忽略) | ## 5. 踩坑记录 1. **「指纹一致 + mount 已挂载」≠「Flutter 能读到」** 本次最大的坑:旧版证书模块(0.1)在 Android 11 上虽然把 Reqable CA 挂进了系统 CA store(`mount` 看得到、指纹也对得上),但那种挂载方式对 Flutter 的 BoringSSL 读取路径**不生效**。升级到 1.2 版本后,模块修正了挂载方式(大概率适配了 Android 10+ 的 CA store 读取路径 / 挂载时机),Flutter 才认。排查时不能只看「证书在不在、指纹对不对」,还要确认**证书模块版本够不够新**。 2. **JustTrustMePro 对 Flutter 无效不是配置问题** 反复检查 LSPosed 作用域、重启,都改变不了结果——因为方案本身打不中 Flutter 的 native TLS,不是勾选姿势的问题。 3. **潮谷街其实没有额外 native pinning** 走的是 Flutter 默认「读系统 CA」校验。所以最终没用上 Frida —— 中途「怀疑 pinning、准备 hook `libflutter.so`」的方向偏保守了。 ## 6. 举一反三 **Flutter App 抓包失败(客户端 SSL 握手失败)标准排查顺序:** 1. 先判断是不是 Flutter:`unzip -l xxx.apk | grep libflutter.so`。是 Flutter,就**跳过所有 Java 层方案**(JustTrustMe 系列别再试)。 2. 确认证书装进**系统 CA store**(不是用户 CA)—— Flutter 只读系统 CA。 3. 确认**证书模块版本够新**(本次的坑)——「已挂载 + 指纹一致」不代表 Flutter 读得到。 4. 确认走 **VPN / Tun 透明代理**模式 —— Flutter 默认不读系统 WiFi 代理,普通代理模式流量根本不过 Reqable。 5. 以上全对仍失败,才是真 native pinning,此时唯一可靠手段:**Frida hook `libflutter.so` 的 BoringSSL 证书校验函数**(参考 NVISO 的 disable-flutter-tls-verification 脚本);若担心风控检测(如天御 `libturingmfa`),配合 `zygisk_shamiko` + Zygisk DenyList 隐藏。 **通用结论**:unpinning 方案能不能生效,取决于它作用的层次是否覆盖目标 App 的网络栈——Java 层框架管不到 native 层的 BoringSSL。