0

我的应用程序包含一些关于 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 的大小只有 0x1000 而不是 0xf0000。

这就解释了为什么对超过 0x1000 大小的 VirtualLock 的调用会失败(错误代码 998:对内存位置的访问无效)并且访问内存会使应用程序崩溃。

我在哪里可以找到解释为什么 DLL 仅部分加载?Citrix 是否将 DLL 替换为存根,但未通过 GetModuleInformation 正确报告?还是发生了其他事情?

为什么 NTDLL.DLL 是从 J:\WINDOWS\SYSTEM32 加载的,而大多数其他 DLL 是从 J:\WINDOWS\SYSWOW64 加载的?(这可能表明确实使用了一些 32/64 存根)。

这是我第一次遇到这个问题。

4

1 回答 1

1

Citrix 不会存根 DLL,但它确实对各种 DLL 进行了大量挂钩。这将是我对您所看到的问题的最佳猜测。以下文章描述了挂钩以及如何禁用它:

http://support.citrix.com/article/CTX107824

http://support.citrix.com/article/CTX107825

尝试为您的应用程序禁用挂钩,看看这些问题是否会消失。

于 2013-02-28T23:49:20.703 回答