如何獲得當前執行模組在程序地址空間的位置
阿新 • • 發佈:2019-01-25
(w)WinMain的hInstanceExe引數實際值是一個記憶體基地址;系統將可執行檔案的映像載入到程序地址空間中的這個位置。例如,系統開啟可執行檔案,並將它載入到地址0x00400000,則(w)WinMain的hInstanceExe引數值為0x00400000.
為了知道一個可執行檔案或DLL檔案被載入到程序地址空間的什麼位置,可以使用GetModuleHandle函式來返回一個控制代碼/基地址
- 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的基地址來填寫該指標。以下程式碼對這幾種方法進行演示。
- extern"C"const IMAGE_DOS_HEADER __ImageBase;
- void DumpModule()
- {
- HMODULE hMoudle = GetModuleHandle(NULL);
- _tprintf(TEXT("with GetModuleHandle(NULL) = 0x%x\r\n"),hMoudle);
- _tprintf(TEXT("with _ImageBase = 0x%x\r\n"),(HINSTANCE)&__ImageBase);
- hMoudle = NULL;
-
GetModuleHandleEx(
- GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
- (PCTSTR)DumpModule,
- &hMoudle);
- _tprintf(TEXT("with GetModuleHandleEx = 0x%x\r\n"),hMoudle);
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- DumpModule();
- return 0;
- }