dliNotePreLoadLibrary実際に読み込む前に、読み込まれる DLL のコード署名を検証するために、独自の遅延読み込みフックを使用しています。コードが実行されるのを避けるために、(フックLoadLibraryExA(...,...,LOAD_LIBRARY_AS_DATAFILE)はANSI名のみを提供するので問題ありません)を使用してロードし、検証後にアンロードして、コード付きのDLLとしてロードできるようにします。
デバッガーでコードをステップ実行すると、ハンドルを受け取り、そのハンドルが<baseaddress>+1"データ モジュール" に期待されるものであることがわかります。ただし、このハンドルをライブラリ関数内に渡そうとするとGetModuleFileName(これが、名前を渡すことができず、モジュール ハンドルのみを渡すことができない理由でもあります)、関数が戻り0、GetLastError が返されますERROR_MOD_NOT_FOUND。しかし、モジュールはロードされたので、確実に見つかりました。また、これは現在のプロセスにあるため、「対象プロセス」へのアクセスはここでは問題ありません。
そのため、ロードしたばかりの DLLVirtualQueryの実際のベース アドレス ( ) を取得するために使用しない理由を考えましたが (これが問題の場合)、結果は同じままです: .MEMORY_BASIC_INFORMATION::BaseAddress<baseaddress>+1ERROR_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。