1. 程式人生 > >如何獲得當前執行模組在程序地址空間的位置

如何獲得當前執行模組在程序地址空間的位置

(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. void DumpModule()  
  3. {  
  4.     HMODULE hMoudle = GetModuleHandle(NULL);  
  5.     _tprintf(TEXT("with GetModuleHandle(NULL) = 0x%x\r\n"),hMoudle);  
  6.     _tprintf(TEXT("with _ImageBase = 0x%x\r\n"),(HINSTANCE)&__ImageBase);  
  7.     hMoudle = NULL;  
  8.     GetModuleHandleEx(  
  9.         GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,  
  10.         (PCTSTR)DumpModule,  
  11.         &hMoudle);  
  12.     _tprintf(TEXT("with GetModuleHandleEx = 0x%x\r\n"),hMoudle);  
  13. }  
  14. int _tmain(int argc, _TCHAR* argv[])  
  15. {  
  16.     DumpModule();  
  17.     return 0;  
  18. }