windows GetModuleHandle() 如何工作?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4160659/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 15:35:48  来源:igfitidea点击:

How does GetModuleHandle() work?

windows

提问by smwikipedia

I am reading < windows via c/c++ >, it describes GetModuleHandle() API as below:

我正在阅读 < windows via c/c++ >,它描述了 GetModuleHandle() API 如下:

When you call this function, you pass a zero-terminated string that specifies the name of an executable or DLL file loaded into the calling process's address space. If the system finds the specified executable or DLL name, GetModuleHandle returns the base address where that executable or DLL;s file image is loaded.

当您调用此函数时,您将传递一个以零结尾的字符串,该字符串指定加载到调用进程地址空间中的可执行文件或 DLL 文件的名称。如果系统找到指定的可执行文件或 DLL 名称,GetModuleHandle 将返回加载该可执行文件或 DLL 文件映像的基地址。

I am wondering where does the system look for the file name? When I loaded some file into my process address space, is there some centralized table to store the mapping of all the loaded files' names and their load addresses? If we search based on a string match, is it kind of low efficiency?

我想知道系统在哪里查找文件名?当我将一些文件加载​​到我的进程地址空间时,是否有一些集中的表来存储所有加载文件的名称及其加载地址的映射?如果我们根据字符串匹配进行搜索,是不是有点效率低下?

Many thanks for your insigts.

非常感谢您的指点。

回答by swatkat

The loaded module info is maintained as a linked list in process' PEB, in a struct named PEB_LDR_DATA. If you get the PEB pointer, you can traverse through this list and get information like DLL name, base address, entry point, size etc. Check out these pages:
http://msdn.microsoft.com/en-us/library/aa813708.aspx
http://www.codeproject.com/KB/threads/CmdLine.aspx

加载的模块信息在进程的 PEB 中作为链表维护,位于名为PEB_LDR_DATA. 如果您获得 PEB 指针,您可以遍历此列表并获得诸如 DLL 名称、基地址、入口点、大小等信息。查看这些页面:
http: //msdn.microsoft.com/en-us/library/ aa813708.aspx
http://www.codeproject.com/KB/threads/CmdLine.aspx

回答by bmargulies

It looks in the loader (the Windows name for the dynamic linker)'s internal data structure.

它查看加载器(动态链接器的 Windows 名称)的内部数据结构。

GetModuleHandle only works for DLLs that you have loaded in the current process. Whenever the loader loads a DLL into the process, it of course maintains a data structure that includes the module's name. No need to visit the file system.

GetModuleHandle 仅适用于您在当前进程中加载​​的 DLL。每当加载程序将 DLL 加载到进程中时,它当然会维护一个包含模块名称的数据结构。无需访问文件系统。

LdrInitializeThunk runs in user space to start the process of pulling in the DLLs.

LdrInitializeThunk 在用户空间中运行以启动拉入 DLL 的过程。

回答by Oleg

I wanted confirm (see the answer of swatkat), that in my information the implementation of GetModuleHandle()really look inside of Wineand ReactOS(and this). You will see the implementation of GetModuleHandle(). The developers of Wine and ReactOS disassemble the code of Windows and implemented his own code based on the results of disassemble. So the code do in the most cases the same as Windows code do.

我想确认(请参阅swatkat的答案),在我的信息中,GetModuleHandle()真正查看WineReactOS(以及this)内部的实现。您将看到GetModuleHandle(). Wine 和 ReactOS 的开发者反汇编了 Windows 的代码,并根据反汇编的结果实现了自己的代码。所以在大多数情况下,代码的作用与 Windows 代码的作用相同。

If you want you can implement your own implementation of GetModuleHandle()base of VirtualAllocEx()only. See my old answerfor details. (If you not yet know the handle returned by the function GetModuleHandle()is the Address of the corresponding module in the memory, so one need just find in any way the dll in the memory of the current process).

如果您愿意,您可以实现自己的GetModuleHandle()base of VirtualAllocEx()only 实现。有关详细信息,请参阅我的旧答案。(如果你还不知道函数返回的句柄GetModuleHandle()是对应模块在内存中的地址,那么随便找个当前进程内存中的dll即可)。