function call(){
Java.perform(function () {
let BitmapkitUtils = Java.use("com.jingdong.common.utils.BitmapkitUtils");
let context = Java.use("android.app.ActivityThread").currentApplication().getApplicationContext();
let str = "wareBusiness";
let str2 ='{"abTest800":true,"acceptPrivacy":true,"avoidLive":false,"bbtf":"","brand":"Redmi","businessType":"","bybt":"","cityCode":72,"cityId":0,"cpsNoTuan":null,"darkModelEnum":3,"districtId":0,"euaf":false,"eventId":"MyHistory_Product","fromType":0,"isDesCbc":true,"isFromOpenApp":true,"latitude":"0.0","lego":true,"longitude":"0.0","model":"Redmi Note 11T Pro","ocrFlag":false,"oneboxChannel":false,"oneboxKeyword":"","oneboxSource":"","openSimilarFlag":"","overseas":0,"pdVersion":"1","personas":null,"pluginVersion":101050,"plusClickCount":0,"plusLandedFatigue":0,"popBusinessType":"","poplayer":false,"productJdv":"-1|kong|t_1000210271_502774|zssc|d36d13b9-61c4-4fdf-b7f2-11dbc28d14dd-p_1999-pr_100746-at_502774-tg_ext_0-00-0-tgx-5050508-3935-20231110|1699610674","provinceId":"0","prstate":"0","refreshMe":null,"searchWareflag":"","selfDelivery":"0","skuId":"48905840961","source_type":"wojing_history","source_value":"","townId":0,"uAddrId":"0","utmMedium":null,"wareInnerSource":"extra.inner.source.init","yrqNew":"1"}'
let str3 = "789e43b8e08521ee";
let str4 = "android";
let str5 = "12.2.2";
let result = BitmapkitUtils.getSignFromJni(context, str, str2, str3, str4, str5);
console.log("BitmapkitUtils.getSignFromJni result = " + result);
});
}
发现疑似是hash函数
hook dlsym函数,得知函数加载的so
libjdbitmapkit.so
定位到要分析的函数,由于位数疑似md5,所以使用龙哥的findhash插件,进行寻找
熟悉的朋友应该认出了,这个就是md5运算部分,我们寻找上层引用
再次寻找上层引用
发现调用位置就在我们目标分析的函数里(如果没跟到的兄弟可以打印堆栈)
我们进行hook来分析入参
[JavaScript] 纯文本查看复制代码
(function () {
// @ts-ignore
function print_arg(addr) {
try {
var module = Process.findRangeByAddress(addr);
if (module != null) return "\n"+hexdump(addr) + "\n";
return ptr(addr) + "\n";
} catch (e) {
return addr + "\n";
}
}
// @ts-ignore
function hook_native_addr(funcPtr, paramsNum) {
var module = Process.findModuleByAddress(funcPtr);
try {
Interceptor.attach(funcPtr, {
onEnter: function (args) {
this.logs = "";
this.params = [];
// @ts-ignore
this.logs=this.logs.concat("So: " + module.name + " Method: sub_25E0 offset: " + ptr(funcPtr).sub(module.base) + "\n");
for (let i = 0; i < paramsNum; i++) {
this.params.push(args);
this.logs=this.logs.concat("this.args" + i + " onEnter: " + print_arg(args));
}
}, onLeave: function (retval) {
for (let i = 0; i < paramsNum; i++) {
this.logs=this.logs.concat("this.args" + i + " onLeave: " + print_arg(this.params));
}
this.logs=this.logs.concat("retval onLeave: " + print_arg(retval) + "\n");
console.log(this.logs);
}
});
} catch (e) {
console.log(e);
}
}
// @ts-ignore
hook_native_addr(Module.findBaseAddress("libjdbitmapkit.so").add(0x25e0), 0x3);
})();
发现入参是一段base64,解密后是乱码
在md5前,明文进行了额外处理:
v39是我们要分析的密文,
继续往上跟踪v39生成的位置
经过hook可知
密文由sub_18c9c计算而来
其中两个参数是rand随机生成的
在这里决定了sign由哪个函数进行加密
今天我们分析case2里面的加密函数,也是最简单的,后面我会分析剩下两个算法的计算方法
算法肉眼可见的可以复现,所以我们进行hook入参和出参进行分析
[JavaScript] 纯文本查看复制代码
(function () {
// @ts-ignore
function print_arg(addr) {
try {
var module = Process.findRangeByAddress(addr);
if (module != null) return "\n"+hexdump(addr) + "\n";
return ptr(addr) + "\n";
} catch (e) {
return addr + "\n";
}
}
// @ts-ignore
function hook_native_addr(funcPtr, paramsNum) {
var module = Process.findModuleByAddress(funcPtr);
try {
Interceptor.attach(funcPtr, {
onEnter: function (args) {
this.logs = "";
this.params = [];
// @ts-ignore
this.logs=this.logs.concat("So: " + module.name + " Method: sub_6858 offset: " + ptr(funcPtr).sub(module.base) + "\n");
for (let i = 0; i < paramsNum; i++) {
this.params.push(args);
if (i==0){
// this.logs=this.logs.concat("this.args" + i + " onEnter: " +args.readCString());
}
else if(i==3){
this.logs=this.logs.concat("this.args" + i + " onEnter: " +hexdump(args[3]));
}
else {
this.logs=this.logs.concat("this.args" + i + " onEnter: " + print_arg(args));
}
}
}, onLeave: function (retval) {
for (let i = 0; i < paramsNum; i++) {
this.logs=this.logs.concat("this.args" + i + " onLeave: " + print_arg(this.params));
}
this.logs=this.logs.concat("retval onLeave: " + print_arg(retval) + "\n");
console.log(this.logs);
}
});
} catch (e) {
console.log(e);
}
}
// @ts-ignore
hook_native_addr(Module.findBaseAddress("libjdbitmapkit.so").add(0x1882C), 0x4);
})();
不是所有的call都能触发这个分支,得多call几次
我们可以看到明文数据了
[JavaScript] 纯文本查看复制代码
(function () {
// @ts-ignore
function print_arg(addr) {
try {
var module = Process.findRangeByAddress(addr);
if (module != null) return "\n"+hexdump(addr) + "\n";
return ptr(addr) + "\n";
} catch (e) {
return addr + "\n";
}
}
// @ts-ignore
function hook_native_addr(funcPtr, paramsNum) {
var module = Process.findModuleByAddress(funcPtr);
try {
Interceptor.attach(funcPtr, {
onEnter: function (args) {
this.logs = "";
this.params = [];
// @ts-ignore
this.logs=this.logs.concat("So: " + module.name + " Method: sub_6858 offset: " + ptr(funcPtr).sub(module.base) + "\n");
for (let i = 0; i < paramsNum; i++) {
this.params.push(args);
if (i==1){
this.logs=this.logs.concat("this.args" + i + " onEnter: " +args.readCString());
}
else if(i==3){
this.logs=this.logs.concat("this.args" + i + " onEnter: " +hexdump(args[3]));
}
else {
this.logs=this.logs.concat("this.args" + i + " onEnter: " + print_arg(args));
}
}
}, onLeave: function (retval) {
for (let i = 0; i < paramsNum; i++) {
this.logs=this.logs.concat("this.args" + i + " onLeave: " + print_arg(this.params));
}
this.logs=this.logs.concat("retval onLeave: " + print_arg(retval) + "\n");
console.log(this.logs);
}
});
} catch (e) {
console.log(e);
}
}
// @ts-ignore
hook_native_addr(Module.findBaseAddress("libjdbitmapkit.so").add(0x1882C), 0x4);
})();