京东到家的逆向分析记录

京东到家V6.0.3的逆向分析记录

signKeyV1的算法

算法简要

  • 算法逻辑在:libjdpdj.so
  • 算法的加密对象: 请求参数的Value值按Key排序的值
  • 算法**: 应用程序的签名,还原算法时可以从APK解析压的目录META-INF/JINGDONG.RSA 中提取
    京东到家的逆向分析记录
      1. APP没有使用一般的命名CERT.RSA, 而是命名为JINGDONG.RSA, 这是在做一种防护
      1. 熟悉CERT.RSA 文件格式的人知道,这段数据和应用程序版本是无关的,这说明JD服务器是不会因为版本不懂,而选择不同的**。
  • 算法:hmac_sha256 + 简单的**处理

算法流程

    1. 读取应用程序的签名 参见
    • jd.utils.StatisticsReportUtil.getSign
    1. 然后根据签名生成一个32位**
    1. 使用hmac_sha256 的消息摘要算法获取signKeyV1

分析过程

1. 使用Jadx 代开APK文件, 搜索了一下signKeyV1

京东到家的逆向分析记录

2. 发现signKeyV1代码在so层, 然后对IDA 对so 进行分析

京东到家的逆向分析记录

3.简单分析,算法如上, 发现居然会把加密的**打印出来,控制台 adb shell logcat -s JNI , 发现**是不变的

京东到家的逆向分析记录

4. 静态分析算法,可以基本还原了,但是现在需要如下验证

    1. 程序是否使用这个算法,还是混淆视听。 是的话,有点出乎意外的简单
    1. 需要验证还原的算法是否正确, 需要有这个算法入参和出参作为测试
    • 抓包提取入参和出参
    • 动态调试或者hook获取入参和出参

5.验证过程中遇到一些对抗,参见 下小节内容 APP安全防护 和解决方案,最终采用 重打包技术 ,添加打印 jd.net.z.k2 的入参和出参

6.然后编写还原算法

APP安全防护和解决方案

抓包对抗

  • 现象: 使用Fiddler抓包,有时候能抓有时候不能
  • 解决方案:使用v*n 抓包工具PacketCapture抓包

动态调试

  • 现象: IDA动态调试so 和AS 动态 samli,调试不了
  • 解决方案:程序退出,exit, abort 下断点
  • PS: 感觉反调试比较多,暂时不采纳了

反hook框架

  • 现象
    • 1.使用XPosed hook Application.attach 都不来
    • 2.代码检索Xposed 关键字 找到一些关于hook 框架和模拟器检测的代码,编写检测返回值,依然无效, 见模拟器框架检测,参考下面的框架,模拟器检测分析
      1. 根据清单文件 查看程序的自定义Application:com.tencent.bugly.beta.tinker.TinkerPatchReflectApplication
        京东到家的逆向分析记录
      1. APP应该在这个so做了反hook 防护,IDA 打开so, 查找so JNI_Onload
    • 4.在so中发现程序有 稍微混淆, 但是不严重, 而且所有字符串都已经加密了
      • 平坦式混淆
        京东到家的逆向分析记录
      • 字符串都都加密
        京东到家的逆向分析记录
  • 解决方案:
    1. 编写IDA 解析脚本,对抗混淆和字符串加密
    2. 动态调试so
    3. 感觉耗时很久,暂时不搞他, 以后在分析

框架,模拟器检测 分析

  • 模拟器检测
    • com.tencent.bugly.crashreport.common.info.a.R()
      京东到家的逆向分析记录
    • com.tencent.bugly.crashreport.common.info.b.n(Context )
      • com.tencent.bugly.crashreport.common.info.b.o(Context )
        通过模拟器中含有程序包判断
      • com.tencent.bugly.crashreport.common.info.b.p()
        通过模拟器包含deso判断
  • Hook框架检测
    • com.tencent.bugly.crashreport.common.info.a.R()
      京东到家的逆向分析记录
      调用如下四个函数分别取检测
    1. com.tencent.bugly.crashreport.common.info.b.q(Context)
      根据Xposed 的CS 的的安装框架取检测
    2. com.tencent.bugly.crashreport.common.info.b.r()
      XPosed 抛异常检测
    3. com.tencent.bugly.crashreport.common.info.b.s()
      通过maps 读取jar包和so 的名字, 检测有没有CS XPosed
    4. com.tencent.bugly.crashreport.common.info.b.q()
      检测AMS 是否被代理,VIrtualXPosed 会使用这种代理

重打包 插入调试代码

  • 现象:
      1. 使用kstools **应用程序签名,发现签名工具无法读取原始签名信息
      1. 后来发现签名文件 的命名位JINGDONG.RSA 而不是CERT.RSA
  • 解决方案: 修改kstools 工具源码, **签名后,然后插入分析代码

额外

  • 对于libjdpdj 如果静态分析困难的话,可以将这个so放在自己的分析工程进行调试, 这样就能过掉反调试了, 前提是libjdpdj 没有过度的调用Java层方法, libjdpdj.so 满足这个条件