__declspec(dllimport) 实际上是如何工作的?

4

我试图理解动态链接是如何工作的,我已经理解了大部分,但现在编译器或链接器如何知道我要从哪个dll导入呢?

例如,我有一个名为test_program.dll的文件,它导出了一个名为test();的函数,我在我的程序中使用__declspec(dllimport)来引入该函数。在我的系统中可能有成千上万个具有相同名称并且还被导出的函数,编译器是如何区分它们的呢?


虽然有各种保护措施,但我认为简短的答案是它不会。你需要提供正确的 DLL。事实上,一些黑客使用称为 DLL 注入的技术来替换受黑客控制的正确 DLL 为另一个 DLL,从而实现一些黑客攻击。 - john
@john 那你会如何精确地指定它呢?我看到每个人都只是使用 __declspec(dllimport),然后就可以了。虽然它能够工作,但我不明白它的原理是什么? - zeroaceee
2个回答

3
当你在代码中使用test()时,生成的对象文件会被标记为需要test符号。
然后,将你的dll的.lib文件提供给链接器,该库文件包含test符号和加载你的dll所需的代码,其中包括dll的名称。
你可以提供另一个.lib文件,它也包含test符号,这将加载不同的dll。

1
你能够最接近测试你加载的库是否是你所期望的,需要对可执行文件和DLL进行加密签名。
你需要对可执行文件进行签名以确保其未被篡改,你需要对库进行签名以确保你找到的是你创建的那个库。
如果你需要达到这种程度的偏执狂,你可能不会使用__declspec(dllimport),而是会定位DLL,测试其加密签名,然后运行时加载它(LoadLibrary/GetProcAddress)。
我想你可以使用带有延迟加载的__declspec(dllimport),只要你提供一个自定义的延迟加载器助手,但你需要一些方法告诉该助手哪些文件需要额外处理(仅检查签名是不够的,因为攻击者可以提供用其他证书签名的DLL,你需要确保相关的库是用你的证书签名的)。

我认为你可以使用dll清单和#pragma comment(linker...)来自动化地设置依赖关系,以实现这一点。 - Alan Birtles

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接