I can't understand why if i call the CreateFileA
function using the address the program crash.
This snipet should call the CreateFileA
using it's address retrieved from the GetProcAddress
call. Of course in this simple example i could just call it normally, but i need to retrieve each address manually (Even LoadLibraryA
and GetProcAddress
but for the sake of brevity i didn't in this example)
What am i doing wrong? Why if i use CreateFileA
instead of (*CreateFileAAddr)
on the last line it works even if they are pointing to the same thing?
#include <windows.h>
typedef HMODULE(*_LoadLibraryA)(LPCSTR);
typedef FARPROC(*_GetProcAddress)(HMODULE, LPCSTR);
typedef HANDLE(*_CreateFileA)(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
int main() {
_LoadLibraryA LoadLibraryAAddr = (_LoadLibraryA)&LoadLibraryA;
_GetProcAddress GetProcAddressAddr = (_GetProcAddress)&GetProcAddress;
HMODULE kernel32Handle = (*LoadLibraryAAddr)("Kernel32.dll");
if (kernel32Handle == NULL) return -1;
_CreateFileA CreateFileAAddr = (_CreateFileA)((*GetProcAddressAddr)(kernel32Handle, "CreateFileA"));
if ((unsigned long)CreateFileAAddr != (unsigned long)&CreateFileA) return -1; //Just to check if the address is correct for Debug
(*CreateFileAAddr)("123.txt", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, OPEN_ALWAYS, NULL);
return 0;
}
As per my comment, Windows API functions and pointer types to said functions need to be annotated with __stdcall
(or WINAPI
), which will change their calling convention to the one expected by the API (more information on the stdcall calling convention here).
typedef HMODULE(__stdcall *_LoadLibraryA)(LPCSTR);
typedef FARPROC(__stdcall *_GetProcAddress)(HMODULE, LPCSTR);
typedef HANDLE(__stdcall *_CreateFileA)(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
Also side note: the *
must be placed after the __stdcall
, for some reason; otherwise the annotation will do nothing.