Win32 Assembly - Extern function naming (The meaning of '@')

孤街醉人 提交于 2019-12-12 02:42:31

问题


As I see, extern WinAPI functions in assembly code have names like _ExitProcess@4.

What is the meaning of the @4 part, and how to determine what number to use after @ ?

I know that this has something to do with DLL we are linking against, but in many cases it's not known what number to use after the @, and this leads to many nasty undefined reference errors.


回答1:


As Andreas H answer said the number after the @ is the number of bytes the function removes from stack before the function returns. This means it should be easy to determine that number, as it's the also number of bytes you need push on the stack to correctly call the function. It should be the number of PUSH instructions before the call multiplied by 4. In most cases this will also be the number of arguments passed to the function multiplied by 4.

If you want to double check that you've gotten the right number and you have Microsoft Visual Studio installed you can find the decorated symbol name from the Developer Command Prompt like this:

C:\> dumpbin /headers kernel32.lib | find "ExitProcess"
  Symbol name  : _ExitProcess@4
  Name         : ExitProcess

If you're using the MinGW compiler tools to link your assembly code, you can do this instead:

C:\> nm C:\MinGW\lib\libkernel32.a | find "ExitProcess"
00000000 I __imp__ExitProcess@4
00000000 T _ExitProcess@4

You'll need to replace C:\MinGW with the directory you installed MinGW.

Since not all Windows APIs reside in the kernel32 import library you'll need to replace kernel32 with the name of the import library given in the Windows SDK documentation for the API function you want to link to. For example, with MessageBoxA you'd need to use user32.lib with Visual Studio and libuser32.a with MinGW instead.

Note there are few rare Windows APIs that don't use the stdcall calling convention. These are functions like wsprintf that take a variable number of arguments, which the stdcall calling convention doesn't support. These functions just have an underscore _ before their names, and no @ or number after. They also require that the caller remove the arguments from the stack.




回答2:


The @ symbol is, as the leading underscore, part of the function name when the stdcall calling convention is specified for the function.

The number specifies the number of bytes the function removes from the stack.

The compiler generates this number.

The suffix is added so that the function is not accidentally called with the wrong calling convention or the prototype in the source code specifies the wrong number or size of arguments. So the intention is to provide a means to avoid program crashes.

See also https://msdn.microsoft.com/de-de/library/zxk0tw93.aspx




回答3:


If you want to get the number to use, make sure you have _NT_SYMBOL_PATH defined to the correct value.

Like:

srv*https://msdl.microsoft.com/download/symbols

or

srv*c:\MyServerSymbols*https://msdl.microsoft.com/download/symbols

For example (in cmd.exe, windows command line):

set _NT_SYMBOL_PATH=srv*https://msdl.microsoft.com/download/symbols

Then use:

dumpbin /exports /symbols kernel32.dll | grep -i ExitProcess

You'll have to be in the directory where kernel32 is and you'll have to have grep.

Probably is a way to use built in find command. You could also redirect it to a file and then view it in your editor.



来源:https://stackoverflow.com/questions/40030484/win32-assembly-extern-function-naming-the-meaning-of

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!