百趣云 百趣云的博客

得物 App 接口 sign 参数还原

得物的签名架构:算法在 SO,但没有加固

得物 App 接口的 sign 参数有一个让逆向者松一口气的特点:算法在 native 层实现,但 SO 没有加固。这意味着两条路都通——IDA 静态分析能看懂,Frida 动态直调更方便。它是学习"SO 层签名对抗"的舒适入门案例。

Java 层定位:从参数组装追到 JNI 入口

jadx 打开 APK,搜索签名参数的组装点。得物的网络层封装里能找到类似结构:

// 特征:TreeMap 排序 + native 方法
Map<String, String> sorted = new TreeMap<>(params);
String sign = SignUtils.getSign(sorted, salt);  // native 方法

SignUtils 类里有 System.loadLibrary(...) 加载签名 SO,方法声明是 public static native。jadx 里按 X 查引用,能看到所有调用点——得物的 sign 用在接口公共参数组装处,每个请求都过它。

SO 层分析:IDA 标准流程

签名 SO 拖进 IDA,两种找函数的方式:

  1. 静态注册:直接找 Java_包名_SignUtils_getSign 导出符号(得物部分版本是静态注册,符号可见)
  2. 动态注册:符号被 strip 时,找 JNI_OnLoad 里的 RegisterNatives 调用,方法表里有 Java 方法名与 native 函数地址的映射

函数逻辑拆开(不同版本细节有差异,骨架稳定):

  1. 遍历参数 map,按 key 字典序拼 key=value&
  2. 尾部拼 salt(硬编码在 SO 的 .rodata 段,IDA 里按字符串引用直接可见)
  3. 整体 SHA-256(识别特征:初始化常量 0x6a09e667 等,或 K 表 0x428a2f98 开头的一组)
  4. hex 后做固定置换输出

Frida RPC:工程落地的首选

手搓算法要处理 map 排序的边界情况(空值、特殊字符编码),性价比低。Frida 直接调 App 自己的函数:

Java.perform(function() {
    var SignUtils = Java.use('com.du.app.xxx.SignUtils');  // 类名以实际为准
    var TreeMap = Java.use('java.util.TreeMap');

    rpc.exports = {
        sign: function(paramsJson, salt) {
            var map = TreeMap.$new();
            var obj = JSON.parse(paramsJson);
            for (var k in obj) map.put(k, String(obj[k]));
            return SignUtils.getSign(map, salt);
        }
    };
});
import frida

device = frida.get_usb_device()
session = device.attach('com.shizhuang.duapp')
script = session.create_script(open('sign.js').read())
script.load()
sign = script.exports.sign('{"timestamp":"1787968800",...}', 'salt值')

一台挂机手机 + frida-server,就是稳定的签名服务。

数美 smid:签名之外的设备指纹

得物接入了数美风控(SmAntiFraud SDK),接口里的 smid 参数就是数美的设备标识。要点:

  • smid 由数美 SDK 采集设备环境生成,hook SmAntiFraud 类的获取方法可直接拿到
  • 它和 sign 独立校验——sign 对了 smid 异常照样被拦
  • 协议池里 smid 和设备档案绑定,别跨设备复用

精髓:SO 签名类 App 的通用打法

  1. 先评估 Frida RPC 直调,再考虑算法还原。直调半天搞定,还原可能要三天——除非要脱离手机规模化(unidbg 路线),否则直调是最优解。
  2. salt 在 rodata 段,但可能分段存储。IDA 里搜到的"半个 salt"别急着用,交叉引用看拼接逻辑,有的版本会拆成两三段运行时拼。
  3. 关注 SO 的版本更新。App 升级换 SO 时,Frida 脚本里的类名/方法签名可能失效,hook 代码要做好版本适配(按特征搜类,别写死全限定名)。

总结

  1. 得物 sign 在 SO 层但无加固,IDA 可读、Frida 可调
  2. 算法骨架:TreeMap 排序 + salt 拼接 + SHA-256 + 置换
  3. 工程首选 Frida RPC 直调,一台挂机手机就是签名服务
  4. 数美 smid 是独立校验的设备指纹,和 sign 分开管理
By 百趣云 阅读量:2 On