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