const targetSoName = "xxx.so";
setTimeout(() => {
const base = Module.findBaseAddress(targetSoName);
if (!base) {
console.error("[-] Failed to find base address of " + targetSoName);
return;
}
const offset = 0xxxx;
const targetFunc = base.add(offset);
console.log("[*] Hooking Encrypt at: " + targetFunc);
Interceptor.attach(targetFunc, {
onEnter(args) {
const keyPtr = args[1]; // 参数: 密钥地址
const keyLen = args[2].toInt32();
const fixedKey = "xWRp0rWxVliUzQEi";
if (keyLen >= fixedKey.length) {
Memory.writeUtf8String(keyPtr, fixedKey);
console.log("[*] Overridden key with: " + fixedKey);
} else {
console.warn("[!] Key buffer too small, cannot overwrite.");
}
},
onLeave(retval) {
}
});
}, 10000);
脚本里面预留了两个xxx的地方,分别是具体的so名称
const targetSoName = "xxx.so"
加密算法具体的偏移地址
const offset = 0xxxx;
具体是哪个so文件,其实很好定位,这里就不多展开赘述(感兴趣的师傅可以查看文末获取完整逆向过程)主要是偏移地址改怎么计算,看起来很难,其实很简单,只需要把下面的脚本中xxx.so替换成实际的so名称,即可导出该so文件的所有导出函数名称/地址/偏移地址信息
const moduleName = "xxx.so";
const module = Process.findModuleByName(moduleName);
if (!module) {
console.log(`[-] 模块 ${moduleName} 尚未加载`);
} else {
console.log(`[+] 模块 ${moduleName} 已加载`);
console.log(`[+] 基地址: ${module.base}`);
console.log(`[+] 导出函数列表:n`);
const exports = Module.enumerateExports(moduleName);
exports.forEach(exp => {
if (exp.type === "function") {
const offset = exp.address.sub(module.base);
console.log(`[*] ${exp.name} @ ${exp.address} | 偏移: ${offset}`);
}
});
}
用这个方法能立刻确定目标函数的偏移地址信息,将已知信息填入脚本中,运行一下这个脚本,由于我们已经固定了动态密钥为
xWRp0rWxVliUzQEi
所以我们可以直接编写脚本,测试解密抓包中的关键加密数据。妈妈再也不用替我担心动态密钥的问题啦。
原文始发于微信公众号(跟着斯叔唠安全):还搞定不了APP so层算法使用动态密钥加密传输?手把手教会你!
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论