GetProcAddress 不是 return LoadLibraryA 的真实地址

GetProcAddress doesn't return the real address for LoadLibraryA

DWORD dwLoadLibrary = (DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");

当我转到 OllyDbg 中的 returned 地址时,我可以看到该地址指向跳转到 LoadLibraryA 的真实地址的代码。我想获得 LoadLibraryA 的真实地址,它不会改变,因为 kernel32.dll 在每个进程中的相同位置加载,而且我想知道为什么 GetProcAddress 不 return 真实地址。

这是 LoadLibraryA 的 "real" 地址。跳转指令用于工具将间接寻址放在那里。他们会把那个跳转的目的地址和别的东西交换,指向钩子,执行钩子后跳转到原来的位置去真正执行函数。

你怎么知道这不是LoadLibraryA的真实地址?也许试试 WinDbg?

在我的 Windows 8 系统上 GetProcAddress(x, "LoadLibraryA") returns 以正常 mov edi,edi hotpatch reservation 开始的函数(以及函数的其余部分)但不是表示在其他版本不能以跳转开头。

您正在获取 kernel32.LoadLibraryA 的 "real" 地址,因为 GetProcAddress() returns 是真实地址。只是 kernel32.LoadLibrayA 的实现已从 kernel32.dll 移动到 kernelbase.dll,因此 kernel32.LoadLibraryA 仅包含一条指令:

jmp dword ptr[kernelbase.LoadLibraryA]

如果您查看 kernel32.dll 中的更多函数,其中许多函数也具有相同的模式:

kernel32.somefunc:
    jmp [kernelbase.somefunc]