A critical process is a type of process that Windows requires to be running - csrss.exe is an example of such process. Whenever a process like this finishes its execution (or it’s terminated) Windows will respond with an authentic Blue Screen of Death.

Theoretically, you can BSoD yourself whenever you want :)

Note: The complete code is available at the bottom of the page (scroll down).

bsod

Technical Details

Setting a process as a critical process is done by PInvoking NtSetInformationProcess, from ntdll.dll (it requires Debug Privileges). More information about this method can be found below, in the coding section.

Now, whenever a critical process is terminated, the Kernel will throw up a BSoD, with the following bug check:

*** STOP: 0x000000F4

0x000000F4 is the value for CRITICAL_OBJECT_TERMINATION. From now, I think it starts making sense, isn’t it?

Coding Part

First things first, import NtSetInformationProcess via PInvoke, with the following code:

1
2
[DllImport("ntdll.dll", SetLastError = true)]
private static extern int NtSetInformationProcess(IntPtr hProcess, int processInformationClass, ref int processInformation, int processInformationLength);

Method Details:

  • IntPtr hProcess = the process’ handle
  • int processInformationClass = it’s like a ‘flag’ - we supply this value 0x1D (BreakOnTermination)
  • ref int processInformation = value for that flag (1 = enabled / 0 = disabled), in this case, 1 means that it’s a critical process
  • int processInformationLength = is the value supplied for the flag, which in our case is the size of an integer

Before calling this method, you also need Debug Privileges - these privileges also require Administrator Privileges.

In order to obtain them, you must call this method:

1
Process.EnterDebugMode();

Now you can safely call NtSetInformationProcess() and since that wouldn’t require additional explanation, I’ll provide the complete code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

public class CriticalProcess
{
    [DllImport("ntdll.dll", SetLastError = true)]
    private static extern int NtSetInformationProcess(IntPtr hProcess, int processInformationClass, ref int processInformation, int processInformationLength);

    static void Main(string[] args)
    {
        int isCritical = 1;  // we want this to be a Critical Process
        int BreakOnTermination = 0x1D;  // value for BreakOnTermination (flag)

        Process.EnterDebugMode();  //acquire Debug Privileges

        // setting the BreakOnTermination = 1 for the current process
        NtSetInformationProcess(Process.GetCurrentProcess().Handle, BreakOnTermination, ref isCritical, sizeof(int));
    }
}