dliNotePreLoadLibrary
実際に読み込む前に、読み込まれる DLL のコード署名を検証するために、独自の遅延読み込みフックを使用しています。コードが実行されるのを避けるために、(フックLoadLibraryExA(...,...,LOAD_LIBRARY_AS_DATAFILE)
はANSI名のみを提供するので問題ありません)を使用してロードし、検証後にアンロードして、コード付きのDLLとしてロードできるようにします。
デバッガーでコードをステップ実行すると、ハンドルを受け取り、そのハンドルが<baseaddress>+1
"データ モジュール" に期待されるものであることがわかります。ただし、このハンドルをライブラリ関数内に渡そうとするとGetModuleFileName
(これが、名前を渡すことができず、モジュール ハンドルのみを渡すことができない理由でもあります)、関数が戻り0
、GetLastError が返されますERROR_MOD_NOT_FOUND
。しかし、モジュールはロードされたので、確実に見つかりました。また、これは現在のプロセスにあるため、「対象プロセス」へのアクセスはここでは問題ありません。
そのため、ロードしたばかりの DLLVirtualQuery
の実際のベース アドレス ( ) を取得するために使用しない理由を考えましたが (これが問題の場合)、結果は同じままです: .MEMORY_BASIC_INFORMATION::BaseAddress
<baseaddress>+1
ERROR_MOD_NOT_FOUND
私はアイデアがありません。ここで何が起こっているのか誰にも考えがありますか?
テストのプラットフォーム: Windows 7 SP1、x64 (最新のパッチ)
のコードは次のとおりです。
FARPROC WINAPI MyDliHook(unsigned dliNotify, PDelayLoadInfo pdli)
{
switch(dliNotify)
{
case dliNotePreLoadLibrary:
if(0 == lstrcmpiA(pdli->szDll, "DLLNAME.dll"))
{
HMODULE hVerifiedDll = LoadLibraryExA(pdli->szDll, NULL, LOAD_LIBRARY_AS_DATAFILE);
if(hVerifiedDll)
{
MEMORY_BASIC_INFORMATION mbi;
if(0 != VirtualQuery(hVerifiedDll, &mbi, sizeof(mbi)));
{
VerifyModuleSignature((HMODULE)mbi.BaseAddress, pdli->szDll);
}
FreeLibrary(hVerifiedDll);
}
}
break;
default:
break;
}
return NULL;
}
PfnDliHook __pfnDliNotifyHook2 = MyDliHook;
この関数VerifyModuleSignature
は、最初にGetModuleFileName
ファイル名を取得するために呼び出しますが、その段階で失敗します。.exe
プロセスを作成する で、コード署名の検証が正常に機能することを確認しました。
補足:ERROR_MOD_NOT_FOUND
エラーの原因GetModuleFileName
がLoadLibraryExA
. 「汚染された」最後のエラーコードを取得しないようにするためにSetLastError(ERROR_SUCCESS)
、 への呼び出しの直前に呼び出しましたGetModuleFileName
。