我的应用程序包含一些关于DLL的特定逻辑(这里有点太复杂了)。 但是在那个逻辑中,我注意到以下内容(在客户的Citrix终端服务器上):
在NTDLL.DLL上调用GetModuleInformation时,返回的MODULEINFO返回第一个地址(lpBaseOfDll)0x7d600000,大小为0xf0000(所以它的最后一个字节应该是0x7d6effff)。
但是,在崩溃转储文件中,我在WinDbg中看到以下内容(使用!地址):
* 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的大小只有0x1000而不是0xf0000。
这解释了为什么超过0x1000大小的VirtualLock调用失败(错误代码998:对内存位置的访问无效)以及访问内存会导致应用程序崩溃。
在哪里可以找到解释为什么DLL只是部分加载的解释? Citrix是否用存根替换DLL,但是没有通过GetModuleInformation正确报告这个?或者还有其他事情发生了吗?
为什么NTDLL.DLL是从J:\ WINDOWS \ SYSTEM32加载的,而其他大多数DLL是从J:\ WINDOWS \ SYSWOW64加载的? (这可能表明确实使用了一些32/64-stub)。
这是我第一次遇到这个问题。
答案 0 :(得分:1)
Citrix没有存根DLL,但它确实对各种DLL进行了很多挂钩。对于你所看到的问题,这是我最好的猜测。以下文章描述了挂钩以及如何禁用它:
http://support.citrix.com/article/CTX107824
http://support.citrix.com/article/CTX107825
尝试禁用应用程序的挂钩,以查看这些问题是否消失。