pdd搜索请求分析+加密参数部分分析
字数 1493 2025-09-01 11:26:17

PDD App搜索请求加密参数anti-token逆向分析教学文档

1. 分析背景与目标

分析PDD(拼多多)App搜索请求中的加密参数anti-token,目标是通过逆向工程技术定位并获取该参数,实现搜索请求的复现。

2. 工具准备

  • jadx: Java反编译工具,用于分析APK代码
  • Charles: 网络抓包工具,用于捕获和分析HTTP请求
  • frida: 动态分析工具,用于运行时Hook和RPC调用
  • IDA Pro: 反汇编工具,用于分析native层代码

3. 请求分析流程

3.1 抓包分析

  1. 使用Charles抓取PDD App的搜索请求
  2. 观察请求参数,发现存在加密参数anti-token
  3. 确认anti-token为必要参数,缺失时无法获得正确响应

3.2 Java层分析

3.2.1 定位参数生成位置

  1. Hook HashMap.put方法:
    • 由于header构造通常使用HashMap,可以Hook其put方法
    • 当参数为anti-token时打印调用堆栈
// frida hook代码示例
Java.perform(function() {
    var HashMap = Java.use('java.util.HashMap');
    HashMap.put.implementation = function(key, value) {
        if (key === 'anti-token') {
            console.log('anti-token:', value);
            console.log(Java.use("android.util.Log").getStackTraceString(
                Java.use("java.lang.Throwable").$new()));
        }
        return this.put.call(this, key, value);
    };
});
  1. 通过堆栈定位关键类:
    • 对比抓包结果和堆栈信息,定位到com.xunmeng.pinduoduo.secure.DeviceNative

3.2.2 反编译分析

  1. 使用jadx打开APK,搜索anti-token相关信息
  2. 定位到关键方法getAntiToken(),发现其调用了native方法deviceInfo2()
// 伪代码
public String getAntiToken() {
    try {
        return deviceInfo2(context, System.currentTimeMillis());
    } catch (Throwable unused) {
        return "";
    }
}
  1. 查找实现类:
    • 由于直接跟进会跳转到接口定义,需要搜索方法名f(需重命名后搜索)
    • 最终定位到实现类com.xunmeng.pinduoduo.secure.DeviceNative

4. RPC调用方案

4.1 RPC原理

无需了解具体生成逻辑,直接动态调用内部函数获取返回值作为请求参数。

4.2 实现代码

// frida RPC代码
rpc.exports = {
    getAntiToken: function() {
        var result = "";
        Java.perform(function() {
            var DeviceNative = Java.use("com.xunmeng.pinduoduo.secure.DeviceNative");
            var currentApplication = Java.use("android.app.ActivityThread").currentApplication();
            var context = currentApplication.getApplicationContext();
            var timestamp = Java.use("java.lang.System").currentTimeMillis();
            result = DeviceNative.deviceInfo2(context, timestamp);
        });
        return result;
    }
};

4.3 Python调用示例

import frida

def get_anti_token():
    session = frida.get_usb_device().attach("com.xunmeng.pinduoduo")
    script = session.create_script(open("rpc.js").read())
    script.load()
    return script.exports.getantitoken()

5. Native层分析

5.1 定位动态加载的so文件

  1. Hook JNI注册过程:
    • 拦截RegisterNatives函数调用
    • 获取native方法注册时的so模块信息
// frida hook RegisterNatives代码
Interceptor.attach(addrRegisterNatives, {
    onEnter: function(args) {
        var java_class = args[1];
        var class_name = Java.vm.tryGetEnv().getClassName(java_class);
        if (class_name.indexOf("com.xunmeng.pinduoduo.secure.DeviceNative") !== -1) {
            var methods_ptr = args[2];
            var method_count = args[3].toInt32();
            for (var i = 0; i < method_count; i++) {
                var name_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3));
                var sig_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize));
                var fnPtr_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize * 2));
                var name = Memory.readCString(name_ptr);
                var sig = Memory.readCString(sig_ptr);
                var mod = Process.findModuleByAddress(fnPtr_ptr);
                console.log("name:", name, "sig:", sig, "module:", mod.name, "offset:", fnPtr_ptr.sub(mod.base));
            }
        }
    }
});
  1. 运行结果:
    • 定位到deviceInfo2函数位于libpddsecure.so

5.2 IDA静态分析

  1. 使用IDA打开libpddsecure.so
  2. 定位到deviceInfo2函数
  3. 发现使用了OLLVM混淆,反混淆难度大

5.3 函数逻辑分析

初步分析表明:

  1. 函数会读取大量设备信息
  2. 结合时间戳生成一个与设备和时间相关的值
  3. 该值作为anti-token用于请求验证

6. 总结与建议

6.1 技术总结

  1. 参数定位:

    • 通过Hook常用类方法定位关键代码
    • 结合堆栈分析和字符串搜索缩小范围
  2. RPC方案:

    • 适用于快速获取参数值而不关心生成逻辑
    • 需要保持运行环境一致性
  3. Native分析:

    • 动态注册的native方法需要通过Hook JNI注册过程定位
    • 混淆代码增加了静态分析难度

6.2 实践建议

  1. 对于数据爬取需求,优先考虑RPC方案
  2. 对于安全研究,可深入分析so文件的反混淆
  3. 注意法律合规性,仅用于授权研究

7. 扩展知识

  1. JNI动态注册:

    • 通过JNI_OnLoadRegisterNatives实现
    • 比静态注册更灵活且更安全
  2. OLLVM混淆:

    • 常见的代码保护技术
    • 包括控制流平坦化、指令替换、虚假分支等
  3. Frida高级用法:

    • 内存搜索和修改
    • 主动调用与RPC
    • 多线程处理

8. 参考资料

  1. Frida官方文档
  2. Android JNI编程指南
  3. OLLVM反混淆技术研究
  4. 移动安全逆向分析实战
PDD App搜索请求加密参数anti-token逆向分析教学文档 1. 分析背景与目标 分析PDD(拼多多)App搜索请求中的加密参数 anti-token ,目标是通过逆向工程技术定位并获取该参数,实现搜索请求的复现。 2. 工具准备 jadx : Java反编译工具,用于分析APK代码 Charles : 网络抓包工具,用于捕获和分析HTTP请求 frida : 动态分析工具,用于运行时Hook和RPC调用 IDA Pro : 反汇编工具,用于分析native层代码 3. 请求分析流程 3.1 抓包分析 使用Charles抓取PDD App的搜索请求 观察请求参数,发现存在加密参数 anti-token 确认 anti-token 为必要参数,缺失时无法获得正确响应 3.2 Java层分析 3.2.1 定位参数生成位置 Hook HashMap.put方法 : 由于header构造通常使用HashMap,可以Hook其put方法 当参数为 anti-token 时打印调用堆栈 通过堆栈定位关键类 : 对比抓包结果和堆栈信息,定位到 com.xunmeng.pinduoduo.secure.DeviceNative 类 3.2.2 反编译分析 使用jadx打开APK,搜索 anti-token 相关信息 定位到关键方法 getAntiToken() ,发现其调用了native方法 deviceInfo2() 查找实现类 : 由于直接跟进会跳转到接口定义,需要搜索方法名 f (需重命名后搜索) 最终定位到实现类 com.xunmeng.pinduoduo.secure.DeviceNative 4. RPC调用方案 4.1 RPC原理 无需了解具体生成逻辑,直接动态调用内部函数获取返回值作为请求参数。 4.2 实现代码 4.3 Python调用示例 5. Native层分析 5.1 定位动态加载的so文件 Hook JNI注册过程 : 拦截 RegisterNatives 函数调用 获取native方法注册时的so模块信息 运行结果 : 定位到 deviceInfo2 函数位于 libpddsecure.so 中 5.2 IDA静态分析 使用IDA打开 libpddsecure.so 定位到 deviceInfo2 函数 发现使用了OLLVM混淆,反混淆难度大 5.3 函数逻辑分析 初步分析表明: 函数会读取大量设备信息 结合时间戳生成一个与设备和时间相关的值 该值作为 anti-token 用于请求验证 6. 总结与建议 6.1 技术总结 参数定位 : 通过Hook常用类方法定位关键代码 结合堆栈分析和字符串搜索缩小范围 RPC方案 : 适用于快速获取参数值而不关心生成逻辑 需要保持运行环境一致性 Native分析 : 动态注册的native方法需要通过Hook JNI注册过程定位 混淆代码增加了静态分析难度 6.2 实践建议 对于数据爬取需求,优先考虑RPC方案 对于安全研究,可深入分析so文件的反混淆 注意法律合规性,仅用于授权研究 7. 扩展知识 JNI动态注册 : 通过 JNI_OnLoad 和 RegisterNatives 实现 比静态注册更灵活且更安全 OLLVM混淆 : 常见的代码保护技术 包括控制流平坦化、指令替换、虚假分支等 Frida高级用法 : 内存搜索和修改 主动调用与RPC 多线程处理 8. 参考资料 Frida官方文档 Android JNI编程指南 OLLVM反混淆技术研究 移动安全逆向分析实战