winapiassemblynasmldkernel32

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


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.


Solution

  • 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.