是rebase DLL(或提供适当的默认加载地址)值得吗? [英] Is rebasing DLLs (or providing an appropriate default load address) worth the trouble?

查看:242
本文介绍了是rebase DLL(或提供适当的默认加载地址)值得吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



重新绑定DLL意味着修复DLL,这是首选的加载地址是Loader实际上可以加载DLL的加载地址。这可以通过诸如 Rebase.exe 的工具来实现,也可以通过为所有(自己的)dll指定默认加载地址,以便它们适合在可执行过程中。



以这种方式管理DLL基址的全部要点是加快应用程序负载。 (或者我明白了。)



问题现在是:难道值得吗? >

我有书籍 Windows通过C / C ++ 由Richter /他们强烈建议 [a] 确保加载地址都匹配,以便加载程序不必重新加载加载的DLL。



然而,他们没有争论,如果这样可以将应用程序加载时间加快到任何显着的量。



另外,使用ASLR 似乎有可能这是有任何价值,因为加载地址将被随机化。



是否有任何困难的事实在这个的pro / cons?



[a]:在我的WvC ++ / 5th ed在第568ff页的标题为 Rebasing Modules Binding Modules 的部分。在第20章,高级技巧。

解决方案

一个答案我自己,虽然 Hans Passant的答案和其他人正在描述的权衡已经很好了。



最近在我们的应用程序中使用DLL的基础地址,我将这里给出我的结论:



我认为,除非你可以证明,否则为DLL提供非默认的基地址是徒劳的练习。这包括重新编译我的DLL。




  • 对于我控制的DLL ,给定平均应用程序DLL只会一次加载到内存中,因此页面文件上的加载应该是最小的。 (但是请参阅Michal Burr在终端服务器环境的另一个答案中的评论。)


  • 如果DLL提供了固定的基址(没有重新定位)实际上增加了地址空间的碎片,迟早这些地址将不再匹配了。在我们的应用程序中,我们已经为所有DLL提供了一个固定的基地址(由于其他遗留原因而不是因为地址空间碎片),而不使用rebase.exe,而这个显着地增加了我们的地址空间碎片,因为你真的手动无法获取此权限。


  • Rebasing(通过rebase.exe)不便宜。这是构建过程中的另一个步骤,必须进行维护和检查,所以它必须有一些好处。


  • 大型应用程序将始终有一些DLL加载基地址不匹配,因为一些钩子DLL(AV),因为你不rebase第三方DLL(或至少我不会)。


  • 如果您使用RAM磁盘进行分页文件,如果加载的DLL被调出,你可能会更好: - )




所以总而言之,我认为,除了特殊情况(如系统DLL),rebase 不值得麻烦






我想添加一个我在旧新事物中发现的历史作品: Windows 95 rebase DLL如何? -


当需要重新启动DLL时,Windows 95只会在DLL的新基址中记下
,但不会做太多其他事情。真正的
工作发生在DLL的页面最终被交换时,
原始页面已经被转换到磁盘上,然后修复程序被应用到
上飞到原始页面,从而重新定位。固定页面是
,然后映射到进程的地址空间,并允许程序
继续。


查看此过程的完成情况(阅读整个事情),我个人怀疑重新定位是邪恶的一部分立场可以追溯到Win9x的旧时代,记忆力低下。






看,现在有一个旧的新事物上的非历史片段


现在确保我所有的DLL都具有非冲突的重要性基地址?



当天回来,您所劝告的其中一件事就是将您的DLL更新为
,以使它们都具有不重叠的地址范围,从而
避免运行时relo的成本阳离子。现在这还是重要的
吗?



...



在ASLR的存在下,您的DLL无效,因为ASLR将忽略您的基地址/ / em>,并将DLL重定位到其伪随机选择的位置。



...



结论:它不会伤害rebase,以防万一,但了解
表示的收益将非常罕见。使用
/ DYNAMICBASE 启用(并以 / HIGHENTROPYVA 为好的措施)构建您的DLL
并让ASLR进行确保不发生基地址冲突
的工作。这将涵盖几乎所有的真实世界的场景。
如果碰巧属于ASLR
不可用的极少数情况之一,那么您的程序仍然可以工作。由于重新定位罚款,它可能会运行一个



... ASLR实际上做的更好,避免碰撞比手动
由于ASLR可以查看整个系统,因此手动
重新版本需要您了解所有加载到
进程中的DLL,并且跨多个供应商协调基地址是
一般不可能。



Rebasing a DLL means to fix up the DLL such, that it's preferred load adress is the load address that the Loader is actually able to load the DLL at.

This can either be achieved by a tool such as Rebase.exe or by specifying default load addresses for all your (own) dlls so that they "fit" in your executable process.

The whole point of managing the DLL base addresses this way is to speed up application loads. (Or so I understand.)

The question is now: Is it worth the trouble?

I have the book Windows via C/C++ by Richter/Nazarre and they strongly recommend[a] making sure that the load addresses all match up so that the Loader doesn't have to rebase the loaded DLLs.

They fail to argue however, if this speeds up application load times to any significant amount.

Also, with ASLR it seems dubious that this has any value at all, since the load addresses will be randomized anyway.

Are there any hard facts on the pro/cons of this?

[a]: In my WvC++/5th ed it is in the sections titled Rebasing Modules and Binding Modules on pages 568ff. in Chapter 20, DLL Advanced Techniques.

解决方案

I'd like to provide one answer myself, although the answers of Hans Passant and others are describing the tradeoffs already pretty well.

After recently fiddling with DLL base adresses in our application, I will here give my conclusion:

I think that, unless you can prove otherwise, providing DLLs with a non-default Base Address is an exercise in futility. This includes rebasing my DLLs.

  • For the DLLs I control, given the average application, each DLL will be loaded into memory only once anyway, so the load on the paging file should be minimal. (But see the comment of Michal Burr in another answer about Terminal Server environment.)

  • If DLLs are provided with a fixed base address (without rebasing) it will actually increase address space fragmentation, as sooner or later these addresses won't match anymore. In our app we had given all DLLs a fixed base address (for other legacy reasons, and not because of address space fragmentation) without using rebase.exe and this significantly increased address space fragmentation for us because you really can't get this right manually.

  • Rebasing (via rebase.exe) is not cheap. It is another step in the build process that has to be maintained and checked, so it has to have some benefit.

  • A large application will always have some DLLs loaded where the base address does not match, because of some hook DLLs (AV) and because you don't rebase 3rd party DLLs (or at least I wouldn't).

  • If you're using a RAM disk for the paging file, you might actually be better of if loaded DLLs get paged out :-)

So to sum up, I think that rebasing isn't worth the trouble except for special cases like the system DLLs.


I'd like to add a historical piece that I found on Old New Thing: How did Windows 95 rebase DLLs? --

When a DLL needed to be rebased, Windows 95 would merely make a note of the DLL's new base address, but wouldn't do much else. The real work happened when the pages of the DLL ultimately got swapped in. The raw page was swapped off the disk, then the fix-ups were applied on the fly to the raw page, thereby relocating it. The fixed-up page was then mapped into the process's address space and the program was allowed to continue.

Looking at how this process is done (read the whole thing), I personally suspect that part of the "rebasing is evil" stance dates back to the olden days of Win9x and low memory conditions.


Look, now there's a non-historical piece on Old New Thing:

How important is it nowadays to ensure that all my DLLs have non-conflicting base addresses?

Back in the day, one of the things you were exhorted to do was rebase your DLLs so that they all had nonoverlapping address ranges, thereby avoiding the cost of runtime relocation. Is this still important nowadays?

...

In the presence of ASLR, rebasing your DLLs has no effect because ASLR is going to ignore your base address anyway and relocate the DLL into a location of its pseudo-random choosing.

...

Conclusion: It doesn't hurt to rebase, just in case, but understand that the payoff will be extremely rare. Build your DLL with /DYNAMICBASE enabled (and with /HIGHENTROPYVA for good measure) and let ASLR do the work of ensuring that no base address collision occurs. That will cover pretty much all of the real-world scenarios. If you happen to fall into one of the very rare cases where ASLR is not available, then your program will still work. It just may run a little slower due to the relocation penalty.

... ASLR actually does a better job of avoiding collisions than manual rebasing, since ASLR can view the system as a whole, whereas manual rebasing requires you to know all the DLLs that are loaded into your process, and coordinating base addresses across multiple vendors is generally not possible.

这篇关于是rebase DLL(或提供适当的默认加载地址)值得吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆