C# Make a Critical Process (BSoD if Killed)

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

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:

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

usingSystem;usingSystem.Diagnostics;usingSystem.Runtime.InteropServices;publicclassCriticalProcess{[DllImport("ntdll.dll",SetLastError=true)]privatestaticexternintNtSetInformationProcess(IntPtrhProcess,intprocessInformationClass,refintprocessInformation,intprocessInformationLength);staticvoidMain(string[]args){intisCritical=1;// we want this to be a Critical Process
intBreakOnTermination=0x1D;// value for BreakOnTermination (flag)
Process.EnterDebugMode();//acquire Debug Privileges
// setting the BreakOnTermination = 1 for the current process
NtSetInformationProcess(Process.GetCurrentProcess().Handle,BreakOnTermination,refisCritical,sizeof(int));}}