私のアプリケーションには、DLL に関するいくつかの特定のロジックが含まれています (ここで説明するには少し複雑すぎます)。しかし、そのロジックでは、次のことに気付きました (顧客の Citrix ターミナル サーバー上で):
NTDLL.DLL で GetModuleInformation を呼び出すと、返された MODULEINFO は 0x7d600000 の最初のアドレス (lpBaseOfDll) と 0xf0000 のサイズを返します (したがって、最後のバイトは 0x7d6effff にある必要があります)。
ただし、クラッシュ ダンプ ファイルでは、WinDbg で次のように表示されます (!address を使用):
* 7d600000 7d601000 1000 Image "J:\WINDOWS\system32\ntdll.dll"
* 7d610000 7d65f000 4f000 <unclassified>
* 7d65f000 7d660000 1000 <unclassified>
* 7d660000 7d699000 39000 <unclassified>
* 7d6a0000 7d6a6000 6000 <unclassified>
* 7d6b0000 7d6df000 2f000 <unclassified>
* 7d6e0000 7d6e4000 4000 <unclassified>
* 7d800000 7d801000 1000 Image "J:\WINDOWS\SysWOW64\gdi32.dll"
* 7d810000 7d855000 45000 <unclassified>
* 7d860000 7d861000 1000 <unclassified>
* 7d861000 7d862000 1000 <unclassified>
* 7d870000 7d871000 1000 <unclassified>
* 7d880000 7d882000 2000 <unclassified>
したがって、NTDLL.DLL のサイズは 0xf0000 ではなく 0x1000 しかないようです。
これは、0x1000 のサイズを超える VirtualLock の呼び出しが失敗し (エラー コード 998: メモリ ロケーションへの無効なアクセス)、メモリにアクセスするとアプリケーションがクラッシュする理由を説明しています。
DLL が部分的にしかロードされない理由はどこにありますか? Citrix は DLL をスタブに置き換えますが、GetModuleInformation を介してこれを正しく報告しませんか? それとも何か他のことが起こっていますか?
また、NTDLL.DLL は J:\WINDOWS\SYSTEM32 からロードされるのに、他のほとんどの DLL は J:\WINDOWS\SYSWOW64 からロードされるのはなぜですか? (これは、実際に 32/64 スタブが使用されていることを示している可能性があります)。
この問題に遭遇したのは初めてです。