首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SetDllDirectory不级联,因此不能加载依赖项DLL。

SetDllDirectory不级联,因此不能加载依赖项DLL。
EN

Stack Overflow用户
提问于 2017-06-16 11:52:50
回答 1查看 2.1K关注 0票数 2

我从一个目录执行一个exe,例如"C:/test“

DLLs位于目录"C:/test/dlls“中,因此,在这个exe中,我调用:

代码语言:javascript
复制
SetDllDirectory("C:/test/dlls");

然后我打电话

代码语言:javascript
复制
lib1 = LoadLibrary("lib1.dll)

代码语言:javascript
复制
ptrType pr = (ptrType) ::GetProcAddress(lib1, "test")

lib1.dll需要目录"C:/test/ DLLs“中的其他dlls,但是当我执行来自GetProcAddresspr(...) get时,会得到一个错误:

“程序无法启动,因为您的计算机中缺少lib2.dll。请尝试重新安装该程序以解决此问题。”

如果我将lib2.dll移动到"C:/test",就会找到它。这意味着SetDllDirectory()仅对加载第一个DLL有效。

有谁知道为什么和如何修复它吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-06-16 12:13:45

这应该能行。SetDllDirectory会“级联”,因此会影响加载依赖DLL的方式。基本上,SetDllDirectory允许您修改进程的DLL的默认搜索顺序,对此所做的任何更改都会影响整个进程,包括可能加载到该进程中的任何DLL。Windows在隐式加载子进程的依赖项时也使用此搜索顺序。

然而,正如在SetDllDirectory中所指出的,文献资料中有一个致命的缺陷

每次调用SetDllDirectory函数时,它都会替换上一次SetDllDirectory调用中指定的目录。

如果您的流程中有其他代码正在调用SetDllDirectory,那么它将取消您的第一个调用。如果是lib1.dll中的代码在尝试加载lib2.dll之前做到了这一点,那么加载lib2.dll的尝试就会失败。

当然,这是lib1.dll的不良行为。DLLs是客人在申请过程中,因此不应去换地毯。。但并不是所有的代码都表现良好,这使得这是一个脆弱的策略。

另一种可能出错的方法是,如果lib1.dll通过调用LoadLibraryEx并传递覆盖默认搜索顺序(如LOAD_LIBRARY_SEARCH_APPLICATION_DIR )的多个标志之一加载lib2.dll。

最好的解决方案是将您所依赖的所有all放在应用程序目录中。在Windows上,应用程序的目录是应用程序包,所以这是放置它们的最佳地方。用户永远不应该在这个目录中挖掘,所以“乱七八糟”并不是一个问题。它解决了各种问题,包括依赖注入攻击,即有人在当前目录中放置同名的DLL。(您可以通过调用SetDllDirectory并传递一个空字符串从搜索顺序中删除当前目录来防止这种攻击,但现在我们又回到了问题1。如果您家里有客人正在修改DLL搜索顺序,这不是安全问题的可靠解决方法。如果将DLL放在应用程序目录中,将首先找到它们,然后搜索当前目录,在攻击矢量被攻击之前关闭它。)

如果您确实有一个很好的理由将DLL放在不同的目录中,那么您就有了有限的选项。

您不能像上面引用的文档所建议的那样使用AddDllDirectory,因为您不能控制lib1.dll中的代码,因此不能修改它以使用LOAD_LIBRARY_SEARCH_USER_DIRS标志调用LoadLibraryEx

通过指定完整路径来加载lib1.dll是行不通的,因为“如果DLL有依赖项,系统就会搜索依赖DLL,就好像它们只是加载了它们的模块名一样。即使第一个DLL是通过指定完整路径加载的,也是如此。”

这给您留下了使用DLL重定向的选项,或者在应用程序的清单中添加有关依赖关系的信息。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44588618

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档