浅谈 DLL 导出函数中的转发器函数

浅谈 DLL 导出函数中的转发器函数

作者:BlogUpdater |  时间:2023-09-14 |  浏览:382 |  评论已关闭 条评论

在之前的一篇文章中,我们了解到 32 位 DLL 的函数导出方式和 16 位是类似的,只是 32 位 DLL 更倾向于使用基于名称的导出,而不是基于函数序号的导出。

这种倾向性不会在文件格式中表达出来: 16 位和 32 位 DLL 都可以按名称或序号(或两者)导出,但 Win32 的设计者在设计理念上更偏向于仅使用名称导出。

但是 Win32 中有一种新型的导出函数,我们叫它们转发器。
转发器看起来就像常规导出函数一样,只是在序号导出表中的条目,它预示着:这个函数并不是这个 DLL 中的一个真正函数,而是指向了另外一个 DLL 中的实际函数。

举个例子
如果你做一个链接 /dump /exports kernel32.dll,你会看到这样的一行:

151 EnterCriticalSection (forwarded to NTDLL.RtlEnterCriticalSection)

这意味着,如果程序链接了 KERNEL32.EnterCriticalSection 这个函数,则加载器将悄无声息地重定向到 NTDLL.RtlEnterCriticalSection。

转发器是适应从一个 DLL 移动到另一个 DLL 的功能的便捷方法。旧 DLL 可以继续导出函数,但将其转发到新 DLL。

转发技巧实际上比在旧 DLL 中仅使用一个在新 DLL 中调用该函数的存根函数(stub function)要好,因为存根函数会在旧 DLL 和新 DLL 之间创建依赖关系。(毕竟,旧的DLL需要链接到新的DLL才能调用它!

但是,对于转发器,除非有人实际从旧 DLL 请求转发的函数,否则不会加载新的 DLL。因此,在有人真正想要它之前,你无需加载新的 DLL。

好的,今天关于转发器的主题就介绍到这里,关于导出,Win32 已经与 16 位 Windows 有所不同了,但在导入方面,这将是一个全新的”游戏”。
我们下次继续。

总结

如果你是在 32 位 Windows 平台上做开发,则始终使用名称,而不是序号进行 DLL 调用,这样会免去很多麻烦。
毕竟,写入到 SDK 中的名称,不太可能随随便便的改变。

最后

Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《Exported functions that are really forwarders》

最近我写了个东西

正如你们所知道的,拓扑梅尔智慧办公平台(Topomel Box)是一款绿色软件,主要面向经常使用电脑的朋友。它提供了各种提升办公效率的小功能,同时操作上尽可能地简单方便。
我想:你值得拥有。

评论已关闭。