从地址调用函数不起作用
Calling function from address doesn't work
我不明白为什么如果我使用程序崩溃的地址调用 CreateFileA
函数。
此代码段应使用从 GetProcAddress
调用中检索到的地址来调用 CreateFileA
。当然在这个简单的例子中我可以正常调用它,但我需要手动检索每个地址(甚至 LoadLibraryA
和 GetProcAddress
但为了简洁起见我没有在这个例子中)
我做错了什么?为什么如果我在最后一行使用 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
之后;否则注释将不执行任何操作。
我不明白为什么如果我使用程序崩溃的地址调用 CreateFileA
函数。
此代码段应使用从 GetProcAddress
调用中检索到的地址来调用 CreateFileA
。当然在这个简单的例子中我可以正常调用它,但我需要手动检索每个地址(甚至 LoadLibraryA
和 GetProcAddress
但为了简洁起见我没有在这个例子中)
我做错了什么?为什么如果我在最后一行使用 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
之后;否则注释将不执行任何操作。