二进制差异:为什么将 ebx 移动到 eax,而不是推动 ebx?

逆向工程 部件 二元分析 x86 bin-diffing
2021-07-01 19:52:08

我正在做二进制差异,我想知道为什么 mov eax,ebx使用push ebx.

这是二进制差异图像:

补丁前:在此处输入图片说明

补丁后: 在此处输入图片说明

2个回答

?EnsureCollectionCache@CFormElement@@QAEJXZ补丁前后的函数原型相同。它分解为

public: long int __thiscall CFormElement::EnsureCollectionCache(void)

父函数 , 的调用约定在?DoReset@CFromElement@@QAEJH@Z之前和之后也是相同的:

public: long int __thiscall CFormElement::DoReset(int)

在补丁之前和之后,该CFormElement::DoReset函数将其int参数的值保存在 register 中ebx在补丁之前,这个值在 EIP 被压入堆栈,639C2C58因为函数中的其他代码稍后可能会使用它。在补丁之后,该mov eax, ebx指令实际上是一个空操作,因为对 的调用CFormElement::EnsureCollectionCache将覆盖eax

至于编译器为什么做出这样的改变,不看函数的其余部分很难说。也许在补丁之后,函数其余部分的代码int相对于从堆栈中获取参数的值,ebp而不是从堆栈顶部获取它。

这可能是因为调用约定从 __cdecl(使用堆栈接收参数)更改为 __fastcall 甚至是编译器发明的调用约定(使用 EAX 作为寄存器保存相同的信息,这些信息在以前的版本)。