我必须了解这段代码如何跳转退出调用。我只有一个静态 View ,没有动态 View ,因为我无法使用调试器。 这是代码:
; int __cdecl main(int, char **, char **)
main proc near
var_14= dword ptr -14h
var_10= dword ptr -10h
handle= dword ptr -0Ch
fd= dword ptr -8
var_4= dword ptr -4
arg_4= dword ptr 0Ch
push ebp
mov ebp, esp
sub esp, 24h
cmp al, al
jz short near ptr loc_8048DEC+3
xor esp, esp
loc_8048DEC:
mov dword ptr [ecx+42h], 2087D83h
jz short loc_8048E25
mov dword ptr [esp], 0Bh ; status
call _exit
最佳答案
通过使用重叠操作码来混淆反汇编。
首先,无论 al
的内容如何,指令 cmp al, al
都保证设置零标志。因此将执行下一行的 jz
条件跳转。
jz
将三个字节跳转到 mov dword ptr [ecx+42h], 2087D83h
指令中。该指令的十六进制表示为c7 41 42 83 7d 08 02
1。所以我们实际上从 83
开始执行。
但是 83 7d 08 02
反汇编为 cmp dword ptr [ebp+8], 2
。请注意,由于这与 IDA 显示的误导性 mov
指令在同一指令边界上结束,因此接下来要执行的指令将与 IDA 提供的反汇编指令对齐。
那么,在下一行jz Short loc_8048E25
中,如果设置了零标志,我们只会跳转到loc_8048E25
;也就是说,如果 [ebp+8]
(这是 main
的第一个参数,即 argc
)等于 2
.否则,我们会失败并执行接下来的两条指令,这相当于 exit(11)
。
修复 IDA 中的反汇编...
您可以通过单击 mov
行并按 u
键来反汇编 mov
指令。您可以类似地使用 c
键从 loc_8048DEC+3
开始重新组装。在执行此操作之前,您应该保存数据库。
<子>
1. 许多助记符可以用多个字节序列来表示。例如,该特定指令也可能表示为 c7 81 42 00 00 00 83 7d 08 02
,但 A) 编译器倾向于生成最短形式的指令,B) 生成的重叠指令不会“有意义”并且可能会出现段错误。 IDA 可以在十六进制 View 中或适当设置Opcodes > General > Number of opcode bytes
中向您显示每条指令的实际字节表示形式。
关于assembly - 跳跃障碍汇编代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34107028/