模块可以卸载,那么我如何确定它是否仍在内存中?我有一个从GetModuleHandle获得的句柄。当我尝试对它调用GetHandleInformation时,我看到错误0xc0000008 -“指定了无效的句柄”。这发生在它可能被卸载之前。
发布于 2009-07-10 20:42:14
术语“句柄”在这里有点过载-- Win32应用程序接口中的许多不同类的对象被称为“句柄”。
GetHandleInformation用于内核对象的句柄-文件、注册表项、互斥等。
由GetModuleHandle返回的HMODULE由加载器使用,并且不是实际的内核对象,因此GetHandleInformation失败。但是,您在GetHandleInformation中获得的这两个标志对于HMODULE都没有意义。
如果您想检查HMODULE是否仍然加载在内存中,您可以只调用GetModuleHandle -此API应该足够快,可以多次调用。然而,GetModuleHandle的结果在它返回的那一刻可能是无效的--另一个线程可能已经调用了FreeLibrary。最好确保DLL保持加载状态。您可以通过自己调用LoadLibrary或调用将递增DLL的引用计数的GetModuleHandleEx来完成此操作。
发布于 2010-05-13 03:22:14
两种解决方案:
1
在HMODULE上调用GetModuleFileName()。如果模块已加载,您将获得一个有效的文件名。如果它没有加载,你将不会得到一个有效的文件名。在调用GetModuleFileName()之前,请确保将返回的文件名数组的第一个字节设置为'\0‘,或者检查返回值。如果在调用前设置了第一个字节,则可以有效地忽略返回值,只将长度为零的字符串视为“未加载”信号。
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
调用VirtualQuery(),将HMODULE作为要查询的地址。作为实验,在已加载的库和您知道要释放的库上执行此操作。你会发现他们对返回的MEMORY_BASIC_INFORMATION有非常不同的结果。我让您自己找出一个合适的算法来确定两者之间的差异。
注意事项
当然,在您运行这些测试时,另一个线程可能会卸载库的警告也适用。根据我的经验,这不太可能发生,但这在很大程度上取决于你在做什么,你为什么要这么做,以及你什么时候在程序的执行路径上这么做。谨慎使用。
发布于 2016-10-06 09:43:10
这是一个非常简单的API。
PIMAGE_NT_HEADERS (NTAPI* _RtlImageNtHeader)
示例程序:
(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
https://stackoverflow.com/questions/1111820
复制相似问题