文章目录[隐藏]
android 逆向 16 / 38
- app OAuth api_sign 分析
- app sig 参数加密分析 unidbg 模拟黑盒调用
- app sign so 加密参数破解|unidbg
- sgmain x-sign 分析 - unidbg
- androidAsync fridaManager sgmain 70102 rpc 远程调用
- app edata 参数 so aes 加密分析破解|unidbg
- frida 加载 sekiro dex 文件 实现与服务端交互
- frida sekiro 实现 sgmain 70102 远程 rpc 调用
- xposed sekiro hook 获取 wx 万能 key
- unidbg console debugger 使用
- unidbg hook inline hook 使用
- app 公众号文章列表 so 加解密算法分析还原 | 简单分析
- app 公众号文章列表 so 加解密算法分析还原 | 加密 rsa base64 分析
- app 公众号文章列表 so 加解密算法分析还原 | 加密 zip aes 分析
- app 公众号文章列表 so 加解密算法分析还原 | response 内容解密分析
- app sign so 加密算法分析还原|简单分析
- app sign so 加密算法分析还原|so 算法分析
- app sign so 加密算法分析还原|so sub_126AC 函数算法还原
- app so signkeyV1 参数分析
- ida 动态调试 android so 文件|基础入门环境搭建
- app so newSign 参数分析破解
- app tzRgz52a 参数分析破解
- app sign-v2 签名算法 aes 加解密分析
- app so 加密参数分析|protocbuf 分析
- mxtakatak android app 加解密分析
- android app so 加密算法分析破解|mtgsig unidbg
- android app so 加密算法分析破解|siua unidbg
- android app nsign so 加密算法分析
- android app sig 参数 so 加密逻辑逆向分析
- android app so sig 加密参数 unidbg
- 狗狗音乐登陆协议加密参数逆向分析
- android sign so 加密参数分析|unidbg
- android app X-SS-QUERIES 参数分析
- unidbg android app xgorgon 加密参数 leviathan
- sgmain 6.4.x xsign 加密算法分析研究
- sgmain 6.4.x xminiwua 加密算法分析研究
- 某 app mas 算法分析还原 cms so
- 某东登陆协议 tlv 逻辑分析
仅供学习研究 。请勿用于非法用途,本人将不承担任何法律责任。
const 龙哥 = Function() {}
const a = 全能的傻宝,每天都会换一种姿势来分享各种骚操作,10月份开始分享密码学;
const b = 点击加入星球;
return "无敌的龙哥";
推荐阅读
unidbg hook inline hook 使用
unidbg console debugger 使用
so 分析过程在验阶段会使用unidbg debugger hook
功能,不熟悉的可以阅读以上文章
JD app sign so 加密算法分析还原|so 算法分析
JD app sign so 加密算法分析还原|so sub_126AC 函数算法还原
前言
前面分析了搜狗搜索 app 的 so 加解密逻辑,这次就来分析下 某东 app 的,继续学习 so 分析
app 版本 最新版 10.2.0
0x1
先来抓个包
随便点个请求,查看参数,这里有三个是 so
加密返回的
0x2
反编译 apk 查看加密函数
前面 java
层的分析就不说了,最终是找到了这个类 com.jingdong.common.utilsBitmapkitUtils
,调用 getSignFromJni native
函数获取加密参数,一共有六个参数,具体的加密逻辑在 BitmapkitUtils.so
文件里,frida hook
看一下
0x3
frida hook
function hook() {
var BitmapkitUtils = Java.use('com.jingdong.common.utils.BitmapkitUtils');
BitmapkitUtils.getSignFromJni.implementation = function (a, b, c, d, e, f) {
console.log('b: ', b);
console.log('c: ', c);
console.log('d: ', d);
console.log('e: ', e);
console.log('f: ', f);
var res = this.getSignFromJni(a, b, c, d, e, f);
console.log('resf: ', res);
return res;
}
}
function main() {
Java.perform(function () {
hook();
})
}
setImmediate(main);
代码写完执行 frida -U -f com.jingdong.app.mall -l hook.js --no-pause | tee hook.log
命令,查看 hook.log
文件
函数的输入输出很明显,加密结果也能跟请求包对应起来,下面使用 frida
主动调用看看
frida call
function callBitmapkitUtils() {
var BitmapkitUtils = Java.use('com.jingdong.common.utils.BitmapkitUtils');
var currentApplication = Java.use("android.app.ActivityThread").currentApplication();
var context = currentApplication.getApplicationContext();
var b = 'clientImage';
var c = '{"moduleParams":{"18":"1565611060638","19":"1565229712150","25":"1567478504636","27":"1602488415048","28":"1631069159956","30":"1567404005627","32":"1567997588476","34":"1593508185597","35":"1568708316462","37":"1630293538664","42":"1623741761542","44":"1569247647090","46":"1588839806224","47":"1571295610042","61":"1582091758495","70":"1585279774645","74":"1586781606615"}}';
var d = 'd5a585639f505b18';
var e = 'android';
var f = '10.2.0';
var res = BitmapkitUtils.getSignFromJni(context, b, c, d, e, f);
console.log('res: ', res);
}
function main() {
Java.perform(function () {
callBitmapkitUtils();
})
}
setImmediate(main);
执行 frida -UF -l call.js
查看输出每次调用都不一样,应该是跟时间戳有关系,看 sign
的结果应该是 md5 or hmac
,后面既然需要用到 unidbg debugger
功能那就需要先使用 unidbg
跑起来
0x4
使用 unidbg 调用 getSignFromJni 函数
这里的 so 有个坑,会调用 check_status 函数,校验 apk 的签名,有两种方式可以选择
1、直接 so patch 不执行这个函数,参考我之前的文章: JD app sign 加密参数破解 - unidbg
2、直接去补 so 的 check_status 函数,因为我们后面要去分析 so 算法还原,所以本次就选择这种方式
package com.xiayu.jingdong;
import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.LibraryResolver;
import com.github.unidbg.Module;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.linux.android.dvm.*;
import com.github.unidbg.memory.Memory;
import java.io.File;
import java.io.IOException;
public class JingDong1020Test extends AbstractJni {
private final AndroidEmulator emulator;
private final VM vm;
public String apkPath = "apk 文件路径";
public String soPath = "so 文件路径";
private static LibraryResolver createLibraryResolver() {
return new AndroidResolver(23);
}
private static AndroidEmulator createARMEmulator() {
return AndroidEmulatorBuilder
.for32Bit()
.build();
}
public JingDong1020Test() {
emulator = createARMEmulator();
final Memory memory = emulator.getMemory();
memory.setLibraryResolver(createLibraryResolver());
vm = emulator.createDalvikVM(new File(apkPath));
vm.setVerbose(true);
DalvikModule dm = vm.loadLibrary(new File(soPath), false);
vm.setJni(this);
dm.callJNI_OnLoad(emulator);
Module module = dm.getModule();
}
public void callGetSignFromJni() {
DvmClass bitMapKitUtils = vm.resolveClass("com/jingdong/common/utils/BitmapkitUtils");
DvmObject<?> strRc = bitMapKitUtils.callStaticJniMethodObject(
emulator,
"getSignFromJni()(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
vm.addLocalObject(null),
vm.addLocalObject(new StringObject(vm, "clientImage")),
vm.addLocalObject(new StringObject(vm, "{\"moduleParams\":{\"18\":\"1565611060638\",\"19\":\"1565229712150\",\"25\":\"1567478504636\",\"27\":\"1602488415048\",\"28\":\"1631069159956\",\"30\":\"1567404005627\",\"32\":\"1567997588476\",\"34\":\"1593508185597\",\"35\":\"1568708316462\",\"37\":\"1630293538664\",\"42\":\"1623741761542\",\"44\":\"1569247647090\",\"46\":\"1588839806224\",\"47\":\"1571295610042\",\"61\":\"1582091758495\",\"70\":\"1585279774645\",\"74\":\"1586781606615\"}}")),
vm.addLocalObject(new StringObject(vm, "d5a585639f505b18")),
vm.addLocalObject(new StringObject(vm, "android")),
vm.addLocalObject(new StringObject(vm, "10.2.0"))
);
System.out.println("callGetSignFromJni: " + strRc.getValue());
}
public static void main(String[] args) throws IOException {
JingDong1020Test jdSign = new JingDong1020Test();
jdSign.callGetSignFromJni();
jdSign.destroy();
}
private void destroy() throws IOException {
emulator.close();
}
}
全部代码,写完跑起来
环境问题补起来,返回 Application
返回 base.apk
的文件路径
这个是调用了自定义的 com/jingdong/common/utils/BitmapkitZip->unZip
函数,目前没啥好的办法,只有去把 java
复制过来使用,第一个参数是需要解压的 apk
路径,所以我们传递的是本地的 apk
路径
一个加密参数,调用的是 java
内置函数,直接补
这里需要返回一个对象数组
接着又补了一些环境
在运行,结果就出来了,每次运行的结果不一样,下面使用 python
请求测试一下,结果是否可用
0x5
使用
java server
框架启动服务,在使用python
调用java
接口获取sign
参数,测试是否可用
代码写完,结果是可以用的
最后
某东
unidbg
例子就写完了,后面开始去分析so
具体算法
查哪
2022-01-08BitmapkitZip 反编译代码可以发我下吗,我这都是不全的,q857216084
会爬山的小脑虎
2022-01-08@查哪 怎么会不全呢,我也是直接复制的
查哪
2022-01-08@会爬山的小脑虎 jadx或者dex后unZip是空的
会爬山的小脑虎
2022-01-08@查哪 加微信联系 2027762055
嗄嗄
2021-11-29BitmapkitZip函数jadx解析不全,怎么拿全的代码呢?是smali还原吗?
会爬山的小脑虎
2021-11-29@嗄嗄 对 jadx jeb 反编译都有点问题,没法直接用的,我是用 mt管理器 反编译复制的
D0D
2021-11-27你好 我在使用unidbg 调用函数的时候 一直出现Exception in thread "main" java.lang.IllegalStateException: Illegal JNI version: 0xffffffff 这个错误 我这里也去修改了so里面的东西
沈听白
2022-03-15@D0D 你已经解决这个问题了吗