1. 前言
最近在分析一款app时遇见了frida反调试,花了时间简单学习了一下,有不少收获,记录下学习的过程。
2. 抛出问题
frida是一个很强大的hook框架,用的人多了,自然而然就出现了很多检测方案,这次碰到的app就检测了frida,可以正常打开,但是当你用frida -f
启动或者attach进程,不久后就会闪退。
3. 常见frida检测
-
检测 frida-server
文件名 -
检测 27042
默认端口 -
检测 D-Bus
-
检测 /proc/pid/maps
映射文件 -
检测 /proc/pid/tast/tid/stat
或/proc/pid/tast/tid/status
-
双进程保护
★
前两种可以通过修改frida-server文件名,改默认端口绕过。双进程可以通过-f spawn模式启动绕过。其他的需要去hook修改。
4. 定位
先针对简单的几个可能检测的方式,我修改了文件名,改了端口,也尝试了spawn
启动,均会在启动后不久闪退。 这时考虑到其他几种检测。 首先用frida去看看载入了哪些so,看看是哪里检测了,看了个寂寞。
functionfridaProcess(){ Java.perform(function () { var enumMoudle = Process.enumerateModules();for (var i = 0; i < enumMoudle.length; i++){ console.log("", enumMoudle[i].name) } }); } setImmediate(fridaProcess,0)
因为so载入的时候,底层最后open去打开的。 所以再用frida去hook应用中的open函数,看看读取了哪些so或者文件,可以看到最后断在了/proc/self/maps
。
var pth = Module.findExportByName(null,"open"); Interceptor.attach(ptr(pth),{ onEnter:function(args){ this.filename = args[0]; console.log("",this.filename.readCString())if (this.filename.readCString().indexOf(".so") != -1){ args[0] = ptr(0) } },onLeave:function(retval){return retval; } })
5. 稍稍深入
这里当挂上frida后对应的maps文件中会出现re.frida.server
之类的特征,这是在使用frida server
的时候自动创建的,其中存放着frida的功能模块,可以在载入so的hook脚本输出中能看到最后也是断在frida-agent.so
。
这里要绕过这个检测,我是通过备份一个正常启动时的maps文件(这里前面也讲到app不使用frida是能正常启动不闪退的)。
functionmain() { const openPtr = Module.getExportByName('libc.so', 'open'); const open = new NativeFunction(openPtr, 'int', ['pointer', 'int']); var readPtr = Module.findExportByName("libc.so", "read"); var read = new NativeFunction(readPtr, 'int', ['int', 'pointer', "int"]); var fakePath = "/data/data/com.app/maps"; var file = new File(fakePath, "w"); var buffer = Memory.alloc(512); Interceptor.replace(openPtr, new NativeCallback(function (pathnameptr, flag) { var pathname = Memory.readUtf8String(pathnameptr); var realFd = open(pathnameptr, flag);if (pathname.indexOf("maps") >= 0) {while (parseInt(read(realFd, buffer, 512)) !== 0) { var oneLine = Memory.readCString(buffer);if (oneLine.indexOf("tmp") === -1) { file.write(oneLine); } } var filename = Memory.allocUtf8String(fakePath);return open(filename, flag); } var fd = open(pathnameptr, flag);return fd; }, 'int', ['pointer', 'int']));}setImmediate(main)
然后就可以继续调试了。
原文始发于微信公众号(SecretTeam安全团队):frida反调试绕过
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论