获取代码运行所在模块的HMODULE/HINSTANCE的句柄值

最近看代码,遇到一个很有趣的问题:如何获取一个静态库代码链接进模块的句柄?
模块句柄值实际上是这个模块加载内存中的基地址。我们暂且放下这个问题,先看看动态库是如何获取句柄值的。

动态库获取句柄值

正常情况下一个动态库dll获取它的句柄,可以通过GetModuleHandle或者GetModuleHandleEx这个API来获取。

这个两个API都需要把dll模块名传进去才能获取句柄值。但是dll可能被人重命名,所以这个方法不一定百分百可靠。

另外一种办法是在DLLMain入口函数里保存hinstDLL值。但是不一定所有的Dll都有Dll,所以这个方法也是不一定百分百可靠。

还有种方法是调用VirtualQuery接口获取MEMORY_BASIC_INFORMATION值:

MEMORY_BASIC_INFORMATION结构体里面的MEMORY_BASIC_INFORMATION.AllocationBase就是基地址,可以转换成模块的句柄。这个算是获取Dll句柄的终极办法了。但是这个办法毕竟有些hack,不到万不得已,就别用。

从http://www.codeguru.com/Cpp/W-P/dll/tips/article.php/c3635/ 学到一个办法,这里有段代码是专门用来解决这个问题的:

这段代码里面还有另外一种获取模块句柄的方法:__ImageBase。
__ImageBase是Microsoft编译器生成的伪变量,__ImageBase代表着模块的DOS头,也就是模块的起始地址。换言之,也就是这个模块的基地址,这个模块的句柄。

静态库获取句柄值

因为你不知道静态库会被哪个模块链接,所以无法使用GetModuleHandle这个API来获取句柄。它没有DLLMain函数,也无法使用VirtualQuery。幸好静态库同样可以使用__ImageBase。详见https://blogs.msdn.microsoft.com/oldnewthing/20041025-00/?p=37483/ 介绍。

发表评论

电子邮件地址不会被公开。 必填项已用*标注