Android逆向 dlopen

597 阅读1分钟
//高版本尽量使用,没有详细看各个版本的Android,不过记忆中从Android8.0使用的libdl.so,所以应该8.0及以上
//或者一步到位hook所有dlopen(包括dlopen_ext)都调用的函数do_dlopen,这个函数在linker中,所以需要在linker中找到函数地址,并没有导出,但是没有去符号,可以自己解析
//    void *do_dlopen = dlsym(RTLD_DEFAULT, "__dl__Z9do_dlopenPKciPK17android_dlextinfoPKv");
//    LE("do_dlopen=%p", do_dlopen);
//    dump((void*)do_dlopen, onPreCallBack, onCallBack, "do_dlopen");
void test__loader_dlopen(){
    //因为__loader_dlopen只在libdl.so导入,真正的导出函数是在linker中
    void *__loader_dlopen = dlsym(RTLD_DEFAULT, "__loader_dlopen");//0x7d3ff19dd8
    LE("__loader_dlopen=%p", __loader_dlopen);
    if (!__loader_dlopen) {
        //通过libdl.so拿到的__loader_dlopen地址就是linker导出的函数地址。看源码的话这个__loader_dlopen函数只是调用dlopen_ext,应该因为
        //太短无法hook,不过就是因为太短被和dlopen_ext内联成一个函数了,dlopen_ext未导出。所以可以hook。
        void *dl = dlopen("libdl.so", RTLD_LAZY);
        LE("libdl.so=%p", dl);
        __loader_dlopen = dlsym(dl, "__loader_dlopen");//0x7d3ff19dd8
        LE("__loader_dlopen=%p", __loader_dlopen);
    }
    if (!__loader_dlopen) {
        return;
    } 
    //    dump((void*)__loader_dlopen, onPreCallBack, onCallBack, "__loader_dlopen");
    const RetInfo info = dump_replace((void *) __loader_dlopen, (void *) (my__loader_dlopen), NULL,
                                       NULL, "__loader_dlopen");
    if (info.status != success) {
        LE("hook __loader_dlopen error=%d", info.status);
    }
}