正如Andreas H回答的那样,后面的@数字是函数在函数返回之前从堆栈中删除的字节数.这意味着应该很容易确定该数字,因为它是您需要在堆栈上推送以正确调用该函数的字节数.它应该是调用前PUSH指令的数量乘以4.在大多数情况下,这也是传递给函数的参数数量乘以4.
如果您想要仔细检查您是否获得了正确的号码并且安装了Microsoft Visual Studio,则可以从Developer Command Prompt中找到装饰符号名称,如下所示:
C:\> dumpbin /headers kernel32.lib | find "ExitProcess"
Symbol name : _ExitProcess@4
Name : ExitProcess
Run Code Online (Sandbox Code Playgroud)
如果您使用MinGW编译器工具链接汇编代码,则可以执行以下操作:
C:\> nm C:\MinGW\lib\libkernel32.a | find "ExitProcess"
00000000 I __imp__ExitProcess@4
00000000 T _ExitProcess@4
Run Code Online (Sandbox Code Playgroud)
您需要替换C:\MinGWMinGW安装的目录.
由于并非所有Windows API都驻留在kernel32导入库中,因此您需要kernel32使用Windows SDK文档中为要链接的API函数指定的导入库名称进行替换.例如,MessageBoxA您需要使用user32.libVisual Studio和libuser32.aMinGW.
请注意,很少有罕见的Windows API不使用stdcall调用约定.这些函数wsprintf就是采用可变数量的参数,stdcall调用约定不支持这些参数.这些函数_在它们的名称之前只有一个下划线,@之后没有或数字.它们还要求调用者从堆栈中删除参数.