-
本地数据库:databases/sdk_storage/{UID-MD5}/messages.db
-
加密方式:SQLCipher
1. SQLCipher 调用栈
Hook open 系统调用,查看 messages.db 的调用栈:
// int open(const char *pathname, int flags, mode_t mode);
Interceptor.attach(Module.findExportByName(null, "open"), {
onEnter: function (args) {
const pathname = args[0].readCString()
if (pathname.endsWith("messages.db")) {
console.log("open: " + pathname)
console.log(Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n'));
}
}
})
结果如下,来自 liblark.so 的 Native 层调用:
2. Hook 数据库密钥
Hook libsqlcipher.so 导出函数看看密钥,脚本就不贴了:
结果如下:
应用数据中未发现密钥字符串,继续分析密钥来源。
3. 通过 memcpy 切入
如果密钥是运行时生成,再进行字符串操作生成SQL命令,那么这个过程很可能会用到 memcpy 函数。
在合适的时机调用hookMemcpy(),可以Hook到和密钥生成相关的函数地址。
function hookMemcpy() {
Interceptor.attach(Module.findExportByName("libc.so", "memcpy"), {
onEnter: function (args) {
if (args[2].toUInt32() === 32) {
let hex = arrayBufferToHex(args[1].readByteArray(32));
if (hex.indexOf("9e144d3f7cd1") >= 0) {
console.log("FIND!: \n" + hexdump(args[1], {length: 32}))
console.log(Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n'));
console.log("---------------------")
}
}
}
});
}
未完待续。。。