DLL获取自己的模块句柄的方法

http://bbs.s-sos.net/viewthread.php?tid=5630

DLL获取自己的模块句柄的方法


HMODULE GetSelfModuleHandle()
{
        MEMORY_BASIC_INFORMATION mbi;

        return ((::VirtualQuery(GetSelfModuleHandle, &mbi, sizeof(mbi)) != 0)
                ? (HMODULE) mbi.AllocationBase : NULL);
}

 
 
 
 
 
 

 这几天看了一下window核心编程,第22章有一个例子使用远程调用注入Dll的。其中注入Dll的时候载入dll的进程调用VirtualQuery查询进程虚拟空间得到进程载入的所有模块路径。

 

但是,查询代码很奇怪,于是翻看文档,VirtualQuery说明中没有说到过任何与dll有关的话题,但作者又如何肯定可以读出dll的信息呢?看来值得深入研究一下。

 

首先看一下代码:

 

 

  1. #include <Windows.h>
  2. #include <fstream>
  3. #include <tchar.h>
  4. int WINAPI DllMain(HINSTANCE hDllHandle, DWORD dwReason, LPVOID lpReserved)
  5. {
  6.     if (dwReason == DLL_PROCESS_ATTACH)
  7.     {
  8.         std::wfstream file;
  9.         file.open(_T("D://SeeIn.txt"), std::ios_base::out);
  10.         if (!file)
  11.         {
  12.             return FALSE;
  13.         }
  14.         MEMORY_BASIC_INFORMATION memory;
  15.         memset(&memory, 0, sizeof(memory));
  16.         DWORD pFind = NULL;
  17.         while(VirtualQuery((LPVOID)pFind, &memory, sizeof(memory)) == sizeof(memory))
  18.         {
  19.             if (memory.State == MEM_FREE)
  20.             {
  21.                 memory.AllocationBase = memory.BaseAddress;
  22.             }
  23.             if (memory.BaseAddress == hDllHandle ||
  24.                 memory.AllocationBase != memory.BaseAddress ||
  25.                 memory.AllocationBase == 0)
  26.             {
  27.                 pFind += memory.RegionSize;
  28.                 memset(&memory, 0, sizeof(memory));
  29.                 continue;
  30.             }
  31.             else
  32.             {
  33.                 TCHAR szName[MAX_PATH] = {0};
  34.                 if (0 != GetModuleFileName((HMODULE)memory.AllocationBase, szName, sizeof(szName) / sizeof(TCHAR)))
  35.                 {
  36.                     file.write(szName, sizeof(szName));
  37.                     //file.write(_T("/r/n"), sizeof(_T("/r/n")));
  38.                     file.clear();
  39.                 }
  40.             }
  41.             pFind += memory.RegionSize;
  42.             memset(&memory, 0, sizeof(memory));
  43.         }
  44.         file.close();
  45.     }
  46.     return TRUE;
  47. }

 

其中可以看出,AllocationBase == BaseAddress的时候,这个页是一个dll模块载入进来的时候分配的,查看文档,对于AllocationBase 是这么说的:

 

A pointer to the base address of a range of pages allocated by the VirtualAlloc function. The page pointed to by the BaseAddress member is contained within this allocation range.

 

翻译:一个指向一系列范围内的页的基地址的指针,这些页是通过VirtualAlloc 函数分配的。被BaseAddress 成员指向的页被包含在这个分配范围内。

 

通过代码和文档,看一看出,AllocationBase 是页的基地址,BaseAddress 也是页的基地址,唯一不同的是,BaseAddressVirtualAlloc 分配内存后第一页的地址,AllocationBase 是每一页的地址。

 

比如假设windows为每一块由VirtualAlloc 分配的内存准备了若干页:p1,p2,p3,p4,……那么,BaseAddress 就是p1的基地址,而AllocationBase 就分别是p1,p2,p3,p4,……的基地址。

 

当然,要想获得每一个页的AllocationBase ,那就必须不断的调用VirtualQuery遍历这些页。

 

还有一个重要的地方,从这个程序看出,进程载入dll内存空间是由VirtualAlloc 分配的。

 

综上,当AllocationBase == BaseAddress的时候,AllocationBase 就是模块在进程内存中的起始地址,即HMODULE。

 

至此,VirtualQuery应该是比较明了了。

 

通俗说VirtualQuery的功能就是:以页为单位,遍历进程虚拟空间。

 

一点理解,高手路过请指正!

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值