C 获取实际函数LoadLibraryExW的地址而不是存根LoadLibraryExWStub
我试图获取DLLC 获取实际函数LoadLibraryExW的地址而不是存根LoadLibraryExWStub,c,winapi,C,Winapi,我试图获取DLLLoadLibraryExW中函数的地址。但是,当我尝试获取此函数的地址时,实际上我获取了一个LoadLibraryExWStub的地址 #include <stdio.h> #include <Windows.h> intptr_t getFuncAddr(const char* func, const char* dll) { return (intptr_t)GetProcAddress( GetModuleHandle(d
LoadLibraryExW
中函数的地址。但是,当我尝试获取此函数的地址时,实际上我获取了一个LoadLibraryExWStub
的地址
#include <stdio.h>
#include <Windows.h>
intptr_t getFuncAddr(const char* func, const char* dll)
{
return (intptr_t)GetProcAddress(
GetModuleHandle(dll),
func);
}
int main()
{
// Actual address: 000007FEFD28B2B0 Stub address I get instead: 0x00000000771d5680
intptr_t loadLibExWAddr = getFuncAddr("LoadLibraryExW", "kernel32.dll");
printf("%x\n", (int)loadLibExWAddr);
}
在kernel32.dll
的程序集中,我还看到另一个名为LoadLibraryExW
的函数,其定义如下:
LoadLibraryExW:
00000000771D5674 FF 25 CE 80 08 00 jmp qword ptr [__imp_LoadLibraryExW (07725D748h)]
00000000771D567A 90 nop
00000000771D567B 90 nop
00000000771D567C 90 nop
00000000771D567D 90 nop
00000000771D567E 90 nop
00000000771D567F 90 nop
这让我更加困惑。它们如何可以是两个LoadLibraryExW
函数
因此,重申一下,我想获取实际执行DLL加载的核心
LoadLibraryExW
函数的函数地址;并不是所有其他的东西看起来都是这样的。一节历史课在解释这一点时很有帮助
Windows95只有正常的导出功能,NT3&4可能有一些。底层Win32函数存在于kernel32、user32和gdi32中,仅此而已。NTDLL应该是完全没有文档记录和禁止的
在Vista时代,微软进行了一项名为的实验,该实验改变了某些组件的分层结构。在Windows 7中,一些函数实现大部分或全部迁移到新的kernelbase.dll
Win32 ABI和数百万应用程序当然依赖于内核32中的LoadLibraryExW
,因此仍然存在一个简单的存根函数函数的名称仍然是LoadLibraryExW
,但符号的名称中通常有一个存根后缀,因为函数在跳转到新的主位置之前几乎不工作。Windows7还添加了“功能”,该功能通过不将函数绑定到特定的.dll,使这些类型的更改在将来变得更容易
挂钩图书馆不应该对此感到惊讶。忘记符号,关注GetProcAddress
及其返回的地址。从ABI的角度来看,函数以jmp
开头是合法的,任何类型的蹦床/挂钩库都必须能够处理它
如果您只关心符合文档化API的应用程序,那么您最好使用IAT挂钩。如果您想钩住“一切”,那么LoadLibrary*
的深度永远不够
注意:加载程序的核心实际上在NTDLL中,LoadLibrary*
在基于NT的系统上从不执行实际加载。如果您想得到有关加载模块的通知,真正的安全软件可能应该在内核中捕获映像部分
注意:
jmpqwordptr[\uu imp\uu…]
通常是对另一个.dll中的函数的调用。这是有道理的,因为转储文件中的000007FEFD28B2B0
很可能不在内核32中。在解释这一点时,上一节历史课很有帮助
Windows95只有正常的导出功能,NT3&4可能有一些。底层Win32函数存在于kernel32、user32和gdi32中,仅此而已。NTDLL应该是完全没有文档记录和禁止的
在Vista时代,微软进行了一项名为的实验,该实验改变了某些组件的分层结构。在Windows 7中,一些函数实现大部分或全部迁移到新的kernelbase.dll
Win32 ABI和数百万应用程序当然依赖于内核32中的LoadLibraryExW
,因此仍然存在一个简单的存根函数函数的名称仍然是LoadLibraryExW
,但符号的名称中通常有一个存根后缀,因为函数在跳转到新的主位置之前几乎不工作。Windows7还添加了“功能”,该功能通过不将函数绑定到特定的.dll,使这些类型的更改在将来变得更容易
挂钩图书馆不应该对此感到惊讶。忘记符号,关注GetProcAddress
及其返回的地址。从ABI的角度来看,函数以jmp
开头是合法的,任何类型的蹦床/挂钩库都必须能够处理它
如果您只关心符合文档化API的应用程序,那么您最好使用IAT挂钩。如果您想钩住“一切”,那么LoadLibrary*
的深度永远不够
注意:加载程序的核心实际上在NTDLL中,LoadLibrary*
在基于NT的系统上从不执行实际加载。如果您想得到有关加载模块的通知,真正的安全软件可能应该在内核中捕获映像部分
注意:
jmpqwordptr[\uu imp\uu…]
通常是对另一个.dll中的函数的调用。这是有道理的,因为转储中的000007FEFD28B2B0
很可能不在内核32中。不可能。您得到的是DLL导出的内容,而不是您想要的内容。@MichaelChourdakis Hm,这也许可以解释“重复函数”的问题,但我仍然不知道为什么解析LoadLibraryExW
的地址会给我LoadLibraryExWStub
的地址。此外,我如何获得LoadLibraryExW
的“实际”地址。如前所述,您所得到的只是DLL名称->符号的映射。该符号可以是任何与可能具有相同名称的实际函数无关的东西。你到底需要它做什么。热修补?@OverloadedOperator-热修补代码必须分析指令并具有最小的反汇编程序。所以这里没有问题-如果热补丁代码视图跳转(短)它-转到jmp@OverloadedOpeator-你的“实际”地址是什么(是什么?)。你只需要做补丁。全部的别忘了其他人都和你有相同的地址。不可能。您得到的是DLL导出的内容,而不是您想要的内容。@MichaelChourdakis Hm,这也许可以解释“重复函数”的问题,但我仍然不知道为什么解析LoadLibraryExW
的地址会给我LoadLibr的地址
LoadLibraryExW:
00000000771D5674 FF 25 CE 80 08 00 jmp qword ptr [__imp_LoadLibraryExW (07725D748h)]
00000000771D567A 90 nop
00000000771D567B 90 nop
00000000771D567C 90 nop
00000000771D567D 90 nop
00000000771D567E 90 nop
00000000771D567F 90 nop