0

I wonder whether from .Net managed code, or maybe p/invoking the needed NT dll, if I could generate a BSOD (Blue Screen Of Death) with specific bugcheck-code reason.

I know this is possible from a kernel-mode driver by calling KeBugCheck or KeBugCheckEx methods, but I think there is no way to call those methods from user-mode applications.

Someone could clarify me things, and bring an alternative way (if exists) for managed code?.

ElektroStudios
  • 19,105
  • 33
  • 200
  • 417
  • I'm voting to close this question as off-topic because I can't see a practical use for this solution – Matt Wilko Apr 15 '16 at 10:23
  • @Matt Wilko "Off-Topic". really? Could you explain why you consider it as an "Off-Topic"? the problem is clear, the question is clear with no doubts about possible confussions with what I'm asking, and of course the question implies a programming language, so in which manner this can be Off-Topic?. About (some of) the practical uses, you can see them in the reamrks section of the MSDN urls that I linked in my question. I just think that again people like you is downvoting or requesting a closure only because they don't know an answer to a question, so "its a bad question", with any criterion. – ElektroStudios Apr 15 '16 at 10:32
  • Possible duplicate of [Invoke Blue Screen of Death using Managed Code](http://stackoverflow.com/questions/277959/invoke-blue-screen-of-death-using-managed-code) – Siderite Zackwehdex Apr 15 '16 at 10:39
  • @MattWilko: A bugcheck initiates the display of what is commonly referred to as the *BSOD*. This is **the** controlled manner to take down a system, usually after it entered an unrecoverable state. – IInspectable Apr 15 '16 at 10:51
  • Isn't it possible to P/Invoke `KeBugCheck` and `KeBugCheckEx`? – Visual Vincent Apr 15 '16 at 12:26
  • @ElektroStudios, perhaps what Matt Wilko is thinking but not saying is that there are definitely uses of what you are asking that are not good ones. We have no way of knowing for sure and the answers will be available for others that might abuse it. So at least be understanding of that. – Sam Hobbs Apr 15 '16 at 22:39

3 Answers3

1

You can kill the csrss process, pretty simple:

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

Even if that requires administrator rights

ElektroStudios
  • 19,105
  • 33
  • 200
  • 417
Marco
  • 206
  • 1
  • 7
  • How is killing CSRSS the same as shutting down the system? The Win32 subsystem isn't all there is to Windows... – IInspectable Apr 15 '16 at 10:04
  • Thhanks for answer, I knew that killing a critical process causes a BSOD, however, since it is a specific BSOD this does not answer my question, because I cannot specify a custom reason code for that BSOD. – ElektroStudios Apr 15 '16 at 10:15
  • 1
    @IInspectable - Windows cares deeply about the csrss process. If that process dies, windows assumes bad things have happened and tears everything down. – Damien_The_Unbeliever Apr 15 '16 at 10:19
  • @Damien: This is `1` purely coincidential `2` undocumented `3` subject to change, and `4` doesn't allow you to provide a specific bugcheck code. – IInspectable Apr 15 '16 at 10:24
  • 1
    @IInspectable : I wouldn't call [**this**](https://msdn.microsoft.com/en-us/library/windows/hardware/ff560177(v=vs.85).aspx) undocumented. _"Microsoft Windows **cannot run** without WinLogon or **CSRSS**. Therefore, this is one of the few cases where the failure of a user-mode service **can shut down the system**."_ – Visual Vincent Apr 15 '16 at 12:23
  • @VisualVincent: This doesn't explicitly say, that the system is shut down, if the CSRSS service is terminated. The document uses the terms *"fatally compromised"*, and *"failure of a user-mode service"*. A future version of Windows could attempt to restart the CSRSS, if it detects a controlled shutdown of this service. – IInspectable Apr 15 '16 at 12:34
  • @IInspectable : _"cannot run"_ means nothing else than that the process is required for the system to run. If it's terminated the system can't continue running. A future version of Windows could attempt to restart it, but that must include that the CSRSS process is not made as fatal as it is now _(also, you could say that for anything. A future version could change the `KeBugCheck` function too)_. If you compare it to a heart, the body cannot automatically restart the heart if it stops because the body doesn't function without it. – Visual Vincent Apr 15 '16 at 12:53
  • Though, killing a process is not really a "controlled shutdown" either. – Visual Vincent Apr 15 '16 at 13:02
  • @VisualVincent: Obviously the implementation for `KeBugCheck` can change, so long as it doesn't violate the documented contract. My hypothetical change to the behavior in response to terminating the CSRSS service would still be in line with the documentation (which isn't even contractual rather than informational). There used to be times, when a faulting display driver would take down the system. Today, a display driver can get restarted. System resilience gets improved all the time. – IInspectable Apr 15 '16 at 13:04
  • @VisualVincent: Killing a process **using what is available today** may not constitute a clean shutdown (although it would still be controlled). – IInspectable Apr 15 '16 at 13:05
  • @IInspector : Yes, the system resilience gets improved all the time, but there will always be some process that the system cannot run without **at all** (unless of course Microsoft decides that there should be multiple instances of that process running, coorperating with each other and restart an instance if one of them is terminated. Though that _could_ be memory and CPU expensive). – Visual Vincent Apr 15 '16 at 13:12
1

I can't say for certain that the kernel does not provide some means of invoking KeBugCheck with arbitrary arguments from user mode, even if just for highly privileged processes, but I very much hope none does and I certainly sympathise with anyone who wonders why on earth you would want something like this to exist let alone to use it.

Of course, even if the kernel doesn't already expose it for calling from user mode, it is readily available in kernel mode, i.e., to be called by drivers. Even there, however, drivers are strongly discouraged from resorting to it in any code that's ever released. Though a driver could expose a user-mode interface, e.g., through Device I/O Control, for calling KeBugCheck on behalf of a user-mode client, even an unprivileged one, doing so would be incredibly irresponsible of a driver writer (except, perhaps, for private testing).

As for CSRSS, some of you may want to know as background (and perhaps know already) that the architecture has long allowed that CSRSS needn't be critical (in the sense that killing it kills Windows) and also that it needn't be the only one. There is an undocumented function RtlSetProcessIsCritical which programs such as CSRSS call to register themselves as being so vital that when the kernel sees them exit then the kernel should raise either of two particular bug checks.

1

I had some code that did exactly that here we go: you might just need ntdll.dll but I used it without installing anything... though the bug check codes don't seem to be the normal types

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
        );

    }
}

let me clarify that this can be very dangerous, as you are one step away from an infinite loop constantly crashing your computer...

Pluto
  • 26
  • 1