RtlSetProcessIsCriticalの正しくて間違った使い方
詳細はRtlSetProcessIsCriticalを参考にしてもらうとして、次のコードをコンパイルする。次に管理者権限で実行する。
#include <windows.h> #include <winternl.h> #include "util/EnablePrivilege.hpp" // http://www.geocities.co.jp/egggarden/_blog/EnablePrivilege.hpp.txt typedef NTSTATUS (WINAPI* RtlSetProcessIsCriticalType)( BOOLEAN bNew, BOOLEAN *pbOld, BOOLEAN bNeedScb); int main() { // カレントプロセスのSE_DEBUG_NAME特権を有効にする if (!util::EnableProcessPrivilege(::GetCurrentProcess(), SE_DEBUG_NAME, true)) { return 1; } RtlSetProcessIsCriticalType RtlSetProcessIsCritical = (RtlSetProcessIsCriticalType)::GetProcAddress( ::GetModuleHandle("ntdll"), "RtlSetProcessIsCritical"); if (!RtlSetProcessIsCritical) { return 1; } BOOLEAN old = FALSE; NTSTATUS status = RtlSetProcessIsCritical(TRUE, &old, FALSE); return 0; }
以上で、Windowsが死ぬ(デバッガを接続していない限り)。やったね!
SE_DEBUG_NAME権限が必要なので挙動としては真っ当なものだけど、あまりにも素直すぎて楽しかったのでちょっと紹介したくなった。
(要するに、この関数で操作されたプロセスが死ぬとWindowsのブレークが発生するようになる関数です。システムプロセスにはこれが設定されているみたい。)
(12/05追記)以下で類似の仕事ができます。
- RtlSetProcessIsCritical
- RtlSetThreadIsCritical
- NtQueryInformationProcess with ProcessCriticalInformation 0x1D
- NtSetInformationThread with ThreadCriticalInformation 0x12