モジュールはアンロードできるので、モジュールがまだメモリにあるかどうかを確認するにはどうすればよいですか?GetModuleHandleから取得したハンドルがあります。GetHandleInformationを呼び出そうとすると、エラー0xc0000008-「無効なHANDLEが指定されました」が表示されます。これは、アンロードされる前に発生しました。
3 に答える
「ハンドル」という用語は、ここでは少しオーバーロードされています。Win32 API では、さまざまなクラスのオブジェクトが「ハンドル」と呼ばれています。
GetHandleInformation は、カーネル オブジェクト (ファイル、レジストリ キー、ミューテックスなど) へのハンドルに使用されます。
GetModuleHandle によって返される HMODULE はローダーによって使用され、実際のカーネル オブジェクトではないため、GetHandleInformation は失敗します。ただし、GetHandleInformation で取得するフラグはどちらも HMODULE には意味がありません。
HMODULE がまだメモリにロードされているかどうかを確認したい場合は、GetModuleHandle を呼び出すだけです。この API は、何度も呼び出すのに十分な速さです。ただし、GetModuleHandle の結果は、返された瞬間に無効になる可能性があります。別のスレッドが FreeLibrary を呼び出した可能性があります。DLL が読み込まれたままであることを確認することをお勧めします。これを行うには、自分で LoadLibrary を呼び出すか、DLL の参照カウントをインクリメントする GetModuleHandleEx を呼び出します。
2 つのソリューション:
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
HMODULE を照会するアドレスとして渡す VirtualQuery() を呼び出します。実験として、ロードされたライブラリと、解放されることがわかっているライブラリでこれを行います。返された MEMORY_BASIC_INFORMATION の結果が大きく異なることがわかります。この 2 つの違いを判断するための適切なアルゴリズムを考え出すことは、あなたに任せます。
警告
もちろん、これらのテストの実行中に別のスレッドがライブラリをアンロードする可能性があるという警告が適用されます。私の経験では、これが起こる可能性は非常に低いですが、それはあなたが何をしているのか、なぜそれをしているのか、いつそれをしているのか、プログラムの実行パスに大きく依存します. 注意して使用してください。
非常にシンプルな 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