我正在考虑诸如
PTRACE
测试之类的技术。程序(或其执行的各个阶段),插入假断点(例如int3
/ 0xcc
x86操作码)或时间检查。但是,程序上定义的全局策略也会减慢程序分析的速度。了解。所以,我想知道是否还有更强大的。#1 楼
这是我见过或听说过的一些内容:剥离段标题。一个简单而完全合法的行动,可以阻止GDB陷入困境。对其他某些调试器(例如IDA)不起作用。可以使用
sstrip
工具完成。使用
syscall
函数或直接执行系统调用指令,而不是调用诸如ptrace()
之类的特定函数。可以通过在syscall
函数上设置断点或单步执行该文件来克服它,但是如果您不了解它,可能不会很明显。在
main()
之前执行反调试操作,例如在全局对象的构造函数中或使用__attribute__((constructor))
。由于GDB通常在main()
中设置初始断点,因此它可以处理默认情况。解决方法很简单:将断点放在实际文件的入口点(GDB中的info file
)。发送自身与调试相关的信号,例如
SIGTRAP
。 (请注意,使用GDB中的handle SIGTRAP nostop
可以忽略此操作。)使用
ptrace
进行分叉和跟踪。假断点插入:插入int3 / 0xcc将强制调试器在这些字节上停止,因为它们将被处理作为软件断点。如果它们很多,可能会大大降低分析速度。
断点检测:我在本文中看到了此技术,您可以附加一个函数,该函数将在断点被包围时触发。本文还介绍了其他一些技巧。
评论
好的,这似乎是一个合理的技术列表,但直到现在都不足为奇。而且,您缺少断点技巧(在PTRACEd时插入伪断点以使调试器感到困惑,并检查下一个代码块的哈希值以查看是否已插入新的软件断点)。但是,您是否会知道一篇描述Unix的所有这些技术的论文(我知道一些针对MS-Windows的论文,却没有针对Unix系统的论文)。
–恐怖
13年3月22日在17:42
@Emmanuel:随时对其进行编辑并添加更多内容,这就是我将其制作为Wiki的原因。我没有任何论文,但是也许您可以在Phrack之类的书中找到更多技巧。
–伊戈尔·斯科钦斯基♦
13年3月22日在17:46
我的IDA在尝试加载剥离其节头的ARM二进制文件时死了。因此,#1可能仍然是一个有用的技巧(尽管我最终编写了一个脚本来重新构造标头)。
–nneonneo
2014年6月9日在1:38
@nneonneo:如果当前版本发生这种情况,请发送错误报告。谢谢。
–伊戈尔·斯科钦斯基♦
2014年6月9日在21:09
真正的乐趣是fork并将ptrace()自己用作IPC的一种形式。
–约书亚
'18 Sep 7'在4:02
#2 楼
我对反调试技术的理解是,它是猫和老鼠(或猫又是猫)的游戏。直到对立的一面理解该技术后,该技术才失效。我认为最终的优势在于调试器方面。考虑动态二进制工具或虚拟机系统。您可以通过查找平台仿真中的裂缝或故障来检测DBI或仿真的存在,但是这些仅仅是仿真/翻译软件中的错误。如果您拥有“完美”的仿真系统,那么调试后的应用程序将无法知道它是否已被跟踪?所以,我认为您能做的最好的事情就是容易解决的小事情。我记得,Shiva系统仍然代表在Unix平台上进行调试的“好”保护,因为它解密了自己的一小部分以按需运行,然后重新加密它们,正如我记得。
评论
我会将Shiva系统标记为高级打包程序,但实际上并不是反调试技术(即使其主要作用是使调试程序的使用变得非常乏味,因为与可有效设置断点的内存窗口相比,该窗口非常小)一个“正常”程序)。
–恐怖
13年3月22日在17:37
#3 楼
这些都不是,不要尝试去做数学上不可能的事情。被了解。所以,我想知道是否有更强大的工具。
是的,因为无法检测到无法伪造的调试器。
软件无法检测到它是否在运行在完美的模拟或现实世界中。可以停止模拟器,可以分析软件,可以更改变量,基本上可以完成调试器中可以完成的所有操作。
说您要检测父进程是否是调试器。因此,您进行系统调用以获取父PID?调试器可以拦截系统调用并返回任何非必须为真实PID的PID。您想拦截每个SIGTRAP,以便调试器不能再使用它了吗?好了,调试器可以在这种情况下停止并将SIGTRAP也发送到您的进程。您想测量发送SIGTRAP的时间,以了解调试器是否在短时间内停止了发送SIGTRAP的过程,以便您知道何时有调试器?调试器可以替换您的调用以获取时间并返回假时间。假设您在具有返回时间的指令的处理器上运行,因此不需要任何函数调用即可获取时间。现在您可以知道自己获得的时间是真实的吗?不,调试器可以用SIGTRAP指令替换该指令,并在需要时返回,或者在不存在该指令的情况下,可以在可以用任何方式编程的仿真器中运行软件。您可以用来检测调试器或仿真器的所有东西都可能被环境伪造,并且您需要进行0次更改来检测它。
停止调试的唯一方法是不将软件提供给客户,而是将其掌握在您手中。进行云服务并在服务器上运行该软件。在这种情况下,客户无法调试您的程序,因为他没有运行该程序并且无法控制它。除了客户可以以某种方式访问服务器或数据,但这是另一回事。
评论
“一旦了解了反调试技术,我在Internet上发现的所有技术都可以轻松解决” <-大多数情况都是这种情况,但并不是因为这些而打折的原因。您可能需要检查[this] [1]主题。 [1]:reverseengineering.stackexchange.com/questions/1930/…
你不能任何软件都不可能检测它是在真实机器上运行还是可以从外部进行分析的完美仿真。不要尝试做一些数学上不可能的事情。