x86汇编中有两个跳转指令指向同一目标的情况

3
我尝试理解《实用恶意软件分析》一书中Michael Sikorski的一个例子。其中有一个关于反汇编技术的例子我不是很理解。它说一个常见的技巧是创建两个条件指令,即跳转如果为零(JZ)和跳转如果不为零(JNZ),这两个指令结合起来实际上只是一个无条件指令(这对我来说很清楚)。下面是反汇编器创建的两种可能结果的图形。

wrong interpretation

right interpretation

以下引用涉及图 1
“在这个例子中,紧随两条条件跳转指令之后的指令似乎是一个以 0xE8 字节开头的调用指令(call)。然而,事实并非如此,因为两条条件跳转指令实际上指向了 0xE8 字节之后的第 1 个字节。”
这是说,在这个例子中,两个条件跳转指令实际上跳过了一个字节,从而将目标地址指向了紧随其后的 call 指令。其中,jump location loc_4011C4+1 表示目标地址在 loc_4011C4 的基础上再加上 1 个字节,而在图 2 中,目标地址为 loc_4011C5。
希望这能对你有所帮助。

2
跳转目标在调用指令内部的1字节处。为什么?因为程序员是这样编写的,可能是为了混淆目的。图2显示将执行的实际指令。C4+1=C5。 - Jester
1个回答

7
汇编代码编译的结果是本地代码,更具体地说是一系列字节的序列,其中该序列的不同部分对应于原始汇编指令。Intel x86 处理器具有所谓的 CISC 指令集,这基本上意味着指令长度可以从 1 个字节变化到 12 个字节,而且这还没有考虑现在可用的指令集扩展。本文介绍的技术利用了这一事实。
整个关键在于误导那些心怀不轨的人。第二个示例中的代码(包括 pop eaxretn)是我们想要执行并将要执行的代码。然而,因为我们在 pop eax 指令前面插入了一个假字节,在不仔细观察的情况下,反汇编后的代码看起来好像调用了某个内存位置,因为大多数低智商的反汇编器会自动假定二进制机器码中没有间隙。
这种技术并非绝对安全。更复杂的反汇编器将揭示作者的真实意图。另外请注意,如果试图在调试环境中运行此代码的人,则无法使用此技术。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接