问题标签 [dllmain]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - DllMain entry point DLL_PROCESS_DETACH
I have a c++ dll, called from a c# process...
Here is dll entry point...
I get one attach and four detach like so...
Attach Detach Detach Detach Detach
Can anyone explain why?
The process makes just one call to the function.
c++ - 在从挂钩延迟 dll 的 DllMain 调用的 LoadLibrary 上设置挂钩
我的目标是挂钩来自特定 dll 及其依赖项(可能延迟导入)的所有 LoadLibrary 调用。这是我尝试解决此任务的方法:
DONT_RESOLVE_DLL_REFERENCES
使用标志加载此 dll 。1.1。将此算法递归地应用于 dll 的子模块。
- 手动填写此 dll 的导入表。
- Hook all
LoadLibraryA
等LoadLibraryW
功能只是修补 Import Table。 - 使用标志
DllMain
手动调用此 dll。DLL_PROCESS_ATTACH
最后一步我遇到了问题。如果我DllMain
手动调用,那么所有内部LoadLibrary
调用都将从我的模块的地址空间(而不是从 dll 的地址空间)执行,并且我在 step3 中的所有钩子都不会调用。
而且我不想LoadLibrary
在我的主模块中挂钩调用,因为还有其他代码可以调用LoadLibrary
,我不会有这样的副作用。
所以我的问题是我应该如何调用 DllMain 以强制它不在LoadLibrary
我的主模块中使用?是因为延迟进口吗?或者只是因为我打电话DllMain
?或者也许这个任务有更好的解决方案?
这是我运行 dll 的方式:
这是我填写导入表的方式:关于我如何填写导入表的问题
LoadLibrary
hooking 类似于 Import Table 填充。
更新
我添加了来自ApiMonitor的几个屏幕截图,以证明LoadLibrary("...mso20win32client.dll")
该案例是从不同模块调用的,然后我使用上述所有这些内容加载父库olmapi32.dll
(取决于mso20win32client.dll
),然后我只调用LoadLibrary
:
当我使用上述方法时(使用DONT_RESOLVE_DLL_REFERENCES
等DllMain
)(注意最后一行:mso20win32client.dll
从mapi32ex64.dll
- 我的主模块加载):
当我刚刚调用时LoadLibrary("OLMAPI32.dll")
(注意最后一行:mso20win32client.dll
是从olmapi32.dll
我想使用我的方法加载的 dll 加载的):
c++ - 如何在 DLLMain 中启动线程?
如何在 DLLMain 中启动线程意味着 std :: thread - 从根本上说。No 表示 WinApi,STL 表示。当我在流程中运行该函数时,我会从该 DLL 调用应用程序崩溃。先感谢您。
此代码获取文件 (exe) 上的哈希和并将其写入文件。(* 。文本)。但是应用程序崩溃
c++ - 在 VC++ 中从 DLLMAIN 内部调用 D3D 的 CREATEDEVICE 时,它会创建死锁(loaderlock?)。有没有办法克服这个问题?内线终结球
不久前,我发表了一篇关于创建 dll 的帖子,目的是为了注入,这将导致主机应用程序触发 Nvidia Optimus 笔记本电脑以“唤醒”dGpu。这是必要的,因为此处创建的可悲系统 nvidia 导致许多应用程序无法识别电源 dGpu 的存在,而是使用集成的英特尔 gpu。(特别是一些视频处理应用程序使用英特尔的时间比使用英伟达的时间长)。那个帖子在这里。
可以说,我搬到南极工作并放弃了这个项目。几年后我才把它捡回来,并决定学习(足够的)C++ 来在这里编程。我已经创建了 DLL,如果我将 DX 代码放在一个函数中,然后从主机“调用者”程序中调用该函数。它可以工作!!!但是,如果我将该代码放在 DLLMAIN 中,然后简单地从我的“调用者”程序中加载该 dll(而不实际调用特定函数)......该过程将执行!!!但是,当它到达运行 CREATEDEVICE 的代码部分时,它会崩溃。从那以后,我了解到这是由于一个称为死锁或加载器锁的问题造成的。我不确定是哪个问题。我理解这个概念,但没有任何地方接近 C++ 的理解来开发解决方法。
所以基本上..我可以使用一些解决方法在 DLLMAIN 中运行我的程序吗?也许以某种方式产生一个独立的线程(所以 DLLMAIN 可以完成执行到它的返回?)感谢您提供任何信息。我将在此处包含 vcproject 源代码.. 但这是我在网上找到的科学怪人.. 所以不要追求优雅——我对 C++ 编程几乎一无所知!http://s000.tinyupload.com/index.php?file_id=07876333208461296171
windows - 在 Windows 上放置不安全的 DLL 清理代码的安全位置?
我们遇到了一个案例,将FreeLibrary
呼叫放入DllMain
/将是我们的最佳解决方案DLL_PROCESS_DETACH
。
当然,你不能这样做:
从 DllMain 调用 FreeLibrary 是不安全的。
用例是我们有这样的情况:
DLL_1 应该透明地加载 DLL_x。到它的客户端代码,它应该动态加载 DLL_x。现在,加载可以延迟完成,因此LoadLibrary
调用不必驻留在DLL_PROCESS_ATTACH
DLL_1 的部分。
但是一旦客户端完成了 DLL_1,当 DLL_1 从进程中卸载时/之前,它也应该卸载 (== FreeLibrary) DLL_x。
DLL_1/Uninitialize
如果没有客户端必须调用的显式函数,有什么方法可以做到这一点?
我会注意:
DllMain
,因此也不能使用任何 C++ 全局静态析构函数。- kernel32/ntdll 或者共享的 MS CRT 中是否有任何其他回调机制来实现这一点?
- 是否有其他模式可以使这个用例工作?
c++ - 为什么我会收到“LoaderLock”检测?
我正在使用我的 P/Invoked LoadLibrary API 从我的 c# 代码调用 c++ DLL(不是我的代码)。但是当我运行应用程序时,正在检测到 LoaderLock 错误。
起初我将此归咎于我的 DllImport C# 包装器,但是当我尝试加载其他 C++ DLL 时,它工作正常。
我在网上阅读了一些关于 LoaderLock 的文章,似乎 #1 规则是不要在 DllMain 内做任何有趣的事情。当我检查 c++ DllMain 调用 DLL_PROCESS_ATTACH 和 DLL_PROCESS_DETACH 中的一些 API 时。
当我检查 StartAPI() 时,它有一大块代码并调用一个使用CreateProccessA创建进程的函数
这是我为什么会出现 LoaderLock 错误的真正原因吗?
有人告诉我 StartAPI() 应该在 DLL 初始化时运行,还有其他方法可以使这项工作吗?
我计划在另一个线程中调用 StartAPI(),但我读过在 DllMain 中创建线程也是灾难的根源。
谢谢!
winapi - 在哪些情况下,动态 CRT 在调用用户提供的 DllMain 时尚未初始化?
序言:这个问题特别关注并且仅关注通过/MD
. 它不质疑任何其他建议的有效性。DllMain
.
正如我们被告知的那样:(参考:动态链接库最佳实践,MSDN,2006 年 5 月 17 日)
永远不要在 DllMain 中执行以下任务:
- ...
- 使用动态C 运行时 (CRT) 中的内存管理功能。如果 CRT DLL 未初始化,对这些函数的调用可能会导致进程崩溃。
- ...
其他人已经对此提出了质疑(例如:质疑论点的有效性),并且由于我们在那里得到了有用的答案,我们可以清楚地看到一个相当简单的情况,这可能会导致麻烦:
您假设 DLL 的入口点始终是 _DllMainCRTStartup。情况并非如此,它只是链接器的默认设置。它可以是程序员想要的任何东西,可以使用链接器的 /ENTRYPOINT 选项快速轻松地更改。微软无法阻止这种情况发生。
所以这些是这个问题的要素:
在链接和不提供 custom时是否还有其他情况,动态CRT 不应该完全初始化?
/MD
/ENTRYPOINT
- 具体来说,如果所有 DLL 加载仅通过“静态依赖项”完成,即根本没有显式
LoadLibrary
调用,则只是链接时 DLL 依赖项。
- 具体来说,如果所有 DLL 加载仅通过“静态依赖项”完成,即根本没有显式
奖励:MS 文档专门调用了“内存管理功能”,但据我所知,如果 CRT 未初始化,则任何CRT 功能都可能不安全。为什么要这样调用内存管理函数呢?
3号:
写。到自定义
ENTRYPOINT
:我不太明白这怎么会是一个如此重要的场景,以至于它需要被包含在 not-do-in-DllMain 列表中而无需进一步限定。如果我提供了一个自定义入口点,我负责正确初始化 CRT,否则CRT 将无法在我的程序中的任何地方正常工作,而不仅仅是 DllMain。为什么要专门调出 DllMain 部分?这使我回到 Q.1,即如果这是动态CRT 存在问题的唯一场景。澄清或大开眼界,为什么这对 DllMain 比对 DLL 的其他部分更重要,或者我在这里可能会错过什么,将不胜感激。
奖励链接:
理由:我觉得我应该为上下文添加这个:我问这个是因为我们有大量代码通过全局 C++ 对象构造函数来做事。多年来,实际发生故障的事情已经被审查了(如并发LoadLibrary
、线程同步等),但所有代码都充满了std
C++ 和 CRT 函数,这些函数在 Windows XP、7 和 Windows 10 上运行了多年而没有任何已知的问题。虽然我不是一个哭泣“但它确实有效”的人,但我必须在这里对尝试“修复”这个问题是否有任何短期到中等价值进行工程判断。因此,如果肥皂盒答案可以留在他们的盒子里,我将不胜感激。
c++ - 当我尝试在 DllMain 中显示它时,我的对话框不显示
我在 Visua Studio 2015 中创建了一个包含对话框的 Win32 dll,我使用传递给DllMain ()
并使用的 hModuleShowWindow ()
来实际显示窗口,但对话框不显示。
我用来LoadLibrary()
在另一个项目中加载这个 DLL。
问题出在哪里?这是我的代码:
winapi - 仅当动态卸载 DLL 时,DLL 才应释放堆内存?
问题目的:对DllMain
.
在 DllMain 中您不应该做太多事情是“常识”,有些事情绝对不能做,一些最佳实践。
我现在偶然发现了文档中的一个新宝石,这对我来说毫无意义:(emph。我的)
处理时,只有在动态卸载 DLL(参数为 NULL)时
DLL_PROCESS_DETACH
,DLL 才应释放堆内存等资源 。lpReserved
如果进程正在终止(lpvReserved 参数为非 NULL),则除当前线程外,进程中的所有线程要么已经退出,要么已被函数调用显式终止ExitProcess
,这可能会留下 一些进程资源,例如堆不一致的状态。在这种情况下,DLL 清理资源是不安全的。相反,DLL 应该允许操作系统回收内存。
由于全局 C++ 对象在 DllMain/DETACH 期间被清除,这意味着全局 C++ 对象不得释放任何动态内存,因为堆可能处于不一致状态。/ 当 DLL “静态链接”到可执行文件时。/ 当然不是我在那里看到的 - 各种(我们的和第三方的)库的全局 C++ 对象(如果有)在它们的析构函数中分配和解除分配就好了。(除非其他订购错误,oc)
那么,这个警告针对的是什么具体的技术问题呢?
既然段落中提到了线程终止,那么当某些线程没有正确清理时会出现堆损坏问题吗?