我不明白为什么我要使用地址调用CreateFileA函数导致程序崩溃。

该摘录应使用从CreateFileA调用中检索到的地址来调用GetProcAddress。当然,在这个简单的示例中,我可以正常调用它,但是我需要手动检索每个地址(即使LoadLibraryAGetProcAddress,但是为了简洁起见,我在此示例中都没有)

我究竟做错了什么?为什么如果我在最后一行使用CreateFileA而不是(*CreateFileAAddr),即使他们指向同一个东西,它也可以工作?

#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;
}

最佳答案

根据我的评论,Windows API函数和指向这些函数的指针类型需要用__stdcall(或WINAPI)注释,这会将其调用约定更改为API期望的调用约定(有关stdcall调用约定的更多信息, here)。

typedef HMODULE(__stdcall *_LoadLibraryA)(LPCSTR);
typedef FARPROC(__stdcall *_GetProcAddress)(HMODULE, LPCSTR);
typedef HANDLE(__stdcall *_CreateFileA)(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);


另请注意:出于某种原因,必须将*放在__stdcall之后;否则,注释将无济于事。

关于c - 从地址调用功能不起作用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52303813/

10-11 20:14
查看更多