20.4 函数转发器
(1)函数转发器原理(下图是利用Dependency Walker打开Kernel32.dll得到)
①图中CloseThreadpool*等4个函数转发到NTDLL中相应的函数中去了,但我们调用CloseThreadpool*等函数时,exe会被动态地链接到Kernel32.dll。当执行exe时,加载程序会发现被转发的函数实际上在NTDLL.dll中,然后它会将NTDLL.dll模块一并载入。
②当我们调用CloseThreadpool*函数时,那么调用GetProcAddress先在Kernel32的导出段是查找,并发现CloseThreadpool*是一个转发器函数,于是它会递归调用GetProcessAddress,在NTDLL 的导出段中查找相应的函数。
(2)实现自己的函数转发器
#pragma comment(linker,"/export:MyFunc =OtherDll.OtherFunc")
//即正在编译的Dll输出一个名为MyFunc的函数,但实际上这个函数在另一个叫OtherDll.dll模块中,函数名为OtherFunc.
20.5 己知的DLL
(1)操作系统对某些DLL进行了特殊处理,这些Dll被称为己知的Dll。在载入它们的时候,总是从"%SystemRoot%\System32"目录下查找。这些Dll被记录在注册表中如下的位置
(2)当LoadLibrary(TEXT("A_Dll"))时,系统会用正常的搜索规则来定位这个Dll。但如果调用LoadLibrary(TEXT("A_Dll.dll"))时,系统会先将扩展名.dll去掉,然后在注册表查找名称为"A_Dll"的一项,并将载入该项后面“数据”项里指向的Dll(注意,这个Dll会在"%SystemRoot%\System32"目录里查找),如果载入不成功,会返回NULL,GetLastError将返回(ERROR_FILE_NOT_FOUND).
20.6 DLL重定向
(1)早期Windows为了文件共享,将多个应用程序共享的所有模块都放在Windows系统目录中,但会出现一个严重问题,因为安装程序会用老版本的文件覆盖这个目录中的文件,从而妨碍其他应用程序的正常运行。
(2)从Windows2000开始,新增了DLL重定向特性,使得应用程序首先从应用程序的目录中载入模块,只有当加载程序无法找到这个文件时,才会在其他目录中搜索。
(3)为了强制加载程序先检查应用程序的目录,可以在应用程序目录中,建一个文件名为AppName.local的文件(此处的AppName如MyApp.exe),内容无关紧要。
(4)LoadLibrary(Ex)在内部做了修改,来检查这个文件是否存在,如果应用程序目录中存在这个文件,便载入这个目录中的模块。如果不存在该.local文件,则工作方式与以往相同。
(5)由于安全性缘故,该特性默认是关闭的,因为它会使系统从应用程序的文件夹中载为伪造的系统DLL,而不是从Windows的系统文件夹中载入真正的系统DLL。为打开这个特性,可以HKLM\Software\Microsoft\WindowsNT\CurrentVesion\Image File Execution Options注册表项中增一个项名为DevOverrideEnable的DWORD型项,并将值设为1。
原文:http://www.cnblogs.com/5iedu/p/5065184.html