Android的dex文件整体脱壳的脱壳点很多,今天试了下通过hook OpenCommon函数来dump内存中的dex文件,OpenCommon函数是在libart.so这个文件中,通过Process.findModuleByName("libart.so")获取so文件的加载信息,枚举so中的方案,获取到OpenCommon函数地址,对其进行hook,通过OpenCommon的第二个参数args[1]为dex文件的加载基址,第三个参数args[2]为dex文件的大小。
配置好frida环境之后,执行如下命令:frida -U -f com.***** -l OpenCommon.js
其中com开头为要hook的apk包名,OpenCommon.js为注入的js代码的文件名。
hook的js代码如下:
javascript
function hook_native(){
var module_libart=Process.findModuleByName("libart.so");
console.log("module_libart base:"+module_libart.base);
var symbols=module_libart.enumerateSymbols();
var addr_OpenCommon=null;
for(var i=0;i<symbols.length;i++){
var name=symbols[i].name;
if(name.indexOf("OpenCommon")>0){
console.log("OpenCommon name:"+name+"\n"+"OpenCommon addr:"+symbols[i].address);
addr_OpenCommon=symbols[i].address;
}
}
if(addr_OpenCommon){
Interceptor.attach(addr_OpenCommon,{
onEnter:function(args){
var dex_begin = args[1];
//var size = args[2];//参数中的文件大小和dex基地址加偏移取出来的dex的大小是一样的
console.log("magic: " + Memory.readUtf8String(dex_begin));
var filesize_address = parseInt(dex_begin,16) + 0x20;
var dex_size = Memory.readInt(ptr(filesize_address));
console.log("dex_begin:" + dex_begin);
console.log("dex_size :" + dex_size);
var filename="/data/data/com.qujianpan.client.fast/" + dex_size + "opencommon.dex";
console.log("filename:" + filename);
var file = new File(filename, "wb");
file.write(Memory.readByteArray(dex_begin, dex_size));
file.flush();
file.close();
},onLeave:function(retval){
}
})
}
}
function main(){
hook_native();
}
setImmediate(main)