可以卸载一个模块,那么如何确定它是否仍在存储器中?我有一个从getModulehandle获得的手柄。当我尝试在其上调用Gethandleformation时,我会看到错误0xc0000008-“指定了无效的手柄”。这发生在本来可以卸载之前。

有帮助吗?

解决方案

“句柄”一词在这里有点超载 - Win32 API中的许多不同类别的对象称为“ handles”。

Gethandleformation用于句柄用于内核对象 - 文件,注册表键,静音等。

GetModuleHandle返回的HMODULE由加载程序使用,不是实际的内核对象,因此GethandLeinformation失败了。但是,您在Gethandleformation中获得的旗帜对Hmodule都没有意义。

如果要检查HMODULE是否仍在内存中加载,则只需调用GetModuleHandle-此API应该足够快地调用很多次。但是,getModulehandle的结果在返回的那一刻时可能无效 - 另一个线程可能称为Freelibrary。最好确保DLL确实保持加载。您可以通过自己调用LoadLibrary或调用GetModuleHandleex来执行此操作,以增加DLL的参考计数。

其他提示

两个解决方案:

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作为查询地址。作为一个实验,请在已加载的库和图书馆上进行此操作,您知道将被释放。您会发现它们对返回的MONEME_BASIC_INFORMATION的结果非常不同。我让您使用合适的算法来确定两者之间的差异。

警告

当然,在适用这些测试的EIHER时,另一线程可能会卸载库的警告。根据我的经验,这极不可能发生,但这很大程度上取决于您在做什么,为什么要做的事情以及您在执行程序的执行路径时。 谨慎使用。

这是非常简单的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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top