为啥注入的任何 DLL 都会使主机进程崩溃?

Posted

技术标签:

【中文标题】为啥注入的任何 DLL 都会使主机进程崩溃?【英文标题】:Why would any DLL being injected crash a host process?为什么注入的任何 DLL 都会使主机进程崩溃? 【发布时间】:2012-02-07 04:30:59 【问题描述】:

在对我的软件的新版本进行 Beta 测试时,一些用户在运行该应用时报告了异常。在这两种情况下都是:“应用程序无法正确启动(0xc0000142)”。我也将其视为 0xc0000005。我发现一个本地系统也有这个错误,并且在调试器下运行它时发现,“datamngr.dll”有访问冲突并且在堆上分配失败。我很快发现“datamngr.dll”是间谍软件,并且正在加载,就像它在系统的 AppInit 中一样。

一旦我清除了 AppInit reg 键,这个问题就消失了。我通过进程监视器检查了它,每当注入这个 DLL 时,我的应用程序就会崩溃。我以为它只是写得不好的间谍软件,但后来我发现其他 DLL 也在做同样的事情(例如 acaptuser32.dll,它是合法软件)。对我来说奇怪的是我的软件的以前版本没有崩溃。两个版本之间有很多很多的变化,所以很难说是什么。

我从哪里开始?一些在线探索显示 Firefox 等应用程序替换 LoadLibrary 以将 DLL 列入黑名单以防止注入。但我想从更基本的开始——为什么应用程序现在崩溃了,而以前没有?

我意识到这是非常模糊的,但这几乎是不可避免的。我希望我做错的项目的属性中有一些明显的东西。我尝试过打开和关闭 ASLR,打开和关闭 DEP...我尝试过延迟加载 user32.dll 并通过 LoadLibrary 手动加载它(SetErrorMode 设置为忽略错误),但对我来说没有任何效果。我们已经在 Windows XP 和 Windows 7(32 位和 64 位)上看到了这种情况。

任何关于从哪里开始的指针将不胜感激。如果有人需要其他详细信息,我会提供尽可能多的信息。

干杯

【问题讨论】:

You are pretty much boned 你有某种版本控制吗?最明显的故障排除措施是确定行为发生变化的确切点 - 尽管我个人会从源代码重建以前的版本开始,以防它是您的构建工具而不是应用程序源本身的变化。跨度> 程序是在进入你的应用程序主函数之前还是之后崩溃?运行时库的main函数呢? 另一种可能有用的方法是编写自己的注入 DLL,以便您可以更轻松地调试问题,以确定 DLL 初始化中的哪个步骤失败。确定一个无关紧要的 DLL 是否导致崩溃也应该很有用,如果不是,则尝试缩小 DLL 中导致崩溃的操作。 嗨,Harry - 我们确实有版本控制,但一年有 40 名开发人员,所以变更集非常庞大。现在我正在比较旧项目和新项目的 VS 设置(我们都使用 VS 2010)。在我们到达我们的主函数甚至运行时库的主函数之前,这已经崩溃了。我一定会尝试注入的微不足道的 DLL -- 谢谢 :) 【参考方案1】:

我确实找到了解决办法。我使用 Process Monitor 来比较有和没有 DLL 注入器的版本中 DLL 加载的顺序。然后让我印象深刻的一件事是我拥有的加载 .NET(通过 LoadLibrary)的 C++ DLL 被首先包含在内。由于 CLR 是如此庞大,我决定尝试延迟加载该 DLL 和所有 .NET DLL。仅此而已 - 我的问题已经解决了。

就像 Raymond Chen 所说的那样——订单很脆弱。如果其他人遇到这个问题,我建议只是调整你的 DLL 加载顺序。

【讨论】:

以上是关于为啥注入的任何 DLL 都会使主机进程崩溃?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 ntdll.dll 会使我的 c++ 可执行文件崩溃?

使用 C# 将 dll 注入当前进程

强制任何正在运行的进程崩溃

使用 C 崩溃记事本进行 DLL 注入

为啥这个 xamarin Binding Converter 会使应用程序崩溃?

为啥在我尝试过的每个 XAMPP 安装中 xdebug 都会使 apache 崩溃?