Mar*_* Ba 27 c c++ windows dll
重新绑定DLL意味着修复DLL,这是首选的加载地址是Loader实际上能够加载DLL的加载地址.
这可以通过诸如Rebase.exe或通过为所有(自己的)dll指定默认加载地址等工具来实现,以便它们"适合"您的可执行进程.
以这种方式管理DLL基地址的重点是加速应用程序负载.(或者我理解.)
现在的问题是:值得麻烦吗?
我有Richter/Nazarre的Windows via C/C++一书,他们强烈建议[a]确保加载地址全部匹配,以便Loader不必重新加载加载的DLL.
但是,如果这样可以将应用程序加载时间加快到任何显着的数量,他们就无法争辩.
此外,对于ASLR,它似乎有任何价值,因为负载地址无论如何都是随机的.
关于这个的利弊是否有任何确凿的事实?
[a]:在我的WvC++/5th ed中,它位于第568ff页的标题为Rebasing Modules and Binding Modules的部分.在第20章,DLL高级技巧.
Han*_*ant 12
修补可重定位的地址并不是什么大问题,它以内存速度(微秒)运行.更大的问题是包含此代码的页面现在需要由页面文件而不是DLL文件备份.换句话说,当包含代码的页面未映射时,需要将它们写入页面文件而不是仅丢弃.
这样做的成本并不容易,特别是在具有大量RAM的现代机器上.它只计算机器开始负载时有很多进程争夺内存.和分页文件的碎片.
但显然,变基是一种非常便宜的优化.在Debug + Windows + Modules窗口中很容易看到,在重新命名的DLL上有一个明亮的图标."地址"列为您提供了一个很好的提示,即基本地址是一个不错的选择.在它们之间留出足够的空间,这样您就不必在程序增长时不断调整它.
我想自己提供一个答案,尽管Hans Passant和其他人的答案已经很好地描述了这些权衡.
在我们的应用程序中最近摆弄DLL基地址后,我将在此给出我的结论:
我认为,除非你能证明不是这样,否则为DLL提供非默认的基地址是徒劳的.这包括重新定义我的DLL.
对于我控制的DLL,给定平均应用程序,每个DLL只会被加载到内存中一次,因此页面文件上的负载应该是最小的.(但请参阅Michal Burr在关于终端服务器环境的另一个答案中的评论.)
如果为DLL提供了固定的基址(没有重新定位),它实际上会增加地址空间碎片,因为这些地址迟早不再匹配.在我们的应用程序中,我们给了所有DLL一个固定的基地址(出于其他遗留原因,而不是因为地址空间碎片)而没有使用rebase.exe,这显着增加了我们的地址空间碎片,因为你真的无法手动获得这个权限.
重新定位(通过rebase.exe)并不便宜.这是构建过程中的另一个步骤,必须进行维护和检查,因此必须有一些好处.
一个大型应用程序将始终加载一些DLL,其中基地址不匹配,因为一些钩子DLL(AV)和因为你没有rebase第三方DLL(或至少我不会).
如果您使用RAM磁盘作为分页文件,如果加载的DLL被分页,您实际上可能会更好:-)
总而言之,我认为除了像系统DLL这样的特殊情况之外,重新定位不值得.
我想添加一个我在Old New Thing上发现的历史片段:Windows 95如何修改DLL?-
当需要重新定义DLL时,Windows 95只会记录DLL的新基址,但不会做太多其他事情.真正的工作发生在DLL的页面最终被交换时.原始页面被交换掉磁盘,然后修复程序被动态应用到原始页面,从而重新定位它.然后将修复后的页面映射到进程的地址空间,并允许程序继续.
看看这个过程是如何完成的(阅读整篇文章),我个人怀疑"变形是邪恶的"部分可以追溯到Win9x和低内存条件的旧时代.
看,现在Old Old Thing上有一件非历史作品:
现在确保我的所有DLL都具有非冲突的基址是多么重要?
回到白天,你被告知要做的事情之一是重新绑定你的DLL,以便它们都具有非重叠的地址范围,从而避免了运行时重定位的成本.这现在仍然很重要吗?
...
在存在ASLR的情况下,重新定义DLL无效,因为ASLR 无论如何都会忽略您的基址,并将DLL重定位到其伪随机选择的位置.
...
结论:为了以防万一,它不会因为退货而受到损害,但要明白,这种回报将极为罕见.使用已
/DYNAMICBASE启用(并且有/HIGHENTROPYVA良好的措施)构建您的DLL, 并让ASLR完成确保不发生基址冲突的工作.这将涵盖几乎所有的现实场景.如果您碰巧遇到ASLR不可用的极少数情况之一,那么您的程序仍然有效.由于搬迁罚款,它可能会运行一点慢.... ASLR实际上比避免手动变基更能避免冲突,因为ASLR可以将系统视为一个整体,而手动变基需要您知道加载到流程中的所有DLL,并协调多个供应商的基地址通常是不可能的.
| 归档时间: |
|
| 查看次数: |
4407 次 |
| 最近记录: |