LoadLibrary/GetProcAddress 导入程序的 Hook API

Hook APIs that imported to program by LoadLibrary/GetProcAddress

我知道如何从 IAT table 挂接函数,但我对通过调用 LoadLibrary/GetProcAddress 函数导入的 API 有疑问。我想确切地知道有人如何挂接这些功能。我意识到我应该挂钩 GetProcAddress 函数,但是如何检查传递给该函数的参数?

例如,考虑一个将通过 LoadLibrary/GetProcAddress 包含 MessageBoxW 的程序,我如何挂钩 MessageBoxW 然后检查传递给它的参数?

我在 Whosebug 和 Google 中搜索了很多,但我找不到关于此的分步教程。所以,如果你有这样的教程或文章,我将非常感激阅读它们。

为了挂钩 API 它们在 LoadLibrary/GetProcAddress 的帮助下动态加载到二进制文件中,您应该拦截 return GetProcAddress 的地址和函数的名称传递给它(例如,考虑一个程序尝试以这种方式加载 MessageBoxA)。

在第二步中,您应该将 MessageBoxA 的原始地址 API 保存在像 OriginalMessageBoxA 这样的变量中。

在第三步也是最后一步中,您应该 return 修改后的 API (HookedMessageBoxA) 的地址到 GetProcAddress 的被调用方,这样当程序尝试调用该地址时,程序将重定向到你的功能。类似于以下内容:

VOID* HookedGetProcAddress(HMODULE hModule, LPCSTR lpProcName)
{
    if (std::string(lpProcName).compare("MessageBoxA") == 0)
    {
        OMessageBoxA = (PMessageBoxA)GetProcAddress(hModule, lpProcName);
        return HookedMessageBoxA;
    }
    else
    {
        return OGetProcAddress(hModule, lpProcName);
    }
}

在那一刻,调用者将通过您的 HookedMessageBoxA,您可以检查传递给 MessageBoxA 的参数。正如人们所说,它有点像普通的 IAT 钩子,只是有一些小的变化和技巧。