我正在阅读< windows通过c / c ++>,它描述了GetModuleHandle()API,如下所示:
调用此函数时,传递一个以零结尾的字符串,该字符串指定加载到调用进程的地址空间中的可执行文件或DLL文件的名称。 如果系统找到指定的可执行文件或DLL名称,GetModuleHandle将返回加载该可执行文件或DLL文件映像的基址。
我想知道系统在哪里寻找文件名?当我将一些文件加载到我的进程地址空间时,是否有一些集中表来存储所有已加载文件的名称及其加载地址的映射?如果我们根据字符串匹配进行搜索,那么效率会低吗?
非常感谢你的诅咒。
答案 0 :(得分:10)
加载的模块信息在进程'PEB中保存为名为PEB_LDR_DATA
的结构中的链接列表。如果你得到PEB指针,你可以遍历这个列表并获取DLL名称,基地址,入口点,大小等信息。查看这些页面:
http://msdn.microsoft.com/en-us/library/aa813708.aspx
http://www.codeproject.com/KB/threads/CmdLine.aspx
答案 1 :(得分:4)
它在加载器中查找(动态链接器的Windows名称)的内部数据结构。
GetModuleHandle仅适用于您在当前进程中加载的DLL。每当加载器将DLL加载到进程中时,它当然会维护一个包含模块名称的数据结构。无需访问文件系统。
LdrInitializeThunk在用户空间中运行以启动拉入DLL的过程。
答案 2 :(得分:4)
我想要确认(请参阅 swatkat 的答案),在我的信息中,GetModuleHandle()
的实施真正了解Wine和ReactOS(以及this)。您将看到GetModuleHandle()
的实现。 Wine和ReactOS的开发人员反汇编Windows代码,并根据反汇编的结果实现自己的代码。因此代码在大多数情况下与Windows代码相同。
如果您愿意,您只能实现自己GetModuleHandle()
VirtualAllocEx()
基础的实现。有关详细信息,请参阅我的old answer。 (如果你还不知道函数GetModuleHandle()
返回的句柄是内存中相应模块的地址,那么只需要以任何方式查找当前进程内存中的dll。)