ImageVerifierCode 换一换
格式:DOCX , 页数:11 ,大小:257.67KB ,
资源ID:8153067      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/8153067.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Windows下DLL查找顺序160614.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Windows下DLL查找顺序160614.docx

1、Windows下DLL查找顺序160614Windows下DLL查找顺序Hanford2014年06月06日目 录第1章 说明 21.1 查找顺序 21.1.1 检查DllCharacteristics字段 31.1.2 读取manifset资源 31.1.3 读取manifset文件 41.1.4 载入 51.1.5 私有程序集 51.1.6 常规DLL的查找顺序 71.2 禁用隔离 71.2.1 修改DllCharacteristics字段 71.2.2 修改manifset 91.2.3 修改msvcr*.dll 11第1章 说明1.1 查找顺序使用VC+2008创建一个Win32项目,

2、如下图所示图1.1编译这个程序(Debug版),将得到 Test.exe 文件。使用 eXeScope 打开Test.exe,可以发现 Test.exe 在运行时需要文件 msvcr90d.dll。如下图所示:图1.2运行Test.exe时,Windows需要找到msvcr90d.dll,并将其加载至内存,然后Test.exe才能正常运行。下面对msvcr90d.dll的查找顺序进行简要说明。注意:如果操作系统比 Windows XP 还陈旧,msvcr90d.dll的查找顺序请参考1.1.6节。1.1.1 检查DllCharacteristics字段Windows首先检查Test.exe中D

3、llCharacteristics字段的数值可使用eXeScope查看DllCharacteristics字段的数值,如下图所示:图1.3根据上图可知:DllCharacteristics = 0x8140,因此:(0x8140 & IMAGE_DLLCHARACTERISTICS_NO_ISOLATION) = 0上面的宏 IMAGE_DLLCHARACTERISTICS_NO_ISOLATION 其实就是0x200,它表示一个二进制位。这个二进制位为0/1表示使用/不使用隔离(isolation)。Test.exe中DllCharacteristics的这个二进制位为零,表示使用隔离。如果

4、某个程序不使用隔离,请跳至1.1.6节。1.1.2 读取manifset资源Test.exe使用隔离,所以Windows会检查Test.exe里有没有manifset资源(类型为24,编号为1)。下图表示Test.exe里存在manifset资源。图1.4可使用记事本打开文件Test.exe.embed.manifest,查看manifset资源的内容。如下图所示:图1.51.1.3 读取manifset文件如果上一步未找到manifset资源,Windows会检查是否存在manifset文件。Test.exe的manifset文件就是Test.exe.manifest,它与Test.exe应

5、在同一目录内,否则Windows无法找到。Test.exe.manifest的内容应该与Test.exe.embed.manifest的内容保持一致。这样Windows才能顺利读取manifset信息。1.1.4 载入经过上面两步,Windows读取了manifset信息后发现:Test.exe需要程序集“Microsoft.VC90.DebugCRT”(参考上图)。现在,Windows会到C:WINDOWSWinSxS目录下查找这个程序集。在Windows7的C:WindowswinsxsManifests目录下存在文件x86_policy.9.0.microsoft.vc90.debugc

6、rt_1fc8b3b9a1e18e3b_9.0.30729.1_none_61305e07e4f1bc01.manifest,其内容如下图所示:图1.6其重点为:9.0.21022.8版本的程序集“Microsoft.VC90.DebugCRT”被重定向至版本9.0.30729.1。Windows会加载目录C:Windowswinsxsx86_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.1_none_bb1f6aa1308c35eb目录下的msvcr90d.dll。注意:在Windows XP下,重定向文件为9.0.30729.1.po

7、licy,它位于C:WINDOWSWinSxSPoliciesx86_policy.9.0.Microsoft.VC90.DebugCRT_1fc8b3b9a1e18e3b_x-ww_037be2321.1.5 私有程序集如果Windows在C:WINDOWSWinSxS里找不到合适版本的msvcr90d.dll,就会在Test.exe所在目录进行查找。位于C:WINDOWSWinSxS目录下的程序集属于共享程序集,能够被多个程序所共享。位于Test.exe所在目录的程序集属于Test.exe的私有程序集。私有程序集的搜索步骤大致为:在Test.exe所在目录查找子目录Microsoft.VC

8、90.DebugCRT,如果存在就会核对该目录内的文件Microsoft.VC90.DebugCRT.manifest。如果与要求的msvcr90d.dll版本一致,就会载入该目录下的msvcr90d.dll。使用私有程序集的具体操作如下:将目录C:Program Files (x86)Microsoft Visual Studio 9.0VCredistDebug_NonRedistx86Microsoft.VC90.DebugCRT复制到Test.exe所在目录(接下来用表示)。记事本打开Microsoft.VC90.DebugCRTMicrosoft.VC90.DebugCRT.mani

9、fest,将版本号修改为Test.exe需要的版本号,亦即下图的版本号需要与图1.5的版本号保持一致。图1.7如果Test.exe需要载入Func.dll,而后者也需要程序集“Microsoft.VC90.DebugCRT”,就可以把目录C:Program Files (x86)Microsoft Visual Studio 9.0VCredistDebug_NonRedistx86Microsoft.VC90.DebugCRT复制到Func.dll所在目录(注意:不是Test.exe所在的目录)。如果Test.exe与Func.dll在同一目录内,而它们需要的程序集版本还不相同,那就比较麻烦

10、了。说明:1、私有程序集的搜索步骤远比本文描述的复杂,详细信息请参考MSDN中的Assembly Searching Sequence,网址如下:2、如果Windows在共享程序集和私有程序集里均未找到合适版本的msvcr90d.dll,就会终止程序并显示如下界面,即使msvcr90d.dll与Test.exe在同一目录下,Windows也不会载入。图1.81.1.6 常规DLL的查找顺序根据图1.2可知,Test.exe运行时还需要USER32.dll、KERNEL32.dll。这两个动态库不属于任何程序集,是常规的DLL文件。加载它们时的查找顺序请参考MSDN中的Dynamic-Link

11、Library Search Order,网址如下:1.2 禁用隔离根据上文描述可知:C:WINDOWSWinSxS目录下允许存放某个组件(如:msvcr90d.dll)的多个版本,此即为“并列共享”(Side-by-side Assembly Sharing)。它主要是为了解决“DLL地狱”问题的,但它带来的问题比解决的问题并不少:VC+2005/2008编译生成的程序在用户的电脑上可能无法运行。为了能够更方便的发布程序,接下来介绍几种禁用隔离的方法。1.2.1 修改DllCharacteristics字段修改DllCharacteristics字段的思路就是让DllCharacterist

12、ics & 0x200不等于零。下面分两种情况进行说明:一是没有源代码,只有执行程序(如:Test.exe);二是有源代码。没有源代码,只能修改Test.exe文件。根据图1.3可知:Test.exe的字段DllCharacteristics首地址为0x13E,数值为0x8140。将0x8140改成(0x8140 | 0x200)=0x8340即可。如下图所示,使用vc2008 的Open With 打开文件Test.exe图1.9选择二进制编辑器(Binary Editor)。图1.10按下Ctrl+G,输入地址0x13E,单击“OK”按钮,即可定位到0x13E处。当前的数值为0x8140(

13、注意:低位在前,高位在后,就是下图中的40 81),将40 81改为40 83(即更改数值为0x8340),然后保存Test.exe。图1.11如果有源代码,只要修改一下配置重新编译一遍即可。具体就是修改“Allow Isolation”为“Dont allow side-by-side isolation”,如下图所示:图1.12现在Test.exe运行时就不会被隔离了,不过此时运行它还是会出错。这是msvcr90d.dll的缘故,下文将说明如何对msvcr90d.dll进行修改。1.2.2 修改manifset只有Test.exe,没有源代码,且manifset在Test.exe.mani

14、fest文件时。把 .删除即可,如下图所示:图1.13只有Test.exe,没有源代码,且manifset在Test.exe内部时。用图1.10中的资源编辑器(Resource Editor)打开Test.exe,删除.之间的内容(或者直接删除整个manifest)。如下图所示。图1.14如果有源代码,只要修改一下配置重新编译一遍即可。具体就是修改“Generate Manifest”为“No”,如下图所示:图1.15没有manifest指定程序集,Test.exe运行时就不会查找、加载程序集了,不过此时运行它还是会出错。这是msvcr90d.dll的缘故,下文将说明如何对msvcr90d.d

15、ll进行修改。1.2.3 修改msvcr*.dll使用VC+2005或VC+2008编译生成的程序,只要用到了msvcr80.dll、msvcr80d.dll、msvcr90.dll、msvcr90d.dll这四个文件中的任何一个,就必须启用隔离。一旦隔离被禁用,运行时就会崩溃并出现如下错误提示:图1.16这是msvcr?.dll造成的。以下代码节选自C:Program Files (x86)Microsoft Visual Studio 9.0VCcrtsrccrtlib.c#if defined (_CRT_CHECK_MANIFEST) if (!_check_manifest(hDll

16、Handle) return FALSE; #endif /* defined (_CRT_CHECK_MANIFEST) */这段代码表示:加载msvcr?.dll时会调用_check_manifest,检查manifest信息。如果_check_manifest返回FALSE,整个程序就会崩溃。现在再看看函数_check_manifest的代码(同样节选自crtlib.c): static BOOL _cdecl _check_manifest(HMODULE hDllHandle) pfnFindActCtxSectionStringW = (PFN_FINDAC) GetProcAdd

17、ress( hKernel32, FindActCtxSectionStringW); if (pfnFindActCtxSectionStringW = NULL) return TRUE; 根据上面的代码可知:将字符串FindActCtxSectionStringW的首字符改成00H,则GetProcAddress就会返回NULL,_check_manifest就会返回TRUE。因此,使用vc2008的二进制编辑器打开某个msvcr?.dll。找到FindActCtxSectionStringW后,将第一个字符F改成00H即可(也可全部改成 00H)。图1.17经过步骤1.2.1或1.2.2,以及步骤1.2.3,再将改好后的msvcr?.dll与Test.exe放在同一目录内,现在Test.exe即可载入同一目录下的msvcr?.dll了,再也不用到共享程序集、私有程序集里去查找、加载了。

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1