Windows DLL搜索顺序
2015-11-28 15:14
447 查看
原文:http://m.blog.csdn.net/blog/SR0ad/8180019
Windows程序直接或间接通过LoadLibrary/LoadLibraryEx加载一个DLL时,Windows会按照一定的顺序去系统中搜索指定的DLL,这个顺序称之为DLL搜索顺序。
下面举例A.exe调用B.dll的情况:
一、系统环境影响
1.如果在LoadLibrary/LoadLibraryEx调用时B.dll被指定了路径而该路径下并不存在B.dll,LoadLibrary/LoadLibraryEx会直接失败。
2.如果B.dll这个模块已经存在于内存中,系统只作manifest检查和redirection检查,而不管指定的B.dll路径是否与内存中的B.dll一致,并且系统不会再试图搜索B.dll。
3.KnownDlls,注册表中的HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs 登记了所谓KnownDlls的名称和它们的路径。如果B.dll存在于该键下,系统会加载该注册表项指定路径的B.dll,而不管它在LoadLibrary/LoadLiraryEx被指定的路径。
4.如果被加载的B.dll依赖于其他的DLL,这些被依赖的DLL会按照B.dll没有指定路径时的相同方式加载。(假如B.dll依赖于它相同目录下的DepDll.dll,搜索DepDll.dll时并不会从B.dll所在目录开始)
二、标准的DLL搜索顺序
不附加任何其他条件时,标准的DLL搜索顺序如下:
1.应用程序的加载目录:D:\SR0ad
2.当前目录(默认为程序加载目录,可以通过SetCurrentDirectory修改,通过GetCurrentDirectory获取)
3.系统目录(32位系统下通常是,C:\Windows\System32,可以通过GetSystemDirectory获取)
4.16位系统目录(忽略)
5.Windows目录(通常是,C:\Windows,可以通过GetWindowsDirectory获取)
6.PATH环境变量中列出的所有路径
三、DLL重定向
DLL重定向用来解决系统中存在并且同时需要同一个DLL的多个版本的问题。当系统中已经存在B.dll,而A需要自己的B.dll时,就要用到DLL重定向。
在应用程序安装目录下建立应用程序名+.local后缀的重定向文件D:\SR0ad\A.exe.local,B.dll必须安装在D:\SR0ad\目录下。
不管重定向文件A.exe.local的内容如何,使用LoadLibrary/LoadLibraryEx加载B.dll时,只要D:\SR0ad\B.dll存在,系统都会加载D:\SR0ad\B.dll,而不管LoadLibrary/LoadLibraryEx是否为它指定全路径。
如果A.exe.local是个目录,并且D:\SR0ad\A.exe.local\B.dll存在,系统则会加载D:\SR0ad\A.exe.local\B.dll,同样不管为LoadLibrary/LoadLibraryEx是否为它指定全路径。
PS:DLL重定向有两个例外,KnownDLLs不能被重定向;如果应用程序存在manifest,.local文件会被忽略。
参考文章:Dynamic-Link Library Search Order,http://msdn.microsoft.com/en-us/library/ms682586%28VS.85%29.aspx
下面通过一个例子,来测试一下Win7下,具体的搜索路径是什么。
分别在一下路径放了生成的dll文件,之后运行exe,显示那个dll路径,删除掉继续运行,直至找不到dll文件为止。
至此也算是验证了搜索路径,至于安全搜索模式,就当忽略吧。
更多参考:http://blog.csdn.net/magictong/article/details/6931520
海风月影:神奇的马甲dll
Windows程序直接或间接通过LoadLibrary/LoadLibraryEx加载一个DLL时,Windows会按照一定的顺序去系统中搜索指定的DLL,这个顺序称之为DLL搜索顺序。
下面举例A.exe调用B.dll的情况:
一、系统环境影响
1.如果在LoadLibrary/LoadLibraryEx调用时B.dll被指定了路径而该路径下并不存在B.dll,LoadLibrary/LoadLibraryEx会直接失败。
2.如果B.dll这个模块已经存在于内存中,系统只作manifest检查和redirection检查,而不管指定的B.dll路径是否与内存中的B.dll一致,并且系统不会再试图搜索B.dll。
3.KnownDlls,注册表中的HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs 登记了所谓KnownDlls的名称和它们的路径。如果B.dll存在于该键下,系统会加载该注册表项指定路径的B.dll,而不管它在LoadLibrary/LoadLiraryEx被指定的路径。
4.如果被加载的B.dll依赖于其他的DLL,这些被依赖的DLL会按照B.dll没有指定路径时的相同方式加载。(假如B.dll依赖于它相同目录下的DepDll.dll,搜索DepDll.dll时并不会从B.dll所在目录开始)
二、标准的DLL搜索顺序
不附加任何其他条件时,标准的DLL搜索顺序如下:
1.应用程序的加载目录:D:\SR0ad
2.当前目录(默认为程序加载目录,可以通过SetCurrentDirectory修改,通过GetCurrentDirectory获取)
3.系统目录(32位系统下通常是,C:\Windows\System32,可以通过GetSystemDirectory获取)
4.16位系统目录(忽略)
5.Windows目录(通常是,C:\Windows,可以通过GetWindowsDirectory获取)
6.PATH环境变量中列出的所有路径
三、DLL重定向
DLL重定向用来解决系统中存在并且同时需要同一个DLL的多个版本的问题。当系统中已经存在B.dll,而A需要自己的B.dll时,就要用到DLL重定向。
在应用程序安装目录下建立应用程序名+.local后缀的重定向文件D:\SR0ad\A.exe.local,B.dll必须安装在D:\SR0ad\目录下。
不管重定向文件A.exe.local的内容如何,使用LoadLibrary/LoadLibraryEx加载B.dll时,只要D:\SR0ad\B.dll存在,系统都会加载D:\SR0ad\B.dll,而不管LoadLibrary/LoadLibraryEx是否为它指定全路径。
如果A.exe.local是个目录,并且D:\SR0ad\A.exe.local\B.dll存在,系统则会加载D:\SR0ad\A.exe.local\B.dll,同样不管为LoadLibrary/LoadLibraryEx是否为它指定全路径。
PS:DLL重定向有两个例外,KnownDLLs不能被重定向;如果应用程序存在manifest,.local文件会被忽略。
参考文章:Dynamic-Link Library Search Order,http://msdn.microsoft.com/en-us/library/ms682586%28VS.85%29.aspx
下面通过一个例子,来测试一下Win7下,具体的搜索路径是什么。
#include <Windows.h> #include <iostream> using namespace std; BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch(ul_reason_for_call) { case DLL_PROCESS_ATTACH: char szDllPath[MAX_PATH] = {0}; GetModuleFileNameA(hModule, szDllPath, MAX_PATH); cout<<"DLL PATH:"<<szDllPath<<endl; break; } return TRUE; }dll会获得自身的路径并输出,然后将dll放在各各路径,之后运行exe,通过LoadLibrary("SR0adDLL.dll");加载便可看到dll处于什么路径下。
#include <Windows.h> #include <iostream> using namespace std; int main() { HMODULE hDll = LoadLibrary("SR0adDLL.dll"); if (!hDll) { cout<<"SR0adDLL.dll Load Error\n"<<endl; } return 0; }
分别在一下路径放了生成的dll文件,之后运行exe,显示那个dll路径,删除掉继续运行,直至找不到dll文件为止。
至此也算是验证了搜索路径,至于安全搜索模式,就当忽略吧。
更多参考:http://blog.csdn.net/magictong/article/details/6931520
海风月影:神奇的马甲dll
相关文章推荐
- 如何重装TCP/IP协议
- Windows 8 官方高清壁纸欣赏与下载
- 谁是桌面王者?Win PK Linux三大镇山之宝
- 对《大家都在点赞 Windows Terminal,我决定给你泼一盆冷水》一文的商榷
- Windows Clang开发环境备忘
- 从Windows系统下访问Linux分区相关软件
- 对《大家都在点赞 Windows Terminal,我决定给你泼一盆冷水》一文的商榷
- Windows下搭建本地SVN服务器
- Visual Studio 2012 示例代码浏览器 - 数以千计的开发示例近在手边,唾手可得
- Visual Studio 2012 示例代码浏览器 - 数以千计的开发示例近在手边,唾手可得
- 微软镜像下载
- windows server域用户提升到本地更高权限组中的方法
- 使用命令修改注册表键值及权限
- 通过手机、电脑远程开关机,Windows和linux机手机,电脑相互控制
- Windows XP最新应用技巧大荟萃
- Windows 系统组策略应用全攻略(上)第1/2页
- VBS脚本写的Windows硬件检测工具分享
- Microsoft Windows Vista 简体中文企业版 MVL DVD IMG 32-bit(1.9GB)