Set process as critical on Windows in C++
In Windows, there exists an obscure ZwAPI/NTAPI feature that lets you set a process as critical/system. A critical process will bugcheck (BSOD) the computer with a 0x000000F4 (CRITICAL_OBJECT_TERMINATION) bugcheck. This requires at least Windows XP to function.
Example code:
- nt_types.h:
// Assorted winternal things that are used in NtAPI layer
#pragma once
#include <windows.h>
typedef LONG NTSTATUS;
typedef NTSTATUS (NTAPI* PtrAdjPrv)(ULONG Privilege,BOOLEAN Enable, BOOLEAN CurrentThread, PBOOLEAN Enabled);
typedef NTSTATUS (NTAPI* PtrSInfoProc)(HANDLE ProcessHandle, ULONG ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength);
// some NT values we use
enum {
SeDebugPrivilege = 19,
ProcessBreakOnTermination = 0x1d
};
- ntapi.h:
// Public NTAPI layer
#pragma once
namespace ntapi {
int SetCritical();
}
- ntapi.cc:
// NTAPI interface code
#include <windows.h>
#include "nt_types.h"
// NTAPI function pointers
PtrAdjPrv RtlAdjustPrivilege;
PtrSInfoProc NtSetInformationProcess;
namespace ntapi {
bool initalized;
int setup(){
HMODULE hNTDLL = LoadLibrary("NTDLL.DLL");
if(hNTDLL){
RtlAdjustPrivilege = (PtrAdjPrv)GetProcAddress(hNTDLL, "RtlAdjustPrivilege");
if(!RtlAdjustPrivilege){
return 1;
}
NtSetInformationProcess = (PtrSInfoProc)GetProcAddress(hNTDLL, "NtSetInformationProcess");
if(!NtSetInformationProcess){
return 1;
}
FreeLibrary(hNTDLL);
initalized = true;
return 0;
} else {
return 1;
}
}
int SetCritical(ULONG BreakOnTermination) {
if(initalized == false){
if(setup() == 1){
return 1; // failed to get our pointers
}
}
BOOLEAN bl;
RtlAdjustPrivilege(SeDebugPrivilege, TRUE, FALSE, &bl);
NtSetInformationProcess(GetCurrentProcess(), ProcessBreakOnTermination, &BreakOnTermination, sizeof(ULONG));
return 0;
}
}
- main.cc:
#include <ntapi.h>
#include <windows.h>
int main() {
if(!ntapi::SetCritical(1)){
return 1; // failed
}
MessageBox(NULL, "I'm a lemon", "Free minecraft tutorials", MB_OK);
return 0;
}
Three things to note:
- This requires Administrator privileges in order to work, so, if you have Windows Vista and up with UAC enabled, you'll need to run it as Administrator (Right click > Run as Administrator)
- If your process gets killed or returns/dies normally, the computer that it is running on WILL bugcheck (BSOD).
- If you want to make sure the computer can reboot normally, listen for shutdown/reboot and call ntapi::SetCritical(0).