DLL 內部獲取自身絕對路徑

常見的獲取方法是通過 GetModuleHandle(NULL),獲取當前EXE句柄,然後通過GetModuleFileName獲取EXE路徑。Dll在該路徑下加上 “xxx.dll”,即可。
但是有時候 dll 與 exe 不一定在一個位置,甚至 dll 並沒有按照指定的目錄關係與 exe 有明確的對應關係,甚至 dll 的最終名稱作爲 dll 的編寫者並不清楚(比如重命名)。

有以下幾種方法:

  1. 在dllmain中保存HMODULE
  2. 使用如下代碼 GetSelfModuleHandle
HMODULE GetSelfModuleHandle()
{
	MEMORY_BASIC_INFORMATION mbi;
	// AABB 是 dll 內部任意一個函數或全局變量地址
	return ((::VirtualQuery(AABB, &mbi, sizeof(mbi)) != 0) ? (HMODULE)mbi.AllocationBase : NULL);
	// 更簡單的直接用當前函數本身
	return ((::VirtualQuery(GetSelfModuleHandle, &mbi, sizeof(mbi)) != 0) ? (HMODULE)mbi.AllocationBase : NULL);
}
  1. 使用 GetModuleHandleEx
HMODULE hModule = NULL;
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
            (LPCSTR)&XXX, //可以是任何函數,全局變量等的地址
           &hModule);
// 更簡單的
	HMODULE hModule = NULL;
	GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
		__FUNCTION__,
		&hModule);
	HMODULE hModule = NULL;
	GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
		__FUNCTIONW__,
		&hModule);
  1. 使用 __ImageBase
   	extern "C" IMAGE_DOS_HEADER __ImageBase;
   	HMODULE _hd = (HMODULE)&__ImageBase;

以上只要得到了 HMODULE ,自然可以通過 GetModuleFileName 來獲取了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章