Set process as critical on Windows in C++

From Computernewb Wiki
Revision as of 22:48, 17 May 2022 by Dartz (talk | contribs) (1 revision imported)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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