add plugins-extra

This commit is contained in:
AirDog46
2025-05-13 19:49:49 +03:00
parent c5fab8aa94
commit 3575d86c17
531 changed files with 70258 additions and 1 deletions

View File

@@ -0,0 +1,2 @@
1.0
* Initial release

View File

@@ -0,0 +1,147 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (Australia) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS
#pragma code_page(1252)
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,0
PRODUCTVERSION 1,0,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "0c0904b0"
BEGIN
VALUE "CompanyName", "dmex"
VALUE "FileDescription", "Terminator plugin for Process Hacker"
VALUE "FileVersion", "1.0"
VALUE "InternalName", "dmex.TerminatorPlugin"
VALUE "LegalCopyright", "Licensed under the GNU GPL, v3."
VALUE "OriginalFilename", "TerminatorPlugin.dll"
VALUE "ProductName", "Terminator plugin for Process Hacker"
VALUE "ProductVersion", "1.0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0xc09, 1200
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_TERMINATOR DIALOGEX 0, 0, 345, 273
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "Terminator"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "Static",IDC_TERMINATOR_TEXT,7,7,331,8
CONTROL "",IDC_TERMINATOR_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,21,331,225
DEFPUSHBUTTON "Run selected",IDC_RUNSELECTED,225,252,59,14
PUSHBUTTON "Close",IDOK,289,252,50,14
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_TERMINATOR, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 338
TOPMARGIN, 7
BOTTOMMARGIN, 266
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// AFX_DIALOG_LAYOUT
//
IDD_TERMINATOR AFX_DIALOG_LAYOUT
BEGIN
0
END
#endif // English (Australia) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{93D93301-3638-4CFA-8F1B-547528023087}</ProjectGuid>
<RootNamespace>TerminatorPlugin</RootNamespace>
<Keyword>Win32Proj</Keyword>
<ProjectName>TerminatorPlugin</ProjectName>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\ExtraPlugins.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\ExtraPlugins.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\ExtraPlugins.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\ExtraPlugins.props" />
</ImportGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Debug32</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release64</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release32</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<TreatWarningAsError>false</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<TreatWarningAsError>false</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<TreatWarningAsError>false</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<TreatWarningAsError>false</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="dialog.c" />
<ClCompile Include="kph2.c" />
<ClCompile Include="kph2data.c" />
<ClCompile Include="phapi.c" />
<ClCompile Include="termator.c" />
<ClCompile Include="main.c" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="TerminatorPlugin.rc" />
</ItemGroup>
<ItemGroup>
<Text Include="CHANGELOG.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="kph2api.h" />
<ClInclude Include="kph2user.h" />
<ClInclude Include="main.h" />
<ClInclude Include="phapi.h" />
<ClInclude Include="resource.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>

View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="termator.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="kph2.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="kph2data.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="phapi.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="dialog.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="TerminatorPlugin.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<Text Include="CHANGELOG.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="main.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="kph2user.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="kph2api.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="phapi.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,359 @@
/*
* Process Hacker Extra Plugins -
* Terminator Plugin
*
* Copyright (C) 2009-2016 wj32
* Copyright (C) 2016 dmex
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "main.h"
#include "kph2user.h"
BOOLEAN ShowKphWarning(
_In_ HWND ParentWindowHandle
)
{
return PhShowMessage(
ParentWindowHandle,
MB_ICONWARNING | MB_YESNO,
L"WARNING WARNING WARNING\r\nYou can be banned by anti-cheat software for using this plugin. "
L"Are you absolutely sure you want to continue?"
) == IDYES;
}
VOID ShowDebugWarning(
_In_ HWND ParentWindowHandle,
_In_ PPH_PROCESS_ITEM ProcessItem
)
{
NTSTATUS status;
HANDLE processHandle;
HANDLE debugObjectHandle;
if (NT_SUCCESS(PhOpenProcess(
&processHandle,
PROCESS_QUERY_INFORMATION | PROCESS_SUSPEND_RESUME,
ProcessItem->ProcessId
)))
{
if (NT_SUCCESS(PhGetProcessDebugObject(
processHandle,
&debugObjectHandle
)))
{
if (PhShowMessage(
ParentWindowHandle,
MB_ICONWARNING | MB_YESNO,
L"The selected process is currently being debugged, which can prevent it from being terminated. "
L"Do you want to detach the process from its debugger?"
) == IDYES)
{
ULONG flags;
// Disable kill-on-close.
flags = 0;
NtSetInformationDebugObject(
debugObjectHandle,
DebugObjectFlags,
&flags,
sizeof(ULONG),
NULL
);
if (!NT_SUCCESS(status = NtRemoveProcessDebug(processHandle, debugObjectHandle)))
PhShowStatus(ParentWindowHandle, L"Unable to detach the process", status, 0);
}
NtClose(debugObjectHandle);
}
NtClose(processHandle);
}
}
VOID InitializeKph2(
VOID
)
{
NTSTATUS status;
PPH_STRING directory;
PPH_STRING path;
PPH_STRING kprocesshackerFileName;
KPH_PARAMETERS parameters;
if (Kph2IsConnected())
return;
directory = PH_AUTO(PhGetApplicationDirectory());
path = PhIsExecutingInWow64() ? PhaCreateString(KPH_PATH32) : PhaCreateString(KPH_PATH64);
kprocesshackerFileName = PH_AUTO(PhConcatStringRef2(&directory->sr, &path->sr));
// Require SeDebugPrivilege for all KPH connections.
parameters.SecurityLevel = KphSecurityPrivilegeCheck;
parameters.CreateDynamicConfiguration = TRUE;
// Install the service
if (NT_SUCCESS(status = Kph2InstallEx(KPH_DEVICE_SHORT_NAME, kprocesshackerFileName->Buffer, &parameters)))
{
if (!NT_SUCCESS(status = Kph2Connect(KPH_DEVICE_NAME)))
{
PhShowStatus(NULL, L"Unable to connect to KProcessHacker2", status, 0);
}
}
else
{
if (WIN32_FROM_NTSTATUS(status) == ERROR_SERVICE_MARKED_FOR_DELETE)
{
if (!NT_SUCCESS(status = Kph2Connect(KPH_DEVICE_NAME)))
{
PhShowStatus(NULL, L"Unable to connect to KProcessHacker2", status, 0);
}
}
else
{
PhShowStatus(NULL, L"Unable to install KProcessHacker2", status, 0);
}
}
}
VOID ShutdownAndDeleteKph2(
VOID
)
{
NTSTATUS status;
if (Kph2IsConnected())
{
if (!NT_SUCCESS(status = Kph2Disconnect()))
{
PhShowStatus(NULL, L"Unable to disconnect KProcessHacker2", status, 0);
}
}
if (!NT_SUCCESS(status = Kph2Uninstall(KPH_DEVICE_SHORT_NAME)))
{
if (WIN32_FROM_NTSTATUS(status) != ERROR_SERVICE_DOES_NOT_EXIST)
{
PhShowStatus(NULL, L"Unable to uninstall KProcessHacker2", status, 0);
}
}
}
INT_PTR CALLBACK PhpProcessTerminatorDlgProc(
_In_ HWND hwndDlg,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
PTERMINATOR_CONTEXT context = NULL;
if (uMsg == WM_INITDIALOG)
{
context = (PTERMINATOR_CONTEXT)PhAllocate(sizeof(TERMINATOR_CONTEXT));
memset(context, 0, sizeof(TERMINATOR_CONTEXT));
context->ProcessItem = (PPH_PROCESS_ITEM)lParam;
SetProp(hwndDlg, L"Context", (HANDLE)context);
}
else
{
context = (PTERMINATOR_CONTEXT)GetProp(hwndDlg, L"Context");
if (uMsg == WM_DESTROY)
{
PhDeleteLayoutManager(&context->LayoutManager);
RemoveProp(hwndDlg, L"Context");
ShutdownAndDeleteKph2();
}
}
if (context == NULL)
return FALSE;
switch (uMsg)
{
case WM_INITDIALOG:
{
HWND lvHandle;
HIMAGELIST imageList;
SetWindowText(hwndDlg, PhaFormatString(
L"Terminator - %s (%u)",
context->ProcessItem->ProcessName->Buffer,
HandleToUlong(context->ProcessItem->ProcessId)
)->Buffer);
PhCenterWindow(hwndDlg, GetParent(hwndDlg));
PhInitializeLayoutManager(&context->LayoutManager, hwndDlg);
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_TERMINATOR_LIST), NULL, PH_ANCHOR_ALL);
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_RUNSELECTED), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT);
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT);
lvHandle = GetDlgItem(hwndDlg, IDC_TERMINATOR_LIST);
PhAddListViewColumn(lvHandle, 0, 0, 0, LVCFMT_LEFT, 70, L"ID");
PhAddListViewColumn(lvHandle, 1, 1, 1, LVCFMT_LEFT, 400, L"Description");
ListView_SetExtendedListViewStyleEx(lvHandle, LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER | LVS_EX_INFOTIP | LVS_EX_LABELTIP | LVS_EX_CHECKBOXES, -1);
PhSetControlTheme(lvHandle, L"explorer");
imageList = ImageList_Create(16, 16, ILC_COLOR32, 0, 0);
ImageList_SetImageCount(imageList, 2);
PhSetImageListBitmap(imageList, 0, (HINSTANCE)NtCurrentPeb()->ImageBaseAddress, MAKEINTRESOURCE(PHAPP_IDB_CROSS));
PhSetImageListBitmap(imageList, 1, (HINSTANCE)NtCurrentPeb()->ImageBaseAddress, MAKEINTRESOURCE(PHAPP_IDB_TICK));
for (ULONG i = 0; i < sizeof(PhTerminatorTests) / sizeof(TEST_ITEM); i++)
{
INT itemIndex;
BOOLEAN check;
itemIndex = PhAddListViewItem(
lvHandle,
MAXINT,
PhTerminatorTests[i].Id,
&PhTerminatorTests[i]
);
PhSetListViewSubItem(lvHandle, itemIndex, 1, PhTerminatorTests[i].Description);
PhSetListViewItemImageIndex(lvHandle, itemIndex, -1);
check = TRUE;
if (PhEqualStringZ(PhTerminatorTests[i].Id, L"M1", FALSE))
check = FALSE;
ListView_SetCheckState(lvHandle, itemIndex, check);
}
ListView_SetImageList(lvHandle, imageList, LVSIL_SMALL);
SetDlgItemText(
hwndDlg,
IDC_TERMINATOR_TEXT,
L"Double-click a termination method or click Run Selected."
);
}
break;
case WM_SIZE:
PhLayoutManagerLayout(&context->LayoutManager);
break;
case WM_COMMAND:
{
INT id = LOWORD(wParam);
switch (id)
{
case IDCANCEL: // Esc and X button to close
case IDOK:
EndDialog(hwndDlg, IDOK);
break;
case IDC_RUNSELECTED:
{
InitializeKph2();
if (PhShowConfirmMessage(hwndDlg, L"run", L"the selected terminator tests", NULL, FALSE))
{
HWND lvHandle;
ULONG i;
lvHandle = GetDlgItem(hwndDlg, IDC_TERMINATOR_LIST);
for (i = 0; i < sizeof(PhTerminatorTests) / sizeof(TEST_ITEM); i++)
{
if (ListView_GetCheckState(lvHandle, i))
{
if (PhpRunTerminatorTest(hwndDlg, context->ProcessItem, i))
{
break;
}
}
}
}
}
break;
}
}
break;
case WM_NOTIFY:
{
LPNMHDR header = (LPNMHDR)lParam;
if (header->hwndFrom == GetDlgItem(hwndDlg, IDC_TERMINATOR_LIST))
{
if (header->code == NM_DBLCLK)
{
LPNMITEMACTIVATE itemActivate = (LPNMITEMACTIVATE)header;
if (itemActivate->iItem != -1)
{
if (PhShowConfirmMessage(hwndDlg, L"run", L"the selected test", NULL, FALSE))
{
InitializeKph2();
PhpRunTerminatorTest(
hwndDlg,
context->ProcessItem,
itemActivate->iItem
);
}
}
}
else if (header->code == LVN_ITEMCHANGED)
{
ULONG i;
BOOLEAN oneSelected;
oneSelected = FALSE;
for (i = 0; i < sizeof(PhTerminatorTests) / sizeof(TEST_ITEM); i++)
{
if (ListView_GetCheckState(header->hwndFrom, i))
{
oneSelected = TRUE;
break;
}
}
EnableWindow(GetDlgItem(hwndDlg, IDC_RUNSELECTED), oneSelected);
}
}
}
break;
}
return FALSE;
}
VOID PhShowProcessTerminatorDialog(
_In_ HWND ParentWindowHandle,
_In_ PPH_PROCESS_ITEM ProcessItem
)
{
if (!ShowKphWarning(ParentWindowHandle))
return;
ShowDebugWarning(ParentWindowHandle, ProcessItem);
DialogBoxParam(
PluginInstance->DllBase,
MAKEINTRESOURCE(IDD_TERMINATOR),
NULL,
PhpProcessTerminatorDlgProc,
(LPARAM)ProcessItem
);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,215 @@
#ifndef _KPHAPI_H
#define _KPHAPI_H
// This file contains KProcessHacker definitions shared across kernel-mode and user-mode.
// Process information
typedef enum _KPH_PROCESS_INFORMATION_CLASS
{
KphProcessProtectionInformation = 1, // q: KPH_PROCESS_PROTECTION_INFORMATION
KphProcessExecuteFlags = 2, // s: ULONG
KphProcessIoPriority = 3, // qs: ULONG
MaxKphProcessInfoClass
} KPH_PROCESS_INFORMATION_CLASS;
typedef struct _KPH_PROCESS_PROTECTION_INFORMATION
{
BOOLEAN IsProtectedProcess;
} KPH_PROCESS_PROTECTION_INFORMATION, *PKPH_PROCESS_PROTECTION_INFORMATION;
// Thread information
typedef enum _KPH_THREAD_INFORMATION_CLASS
{
KphThreadWin32Thread = 1, // q: PVOID
KphThreadImpersonationToken = 2, // s: HANDLE
KphThreadIoPriority = 3, // qs: ULONG
MaxKphThreadInfoClass
} KPH_THREAD_INFORMATION_CLASS;
// Process handle information
typedef struct _KPH_PROCESS_HANDLE
{
HANDLE Handle;
PVOID Object;
ACCESS_MASK GrantedAccess;
USHORT ObjectTypeIndex;
USHORT Reserved1;
ULONG HandleAttributes;
ULONG Reserved2;
} KPH_PROCESS_HANDLE, *PKPH_PROCESS_HANDLE;
typedef struct _KPH_PROCESS_HANDLE_INFORMATION
{
ULONG HandleCount;
KPH_PROCESS_HANDLE Handles[1];
} KPH_PROCESS_HANDLE_INFORMATION, *PKPH_PROCESS_HANDLE_INFORMATION;
// Object information
typedef enum _KPH_OBJECT_INFORMATION_CLASS
{
KphObjectBasicInformation, // q: OBJECT_BASIC_INFORMATION
KphObjectNameInformation, // q: OBJECT_NAME_INFORMATION
KphObjectTypeInformation, // q: OBJECT_TYPE_INFORMATION
KphObjectHandleFlagInformation, // qs: OBJECT_HANDLE_FLAG_INFORMATION
KphObjectProcessBasicInformation, // q: PROCESS_BASIC_INFORMATION
KphObjectThreadBasicInformation, // q: THREAD_BASIC_INFORMATION
KphObjectEtwRegBasicInformation, // q: ETWREG_BASIC_INFORMATION
KphObjectFileObjectInformation, // q: KPH_FILE_OBJECT_INFORMATION
KphObjectFileObjectDriver, // q: KPH_FILE_OBJECT_DRIVER
MaxKphObjectInfoClass
} KPH_OBJECT_INFORMATION_CLASS;
typedef struct _KPH_FILE_OBJECT_INFORMATION
{
BOOLEAN LockOperation;
BOOLEAN DeletePending;
BOOLEAN ReadAccess;
BOOLEAN WriteAccess;
BOOLEAN DeleteAccess;
BOOLEAN SharedRead;
BOOLEAN SharedWrite;
BOOLEAN SharedDelete;
LARGE_INTEGER CurrentByteOffset;
ULONG Flags;
} KPH_FILE_OBJECT_INFORMATION, *PKPH_FILE_OBJECT_INFORMATION;
typedef struct _KPH_FILE_OBJECT_DRIVER
{
HANDLE DriverHandle;
} KPH_FILE_OBJECT_DRIVER, *PKPH_FILE_OBJECT_DRIVER;
// Driver information
typedef enum _DRIVER_INFORMATION_CLASS
{
DriverBasicInformation,
DriverNameInformation,
DriverServiceKeyNameInformation,
MaxDriverInfoClass
} DRIVER_INFORMATION_CLASS;
typedef struct _DRIVER_BASIC_INFORMATION
{
ULONG Flags;
PVOID DriverStart;
ULONG DriverSize;
} DRIVER_BASIC_INFORMATION, *PDRIVER_BASIC_INFORMATION;
typedef struct _DRIVER_NAME_INFORMATION
{
UNICODE_STRING DriverName;
} DRIVER_NAME_INFORMATION, *PDRIVER_NAME_INFORMATION;
typedef struct _DRIVER_SERVICE_KEY_NAME_INFORMATION
{
UNICODE_STRING ServiceKeyName;
} DRIVER_SERVICE_KEY_NAME_INFORMATION, *PDRIVER_SERVICE_KEY_NAME_INFORMATION;
// ETW registration object information
typedef struct _ETWREG_BASIC_INFORMATION
{
GUID Guid;
ULONG_PTR SessionId;
} ETWREG_BASIC_INFORMATION, *PETWREG_BASIC_INFORMATION;
// Device
#define KPH_DEVICE_SHORT_NAME L"KProcessHacker2"
#define KPH_DEVICE_TYPE 0x9999
#define KPH_DEVICE_NAME (L"\\Device\\" KPH_DEVICE_SHORT_NAME)
// Parameters
typedef enum _KPH_SECURITY_LEVEL
{
KphSecurityNone = 0, // all clients are allowed
KphSecurityPrivilegeCheck = 1, // require SeDebugPrivilege
KphMaxSecurityLevel
} KPH_SECURITY_LEVEL, *PKPH_SECURITY_LEVEL;
typedef struct _KPH_DYN_STRUCT_DATA
{
SHORT EgeGuid;
SHORT EpObjectTable;
SHORT Reserved0;
SHORT Reserved1;
SHORT EpRundownProtect;
SHORT EreGuidEntry;
SHORT HtHandleContentionEvent;
SHORT OtName;
SHORT OtIndex;
SHORT ObDecodeShift;
SHORT ObAttributesShift;
} KPH_DYN_STRUCT_DATA, *PKPH_DYN_STRUCT_DATA;
typedef struct _KPH_DYN_PACKAGE
{
USHORT MajorVersion;
USHORT MinorVersion;
USHORT ServicePackMajor; // -1 to ignore
USHORT BuildNumber; // -1 to ignore
ULONG ResultingNtVersion; // PHNT_*
KPH_DYN_STRUCT_DATA StructData;
} KPH_DYN_PACKAGE, *PKPH_DYN_PACKAGE;
#define KPH_DYN_CONFIGURATION_VERSION 2
#define KPH_DYN_MAXIMUM_PACKAGES 64
typedef struct _KPH_DYN_CONFIGURATION
{
ULONG Version;
ULONG NumberOfPackages;
KPH_DYN_PACKAGE Packages[1];
} KPH_DYN_CONFIGURATION, *PKPH_DYN_CONFIGURATION;
// Features
// No features defined.
// Control codes
#define KPH_CTL_CODE(x) CTL_CODE(KPH_DEVICE_TYPE, 0x800 + x, METHOD_NEITHER, FILE_ANY_ACCESS)
// General
#define KPH_GETFEATURES KPH_CTL_CODE(0)
// Processes
#define KPH_OPENPROCESS KPH_CTL_CODE(50)
#define KPH_OPENPROCESSTOKEN KPH_CTL_CODE(51)
#define KPH_OPENPROCESSJOB KPH_CTL_CODE(52)
#define KPH_SUSPENDPROCESS KPH_CTL_CODE(53)
#define KPH_RESUMEPROCESS KPH_CTL_CODE(54)
#define KPH_TERMINATEPROCESS KPH_CTL_CODE(55)
#define KPH_READVIRTUALMEMORY KPH_CTL_CODE(56)
#define KPH_WRITEVIRTUALMEMORY KPH_CTL_CODE(57)
#define KPH_READVIRTUALMEMORYUNSAFE KPH_CTL_CODE(58)
#define KPH_QUERYINFORMATIONPROCESS KPH_CTL_CODE(59)
#define KPH_SETINFORMATIONPROCESS KPH_CTL_CODE(60)
// Threads
#define KPH_OPENTHREAD KPH_CTL_CODE(100)
#define KPH_OPENTHREADPROCESS KPH_CTL_CODE(101)
#define KPH_TERMINATETHREAD KPH_CTL_CODE(102)
#define KPH_TERMINATETHREADUNSAFE KPH_CTL_CODE(103)
#define KPH_GETCONTEXTTHREAD KPH_CTL_CODE(104)
#define KPH_SETCONTEXTTHREAD KPH_CTL_CODE(105)
#define KPH_CAPTURESTACKBACKTRACETHREAD KPH_CTL_CODE(106)
#define KPH_QUERYINFORMATIONTHREAD KPH_CTL_CODE(107)
#define KPH_SETINFORMATIONTHREAD KPH_CTL_CODE(108)
// Handles
#define KPH_ENUMERATEPROCESSHANDLES KPH_CTL_CODE(150)
#define KPH_QUERYINFORMATIONOBJECT KPH_CTL_CODE(151)
#define KPH_SETINFORMATIONOBJECT KPH_CTL_CODE(152)
#define KPH_DUPLICATEOBJECT KPH_CTL_CODE(153)
// Misc.
#define KPH_OPENDRIVER KPH_CTL_CODE(200)
#define KPH_QUERYINFORMATIONDRIVER KPH_CTL_CODE(201)
#endif

View File

@@ -0,0 +1,261 @@
/*
* Process Hacker -
* KProcessHacker dynamic data definitions
*
* Copyright (C) 2011-2013 wj32
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "main.h"
#include "kph2user.h"
#ifdef _WIN64
ULONG Kphp2GetKernelRevisionNumber(
VOID
)
{
ULONG result;
PPH_STRING kernelFileName;
PVOID versionInfo;
VS_FIXEDFILEINFO *rootBlock;
ULONG rootBlockLength;
result = 0;
kernelFileName = PhGetKernelFileName();
PhMoveReference(&kernelFileName, PhGetFileName(kernelFileName));
versionInfo = PhGetFileVersionInfo(kernelFileName->Buffer);
PhDereferenceObject(kernelFileName);
if (versionInfo && VerQueryValue(versionInfo, L"\\", &rootBlock, &rootBlockLength) && rootBlockLength != 0)
result = rootBlock->dwFileVersionLS & 0xffff;
PhFree(versionInfo);
return result;
}
NTSTATUS Kph2InitializeDynamicPackage(
_Out_ PKPH_DYN_PACKAGE Package
)
{
ULONG majorVersion, minorVersion, servicePack, buildNumber;
majorVersion = PhOsVersion.dwMajorVersion;
minorVersion = PhOsVersion.dwMinorVersion;
servicePack = PhOsVersion.wServicePackMajor;
buildNumber = PhOsVersion.dwBuildNumber;
memset(&Package->StructData, -1, sizeof(KPH_DYN_STRUCT_DATA));
Package->MajorVersion = (USHORT)majorVersion;
Package->MinorVersion = (USHORT)minorVersion;
Package->ServicePackMajor = (USHORT)servicePack;
Package->BuildNumber = -1;
// Windows Vista, Windows Server 2008
if (majorVersion == 6 && minorVersion == 0)
{
Package->ResultingNtVersion = PHNT_VISTA;
if (servicePack == 0)
{
Package->StructData.OtName = 0x78;
Package->StructData.OtIndex = 0x90;
}
else if (servicePack == 1)
{
Package->StructData.OtName = 0x10;
Package->StructData.OtIndex = 0x28;
}
else if (servicePack == 2)
{
Package->StructData.OtName = 0x10;
Package->StructData.OtIndex = 0x28;
}
else
{
return STATUS_NOT_SUPPORTED;
}
Package->StructData.EgeGuid = 0x14;
Package->StructData.EpObjectTable = 0x160;
Package->StructData.EpRundownProtect = 0xd8;
Package->StructData.EreGuidEntry = 0x10;
}
// Windows 7, Windows Server 2008 R2
else if (majorVersion == 6 && minorVersion == 1)
{
ULONG revisionNumber = Kphp2GetKernelRevisionNumber();
Package->ResultingNtVersion = PHNT_WIN7;
if (servicePack == 0)
{
}
else if (servicePack == 1)
{
}
else
{
return STATUS_NOT_SUPPORTED;
}
Package->StructData.EgeGuid = 0x14;
Package->StructData.EpObjectTable = 0x200;
Package->StructData.EpRundownProtect = 0x178;
Package->StructData.EreGuidEntry = revisionNumber >= 19160 ? 0x20 : 0x10;
Package->StructData.OtName = 0x10;
Package->StructData.OtIndex = 0x28; // now only a UCHAR, not a ULONG
}
// Windows 8, Windows Server 2012
else if (majorVersion == 6 && minorVersion == 2 && buildNumber == 9200)
{
Package->BuildNumber = 9200;
Package->ResultingNtVersion = PHNT_WIN8;
Package->StructData.EgeGuid = 0x14;
Package->StructData.EpObjectTable = 0x408;
Package->StructData.EpRundownProtect = 0x2d8;
Package->StructData.EreGuidEntry = 0x10;
Package->StructData.HtHandleContentionEvent = 0x30;
Package->StructData.OtName = 0x10;
Package->StructData.OtIndex = 0x28;
Package->StructData.ObDecodeShift = 19;
Package->StructData.ObAttributesShift = 20;
}
// Windows 8.1, Windows Server 2012 R2
else if (majorVersion == 6 && minorVersion == 3 && buildNumber == 9600)
{
ULONG revisionNumber = Kphp2GetKernelRevisionNumber();
Package->BuildNumber = 9600;
Package->ResultingNtVersion = PHNT_WINBLUE;
Package->StructData.EgeGuid = 0x18;
Package->StructData.EpObjectTable = 0x408;
Package->StructData.EpRundownProtect = 0x2d8;
Package->StructData.EreGuidEntry = revisionNumber >= 17736 ? 0x20 : 0x10;
Package->StructData.HtHandleContentionEvent = 0x30;
Package->StructData.OtName = 0x10;
Package->StructData.OtIndex = 0x28;
Package->StructData.ObDecodeShift = 16;
Package->StructData.ObAttributesShift = 17;
}
// Windows 10
else if (majorVersion == 10 && minorVersion == 0 && buildNumber == 10240)
{
Package->BuildNumber = 10240;
Package->ResultingNtVersion = PHNT_THRESHOLD;
Package->StructData.EgeGuid = 0x18;
Package->StructData.EpObjectTable = 0x418;
Package->StructData.EreGuidEntry = 0x20;
Package->StructData.HtHandleContentionEvent = 0x30;
Package->StructData.OtName = 0x10;
Package->StructData.OtIndex = 0x28;
Package->StructData.ObDecodeShift = 16;
Package->StructData.ObAttributesShift = 17;
}
else if (majorVersion == 10 && minorVersion == 0 && buildNumber == 10586)
{
Package->BuildNumber = 10586;
Package->ResultingNtVersion = PHNT_THRESHOLD2;
Package->StructData.EgeGuid = 0x18;
Package->StructData.EpObjectTable = 0x418;
Package->StructData.EreGuidEntry = 0x20;
Package->StructData.HtHandleContentionEvent = 0x30;
Package->StructData.OtName = 0x10;
Package->StructData.OtIndex = 0x28;
Package->StructData.ObDecodeShift = 16;
Package->StructData.ObAttributesShift = 17;
}
else if (majorVersion == 10 && minorVersion == 0 && buildNumber == 14393)
{
Package->BuildNumber = 14393;
Package->ResultingNtVersion = PHNT_THRESHOLD2;
Package->StructData.EgeGuid = 0x18;
Package->StructData.EpObjectTable = 0x418;
Package->StructData.EreGuidEntry = 0x20;
Package->StructData.HtHandleContentionEvent = 0x30;
Package->StructData.OtName = 0x10;
Package->StructData.OtIndex = 0x28;
Package->StructData.ObDecodeShift = 16;
Package->StructData.ObAttributesShift = 17;
}
else
{
return STATUS_NOT_SUPPORTED;
}
return STATUS_SUCCESS;
}
#else
NTSTATUS Kph2InitializeDynamicPackage(
_Out_ PKPH_DYN_PACKAGE Package
)
{
ULONG majorVersion, minorVersion, servicePack, buildNumber;
majorVersion = PhOsVersion.dwMajorVersion;
minorVersion = PhOsVersion.dwMinorVersion;
servicePack = PhOsVersion.wServicePackMajor;
buildNumber = PhOsVersion.dwBuildNumber;
memset(&Package->StructData, -1, sizeof(KPH_DYN_STRUCT_DATA));
Package->MajorVersion = (USHORT)majorVersion;
Package->MinorVersion = (USHORT)minorVersion;
Package->ServicePackMajor = (USHORT)servicePack;
Package->BuildNumber = -1;
// Windows 10
if (majorVersion == 10 && minorVersion == 0 && buildNumber == 10240)
{
Package->BuildNumber = 10240;
Package->ResultingNtVersion = PHNT_THRESHOLD;
Package->StructData.EgeGuid = 0xc;
Package->StructData.EpObjectTable = 0x154;
Package->StructData.EreGuidEntry = 0x10;
Package->StructData.OtName = 0x8;
Package->StructData.OtIndex = 0x14;
}
else if (majorVersion == 10 && minorVersion == 0 && buildNumber == 10586)
{
Package->BuildNumber = 10586;
Package->ResultingNtVersion = PHNT_THRESHOLD;
Package->StructData.EgeGuid = 0xc;
Package->StructData.EpObjectTable = 0x154;
Package->StructData.EreGuidEntry = 0x10;
Package->StructData.OtName = 0x8;
Package->StructData.OtIndex = 0x14;
}
else
{
return STATUS_NOT_SUPPORTED;
}
return STATUS_SUCCESS;
}
#endif

View File

@@ -0,0 +1,327 @@
#ifndef _PH_KPHUSER_H
#define _PH_KPHUSER_H
#include "kph2api.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _KPH_PARAMETERS
{
KPH_SECURITY_LEVEL SecurityLevel;
BOOLEAN CreateDynamicConfiguration;
} KPH_PARAMETERS, *PKPH_PARAMETERS;
NTSTATUS
NTAPI
Kph2Connect(
_In_opt_ PWSTR DeviceName
);
NTSTATUS
NTAPI
Kph2Connect2(
_In_opt_ PWSTR DeviceName,
_In_ PWSTR FileName
);
NTSTATUS
NTAPI
Kph2Connect2Ex(
_In_opt_ PWSTR DeviceName,
_In_ PWSTR FileName,
_In_opt_ PKPH_PARAMETERS Parameters
);
NTSTATUS
NTAPI
Kph2Disconnect(
VOID
);
BOOLEAN
NTAPI
Kph2IsConnected(
VOID
);
NTSTATUS
NTAPI
Kph2SetParameters(
_In_opt_ PWSTR DeviceName,
_In_ PKPH_PARAMETERS Parameters
);
NTSTATUS
NTAPI
Kph2Install(
_In_opt_ PWSTR DeviceName,
_In_ PWSTR FileName
);
NTSTATUS
NTAPI
Kph2InstallEx(
_In_opt_ PWSTR DeviceName,
_In_ PWSTR FileName,
_In_opt_ PKPH_PARAMETERS Parameters
);
NTSTATUS
NTAPI
Kph2Uninstall(
_In_opt_ PWSTR DeviceName
);
NTSTATUS
NTAPI
Kph2GetFeatures(
_Out_ PULONG Features
);
NTSTATUS
NTAPI
Kph2OpenProcess(
_Out_ PHANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ PCLIENT_ID ClientId
);
NTSTATUS
NTAPI
Kph2OpenProcessToken(
_In_ HANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
_Out_ PHANDLE TokenHandle
);
NTSTATUS
NTAPI
Kph2OpenProcessJob(
_In_ HANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
_Out_ PHANDLE JobHandle
);
NTSTATUS
NTAPI
Kph2SuspendProcess(
_In_ HANDLE ProcessHandle
);
NTSTATUS
NTAPI
Kph2ResumeProcess(
_In_ HANDLE ProcessHandle
);
NTSTATUS
NTAPI
Kph2TerminateProcess(
_In_ HANDLE ProcessHandle,
_In_ NTSTATUS ExitStatus
);
NTSTATUS
NTAPI
Kph2ReadVirtualMemory(
_In_ HANDLE ProcessHandle,
_In_ PVOID BaseAddress,
_Out_writes_bytes_(BufferSize) PVOID Buffer,
_In_ SIZE_T BufferSize,
_Out_opt_ PSIZE_T NumberOfBytesRead
);
NTSTATUS
NTAPI
Kph2WriteVirtualMemory(
_In_ HANDLE ProcessHandle,
_In_opt_ PVOID BaseAddress,
_In_reads_bytes_(BufferSize) PVOID Buffer,
_In_ SIZE_T BufferSize,
_Out_opt_ PSIZE_T NumberOfBytesWritten
);
NTSTATUS
NTAPI
Kph2ReadVirtualMemoryUnsafe(
_In_opt_ HANDLE ProcessHandle,
_In_ PVOID BaseAddress,
_Out_writes_bytes_(BufferSize) PVOID Buffer,
_In_ SIZE_T BufferSize,
_Out_opt_ PSIZE_T NumberOfBytesRead
);
NTSTATUS
NTAPI
Kph2QueryInformationProcess(
_In_ HANDLE ProcessHandle,
_In_ KPH_PROCESS_INFORMATION_CLASS ProcessInformationClass,
_Out_writes_bytes_(ProcessInformationLength) PVOID ProcessInformation,
_In_ ULONG ProcessInformationLength,
_Out_opt_ PULONG ReturnLength
);
NTSTATUS
NTAPI
Kph2SetInformationProcess(
_In_ HANDLE ProcessHandle,
_In_ KPH_PROCESS_INFORMATION_CLASS ProcessInformationClass,
_In_reads_bytes_(ProcessInformationLength) PVOID ProcessInformation,
_In_ ULONG ProcessInformationLength
);
NTSTATUS
NTAPI
Kph2OpenThread(
_Out_ PHANDLE ThreadHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ PCLIENT_ID ClientId
);
NTSTATUS
NTAPI
Kph2OpenThreadProcess(
_In_ HANDLE ThreadHandle,
_In_ ACCESS_MASK DesiredAccess,
_Out_ PHANDLE ProcessHandle
);
NTSTATUS
NTAPI
Kph2TerminateThread(
_In_ HANDLE ThreadHandle,
_In_ NTSTATUS ExitStatus
);
NTSTATUS
NTAPI
Kph2TerminateThreadUnsafe(
_In_ HANDLE ThreadHandle,
_In_ NTSTATUS ExitStatus
);
NTSTATUS
NTAPI
Kph2GetContextThread(
_In_ HANDLE ThreadHandle,
_Inout_ PCONTEXT ThreadContext
);
NTSTATUS
NTAPI
Kph2SetContextThread(
_In_ HANDLE ThreadHandle,
_In_ PCONTEXT ThreadContext
);
NTSTATUS
NTAPI
Kph2CaptureStackBackTraceThread(
_In_ HANDLE ThreadHandle,
_In_ ULONG FramesToSkip,
_In_ ULONG FramesToCapture,
_Out_writes_(FramesToCapture) PVOID *BackTrace,
_Out_opt_ PULONG CapturedFrames,
_Out_opt_ PULONG BackTraceHash
);
NTSTATUS
NTAPI
Kph2QueryInformationThread(
_In_ HANDLE ThreadHandle,
_In_ KPH_THREAD_INFORMATION_CLASS ThreadInformationClass,
_Out_writes_bytes_(ThreadInformationLength) PVOID ThreadInformation,
_In_ ULONG ThreadInformationLength,
_Out_opt_ PULONG ReturnLength
);
NTSTATUS
NTAPI
Kph2SetInformationThread(
_In_ HANDLE ThreadHandle,
_In_ KPH_THREAD_INFORMATION_CLASS ThreadInformationClass,
_In_reads_bytes_(ThreadInformationLength) PVOID ThreadInformation,
_In_ ULONG ThreadInformationLength
);
NTSTATUS
NTAPI
Kph2EnumerateProcessHandles(
_In_ HANDLE ProcessHandle,
_Out_writes_bytes_(BufferLength) PVOID Buffer,
_In_opt_ ULONG BufferLength,
_Out_opt_ PULONG ReturnLength
);
NTSTATUS
NTAPI
Kph2EnumerateProcessHandles2(
_In_ HANDLE ProcessHandle,
_Out_ PKPH_PROCESS_HANDLE_INFORMATION *Handles
);
NTSTATUS
NTAPI
Kph2QueryInformationObject(
_In_ HANDLE ProcessHandle,
_In_ HANDLE Handle,
_In_ KPH_OBJECT_INFORMATION_CLASS ObjectInformationClass,
_Out_writes_bytes_(ObjectInformationLength) PVOID ObjectInformation,
_In_ ULONG ObjectInformationLength,
_Out_opt_ PULONG ReturnLength
);
NTSTATUS
NTAPI
Kph2SetInformationObject(
_In_ HANDLE ProcessHandle,
_In_ HANDLE Handle,
_In_ KPH_OBJECT_INFORMATION_CLASS ObjectInformationClass,
_In_reads_bytes_(ObjectInformationLength) PVOID ObjectInformation,
_In_ ULONG ObjectInformationLength
);
NTSTATUS
NTAPI
Kph2DuplicateObject(
_In_ HANDLE SourceProcessHandle,
_In_ HANDLE SourceHandle,
_In_opt_ HANDLE TargetProcessHandle,
_Out_opt_ PHANDLE TargetHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ ULONG HandleAttributes,
_In_ ULONG Options
);
NTSTATUS
NTAPI
Kph2OpenDriver(
_Out_ PHANDLE DriverHandle,
_In_ POBJECT_ATTRIBUTES ObjectAttributes
);
NTSTATUS
NTAPI
Kph2QueryInformationDriver(
_In_ HANDLE DriverHandle,
_In_ DRIVER_INFORMATION_CLASS DriverInformationClass,
_Out_writes_bytes_(DriverInformationLength) PVOID DriverInformation,
_In_ ULONG DriverInformationLength,
_Out_opt_ PULONG ReturnLength
);
// kphdata
NTSTATUS
NTAPI
Kph2InitializeDynamicPackage(
_Out_ PKPH_DYN_PACKAGE Package
);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,105 @@
/*
* Process Hacker Extra Plugins -
* Terminator Plugin
*
* Copyright (C) 2016 dmex
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "main.h"
PPH_PLUGIN PluginInstance;
static PH_CALLBACK_REGISTRATION MenuItemCallbackRegistration;
static PH_CALLBACK_REGISTRATION ProcessMenuInitializingCallbackRegistration;
VOID MenuItemCallback(
_In_opt_ PVOID Parameter,
_In_opt_ PVOID Context
)
{
PPH_PLUGIN_MENU_ITEM menuItem = Parameter;
switch (menuItem->Id)
{
case TERMINATOR_MENU_ITEM:
{
PhShowProcessTerminatorDialog(menuItem->OwnerWindow, menuItem->Context);
}
break;
}
}
VOID NTAPI ProcessMenuInitializingCallback(
_In_opt_ PVOID Parameter,
_In_opt_ PVOID Context
)
{
PPH_PLUGIN_MENU_INFORMATION menuInfo = Parameter;
PPH_EMENU_ITEM miscMenuItem;
PPH_EMENU_ITEM terminatorMenuItem;
PPH_PROCESS_ITEM processItem;
miscMenuItem = PhFindEMenuItem(menuInfo->Menu, 0, L"Miscellaneous", 0);
if (!miscMenuItem)
return;
processItem = menuInfo->u.Process.NumberOfProcesses == 1 ? menuInfo->u.Process.Processes[0] : NULL;
terminatorMenuItem = PhPluginCreateEMenuItem(PluginInstance, 0, TERMINATOR_MENU_ITEM, L"Terminator", processItem);
PhInsertEMenuItem(miscMenuItem, terminatorMenuItem, -1);
if (!PhGetOwnTokenAttributes().Elevated || !processItem)
{
terminatorMenuItem->Flags |= PH_EMENU_DISABLED;
}
}
LOGICAL DllMain(
_In_ HINSTANCE Instance,
_In_ ULONG Reason,
_Reserved_ PVOID Reserved
)
{
if (Reason == DLL_PROCESS_ATTACH)
{
PPH_PLUGIN_INFORMATION info;
PluginInstance = PhRegisterPlugin(PLUGIN_NAME, Instance, &info);
if (!PluginInstance)
return FALSE;
info->DisplayName = L"Terminator";
info->Description = L"Terminator";
info->Author = L"dmex";
PhRegisterCallback(
PhGetPluginCallback(PluginInstance, PluginCallbackMenuItem),
MenuItemCallback,
NULL,
&MenuItemCallbackRegistration
);
PhRegisterCallback(
PhGetGeneralCallback(GeneralCallbackProcessMenuInitializing),
ProcessMenuInitializingCallback,
NULL,
&ProcessMenuInitializingCallbackRegistration
);
}
return TRUE;
}

View File

@@ -0,0 +1,71 @@
/*
* Process Hacker Extra Plugins -
* Terminator Plugin
*
* Copyright (C) 2016 dmex
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _T_H_
#define _T_H_
#define PLUGIN_NAME L"dmex.TerminatorPlugin"
#define KPH_PATH32 L"plugins\\kph2\\kprocesshacker2_x32.sys"
#define KPH_PATH64 L"plugins\\kph2\\kprocesshacker2_x64.sys"
#define TERMINATOR_MENU_ITEM 1
#define CINTERFACE
#define COBJMACROS
#include <phdk.h>
#include <phappresource.h>
#include <windowsx.h>
#include "resource.h"
typedef struct _TERMINATOR_CONTEXT
{
HWND WindowHandle;
PH_LAYOUT_MANAGER LayoutManager;
PPH_PROCESS_ITEM ProcessItem;
} TERMINATOR_CONTEXT, *PTERMINATOR_CONTEXT;
typedef NTSTATUS (NTAPI *PTEST_PROC)(
_In_ HANDLE ProcessId
);
typedef struct _TEST_ITEM
{
PWSTR Id;
PWSTR Description;
PTEST_PROC TestProc;
} TEST_ITEM, *PTEST_ITEM;
extern PPH_PLUGIN PluginInstance;
extern TEST_ITEM PhTerminatorTests[16];
VOID PhShowProcessTerminatorDialog(
_In_ HWND ParentWindowHandle,
_In_ PPH_PROCESS_ITEM ProcessItem
);
BOOLEAN PhpRunTerminatorTest(
_In_ HWND WindowHandle,
_In_ PPH_PROCESS_ITEM ProcessItem,
_In_ INT Index
);
#endif _T_H_

View File

@@ -0,0 +1,297 @@
/*
* Process Hacker Extra Plugins -
* Terminator Plugin
*
* Copyright (C) 2009-2016 wj32
* Copyright (C) 2016 dmex
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "main.h"
#include "kph2user.h"
/**
* Opens a process.
*
* \param ProcessHandle A variable which receives a handle to the process.
* \param DesiredAccess The desired access to the process.
* \param ProcessId The ID of the process.
*/
NTSTATUS Ph2OpenProcess(
_Out_ PHANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ HANDLE ProcessId
)
{
CLIENT_ID clientId;
clientId.UniqueProcess = ProcessId;
clientId.UniqueThread = NULL;
if (Kph2IsConnected())
{
return Kph2OpenProcess(
ProcessHandle,
DesiredAccess,
&clientId
);
}
else
{
return PhOpenProcess(
ProcessHandle,
DesiredAccess,
ProcessId
);
}
}
/**
* Opens a thread.
*
* \param ThreadHandle A variable which receives a handle to the thread.
* \param DesiredAccess The desired access to the thread.
* \param ThreadId The ID of the thread.
*/
NTSTATUS Ph2OpenThread(
_Out_ PHANDLE ThreadHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ HANDLE ThreadId
)
{
CLIENT_ID clientId;
clientId.UniqueProcess = NULL;
clientId.UniqueThread = ThreadId;
if (Kph2IsConnected())
{
return Kph2OpenThread(
ThreadHandle,
DesiredAccess,
&clientId
);
}
else
{
return PhOpenThread(
ThreadHandle,
DesiredAccess,
ThreadId
);
}
}
/**
* Duplicates a handle.
*
* \param SourceProcessHandle A handle to the source process. The handle must have
* PROCESS_DUP_HANDLE access.
* \param SourceHandle The handle to duplicate from the source process.
* \param TargetProcessHandle A handle to the target process. If DUPLICATE_CLOSE_SOURCE is specified
* in the \a Options parameter, this parameter can be NULL.
* \param TargetHandle A variable which receives the new handle in the target process. If
* DUPLICATE_CLOSE_SOURCE is specified in the \a Options parameter, this parameter can be NULL.
* \param DesiredAccess The desired access to the object referenced by the source handle.
* \param HandleAttributes The attributes to apply to the new handle.
* \param Options The options to use when duplicating the handle.
*/
NTSTATUS Ph2DuplicateObject(
_In_ HANDLE SourceProcessHandle,
_In_ HANDLE SourceHandle,
_In_opt_ HANDLE TargetProcessHandle,
_Out_opt_ PHANDLE TargetHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ ULONG HandleAttributes,
_In_ ULONG Options
)
{
NTSTATUS status;
if (Kph2IsConnected())
{
status = Kph2DuplicateObject(
SourceProcessHandle,
SourceHandle,
TargetProcessHandle,
TargetHandle,
DesiredAccess,
HandleAttributes,
Options
);
// If KPH couldn't duplicate the handle, pass through to NtDuplicateObject. This is for
// special objects like ALPC ports.
if (status != STATUS_NOT_SUPPORTED)
return status;
}
return NtDuplicateObject(
SourceProcessHandle,
SourceHandle,
TargetProcessHandle,
TargetHandle,
DesiredAccess,
HandleAttributes,
Options
);
}
/**
* Terminates a thread.
*
* \param ThreadHandle A handle to a thread. The handle must have THREAD_TERMINATE access.
* \param ExitStatus A status value that indicates why the thread is being terminated.
*/
NTSTATUS Ph2TerminateThread(
_In_ HANDLE ThreadHandle,
_In_ NTSTATUS ExitStatus
)
{
#ifndef _WIN64
NTSTATUS status;
if (Kph2IsConnected())
{
status = Kph2TerminateThread(
ThreadHandle,
ExitStatus
);
if (status != STATUS_NOT_SUPPORTED)
return status;
}
#endif
return NtTerminateThread(
ThreadHandle,
ExitStatus
);
}
/**
* Gets the processor context of a thread.
*
* \param ThreadHandle A handle to a thread. The handle must have THREAD_GET_CONTEXT access.
* \param Context A variable which receives the context structure.
*/
NTSTATUS Ph2GetThreadContext(
_In_ HANDLE ThreadHandle,
_Inout_ PCONTEXT Context
)
{
if (Kph2IsConnected())
{
return Kph2GetContextThread(ThreadHandle, Context);
}
else
{
return NtGetContextThread(ThreadHandle, Context);
}
}
/**
* Sets the processor context of a thread.
*
* \param ThreadHandle A handle to a thread. The handle must have THREAD_SET_CONTEXT access.
* \param Context The new context structure.
*/
NTSTATUS Ph2SetThreadContext(
_In_ HANDLE ThreadHandle,
_In_ PCONTEXT Context
)
{
if (Kph2IsConnected())
{
return Kph2SetContextThread(ThreadHandle, Context);
}
else
{
return NtSetContextThread(ThreadHandle, Context);
}
}
/**
* Copies memory from the current process into another process.
*
* \param ProcessHandle A handle to a process. The handle must have PROCESS_VM_WRITE access.
* \param BaseAddress The address to which memory is to be copied.
* \param Buffer A buffer which contains the memory to copy.
* \param BufferSize The number of bytes to copy.
* \param NumberOfBytesWritten A variable which receives the number of bytes copied from the buffer.
*/
NTSTATUS Ph2WriteVirtualMemory(
_In_ HANDLE ProcessHandle,
_In_ PVOID BaseAddress,
_In_reads_bytes_(BufferSize) PVOID Buffer,
_In_ SIZE_T BufferSize,
_Out_opt_ PSIZE_T NumberOfBytesWritten
)
{
NTSTATUS status;
status = NtWriteVirtualMemory(
ProcessHandle,
BaseAddress,
Buffer,
BufferSize,
NumberOfBytesWritten
);
if (status == STATUS_ACCESS_DENIED && Kph2IsConnected())
{
status = Kph2WriteVirtualMemory(
ProcessHandle,
BaseAddress,
Buffer,
BufferSize,
NumberOfBytesWritten
);
}
return status;
}
/**
* Terminates a process.
*
* \param ProcessHandle A handle to a process. The handle must have PROCESS_TERMINATE access.
* \param ExitStatus A status value that indicates why the process is being terminated.
*/
NTSTATUS Ph2TerminateProcess(
_In_ HANDLE ProcessHandle,
_In_ NTSTATUS ExitStatus
)
{
NTSTATUS status;
if (Kph2IsConnected())
{
status = Kph2TerminateProcess(
ProcessHandle,
ExitStatus
);
if (status != STATUS_NOT_SUPPORTED)
return status;
}
return NtTerminateProcess(
ProcessHandle,
ExitStatus
);
}

View File

@@ -0,0 +1,73 @@
/*
* Process Hacker Extra Plugins -
* Terminator Plugin
*
* Copyright (C) 2016 dmex
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
NTSTATUS Ph2OpenProcess(
_Out_ PHANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ HANDLE ProcessId
);
NTSTATUS Ph2OpenThread(
_Out_ PHANDLE ThreadHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ HANDLE ThreadId
);
NTSTATUS Ph2DuplicateObject(
_In_ HANDLE SourceProcessHandle,
_In_ HANDLE SourceHandle,
_In_opt_ HANDLE TargetProcessHandle,
_Out_opt_ PHANDLE TargetHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ ULONG HandleAttributes,
_In_ ULONG Options
);
NTSTATUS Ph2TerminateThread(
_In_ HANDLE ThreadHandle,
_In_ NTSTATUS ExitStatus
);
NTSTATUS Ph2GetThreadContext(
_In_ HANDLE ThreadHandle,
_Inout_ PCONTEXT Context
);
NTSTATUS Ph2SetThreadContext(
_In_ HANDLE ThreadHandle,
_In_ PCONTEXT Context
);
NTSTATUS Ph2WriteVirtualMemory(
_In_ HANDLE ProcessHandle,
_In_ PVOID BaseAddress,
_In_reads_bytes_(BufferSize) PVOID Buffer,
_In_ SIZE_T BufferSize,
_Out_opt_ PSIZE_T NumberOfBytesWritten
);
NTSTATUS Ph2TerminateProcess(
_In_ HANDLE ProcessHandle,
_In_ NTSTATUS ExitStatus
);

View File

@@ -0,0 +1,19 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by TerminatorPlugin.rc
//
#define IDD_TERMINATOR 101
#define IDC_RUNSELECTED 1001
#define IDC_TERMINATOR_LIST 1002
#define IDC_TERMINATOR_TEXT 1003
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 103
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1004
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -0,0 +1,728 @@
/*
* Process Hacker Extra Plugins -
* Terminator Plugin
*
* Copyright (C) 2010-2011 wj32
* Copyright (C) 2016 dmex
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "main.h"
#include "phapi.h"
#include "kph2user.h"
static PVOID GetExitProcessFunction(
VOID
)
{
if (WindowsVersion >= WINDOWS_VISTA)
return PhGetModuleProcAddress(L"ntdll.dll", "RtlExitUserProcess");
return PhGetModuleProcAddress(L"kernel32.dll", "ExitProcess");
}
NTSTATUS NTAPI TerminatorTP1(
_In_ HANDLE ProcessId
)
{
NTSTATUS status;
HANDLE processHandle;
if (NT_SUCCESS(status = Ph2OpenProcess(
&processHandle,
PROCESS_TERMINATE,
ProcessId
)))
{
// Don't use KPH.
status = NtTerminateProcess(processHandle, STATUS_SUCCESS);
NtClose(processHandle);
}
return status;
}
NTSTATUS NTAPI TerminatorTP2(
_In_ HANDLE ProcessId
)
{
NTSTATUS status;
HANDLE processHandle;
if (NT_SUCCESS(status = Ph2OpenProcess(
&processHandle,
PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE,
ProcessId
)))
{
status = RtlCreateUserThread(
processHandle,
NULL,
FALSE,
0,
0,
0,
(PUSER_THREAD_START_ROUTINE)GetExitProcessFunction(),
NULL,
NULL,
NULL
);
NtClose(processHandle);
}
return status;
}
NTSTATUS NTAPI TerminatorTTGeneric(
_In_ HANDLE ProcessId,
_In_ BOOLEAN UseKph
)
{
NTSTATUS status;
PVOID processes;
PSYSTEM_PROCESS_INFORMATION process;
if (UseKph && !Kph2IsConnected())
return STATUS_NOT_SUPPORTED;
if (!NT_SUCCESS(status = PhEnumProcesses(&processes)))
return status;
process = PhFindProcessInformation(processes, ProcessId);
if (!process)
{
PhFree(processes);
return STATUS_INVALID_CID;
}
for (ULONG i = 0; i < process->NumberOfThreads; i++)
{
HANDLE threadHandle;
if (NT_SUCCESS(Ph2OpenThread(
&threadHandle,
THREAD_TERMINATE,
process->Threads[i].ClientId.UniqueThread
)))
{
if (UseKph)
Kph2TerminateThread(threadHandle, STATUS_SUCCESS);
else
NtTerminateThread(threadHandle, STATUS_SUCCESS);
NtClose(threadHandle);
}
}
PhFree(processes);
return STATUS_SUCCESS;
}
NTSTATUS NTAPI TerminatorTT1(
_In_ HANDLE ProcessId
)
{
return TerminatorTTGeneric(ProcessId, FALSE);
}
NTSTATUS NTAPI TerminatorTT2(
_In_ HANDLE ProcessId
)
{
NTSTATUS status;
PVOID processes;
PSYSTEM_PROCESS_INFORMATION process;
CONTEXT context;
PVOID exitProcess;
exitProcess = GetExitProcessFunction();
if (!NT_SUCCESS(status = PhEnumProcesses(&processes)))
return status;
process = PhFindProcessInformation(processes, ProcessId);
if (!process)
{
PhFree(processes);
return STATUS_INVALID_CID;
}
for (ULONG i = 0; i < process->NumberOfThreads; i++)
{
HANDLE threadHandle;
if (NT_SUCCESS(Ph2OpenThread(
&threadHandle,
THREAD_GET_CONTEXT | THREAD_SET_CONTEXT,
process->Threads[i].ClientId.UniqueThread
)))
{
#ifdef _M_IX86
context.ContextFlags = CONTEXT_CONTROL;
Ph2GetThreadContext(threadHandle, &context);
context.Eip = (ULONG)exitProcess;
Ph2SetThreadContext(threadHandle, &context);
#else
context.ContextFlags = CONTEXT_CONTROL;
Ph2GetThreadContext(threadHandle, &context);
context.Rip = (ULONG64)exitProcess;
Ph2SetThreadContext(threadHandle, &context);
#endif
NtClose(threadHandle);
}
}
PhFree(processes);
return STATUS_SUCCESS;
}
NTSTATUS NTAPI TerminatorTP1a(
_In_ HANDLE ProcessId
)
{
NTSTATUS status;
HANDLE processHandle = NtCurrentProcess();
if (!NT_SUCCESS(status = NtGetNextProcess(
NtCurrentProcess(),
ProcessQueryAccess | PROCESS_TERMINATE,
0,
0,
&processHandle
)))
{
return status;
}
for (ULONG i = 0; i < 1000; i++) // make sure we don't go into an infinite loop or something
{
HANDLE newProcessHandle;
PROCESS_BASIC_INFORMATION basicInfo;
if (NT_SUCCESS(PhGetProcessBasicInformation(processHandle, &basicInfo)))
{
if (basicInfo.UniqueProcessId == ProcessId)
{
Ph2TerminateProcess(processHandle, STATUS_SUCCESS);
break;
}
}
if (NT_SUCCESS(status = NtGetNextProcess(
processHandle,
ProcessQueryAccess | PROCESS_TERMINATE,
0,
0,
&newProcessHandle
)))
{
NtClose(processHandle);
processHandle = newProcessHandle;
}
else
{
NtClose(processHandle);
break;
}
}
return status;
}
NTSTATUS NTAPI TerminatorTT1a(
_In_ HANDLE ProcessId
)
{
NTSTATUS status;
HANDLE processHandle;
HANDLE threadHandle;
if (NT_SUCCESS(status = Ph2OpenProcess(
&processHandle,
PROCESS_QUERY_INFORMATION, // NtGetNextThread actually requires this access for some reason
ProcessId
)))
{
if (!NT_SUCCESS(status = NtGetNextThread(
processHandle,
NULL,
THREAD_TERMINATE,
0,
0,
&threadHandle
)))
{
NtClose(processHandle);
return status;
}
for (ULONG i = 0; i < 1000; i++)
{
HANDLE newThreadHandle;
Ph2TerminateThread(threadHandle, STATUS_SUCCESS);
if (NT_SUCCESS(NtGetNextThread(
processHandle,
threadHandle,
THREAD_TERMINATE,
0,
0,
&newThreadHandle
)))
{
NtClose(threadHandle);
threadHandle = newThreadHandle;
}
else
{
NtClose(threadHandle);
break;
}
}
NtClose(processHandle);
}
return status;
}
NTSTATUS NTAPI TerminatorCH1(
_In_ HANDLE ProcessId
)
{
NTSTATUS status;
HANDLE processHandle;
if (NT_SUCCESS(status = Ph2OpenProcess(
&processHandle,
PROCESS_DUP_HANDLE,
ProcessId
)))
{
for (ULONG i = 0; i < 0x1000; i += 4)
{
Ph2DuplicateObject(
processHandle,
UlongToHandle(i),
NULL,
NULL,
0,
0,
DUPLICATE_CLOSE_SOURCE
);
}
NtClose(processHandle);
}
return status;
}
static BOOL CALLBACK DestroyProcessWindowsProc(
_In_ HWND hwnd,
_In_ LPARAM lParam
)
{
ULONG processId;
GetWindowThreadProcessId(hwnd, &processId);
if (processId == (ULONG)lParam)
{
PostMessage(hwnd, WM_DESTROY, 0, 0);
}
return TRUE;
}
NTSTATUS NTAPI TerminatorW1(
_In_ HANDLE ProcessId
)
{
EnumWindows(DestroyProcessWindowsProc, (LPARAM)ProcessId);
return STATUS_SUCCESS;
}
static BOOL CALLBACK QuitProcessWindowsProc(
_In_ HWND hwnd,
_In_ LPARAM lParam
)
{
ULONG processId;
GetWindowThreadProcessId(hwnd, &processId);
if (processId == (ULONG)lParam)
{
PostMessage(hwnd, WM_QUIT, 0, 0);
}
return TRUE;
}
NTSTATUS NTAPI TerminatorW2(
_In_ HANDLE ProcessId
)
{
EnumWindows(QuitProcessWindowsProc, (LPARAM)ProcessId);
return STATUS_SUCCESS;
}
static BOOL CALLBACK CloseProcessWindowsProc(
_In_ HWND hwnd,
_In_ LPARAM lParam
)
{
ULONG processId;
GetWindowThreadProcessId(hwnd, &processId);
if (processId == (ULONG)lParam)
{
PostMessage(hwnd, WM_CLOSE, 0, 0);
}
return TRUE;
}
NTSTATUS NTAPI TerminatorW3(
_In_ HANDLE ProcessId
)
{
EnumWindows(CloseProcessWindowsProc, (LPARAM)ProcessId);
return STATUS_SUCCESS;
}
NTSTATUS NTAPI TerminatorTJ1(
_In_ HANDLE ProcessId
)
{
NTSTATUS status;
HANDLE processHandle;
// TODO: Check if the process is already in a job.
if (NT_SUCCESS(status = Ph2OpenProcess(
&processHandle,
PROCESS_SET_QUOTA | PROCESS_TERMINATE,
ProcessId
)))
{
HANDLE jobHandle;
status = NtCreateJobObject(&jobHandle, JOB_OBJECT_ALL_ACCESS, NULL);
if (NT_SUCCESS(status))
{
status = NtAssignProcessToJobObject(jobHandle, processHandle);
if (NT_SUCCESS(status))
status = NtTerminateJobObject(jobHandle, STATUS_SUCCESS);
NtClose(jobHandle);
}
NtClose(processHandle);
}
return status;
}
NTSTATUS NTAPI TerminatorTD1(
_In_ HANDLE ProcessId
)
{
NTSTATUS status;
HANDLE processHandle;
if (NT_SUCCESS(status = Ph2OpenProcess(
&processHandle,
PROCESS_SUSPEND_RESUME,
ProcessId
)))
{
HANDLE debugObjectHandle;
OBJECT_ATTRIBUTES objectAttributes;
InitializeObjectAttributes(
&objectAttributes,
NULL,
0,
NULL,
NULL
);
if (NT_SUCCESS(NtCreateDebugObject(
&debugObjectHandle,
DEBUG_PROCESS_ASSIGN,
&objectAttributes,
DEBUG_KILL_ON_CLOSE
)))
{
NtDebugActiveProcess(processHandle, debugObjectHandle);
NtClose(debugObjectHandle);
}
NtClose(processHandle);
}
return status;
}
NTSTATUS NTAPI TerminatorTP3(
_In_ HANDLE ProcessId
)
{
NTSTATUS status;
HANDLE processHandle;
if (!Kph2IsConnected())
return STATUS_NOT_SUPPORTED;
if (NT_SUCCESS(status = Ph2OpenProcess(
&processHandle,
SYNCHRONIZE, // KPH doesn't require any access for this operation
ProcessId
)))
{
status = Kph2TerminateProcess(processHandle, STATUS_SUCCESS);
NtClose(processHandle);
}
return status;
}
NTSTATUS NTAPI TerminatorTT3(
_In_ HANDLE ProcessId
)
{
return TerminatorTTGeneric(ProcessId, TRUE);
}
NTSTATUS NTAPI TerminatorM1(
_In_ HANDLE ProcessId
)
{
NTSTATUS status;
HANDLE processHandle;
if (NT_SUCCESS(status = Ph2OpenProcess(
&processHandle,
PROCESS_QUERY_INFORMATION | PROCESS_VM_WRITE,
ProcessId
)))
{
PVOID pageOfGarbage;
SIZE_T pageSize;
PVOID baseAddress;
MEMORY_BASIC_INFORMATION basicInfo;
pageOfGarbage = NULL;
pageSize = PAGE_SIZE;
if (!NT_SUCCESS(NtAllocateVirtualMemory(
NtCurrentProcess(),
&pageOfGarbage,
0,
&pageSize,
MEM_COMMIT,
PAGE_READONLY
)))
{
NtClose(processHandle);
return STATUS_NO_MEMORY;
}
baseAddress = (PVOID)0;
while (NT_SUCCESS(NtQueryVirtualMemory(
processHandle,
baseAddress,
MemoryBasicInformation,
&basicInfo,
sizeof(MEMORY_BASIC_INFORMATION),
NULL
)))
{
ULONG i;
// Make sure we don't write to views of mapped files. That
// could possibly corrupt files!
if (basicInfo.Type == MEM_PRIVATE)
{
for (i = 0; i < basicInfo.RegionSize; i += PAGE_SIZE)
{
Ph2WriteVirtualMemory(
processHandle,
PTR_ADD_OFFSET(baseAddress, i),
pageOfGarbage,
PAGE_SIZE,
NULL
);
}
}
baseAddress = PTR_ADD_OFFSET(baseAddress, basicInfo.RegionSize);
}
// Size needs to be zero if we're freeing.
pageSize = 0;
NtFreeVirtualMemory(
NtCurrentProcess(),
&pageOfGarbage,
&pageSize,
MEM_RELEASE
);
NtClose(processHandle);
}
return status;
}
NTSTATUS NTAPI TerminatorM2(
_In_ HANDLE ProcessId
)
{
NTSTATUS status;
HANDLE processHandle;
if (NT_SUCCESS(status = Ph2OpenProcess(
&processHandle,
PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION,
ProcessId
)))
{
PVOID baseAddress;
MEMORY_BASIC_INFORMATION basicInfo;
ULONG oldProtect;
baseAddress = (PVOID)0;
while (NT_SUCCESS(NtQueryVirtualMemory(
processHandle,
baseAddress,
MemoryBasicInformation,
&basicInfo,
sizeof(MEMORY_BASIC_INFORMATION),
NULL
)))
{
SIZE_T regionSize;
regionSize = basicInfo.RegionSize;
NtProtectVirtualMemory(
processHandle,
&basicInfo.BaseAddress,
&regionSize,
PAGE_NOACCESS,
&oldProtect
);
baseAddress = PTR_ADD_OFFSET(baseAddress, basicInfo.RegionSize);
}
NtClose(processHandle);
}
return status;
}
TEST_ITEM PhTerminatorTests[16] =
{
{ L"TP1", L"Terminates the process using NtTerminateProcess", TerminatorTP1 },
{ L"TP2", L"Creates a remote thread in the process which terminates the process", TerminatorTP2 },
{ L"TT1", L"Terminates the process' threads", TerminatorTT1 },
{ L"TT2", L"Modifies the process' threads with contexts which terminate the process", TerminatorTT2 },
{ L"TP1a", L"Terminates the process using NtTerminateProcess (alternative method)", TerminatorTP1a },
{ L"TT1a", L"Terminates the process' threads (alternative method)", TerminatorTT1a },
{ L"CH1", L"Closes the process' handles", TerminatorCH1 },
{ L"W1", L"Sends the WM_DESTROY message to the process' windows", TerminatorW1 },
{ L"W2", L"Sends the WM_QUIT message to the process' windows", TerminatorW2 },
{ L"W3", L"Sends the WM_CLOSE message to the process' windows", TerminatorW3 },
{ L"TJ1", L"Assigns the process to a job object and terminates the job", TerminatorTJ1 },
{ L"TD1", L"Debugs the process and closes the debug object", TerminatorTD1 },
{ L"TP3", L"Terminates the process in kernel-mode", TerminatorTP3 },
{ L"TT3", L"Terminates the process' threads in kernel-mode", TerminatorTT3 },
{ L"M1", L"Writes garbage to the process' memory regions", TerminatorM1 },
{ L"M2", L"Sets the page protection of the process' memory regions to PAGE_NOACCESS", TerminatorM2 }
};
BOOLEAN PhpRunTerminatorTest(
_In_ HWND WindowHandle,
_In_ PPH_PROCESS_ITEM ProcessItem,
_In_ INT Index
)
{
NTSTATUS status;
PTEST_ITEM testItem;
HWND lvHandle;
PVOID processes;
BOOLEAN success = FALSE;
LARGE_INTEGER interval;
lvHandle = GetDlgItem(WindowHandle, IDC_TERMINATOR_LIST);
if (!PhGetListViewItemParam(
lvHandle,
Index,
&testItem
))
return FALSE;
status = testItem->TestProc(ProcessItem->ProcessId);
interval.QuadPart = -1000 * PH_TIMEOUT_MS;
NtDelayExecution(FALSE, &interval);
if (status == STATUS_NOT_SUPPORTED)
{
PPH_STRING concat;
concat = PhConcatStrings2(L"(Not available) ", testItem->Description);
PhSetListViewSubItem(lvHandle, Index, 1, concat->Buffer);
PhDereferenceObject(concat);
}
if (!NT_SUCCESS(PhEnumProcesses(&processes)))
return FALSE;
// Check if the process exists.
if (!PhFindProcessInformation(processes, ProcessItem->ProcessId))
{
PhSetListViewItemImageIndex(lvHandle, Index, 1);
SetDlgItemText(WindowHandle, IDC_TERMINATOR_TEXT, L"The process was terminated.");
success = TRUE;
}
else
{
PhSetListViewItemImageIndex(lvHandle, Index, 0);
}
PhFree(processes);
UpdateWindow(WindowHandle);
return success;
}