介绍
我们都知道当我们结束掉系统的一个关键进程的时候,电脑会发生蓝屏,比如我们结束掉csrss.exe这个进程的时候。
那么到底是为什么呢?为什么有些关键进程挂了会蓝屏,有些进程挂了反而没事?其实都是因为该进程的一个标志位就是这个”ProcessBreakOnTermination “,通过这个标志这是一个关键进程。同时还有”ThreadBreakOnTermination” 这个标志位,标志这是一个关键线程
有些恶意软件也会利用到这两个标志,当我们把他杀了的时候系统就蓝屏了。很ex的一种操作
相关的api和代码
要用的api其实就是这两个(未导出的api,同时需要有调试权限才能设置为关键进程)
1 2
| NTSTATUS NTAPI RtlSetThreadIsCritical(IN BOOLEAN NewValue,OUT PBOOLEAN OldValue OPTIONAL,IN BOOLEAN NeedBreaks) NTSTATUS NTAPI RtlSetProcessIsCritical (IN BOOLEAN NewValue,OUT PBOOLEAN OldValue OPTIONAL,IN BOOLEAN NeedBreaks);
|
演示代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| #include <stdio.h> #include <windows.h>
bool EnableDebugPrivilege(); bool TestCriticalApi(); typedef NTSTATUS(__cdecl *RTLSETPROCESSISCRITICAL)(IN BOOLEAN NewValue,OUT PBOOLEAN OldValue OPTIONAL,IN BOOLEAN NeedBreaks);
int main(void) { TestCriticalApi(); return 0; }
bool EnableDebugPrivilege() { HANDLE hToken = NULL; LUID debugPrivilegeValueLuid={0}; TOKEN_PRIVILEGES tokenPrivilege = {0};
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) return false;
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &debugPrivilegeValueLuid)) { CloseHandle(hToken); return false; }
tokenPrivilege.PrivilegeCount = 1; tokenPrivilege.Privileges[0].Luid = debugPrivilegeValueLuid; tokenPrivilege.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!AdjustTokenPrivileges(hToken, FALSE, &tokenPrivilege, sizeof(tokenPrivilege), NULL, NULL)) { CloseHandle(hToken); return false; }
return true; }
bool TestCriticalApi() { if(!EnableDebugPrivilege()) return false;
HMODULE hNtdllMod = GetModuleHandle(TEXT("ntdll.dll")); if(!hNtdllMod) return false;
RTLSETPROCESSISCRITICAL RtlSetProcessIsCritical; RtlSetProcessIsCritical = (RTLSETPROCESSISCRITICAL)GetProcAddress(hNtdllMod, "RtlSetProcessIsCritical"); if (!RtlSetProcessIsCritical) return false;
NTSTATUS status = RtlSetProcessIsCritical(TRUE, NULL, FALSE); printf("status:%x\n",status);
getchar();
status = RtlSetProcessIsCritical(FALSE, NULL, FALSE); printf("status:%x\n",status); getchar();
return true; }
|
已经卡死了,在windag这能看见显示为critical process

直接在windag上面看看标志

标志为1,生效了的。