在c++中按名称获取函数

Getting function by name in c++

本文关键字:获取 函数 c++      更新时间:2023-10-16

代码:

#include <tchar.h>
#include <windows.h>

typedef INT (WINAPI * lolMessageBoxA)(HWND,LPCSTR,LPCSTR,UINT);

int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    lolMessageBoxA UchwytMessageBoxA;
    UchwytMessageBoxA = lolMessageBoxA(GetProcAddress(GetModuleHandle("User32.dll"),"MessageBoxA"));
    UchwytMessageBoxA(NULL,"TEST WINDOWS","TEXT 2", MB_OKCANCEL | MB_ICONWARNING);
    return 0;
}

当我在制作钩子之前正常调用MessageBoxA时,钩子部分工作得很好。但当我删除了那个部分,只留下了"挂钩"部分时,它失败了。。。

已解决:

#include <tchar.h>
#include <windows.h>

typedef INT (WINAPI * lolMessageBoxA)(HWND,LPCSTR,LPCSTR,UINT);

int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    lolMessageBoxA UchwytMessageBoxA;
    LoadLibraryA("User32.dll");
    UchwytMessageBoxA = lolMessageBoxA(GetProcAddress(GetModuleHandle("User32.dll"),"MessageBoxA"));
    UchwytMessageBoxA(NULL,"TEST WINDOWS","TEXT 2", MB_OKCANCEL | MB_ICONWARNING);
    return 0;
}

如上所述,进程没有理由加载user32.dll。因此,对GetModuleHandle的调用将返回NULL。那么对GetProcAddress的调用也将失败并返回NULL。好吧,你可以看到接下来会发生什么。

当您直接调用MessageBoxA时,链接器会生成一个导入表,强制加载程序加载user32.dll。但是当您删除对MessageBoxA的调用时,它就没有必要这样做了

您应该将对GetModuleHandle的调用替换为对LoadLibrary的调用,从而强制加载库。

最后,您提出这个问题的真正原因是您的代码忽略了错误检查。不要那样做。检查Win32函数调用返回的值。如果你这样做了,你就可以自己解决这个问题了。