京东到家的逆向分析记录
京东到家V6.0.3的逆向分析记录
signKeyV1的算法
算法简要
- 算法逻辑在:libjdpdj.so
- 算法的加密对象: 请求参数的Value值按Key排序的值
- 算法**: 应用程序的签名,还原算法时可以从APK解析压的目录META-INF/JINGDONG.RSA 中提取
-
- APP没有使用一般的命名CERT.RSA, 而是命名为JINGDONG.RSA, 这是在做一种防护
-
- 熟悉CERT.RSA 文件格式的人知道,这段数据和应用程序版本是无关的,这说明JD服务器是不会因为版本不懂,而选择不同的**。
-
- 算法:hmac_sha256 + 简单的**处理
算法流程
-
- 读取应用程序的签名 参见
- jd.utils.StatisticsReportUtil.getSign
-
- 然后根据签名生成一个32位**
-
- 使用hmac_sha256 的消息摘要算法获取signKeyV1
分析过程
1. 使用Jadx 代开APK文件, 搜索了一下signKeyV1
2. 发现signKeyV1代码在so层, 然后对IDA 对so 进行分析
3.简单分析,算法如上, 发现居然会把加密的**打印出来,控制台 adb shell logcat -s JNI , 发现**是不变的
4. 静态分析算法,可以基本还原了,但是现在需要如下验证
-
- 程序是否使用这个算法,还是混淆视听。 是的话,有点出乎意外的简单
-
- 需要验证还原的算法是否正确, 需要有这个算法入参和出参作为测试
- 抓包提取入参和出参
- 动态调试或者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 框架和模拟器检测的代码,编写检测返回值,依然无效, 见模拟器框架检测,参考下面的框架,模拟器检测分析
-
- 根据清单文件 查看程序的自定义Application:com.tencent.bugly.beta.tinker.TinkerPatchReflectApplication
- 根据清单文件 查看程序的自定义Application:com.tencent.bugly.beta.tinker.TinkerPatchReflectApplication
-
- APP应该在这个so做了反hook 防护,IDA 打开so, 查找so JNI_Onload
- 4.在so中发现程序有 稍微混淆, 但是不严重, 而且所有字符串都已经加密了
- 平坦式混淆
- 字符串都都加密
- 平坦式混淆
- 解决方案:
- 编写IDA 解析脚本,对抗混淆和字符串加密
- 动态调试so
- 感觉耗时很久,暂时不搞他, 以后在分析
框架,模拟器检测 分析
- 模拟器检测
- 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判断
- com.tencent.bugly.crashreport.common.info.b.o(Context )
- com.tencent.bugly.crashreport.common.info.a.R()
- Hook框架检测
- com.tencent.bugly.crashreport.common.info.a.R()
调用如下四个函数分别取检测
- com.tencent.bugly.crashreport.common.info.b.q(Context)
根据Xposed 的CS 的的安装框架取检测 - com.tencent.bugly.crashreport.common.info.b.r()
XPosed 抛异常检测 - com.tencent.bugly.crashreport.common.info.b.s()
通过maps 读取jar包和so 的名字, 检测有没有CS XPosed - com.tencent.bugly.crashreport.common.info.b.q()
检测AMS 是否被代理,VIrtualXPosed 会使用这种代理
- com.tencent.bugly.crashreport.common.info.a.R()
重打包 插入调试代码
- 现象:
-
- 使用kstools **应用程序签名,发现签名工具无法读取原始签名信息
-
- 后来发现签名文件 的命名位JINGDONG.RSA 而不是CERT.RSA
-
- 解决方案: 修改kstools 工具源码, **签名后,然后插入分析代码
额外
- 对于libjdpdj 如果静态分析困难的话,可以将这个so放在自己的分析工程进行调试, 这样就能过掉反调试了, 前提是libjdpdj 没有过度的调用Java层方法, libjdpdj.so 满足这个条件