27 _In_ HANDLE ProcessHandle,
28 _In_ ACCESS_MASK DesiredAccess,
29 _In_ ULONG HandleAttributes,
31 _Out_ PHANDLE NewProcessHandle
35 _In_ HANDLE ProcessHandle,
36 _In_ HANDLE ThreadHandle,
37 _In_ ACCESS_MASK DesiredAccess,
38 _In_ ULONG HandleAttributes,
40 _Out_ PHANDLE NewThreadHandle
50 typedef struct _TEST_ITEM
65 _In_ HWND ParentWindowHandle,
71 HANDLE debugObjectHandle;
76 ProcessItem->ProcessId
86 MB_ICONWARNING | MB_YESNO,
87 L
"The selected process is currently being debugged, which can prevent it from being terminated. "
88 L
"Do you want to detach the process from its debugger?"
104 PhShowStatus(ParentWindowHandle, L
"Unable to detach the process", status, 0);
107 NtClose(debugObjectHandle);
110 NtClose(processHandle);
122 static PVOID GetExitProcessFunction(
133 static NTSTATUS NTAPI TerminatorTP1(
138 HANDLE processHandle;
147 status = NtTerminateProcess(processHandle, STATUS_SUCCESS);
149 NtClose(processHandle);
155 static NTSTATUS NTAPI TerminatorTP2(
156 _In_ HANDLE ProcessId
160 HANDLE processHandle;
181 NtClose(processHandle);
187 static NTSTATUS NTAPI TerminatorTTGeneric(
188 _In_ HANDLE ProcessId,
190 _In_ BOOLEAN UseKphDangerous
199 return STATUS_NOT_SUPPORTED;
209 return STATUS_INVALID_CID;
227 NtTerminateThread(threadHandle, STATUS_SUCCESS);
229 NtClose(threadHandle);
235 return STATUS_SUCCESS;
238 static NTSTATUS NTAPI TerminatorTT1(
239 _In_ HANDLE ProcessId
242 return TerminatorTTGeneric(ProcessId,
FALSE,
FALSE);
245 static NTSTATUS NTAPI TerminatorTT2(
246 _In_ HANDLE ProcessId
256 exitProcess = GetExitProcessFunction();
266 return STATUS_INVALID_CID;
275 THREAD_GET_CONTEXT | THREAD_SET_CONTEXT,
280 context.ContextFlags = CONTEXT_CONTROL;
282 context.Eip = (ULONG)exitProcess;
285 context.ContextFlags = CONTEXT_CONTROL;
287 context.Rip = (ULONG64)exitProcess;
291 NtClose(threadHandle);
297 return STATUS_SUCCESS;
300 static NTSTATUS NTAPI TerminatorTP1a(
301 _In_ HANDLE ProcessId
306 HANDLE processHandle = NtCurrentProcess();
311 if (!ntGetNextProcess)
312 return STATUS_NOT_SUPPORTED;
323 for (i = 0; i < 1000; i++)
325 HANDLE newProcessHandle;
326 PROCESS_BASIC_INFORMATION basicInfo;
330 if (basicInfo.UniqueProcessId == ProcessId)
345 NtClose(processHandle);
346 processHandle = newProcessHandle;
350 NtClose(processHandle);
358 static NTSTATUS NTAPI TerminatorTT1a(
359 _In_ HANDLE ProcessId
364 HANDLE processHandle;
370 if (!ntGetNextThread)
371 return STATUS_NOT_SUPPORTED;
388 NtClose(processHandle);
392 for (i = 0; i < 1000; i++)
394 HANDLE newThreadHandle;
407 NtClose(threadHandle);
408 threadHandle = newThreadHandle;
412 NtClose(threadHandle);
417 NtClose(processHandle);
423 static NTSTATUS NTAPI TerminatorCH1(
424 _In_ HANDLE ProcessId
428 HANDLE processHandle;
438 for (i = 0; i < 0x1000; i += 4)
447 DUPLICATE_CLOSE_SOURCE
451 NtClose(processHandle);
457 static BOOL CALLBACK DestroyProcessWindowsProc(
464 GetWindowThreadProcessId(hwnd, &processId);
466 if (processId == (ULONG)lParam)
468 PostMessage(hwnd, WM_DESTROY, 0, 0);
474 static NTSTATUS NTAPI TerminatorW1(
475 _In_ HANDLE ProcessId
478 EnumWindows(DestroyProcessWindowsProc, (LPARAM)ProcessId);
479 return STATUS_SUCCESS;
482 static BOOL CALLBACK QuitProcessWindowsProc(
489 GetWindowThreadProcessId(hwnd, &processId);
491 if (processId == (ULONG)lParam)
493 PostMessage(hwnd, WM_QUIT, 0, 0);
499 static NTSTATUS NTAPI TerminatorW2(
500 _In_ HANDLE ProcessId
503 EnumWindows(QuitProcessWindowsProc, (LPARAM)ProcessId);
504 return STATUS_SUCCESS;
507 static BOOL CALLBACK CloseProcessWindowsProc(
514 GetWindowThreadProcessId(hwnd, &processId);
516 if (processId == (ULONG)lParam)
518 PostMessage(hwnd, WM_CLOSE, 0, 0);
524 static NTSTATUS NTAPI TerminatorW3(
525 _In_ HANDLE ProcessId
528 EnumWindows(CloseProcessWindowsProc, (LPARAM)ProcessId);
529 return STATUS_SUCCESS;
532 static NTSTATUS NTAPI TerminatorTJ1(
533 _In_ HANDLE ProcessId
537 HANDLE processHandle;
553 status = NtAssignProcessToJobObject(jobHandle, processHandle);
556 status = NtTerminateJobObject(jobHandle, STATUS_SUCCESS);
561 NtClose(processHandle);
567 static NTSTATUS NTAPI TerminatorTD1(
568 _In_ HANDLE ProcessId
572 HANDLE processHandle;
580 HANDLE debugObjectHandle;
599 NtClose(debugObjectHandle);
602 NtClose(processHandle);
608 static NTSTATUS NTAPI TerminatorTP3(
609 _In_ HANDLE ProcessId
613 HANDLE processHandle;
616 return STATUS_NOT_SUPPORTED;
626 NtClose(processHandle);
632 static NTSTATUS NTAPI TerminatorTT3(
633 _In_ HANDLE ProcessId
636 return TerminatorTTGeneric(ProcessId,
TRUE,
FALSE);
639 static NTSTATUS NTAPI TerminatorTT4(
640 _In_ HANDLE ProcessId
643 return TerminatorTTGeneric(ProcessId,
FALSE,
TRUE);
646 static NTSTATUS NTAPI TerminatorM1(
647 _In_ HANDLE ProcessId
651 HANDLE processHandle;
662 MEMORY_BASIC_INFORMATION basicInfo;
664 pageOfGarbage = NULL;
676 NtClose(processHandle);
677 return STATUS_NO_MEMORY;
680 baseAddress = (PVOID)0;
687 sizeof(MEMORY_BASIC_INFORMATION),
695 if (basicInfo.Type == MEM_PRIVATE)
697 for (i = 0; i < basicInfo.RegionSize; i +=
PAGE_SIZE)
721 NtClose(processHandle);
727 static NTSTATUS NTAPI TerminatorM2(
728 _In_ HANDLE ProcessId
732 HANDLE processHandle;
741 MEMORY_BASIC_INFORMATION basicInfo;
744 baseAddress = (PVOID)0;
751 sizeof(MEMORY_BASIC_INFORMATION),
757 regionSize = basicInfo.RegionSize;
760 &basicInfo.BaseAddress,
768 NtClose(processHandle);
776 { L
"TP1", L
"Terminates the process using NtTerminateProcess", TerminatorTP1 },
777 { L
"TP2", L
"Creates a remote thread in the process which terminates the process", TerminatorTP2 },
778 { L
"TT1", L
"Terminates the process' threads", TerminatorTT1 },
779 { L
"TT2", L
"Modifies the process' threads with contexts which terminate the process", TerminatorTT2 },
780 { L
"TP1a", L
"Terminates the process using NtTerminateProcess (alternative method)", TerminatorTP1a },
781 { L
"TT1a", L
"Terminates the process' threads (alternative method)", TerminatorTT1a },
782 { L
"CH1", L
"Closes the process' handles", TerminatorCH1 },
783 { L
"W1", L
"Sends the WM_DESTROY message to the process' windows", TerminatorW1 },
784 { L
"W2", L
"Sends the WM_QUIT message to the process' windows", TerminatorW2 },
785 { L
"W3", L
"Sends the WM_CLOSE message to the process' windows", TerminatorW3 },
786 { L
"TJ1", L
"Assigns the process to a job object and terminates the job", TerminatorTJ1 },
787 { L
"TD1", L
"Debugs the process and closes the debug object", TerminatorTD1 },
788 { L
"TP3", L
"Terminates the process in kernel-mode", TerminatorTP3 },
789 { L
"TT3", L
"Terminates the process' threads in kernel-mode", TerminatorTT3 },
790 { L
"TT4", L
"Terminates the process' threads using a dangerous kernel-mode method", TerminatorTT4 },
791 { L
"M1", L
"Writes garbage to the process' memory regions", TerminatorM1 },
792 { L
"M2", L
"Sets the page protection of the process' memory regions to PAGE_NOACCESS", TerminatorM2 }
795 static BOOLEAN PhpRunTerminatorTest(
796 _In_ HWND WindowHandle,
805 BOOLEAN success =
FALSE;
806 LARGE_INTEGER interval;
824 L
"The TT4 test may cause the system to crash.",
830 status = testItem->TestProc(processItem->
ProcessId);
832 NtDelayExecution(
FALSE, &interval);
834 if (status == STATUS_NOT_SUPPORTED)
860 UpdateWindow(WindowHandle);
879 HIMAGELIST imageList;
885 L
"Terminator - %s (%u)",
889 SetWindowText(hwndDlg, title->
Buffer);
892 SetProp(hwndDlg, L
"ProcessItem", (HANDLE)processItem);
897 ListView_SetExtendedListViewStyleEx(lvHandle, LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER | LVS_EX_INFOTIP | LVS_EX_LABELTIP | LVS_EX_CHECKBOXES, -1);
900 imageList = ImageList_Create(16, 16, ILC_COLOR32, 0, 0);
901 ImageList_SetImageCount(imageList, 2);
913 PhTerminatorTests[i].Id,
914 &PhTerminatorTests[i]
924 ListView_SetCheckState(lvHandle, itemIndex, check);
927 ListView_SetImageList(lvHandle, imageList, LVSIL_SMALL);
932 L
"Double-click a termination method or click Run Selected."
938 RemoveProp(hwndDlg, L
"ProcessItem");
943 INT
id = LOWORD(wParam);
949 EndDialog(hwndDlg, IDOK);
962 if (ListView_GetCheckState(lvHandle, i))
964 if (PhpRunTerminatorTest(
979 LPNMHDR header = (LPNMHDR)lParam;
983 if (header->code == NM_DBLCLK)
985 LPNMITEMACTIVATE itemActivate = (LPNMITEMACTIVATE)header;
987 if (itemActivate->iItem != -1)
991 PhpRunTerminatorTest(
998 else if (header->code == LVN_ITEMCHANGED)
1001 BOOLEAN oneSelected;
1003 oneSelected =
FALSE;
1007 if (ListView_GetCheckState(header->hwndFrom, i))