Unix 平台上的反调试技术?

逆向工程 部件 混淆 反调试
2021-06-22 02:16:06

我正在尝试扫描所有可能的技术来破坏 Unix 平台(即 POSIX 和更多)上调试器的使用。

我正在考虑诸如PTRACE在程序开始时(或在其执行的各个点)进行测试、插入假断点(例如int3/ 0xccx86 操作码)或时间检查等技术。但是,还为程序定义了全局策略以减慢程序的分析。

目前,只要理解了反调试技术,我在 Internet 上找到的所有技术都可以轻松解决。所以,我想知道是否有更强的。

3个回答

以下是我见过或听说过的一些:

  • 剥离节标题。一个简单而完全合法的行动,阻止 GDB 停滞不前。不适用于其他一些调试器(例如 IDA)。可以使用sstrip工具完成

  • 使用syscall函数或直接系统调用指令,而不是调用特定的函数,如ptrace(). 可以通过在syscall函数上设置断点或仅单步执行文件来击败,但如果您不了解它,则可能不明显。

  • 在 之前执行反调试操作main(),例如在全局对象的构造函数中或使用__attribute__((constructor)). 由于 GDB 通常在 中设置初始断点main(),因此它会处理默认情况。解决方法很简单:将断点放在实际文件的入口点(info file在 GDB 中)。

  • 向自身发送与调试相关的信号,例如SIGTRAP. (请注意,这handle SIGTRAP nostop在 GDB 中可以忽略。)

  • 使用ptrace.

  • 假断点插入:插入 int3/0xcc 将强制调试器在这些字节上停止,因为它们将被视为软件断点。如果它们很多,可能会大大减慢分析速度。

  • 断点检测:我在这篇论文中看到了这个技术,你可以附加一个函数,当遇到断点时会触发。本文还介绍了一些其他技巧。

我对反调试技术的理解是,它是一场猫捉老鼠(或猫也猫)的游戏。一种技术在被对方理解之前会起作用,然后它就不再起作用了。我认为最终的优势在于调试器。考虑动态二进制检测或虚拟机系统。您可以通过查找平台仿真中的裂缝或故障来检测 DBI 或仿真的存在,但这只是仿真/翻译软件中的错误。如果您有一个“完美”的仿真系统,那么调试后的应用程序就不会知道它正在被跟踪吗?

所以我认为你能做的最好的事情就是容易解决的小事。我仍然认为 Shiva 系统代表了在 Unix 平台上进行调试的“好的”保护,因为它解密了自身的一小部分以按需运行,然后重新加密它们,我记得。

他们不是,不要试图做数学上不可能的事情。

目前,只要理解了反调试技术,我在 Internet 上找到的所有技术都可以轻松解决。所以,我想知道是否有更强的。

是的,因为无法检测无法伪造的调试器。软件无法检测它是在完美的仿真环境中还是在现实世界中运行。并且可以停止仿真器,可以分析软件,可以更改变量,基本上所有可以在调试器中完成的事情都可以完成。

假设您想检测父进程是否为调试器。所以你进行系统调用来获取父PID?调试器可以拦截系统调用并返回任何不必是真实 PID 的 PID。您想拦截每个 SIGTRAP 以便调试器不能再使用它吗?那么调试器可以在这种情况下停止并将 SIGTRAP 也发送到您的进程。您想测量发送 SIGTRAP 的时间,以了解进程是否会因发送 SIGTRAP 的调试器而停止一小段时间,以便知道何时有调试器?调试器可以替换您的调用以获取时间并返回假时间。假设您在具有返回时间的指令的处理器上运行,因此不需要函数调用来获取时间。现在你可以知道你得到的时间是真实的吗?不,调试器可以用 SIGTRAP 指令替换这条指令,并在他想要的任何时候返回,或者在这样的指令不存在的情况下,在可以以任何方式编程的仿真器中运行软件。你能想出的一切来检测调试器或模拟器都可以被环境伪造,你有 0 次更改来检测它。

停止调试的唯一方法是不将软件交给客户,而是将其保存在您的手中。制作云服务并在您的服务器上运行该软件。在这种情况下,客户无法调试您的程序,因为他没有运行它并且无法控制它。除了客户可以以某种方式访问​​服务器或数据,但这是另一回事。