吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 403|回复: 7
上一主题 下一主题
收起左侧

[Android 原创] 某痛单词过frida检测

  [复制链接]
跳转到指定楼层
楼主
bingyue 发表于 2025-1-8 20:47 回帖奖励

小白第一次发帖,可能写的不太好,见谅


本文已同步到本人博客,本人博客为

5Yaw5pyI5Y2a5a6i


今天来给大家分享一个案例,某某单词app,由于该app有反调试,本文就介绍一下如何绕过他的反调试


参考资料

绕过最新版bilibili app反frida机制

绕过bilibili frida反调试


开始

检测Frida的机制一般在Native层实现,通常会创建几个线程轮询检测。首先要知道检测机制是由哪个so实现的,通过hook android_dlopen_ext函数,观察加载到哪个so的时候,触发反调试进程终止即可。下面我们来试一下

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("load " + path);
        }
    }
}
);

可以看到,在加载libmsaoaidsec.so后,frida挂掉了

现在直接注入我们的线程替换脚本,看看这个so加载的线程

function check_pthread_create(name = null) {
    var pthread_create_addr = Module.findExportByName(null, 'pthread_create');

    var pthread_create = new NativeFunction(pthread_create_addr, "int", ["pointer", "pointer", "pointer", "pointer"]);
    Interceptor.replace(pthread_create_addr, new NativeCallback(function (parg0, parg1, parg2, parg3) {
        var module = Process.findModuleByAddress(parg2)
        var so_base = module.base;
        var off = "0x" + parg2.sub(so_base).toString(16)
        var so_name = module.name;
        console.log(so_name, off, parg3)

        return pthread_create(parg0, parg1, parg2, parg3);

    }, "int", ["pointer", "pointer", "pointer", "pointer"]))
}
setImmediate(check_pthread_create)

这里创建了三个线程,内存偏移量为0x1c5440x1b8d40x26e5c注:画线的地方不是检测线程,请看清楚so名字

现在回去改dlopen,如果这个so一加载就nop线程

结果不尽人意,这里获取不了libmsaoaidsec.so的基址

因为安卓加载so整个流程如下

linker->init_proc ->JNI_OnLoad 

dlopen获取基址,是要等jni加载后的,但是现在jni还没加载我们的frida就被杀掉了,说明检测在init_proc里,我们需要寻找一个合适的hook时机

现在我们打开ida,把so拖进去,静态分析

这里我尝试过寻找发起线程的地方,但从导入函数并没有看到,pthread_create相关字样,他应该是间接调用的,但是我们已经知道了线程的偏移量,所以这里不太重要了

接下来我们继续看init_proc ,这里被ollvm混淆了,转成伪c代码,通过交叉引用,可以得到他是先执行sub_123f0

可以看到sub_123f0_system_property_get调用了一个ro.build.version.sdk,这里我们从注入system_property_get是个不错的选择,因为他是在init.proc阶段执行的

现在我们去hook_system_property_get

function locate_init() {
    let r = null
    Interceptor.attach(Module.findExportByName(null, "__system_property_get"),
        {
            onEnter: function (args) {
                var name = args[0];
                if (name !== undefined && name != null) {
                    name = ptr(name).readCString();
                    console.log(name)
                    if (name.indexOf("ro.build.version.sdk") >= 0) {
                       console.log(Process.findModuleByName("libmsaoaidsec.so").base)
                    }
                }
            }
        }
    );
}

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.search("libmsaoaidsec.so") != -1){
                this.hook = true
                locate_init()
            }
        }
    }
}
);

输出如下,我们成功获取到了基址

那我们就nop上面提到的偏移量吧

完美绕过frida检测


完整代码

function locate_init() {
    let r = null
    Interceptor.attach(Module.findExportByName(null, "__system_property_get"),
        {
            onEnter: function (args) {
                var name = args[0];
                if (name !== undefined && name != null) {
                    name = ptr(name).readCString();
                    //console.log(name)
                    if (name.indexOf("ro.build.version.sdk") >= 0) {
                      var  r = Process.findModuleByName("libmsaoaidsec.so")
                      nop_64(r.base.add("0x1c544"))
                      nop_64(r.base.add("0x1b8d4"))
                      nop_64(r.base.add("0x26e5c"))
                    }
                }
            }
        }
    );
}

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.search("libmsaoaidsec.so") != -1){
                this.hook = true
                locate_init()
            }
        }
    }
}
);

function nop_64(addr) {
    Memory.protect(addr, 4 , 'rwx');
    var w = new Arm64Writer(addr);
    w.putRet();
    w.flush();
    w.dispose();
}

免费评分

参与人数 10威望 +1 吾爱币 +29 热心值 +10 收起 理由
Hameel + 1 热心回复!
正己 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
wanws + 1 + 1 谢谢@Thanks!
0jiao0 + 1 + 1 用心讨论,共获提升!
杨辣子 + 1 + 1 用心讨论,共获提升!
CrazyNut + 3 + 1 用心讨论,共获提升!
yxnwh + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
clabobo + 1 谢谢@Thanks!
无问且问 + 1 + 1 谢谢@Thanks!
Hawcett + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

沙发
clabobo 发表于 2025-1-9 11:49
这么说 其实所有对 frida的检测和 xposed的检测都可以被 绕过
3#
huagequan 发表于 2025-1-9 12:48
4#
stw8899 发表于 2025-1-9 14:05
5#
laoser 发表于 2025-1-9 14:17
清晰值得推荐
6#
Owenpojie 发表于 2025-1-9 16:15
这个是真的厉害!
7#
llfly 发表于 2025-1-9 16:38
思路清晰明了 学习了!
8#
linix 发表于 2025-1-10 08:04
感谢大佬分享,很好的思路
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-1-10 08:29

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表