如何获得当前运行模块在进程地址空间的位置

来源:互联网 发布:ctr预估用什么数据 编辑:程序博客网 时间:2024/05/07 23:10

(w)WinMain的hInstanceExe参数实际值是一个内存基地址;系统将可执行文件的映像加载到进程地址空间中的这个位置。例如,系统打开可执行文件,并将它加载到地址0x00400000,则(w)WinMain的hInstanceExe参数值为0x00400000.

 

为了知道一个可执行文件或DLL文件被加载到进程地址空间的什么位置,可以使用GetModuleHandle函数来返回一个句柄/基地址

 

  1. HMODULE GetModuleHandle(PCTSTR pszModule)  


调用这个函数是,要传递一个以0为终止字符的字符串,它指定了已在主调进程的地址空间中加载的一个可执行文件或DLL文件的名称。如果系统找到了可执行文件或DLL文件名称,GetModuleHandle就会返回可执行文件/DLL文件映像加载到基地址。如果没有找到文件,系统将返回NULL。

 

GetModuleHandle的另一个用法是为pszModule参数传入NULL,这样就可以返回主调进程模块的基地址。如果我们的代码在一个DLL中,那么可利用两种方法来了解代码正在什么模块中运行。

第一个办法是利用链接器提供的伪变量__ImageBase,它指向当前正在运行的模块的基地址。这是C语言运行库启动代码在调用我们的(w)WinMain函数时所做的事情。

第二种方法是调用GetMoudleHandleEx,将GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS作为它的第一个参数,将当前函数的地址作为第二个参数。最后一个参数是一个指向HMODULE的指针,GetModuleHandleEx会用传入函数(即第二个参数)所在DLL的基地址来填写该指针。以下代码对这几种方法进行演示。

 

  1. extern "C" const IMAGE_DOS_HEADER __ImageBase;  
  2.   
  3. void DumpModule()  
  4. {  
  5.     HMODULE hMoudle = GetModuleHandle(NULL);  
  6.     _tprintf(TEXT("with GetModuleHandle(NULL) = 0x%x\r\n"),hMoudle);  
  7.   
  8.     _tprintf(TEXT("with _ImageBase = 0x%x\r\n"),(HINSTANCE)&__ImageBase);  
  9.   
  10.     hMoudle = NULL;  
  11.     GetModuleHandleEx(  
  12.         GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,  
  13.         (PCTSTR)DumpModule,  
  14.         &hMoudle);  
  15.     _tprintf(TEXT("with GetModuleHandleEx = 0x%x\r\n"),hMoudle);  
  16. }  
  17.   
  18. int _tmain(int argc, _TCHAR* argv[])  
  19. {  
  20.     DumpModule();  
  21.     return 0;  
  22. }  


 

0 0
原创粉丝点击