How can I tell if a Windows module handle is still valid?

半城伤御伤魂 提交于 2019-12-05 09:34:52

The term "handle" is a bit overloaded here - lots of different classes of objects in the Win32 API are called "Handles".

GetHandleInformation is used for handles to kernel objects - files, registry keys, mutexes, etc.

The HMODULE returned by GetModuleHandle is used by the loader and is not an actual kernel object, hence GetHandleInformation fails. Neither of the flags you get in GetHandleInformation makes sense for HMODULE though.

If you want to check if the HMODULE is still loaded in memory, you can just call GetModuleHandle - this API should be quick enough to call many times. However, the result of GetModuleHandle can be invalid the moment it returns - another thread could have called FreeLibrary. It is better to ensure that the DLL does stay loaded. You can do this by calling LoadLibrary yourself, or by calling GetModuleHandleEx which will increment the reference count of the DLL.

Two solutions:

1

Call GetModuleFileName() on the HMODULE. If the module is loaded you will get a valid filename. If it is not loaded, you won't get a valid filename. Be sure to either set the first byte of the returned filename array to '\0' before you call GetModuleFileName() or to check the return value. If you set the first byte before the call you can effectively ignore the return value and just treat the zero length string as a "not loaded" signal.

TCHAR szModName[MAX_PATH + 1];

szModName[0] = _T('\0');
GetModuleFileName(hMod, szModName, MAX_PATH);

// zero length string if not loaded, valid DLL name if still loaded

2

Call VirtualQuery() passing the HMODULE as the address to query. As an experiment do this on a loaded library and on a library you know to be freed. You will find they have very differentl results for the returned MEMORY_BASIC_INFORMATION. I leave it to you to work out a suitable algorithm to determine the difference between the two.

Caveat

Of course, the caveat that another thread may unload the library while you are running eiher of these tests applies. In my experience, this is highly unlikely to happen, but that depends very much on what you are doing, why you are doing it, and when you are doing it the program's execution path. Use with care.

It's very simple API.

PIMAGE_NT_HEADERS (NTAPI* _RtlImageNtHeader)

Sample program:

(PVOID)typedef PIMAGE_NT_HEADERS (NTAPI *RTLIMAGENTHEADER)(PVOID);
RTLIMAGENTHEADER RtlImageNtHeader;
HMODULE hDll = GetModuleHandle("ntdll.dll");
HMODULE hDllTmp = LoadLibrary("ws2_32.dll");
RtlImageNtHeader = (RTLIMAGENTHEADER)GetProcAddress(hDll,"RtlImageNtHeader");

struct _IMAGE_NT_HEADERS *r,*r2;
r= RtlImageNtHeader(hDllTmp); 
FreeLibrary(hDllTmp);
r2= RtlImageNtHeader(hDllTmp);

//r = NULL
//r2 = return ws2_32 PE Header address
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!