Skip to content

Instantly share code, notes, and snippets.

@sh9351
Created May 15, 2024 14:47
Show Gist options
  • Save sh9351/a3489f1a91d62273ae4d489040cfee1b to your computer and use it in GitHub Desktop.
Save sh9351/a3489f1a91d62273ae4d489040cfee1b to your computer and use it in GitHub Desktop.
RtlSetProcessIsCritical, now on Node.js!

RtlSetProcessIsCritical.js

This script uses the Win32 FFI to set a Node.js as critical to the Windows system, meaning killing it becomes difficult, and eventually doing so will lead to a BSOD. After a lot of futile attempts using ChatGPT, I just decided to do it myself, although I did combine some of the AI-written code.

Requirements

  • npm i ffi-napi
  • Windows (would probably work on older versions way back to Windows 7, but not guaranteed)

Execution

Just run the script with Node.js, and enjoy!
Previous methods I tried to kill the process:

  • Task Manager - itself crashed :(
  • taskkill /im node.exe - required /f
  • taskkill /f /im node.exe - access denied
  • taskkill /f /im node.exe w/ admin - BSOD(CRITICAL_PROCESS_DIED)

License

GNU GENERAL PUBLIC LICENSE v3
Please don't use this for something evil <3

const ffi = require('ffi-napi')
const ref = require('ref-napi')
const BOOL = ref.types.int32
const LONG = ref.types.long
const HANDLE = ref.refType(ref.types.void)
const LPCSTR = ref.types.CString
const BOOLEAN = ref.types.bool
const PBOOLEAN = ref.refType(BOOLEAN)
const kernel32 = ffi.Library('kernel32', {
'LoadLibraryA': ['pointer', ['string']],
'GetProcAddress': ['pointer', ['pointer', 'string']],
'GetCurrentProcess': ['pointer', []],
'OpenProcessToken': ['int', ['pointer', 'int', 'pointer']],
})
const advapi32 = ffi.Library('advapi32', {
'AdjustTokenPrivileges': ['int', ['pointer', 'bool', 'pointer', 'int', 'pointer', 'pointer']],
'LookupPrivilegeValueA': ['int', ['pointer', 'string', 'pointer']],
})
const hDLL = kernel32.LoadLibraryA('ntdll.dll')
if (hDLL == null) {
console.log('Failed to load ntdll.dll')
process.exit(1)
}
const hToken = ref.alloc('pointer')
const luid = Buffer.alloc(8)
const tkprivs = Buffer.alloc(16)
const SE_DEBUG_NAME = 'SeDebugPrivilege'
const TOKEN_ADJUST_PRIVILEGES = 0x0020
const TOKEN_QUERY = 0x0008
const SE_PRIVILEGE_ENABLED = 0x00000002
if (!kernel32.OpenProcessToken(kernel32.GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, hToken)) {
console.log('OpenProcessToken failed')
process.exit(1)
}
if (!advapi32.LookupPrivilegeValueA(null, SE_DEBUG_NAME, luid)) {
console.log('LookupPrivilegeValueA failed')
process.exit(1)
}
tkprivs.writeUInt32LE(1, 0)
luid.copy(tkprivs, 4)
tkprivs.writeUInt32LE(SE_PRIVILEGE_ENABLED, 12)
if (!advapi32.AdjustTokenPrivileges(hToken.deref(), false, tkprivs, tkprivs.length, null, null)) {
console.log('AdjustTokenPrivileges failed')
process.exit(1)
}
const fSetCritical = ffi.ForeignFunction(kernel32.GetProcAddress(hDLL, 'RtlSetProcessIsCritical'), 'long', ['bool', 'bool', 'bool']);
if (!fSetCritical) {
console.log('GetProcAddress failed')
process.exit(1)
}
const ret = fSetCritical(true, null, false)
if (ret != 0) {
console.log('RtlSetProcessIsCritical failed')
process.exit(1)
}
while (true) { }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment