Reputation: 295
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.
Upvotes: 1
Views: 846
Reputation: 6040
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.lib | findstr _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.
Upvotes: 1
Reputation: 39601
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.
Upvotes: 8
Reputation: 6095
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
Upvotes: 4