![](/img/trans.png)
[英]How to read the function parameters from call stack frames programmatically in Windows?
[英]How is the stack set up in a Windows function call?
首先,我想说我在汇编方面有足够的背景知识,以理解成为一名功能性汇编程序员所需要了解的大部分知识。 不幸的是,我不了解Windows API调用在返回地址方面的工作方式。
这是一些使用Windows的GAS汇编语言编写的示例代码,使用MinGW作为汇编程序,MinGW ld作为链接程序...
.extern _ExitProcess@4
.text
.globl _main
_main:
pushl $0
call _ExitProcess@4
该代码在组装后编译并运行...
as program.s -o program.o
并将其链接...
ld program.o -o program.exe -lkernel32
据我了解,Windows API调用通过推送指令接受参数,如上所示。 然后在通话中;
call _ExitProcess@4
该函数的返回地址放在堆栈中。 然后,这就是我感到困惑的地方,该函数将所有参数弹出堆栈。
我感到困惑是因为,由于堆栈是后进先出的,因此我在弹出堆栈中的参数时会先弹出返回地址。 首先是参数,然后是返回地址,因此从技术上讲应该先弹出。
我的问题是,在通过push操作将参数传递给函数调用并将返回地址放置在堆栈上之后,堆栈的布局是什么样的? 函数在执行时如何从堆栈中弹出参数和返回地址? 最后,返回地址如何从堆栈中弹出,函数调用返回到返回地址中指定的地址?
几乎所有Windows API函数都使用stdcall调用约定 。 就像正常的“ cdecl”约定一样,除了您看到调用的函数负责在返回参数时删除该参数之外,它的工作原理相同。 它使用RET指令执行此操作,该指令采用一个可选的立即操作数。 此操作数是第一次弹出返回值后要从堆栈弹出的字节数。
在cdecl和stdcall调用约定中,函数执行时不会将函数的参数弹出堆栈。 它们留在堆栈上,并使用ESP或EBP相对寻址进行访问。 因此,当ExitProcess需要访问其参数时,它使用诸如mov 4(%esp), %eax
或mov 4(%ebp), %eax
类的指令。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.