当函数不使用 ebp 时,有没有办法调整局部变量?

逆向工程 艾达
2021-06-30 09:06:33

我有一个问题,就像在问题中一样。现代编译器不用于ebp处理局部变量和参数,它们只是计算并将硬编码偏移量添加到esp. 例子:

sub     esp, 5Eh  
...     
mov     [esp+5Eh+var_1], 123h
mov     [esp+5Eh+var_2], 456h
call    some_func            ; var_1 and var_2 point to actual addresses
cmp     eax, 0               ; esp changed (stdcall), var_1 and var_2 point to wrong addresses

...

;  creation of a "fake" variable example:
;  var_3 = -8h
;  var_4 = -12h 
mov     [esp+5Eh+var_3], 78h  ; var_3 at: esp + 5Eh -8h
pop     eax                   ; esp = esp + 4  
mov     [esp+5Eh+var_4], 89h  ; var_4 at: esp + 4  + 5eh -12h = esp + 5Eh -8h = var_3
; desireable fix:
mov     [esp+62h+var_3], 89h 

这会导致大量开销:IDA 创建“假”局部变量(即同一个地址的多个名称),您不能随时随意检查变量,您必须创建附加注释等。所以我想知道有没有办法解决这个问题?

附注。我正在使用 IDA Pro Free。告诉我是否只能在 IDA Pro(完整版)中实现。

2个回答

IDA 生成的变量名不是“假的”;如果函数是ebp基于它们的,它们与它们将被标记的完全相同您描述的问题实际上只是调试时的一个问题,因为这是您唯一可以检查指向的值的时间。我不知道有什么内置方法可以让 IDA 显示你想要的内容。当您将鼠标悬停在操作数上时,IDA 只会获取寄存器的当前值并添加偏移量。如果esp已更改,则它会向您显示错误的地址,这就是您在示例中看到的地址。

由于 IDA 确实知道正确的堆栈偏移量,因此执行您所要求的一种方法是编写一个 IDC 脚本,该脚本在计算最终目标地址之前检查eip和调整esp的差异获取给定地址的堆栈偏移量的 IDC 函数是GetSpd(). 该算法将是这样的:

  1. 计算你感兴趣的操作数的目标地址(即esp+5Eh+var_1 -> 0x10000000)
  2. 获取包含您感兴趣的操作数的行的堆栈指针增量(SPD)(即 5Eh)
  3. 获取eip(即 6Eh)的 SPD
  4. 计算两个 SPD 的差值,并从您在步骤 1 中计算的目标地址加上(或减去)该数量(即 0x10000000 + (6Eh-5Eh) = 0x10000010)
  5. 转到您计算出的地址([0x10000010] 包含您要查找的变量)

将光标置于给定函数内,按Alt+P编辑函数属性。Edit function窗口中,取消选中BP based frame并按OK