记一次学习过程,需求解密"sign"字段 得到其算法
- com.maihan.tredian 淘最热点
- so层 算法
- base64
- sha1
1. 点击登录抓包
请求
{"code":"111111","device_id":"771f9ed014238510a1e2178074eb9bd9","channel":"aliapp","sign":"cd734b9bbe1f3b13b7ec3309f1033aa322101bdc","nonce":"sb4uzj1620898124413","mac":"F4:F5:DB:23:63:06","imei2":"864699038686535","device_name":"Xiaomi MI 5X","imei1":"864699038686527","system":"1","phone":"13333333333","app_ver":"53","device_udid":"4816f503c2f86992101c212da8b65171","from":"app","os_ver_code":"27","timestamp":"1620898124"}
{
"code": "111111",
"device_id": "771f9ed014238510a1e2178074eb9bd9",
"channel": "aliapp",
"sign": "cd734b9bbe1f3b13b7ec3309f1033aa322101bdc",
"nonce": "sb4uzj1620898124413",
"mac": "F4:F5:DB:23:63:06",
"imei2": "864699038686535",
"device_name": "Xiaomi MI 5X",
"imei1": "864699038686527",
"system": "1",
"phone": "13333333333",
"app_ver": "53",
"device_udid": "4816f503c2f86992101c212da8b65171",
"from": "app",
"os_ver_code": "27",
"timestamp": "1620898124"
}
响应
{"code":1,"error":{"code":1,"ex_code":0,"exid":"ac0bbd8342dbc5eef82e6507b78c41ca","message":"\u9a8c\u8bc1\u7801\u4e0d\u6b63\u786e","custom_params":[]},"success":false}
{
"code": 1,
"error": {
"code": 1,
"ex_code": 0,
"exid": "ac0bbd8342dbc5eef82e6507b78c41ca",
"message": "\u9a8c\u8bc1\u7801\u4e0d\u6b63\u786e",
"custom_params": []
},
"success": false
}
2. 无壳无加固
3. jadx 分析
- 搜"sign" 一个一个找最后定位到这里
- 进去之后发现算法在so层 有两个a方法,先hook重载
4. frida objection 打印堆栈
- 找到定位 生成 frida.js 主动调用
# 启动进程
objection -g com.maihan.tredian explore
# 在内存中所有已加载的类中搜索包含特定关键词的类
android hooking search classes com.maihan.tredian.util.TreUtil
# 列出类的所有方法
android hooking list class_methods com.maihan.tredian.util.TreUtil
# hook类的所有方法
android hooking watch class com.maihan.tredian.util.TreUtil
# hook方法的参数、返回值和调用栈
android hooking watch class_method com.maihan.tredian.util.TreUtil.sign --dump-args --dump-return --dump-backtrace
# 快速生成frida 脚本
android hooking generate simple com.maihan.tredian.util.TreUtil
5. frida hook 主动调用
- args 每次都会变 先请求一次然后主动调用
主动调用 结果一样 转弄so
6. so层 定位 libtre.so
1. 静态注册直接搜Exports 导出函数 里面 java 得到 Java_com_maihan_tredian_util_TreUtil_sign
2. 结构比较清晰 直接hook
7. firda hook so
- 标准的base64 和 sha1
- hook 然后取前20个 标准的sha1 和base64算法 sign值到此结束
8. hook.js代码
console.log("--------------------");
console.log("com.maihan.tredian"); // 淘最热点
console.log("start...");
// hook_java();
hook_so();
console.log("end...");
console.log("--------------------");
function showStacks() {
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));
}
function hook_java() {
Java.perform(function () {
var TreUtil = Java.use("com.maihan.tredian.util.TreUtil");
TreUtil.sign.implementation = function (str) {
//showStacks();
console.log("sign str: ", str);
var retval = this.sign(str);
console.log("sign retval: ", retval);
return retval;
}
});
}
function call_java() {
Java.perform(function () {
var TreUtil = Java.use("com.maihan.tredian.util.TreUtil");
var retval = TreUtil.sign('app_ver=53&channel=aliapp&code=1111111&device_id=771f9ed014238510a1e2178074eb9bd9&device_name=Xiaomi MI 5X&device_udid=4816f503c2f86992101c212da8b65171&from=app&imei1=864699038686527&imei2=864699038686535&mac=F4:F5:DB:23:63:06&nonce=a52egm1620905618008&os_ver_code=27&phone=13333333333&system=1×tamp=1620905618');
// d6834079cc515b19f317fce0b47ba3cfa52a1992
console.log("call_java retval: ", retval)
});
}
function hook_so() {
var soAddr = Module.findBaseAddress("libtre.so");
//thumb
var base64_encode_new = soAddr.add(0x152C + 1);
var SHA1Result = soAddr.add(0x1640 + 1);
Interceptor.attach(base64_encode_new, {
onEnter: function (args) {
console.log("base64_encode_new onEnter args[0]: ", ptr(args[0]).readCString());
this.args1 = args[1];
// console.log("base64_encode_new onEnter args[2]: ", args[2].toInt32());
},
onLeave: function (retval) {
// console.log("base64_encode_new onLeave retval: ", retval.readCString());
console.log("base64_encode_new onLeave this.args1: ", ptr(this.args1).readCString());
}
});
Interceptor.attach(SHA1Result, {
onEnter: function (args) {
this.args1 = args[1];
},
onLeave: function (retval) {
console.log("SHA1Result onLeave this.args1: \n", hexdump(this.args1));
}
});
}