跳转到正文

App 数据爬取与协议分析

Web 端的数据在 HTML 或 Ajax 接口里,App 端的数据则全部走接口——没有页面源码可看,唯一的入口是网络流量。因此 App 爬取的第一步永远是抓包,而不是写代码。

⚖️ 合规边界(务必先读)

App 逆向的法律与合规风险显著高于 Web 爬取。以下行为超出正常技术研究范畴:

  • 破解加固、脱壳、绕过 SSL Pinning 用于第三方商业 App —— 可能违反《著作权法》对技术保护措施的规定,以及 App 的用户协议
  • 批量获取 App 内的用户信息 —— App 内数据多为登录后可见,抓取几乎必然触及《个人信息保护法》
  • 规避付费或权限限制

正当场景:分析自己开发或所属组织的 App、有明确书面授权的安全测试、以学习协议机制为目的的原理研究。本篇按技术原理组织,不针对任何特定 App。

一、三条技术路线

路线做法效率难度稳定性
接口抓包抓 HTTP(S) 流量,还原接口后用代码直接请求最高受签名/加固影响
UI 自动化驱动真机或模拟器操作界面,抓取屏幕内容最低最高,几乎不会被反制
协议逆向反编译 App,还原签名/加密算法最高算法更新即失效

决策顺序:先抓包看接口是否可直接复用 → 参数有签名则评估逆向成本 → 逆向成本过高或数据量小则退回 UI 自动化。


二、HTTPS 抓包的原理

2.1 中间人代理的工作方式

抓 HTTP 明文很简单,难点全在 HTTPS。抓包工具的本质是受信任的中间人(MITM)

text
App  ──TLS 握手──>  代理(用自签证书冒充服务端)
                      │  代理作为客户端与真实服务端建立第二条 TLS 连接
                      └──TLS 握手──>  真实服务端

代理持有两条独立的加密连接,因此能看到明文。成立的前提是 App 信任代理的自签 CA 证书——整个抓包体系的所有障碍都源于此。

2.2 证书信任的三道门槛

门槛表现处理
未安装 CA 证书所有 HTTPS 请求失败安装代理工具的 CA 证书到设备
Android 7+ 用户证书不受信证书装了但仍失败需将证书装入系统证书目录(需 root),或 App 声明了 networkSecurityConfig 才信任用户证书
SSL Pinning(证书固定)单个 App 失败,其他 App 正常见 2.4

💡 Android 7 是关键分水岭

Android 7.0 起,App 默认只信任系统证书,用户手动安装的证书不再自动生效。这是「证书明明装了却抓不到包」最常见的原因。

可行方案:使用 root 设备将证书写入系统证书区、使用 Android 7 以下的模拟器、或在自有 App 中通过 network_security_config.xml 显式信任用户证书。

2.3 工具对比

工具特点适用
Charles图形界面友好,断点改包方便交互式探索、手动分析
mitmproxy命令行 + Python 脚本化,可编程自动化采集,本篇重点
FiddlerWindows 生态成熟Windows 用户
Wireshark抓的是链路层原始包,能看非 HTTP 协议私有 TCP 协议分析

mitmproxy 的三种运行形态mitmproxy(终端交互界面)、mitmweb(浏览器界面)、mitmdump(无界面 + 脚本,用于自动化)

python
# addon.py:mitmdump 的脚本接口,可直接把流量落库
import json

def response(flow):
    """每个响应都会回调,在这里筛选并处理目标接口。"""
    if "/api/list" not in flow.request.pretty_url:
        return

    data = json.loads(flow.response.get_text())
    for item in data.get("items", []):
        save_to_db(item)          # 边抓边入库,无需还原签名算法

def request(flow):
    """也可以改写请求,例如统一注入调试参数。"""
    flow.request.headers["X-Debug"] = "1"
sh
mitmdump -s addon.py -p 8080

💡 mitmdump 的战术价值

当接口签名逆向成本过高时,mitmdump + UI 自动化 是一个被低估的组合:让自动化脚本驱动 App 正常翻页(签名由 App 自己算),mitmdump 在旁边静默截获所有响应并入库。

完全不需要理解加密算法,代价是速度受限于 App 的真实操作节奏。

2.4 SSL Pinning

App 在代码里内置了服务端证书或公钥的指纹,握手时主动校验对方证书是否与内置值一致,代理的自签证书因此被拒绝。

实现层次说明
Java 层OkHttpCertificatePinnerTrustManager 自定义校验
Native 层.so 里用 OpenSSL/BoringSSL 校验,隐蔽性更高
双向认证服务端还要校验客户端证书,需从 App 中提取客户端证书

技术上的处理方式是用 Frida 在运行时 Hook 校验函数使其恒返回通过,或用 objection 的自动化脚本。这属于绕过 App 的安全机制,仅应在自有 App 或授权测试中使用。

若无授权,遇到 Pinning 的正确响应是改走 UI 自动化路线——它不触碰任何安全机制。


三、UI 自动化

不解析协议,直接驱动界面操作并读取屏幕上的内容。最笨但最稳:不受签名、加密、Pinning 影响,因为你走的就是真实用户路径。

3.1 方案对比

方案原理特点
Appium基于 WebDriver 协议,驱动 UIAutomator2(Android)/XCUITest(iOS)跨平台、生态成熟、需元素定位
Airtest + Poco图像识别 + UI 层级树对无法定位的元素(游戏、Canvas)有优势
uiautomator2直接对接 Android UIAutomator轻量,纯 Android,API 简洁
adb 命令input tap / shell最底层,适合简单固定操作

⚠️ Appium 的 driver 需单独安装

Appium 2.x 起,driver 与 plugin 从主程序中拆分,安装 Appium Server 后必须再单独装驱动(如 appium driver install uiautomator2),否则连接设备时会直接报找不到 driver。网上大量旧教程沿用 1.x 的一体化写法,不能直接照搬。

3.2 核心操作模式

python
# 以 uiautomator2 为例,展示 UI 自动化的通用范式
import uiautomator2 as u2

d = u2.connect()                       # 连接设备(adb 已识别)

d(text="搜索").click()                  # 按文本定位
d(resourceId="com.example:id/input").set_text("关键词")
d.press("enter")

d.xpath('//*[@resource-id="list"]').wait(timeout=10)    # 显式等待

# 滚动加载:UI 自动化的数据获取核心是"边滚动边采集"
seen = set()
for _ in range(50):
    for el in d.xpath('//*[@resource-id="item_title"]').all():
        if el.text not in seen:
            seen.add(el.text)
    d.swipe_ext("up", scale=0.8)       # 上滑加载更多

三个必须处理的工程问题

  1. 去重:滚动过程中同一元素会被反复读取,必须用业务主键去重。
  2. 终止判断:连续 N 次滚动都没有新增数据即视为到底,不能靠固定次数。
  3. 异常恢复:弹窗、广告、网络错误页会打断流程,需要在每轮循环前检查并处理当前界面状态。

3.3 与抓包组合使用

UI 自动化最强的用法不是读屏幕,而是只负责触发请求,数据由抓包层截获

text
Airtest/Appium 驱动滚动  →  App 自己发起带签名的请求  →  mitmdump 截获 JSON  →  入库

这样既避开了签名逆向,又拿到了结构化的接口数据(而非从屏幕文本还原),是很多场景下性价比最高的方案。


四、协议逆向的技术路线

数据量大到 UI 自动化撑不住、且有正当授权时,才进入这一步。

4.1 工具链

阶段工具作用
查看资源与结构apktool解包 APK,得到资源和 smali
反编译 Javajadx(开源,首选)、JEB(商业)把 dex 还原成近似 Java 源码
分析 native 层IDA Pro、Ghidra(开源)反汇编 .so 文件
动态分析Frida、objection运行时 Hook 函数、打印参数与返回值
网络层mitmproxy、Wireshark确认逆向结果与真实流量一致

4.2 静态分析的定位方法

JS 逆向 的思路完全一致——先定位,再理解

  1. 抓包确定目标参数名(如 sign);
  2. jadx 打开 APK,全局搜索该参数名的字符串
  3. 找到拼装请求的位置,回溯签名函数;
  4. 若签名函数是 native 方法(声明带 native 关键字),说明实现在 .so 里,需转入 native 分析。

💡 加固会让静态分析直接失效

主流商业 App 普遍使用加固(壳)。表现为 jadx 打开后看不到业务代码,只有壳的加载器。

此时静态分析基本无效,只能转向动态分析——因为代码运行时必然要在内存中还原。这也是 Frida 成为主流工具的原因。

4.3 动态分析:Frida 的核心价值

Frida 在进程运行时注入 JS 引擎,可以 Hook 任意函数,打印其入参、返回值和调用栈。它跳过了「读懂代码」这一步,直接观察实际行为。

javascript
// Frida 脚本的通用范式:Hook Java 层方法,观察输入输出
Java.perform(function () {
  const Target = Java.use("com.example.security.SignUtil");

  Target.sign.overload("java.lang.String").implementation = function (input) {
    const result = this.sign(input);          // 调用原方法
    console.log("[sign] 入参:", input);
    console.log("[sign] 返回:", result);
    return result;
  };
});

关键认知:Hook 的目标不一定是「破解」,更多时候是观察——搞清楚签名函数到底接收了什么格式的输入,往往比读懂算法本身更重要。多数逆向失败不是算法错了,而是入参拼接顺序错了

4.4 RPC 模拟执行:不还原算法也能调用

算法在 native 层且复杂度极高时,还有一条捷径:不还原它,而是让 App 自己算

text
Python 爬虫  ──HTTP──>  运行在设备上的 RPC 服务  ──调用──>  App 内的签名函数

             <────────────  返回签名结果  ────────────────────┘

实现方式有两种:Frida-RPC(用 Frida 把 App 内的函数暴露成可远程调用的接口)或 AndServer 类方案(在设备上跑一个 HTTP 服务,内部调用 App 的类方法)。

这与 JS 逆向 里的「Node RPC 服务」是完全相同的思想:脱离环境的成本过高时,就把环境本身变成一台可调用的服务器。

代价:需要设备常驻运行、并发能力受限于设备性能、设备故障即服务中断。


五、路线选择速查

场景建议路线
接口无签名,抓包即可复现直接用 httpx 请求接口
接口有签名,数据量大且有授权协议逆向 → Python 复现或 RPC
有 SSL Pinning,无授权UI 自动化
App 已加固动态分析(Frida),或直接 UI 自动化
数据量小(几千条以内)UI 自动化,不值得逆向
需要结构化数据但不想逆向UI 自动化驱动 + mitmdump 截获(推荐组合)

六、与 Web 爬取的技术对应关系

App 逆向的多数概念在 Web 端都有同构物,理解一边就能迁移另一边:

App 端Web 端共同本质
抓包分析接口Ajax 接口分析找到真实数据源
签名参数逆向JS 加密参数逆向还原参数生成算法
Frida HookJS Hook(重写原生函数)运行时拦截观察
Frida-RPC / AndServerNode RPC 服务让原环境当计算服务
SSL PinningTLS 指纹校验客户端身份验证
UI 自动化(Appium)浏览器自动化(Playwright)走真实用户路径
App 加固JS 混淆 / WASM提高静态分析成本

📚 模块与官方文档

抓包工具

工具安装官方文档
mitmproxypip install mitmproxydocs.mitmproxy.org
mitmproxy Addon APIAddon 概览 · 事件钩子 · HTTP 对象
Charles官网下载charlesproxy.com
Fiddler官网下载docs.telerik.com/fiddler
Wireshark系统包wireshark.org/docs

UI 自动化

模块安装官方文档
Appium-Python-Clientpip install Appium-Python-ClientGitHub
Appium Servernpm i -g appiumappium.io/docs
UiAutomator2 Driverappium driver install uiautomator2GitHub
uiautomator2pip install uiautomator2GitHub
airtestpip install airtestairtest.doc.io.netease.com
pocouipip install pocouipoco.readthedocs.io
facebook-wda(iOS)pip install facebook-wdaGitHub
adbAndroid SDKdeveloper.android.com

逆向分析

工具类型官方文档
frida / frida-toolspip install frida-toolsfrida.re/docs · JavaScript API
objectionpip install objectionGitHub
jadx反编译 dexGitHub
apktool解包 APKapktool.org
Ghidra反汇编 soghidra-sre.org
JEB商业反编译pnfsoftware.com

Android 平台文档

资源说明
网络安全配置证书信任规则,抓包受阻时必读
Android 7 CA 证书变更用户证书不再默认受信的官方说明
UI AutomatorUI 自动化的系统级基础

相关笔记

JavaScript 逆向(同构的算法还原与 RPC 思路)· 反爬对抗(代理与登录态)· 请求库详解(拿到接口后的高并发实现)


← 返回 Python 深度研究