包含INT 2D指令似乎是Windows恶意软件作者使用的相当常见的反调试策略。据我了解,它会导致进程在连接调试器时与未连接调试器时有所不同。

我已经读到这部分是由于异步(不是普通程序的一部分)引起的流)递增到指令指针。可以使此增量导致指令断言。

有人可以解释这种反调试策略,特别是为什么对指令指针进行此增量的原因,以及是否连接调试器时会发生什么。

#1 楼

从我的“最终”反调试参考中(请参阅pferrie.host22.com):

中断0x2D是一种特殊情况。执行该命令时,Windows使用当前EIP寄存器值作为异常地址,然后将EIP寄存器值增加1。但是,Windows还将检查EAX寄存器中的值,以确定如何调整异常地址。如果EAX寄存器在所有Windows版本上的值为1、3或4,或者在Windows Vista及更高版本上的值为5,则Windows会将异常地址增加1。最后,如果存在调试器,它将发出EXCEPTION_BREAKPOINT(0x80000003)异常。中断0x2D行为可能给调试器带来麻烦。问题在于某些调试器可能会将EIP寄存器值用作恢复的地址,而其他调试器可能会将异常地址用作恢复的地址。这可能会导致单字节指令被跳过,或者由于缺少第一个字节而执行完全不同的指令。这些行为可用于推断调试器的存在。可以使用以下代码进行检查(对于32位和64位相同)以检查32位或64位Windows环境:

xor  eax, eax ;set Z flag
int  2dh
inc  eax ;debugger might skip
je   being_debugged


[end]

所以您可以看到这里没有异步发生。发生异常时,更改立即发生。
就为什么发生,跳过的字节用于在异常发生时传递一个字节的附加信息。

评论


确实,当我开始阅读它时,没有任何“异步性”检查是很明显的。我以为UD2指令可能会执行类似的操作?

–cb88
13年4月3日在15:40

UD2效果不一样。该行为就像其他任何无效指令一样。它仅用于查看绝对无效的指令的外观(与今天无效的随机操作码组合相反,明天将在新的CPU中变为有效的随机操作码组合)。

–彼得·弗里
13年4月5日在20:40

#2 楼

《反逆向工程指南》以及此处提供的代码的主要解释性注释。

// The Int2DCheck function will check to see if a debugger
// is attached to the current process. It does this by setting up
// SEH and using the Int 2D instruction which will only cause an
// exception if there is no debugger. Also when used in OllyDBG
// it will skip a byte in the disassembly and will create
// some havoc.


注意这里是关于SEH的一些内容。

#3 楼

有关在恶意软件中使用INT2d的一些良好示例,请查看Fu博士的博客: >
有3种不同的示例和解释,其中一种是与Max ++一起使用的,它可以很好地了解您自己的恶意软件示例中的预期结果。

#4 楼


中断0x2D是一种特殊情况。 Windows
在执行时将当前EIP寄存器的值用作异常地址,然后
将EIP寄存器的值加1。但是,Windows也会检查EAX寄存器中的值,以确定如何调整
异常地址。如果EAX寄存器在所有Windows版本上的值为1、3或4,或者在Windows Vista及更高版本上的值为5,则Windows会将异常地址加1。最后,如果存在调试器,它会发出EXCEPTION_BREAKPOINT(0x80000003)异常。中断0x2D行为可能给调试器带来麻烦。
问题是,某些调试器可能会将EIP寄存器值用作要从其恢复的地址,而其他调试器可能会使用
异常地址。作为要恢复的地址。这可能导致
跳过单字节指令,或者由于缺少第一个字节而执行完全不同的指令,
这些行为可以用来推断是否存在字节。调试器。
可以使用以下代码(对于32位和
64位相同)进行检查,以检查32位或64位Windows环境:


起初,我不理解“例外地址”的含义,我认为我并不是唯一的一个。幸运的是,傅博士的博客对此有更好的解释。

傅博士的博客:


这里的“例外地址”是“ EIP值”上下文”(
将被复制回用户进程),并且“ EIP寄存器值”是发生异常时用户进程的真实EIP值。