APP信息
包名:com.douban.frodo
反调试分析
frida尝试注入,如下图直接就挂掉了,说明我们的frida被检测到了
定位so文件
我们需要知道在哪个so文件中加载的线程检测到了我们的firda,可以通过frida hook dlopen方法。
function hook_dlopen(){
//Android8.0之后加载so通过android_dlopen_ext函数
var android_dlopen_ext = Module.findExportByName(null,"android_dlopen_ext");
console.log("addr_android_dlopen_ext",android_dlopen_ext);
Interceptor.attach(android_dlopen_ext,{
onEnter:function(args){
var pathptr = args[0];
if(pathptr!=null && pathptr != undefined){
var path = ptr(pathptr).readCString();
console.log("android_dlopen_ext:",path);
}
},
onLeave:function(retvel){
console.log("leave!");
}
})
}
hook_dlopen()
hook结果如下,是在libmsaoaidsec.so
这个so文件中加载的线程检测到的frida。
定位检测函数
我们可以hook pthread方法来定位检测函数。
function hook_dlopen(){
//Android8.0之后加载so通过android_dlopen_ext函数
var android_dlopen_ext = Module.findExportByName(null,"android_dlopen_ext");
console.log("addr_android_dlopen_ext",android_dlopen_ext);
Interceptor.attach(android_dlopen_ext,{
onEnter:function(args){
var pathptr = args[0];
if(pathptr!=null && pathptr != undefined){
var path = ptr(pathptr).readCString();
if(path.indexOf("libmsaoaidsec.so")!=-1){
console.log("android_dlopen_ext:",path);
hook_pthread()
}
}
},
onLeave:function(retvel){
console.log("leave!");
}
})
}
function hook_pthread() {
var pth_create = Module.findExportByName("libc.so", "pthread_create");
console.log("[pth_create]", pth_create);
Interceptor.attach(pth_create, {
onEnter: function (args) {
var module = Process.findModuleByAddress(args[2]);
if (module != null) {
console.log("address", module.name, args[2].sub(module.base));
}
},
onLeave: function (retval) {}
});
}
function main(){
hook_dlopen()
}
main()
hook结果如下,找到三个函数
替换函数
这里我们把这三个函数函数逻辑替换为空就可以实现绕过。
需要注意的是,我们要找一个合适的时机来替换这三个函数,最好的时机是在dlopen函数加载so的时候的时候,对函数的初始化进行替换。
这里选择hook call_constructors
函数。
function hook_dlopen(){
//Android8.0之后加载so通过android_dlopen_ext函数
var android_dlopen_ext = Module.findExportByName(null,"android_dlopen_ext");
console.log("addr_android_dlopen_ext",android_dlopen_ext);
Interceptor.attach(android_dlopen_ext,{
onEnter:function(args){
var pathptr = args[0];
if(pathptr!=null && pathptr != undefined){
var path = ptr(pathptr).readCString();
if(path.indexOf("libmsaoaidsec.so")!=-1){
console.log("android_dlopen_ext:",path);
hook_call_constructors()
}
}
},
onLeave:function(retvel){
//console.log("leave!");
}
})
}
function hook_call_constructors() {
var linker64_base_addr = Module.getBaseAddress("linker64")
var call_constructors_func_off = 0x2C274 //这个地址是从手机上把linker64 pull出来,然后到IDA中找到的,不同的机型,地址可能不一样
var call_constructors_func_addr = linker64_base_addr.add(call_constructors_func_off)
var listener = Interceptor.attach(call_constructors_func_addr, {
onEnter: function (args) {
console.log("hooked call_constructors")
var module = Process.findModuleByName("libmsaoaidsec.so")
if (module != null) {
Interceptor.replace(module.base.add(0x1c544), new NativeCallback(function () {
console.log("0x1c544:替换成功")
}, "void", []))
Interceptor.replace(module.base.add(0x1b924), new NativeCallback(function () {
console.log("0x1B924:替换成功")
}, "void", []))
Interceptor.replace(module.base.add(0x26e5c), new NativeCallback(function () {
console.log("0x26e5c:替换成功")
}, "void", []))
listener.detach()
}
},
})
}
function main(){
hook_dlopen()
}
main()
hook结果如下,frida检测成功绕过!!
参考文章:https://mp.weixin.qq.com/s/i_k_QOfgAV33_2u9T4OnxA