最新版B站frida检测绕过

[复制链接]
查看2716 | 回复3 | 2024-9-27 20:14:32 | 显示全部楼层 |阅读模式

立即注册,突破游客限制,与技术大牛交流切磋,畅享海量资源,让你的技术之路不再孤单!

您需要 登录 才可以下载或查看,没有账号?立即注册

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

方法 (定位检测点):

检测Frida的机制一般在Native层实现,通常会创建几个线程轮询检测。首先要知道检测机制是由哪个so实现的,通过hook android_dlopen_ext函数,观察加载到哪个so的时候,触发反调试进程终止即可。最终可以定位到检测点在libmsaoaidsec.so中。
  1. var interceptor = Interceptor.attach(Module.findExportByName(null, "android_dlopen_ext"),
  2.         {
  3.             onEnter: function (args) {
  4.                 var pathptr = args[0];
  5.                 if (pathptr !== undefined && pathptr != null) {
  6.                     var path = ptr(pathptr).readCString();
  7.                     console.log("[LOAD]", path)
  8.                 }
  9.             },
  10.         }
  11. )
复制代码

对抗(绕过检测点):
使用IDA载入libmsaoaidsec.so,发现没有导入pthread_create符号


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

  1. var interceptor = Interceptor.attach(Module.findExportByName(null, "pthread_create"),
  2.         {
  3.             onEnter: function (args) {
  4.                 var module = Process.findModuleByAddress(ptr(this.returnAddress))
  5.                 if (module != null) {
  6.                     console.log("[pthread_create] called from", module.name)
  7.                 }
  8.                 else {
  9.                     console.log("[pthread_create] called from", ptr(this.returnAddress))
  10.                 }
  11.             },
  12.         }
  13. )
复制代码
分析
尽管表现有点奇怪,但它一定会调用pthread_create创建检测线程。所以尝试hook dlsym函数,在加载libmsaoaidsec.so之前挂钩dlsym函数,代码如下

  1. function hook_dlsym() {
  2.     var count = 0
  3.     console.log("=== HOOKING dlsym ===")
  4.     var interceptor = Interceptor.attach(Module.findExportByName(null, "dlsym"),
  5.         {
  6.             onEnter: function (args) {
  7.                 const name = ptr(args[1]).readCString()
  8.                 // const module = Process.findModuleByAddress(ptr(this.returnAddress))
  9.                 console.log("[dlsym]", name)
  10.                 if (name == "pthread_create") {
  11.                     count++
  12.                 }
  13.             }
  14.         }
  15.     )
  16.     return Interceptor
  17. }
  18. function hook_dlopen() {
  19.     var interceptor = Interceptor.attach(Module.findExportByName(null, "android_dlopen_ext"),
  20.         {
  21.             onEnter: function (args) {
  22.                 var pathptr = args[0];
  23.                 if (pathptr !== undefined && pathptr != null) {
  24.                     var path = ptr(pathptr).readCString();
  25.                     console.log("[LOAD]", path)
  26.                     if (path.indexOf("libmsaoaidsec.so") > -1) {
  27.                         hook_dlsym()
  28.                     }
  29.                 }
  30.             },
  31.         }
  32.     )
  33.     return interceptor
  34. }
  35. var dlopen_interceptor = hook_dlopen()
复制代码
在加载libmsaoaidsec.so后,调用了2次dlsym获取pthread_create函数,然后进程就终止了。证明它确实会调用pthread_create,只是调用方式不是直接调用,可能采取了一些对抗手段。

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

如下:
  1. function create_fake_pthread_create() {
  2.     const fake_pthread_create = Memory.alloc(4096)
  3.     Memory.protect(fake_pthread_create, 4096, "rwx")
  4.     Memory.patchCode(fake_pthread_create, 4096, code => {
  5.         const cw = new Arm64Writer(code, { pc: ptr(fake_pthread_create) })
  6.         cw.putRet()
  7.     })
  8.     return fake_pthread_create
  9. }
  10. function hook_dlsym() {
  11.     var count = 0
  12.     console.log("=== HOOKING dlsym ===")
  13.     var interceptor = Interceptor.attach(Module.findExportByName(null, "dlsym"),
  14.         {
  15.             onEnter: function (args) {
  16.                 const name = ptr(args[1]).readCString()
  17.                 console.log("[dlsym]", name)
  18.                 if (name == "pthread_create") {
  19.                     count++
  20.                 }
  21.             },
  22.             onLeave: function(retval) {
  23.                 if (count == 1) {
  24.                     retval.replace(fake_pthread_create)
  25.                 }
  26.                 else if (count == 2) {
  27.                     retval.replace(fake_pthread_create)
  28.                     // 完成2次替换, 停止hook dlsym
  29.                     interceptor.detach()
  30.                 }
  31.             }
  32.         }
  33.     )
  34.     return Interceptor
  35. }
  36. function hook_dlopen() {
  37.     var interceptor = Interceptor.attach(Module.findExportByName(null, "android_dlopen_ext"),
  38.         {
  39.             onEnter: function (args) {
  40.                 var pathptr = args[0];
  41.                 if (pathptr !== undefined && pathptr != null) {
  42.                     var path = ptr(pathptr).readCString();
  43.                     console.log("[LOAD]", path)
  44.                     if (path.indexOf("libmsaoaidsec.so") > -1) {
  45.                         hook_dlsym()
  46.                     }
  47.                 }
  48.             }
  49.         }
  50.     )
  51.     return interceptor
  52. }
  53. // 创建虚假pthread_create
  54. var fake_pthread_create = create_fake_pthread_create()
  55. var dlopen_interceptor = hook_dlopen()
复制代码
执行frida -U -f tv.danmaku.bili -l bypass.js后即可绕过反frida机制


这个人还没有签名
TheRain | 2024-9-27 23:01:13 | 显示全部楼层
学到了
这个人还没有签名
ZERO_666666 | 2024-9-29 10:46:51 来自手机 | 显示全部楼层
谢谢分享
这个人还没有签名
alert | 2024-11-9 16:09:13 | 显示全部楼层
这个人还没有签名
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则