CALL指令后,跳转到RETN

逆向工程 ollydbg
2021-07-06 18:14:50

我正在尝试分析一段代码,我对以下行感到困惑:

CALL  fct.00402589

然后在那之后,我遇到了一个以 RETN 开头的块。(见下文)
这是该代码块的几行:

RETN
NOP
PUSH EBP
MOV EBP,ESP
LEA ESP, DWORD PTR SS:[ESP-0X2D0]
PUSH ESP
CALL ntdll.RtCaptureContext
......
......
INT 3 
NOP

正如我所说,在通话之后,我正在排队等候 RETN。但是,当我想更进一步时(单击 ollydbg 的“跳过”按钮),它会在调用指令后跳回下一行。在最后一条指令“NOP”之前的行中,有指令 INT 3。

我发现在某些情况下,特别是作为反调试技术,程序会插入 INT 3 的操作码 0xCC 来混淆调试器。调试器认为这是一个断点,因为通常情况下,调试器使用 OxCC 来设置断点。

因此,我更改了 ollydbg 的调试选项(选项 -> 调试选项 -> 异常,然后单击 INT 3 中断框)。从现在开始,调试器不会捕获异常,而是将异常传递给程序。

当我再次启动程序并来到调用指令时,会出现以下内容(我再次复制了一些行):

JMP DWORD PTR DS: [<%crtdll._GetMainArgs>] 
NOP
NOP
ADD BYTE PTR DS:[EAX], AL
ADD BYTE PTR DS:[EAX], AL
JMP DWORD PTR DS: [<%crtdll._strcmpi>]
NOP
NOP
ADD BYTE PTR DS:[EAX], AL
ADD BYTE PTR DS:[EAX], AL
JMP DWORD PTR DS: [<%crtdll._atoi>]
NOP
NOP
ADD BYTE PTR DS:[EAX], AL
ADD BYTE PTR DS:[EAX], AL
JMP DWORD PTR DS: [<%crtdll._exit>]
NOP
NOP
ADD BYTE PTR DS:[EAX], AL
ADD BYTE PTR DS:[EAX], AL
JMP DWORD PTR DS: [<%crtdll._memcpy>]
NOP
NOP
----

等等,有人知道吗?或者有人可以解释我这里发生了什么?

1个回答

int3你看到你的存在拆卸用于调试的目的,因为当有在执行代码中的错误被击中。它旨在将控制权转移到调试器,以便向用户(即开发人员)提供有关问题位置和可能原因的更有意义的信息。在没有调试器的情况下,它将强制终止程序,这是最安全的操作。例如,在堆损坏的情况下,继续执行可能导致任意代码的利用和执行。

int3指令出现还有其他原因——它们可能是例程之间未使用的填充,特别是对于热补丁感知功能等。的存在int3并不总是表示反调试技术。事实上,可以说它更可能根本不是一种反调试技术。

编辑:在您的评论更好地澄清了您的问题之后-您要问的不是跳转到返回,而是跳转到返回的例程。那是完全不同的。

因此,对例程的调用会将返回地址留在堆栈中。该返回地址是紧跟在调用指令之后的那一行。当例程执行 ret 指令时,代码在调用后恢复。跳转指令只是将控制权转移到将返回的例程,允许代码继续执行。

将控制权转移到 exit() 例程,无论名称如何,都按照它的建议进行:它会导致进程终止。如果您正在通过代码进行跟踪并且您命中了该代码,那么该过程就完成了。如果您认为它应该做更多的事情,那么您需要观察在控制权转移之前执行的代码。也许程序希望设置特定的命令行选项,以便完成任何工作。