使用托管代码调用蓝屏死机

Posted

技术标签:

【中文标题】使用托管代码调用蓝屏死机【英文标题】:Invoke Blue Screen of Death using Managed Code 【发布时间】:2010-09-21 15:13:19 【问题描述】:

只是好奇:是否可以在 Windows XP/Vista 下使用 .net 托管代码调用 Windows 蓝屏死机?如果可能的话,示例代码是什么?

仅作记录,这不是出于任何恶意目的,我只是想知道需要什么样的代码才能真正杀死指定的操作系统。

【问题讨论】:

Vista有蓝屏死机吗?顺便说一句:可能有什么非恶意目的? DilbertDave:有时当您想要一次完整转储时触发。对低级别的东西很有用,但不确定 .NET ... @Alex Angas:如果您想将其用于调试目的,您最好使用 windbg 来获取 minidump。 这是一个重要的问题。如果我将 .NET 应用程序部署到客户端,然后他们出现蓝屏死机,我想知道我是否可以说“这绝对不是由我的应用程序引起的,因为它是 .NET 应用程序”。 @DilbertDave 是的,Vista 中有一个 BSOD。 【参考方案1】:

键盘的东西可能是一个不错的选择,但如果你需要通过代码来做,请继续阅读...

您实际上并不需要吐槽任何东西,您需要做的就是找到 KeBugCheck(Ex) 函数并调用它。

http://msdn.microsoft.com/en-us/library/ms801640.aspx http://msdn.microsoft.com/en-us/library/ms801645.aspx

对于手动启动的崩溃,您希望使用 0xE2 (MANUALLY_INITIATED_CRASH) 或 0xDEADDEAD (MANUALLY_INITIATED_CRASH1) 作为错误检查代码。它们被明确保留用于该用途。

但是,找到函数可能有点棘手。 Windows DDK 可能会有所帮助(检查 Ntddk.h) - 我目前没有它,而且我现在似乎无法找到决定性的信息 - 我认为它在 ntoskrnl.exe 中或ntkrnlpa.exe,但我不确定,目前没有验证它的工具。

您可能会发现只编写一个简单的 C++ 应用程序或调用该函数的东西,然后运行它会更容易。

请注意,我假设 Windows 不会阻止您从用户空间访问该功能(.NET 可能有一些特殊规定)。我自己没有测试过。

【讨论】:

KeBugCheck(Ex) 是一个核函数。 ntdll.dll 中似乎没有相应的用户模式包装器。 KeBugCheck 函数不会有用户模式包装器,因为不允许用户模式程序使系统崩溃。但是,这并不妨碍您编写自己的内核模式驱动程序来实现这一点。【参考方案2】:

我不知道它是否真的有效,我确定您需要管理员权限,但您可以设置 CrashOnCtrlScroll 注册表项,然后使用 SendKeys 发送 CTRL+Scroll Lock+Scroll Lock。

但我相信这必须来自键盘驱动程序,所以我猜一个简单的 SendKeys 还不够好,您要么需要以某种方式连接到键盘驱动程序(听起来真的很乱),要么检查 CrashDump 是否有可通过 P/Invoke 调用的 API。

http://support.microsoft.com/kb/244139

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters 名称:CrashOnCtrlScroll 数据类型:REG_DWORD 值:1 重启

【讨论】:

我发现这篇关于 Tech Republic 的文章更容易理解。不过,这是相同的技术:articles.techrepublic.com.com/5100-10878_11-5710338.html【参考方案3】:

我不得不说不。您必须 p/invoke 并与位于内核空间中的驱动程序或其他代码交互。 .NET 代码与这个领域相去甚远,尽管在未来的 Windows 版本中有一些关于托管驱动程序的讨论。再等几年,你就可以像我们不受管理的朋友一样崩溃了。

【讨论】:

【参考方案4】:

据我所知,真正的蓝屏死机需要内核模式代码失败。 Vista 仍然有 BSOD,但它们的频率较低,因为新的驱动程序模型在内核模式下的驱动程序较少。任何用户模式故障只会导致您的应用程序被终止。

您不能在内核模式下运行托管代码。所以如果你想蓝屏,你需要使用 PInvoke。但即便如此,也是相当困难的。你需要做一些非常花哨的 PInvokes 才能在内核模式下得到一些东西。

但是在成千上万的 SO 用户中,可能有人这样做了 :-)

【讨论】:

【参考方案5】:

您可以使用触发内核崩溃的 OSR Online 工具。我自己从未尝试过,但我想您可以通过标准的 .net Process 类运行它:

http://www.osronline.com/article.cfm?article=153

【讨论】:

【参考方案6】:

我曾经不负责任地使用 .NET 1.1 中的 System.Net.Sockets 在 Windows XP 上生成 BSOD。我可以经常重复它,但不幸的是那是几年前的事了,我不记得我到底是如何触发它的,也不记得有源代码了。

【讨论】:

我在 Vista 上的 .NET 3.5 中也看到了这一点,更新板载网络接口的驱动程序解决了这个问题。显然 .NET 程序触发了之前没有其他程序触发过的驱动程序问题。【参考方案7】:

尝试在directx8 或directx9 中使用directshow 进行实时视频输入,大多数调用都转到内核模式视频驱动程序。从实时视频捕获源运行回调过程时,我成功地出现了很多蓝屏,特别是如果您的回调需要很长时间,可能会停止整个内核驱动程序。

【讨论】:

【参考方案8】:

当托管代码可以访问错误的内核驱动程序时,它可能会导致错误检查。但是,直接导致 BSOD 的将是内核驱动程序(例如,uffe 的 DirectShow BSOD、Terence Lewis 的套接字 BSOD 或在将 BitTorrent 与某些网络适配器一起使用时看到的 BSOD)。

对特权低级资源的直接用户模式访问可能会导致错误检查(例如,在Device\PhysicalMemory 上乱涂,如果它没有首先损坏您的硬盘;Vista 不允许用户模式访问物理记忆)。

如果您只需要转储文件,Mendelt 建议使用 WinDbg 比利用内核驱动程序中的错误要好得多。不幸的是,本地内核调试不支持.dump 命令,因此您需要通过串行或 1394 连接的第二台 PC,或通过虚拟串行端口连接的 VM。 LiveKd 可能是单 PC 选项,如果您不需要内存转储的状态完全自洽。

【讨论】:

【参考方案9】:

这个不需要任何内核模式驱动程序,只需要一个 SeDebugPrivilege。您可以通过NtSetInformationProcessRtlSetProcessIsCritical 将您的进程设置为关键,然后终止您的进程。您将看到与杀死 csrss.exe 相同的错误检查代码,因为您在进程上设置了相同的“关键”标志。

【讨论】:

【参考方案10】:

不幸的是,我知道如何执行此操作,因为我们服务器上的 .NET 服务导致蓝屏。 (注意:Windows Server 2008 R2,不是 XP/Vista)。

我简直不敢相信 .NET 程序是罪魁祸首,但确实如此。此外,我刚刚在虚拟机中复制了蓝屏。

违规代码,导致 0x00000f4:

string name = string.Empty; // This is the cause of the problem, should check for IsNullOrWhiteSpace

foreach (Process process in Process.GetProcesses().Where(p => p.ProcessName.StartsWith(name, StringComparison.OrdinalIgnoreCase)))

    Check.Logging.Write("FindAndKillProcess THIS SHOULD BLUE SCREEN " + process.ProcessName);
    process.Kill();
    r = true;

如果有人想知道我为什么要复制蓝屏,那并没有恶意。我已经修改了我们的日志记录类,以将一个参数告诉write direct to disk,因为尽管调用了 .Flush(),但在 BSOD 之前的操作并未出现在日志中。我复制了服务器崩溃以测试日志记录更改。 VM 正常崩溃,但日志记录工作正常。

编辑:杀死csrss.exe 似乎是导致蓝屏的原因。根据 cmets,这很可能发生在内核代码中。

【讨论】:

就像上面提到的cmets,蓝屏只能由内核代码触发。您的代码很可能会触发某些驱动程序,这就是崩溃的原因。不过,这表明底层 kernel 代码不够健壮,这实际上是一个可以被利用的漏洞,直到在内核代码中修复。 是的,我认为你是对的。基本上我的代码会杀死一个导致 Windows 崩溃的基本运行时服务。【参考方案11】:

我发现如果您以管理员身份运行 taskkill /F /IM svchost.exe,它会尝试同时杀死几乎所有服务主机。

【讨论】:

以上是关于使用托管代码调用蓝屏死机的主要内容,如果未能解决你的问题,请参考以下文章

电脑死机,蓝屏报错代码的含义

从完整的内存转储中查看托管堆栈

让非托管 c++ 代码调用调用 c# 代码的托管 c++ 代码

从托管 C# 代码调用非托管 C++ 代码以生成脱机域加入 blob

托管 C# 代码未发生非托管调用

非托管代码中调用托管代码