逆向遇到反调试怎么办:六种检测和绕过方法
逆向时遇到反调试是最烦的。程序一检测到调试器就退出或者改逻辑。这篇讲几种常见的反调试和绕过方法。一、ptrace 检测
最经典的反调试。Linux 下程序调用 ptrace(PTRACE_TRACEME) 来检测是否已被调试。如果返回 -1 说明已经有一个调试器在跟踪它。
绕过方法:用 Frida hook ptrace 函数,让它永远返回 0:
Interceptor.attach(Module.findExportByName(null, "ptrace"), {
onEnter: function(args) {
args = ptr(0);// 改成 PTRACE_TRACEME
},
onLeave: function(retval) {
retval.replace(0);// 返回0表示成功
}
});
二、TracerPid 检测
程序读取 /proc/self/status 文件,看 TracerPid 字段。正常是 0,被调试时是调试器的 PID。
绕过方法:hook fopen 或 open 函数,当打开 /proc/self/status 时替换内容:
var fopen = Module.findExportByName(null, "fopen");
Interceptor.attach(fopen, {
onLeave: function(retval) {
var path = this.context.r0; // 需要根据架构调整
// 读取文件内容,把 TracerPid 改成 0
}
});
更简单的办法:用 Frida 的文件重定向,或者直接 patch so 二进制,把检测函数 NOP 掉。
三、时间检测
程序在关键函数前后读取系统时间,如果差值过大就认为被断点调试了。
绕过方法:hook clock_gettime 或 gettimeofday,在断点暂停期间让时间"不流逝":
var orig_clock_gettime = Module.findExportByName(null, "clock_gettime");
var fake_time = 0;
Interceptor.attach(orig_clock_gettime, {
onLeave: function(retval) {
if (fake_time === 0) fake_time = this.context.r1.toInt32 ? this.context.r1 : 0;
// 固定返回相同时间戳
}
});
四、inotify 文件监控检测
程序用 inotify 监控 /proc/self/maps 或 /proc/self/mem 的访问。调试器读内存时会触发通知。
绕过方法:hook inotify_add_watch,当监控的路径包含 /proc/self 时返回一个假 fd。
五、调试器特征检测
程序检查 /proc/self/cmdline 是否包含 "frida"、"gdb"、"lldb" 等字符串。或者扫描端口看有没有 Frida server 在 27042 端口。
绕过方法:
[*]改 Frida server 名称和默认端口:./frida-server -l 0.0.0.0:8888
[*]用 frida-gadget 注入而不是 frida-server,不开放端口
[*]hook 字符串比较函数,让 "frida" 比较返回不匹配
六、实战思路
遇到反调试不要一个一个绕,按这个流程来:
[*]先用 Frida trace 看程序调用了哪些检测函数(ptrace、open、clock_gettime 等)
[*]找到检测逻辑的入口点
[*]批量 hook 所有检测函数
[*]如果还有问题,可能有多层检测,逐层排查
七、终极方案:静态 patch
如果动态绕过太麻烦,直接在 IDA 里找到检测函数的二进制代码,用 NOP 指令替换。ARM64 的 NOP 是 0x1F2003D5。改完后保存 so 文件,替换回去。
https://www.metk.cn/img/posts/anti_debug.jpg
反调试的本质是猫鼠游戏。开发者加检测是为了增加逆向成本,你绕过是为了降低成本。大部分反调试都可以用 Frida 动态 hook 绕过,少数需要静态 patch。掌握这两种方法就够了。 想请教一下,你用的这个版本是哪个?我这边跑起来报错。 感谢,正需要这个,之前找的资料都太老了。 这个方法我用过,确实可行,不过新一点的版本已经加了检测。 我这边环境是Mac,有些步骤要调整,回头补个差异说明。 这篇干货,比那些只有命令没有解释的强太多了。 步骤写得很清楚,跟着走了一遍,卡在第二步的环境配置上,后来装了老版本才好。 实战出来的经验和文档里写的完全是两码事,楼主这个很真实。 这个思路让我想到另一个场景,回头试试能不能套用。 感谢分享,之前一直卡在这个点,看完豁然开朗。