翻译《The Old New Thing》 - Some reasons not to do anything scary in your DllMain

news2024/10/8 16:51:01

Some reasons not to do anything scary in your DllMain - The Old New Thing (microsoft.com)icon-default.png?t=N7T8https://devblogs.microsoft.com/oldnewthing/20040127-00/?p=40873

Raymond Chen 2004年01月27日


简介

这篇文章讨论了为什么不应该在DLL的DllMain函数中执行复杂的操作

正文

        众所周知,我们不应该在DLL的DllMain函数中进行任何复杂的操作。Oleg Lvovitch就此写过两篇精彩的文章,一篇解释了事情的运作方式,另一篇则讲述了当事情不按预期进行时可能遇到的问题。这里再补充一个简单的理由:在许多情况下,加载一个库并不意味着要全面利用它的功能。例如,某人可能会以以下方式加载你的库,仅仅是为了获取一个图标:

// 为了说明目的,省略了错误检查
hinst = LoadLibrary("you");
hicon = LoadIcon(hinst, MAKEINTRESOURCE(5));
FreeLibrary(hinst);

        如果这时你的DLL突然执行了复杂的操作,比如启动一个计时器或线程,这可能会让对方感到意外,甚至不快。

        虽然可以通过使用LoadLibraryExLOAD_LIBRARY_AS_DATAFILE标志来避免这种情况,但这并不是我要讨论的重点。

        你的库还可能在没有运行任何代码的情况下被加载,尤其是当它作为其他DLL的依赖项时。假设“middle.dll”是一个连接到你的DLL的中间库。代码可能会这样加载它:

hinst = LoadLibrary("middle");
pfn = GetProcAddress(hinst, "SomeFunction");
pfn(...);
FreeLibrary(hinst);

         

        当“middle.dll”被加载时,你的DLL也会被加载和初始化。这意味着即使“SomeFunction”函数没有使用你的DLL,你的初始化代码也会执行。

        这种“中间DLL短暂加载”的情况实际上非常普遍。例如,当执行“Regsvr32 middle.dll”命令注册DLL时,中间DLL会被加载以调用其DllRegisterServer函数,这个函数通常只是简单地添加一些注册表键,并不会调用你的辅助DLL。

        另一个例子是打开控制面板文件夹。控制面板文件夹会加载每个*.cpl文件,以调用其CplApplet函数来确定显示哪个图标,这通常也不会涉及到你的辅助DLL。

        在你的DLL的DLL_PROCESS_ATTACH处理程序中,绝不应该创建任何具有线程亲和性的对象。因为你无法控制是哪个线程发送DLL_PROCESS_ATTACH消息,也无法预知是哪个线程发送DLL_PROCESS_DETACH消息。如果发送DLL_PROCESS_ATTACH消息的线程在加载你的DLL后立即结束,那么任何依赖该线程的对象都会停止工作。即使该线程没有立即结束,也没有保证说调用FreeLibrary的线程和调用LoadLibrary的是同一个,因此你无法在DLL_PROCESS_DETACH中正确清理这些对象。

        此外,绝不应该在你的DLL的DLL_PROCESS_ATTACH中创建窗口。除了线程亲和性的问题,全局钩子如果在加载器锁内部运行,也可能导致灾难性的后果,比如系统死锁。

明天我将提供更多相关的例子。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1617718.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SAP DMS创建文档根目录操作简介

前面我们已经对DMS的后台进行了系统的配置,本文开始我们对DMS的前台操作进行说明 1、CV01N创建文档 注意:EDIPUBLICROOTFOLDER为根目录的凭证号,不允许更改。 输入好后回车。进入下图所示: 点击文档浏览器,进入下一屏如下图: 注意:点击创建新的私人文件夹按创建是创…

使用CSS3 + Vue3 + js-tool-big-box工具,实现炫酷五一倒计时动效

时间过得真是飞速,很快又要到一年一度的五一劳动节啦,今年五天假,做好准备了吗?今天我们用CSS3 Vue3 一个前端工具库 js-tool-big-box来实现一个炫酷的五一倒计时动效吧。 目录 1 先制作一个CSS3样式 2 Vue3功能提前准备 3…

基于DEAP数据集的四种机器学习方法的情绪分类

在机器学习领域,KNN(K-Nearest Neighbors)、SVM(Support Vector Machine)、决策树(Decision Tree)和随机森林(Random Forest)是常见且广泛应用的算法。 介绍 1. KNN&am…

windows本地提权--令牌窃取烂土豆UAC

免责声明:本文仅做技术交流与学习,请知法守法,不要乱搞破坏等等... 目录 一.令牌窃取 操作: 1-生成-->上传后门后,让msf上线 2-执行命令 二.烂土豆(MS16-075) 操作: 1-先让MSF上线 2-上传烂土豆 3-执行命令 三.UAC(用户账户控制) 1-MSF模块提权 2-UACME 项目(yy…

Kafak详解(1)

简介 消息队列 为什么要有消息队列 图-1 消息队列的使用 消息队列 1)消息Message:网络中的两台计算机或者两个通讯设备之间传递的数据。例如说:文本、音乐、视频等内容。 2)队列Queue:一种特殊的线性表(数据元素首尾相接),特…

应对电网挑战!lonQ与橡树岭国家实验室利用量子技术改善关键基础设施

内容来源:量子前哨(ID:Qforepost) 文丨浪味仙 排版丨沛贤 深度好文:1800字丨6分钟阅读 摘要:美国电网正在面临需求增加和能源扩散的挑战,对能够应对优化和安全挑战的创新解决方案有着迫切需求…

黑马鸿蒙学习5:LIST容器

LIST容器,其实就是如果FOREACH容器展示不全的话,会自动有滚动条了。要注意的是,LIST中必须有固定的listitem这个项,而且列表里面只能包含一个根组件。 必须把ROW容器放到listitem中,如下:

node+vue3的websocket前后端消息推送

nodevue3的websocket前后端消息推送 前期写web项目时,前端获取数据的方式一般是向后端发起数据请求,然后后端向前端发送数据,然后对数据进行渲染,这是最常规的一种数据通讯方式,适用于绝大部分前后端分离的项目 实际…

云原生的基石:containerd引领未来容器发展趋势

文章目录 一、Containerd简介:容器技术的心脏二、Containerd核心原理解析三、Containerd与Docker的关系四、Containerd在云原生应用部署中的作用五、Containerd的扩展性和插件机制六、Containerd的安全特性七、Containerd的性能优化八、Containerd的社区和生态系统九…

阿里云mysql8.0 this is incompatible withsql mode=only full group by

阿里云RDS中mysql5.6升级为8.0后,出现如下问题: ### Error querying database. Cause:java.sql.SQLSyntaxErrorException: Expression #1 of SELECT listis not in GROUP BY clause and contains nonaggregatedcolumn temp.product_id which is not fun…

SMT工艺上出现焊锡球,将有什么影响?

在表面贴装技术(SMT)加工过程中,可能会出现焊锡球形成的问题,焊锡球的存在不仅影响产品的外观质量,还可能导致电路短路,从而影响产品性能和可靠性,所以必须提前了解焊锡球的形成原因&#xff0c…

Python-VBA函数之旅-input函数

目录 一、input函数的常见应用场景: 二、input函数使用注意事项: 三、如何用好input函数? 1、input函数: 1-1、Python: 1-2、VBA: 2、推荐阅读: 个人主页:神奇夜光杯-CSDN博…

CommunityToolkit.Mvvm笔记---RelayCommand

RelayCommand 和 RelayCommand<T> 是 ICommand 实现&#xff0c;这些实现可向视图公开方法或委托。 这些类型充当在 viewmodel 和 UI 元素之间绑定命令的方法。 平台API&#xff1a;RelayCommand、RelayCommand<T>、IRelayCommand、IRelayCommand<T> 工作原理…

FPGA组合逻辑电路设计之译码器

在数字电路中可以根据电路功能的不同分为&#xff0c;组合逻辑电路与时序逻辑电路。组合逻辑 电路在逻辑功能上的特点是任意时刻的输出仅仅取决于该时刻的输入&#xff0c;与电路原来的状态无 关。而时序逻辑从电路特征上看来&#xff0c;其特点为任意时刻的输出不仅取决于该…

电子邮箱是什么?电子邮箱怎么申请注册?

虽然通过电子邮箱收发邮件办公已经成为常态&#xff0c;但是很多人不清楚电子邮箱是什么&#xff1f;电子邮箱是指通过网络传递的“邮局”&#xff0c;可以用来收发电子邮件。每个人的电子邮箱地址都是唯一的&#xff0c;确保他人的邮件能准确送到我们的电子邮箱之中。电子邮箱…

字符长、看不懂、费率飙升|Runes协议上线后发生了什么?

作者&#xff1a;比特里里 X/推&#xff1a;lilyanna_btc 1、字符数长了&#xff0c;单词都完整了&#xff0c;反而看不懂了 由于 Runes 协议的字符长度限制&#xff0c;大部分的票都在 13 个字符及以上&#xff0c;人名、域名、slogan&#xff0c;各类玩法都出来了。很多人适…

Github Actions实现CI/CD(golang项目)

Github Actions构建CI/CD&#xff08;golang项目&#xff09; 1 基础概念 1.1 Actions GitHub Actions允许构建一个完整的 CI/CD Pipeline&#xff0c;与 GitHub 生态系统深度集成&#xff0c;而无需使用 Travis CI 或者 Circle CI 等第三方服务&#xff0c;对于开源项目都是…

MongoDB数据恢复—拷贝MongoDB数据库文件后无法启动服务的数据恢复案例

服务器数据恢复环境&#xff1a; 一台Windows Server操作系统服务器&#xff0c;服务器上部署MongoDB数据库。 MongoDB数据库故障&检测&#xff1a; 工作人员在未关闭MongoDB数据库服务的情况下&#xff0c;将数据库文件拷贝到其他分区。拷贝完成后将原MongoDB数据库所在分…

AI人工智能培训老师叶梓:大数据治理的关键工具:开源数据血缘分析系统

在大数据时代&#xff0c;数据的产生和传播速度日益加快&#xff0c;数据之间的关系也变得日益复杂。为了更好地管理和理解数据之间的关系&#xff0c;数据血缘分析系统应运而生。本文将介绍几个开源的数据血缘分析系统&#xff0c;它们在数据治理、数据质量管理和数据隐私保护…

Python学习从0开始——项目一day02数据库连接

Python学习从0开始——项目一day02数据库连接 一、在线云数据库二、测试数据库连接三、数据库驱动介绍四、SQL执行4.1插入测试数据4.2安装数据库连接模块4.3测试SQL语句执行4.4执行SQL的固定步骤及示例 一、在线云数据库 找了一个在线数据库&#xff0c;需要邮箱注册&#xff…