如果你认真瞧过LoadLibraryEx函数的文档,就会发现它有这样一个标志
DONT_RESOLVE_DLL_REFERENCES。关于此标志,文档是这样描述的:

如果使用了此标志,并且加载的是一个DLL模块,系统在进程和线程初始化/退出的时候,不会调用DllMain,同时,系统也不会加载该模块引用的其他模块。
如果你系统仅仅是访问DLL模块中的数据或者是资源的话,则使用LOAD_LIBRARY_AS_DATAFILE会是一个更佳的选择。

在我看来,上面所建议的LOAD_LIBRARY_AS_DATAFILE还远远不够。
因为,
DONT_RESOLVE_DLL_REFERENCES这个标志实际上有点类似于一个”定时炸弹”。

请再次认真阅读下关于这个标志的文档,试着深入地理解它会做什么以及它不会做什么。
模块被加载到内存的时候,系统不会调用它的初始化函数,并且其所有依赖的模块也不会被加载。结果就是,你无法执行此模块中的任何代码。(说得更准确地的话,就是如果你试图执行该模块中的代码,会导致程序崩溃,一万DLL模块还未初始化其自身,并且它的DLL导入表都没有得到解析)
但是,和LOAD_LIBRARY_AS_DATAFILE标志不同的是,被加载的DLL可以被GetModuleHandle所发现,并且可以使用GetProcAddress。

很明显,对于一个使用了标志进行加载的模块使用GetProcAddress是一个坏主意。因为上面我们提到过,你根本无法执行这个DLL中的任何代码。那从DLL中获取一个函数入口点又有什么意义呢?

而GetModuleHandle就会触发这个定时炸弹。

使用GetModuleHandle来查看一个DLL是否已经加载了是一个很常见的使用场景,如果加载了,则继续使用GetProcAddress来获取一个函数的地址并调用它。如果DLL使用的是
DONT_RESOLVE_DLL_REFERENCES标志来加载的话,GetModuleHandle和GetProcAddress将会调用成功,但是执行函数的时候会导致程序崩溃。执行这种操作的代码不知道DLL是使用 DONT_RESOLVE_DLL_REFERENCES 加载的,它没有办法保护自己。

(请注意,这样做的代码无论如何都是不安全的,因为最初加载 DLL 的代码可能会在另一个线程上执行 FreeLibrary,从而导致代码从第一个线程下面被撕掉。第二个问题可以通过使用 GetModuleHandleEx”修复”这个问题,可以通过指定它增加 DLL 引用计数,但这并不能解决第一个问题。)

即使你使用LoadLibrary加载DLL并将该句柄传递给GetProcAddress,程序仍然会崩溃,因为LoadLibrary注意到DLL已加载并且只是增加引用计数。

我们看看下面的例子:

如果你在没有命令行参数的情况下运行这个程序,那么一切都会正常运行:记事本会顺利启动。 但是,如果你传递一个命令行参数,这会启动”定时炸弹”,并且对 ShellExecuteA 的调用会导致程序崩溃,因为 shell32.dll 是在没有解析其 DLL 引用的情况下加载的。

换句话说,
DONT_RESOLVE_DLL_REFERENCES 从根本上说是有缺陷的,应该避免。 它继续存在只是为了向后兼容。

总结

太长不看版:任何情况下,请勿使用
DONT_RESOLVE_DLL_REFERENCES,保护他人,也保护自己。

最后

Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《LoadLibraryEx(
DONT_RESOLVE_DLL_REFERENCES) is fundamentally flawed》

LoadLibraryEx(DONT_RESOLVE_DLL_REFERENCES)的缺陷相关推荐

  1. TVM适配NN编译Compiler缺陷

    TVM适配NN编译Compiler缺陷 内容纲要 前言 TVM针对VTA的编译流程 i. 自定义VTA架构:TVM的缺陷与性能瓶颈 TVM缺陷与瓶颈 i. 缺陷一:SRAM配置灵活性差 ii. 缺陷二 ...

  2. 基于U-Net图像分割的划痕缺陷分割(课程设计)

    基于U-Net的划痕缺陷分割(课程设计) 论文:**U-Net: Convolutional Networks for Biomedical Image Segmentation** https:// ...

  3. IIS7.5 HTTP 错误 500 调用loadlibraryex失败的解决方法

    在IIS7.5打开网页的时候,提示: HTTP 错误 500.0 - Internal Server Error 调用 LoadLibraryEx 失败,在 ISAPI 筛选器 C:\Windows\ ...

  4. 零代价修复海量服务器的内核缺陷——UCloud内核热补丁技术揭秘

    下述为UCloud资深工程师邱模炯在InfoQ架构师峰会上的演讲--<UCloud云平台的内核实践>中非常受关注的内核热补丁技术的一部分.给大家揭开了UCloud云平台内核技术的神秘面纱. ...

  5. 项目管理和缺陷跟踪工具Redmine

    官网: http://www.redmine.org/ http://demo.redmine.org/ 下载: http://www.redmine.org/projects/redmine/wik ...

  6. VC下通过进程ID获取进程镜像文件路径的方法及其存在的缺陷

    工作中经常会遇到通过进程ID获取进程镜像文件或者其他模块的路径的需求.(转载请指明出处)网上关于方案大致存在两种方案: OpenProcess->GetModuleFileName OpenPr ...

  7. 搭建Mantis 缺陷管理系统(转)

    转自 什么是Mantis MantisBT is a free popular web-based bugtracking system (feature list). It is written i ...

  8. 《C陷阱与缺陷》一导读

    前 言 C陷阱与缺陷 对于经验丰富的行家而言,得心应手的工具在初学时的困难程度往往要超过那些容易上手的工具.刚刚接触飞机驾驶的学员,初航时总是谨小慎微,只敢沿着海岸线来回飞行,等他们稍有经验就会明白这 ...

  9. 基于matlab的硅晶体模型,基于Matlab的图像处理技术识别硅太阳电池的缺陷

    第 44 卷 第 7 期 2010 年 7 月 上 海 交 通 大 学 学 报 JOURNAL OF SHANGHAI J IAOTON G UNIVERSITY Vol. 44 No. 7 Jul. ...

最新文章

  1. CV技术在医疗领域中有哪些应用?Salesforce、谷歌、斯坦福综述文章登上Nature子刊...
  2. npm -S -D的区别
  3. ID,ClientID,UniqueID的区别
  4. rest spring_Spring REST:异常处理卷。 3
  5. 深圳某集团招聘信息安全工程师
  6. 微信小程序遇到的那些坑
  7. .NET Core微服务之基于Steeltoe使用Zipkin实现分布式追踪
  8. H5-表格的基本样式
  9. Win10 cmd禁用笔记本自带键盘
  10. Siebel系统中配置LDAP认证
  11. Sims 4 Cottage Living 模拟人生4乡间生活 作弊码整理
  12. 宝塔面板ftp空间连接失败解决方案汇总
  13. Redis 实现热度统计和已读未读功能
  14. Java版本微信授权登录(升级版)
  15. 微信小程序播放m3u8视频总结
  16. 第一章Web技术概述
  17. 双球坐标系_天球坐标系 - 中文百科
  18. 【unity shader】unity游戏特效-仿《黑暗欺骗》模型消融消失效果
  19. 如何在 Debian 10 上配置 sources.list
  20. Microsoft Office 2016安装教程

热门文章

  1. hrbp 牵着鼻子走_8招让你不再被职场牵着鼻子走
  2. Chrome浏览器如何导入证书(最新!)
  3. IMEI、IMSI、ICCID、SN是什么?意义和区别?通信模组或手机的唯一识别码
  4. python 打印99乘法口诀
  5. android设备id完美解决方法,如何在Android中获取唯一的设备硬件ID?
  6. 自建内网穿透服务器替换TeamViewer和向日葵,实现远程控制。
  7. nltk.stem.WordNetLemmatizer()时报错BadZipFile(“File is not a zip file“)的解决方法
  8. 谷歌浏览器Chrome通过命令截图整个网页,screen,通过插件生成gif图片,以及通过插件进行录屏
  9. 网页防篡改使用详解及体会
  10. MySQL:指定索引+事务+存储引擎的配置 开发必备 天呐!为什么会有索引这种东西