有没有办法让Windows 7 x64从本地目录加载ntdll.dll,而不是system32?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了有没有办法让Windows 7 x64从本地目录加载ntdll.dll,而不是system32?相关的知识,希望对你有一定的参考价值。
我正在开发一个应用程序,它可以保存自定义进程的状态,然后从停止的点恢复它。
现在有以下问题。当系统重启时,系统模块的所有基地址都是随机的(ntdll.dll
,kernelbase.dll
,kernel32.dll
等)。操作系统是Windows 7 x64 Enterprise。在重新启动后尝试恢复应用程序时,它显然会崩溃(但在重新启动之前从恢复点运行良好)。我看到2个解决方案:
- 在应用程序中加载系统模块时,使其地址静态
- 修补应用程序中目标模块的所有引用(堆栈上的函数地址,可以保存在堆中的地址等)
显然,第二种方式很难。我们要进行完整的应用程序分析,不同的数据代码,不同的数据,它可能是从参考系统模块的简单整数...所以我选择了第一种方式。
在虚拟内存中加载模块时,OS首先检查物理内存中是否已存在具有此类名称的模块。如果有,它只是将此模块映射到虚拟地址空间。在这种情况下,模块从ntdll.dll
的C:WindowsSystem32
tdll.dll
的初始位置加载。即使将此模块复制到应用程序目录,禁用ASLR标志并将映像库修补为某个值,该模块仍将从系统目录加载。需要一些重定向方式。
从MSDN我们学到以下内容(“桌面应用程序的搜索顺序”部分):
桌面应用程序可以通过使用DLL redirection或使用manifest指定完整路径来控制加载DLL的位置。如果未使用这些方法,系统将在加载时搜索DLL,如本节所述。
因此,至少有两种方法可以实现这一目标。
在关于DLL重定向的页面上,我们看到:
已知的DLL无法重定向。有关已知DLL的列表,请参阅以下注册表项:HKEY_LOCAL_MACHINE SYSTEM CurrentControlSet Control Session Manager KnownDLLs。系统使用Windows文件保护来确保除了操作系统更新(如Service Pack)之外,不会更新或删除此类系统DLL。
我想重定向的模块是已知的DLL,因此无法应用此变体。
清除了清单。关于使用它们有一个很好的article。本文作者创建了存根DLL来替换原始的(user32.dll
),然后使应用程序加载这个被替换的DLL。重点是在搜索导入的函数时加载此DLL,而不是在应用程序的最开始时加载,如ntdll.dll
。
更具体地说,让我们参考“Windows Internals,Sixth Edition”,p。 359解释了流程创建的细节。那里有7个阶段:
- 转换和验证参数和标志
- 打开要执行的图像
- 创建Windows Executive Process对象
- 创建初始线程及其堆栈和上下文
- 执行Windows子系统特定的后初始化
- 开始执行初始线程
- 在新流程的上下文中执行流程初始化
这里最重要的一点是:
ntdll.dll
的映射发生在第3阶段;- 在第5阶段开始时我们阅读(重点是我的):
此时,Kernel32.dll向Windows子系统发送一条消息,以便它可以设置SxS信息(有关并排程序集的更多信息,请参阅本节末尾),例如清单文件,DLL重定向路径和新流程的进程外执行。
这意味着在重定向有可能发生之前加载ntdll.dll
。有关重定向主题的SO有很多问题,但它们都是关于在搜索导入函数时加载的DLL,或者是在应用程序中可能发生重定向时通过LoadLibrary
显式加载的DLL。
但是,ntdll.dll
在任何情况下都会在很早的阶段加载。
使用我到目前为止收集的所有信息,我能够进行应用程序搜索,例如,在应用程序的目录中使用kernel32.dll
(使用本段中的链接)。但我无法重定向搜索ntdll.dll
。
完全可以从用户模式?
附:有一种方法可以全局禁用ASLR,请参阅此post。然而,这是一种非常粗鲁的方式,像Internet Explorer
,Adobe Reader
这样的应用程序无法工作,整个操作系统都容易受到漏洞的攻击。
以上是关于有没有办法让Windows 7 x64从本地目录加载ntdll.dll,而不是system32?的主要内容,如果未能解决你的问题,请参考以下文章
Rails 应用程序无法通过命名管道/套接字连接到本地 MySQL 服务器 --- Windows 7 x64
在 Windows 7 Git Bash 中,有没有办法探索当前位置的目录?