Win32程序集 - 外部函数命名('@'的含义)
正如我所见,extern
汇编代码中的WinAPI函数的名称有[email protected]
。Win32程序集 - 外部函数命名('@'的含义)
@4
部分的含义是什么,以及如何确定在@
之后要使用哪个数字?
我知道这与我们链接的DLL有关,但在很多情况下,我们不知道在@
之后使用了什么数字,这会导致许多令人讨厌的undefined reference
错误。
参见如安德烈亚斯ħ回答说@
后的数字是一个字节的函数返回之前的号码的功能从栈中删除。这意味着应该很容易确定该数字,因为它需要的字节数也会推送到堆栈上以正确调用该函数。它应该是调用之前PUSH指令的数量乘以4.在大多数情况下,这也将是传递给函数的参数的数量乘以4。
如果要仔细检查你已经得到了正确的数字,你有微软的Visual Studio安装,你可以找到从开发人员命令提示符这样的装饰符号名称:
C:\> dumpbin /headers kernel32.lib | find "ExitProcess"
Symbol name : [email protected]
Name : ExitProcess
如果”重新使用MinGW的编译工具链接你的汇编代码,你可以这样做,而不是:
C:\> nm C:\MinGW\lib\libkernel32.a | find "ExitProcess"
00000000 I [email protected]
00000000 T [email protected]
你需要在你安装MinGW的目录,以取代C:\MinGW
。
由于并非所有Windows API都驻留在kernel32
导入库中,您需要用Windows SDK文档中给出的导入库的名称替换kernel32
,以获取要链接到的API函数。例如,对于MessageBoxA
,您需要在Visual Studio中使用user32.lib
,而在MinGW中使用libuser32.a
。
请注意,有几种罕见的Windows API不使用stdcall
调用约定。这些功能类似于wsprintf
,其采用可变数量的参数,其中stdcall
调用约定不支持。这些函数名称前只有一个下划线_
,并且没有@
或之后的数字。他们还要求调用者从堆栈中移除参数。
如果您想获取要使用的号码,请确保将_NT_SYMBOL_PATH定义为正确的值。
喜欢:
srv*https://msdl.microsoft.com/download/symbols
或
srv*c:\MyServerSymbols*https://msdl.microsoft.com/download/symbols
例如(在cmd.exe的,窗口的命令行):
set _NT_SYMBOL_PATH=srv*https://msdl.microsoft.com/download/symbols
然后使用:
dumpbin /exports /symbols kernel32.dll | grep -i ExitProcess
你必须在kernel32所在的目录下,你必须有grep。
可能是一种使用内置find命令的方法。你也可以将它重定向到一个文件,然后在你的编辑器中查看它。
不适合我。我只是得到'289 120 ExitProcess(转发给NTDLL.RtlExitUserProcess)'。 –
更正了......需要添加/符号 –
仍然没有运气,我用'/ exports/symbols'得到了同样的结果。 –
当为函数指定stdcall调用约定时,@符号是作为前导下划线的函数名称的一部分。
该数字指定函数从堆栈中移除的字节数。
编译器生成此编号。
添加了后缀,以便函数不会被意外地调用错误的调用约定,或者源代码中的原型指定错误的参数数目或大小。所以意图是提供避免程序崩溃的手段。
这种方法确实有效。 – hakeris1010