From 22bf8a798e5366c2687bd61688e489ac48ebf7e9 Mon Sep 17 00:00:00 2001 From: wj32 Date: Sun, 19 Apr 2009 09:51:04 +0000 Subject: [PATCH] KphTerminateProcess now uses PsTerminateProcess where possible; if the wrong address is found it should not BSOD the system because the first 5 bytes are checked against the known standard function prologue. git-svn-id: svn://svn.code.sf.net/p/processhacker/code@1099 21ef857c-d57f-4fe0-8362-d861dc6d29cd --- trunk/CHANGELOG.txt | 2 + trunk/KProcessHacker/i386/kprocesshacker.sys | Bin 20992 -> 21504 bytes trunk/KProcessHacker/include/kph.h | 38 +++++++--- trunk/KProcessHacker/include/ps.h | 5 ++ trunk/KProcessHacker/include/version.h | 21 ++++-- trunk/KProcessHacker/include/zw.h | 17 +++++ trunk/KProcessHacker/kph.c | 25 ++++++- trunk/KProcessHacker/mm.c | 4 +- trunk/KProcessHacker/ob.c | 12 +-- trunk/KProcessHacker/ps.c | 75 ++++++++++++++++--- trunk/KProcessHacker/version.c | 35 +++++++-- 11 files changed, 189 insertions(+), 45 deletions(-) diff --git a/trunk/CHANGELOG.txt b/trunk/CHANGELOG.txt index 56beef8a3..2bc9a24f4 100644 --- a/trunk/CHANGELOG.txt +++ b/trunk/CHANGELOG.txt @@ -2,6 +2,8 @@ Process Hacker 1.3.6.6 * NEW/IMPROVED: + * "Terminate process" now uses a special kernel-mode method to bypass + almost all anti-termination methods * Basic support for Windows 7 in Process Hacker and KProcessHacker * Proper symbol support with dbghelp.dll * Private, Shared and Shareable Working Set columns diff --git a/trunk/KProcessHacker/i386/kprocesshacker.sys b/trunk/KProcessHacker/i386/kprocesshacker.sys index 73541c6e621838a47d591ac995ff28926440d85b..2429a09f4b61d18a58c681be38674ade989b441e 100644 GIT binary patch delta 3951 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 J4SFvq`@e}EPYnP7 diff --git a/trunk/KProcessHacker/include/kph.h b/trunk/KProcessHacker/include/kph.h index 447b1dfdf..c768021b8 100644 --- a/trunk/KProcessHacker/include/kph.h +++ b/trunk/KProcessHacker/include/kph.h @@ -20,8 +20,8 @@ * along with Process Hacker. If not, see . */ -#ifndef _KPH_NT_H -#define _KPH_NT_H +#ifndef _KPH_H +#define _KPH_H #include "kprocesshacker.h" #include "debug.h" @@ -31,10 +31,24 @@ #include "ps.h" #include "zw.h" -extern _PsGetProcessJob PsGetProcessJob; -extern _PsSuspendProcess PsSuspendProcess; -extern _PsResumeProcess PsResumeProcess; -extern _MmCopyVirtualMemory MmCopyVirtualMemory; +#ifdef EXT +#undef EXT +#endif + +#ifdef _KPH_PRIVATE +#define EXT +#define EQNULL = NULL +#else +#define EXT extern +#define EQNULL +#endif + +EXT _MmCopyVirtualMemory MmCopyVirtualMemory EQNULL; +EXT _NtClose __NtClose EQNULL; +EXT _PsGetProcessJob PsGetProcessJob EQNULL; +EXT _PsResumeProcess PsResumeProcess EQNULL; +EXT _PsSuspendProcess PsSuspendProcess EQNULL; +EXT _PsTerminateProcess __PsTerminateProcess EQNULL; typedef struct _KPH_ATTACH_STATE { @@ -191,7 +205,7 @@ NTSTATUS KphWriteVirtualMemory( /* OB */ -NTSTATUS KphObDuplicateObject( +NTSTATUS ObDuplicateObject( PEPROCESS SourceProcess, PEPROCESS TargetProcess, HANDLE SourceHandle, @@ -202,12 +216,18 @@ NTSTATUS KphObDuplicateObject( KPROCESSOR_MODE AccessMode ); -PHANDLE_TABLE KphObReferenceProcessHandleTable( +PHANDLE_TABLE ObReferenceProcessHandleTable( PEPROCESS Process ); -VOID KphObDereferenceProcessHandleTable( +VOID ObDereferenceProcessHandleTable( PEPROCESS Process ); +/* PS */ +NTSTATUS PsTerminateProcess( + PEPROCESS Process, + NTSTATUS ExitStatus + ); + #endif \ No newline at end of file diff --git a/trunk/KProcessHacker/include/ps.h b/trunk/KProcessHacker/include/ps.h index 802e31bec..a16871222 100644 --- a/trunk/KProcessHacker/include/ps.h +++ b/trunk/KProcessHacker/include/ps.h @@ -69,6 +69,11 @@ typedef NTSTATUS (NTAPI *_PsSuspendProcess)( PEPROCESS Process ); +typedef NTSTATUS (__fastcall *_PsTerminateProcess)( + PEPROCESS Process, + NTSTATUS ExitStatus + ); + /* STRUCTS */ typedef struct _KEXECUTE_OPTIONS diff --git a/trunk/KProcessHacker/include/version.h b/trunk/KProcessHacker/include/version.h index e6f91a500..f67479fcc 100644 --- a/trunk/KProcessHacker/include/version.h +++ b/trunk/KProcessHacker/include/version.h @@ -25,16 +25,20 @@ #include "kprocesshacker.h" -#define WINDOWS_XP '0051' -#define WINDOWS_SERVER_2003 '0052' -#define WINDOWS_VISTA '0060' -#define WINDOWS_7 '0061' +#define WINDOWS_XP 51 +#define WINDOWS_SERVER_2003 52 +#define WINDOWS_VISTA 60 +#define WINDOWS_7 61 #define KVOFF(object, offset) ((PCHAR)(object) + offset) NTSTATUS KvInit(); -#ifdef KPH_VERSION_PRIVATE +#ifdef EXT +#undef EXT +#endif + +#ifdef _VERSION_PRIVATE #define EXT #else #define EXT extern @@ -46,7 +50,7 @@ EXT ACCESS_MASK ProcessAllAccess; EXT ACCESS_MASK ThreadAllAccess; /* Offsets */ -/* +/* Structures * Et: ETHREAD * Ep: EPROCESS * Ot: OBJECT_TYPE @@ -62,4 +66,9 @@ EXT ULONG OffEpProtectedProcessBit; EXT ULONG OffEpRundownProtect; EXT ULONG OffOtiGenericMapping; +/* Functions + * These are all offsets from NtClose. + */ +EXT ULONG OffPsTerminateProcess; + #endif diff --git a/trunk/KProcessHacker/include/zw.h b/trunk/KProcessHacker/include/zw.h index 6107e9fce..6937f5c5a 100644 --- a/trunk/KProcessHacker/include/zw.h +++ b/trunk/KProcessHacker/include/zw.h @@ -54,6 +54,19 @@ #define JOB_OBJECT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \ 0x1F) +typedef struct _SYSTEM_MODULE_INFORMATION +{ + ULONG Reserved[2]; + PVOID Base; + ULONG Size; + ULONG Flags; + USHORT Index; + USHORT Unknown; + USHORT LoadCount; + USHORT ModuleNameOffset; + CHAR ImageName[256]; +} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; + NTSTATUS NTAPI ZwOpenProcessToken( HANDLE ProcessHandle, ACCESS_MASK DesiredAccess, @@ -67,4 +80,8 @@ NTSTATUS NTAPI ZwSetInformationProcess( ULONG ProcessInformationLength ); +typedef NTSTATUS (NTAPI *_NtClose)( + HANDLE Handle + ); + #endif diff --git a/trunk/KProcessHacker/kph.c b/trunk/KProcessHacker/kph.c index f8f685e1d..60c16dac8 100644 --- a/trunk/KProcessHacker/kph.c +++ b/trunk/KProcessHacker/kph.c @@ -20,12 +20,10 @@ * along with Process Hacker. If not, see . */ +#define _KPH_PRIVATE #include "include/kph.h" -_PsGetProcessJob PsGetProcessJob = NULL; -_PsSuspendProcess PsSuspendProcess = NULL; -_PsResumeProcess PsResumeProcess = NULL; -_MmCopyVirtualMemory MmCopyVirtualMemory = NULL; +static char StandardPrologue[] = { 0x8b, 0xff, 0x55, 0x8b, 0xec }; PVOID GetSystemRoutineAddress(WCHAR *Name) { @@ -50,11 +48,30 @@ NTSTATUS KphNtInit() { NTSTATUS status = STATUS_SUCCESS; + __NtClose = GetSystemRoutineAddress(L"NtClose"); + + /* NtClose is used as a reference point for any addresses + dependent on where the kernel is loaded. */ + if (!__NtClose) + return STATUS_NOT_SUPPORTED; + MmCopyVirtualMemory = GetSystemRoutineAddress(L"MmCopyVirtualMemory"); PsGetProcessJob = GetSystemRoutineAddress(L"PsGetProcessJob"); PsResumeProcess = GetSystemRoutineAddress(L"PsResumeProcess"); PsSuspendProcess = GetSystemRoutineAddress(L"PsSuspendProcess"); + /* Initialize function pointers */ + if (OffPsTerminateProcess) + { + __PsTerminateProcess = (_PsTerminateProcess)((ULONG)__NtClose + OffPsTerminateProcess); + dprintf("PsTerminateProcess: 0x%08x\n", __PsTerminateProcess); + if (memcmp(__PsTerminateProcess, StandardPrologue, 5) != 0) + { + __PsTerminateProcess = NULL; + dprintf("PsTerminateProcess failed memory check\n"); + } + } + return status; } diff --git a/trunk/KProcessHacker/mm.c b/trunk/KProcessHacker/mm.c index 9b1333711..f9bc18ed6 100644 --- a/trunk/KProcessHacker/mm.c +++ b/trunk/KProcessHacker/mm.c @@ -36,7 +36,7 @@ NTSTATUS KphReadVirtualMemory( PEPROCESS processObject; ULONG returnLength = 0; - if (MmCopyVirtualMemory == NULL) + if (!MmCopyVirtualMemory) return STATUS_NOT_SUPPORTED; if (AccessMode != KernelMode) @@ -107,7 +107,7 @@ NTSTATUS KphWriteVirtualMemory( PEPROCESS processObject; ULONG returnLength = 0; - if (MmCopyVirtualMemory == NULL) + if (!MmCopyVirtualMemory) return STATUS_NOT_SUPPORTED; if (AccessMode != KernelMode) diff --git a/trunk/KProcessHacker/ob.c b/trunk/KProcessHacker/ob.c index b3ca21b58..5fbc27787 100644 --- a/trunk/KProcessHacker/ob.c +++ b/trunk/KProcessHacker/ob.c @@ -81,7 +81,7 @@ NTSTATUS KphDuplicateObject( } /* Call the internal function */ - status = KphObDuplicateObject( + status = ObDuplicateObject( sourceProcess, targetProcess, SourceHandle, @@ -121,7 +121,7 @@ BOOLEAN KphEnumProcessHandleTable( BOOLEAN result = FALSE; PHANDLE_TABLE handleTable = NULL; - handleTable = KphObReferenceProcessHandleTable(Process); + handleTable = ObReferenceProcessHandleTable(Process); if (!handleTable) return FALSE; @@ -131,18 +131,18 @@ BOOLEAN KphEnumProcessHandleTable( EnumHandleProcedure, Context, Handle); - KphObDereferenceProcessHandleTable(Process); + ObDereferenceProcessHandleTable(Process); return result; } -VOID KphObDereferenceProcessHandleTable( +VOID ObDereferenceProcessHandleTable( PEPROCESS Process ) { ExReleaseRundownProtection((PEX_RUNDOWN_REF)KVOFF(Process, OffEpRundownProtect)); } -NTSTATUS KphObDuplicateObject( +NTSTATUS ObDuplicateObject( PEPROCESS SourceProcess, PEPROCESS TargetProcess, HANDLE SourceHandle, @@ -257,7 +257,7 @@ OpenObjectEnd: return status; } -PHANDLE_TABLE KphObReferenceProcessHandleTable( +PHANDLE_TABLE ObReferenceProcessHandleTable( PEPROCESS Process ) { diff --git a/trunk/KProcessHacker/ps.c b/trunk/KProcessHacker/ps.c index 2fd851b14..1dcab66a2 100644 --- a/trunk/KProcessHacker/ps.c +++ b/trunk/KProcessHacker/ps.c @@ -419,7 +419,7 @@ NTSTATUS KphResumeProcess( NTSTATUS status = STATUS_SUCCESS; PEPROCESS processObject; - if (PsResumeProcess == NULL) + if (!PsResumeProcess) return STATUS_NOT_SUPPORTED; status = ObReferenceObjectByHandle( @@ -472,7 +472,7 @@ NTSTATUS KphSuspendProcess( NTSTATUS status = STATUS_SUCCESS; PEPROCESS processObject; - if (PsSuspendProcess == NULL) + if (!PsSuspendProcess) return STATUS_NOT_SUPPORTED; status = ObReferenceObjectByHandle( @@ -515,22 +515,73 @@ NTSTATUS KphTerminateProcess( return status; /* Can't terminate ourself. Get user-mode to do it. */ - if (PsGetProcessId(processObject) == PsGetCurrentProcessId()) + if (processObject == PsGetCurrentProcess()) { ObDereferenceObject(processObject); return STATUS_DISK_FULL; } - /* We have to open it again because ZwTerminateProcess only accepts kernel handles. */ - clientId.UniqueThread = 0; - clientId.UniqueProcess = PsGetProcessId(processObject); - status = KphOpenProcess(&newProcessHandle, 0x1, &objectAttributes, &clientId, KernelMode); - ObDereferenceObject(processObject); - - if (NT_SUCCESS(status)) + if (__PsTerminateProcess) { - status = ZwTerminateProcess(newProcessHandle, ExitStatus); - ZwClose(newProcessHandle); + status = PsTerminateProcess(processObject, ExitStatus); + } + else + { + /* We have to open it again because ZwTerminateProcess only accepts kernel handles. */ + clientId.UniqueThread = 0; + clientId.UniqueProcess = PsGetProcessId(processObject); + status = KphOpenProcess(&newProcessHandle, 0x1, &objectAttributes, &clientId, KernelMode); + ObDereferenceObject(processObject); + + if (NT_SUCCESS(status)) + { + status = ZwTerminateProcess(newProcessHandle, ExitStatus); + ZwClose(newProcessHandle); + } + } + + return status; +} + +NTSTATUS PsTerminateProcess( + PEPROCESS Process, + NTSTATUS ExitStatus + ) +{ + PVOID psTerminateProcess = __PsTerminateProcess; + NTSTATUS status; + + if (!psTerminateProcess) + return STATUS_NOT_SUPPORTED; + + if (WindowsVersion == WINDOWS_XP) + { + /* PsTerminateProcess on XP is stdcall */ + __asm + { + push [ExitStatus] + push [Process] + call [psTerminateProcess] + mov [status], eax + } + } + else if ( + WindowsVersion == WINDOWS_VISTA || + WindowsVersion == WINDOWS_7 + ) + { + /* PsTerminateProcess on Vista and above is thiscall */ + __asm + { + push [ExitStatus] + mov ecx, [Process] + call [psTerminateProcess] + mov [status], eax + } + } + else + { + return STATUS_NOT_SUPPORTED; } return status; diff --git a/trunk/KProcessHacker/version.c b/trunk/KProcessHacker/version.c index 48f92c6bc..a7b990aef 100644 --- a/trunk/KProcessHacker/version.c +++ b/trunk/KProcessHacker/version.c @@ -20,10 +20,15 @@ * along with Process Hacker. If not, see . */ -#define KPH_VERSION_PRIVATE +#define _VERSION_PRIVATE #include "include/version.h" #include "include/debug.h" +/* The following offsets took me a long time to work out, so + please do not steal them. If you want to use them, please + license your project under the GNU GPL (although you are + not legally required to). + */ NTSTATUS KvInit() { NTSTATUS status = STATUS_SUCCESS; @@ -58,15 +63,26 @@ NTSTATUS KvInit() /* Windows XP SP0 and 1 are not supported */ if (servicePack == 0) + { return STATUS_NOT_SUPPORTED; + } else if (servicePack == 1) + { return STATUS_NOT_SUPPORTED; + } else if (servicePack == 2) - ; + { + /* Seems to be OK for both ntkrnlpa and ntkrpamp */ + OffPsTerminateProcess = 0x16576; + } else if (servicePack == 3) - ; + { + OffPsTerminateProcess = 0x1676c; + } else + { return STATUS_NOT_SUPPORTED; + } dprintf("Initialized version-specific data for Windows XP SP%d\n", servicePack); } @@ -97,12 +113,13 @@ NTSTATUS KvInit() if (servicePack == 0) { OffOtiGenericMapping = 0x60 + 0xc; + OffPsTerminateProcess = 0x29b83; } /* SP1 */ else if (servicePack == 1) { - /* They got rid of the Mutex (an ERESOURCE) */ - OffOtiGenericMapping = 0x28 + 0xc; + OffOtiGenericMapping = 0x28 + 0xc; /* They got rid of the Mutex (an ERESOURCE) */ + OffPsTerminateProcess = 0x7768a; } else { @@ -129,9 +146,15 @@ NTSTATUS KvInit() /* SP0 */ if (servicePack == 0) - ; + { + /* In Windows 7 PsTerminateProcess is before + NtClose, so we have a negative number here. */ + OffPsTerminateProcess = 0xfff80dc2; + } else + { return STATUS_NOT_SUPPORTED; + } dprintf("Initialized version-specific data for Windows 7 SP%d\n", servicePack); }