为什么 IDA 定义负偏移量?

逆向工程 艾达
2021-06-21 13:25:41
a = byte ptr -19h

为什么从堆栈基数偏移可以是负数?任何人都可以为我解释一下吗?

1个回答

IDA 在函数定义的顶部显示变量的方式是通过它们在函数开头的堆栈基址 ( ebp, rbp)的偏移量

除非发生了一些奇怪的事情,否则负偏移意味着函数本身为局部变量分配了堆栈空间(或者,也取决于编译器和参数传递的调用约定)。

当通过减去堆栈指针(esprsp分配堆栈空间时,无论是否使用堆栈基址寄存器,基址堆栈都不会改变因此,堆栈基址寄存器下方内存变得可用。当堆栈基址寄存器未使用时,IDA 仍会显示相对于堆栈基址的堆栈偏移量,通过显式拆分堆栈基址偏移量(从当前堆栈位置)和从堆栈基址的变量偏移量。

例如,看看下面的函数 prelog:

var_448= qword ptr -448h
var_438= word ptr -438h
var_436= byte ptr -436h
var_434= byte ptr -434h
var_38= qword ptr -38h
var_28= qword ptr -28h
arg_0= qword ptr  8
arg_10= qword ptr  18h

mov     r11, rsp
push    rbp
push    rsi
push    r14
push    r15
sub     rsp, 448h
mov     rax, cs:__security_cookie
xor     rax, rsp
mov     [rsp+468h+var_38], rax

您可以看到var_38is at offset -38from the stack base, 但由于rsp用于访问var_38,IDA 显示468h+var_38而不是使用的立即偏移量。这样做是为了显示正在访问的变量,而不管当前堆栈位置如何。

添加rsp468h为我们提供堆栈基数作为使用当前堆栈指针和函数开始时的堆栈增量的计算。这就是编译器通过从堆栈寄存器和增量计算它来避免使用堆栈基址寄存器的方式。