确定DLL的加载路径 [英] Determine the loaded path for DLLs

查看:126
本文介绍了确定DLL的加载路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望我的申请符合以下结构。

  Exe 
|
| ----- DLL\DLL.dll,DLL\common.dll
|
| ----- DLL2\DLL2.dll,DLL2\common.dll

我的EXE将加载DLL通过

  LoadLibraryEx(_T(DLL\\DLL.dll),0 ,0); 
LoadLibraryEx(_T(DLL2\\DLL2.dll),0,0);

DLL.dll DLL2.dll 项目将通过lib文件链接到 common.dll 。但是,在执行过程中,将会有两个不同版本的 common.dll



< > Exe
希望我将 common.dll 放在与 Exe 相同的目录,目录为 DLL DLL2 。有什么办法,我可以解决这个,通过能够有上述目录结构。但是,仍然使用lib链接 DLL / DLL2 common

/ strong>



这对我来说是个坏主意。是真的有必要吗?


  • 确保加载的DLL可以找到不在搜索路径中的其他DLL。



    (如果你没有动态加载DLL.dll和DLL2.dll然后我不知道会是什么幸运的是,我看到你是:))



    如果您动态加载DLL.dll和DLL2.dll(即在运行时使用LoadLibrary,而不是在构建时链接到它们的.lib文件)可以事先调用 SetDllDirectory 以显式添加DLL或DLL2目录到搜索路径。



    请注意,这是一个很好的做法,除非它打破了一个糟糕的在程序开始时调用SetDllDirectory(),从DLL搜索路径中删除当前工作目录(不是程序的目录,不要担心)。这减轻了安全问题,其中您的代码可能被欺骗加载DLL。但是请注意,如果您通过调用SetDllDirectory(NULL)重置搜索路径,那么您需要再次调用SetDllDirectory()。


  • 所以你会有这样的代码:

      SetDllDirectory // 重启。 
    SetDllDirectory(); //插入二进制种植安全漏洞。 `
    SetDllDirectory(C:\MyExePath\DLL);
    LoadLibrary(C:\MyExePath\DLL\DLL.dll);

    SetDllDirectory(NULL); // 重启。
    SetDllDirectory(); //插入二进制种植安全漏洞。
    SetDllDirectory(C:\MyExePath\DLL2);
    LoadLibrary(C:\MyExePath\DLL2\DLL2.dll);

    SetDllDirectory(NULL); // 重启。
    SetDllDirectory(); //插入二进制种植安全漏洞。

    (未经测试,对任何错误或缺少参数抱歉, / p>

    (你应该在运行时计算C:\MyExePath,硬编码很明显。)



    (我假设DLL.dll和DLL2.dll隐藏加载它们的common.dll如果他们通过LoadLibrary调用加载common.dll,问题更容易:只是让他们计算自己的路径,然后通过LoadLibrary是common.dll的完整路径。)



    注意:SetDllDirectory会影响整个过程。如果你的进程有多个线程,你应该确保SetDllDirectory调用彼此隔离以及任何可能触发LoadLibrary调用的事情。例如在启动时加载库,如果可能,生成任何其他线程。


    I wish to have my application in the following structure.

    Exe
     |
     |----- DLL\DLL.dll, DLL\common.dll 
     |
     |----- DLL2\DLL2.dll, DLL2\common.dll
    

    My EXE will load the DLLs through

    LoadLibraryEx(_T("DLL\\DLL.dll"), 0, 0);
    LoadLibraryEx(_T("DLL2\\DLL2.dll"), 0, 0);
    

    DLL.dll and DLL2.dll project will link against common.dll through lib file. There will be 2 different versions of common.dll though.

    However, during execution, Exe expected me to place common.dll same directory as Exe, but not same directory as DLL and DLL2. Is there any way I can resolve this, by able to have the above directory structure. Yet, still use lib to link against DLL/DLL2 with common.

    解决方案

    1. You want to load two different DLLs with the same name (common.dll) into the same process.

      That seems like a bad idea to me. Is it really necessary? Could one of them be renamed?

    2. Ensuring the DLLs you load can find other DLLs which aren't in the search path.

      (If you were not dynamically loading DLL.dll and DLL2.dll then I'm not sure what the would be. Luckily, I see you are. :))

      If you are dynamically loading DLL.dll and DLL2.dll (that is, using LoadLibrary at runtime instead of linking to their .lib files at build time), then you can call SetDllDirectory beforehand to explicitly add the DLL or DLL2 directories to the search path. You would want to only have one directory in the path at once to ensure the right common.dll was loaded.

      Note that it is good practice, unless it breaks a poorly-written component, to call SetDllDirectory("") at the start of your program to remove the current-working-directory (not the program's directory, don't worry) from the DLL search path. This mitigates security issues where your code can be tricked into loading DLLs. But also note that if you reset the search path by calling SetDllDirectory(NULL) then you need to call SetDllDirectory("") again afterwards.

    So you'd have code like this:

    SetDllDirectory(NULL); // Reset.
    SetDllDirectory(""); // Plug "binary planting" security hole. `
    SetDllDirectory("C:\MyExePath\DLL");
    LoadLibrary("C:\MyExePath\DLL\DLL.dll");
    
    SetDllDirectory(NULL); // Reset.
    SetDllDirectory(""); // Plug "binary planting" security hole.
    SetDllDirectory("C:\MyExePath\DLL2");
    LoadLibrary("C:\MyExePath\DLL2\DLL2.dll");
    
    SetDllDirectory(NULL); // Reset.
    SetDllDirectory(""); // Plug "binary planting" security hole.
    

    (Untested so apologies for any mistakes or missing arguments. Should give you the idea, though.)

    (You should calculate the C:\MyExePath at runtime. Hard-coding it would be bad, obviously.)

    (I am assuming that DLL.dll and DLL2.dll load their common.dll implicitly. If they are loading common.dll via a LoadLibrary call then the problem is even easier: Just make them calculate their own paths and then pass LoadLibrary the full path to common.dll.)

    Beware: SetDllDirectory affects your entire process. If your process has multiple threads you should ensure the SetDllDirectory calls are isolated from each other as well as anything else that may trigger a LoadLibrary call. e.g. Load the libraries at startup before you spawn any other thread, if possible.

    这篇关于确定DLL的加载路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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