API逆向工程

Flow-X

2026-05-15 00:00:00

工具链

mitmproxy

命令行 HTTP/HTTPS 代理抓包工具:

mitmproxy -p 8080

设置系统/浏览器代理到 8080 端口即可记录所有 HTTP/HTTPS 请求。首次使用需安装 CA 证书以解密 HTTPS。

Frida:动态插桩

核心是在目标进程里注入 JS 引擎,用 JS 脚本 hook 任意函数——不是代理抓包,而是钻进应用内部。

pip install frida-tools
frida-ps -U          # USB 连接的手机
frida -U -l hook.js com.example.app

典型 hook 脚本:

// hook Java 加密方法(Android)
Java.perform(function() {
    var Cipher = Java.use("javax.crypto.Cipher");
    Cipher.doFinal.overload("[B").implementation = function(data) {
        console.log("[Cipher.doFinal] input:", bytesToHex(data));
        var result = this.doFinal(data);
        console.log("[Cipher.doFinal] output:", bytesToHex(result));
        return result;
    };
});

// hook native 函数
Interceptor.attach(Module.findExportByName("libssl.so", "SSL_write"), {
    onEnter: function(args) {
        console.log("SSL_write, data:", hexdump(args[1], {length: args[2].toInt32()}));
    }
});

Frida 在分析链路中的位置:mitmproxy/Burp 负责看”线路上传了什么”,Frida 负责看”代码里算了什么”。当抓包抓到加密密文或不认识的签名时,用 Frida hook 对应的 encrypt/sign 函数拿到入参,就能知道原始数据和算法。

场景 Frida 做的事
SSL Pinning hook okhttp3.CertificatePinner.check() 让它直接 return
签名参数 (sign=xxx) hook MessageDigest 或自定义 sign 方法,拿到参与签名的原始字符串
加密 body hook Cipher.doFinal() 看加密前明文
自研协议 (非 HTTP) hook Socket.send() / Socket.recv() 抓二进制
反调试检测 hook android.os.Debug.isDebuggerConnected() 返回 false

BurpSuite

除 Proxy → HTTP History 记录功能外,核心模块:

Web 端抓取请求

覆盖原生 fetch / XMLHttpRequest

const origFetch = window.fetch;
window.fetch = async function(...args) {
    const [url, options] = args;
    console.group(`[fetch] ${options?.method || 'GET'} ${url}`);
    console.log('headers:', options?.headers);
    options?.body && console.log('body:', options.body);
    const response = await origFetch(...args);
    const clone = response.clone();
    clone.text().then(body => {
        console.log('response:', body);
        console.groupEnd();
    });
    return response;
};

优势:可在任意页面注入(Tampermonkey/浏览器扩展),无需配置代理。能拿到请求体和响应体。

Performance API

performance.getEntriesByType('resource').forEach(entry => {
    console.log({
        name: entry.name,
        initiatorType: entry.initiatorType,  // fetch / xmlhttprequest / script / img …
        duration: entry.duration,
        transferSize: entry.transferSize,
    });
});

// 持续监听新请求
const observer = new PerformanceObserver(list => {
    list.getEntries().forEach(entry => {
        console.log('[new request]', entry.name, entry.initiatorType);
    });
});
observer.observe({ type: 'resource', buffered: true });

两者区别: - 覆盖 fetch/XHR:能拿到请求体和响应体,适合做 API 文档 - Performance API:只有元数据(URL、耗时、大小),拿不到 body,但覆盖所有资源类型(img、script、css),适合性能分析

实践中通常结合使用:PerformanceObserver 监控所有请求 URL,对 XHR/fetch 类请求再配合覆盖方式拿 body。

实践流程

1. 抓包 (mitmproxy/Burp/浏览器脚本)
      ↓
2. 分类整理:按 domain + URL pattern 归类,过滤静态资源,提取 API 请求
      ↓
3. 参数分析:
   - 动态参数(时间戳、nonce)→ Frida hook 看生成逻辑
   - 签名参数(sign、token)→ Frida hook 看签名算法
   - 加密参数 → Frida hook Cipher 看明文
      ↓
4. 形成 API 文档(端点、方法、参数名、参数类型、响应格式、鉴权方式)
      ↓
5. 基于文档开发辅助工具(脚本/CLI/自动化)

实践建议: - Burp 抓到的请求可以 Export 保存为文件,方便离线分析 - 参数去重可用 Burp 的 Param Miner 扩展自动发现隐藏参数 - API 文档用 OpenAPI/Swagger 格式,后续可直接导入 Postman 或生成 SDK