Windowsのモジュールのハンドルがまだ有効であるかどうかを確認することができますか?
質問
モジュールをアンロードすることができ、それがメモリに残っている場合はどのように私は確かに言うことができますか?私はのGetModuleHandleから得られ、それへのハンドルを、持っています。私はそれにGetHandleInformationを呼び出すしようとしたとき、私は、エラー0xc0000008を参照してください - 「無効なハンドルが指定されました。」それがアンロードされている可能性が前にこれが起こっています。
解決
用語「ハンドル」はビット、ここで過負荷になっている - のWin32 API内のオブジェクトの異なるクラスの多くは、「ハンドル」と呼ばれている。
。GetHandleInformationはオブジェクトカーネルにハンドルのために使用されている - 。ファイル、レジストリキー、ミューテックス、など。
のGetModuleHandleによって返さHMODULEはローダによって使用され、GetHandleInformationが失敗したため、実際のカーネルオブジェクトではありません。あなたがGetHandleInformationに入るフラグのどちらもかかわらず、HMODULEのために理にかなっています。
あなたはHMODULEはまだメモリにロードされているかどうかを確認したい場合は、あなただけのGetModuleHandleを呼び出すことができます - このAPIは、何度も呼び出すのに十分な速さが必要となります。別のスレッドがFreeLibraryを呼ばれたかもしれない - しかし、のGetModuleHandleの結果は、それが返す瞬間を無効することができます。 DLLが読み込まれた滞在しないことを確認することをお勧めします。あなたは、またはDLLの参照カウントをインクリメントしますGetModuleHandleExを呼び出してLoadLibraryの自分自身を呼び出すことによってこれを行うことができます。
他のヒント
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
コールVirtualQuery()を照会するアドレスとしてHMODULEを渡します。実験としてロードされたライブラリに、あなたが解放されるために知っているライブラリでこれを行います。あなたは、彼らが返さMEMORY_BASIC_INFORMATIONのために非常にdifferentl結果を持っています。私は2つの間の差を決定するために適切なアルゴリズムを動作するようにあなたにそれを残しています。
警告
もちろん、あなたが適用されるこれらのテストの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