.Net 托管代码可能导致任意蓝屏死机?

Posted

技术标签:

【中文标题】.Net 托管代码可能导致任意蓝屏死机?【英文标题】:It's possible from .Net managed code to cause an arbitrary BSOD? 【发布时间】:2016-08-07 05:38:54 【问题描述】:

我想知道是否可以通过 .Net 托管代码,或者 p/调用所需的 NT dll,是否可以生成具有特定错误检查代码原因的 BSOD(蓝屏死机)。

我知道这可以通过调用 KeBugCheckKeBugCheckEx 方法从内核模式驱动程序中实现,但我认为没有办法调用这些方法来自用户模式应用程序。

有人可以澄清一下,并为托管代码带来另一种方式(如果存在)?

【问题讨论】:

我投票结束这个问题,因为我看不出这个解决方案的实际用途 @Matt Wilko“离题”。真的吗?你能解释一下为什么你认为它是一个“离题”吗?问题很清楚,问题很清楚,毫无疑问可能与我所问的内容混淆,当然这个问题暗示了一种编程语言,那么这可以通过哪种方式成为题外话?关于(一些)实际用途,您可以在我在问题中链接的 MSDN url 的 reamrks 部分中看到它们。我只是认为像你这样的人再次投票或要求关闭只是因为他们不知道问题的答案,所以“这是一个糟糕的问题”,任何标准。 Invoke Blue Screen of Death using Managed Code的可能重复 @MattWilko:错误检查会启动通常称为 BSOD 的显示。这是关闭系统的受控方式,通常是在系统进入不可恢复状态之后。 不能P/Invoke KeBugCheckKeBugCheckEx吗? 【参考方案1】:

我有一些代码正是这样做的 开始了: 你可能只需要ntdll.dll,但我没有安装任何东西就使用了它...... 虽然错误检查代码似乎不是正常类型

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.IO;

namespace bsod

    class Program
    


        private static uint STATUS_ASSERTION_FAILURE = 0xC0000420;
      //  private static uint KMODE_EXEPTION_NOT_HANDLED=0x0000008E;
        static void Main(string[] args) 

            while (Console.ReadKey(true).Key == ConsoleKey.W) 
            

                    crash();

            

        
        static void crash()
        

            bool previousValue=false;
           // Console.WriteLine("Adjusting privileges");
            RtlAdjustPrivilege(19, true, false, out previousValue);
           // Console.WriteLine("Triggering BSOD");
            uint oul = 0;
            IntPtr sptr = Marshal.StringToHGlobalAnsi("");
            NtRaiseHardError(STATUS_ASSERTION_FAILURE, 0, 0, IntPtr.Zero, 6, out oul);

        

        [DllImport("ntdll.dll")]
        private static extern uint RtlAdjustPrivilege(
int Privilege,
bool bEnablePrivilege,
bool IsThreadPrivilege,
out bool PreviousValue
);

        [DllImport("ntdll.dll")]
        private static extern uint NtRaiseHardError(
            uint ErrorStatus,
            uint NumberOfParameters,
            uint UnicodeStringParameterMask,
            IntPtr Parameters,
            uint ValidResponseOption,
            out uint Response
        );

    

让我澄清一下,这可能是非常危险的,因为您离不断使计算机崩溃的无限循环只有一步之遥...

【讨论】:

【参考方案2】:

你可以杀死csrss进程,很简单:

System.Diagnostics.Process.GetProcessesByName("csrss").Single().Kill();

即使这需要管理员权限

【讨论】:

杀掉CSRSS和关闭系统有什么区别? Win32 子系统并不是 Windows 的全部... 感谢回答,我知道杀死关键进程会导致 BSOD,但是,由于它是特定的 BSOD,因此无法回答我的问题,因为我无法为该 BSOD 指定自定义原因代码。 @IInspectable - Windows 非常关心 csrss 进程。如果该进程终止,windows 会假定发生了坏事并销毁所有内容。 @Damien:这是1 纯属巧合2 无证3 可能会更改,4 不允许您提供特定的错误检查代码。 @IInspectable :我不会打电话给this undocumented。 “Microsoft Windows 无法在没有 WinLogon 或 CSRSS 的情况下运行。因此,这是用户模式服务失败可以关闭的少数情况之一关闭系统。”【参考方案3】:

我不能肯定地说内核没有提供一些从用户模式使用任意参数调用 KeBugCheck 的方法,即使只是针对高特权进程,但我非常希望没有提供,我当然同情任何人想知道为什么你会想要这样的东西存在,更不用说使用它了。

当然,即使内核尚未公开它以供从用户模式调用,它在内核模式下也很容易使用,即由驱动程序调用。然而,即使在那里,强烈建议驱动程序不要在任何已发布的代码中使用它。尽管驱动程序可以公开用户模式接口,例如,通过设备 I/O 控制,以代表用户模式客户端调用 KeBugCheck,即使是非特权客户端,这样做对于驱动程序编写者来说是非常不负责任的(除了,也许,用于私人测试)。

至于 CSRSS,你们中的一些人可能想知道(并且可能已经知道)该架构长期以来允许 CSRSS 不必是关键的(在某种意义上杀死它会杀死 Windows)并且它也不需要不是唯一的。有一个未记录的函数RtlSetProcessIsCritical,诸如 CSRSS 之类的程序调用它来注册自己非常重要,以至于当内核看到它们退出时,内核应该提出两个特定的错误检查中的任何一个。

【讨论】:

以上是关于.Net 托管代码可能导致任意蓝屏死机?的主要内容,如果未能解决你的问题,请参考以下文章

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

本地代码与托管代码

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

对“XXX::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们

对“xxx”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们。 错误解决一例。(代码片段

类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们的问题的解决方法