need to patch");//在这里patch hook_pthread_create(); // bypass() //这里可以开始进行HOOK } } } });}function call_func(){ console.log("frida call_func")}function hook_pthread_create() { var pthread_create = Module.findExportByName("libc.so"。
"void"。
onLeave: function(retval) {} });} 这里是可以绕过XHS的frida检测的。
说明是在之前进行frida检测 } } } });}setImmediate(hook_dlopen,frida检测的是在JNI_Onload函数之前,在我的so文件执行流程的过程中有细节分析,那么我们也可以对于这里的三个线程进行NOP 这里按照最原始的方法, { onEnter: function(args) { var thread_ptr = args[2]; if (thread_ptr.compare(libmsaoaidsec.base) 0 || thread_ptr.compare(libmsaoaidsec.base.add(libmsaoaidsec.size)) = 0) { console.log("pthread_create other thread: " + thread_ptr); } else { console.log("pthread_create libmsaoaidsec.so thread: " + thread_ptr + " offset: " + thread_ptr.sub(libmsaoaidsec.base)); } },不去NOP掉 pthead_create函数 。
直接frida就被检测了, onLeave:function(){ } })}function hook_system_property_get() { var system_property_get_addr = Module.findExportByName(null, 个人博客: b站frida反检测分析绕过 - fisherman-ovo - 博客园[/md] 本文章中所有内容仅供学习交流使用,作者并没有去实现正面对抗, 下载次数: 3) 下载附件 2025-3-6 16:01 上传 但是其实我们通过之前的方法也能看到对应的pthead_create创建线程的位置 function hook_dlopen(soName = '') { Interceptor.attach(Module.findExportByName(null, path) if (path.indexOf("libmsaoaidsec.so") -1) { hook_dlsym() } } } } ) return interceptor}// 创建虚假pthread_createvar fake_pthread_create = create_fake_pthread_create()var dlopen_interceptor = hook_dlopen() image-20250306153129200.png (2.25 MB, { onEnter: function(args) { var pathptr = args[0]; if (pathptr) { var path = ptr(pathptr).readCString(); console.log("Loading: " + path); if (path.indexOf(soName) = 0) { console.log("Already loading: " + soName); hook_system_property_get(); } } } });}function hook_system_property_get() { var system_property_get_addr = Module.findExportByName(null,也能实现绕过的,这里的frida检测有了三个线程,有时间学习一下, { onEnter: function(args) { var pathptr = args[0]; if (pathptr) { var path = ptr(pathptr).readCString(); console.log("Loading: " + path); if (path.indexOf(soName) = 0) { console.log("Already loading: " + soName); hook_system_property_get(); } } } });}function hook_system_property_get() { var system_property_get_addr = Module.findExportByName(null。
同时在其他高版本的各种frida检测中,4,也开始去检测pthread_create是否被HOOK了, image-20250304174423941.png (109.82 KB。
可以直接在导入表里面找到的, "pthread_create"); var libmsaoaidsec = Process.findModuleByName("libmsaoaidsec.so"); if (!libmsaoaidsec) { console.log("libmsaoaidsec.so not found"); return; } console.log("libmsaoaidsec.so base: " + libmsaoaidsec.base); if (!pthread_create) { console.log("pthread_create not found"); return; } Interceptor.attach(pthread_create,"libmsaoaidsec.so")function hook_JNI(){ let module_msaoaidsec = Process.findModuleByName("libmsaoaidsec.so") if(!module_msaoaidsec){ console.log("module_msaoaidsec wrong") } console.log("get module_msaoaidsec") Interceptor.attach(module_msaoaidsec.base.add(0x013A4C+1),原作者使用了hook _system_property_get函数,去判断检测函数在JNI_Onload之前还是之后,在这里之前,这里是 init_proc函数较早的位置,[])) Interceptor.replace(libmsaoaidsec.base.add(0x1b8d4), onLeave: function(retval) { if (count == 1) { retval.replace(fake_pthread_create) } else if (count == 2) { retval.replace(fake_pthread_create) // 完成2次替换,也是在system_property_get的函数的位置进行HOOK的, 下载次数: 3) 下载附件 2025-3-6 16:01 上传 image-20250304175126362.png (19.96 KB, { onEnter: function(args) { var thread_ptr = args[2]; if (thread_ptr.compare(libmsaoaidsec.base) 0 || thread_ptr.compare(libmsaoaidsec.base.add(libmsaoaidsec.size)) = 0) { console.log("pthread_create other thread: " + thread_ptr); } else { console.log("pthread_create libmsaoaidsec.so thread: " + thread_ptr + " offset: " + thread_ptr.sub(libmsaoaidsec.base)); } },但是实际上这里的位置也已经被混淆了,[])) Interceptor.replace(libmsaoaidsec.base.add(0x26e5c),以及其中的NOP的实际。
我们就可以判断大概率就是被混淆了的pthead_create函数 正面对抗 按照之前旧版本的frida检测,我这里也是测试过的,所以大概率的可能是在libmsaoaidsec.so进行的frida检测, "rwx") Memory.patchCode(fake_pthread_create, { onEnter: function(args) { var nameptr = args[0]; if (nameptr) { var name = ptr(nameptr).readCString(); if (name.indexOf("ro.build.version.sdk") = 0) { console.log("Found ro.build.version.sdk, "android_dlopen_ext")。
[])) } }, 参考文章:[原创]绕过bilibili frida反调试-Android安全-看雪-安全社区|安全招聘|kanxue.com bilibili7.76.0 7.26.1: image-20250305141556864.png (45.56 KB, code = { const cw = new Arm64Writer(code,那么我们就去交叉引用看看在哪引用的 image-20250305144950838.png (44.54 KB, "pthread_create"); var libmsaoaidsec = Process.findModuleByName("libmsaoaidsec.so"); if (!libmsaoaidsec) { console.log("libmsaoaidsec.so not found"); return; } console.log("libmsaoaidsec.so base: " + libmsaoaidsec.base); if (!pthread_create) { console.log("pthread_create not found"); return; } Interceptor.attach(pthread_create,{pc:ptr(addr)}); cw.putNop(); cw.putNop(); cw.flush(); })}function bypass(){ let module = Process.findModuleByName("libmsaoaidsec.so") nop_code(module.base.add(0x010AE4)) nop_code(module.base.add(0x113F8))}setImmediate(hook_dlopen, { onEnter: function(args) { var thread_ptr = args[2]; if (thread_ptr.compare(libmsaoaidsec.base) 0 || thread_ptr.compare(libmsaoaidsec.base.add(libmsaoaidsec.size)) = 0) { console.log("pthread_create other thread: " + thread_ptr); } else { console.log("pthread_create libmsaoaidsec.so thread: " + thread_ptr + " offset: " + thread_ptr.sub(libmsaoaidsec.base)); } },这里可以去patch frida检测 // hook_JNI() // setTimeout(hook_JNI, 下载次数: 3) 下载附件 2025-3-6 16:01 上传 image-20250305103007170.png (119.26 KB,但是我们既然能通过这个代码找到对应的线程,这里多半也就是进行frida检测的位置的了 pthread_create libmsaoaidsec.so thread: 0x76bcce0544 offset: 0x1c544pthread_create libmsaoaidsec.so thread: 0x76bccdf8d4 offset: 0x1b8d4pthread_create libmsaoaidsec.so thread: 0x76bcceae5c offset: 0x26e5c 同时这里我们进行HOOK的检测frida线程在哪的时候, "android_dlopen_ext"), "android_dlopen_ext")。
下载次数: 3) 下载附件 2025-3-6 16:02 上传 image-20250305150437030.png (19.08 KB。
去HOOK JNI_Onload函数,说明实际上还是去执行了 _system_property_get(ro.build.version.sdk) 这个函数的,"void", { onEnter: function (args) { var pathptr = args[0]; if (pathptr !== undefined pathptr != null) { var path = ptr(pathptr).readCString(); console.log("[LOAD]"。
而且既然代码可以直接检测得到frida检测的线程的地址,"void",在前两次进行调用pthead_create函数时。
下载次数: 2) 下载附件 2025-3-6 16:01 上传 这里就绕过frida了,[])) Interceptor.replace(libmsaoaidsec.base.add(0x26e5c),比如像 pthread_create 会去调用更底层的 clone函数 同样的的还会去调用Sys_clone函数, 下载次数: 3) 下载附件 2025-3-6 16:01 上传 image-20250305102030763.png (25.16 KB,而是去patch掉对应的frida函数, "__system_property_get"); if (!system_property_get_addr) { console.log("__system_property_get not found"); return; } Interceptor.attach(system_property_get_addr,new NativeCallback(function(){ console.log("Interceptor.replace: 0x1c544") }, function hook_dlopen(soName = '') { Interceptor.attach(Module.findExportByName(null,{ onEnter:function() { console.log("JNI_onLoad") },达成绕过, 下载次数: 4) 下载附件 2025-3-6 16:02 上传 同样也可以实现绕过, "libmsaoaidsec.so"); image-20250305144616783.png (860.96 KB, { onEnter: function(args) { var pathptr = args[0]; if (pathptr) { var path = ptr(pathptr).readCString(); console.log("Loading: " + path); if (path.indexOf(soName) = 0) { console.log("Already loading: " + soName); hook_system_property_get()//这里是在__system_property_get之后进行的frida检测,在7.26.1中frida检测是有两个线程的。
在dlopen了之后, bilibili的旧版本frida检测 image-20250304173059677.png (323.94 KB, 停止hook dlsym interceptor.detach() } } } ) return Interceptor}function hook_dlopen() { var interceptor = Interceptor.attach(Module.findExportByName(null。
"__system_property_get"); if (!system_property_get_addr) { console.log("__system_property_get not found"); return; } Interceptor.attach(system_property_get_addr,而在7.76.0中, "libmsaoaidsec.so"); image-20250304173504546.png (439.55 KB,new NativeCallback(function(){ console.log("Interceptor.replace: 0x1c544") },当对应的线程的地址在libmsaoaidsec.so的地址区域内的时候, "pthread_create"); var libmsaoaidsec = Process.findModuleByName("libmsaoaidsec.so"); if (!libmsaoaidsec) { console.log("libmsaoaidsec.so not found"); return; } console.log("libmsaoaidsec.so base: " + libmsaoaidsec.base); if (!pthread_create) { console.log("pthread_create not found"); return; } Interceptor.attach(pthread_create,共获提升! 就往丶 + 1 + 1 我很赞同! 查看全部评分 , { onEnter: function(args) { var nameptr = args[0]; if (nameptr) { var name = ptr(nameptr).readCString(); if (name.indexOf("ro.build.version.sdk") = 0) { console.log("Found ro.build.version.sdk, 下载次数: 3) 下载附件 2025-3-6 16:01 上传 其实是能够发现还是在init_proc的sub_123F0函数的位置的 image-20250305145110772.png (38.4 KB,[])) Interceptor.replace(libmsaoaidsec.base.add(0x1b8d4),"void",并且开始进行frida检测线程创建的pthead_create函数时期 function hook_pthread_create() { var pthread_create = Module.findExportByName("libc.so",去调用fake_pthead_create函数。
通过的方式就是在HOOK dlsym函数,通过dlopen的位置去HOOK system_property_get 当参数是ro.build.version.sdk然后去hook pthread_create dlopen ———system_property_get————pthread_create image-20250305101304937.png (1005.51 KB,其实是发现在libmsaoaidsec.so一共是开启了三个线程的,。
可以看到这里有两个线程出现了 我们可以去通过IDA看看 image-20250305101938410.png (91.55 KB,来看看对于frida检测的线程是在哪里启动的。
onLeave: function(retval) {} });} image-20250306152208226.png (1.89 MB,"void", function hook_pthread_create() { var pthread_create = Module.findExportByName("libc.so", 下载次数: 3) 下载附件 2025-3-6 16:01 上传 image-20250305150358745.png (14.73 KB,[])) num++ } } },擅自使用本文讲解的技术而导致的任何意外。
不用于其他任何目的, pthread_create —— clone ——Sys_clone等多种方式, 下载次数: 3) 下载附件 2025-3-6 16:01 上传 image-20250305145028014.png (72.21 KB, { pc: ptr(fake_pthread_create) }) cw.putRet() }) return fake_pthread_create}function hook_dlsym() { var count = 0 console.log("=== HOOKING dlsym ===") var interceptor = Interceptor.attach(Module.findExportByName(null。
以下是取巧绕过的代码(复制于上面的网址): function create_fake_pthread_create() { const fake_pthread_create = Memory.alloc(4096) Memory.protect(fake_pthread_create,这里是在JNI_Onload之前出现的frida检测, onLeave: function(retval) {} });} 在这里我们通过去HOOK dlopen的位置,我们需要知道是在哪进行HOOK是最为有用的 这里我们可以通过在dlopen结束之后, 停止hook dlsym interceptor.detach() } } [md]# XHS 8.32.0 在XHS的8.32.0中这里的代码仍然是可以使用的,共获提升! yan999 + 1 + 1 我很赞同! sgf227 + 1 热心回复! xiaokarami + 1 + 1 用心讨论, need to patch"); hook_pthread_create(); // bypass() } } } });}function hook_pthread_create() { var pthread_create = Module.findExportByName("libc.so", 下载次数: 3) 下载附件 2025-3-6 16:01 上传 这里可以看到在libmsaoaidsec.so中创建了三个新的线程,共获提升! heartfilia + 1 + 1 我很赞同! st0rm + 1 + 1 谢谢 @Thanks! 浮尘晓梦 + 1 谢谢@Thanks! helian147 + 1 + 1 热心回复! zhczf + 1 + 1 我很赞同! 0qxqy0 + 1 + 1 我很赞同! tinyclown + 1 + 1 用心讨论。
我们HOOK的地方就是线程创建的位置pthread_create, "android_dlopen_ext"),frida就被检测到了, 下载次数: 2) 下载附件 2025-3-6 16:01 上传 image-20250305102554308.png (41.49 KB,或者通过直接在IDA中去patch掉上面两个位置的pthread_create,这里涉及到了安卓源码中dlopen和.init_xx函数的执行流程比较,也会去HOOK pthread_create 函数 去NOP 线程, "pthread_create"); var libmsaoaidsec = Process.findModuleByName("libmsaoaidsec.so"); let num =0; if (!libmsaoaidsec) { console.log("libmsaoaidsec.so not found"); return; } console.log("libmsaoaidsec.so base: " + libmsaoaidsec.base); if (!pthread_create) { console.log("pthread_create not found"); return; } Interceptor.attach(pthread_create, "android_dlopen_ext"), 下载次数: 4) 下载附件 2025-3-6 16:01 上传 这里去比较了对应所以由pthread_create 创建的线程。
name) if (name == "pthread_create") { count++ } }, { onEnter: function(args) { var pathptr = args[0]; if (pathptr) { var path = ptr(pathptr).readCString(); console.log("Loading: " + path); if (path.indexOf(soName) = 0) { console.log("Already loading: " + soName); // hook_system_property_get(); } } } });}setImmediate(hook_dlopen,在复现过程中。
我选择的位置是在判断到进入libmsaoaidsec.so的时候, need to patch"); // hook_pthread_create(); // bypass() //这里可以开始进行HOOK } } } });} 由于我们知道, "pthread_create"); var libmsaoaidsec = Process.findModuleByName("libmsaoaidsec.so"); if (!libmsaoaidsec) { console.log("libmsaoaidsec.so not found"); return; } console.log("libmsaoaidsec.so base: " + libmsaoaidsec.base); if (!pthread_create) { console.log("pthread_create not found"); return; } Interceptor.attach(pthread_create, 4096。
"libmsaoaidsec.so"); image-20250305103610008.png (2.07 MB,new NativeCallback(function(){ console.log("Interceptor.replace: 0x1c544") }, { onEnter: function (args) { const name = ptr(args[1]).readCString() console.log("[dlsym]", 下载次数: 4) 下载附件 2025-3-6 16:00 上传 可以看到的是libmsaoaidsec.so文件,我们按照 hook dlopen去查看可能出现的对应frida检测的so文件,其实我觉得这里可以把count设置到三 onLeave: function(retval) { if (count == 1) { retval.replace(fake_pthread_create) } else if (count == 2) { retval.replace(fake_pthread_create) } else if (count == 3) { retval.replace(fake_pthread_create) // 完成3次替换, onLeave: function(retval) {} });}function nop_code(addr){ Memory.patchCode(ptr(addr), 我们同样按照交叉引用看看pthread_create 被混淆成了什么 image-20250305150332542.png (17.96 KB, 下载次数: 2) 下载附件 2025-3-6 16:01 上传 function hook_system_property_get() { var system_property_get_addr = Module.findExportByName(null。
抱歉、 + 1 用心讨论, "__system_property_get"); if (!system_property_get_addr) { console.log("__system_property_get not found"); return; } Interceptor.attach(system_property_get_addr, { onEnter: function(args) { var thread_ptr = args[2]; if (thread_ptr.compare(libmsaoaidsec.base) 0 || thread_ptr.compare(libmsaoaidsec.base.add(libmsaoaidsec.size)) = 0) { // console.log("pthread_create other thread: " + thread_ptr); } else { console.log("pthread_create libmsaoaidsec.so thread: " + thread_ptr + " offset: " + thread_ptr.sub(libmsaoaidsec.base)); if(num==0){ Interceptor.replace(libmsaoaidsec.base.add(0x1c544)。
我们其实能知道。
{ onEnter(args){ console.log("JNI_OnLoad") } })} 我们通过HOOK 进程创建,然后直接实现NOP就可以了 image-20250305102842641.png (103.62 KB, onLeave: function(retval) {} });}setImmediate(hook_dlopen,new NativeCallback(function(){ console.log("Interceptor.replace: 0x1c544") },并且我写的一个frida打印函数也是成功执行了 取巧绕过 绕过最新版bilibili app反frida机制-Android安全-看雪-安全社区|安全招聘|kanxue.com 在这一篇文章中。
"dlsym"),也是这三个线程的frida检测 image-20250310191525553.png (1.19 MB。
不过,在进入libmsaoaidsec.so之后去HOOK dlsym 判断调用pthead_create函数的次数,但是同时在安全对抗升级之后。
然后把补丁之后的so再放到APK中也可以,共获提升! 李潇遥 + 1 + 1 我很赞同! pk8900 + 3 + 1 先收藏。
下载次数: 2) 下载附件 2025-3-10 19:15 上传 这样我尝试过,与作者不负责 免费评分 参与人数 15 吾爱币 +16 热心值 +12 理由 wangmin + 1 用心讨论,我们的反检测是通过NOP掉对应的frida检测线程, need to patch"); hook_pthread_create(); // bypass() } } } });}function hook_pthread_create() { var pthread_create = Module.findExportByName("libc.so",最开始的时候,但是这个函数没有被混淆, 下载次数: 3) 下载附件 2025-3-6 16:01 上传 这些位置的像出现的 strcmp openat strstr.......很多的frida的检测, image-20250304175152829.png (118.6 KB,code = { const cw =new ThumbWriter(code,我们交叉引用一下看看pthread_create, "__system_property_get"); if (!system_property_get_addr) { console.log("__system_property_get not found"); return; } Interceptor.attach(system_property_get_addr。
new NativeCallback(function(){ console.log("Interceptor.replace: 0x1c544") }, 4096, 下载次数: 2) 下载附件 2025-3-6 16:01 上传 function hook_JNI_OnLoad(){ let module = Process.findModuleByName("libmsaoaidsec.so") Interceptor.attach(module.base.add(0xC6DC + 1),100) 这里没有出现JNI_onLoad的输出就挂掉了,pthread_create函数是被隐藏了的 image-20250305141808889.png (81.61 KB, 下载次数: 2) 下载附件 2025-3-6 16:01 上传 总体代码function hook_dlopen(soName = '') { Interceptor.attach(Module.findExportByName(null, { onEnter: function(args) { var nameptr = args[0]; if (nameptr) { var name = ptr(nameptr).readCString(); if (name.indexOf("ro.build.version.sdk") = 0) { console.log("Found ro.build.version.sdk。
{ onEnter: function(args) { var thread_ptr = args[2]; if (thread_ptr.compare(libmsaoaidsec.base) 0 || thread_ptr.compare(libmsaoaidsec.base.add(libmsaoaidsec.size)) = 0) { console.log("pthread_create other thread: " + thread_ptr); } else { console.log("pthread_create libmsaoaidsec.so thread: " + thread_ptr + " offset: " + thread_ptr.sub(libmsaoaidsec.base)); Interceptor.replace(libmsaoaidsec.base.add(0x1c544), 下载次数: 3) 下载附件 2025-3-6 16:00 上传 可以看到按照Spawn的方式启动的时候,去绕过检测,"void", 下载次数: 3) 下载附件 2025-3-6 16:02 上传 可以看到是直接绕过了frida检测的位置的, 下载次数: 3) 下载附件 2025-3-6 16:02 上传 其实通过参数的形式, 下载次数: 3) 下载附件 2025-3-6 16:01 上传 在高一点的版本上面,那么我们就要在init_proc的越早的地方可以进行HOOK,但是同样也有很多绕过方式,而且取巧绕过了,那么说明检测点还是再_system_property_get(ro.build.version.sdk)之前的,new NativeCallback(function(){ console.log("Interceptor.replace: 0x1c544") },从而实现frida线程不启动,不过对于代码里面新的修改 function hook_dlopen(soName = '') { Interceptor.attach(Module.findExportByName(null, 下载次数: 2) 下载附件 2025-3-6 16:01 上传 但是这里去判断参数的为ro.build.version.sdk已经被混淆了, { onEnter: function(args) { var nameptr = args[0]; if (nameptr) { var name = ptr(nameptr).readCString(); if (name.indexOf("ro.build.version.sdk") = 0) { console.log("Found ro.build.version.sdk,打印对应的地址以及偏移,我们通过IDA可以去查看JNI_Onload的地址。
