cdecl 调用约定
逆向工程
艾达
恶意软件
2021-07-11 09:40:59
2个回答
esp
register 是堆栈指针,它指向堆栈的头部,即二进制中的最低地址。
#1 初始堆栈帧:
|local var 1| <- esp (lowest address)
|local var 2|
|-----------|
|-----------|
|-----------|
|local var n| <- ebp
在push
指令之后,堆栈将查看:
#2 调用前的堆栈帧:
|a| <- esp
|b|
|c|
|local var 1|
|local var 2|
|-----------|
|-----------|
|-----------|
|local var n| <- ebp
所以现在 3 个额外的值被添加到当前函数的堆栈帧中,以便将参数传递给test
函数。3 个参数 * 参数的 4 字节大小 = 12 字节。
之后test
的回报,我们需要从#2回到我们的#1堆栈帧-我们希望esp
给点回local var 1
。为此,我们需要将 12 添加到 esp - 请记住,堆栈从最高地址到最低地址增长,并且我们的 3 个参数的大小为 12 字节。这是add esp, 12
指令,它被称为清理堆栈。
在cdecl
调用中,调用者,即当前函数,负责清理堆栈。在其他调用约定中,像stdcall
被调用者负责清理堆栈 - 将堆栈指针的状态恢复到调用之前。
补充一下前面的答案,这里的“清理”不是字面意义上的,而是表示代码将堆栈指针 ( esp
)返回到调用之前的值。不幸的是,这个术语非常根深蒂固,因此将来也可能会继续混淆新的学习者。
其它你可能感兴趣的问题