a = byte ptr -19h
为什么从堆栈基数偏移可以是负数?任何人都可以为我解释一下吗?
a = byte ptr -19h
为什么从堆栈基数偏移可以是负数?任何人都可以为我解释一下吗?
IDA 在函数定义的顶部显示变量的方式是通过它们在函数开头的堆栈基址 ( ebp
, rbp
)的偏移量。
除非发生了一些奇怪的事情,否则负偏移意味着函数本身为局部变量分配了堆栈空间(或者,也取决于编译器和参数传递的调用约定)。
当通过减去堆栈指针(esp
,rsp
)分配堆栈空间时,无论是否使用堆栈基址寄存器,基址堆栈都不会改变。因此,堆栈基址寄存器下方的内存变得可用。当堆栈基址寄存器未使用时,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_38
is at offset -38
from the stack base, 但由于rsp
用于访问var_38
,IDA 显示468h+var_38
而不是使用的立即偏移量。这样做是为了显示正在访问的变量,而不管当前堆栈位置如何。
添加rsp
并468h
为我们提供堆栈基数作为使用当前堆栈指针和函数开始时的堆栈增量的计算。这就是编译器通过从堆栈寄存器和增量计算它来避免使用堆栈基址寄存器的方式。