Frida反调试对抗系列(四)百度加固

 本文只是交流技术,如有侵权请联系我删除。

知识星球:https://t.zsxq.com/kNlj4 

前言:

上一篇文章我们提到 我们使用github开源魔改好的frida server

但是仍然有一些厂商的server不能通过,那么这篇文章针对百度加固 进行快速通过frida反调试,首先针对JAVA API部分第一节已经提到不再多说。

大家可以 看看 参考文章 APP使用frida反调试检测绕过 - 树大招疯 - 博客园

测试样本一 百度加固 小米汽车 1.8.2

按照检测思路,一般会用pthread_create起线程

绕过的方法很简单,直接nop掉pthread_create或者替换检测函数的代码逻辑都可以

function create_pthread_create() {
    const pthread_create_addr = Module.findExportByName(null, "pthread_create");
    const pthread_create = new NativeFunction(pthread_create_addr, "int", ["pointer", "pointer", "pointer", "pointer"]);
// new NativeCallback(...)
// NativeCallback用于创建一个新的回调函数,在这个回调中,我们可以定义拦截后的行为。这里是重写pthread_create函数的逻辑。
// pargparg1,parg2,parg3是pthread_create的四个参数,通常是:
// parg0: 线程的地址或 ID。
// parg1: 线程的栈大小。
// parg2: 线程的入口地址(即线程函数)。
// parg3: 传递给线程的参数
    return new NativeCallback((parg0, parg1, parg2, parg3) => {
        // 获取线程入口地址的模块信息
        const module = Process.findModuleByAddress(parg2);
        const so_name = module.name;
        const baseAddr = module.base;
        // 打印线程的相关信息
        console.log("pthread_create", so_name, "0x" + parg2.sub(baseAddr).toString(16), "0x" + parg3.toString(16));


        // 调用原始的 pthread_create 执行线程创建
        return pthread_create(parg0, parg1, parg2, parg3);
    }, "int", ["pointer", "pointer", "pointer", "pointer"]);
}

function replace_thread() {
    var new_pthread_create = create_pthread_create();
    var pthread_create_addr = Module.findExportByName(null, "pthread_create");

    //替换 pthread_create 函数
    Interceptor.replace(pthread_create_addr, new_pthread_create);
}

// 启动初次替换
replace_thread();

测试样本二 百度加固 追书神器 3.45.38

用第一个js会导致卡死:由于使用 Process.findModuleByName 时出现卡死(即程序挂起、无响应等问题),有几种可能的原因,通常涉及到模块加载状态、权限问题或程序的多线程操作等

所以流程改变一下换一种方式 条条大路同罗马:

function hook_dlopen() {
    Interceptor.attach(Module.findExportByName(null, "android_dlopen_ext"), {
        onEnter: function (args) {
            var pathptr = args[0];
            if (pathptr !== undefined && pathptr != null) {
                var path = ptr(pathptr).readCString();
                console.log(path)
            }
        },
        onLeave: function (retval) {
        }
    });
}

hook_dlopen()

我们先确定 哪个so退出了 是 libmsaoaidsec.so

案例1的js代码可以得到 libmsaoaidsec.so 的进程偏移

pthread_create libmsaoaidsec.so 0x1c544 0x731552b960
pthread_create libmsaoaidsec.so 0x1b8d4 0x0
pthread_create libmsaoaidsec.so 0x26e5c 0x0

采用另一种方式nop掉

function hook_dlopen(soName = '') {
    Interceptor.attach(Module.findExportByName(null, "android_dlopen_ext"),
        {
            onEnter: function (args) {
                var pathptr = args[0];
                if (pathptr !== undefined && pathptr != null) {
                    var path = ptr(pathptr).readCString();
                    if (path.indexOf(soName) >= 0) {
                        locate_init()
                    }
                }
            }
        }
    );
}

function locate_init() {
    let secmodule = null
    Interceptor.attach(Module.findExportByName(null, "__system_property_get"),
        {
            // _system_property_get("ro.build.version.sdk", v1);
            onEnter: function (args) {
                secmodule = Process.findModuleByName("libmsaoaidsec.so")
                var name = args[0];
                if (name !== undefined && name != null) {
                    name = ptr(name).readCString();
                    if (name.indexOf("ro.build.version.sdk") >= 0) {
                        // 这是.init_proc刚开始执行的地方,是一个比较早的时机点
                        // do something
                        // hook_pthread_create()
                        bypass()
                    }
                }
            }
        }
    );
}

function hook_pthread_create() {
    console.log("libmsaoaidsec.so --- " + Process.findModuleByName("libmsaoaidsec.so").base)
    Interceptor.attach(Module.findExportByName("libc.so", "pthread_create"), {
        onEnter(args) {
            let func_addr = args[2]
            console.log("The thread function address is " + func_addr)
        }
    })
}

function nopFunc(parg2) {
    // 修改内存保护,使其可写
    Memory.protect(parg2, 4, 'rwx');
    // 使用 Arm64Writer 写入 'ret' 指令
    var writer = new Arm64Writer(parg2);
    writer.putRet();
    writer.flush();
    writer.dispose();
    console.log("nop " + parg2 + " success");
}

function bypass(){
    let module = Process.findModuleByName("libmsaoaidsec.so")
    nopFunc(module.base.add(0x1c544))
    nopFunc(module.base.add(0x1b8d4))
    nopFunc(module.base.add(0x26e5c))

}
// pthread\_create libmsaoaidsec.so 0x1c544 0x731552b960\
// pthread\_create libmsaoaidsec.so 0x1b8d4 0x0\
// pthread\_create libmsaoaidsec.so 0x26e5c 0x0

setImmediate(hook_dlopen, "libmsaoaidsec.so")

my:
 

let WX = 15232101239

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值