首页
社区
课程
招聘
绕过最新版bilibili app反frida机制
发表于: 2024-5-1 17:31 33529

绕过最新版bilibili app反frida机制

2024-5-1 17:31
33529

安卓的最新版B站APP(7.76.0)有反FRIDA机制,本文介绍一下如何绕过它

截止到2024年5月1日,B站最新版的安卓APP(7.76.0)有反Frida机制,不管是spawn还是attach,都无法注入frida,如下图所示。本文介绍一下如何绕过它

检测Frida的机制一般在Native层实现,通常会创建几个线程轮询检测。首先要知道检测机制是由哪个so实现的,通过hook android_dlopen_ext函数,观察加载到哪个so的时候,触发反调试进程终止即可。Frida脚本代码与输出如下,最终可以定位到检测点在libmsaoaidsec.so中。

使用IDA载入libmsaoaidsec.so,发现没有导入pthread_create符号

使用Frida脚本尝试HOOK pthread_create 函数,也没有找到来自libmsaoaidsec.so的调用

尽管表现有点奇怪,但它一定会调用pthread_create创建检测线程。所以尝试hook dlsym函数,在加载libmsaoaidsec.so之前挂钩dlsym函数,代码如下

输出如下,在加载libmsaoaidsec.so后,调用了2次dlsym获取pthread_create函数,然后进程就终止了。证明它确实会调用pthread_create,只是调用方式不是直接调用,可能采取了一些对抗手段。

它应该是使用了一些反hook的手段,没有必要和它正面对抗。简单描述一下我的绕过策略,创建一个fake_pthread_create函数,它只有一条ret汇编指令,然后hook来自libmsaoaidsec.so的前2次对dlsym的调用,返回fake_pthread_create函数的地址,这样就达成了欺骗它调用fake_pthread_create函数的目的。最终代码如下

执行frida -U -f tv.danmaku.bili -l bypass.js后即可绕过反frida机制,如下图所示

代码也可从github下载,见引用[1]。

[1] https://github.com/ddddhm1234/bypass_bilibili/

var interceptor = 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)
                }
            },
        }
)
var interceptor = 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)
                }
            },
        }
)
var interceptor = Interceptor.attach(Module.findExportByName(null, "pthread_create"),
        {
            onEnter: function (args) {
                var module = Process.findModuleByAddress(ptr(this.returnAddress))
                if (module != null) {
                    console.log("[pthread_create] called from", module.name)
                }
                else {
                    console.log("[pthread_create] called from", ptr(this.returnAddress))
                }
            },
        }
)
var interceptor = Interceptor.attach(Module.findExportByName(null, "pthread_create"),
        {
            onEnter: function (args) {
                var module = Process.findModuleByAddress(ptr(this.returnAddress))
                if (module != null) {
                    console.log("[pthread_create] called from", module.name)
                }
                else {
                    console.log("[pthread_create] called from", ptr(this.returnAddress))
                }
            },
        }
)
function hook_dlsym() {
    var count = 0
    console.log("=== HOOKING dlsym ===")
    var interceptor = Interceptor.attach(Module.findExportByName(null, "dlsym"),
        {
            onEnter: function (args) {
                const name = ptr(args[1]).readCString()
                // const module = Process.findModuleByAddress(ptr(this.returnAddress))
                console.log("[dlsym]", name)
                if (name == "pthread_create") {
                    count++
                }
            }
        }
    )
    return Interceptor
}
 
function hook_dlopen() {
    var interceptor = 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)
                    if (path.indexOf("libmsaoaidsec.so") > -1) {
                        hook_dlsym()
                    }
                }
            },
        }
    )
    return interceptor
}
 
var dlopen_interceptor = hook_dlopen()
function hook_dlsym() {
    var count = 0
    console.log("=== HOOKING dlsym ===")
    var interceptor = Interceptor.attach(Module.findExportByName(null, "dlsym"),
        {
            onEnter: function (args) {
                const name = ptr(args[1]).readCString()
                // const module = Process.findModuleByAddress(ptr(this.returnAddress))
                console.log("[dlsym]", name)
                if (name == "pthread_create") {
                    count++
                }
            }
        }
    )
    return Interceptor
}
 
function hook_dlopen() {
    var interceptor = 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)
                    if (path.indexOf("libmsaoaidsec.so") > -1) {
                        hook_dlsym()
                    }

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2024-5-1 17:31 被天水姜伯约编辑 ,原因: 第一次上传没写标题
收藏
免费 33
支持
分享
最新回复 (23)
雪    币: 9207
活跃值: (6420)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
2024-5-1 21:31
0
雪    币: 3594
活跃值: (31031)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感谢分享
2024-5-1 22:08
1
雪    币: 3729
活跃值: (4111)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
厉害了。
2024-5-2 12:42
0
雪    币: 52
活跃值: (378)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
2024-5-2 13:12
0
雪    币: 1460
活跃值: (1590)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
牛逼了大佬
2024-5-3 10:25
0
雪    币: 489
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
奇怪了,我看了下这个版本的app,我在它那个so init函数的入口处hook pthread_create是可以看到有检测线程的,应该是你下hook的时机没对
2024-5-3 15:25
1
雪    币: 2760
活跃值: (5288)
能力值: ( LV9,RANK:225 )
在线值:
发帖
回帖
粉丝
8
安卓逆向test 奇怪了,我看了下这个版本的app,我在它那个so init函数的入口处hook pthread_create是可以看到有检测线程的,应该是你下hook的时机没对
我发现了,Process.findModuleByAddress(ptr(this.returnAddress)),我在hook pthread_create时尝试获取了返回地址所属的so文件,frida脚本卡在这行代码没动了,我以为没有hook到
2024-5-3 16:04
0
雪    币: 4895
活跃值: (3924)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
牛逼了大佬
2024-5-4 12:11
0
雪    币: 268
活跃值: (871)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
姜师?
2024-5-11 11:54
0
雪    币: 58
活跃值: (1780)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11

厉害了

最后于 2024-5-21 15:58 被道破红尘编辑 ,原因:
2024-5-21 15:58
0
雪    币: 171
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
学习到了,感谢楼主分享。
2024-5-23 14:24
0
雪    币: 171
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
13
安卓逆向test 奇怪了,我看了下这个版本的app,我在它那个so init函数的入口处hook pthread_create是可以看到有检测线程的,应该是你下hook的时机没对
大佬你在那个 so init 函数入口处 hook 的脚本,能发一下吗?
2024-5-23 16:20
0
雪    币: 1609
活跃值: (1340)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
14
學習了 分享一下另外的解決思路, 一種是IO重定向maps(配合魔改的frida), 另一種是直接不加載libmsaoaidsec.so
2024-5-24 11:41
0
雪    币: 4
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15
大哥,我有个问题:我从豌豆荚下载的7.76.0版本的app,我hook了看到只开了一个线程,而且换了线程过不去检测。
之前我也遇到过类似的情况:跟着一个文章操作,app的版本一样,但是结果也是不一样。
您知道这是什么原因吗
2024-5-24 20:58
0
雪    币: 179
活跃值: (694)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
当在Java.perform()中hook java层代码的时候无法绕过反frida机制
2024-5-27 16:59
0
雪    币: 657
活跃值: (5514)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
在启动时候 hook  art中的regitsternative方法好像还是会被检测,我看了一下这个函数调用的返回地址没在本模块内,不知道怎么定位检测了, 楼主有遇到吗?
2024-6-4 11:13
0
雪    币: 8
活跃值: (519)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
你不会就是那个传说中的孔明关门弟子吧
2024-6-5 17:22
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
19
老哥,私一个APP逆向,有偿
2024-7-25 17:02
0
雪    币: 1427
活跃值: (3120)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
感谢分享
2024-7-25 18:28
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
21
老哥,私一个APP逆向,有偿
2024-7-25 21:21
0
雪    币: 3109
活跃值: (2493)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
ariesGinn 当在Java.perform()中hook java层代码的时候无法绕过反frida机制
请问解决了吗
2024-8-5 18:23
0
雪    币: 316
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
23
MANKVIS 请问解决了吗
同问
2024-10-26 15:53
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
24
其实替换一次就行了,打印下retval两次地址你就会发现都是相同的,因为替换的是函数定义,而且不是调用地~~
2024-12-13 16:58
0
游客
登录 | 注册 方可回帖
返回
//