windows核心编程(第五版)的20.6节介绍了Dll重定向。

0x01  Dll重定向简介

  产生Dll重定向原因: 

    应用程序 a.exe 依赖动态链接库 compoent.dll 1.0 版本。但是用户的另一个软件 b 在系统的系统目录安装了 component.dll 2.0 版本,这两个版本不兼容

  因此,Windows 在加载 component.dll 的时候,会直接加载系统目录中的 component.dll,这就造成了 a.exe 程序无法运行,如果这时用户需要同时使用两个软件,就会造成所谓的 DLL Hell。

  

  动态链接库重定向技术如何解决 DLL Hell:

    这里有两种方法可以作为解决方案:

    1.创建 a.exe.local 文件,该文件内容为空。

      这时系统就会强制使 a.exe LoadLibrary 时先在 a.exe 所在的目录下查找要加载的动态库,之后才到系统目录下寻找。这个解决方法适用于两个不同的应用。

    2.创建 a.exe.local 目录,将 a.exe 依赖的库放入其中。

      这时系统就会强制使 a.exe LoadLibrary 时先在 a.exe.local 目录下查找要加载的动态库,之后才到系统目录下寻找。这个解决方法适用于单个应用中存在两个应用程序,并且以来同名但是互不兼容的库。

  动态链接库重定向技术实际上是 M$ 修改了 LoadLibrary(Ex) 的代码,使其在调用时先检测是否存在 <AppName>.local 文件或目录实现重定向的。它是作为临时解决 DLL HELL 的方法。并且,当应用程序存在 Manifest 时,该技术将不会起作用。

0x01  Dll重定向实现步骤:  

   (假设我的EXE为SHApp.exe, 要调试的DLL为 SHModule.dll):

  1) 在 SHApp.exe 的目录下创建一个 SHApp.exe.local

  2) 把你希望加载的 SHModule.dll 复制到 SHApp.exe.local 目录下

  3) 运行 SHApp.exe

  

#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>

int main()
{
	CHAR szMoudlePath[MAX_PATH];
	LPSTR szKernel32 = "kernel32.dll";
	LPSTR szuser32 = "user32.dll";
	HMODULE hKernel32;


	//使用NULL参数,获取本模块路径
	if (!GetModuleFileNameA(NULL, szMoudlePath, MAX_PATH))
		{return 0;}
	printf("本模块路径 %s 

", szMoudlePath);

	hKernel32 = LoadLibraryA(szKernel32);
	//使用Kernel32.dll的句柄模块,获取其路径
	if (!GetModuleFileNameA(hKernel32, szMoudlePath, MAX_PATH))
		{return 0;}
	printf("kernel32模块路径 %s 
", szMoudlePath);


	return 0;
}

  

  按照这位博主的说法(http://blog.csdn.net/zacklin/article/details/7535569),要打开.local这个功能,需要在注册表设置DevOverrideEnable值,并且重启机器

  [HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Image File Execution Options]

  ”DevOverrideEnable”=dword:00000001

  然而,在笔者win10的注册表上,并没有找到这个键值:

  Dll重定向(尚存否?)-风君雪科技博客

   所以笔者猜测win10下的此技术可能得到了改进?又或者是我个人的原因?各位看官路过如若知晓的话,还望不吝赐教,感激不尽~