From 692aac15a962dfe62ec9ea59addbebfa5e5a751e Mon Sep 17 00:00:00 2001 From: wj32 Date: Mon, 3 Jan 2011 00:18:32 +0000 Subject: [PATCH] rewriting KPH interface git-svn-id: svn://svn.code.sf.net/p/processhacker/code@3975 21ef857c-d57f-4fe0-8362-d861dc6d29cd --- .../ProcessHacker.Native/KProcessHacker.cs | 1207 ++++------------- .../Objects/ProcessHandle.cs | 6 +- .../ProcessHacker.Native.csproj | 2 +- 3 files changed, 256 insertions(+), 959 deletions(-) diff --git a/1.x/trunk/ProcessHacker.Native/KProcessHacker.cs b/1.x/trunk/ProcessHacker.Native/KProcessHacker.cs index 2d3d6b06c..79650b406 100644 --- a/1.x/trunk/ProcessHacker.Native/KProcessHacker.cs +++ b/1.x/trunk/ProcessHacker.Native/KProcessHacker.cs @@ -2,7 +2,7 @@ * Process Hacker - * KProcessHacker interfacing code * - * Copyright (C) 2009 wj32 + * Copyright (C) 2009-2011 wj32 * * This file is part of Process Hacker. * @@ -48,87 +48,55 @@ namespace ProcessHacker.Native set { _instance = value; } } - /// - /// A control code used by KProcessHacker to represent a specific function. - /// - private enum Control : uint + public static int KphCtlCode(int x) { - ClientCloseHandle = 0, - SsQueryClientEntry, - Reserved1, - KphOpenProcess, - KphOpenThread, - KphOpenProcessToken, - GetProcessProtected, - SetProcessProtected, - KphTerminateProcess, - KphSuspendProcess, - KphResumeProcess, - KphReadVirtualMemory, - KphWriteVirtualMemory, - SetProcessToken, - GetThreadStartAddress, - SetHandleAttributes, - GetHandleObjectName, - KphOpenProcessJob, - KphGetContextThread, - KphSetContextThread, - KphGetThreadWin32Thread, - KphDuplicateObject, - ZwQueryObject, - KphGetProcessId, - KphGetThreadId, - KphTerminateThread, - GetFeatures, - KphSetHandleGrantedAccess, - KphAssignImpersonationToken, - ProtectAdd, - ProtectRemove, - ProtectQuery, - KphUnsafeReadVirtualMemory, - SetExecuteOptions, - KphQueryProcessHandles, - KphOpenThreadProcess, - KphCaptureStackBackTraceThread, - KphDangerousTerminateThread, - KphOpenType, - KphOpenDriver, - KphQueryInformationDriver, - KphOpenDirectoryObject, - SsRef, - SsUnref, - SsCreateClientEntry, - SsCreateRuleSetEntry, - SsRemoveRule, - SsAddProcessIdRule, - SsAddThreadIdRule, - SsAddPreviousModeRule, - SsAddNumberRule, - SsEnableClientEntry, - KphOpenNamedObject, - KphQueryInformationProcess, - KphQueryInformationThread, - KphSetInformationProcess, - KphSetInformationThread, + return Win32.CtlCode(KphDeviceType, 0x800 + x, DeviceControlMethod.Neither, DeviceControlAccess.Any); } + public const int KphDeviceType = 0x9999; + public static readonly int IoCtlGetFeatures = KphCtlCode(0); + public static readonly int IoCtlOpenProcess = KphCtlCode(50); + public static readonly int IoCtlOpenProcessToken = KphCtlCode(51); + public static readonly int IoCtlOpenProcessJob = KphCtlCode(52); + public static readonly int IoCtlSuspendProcess = KphCtlCode(53); + public static readonly int IoCtlResumeProcess = KphCtlCode(54); + public static readonly int IoCtlTerminateProcess = KphCtlCode(55); + public static readonly int IoCtlReadVirtualMemory = KphCtlCode(56); + public static readonly int IoCtlWriteVirtualMemory = KphCtlCode(57); + public static readonly int IoCtlReadVirtualMemoryUnsafe = KphCtlCode(58); + public static readonly int IoCtlQueryInformationProcess = KphCtlCode(59); + public static readonly int IoCtlSetInformationProcess = KphCtlCode(60); + public static readonly int IoCtlOpenThread = KphCtlCode(100); + public static readonly int IoCtlOpenThreadProcess = KphCtlCode(101); + public static readonly int IoCtlTerminateThread = KphCtlCode(102); + public static readonly int IoCtlTerminateThreadUnsafe = KphCtlCode(103); + public static readonly int IoCtlGetContextThread = KphCtlCode(104); + public static readonly int IoCtlSetContextThread = KphCtlCode(105); + public static readonly int IoCtlCaptureStackBackTraceThread = KphCtlCode(106); + public static readonly int IoCtlQueryInformationThread = KphCtlCode(107); + public static readonly int IoCtlSetInformationThread = KphCtlCode(108); + public static readonly int IoCtlEnumerateProcessHandles = KphCtlCode(150); + public static readonly int IoCtlQueryInformationObject = KphCtlCode(151); + public static readonly int IoCtlSetInformationObject = KphCtlCode(152); + public static readonly int IoCtlDuplicateObject = KphCtlCode(153); + public static readonly int IoCtlOpenDriver = KphCtlCode(200); + public static readonly int IoCtlQueryInformationDriver = KphCtlCode(201); + [Flags] public enum KphFeatures : int { - PsTerminateProcess = 0x1, - PspTerminateThreadByPointer = 0x2 + None = 0 // none so far } private string _deviceName; private FileHandle _fileHandle; - private uint _baseControlNumber; private KphFeatures _features; /// /// Creates a connection to KProcessHacker. /// public KProcessHacker() - : this("KProcessHacker") + : this("KProcessHacker2") { } /// @@ -148,9 +116,6 @@ namespace ProcessHacker.Native { _deviceName = deviceName; - if (OSVersion.Architecture != OSArch.I386) - throw new NotSupportedException("KProcessHacker does not support 64-bit Windows."); - try { _fileHandle = new FileHandle( @@ -173,7 +138,7 @@ namespace ProcessHacker.Native try { - using (shandle = new ServiceHandle("KProcessHacker", ServiceAccess.Start)) + using (shandle = new ServiceHandle(deviceName, ServiceAccess.Start)) { shandle.Start(); } @@ -222,18 +187,7 @@ namespace ProcessHacker.Native } _fileHandle.SetHandleFlags(Win32HandleFlags.ProtectFromClose, Win32HandleFlags.ProtectFromClose); - - byte[] bytes = _fileHandle.Read(4); - - fixed (byte* bytesPtr = bytes) - _baseControlNumber = *(uint*)bytesPtr; - - try - { - _features = this.GetFeatures(); - } - catch - { } + _features = this.KphGetFeatures(); } public string DeviceName @@ -246,11 +200,6 @@ namespace ProcessHacker.Native get { return _features; } } - private int CtlCode(Control ctl) - { - return (int)(_baseControlNumber + ((uint)ctl * 4)); - } - /// /// Closes the connection to KProcessHacker. /// @@ -260,946 +209,292 @@ namespace ProcessHacker.Native _fileHandle.Dispose(); } - public void ClientCloseHandle(IntPtr handle) + [StructLayout(LayoutKind.Sequential)] + private struct KphGetFeaturesInput { - byte* inData = stackalloc byte[4]; - - *(int*)inData = handle.ToInt32(); - - _fileHandle.IoControl(CtlCode(Control.ClientCloseHandle), inData, 4, null, 0); + public int* Features; } - public KphFeatures GetFeatures() + public KphFeatures KphGetFeatures() { - byte* outData = stackalloc byte[4]; + KphGetFeaturesInput input; + int features; - _fileHandle.IoControl(CtlCode(Control.GetFeatures), null, 0, outData, 4); + input.Features = &features; + _fileHandle.IoControl(IoCtlGetFeatures, &input, sizeof(KphGetFeaturesInput), null, 0); - return (KphFeatures)(*(int*)outData); + return (KphFeatures)features; } - public string GetHandleObjectName(ProcessHandle processHandle, IntPtr handle) + [StructLayout(LayoutKind.Sequential)] + private struct KphOpenProcessInput { - byte* inData = stackalloc byte[8]; - byte[] outData = new byte[2048]; - - *(int*)inData = processHandle; - *(int*)(inData + 4) = handle.ToInt32(); - - try - { - int len = _fileHandle.IoControl(CtlCode(Control.GetHandleObjectName), - inData, 8, outData); - - return Encoding.Unicode.GetString(outData, 8, len - 8).TrimEnd('\0'); - } - catch - { } - - return null; + public IntPtr* ProcessHandle; + public int DesiredAccess; + public ClientId* ClientId; } - public bool GetProcessProtected(int pid) + public IntPtr KphOpenProcess(int pid, ProcessAccess desiredAccess) { - byte[] result = new byte[1]; + KphOpenProcessInput input; + IntPtr processHandle; + ClientId clientId; - _fileHandle.IoControl(CtlCode(Control.GetProcessProtected), - (byte*)&pid, 4, result); + clientId.ProcessId = pid; + clientId.ThreadId = 0; - return result[0] != 0; + input.ProcessHandle = &processHandle; + input.DesiredAccess = (int)desiredAccess; + input.ClientId = &clientId; + _fileHandle.IoControl(IoCtlOpenProcess, &input, sizeof(KphOpenProcessInput), null, 0); + + return processHandle; } - public uint GetThreadStartAddress(ThreadHandle threadHandle) + [StructLayout(LayoutKind.Sequential)] + private struct KphOpenProcessTokenInput { - byte* outData = stackalloc byte[4]; - int threadHandleInt = threadHandle; - - _fileHandle.IoControl(CtlCode(Control.GetThreadStartAddress), - (byte*)&threadHandleInt, 4, outData, 4); - - return *(uint*)outData; + public IntPtr ProcessHandle; + public int DesiredAccess; + public IntPtr* TokenHandle; } - public void KphAssignImpersonationToken(ThreadHandle threadHandle, TokenHandle tokenHandle) + public IntPtr KphOpenProcessToken(ProcessHandle processHandle, TokenAccess desiredAccess) { - byte* inData = stackalloc byte[8]; + KphOpenProcessTokenInput input; + IntPtr tokenHandle; - *(int*)inData = threadHandle; - *(int*)(inData + 4) = tokenHandle; + input.ProcessHandle = processHandle; + input.DesiredAccess = (int)desiredAccess; + input.TokenHandle = &tokenHandle; + _fileHandle.IoControl(IoCtlOpenProcessToken, &input, sizeof(KphOpenProcessTokenInput), null, 0); - _fileHandle.IoControl(CtlCode(Control.KphAssignImpersonationToken), inData, 8, null, 0); + return tokenHandle; } - public unsafe int KphCaptureStackBackTraceThread( - ThreadHandle threadHandle, - int framesToSkip, - int framesToCapture, - IntPtr[] backTrace, - out int backTraceHash - ) + [StructLayout(LayoutKind.Sequential)] + private struct KphOpenProcessJobInput { - byte* inData = stackalloc byte[6 * sizeof(int)]; - int capturedFramesLocal; - int backTraceHashLocal; - - if (framesToCapture > backTrace.Length) - throw new ArgumentOutOfRangeException("Back trace buffer is too small."); - - fixed (IntPtr* backTracePtr = backTrace) - { - *(int*)inData = threadHandle; - *(int*)(inData + 0x4) = framesToSkip; - *(int*)(inData + 0x8) = framesToCapture; - *(int*)(inData + 0xc) = (int)backTracePtr; - *(int*)(inData + 0x10) = (int)&capturedFramesLocal; - *(int*)(inData + 0x14) = (int)&backTraceHashLocal; - - _fileHandle.IoControl(CtlCode(Control.KphCaptureStackBackTraceThread), inData, 6 * sizeof(int), null, 0); - backTraceHash = backTraceHashLocal; - - return capturedFramesLocal; - } + public IntPtr ProcessHandle; + public int DesiredAccess; + public IntPtr* JobHandle; } - public void KphDangerousTerminateThread(ThreadHandle threadHandle, NtStatus exitStatus) + public IntPtr KphOpenProcessJob(ProcessHandle processHandle, TokenAccess desiredAccess) { - byte* inData = stackalloc byte[8]; + KphOpenProcessJobInput input; + IntPtr jobHandle; - *(int*)inData = threadHandle; - *(int*)(inData + 4) = (int)exitStatus; + input.ProcessHandle = processHandle; + input.DesiredAccess = (int)desiredAccess; + input.JobHandle = &jobHandle; + _fileHandle.IoControl(IoCtlOpenProcessJob, &input, sizeof(KphOpenProcessJobInput), null, 0); - _fileHandle.IoControl(CtlCode(Control.KphDangerousTerminateThread), inData, 8, null, 0); + return jobHandle; } - public void KphDuplicateObject( - int sourceProcessHandle, - int sourceHandle, - int targetProcessHandle, - out int targetHandle, - int desiredAccess, - HandleFlags handleAttributes, - DuplicateOptions options - ) + [StructLayout(LayoutKind.Sequential)] + private struct KphSuspendProcessInput { - int handle; - - KphDuplicateObject( - sourceProcessHandle, - sourceHandle, - targetProcessHandle, - (int)&handle, - desiredAccess, - handleAttributes, - options - ); - - targetHandle = handle; - } - - public void KphDuplicateObject( - int sourceProcessHandle, - int sourceHandle, - int targetProcessHandle, - int targetHandle, - int desiredAccess, - HandleFlags handleAttributes, - DuplicateOptions options - ) - { - byte[] data = new byte[7 * sizeof(int)]; - - fixed (byte* dataPtr = data) - { - *(int*)(dataPtr + 0x0) = sourceProcessHandle; - *(int*)(dataPtr + 0x4) = sourceHandle; - *(int*)(dataPtr + 0x8) = targetProcessHandle; - *(int*)(dataPtr + 0xc) = targetHandle; - *(int*)(dataPtr + 0x10) = desiredAccess; - *(int*)(dataPtr + 0x14) = (int)handleAttributes; - *(int*)(dataPtr + 0x18) = (int)options; - - _fileHandle.IoControl(CtlCode(Control.KphDuplicateObject), data, null); - } - } - - public void KphGetContextThread(ThreadHandle threadHandle, Context* context) - { - byte* inData = stackalloc byte[8]; - - *(int*)inData = threadHandle; - *(int*)(inData + 4) = (int)context; - - _fileHandle.IoControl(CtlCode(Control.KphGetContextThread), inData, 8, null, 0); - } - - public int KphGetProcessId(ProcessHandle processHandle, IntPtr handle) - { - byte* inData = stackalloc byte[8]; - byte* outData = stackalloc byte[4]; - - *(int*)inData = processHandle; - *(int*)(inData + 4) = handle.ToInt32(); - - _fileHandle.IoControl(CtlCode(Control.KphGetProcessId), inData, 8, outData, 4); - - return *(int*)outData; - } - - public int KphGetThreadId(ProcessHandle processHandle, IntPtr handle, out int processId) - { - byte* inData = stackalloc byte[8]; - byte* outData = stackalloc byte[8]; - - *(int*)inData = processHandle; - *(int*)(inData + 4) = handle.ToInt32(); - - _fileHandle.IoControl(CtlCode(Control.KphGetThreadId), inData, 8, outData, 8); - processId = *(int*)(outData + 4); - - return *(int*)outData; - } - - public int KphGetThreadWin32Thread(ThreadHandle threadHandle) - { - int threadHandleInt = threadHandle; - byte* outData = stackalloc byte[4]; - - _fileHandle.IoControl(CtlCode(Control.KphGetThreadWin32Thread), (byte*)&threadHandleInt, 4, outData, 4); - - return *(int*)outData; - } - - public int KphOpenDirectoryObject(DirectoryAccess access, ObjectAttributes objectAttributes) - { - byte* inData = stackalloc byte[0xc]; - int directoryObjectHandle; - - *(int*)inData = (int)&directoryObjectHandle; - *(int*)(inData + 0x4) = (int)access; - *(int*)(inData + 0x8) = (int)&objectAttributes; - - _fileHandle.IoControl(CtlCode(Control.KphOpenDirectoryObject), inData, 0xc, null, 0); - - return directoryObjectHandle; - } - - public int KphOpenDriver(ObjectAttributes objectAttributes) - { - byte* inData = stackalloc byte[8]; - int driverHandle; - - *(int*)inData = (int)&driverHandle; - *(int*)(inData + 4) = (int)&objectAttributes; - - _fileHandle.IoControl(CtlCode(Control.KphOpenDriver), inData, 8, null, 0); - - return driverHandle; - } - - public int KphOpenNamedObject(int access, ObjectAttributes objectAttributes) - { - byte* inData = stackalloc byte[0xc]; - int handle; - - *(int*)inData = (int)&handle; - *(int*)(inData + 4) = access; - *(int*)(inData + 8) = (int)&objectAttributes; - - _fileHandle.IoControl(CtlCode(Control.KphOpenNamedObject), inData, 0xc, null, 0); - - return handle; - } - - public int KphOpenProcess(int pid, ProcessAccess desiredAccess) - { - byte* inData = stackalloc byte[8]; - byte* outData = stackalloc byte[4]; - - *(int*)inData = pid; - *(uint*)(inData + 4) = (uint)desiredAccess; - - _fileHandle.IoControl(CtlCode(Control.KphOpenProcess), inData, 8, outData, 4); - - return *(int*)outData; - } - - public int KphOpenProcessJob(ProcessHandle processHandle, JobObjectAccess desiredAccess) - { - byte* inData = stackalloc byte[8]; - byte* outData = stackalloc byte[4]; - - *(int*)inData = processHandle; - *(uint*)(inData + 4) = (uint)desiredAccess; - - _fileHandle.IoControl(CtlCode(Control.KphOpenProcessJob), inData, 8, outData, 4); - - return *(int*)outData; - } - - public int KphOpenProcessToken(ProcessHandle processHandle, TokenAccess desiredAccess) - { - byte* inData = stackalloc byte[8]; - byte* outData = stackalloc byte[4]; - - *(int*)inData = processHandle; - *(uint*)(inData + 4) = (uint)desiredAccess; - - _fileHandle.IoControl(CtlCode(Control.KphOpenProcessToken), inData, 8, outData, 4); - - return *(int*)outData; - } - - public int KphOpenThread(int tid, ThreadAccess desiredAccess) - { - byte* inData = stackalloc byte[8]; - byte* outData = stackalloc byte[4]; - - *(int*)inData = tid; - *(uint*)(inData + 4) = (uint)desiredAccess; - - _fileHandle.IoControl(CtlCode(Control.KphOpenThread), inData, 8, outData, 4); - - return *(int*)outData; - } - - public int KphOpenThreadProcess(ThreadHandle threadHandle, ProcessAccess desiredAccess) - { - byte* inData = stackalloc byte[8]; - byte* outData = stackalloc byte[4]; - - *(int*)inData = threadHandle; - *(uint*)(inData + 4) = (uint)desiredAccess; - - _fileHandle.IoControl(CtlCode(Control.KphOpenThreadProcess), inData, 8, outData, 4); - - return *(int*)outData; - } - - public int KphOpenType(ObjectAttributes objectAttributes) - { - byte* inData = stackalloc byte[8]; - int typeHandle; - - *(int*)inData = (int)&typeHandle; - *(int*)(inData + 4) = (int)&objectAttributes; - - _fileHandle.IoControl(CtlCode(Control.KphOpenType), inData, 8, null, 0); - - return typeHandle; - } - - public void KphQueryInformationDriver( - DriverHandle driverHandle, - DriverInformationClass driverInformationClass, - IntPtr driverInformation, - int driverInformationLength, - out int returnLength - ) - { - byte* inData = stackalloc byte[0x14]; - int returnLengthLocal; - - *(int*)inData = driverHandle; - *(int*)(inData + 0x4) = (int)driverInformationClass; - *(int*)(inData + 0x8) = driverInformation.ToInt32(); - *(int*)(inData + 0xc) = driverInformationLength; - *(int*)(inData + 0x10) = (int)&returnLengthLocal; - - try - { - _fileHandle.IoControl(CtlCode(Control.KphQueryInformationDriver), inData, 0x14, null, 0); - } - finally - { - returnLength = returnLengthLocal; - } - } - - public void KphQueryInformationProcess( - ProcessHandle processHandle, - ProcessInformationClass processInformationClass, - IntPtr processInformation, - int processInformationLength, - out int returnLength - ) - { - byte* inData = stackalloc byte[0x14]; - int returnLengthLocal; - - *(int*)inData = processHandle; - *(int*)(inData + 0x4) = (int)processInformationClass; - *(int*)(inData + 0x8) = processInformation.ToInt32(); - *(int*)(inData + 0xc) = processInformationLength; - *(int*)(inData + 0x10) = (int)&returnLengthLocal; - - try - { - _fileHandle.IoControl(CtlCode(Control.KphQueryInformationProcess), inData, 0x14, null, 0); - } - finally - { - returnLength = returnLengthLocal; - } - } - - public void KphQueryInformationThread( - ThreadHandle threadHandle, - ThreadInformationClass threadInformationClass, - IntPtr threadInformation, - int threadInformationLength, - out int returnLength - ) - { - byte* inData = stackalloc byte[0x14]; - int returnLengthLocal; - - *(int*)inData = threadHandle; - *(int*)(inData + 0x4) = (int)threadInformationClass; - *(int*)(inData + 0x8) = threadInformation.ToInt32(); - *(int*)(inData + 0xc) = threadInformationLength; - *(int*)(inData + 0x10) = (int)&returnLengthLocal; - - try - { - _fileHandle.IoControl(CtlCode(Control.KphQueryInformationThread), inData, 0x14, null, 0); - } - finally - { - returnLength = returnLengthLocal; - } - } - - public void KphQueryProcessHandles(ProcessHandle processHandle, IntPtr buffer, int bufferLength, out int returnLength) - { - byte* inData = stackalloc byte[0x10]; - int returnLengthLocal; - - *(int*)inData = processHandle; - *(int*)(inData + 0x4) = buffer.ToInt32(); - *(int*)(inData + 0x8) = bufferLength; - *(int*)(inData + 0xc) = (int)&returnLengthLocal; - - try - { - _fileHandle.IoControl(CtlCode(Control.KphQueryProcessHandles), inData, 0x10, null, 0); - } - finally - { - returnLength = returnLengthLocal; - } - } - - public void KphReadVirtualMemory(ProcessHandle processHandle, int baseAddress, byte[] buffer, int length, out int bytesRead) - { - fixed (byte* bufferPtr = buffer) - { - this.KphReadVirtualMemory(processHandle, baseAddress, new IntPtr(bufferPtr), length, out bytesRead); - } - } - - public void KphReadVirtualMemory(ProcessHandle processHandle, int baseAddress, IntPtr buffer, int length, out int bytesRead) - { - NtStatus status; - - status = KphReadVirtualMemorySafe(processHandle, baseAddress, buffer, length, out bytesRead); - - if (status >= NtStatus.Error) - Win32.Throw(status); - } - - public NtStatus KphReadVirtualMemorySafe(ProcessHandle processHandle, int baseAddress, IntPtr buffer, int length, out int bytesRead) - { - NtStatus status; - byte* inData = stackalloc byte[0x14]; - int returnLength; - int br; - - *(int*)inData = processHandle; - *(int*)(inData + 0x4) = baseAddress; - *(int*)(inData + 0x8) = (int)buffer; - *(int*)(inData + 0xc) = length; - *(int*)(inData + 0x10) = (int)&br; - - status = _fileHandle.IoControl(CtlCode(Control.KphReadVirtualMemory), (IntPtr)inData, 0x14, IntPtr.Zero, 0, out returnLength); - - bytesRead = br; - - return status; - } - - public NtStatus KphReadVirtualMemoryUnsafe(ProcessHandle processHandle, int baseAddress, void* buffer, int length, out int bytesRead) - { - return KphReadVirtualMemoryUnsafe(processHandle, baseAddress, new IntPtr(buffer), length, out bytesRead); - } - - public NtStatus KphReadVirtualMemoryUnsafe(ProcessHandle processHandle, int baseAddress, IntPtr buffer, int length, out int bytesRead) - { - NtStatus status; - byte* inData = stackalloc byte[0x14]; - int returnLength; - int br; - - *(int*)inData = processHandle; - *(int*)(inData + 0x4) = baseAddress; - *(int*)(inData + 0x8) = (int)buffer; - *(int*)(inData + 0xc) = length; - *(int*)(inData + 0x10) = (int)&br; - - status = _fileHandle.IoControl(CtlCode(Control.KphUnsafeReadVirtualMemory), (IntPtr)inData, 0x14, IntPtr.Zero, 0, out returnLength); - - bytesRead = br; - - return status; - } - - public void KphResumeProcess(ProcessHandle processHandle) - { - int processHandleInt = processHandle; - - _fileHandle.IoControl(CtlCode(Control.KphResumeProcess), - (byte*)&processHandleInt, 4, null, 0); - } - - public void KphSetContextThread(ThreadHandle threadHandle, Context* context) - { - byte* inData = stackalloc byte[8]; - - *(int*)inData = threadHandle; - *(int*)(inData + 4) = (int)context; - - _fileHandle.IoControl(CtlCode(Control.KphSetContextThread), inData, 8, null, 0); - } - - public void KphSetHandleGrantedAccess(IntPtr handle, int grantedAccess) - { - byte* inData = stackalloc byte[8]; - - *(int*)inData = handle.ToInt32(); - *(int*)(inData + 4) = grantedAccess; - - _fileHandle.IoControl(CtlCode(Control.KphSetHandleGrantedAccess), inData, 8, null, 0); - } - - public void KphSetInformationProcess( - ProcessHandle processHandle, - ProcessInformationClass processInformationClass, - IntPtr processInformation, - int processInformationLength - ) - { - byte* inData = stackalloc byte[0x10]; - - *(int*)inData = processHandle; - *(int*)(inData + 0x4) = (int)processInformationClass; - *(int*)(inData + 0x8) = processInformation.ToInt32(); - *(int*)(inData + 0xc) = processInformationLength; - - _fileHandle.IoControl(CtlCode(Control.KphSetInformationProcess), inData, 0x10, null, 0); - } - - public void KphSetInformationThread( - ThreadHandle threadHandle, - ThreadInformationClass threadInformationClass, - IntPtr threadInformation, - int threadInformationLength - ) - { - byte* inData = stackalloc byte[0x10]; - - *(int*)inData = threadHandle; - *(int*)(inData + 0x4) = (int)threadInformationClass; - *(int*)(inData + 0x8) = threadInformation.ToInt32(); - *(int*)(inData + 0xc) = threadInformationLength; - - _fileHandle.IoControl(CtlCode(Control.KphSetInformationThread), inData, 0x10, null, 0); + public IntPtr ProcessHandle; } public void KphSuspendProcess(ProcessHandle processHandle) { - int processHandleInt = processHandle; + KphSuspendProcessInput input; - _fileHandle.IoControl(CtlCode(Control.KphSuspendProcess), - (byte*)&processHandleInt, 4, null, 0); + input.ProcessHandle = processHandle; + _fileHandle.IoControl(IoCtlSuspendProcess, &input, sizeof(KphSuspendProcessInput), null, 0); + } + + [StructLayout(LayoutKind.Sequential)] + private struct KphResumeProcessInput + { + public IntPtr ProcessHandle; + } + + public void KphResumeProcess(ProcessHandle processHandle) + { + KphResumeProcessInput input; + + input.ProcessHandle = processHandle; + _fileHandle.IoControl(IoCtlResumeProcess, &input, sizeof(KphResumeProcessInput), null, 0); + } + + [StructLayout(LayoutKind.Sequential)] + private struct KphTerminateProcessInput + { + public IntPtr ProcessHandle; + public NtStatus ExitStatus; } public void KphTerminateProcess(ProcessHandle processHandle, NtStatus exitStatus) { - byte* inData = stackalloc byte[8]; + KphTerminateProcessInput input; - *(int*)inData = processHandle; - *(int*)(inData + 4) = (int)exitStatus; - - try - { - _fileHandle.IoControl(CtlCode(Control.KphTerminateProcess), inData, 8, null, 0); - } - catch (WindowsException ex) - { - // STATUS_CANT_TERMINATE_SELF means we tried to terminate ourself. Kernel-mode can't do it, - // so we do it now. - if (ex.Status == NtStatus.CantTerminateSelf) - Win32.TerminateProcess(new IntPtr(-1), (int)exitStatus); - else - throw ex; - } + input.ProcessHandle = processHandle; + input.ExitStatus = exitStatus; + _fileHandle.IoControl(IoCtlTerminateProcess, &input, sizeof(KphTerminateProcessInput), null, 0); } - public void KphTerminateThread(ThreadHandle threadHandle, NtStatus exitStatus) + [StructLayout(LayoutKind.Sequential)] + private struct KphReadVirtualMemoryInput { - byte* inData = stackalloc byte[8]; - - *(int*)inData = threadHandle; - *(int*)(inData + 4) = (int)exitStatus; - - try - { - _fileHandle.IoControl(CtlCode(Control.KphTerminateThread), inData, 8, null, 0); - } - catch (WindowsException ex) - { - if (ex.Status == NtStatus.CantTerminateSelf) - Win32.TerminateThread(new IntPtr(-2), (int)exitStatus); - else - throw ex; - } + public IntPtr ProcessHandle; + public IntPtr BaseAddress; + public IntPtr Buffer; + public IntPtr BufferSize; + public IntPtr* NumberOfBytesRead; } - public void KphWriteVirtualMemory(ProcessHandle processHandle, int baseAddress, byte[] buffer, int length, out int bytesWritten) + public void KphReadVirtualMemory(ProcessHandle processHandle, IntPtr baseAddress, IntPtr buffer, IntPtr bufferSize, out IntPtr numberOfBytesRead) { - fixed (byte* bufferPtr = buffer) - this.KphWriteVirtualMemory(processHandle, baseAddress, new IntPtr(bufferPtr), length, out bytesWritten); + KphReadVirtualMemoryInput input; + + input.ProcessHandle = processHandle; + input.BaseAddress = baseAddress; + input.Buffer = buffer; + input.BufferSize = bufferSize; + input.NumberOfBytesRead = &numberOfBytesRead; + _fileHandle.IoControl(IoCtlReadVirtualMemory, &input, sizeof(KphReadVirtualMemoryInput), null, 0); } - public void KphWriteVirtualMemory(ProcessHandle processHandle, int baseAddress, IntPtr buffer, int length, out int bytesWritten) + [StructLayout(LayoutKind.Sequential)] + private struct KphWriteVirtualMemoryInput { - byte* inData = stackalloc byte[0x14]; - int returnLength; - - *(int*)inData = processHandle; - *(int*)(inData + 0x4) = baseAddress; - *(int*)(inData + 0x8) = (int)buffer; - *(int*)(inData + 0xc) = length; - *(int*)(inData + 0x10) = (int)&returnLength; - - try - { - _fileHandle.IoControl(CtlCode(Control.KphWriteVirtualMemory), inData, 0x14, null, 0); - } - finally - { - bytesWritten = returnLength; - } + public IntPtr ProcessHandle; + public IntPtr BaseAddress; + public IntPtr Buffer; + public IntPtr BufferSize; + public IntPtr* NumberOfBytesWritten; } - public void ProtectAdd(ProcessHandle processHandle, bool allowKernelMode, ProcessAccess ProcessAllowMask, ThreadAccess ThreadAllowMask) + public void KphWriteVirtualMemory(ProcessHandle processHandle, IntPtr baseAddress, IntPtr buffer, IntPtr bufferSize, out IntPtr numberOfBytesWritten) { - byte* inData = stackalloc byte[16]; + KphWriteVirtualMemoryInput input; - *(int*)inData = processHandle; - *(int*)(inData + 0x4) = allowKernelMode ? 1 : 0; - *(int*)(inData + 0x8) = (int)ProcessAllowMask; - *(int*)(inData + 0xc) = (int)ThreadAllowMask; - - _fileHandle.IoControl(CtlCode(Control.ProtectAdd), inData, 16, null, 0); + input.ProcessHandle = processHandle; + input.BaseAddress = baseAddress; + input.Buffer = buffer; + input.BufferSize = bufferSize; + input.NumberOfBytesWritten = &numberOfBytesWritten; + _fileHandle.IoControl(IoCtlWriteVirtualMemory, &input, sizeof(KphWriteVirtualMemoryInput), null, 0); } - public void ProtectQuery(ProcessHandle processHandle, out bool AllowKernelMode, out ProcessAccess ProcessAllowMask, out ThreadAccess ThreadAllowMask) + [StructLayout(LayoutKind.Sequential)] + private struct KphReadVirtualMemoryUnsafeInput { - byte* inData = stackalloc byte[16]; - int allowKernelMode; - ProcessAccess processAllowMask; - ThreadAccess threadAllowMask; - - *(int*)inData = processHandle; - *(int*)(inData + 0x4) = (int)&allowKernelMode; - *(int*)(inData + 0x8) = (int)&processAllowMask; - *(int*)(inData + 0xc) = (int)&threadAllowMask; - - _fileHandle.IoControl(CtlCode(Control.ProtectQuery), inData, 16, null, 0); - - AllowKernelMode = allowKernelMode != 0; - ProcessAllowMask = processAllowMask; - ThreadAllowMask = threadAllowMask; + public IntPtr ProcessHandle; + public IntPtr BaseAddress; + public IntPtr Buffer; + public IntPtr BufferSize; + public IntPtr* NumberOfBytesRead; } - public void ProtectRemove(ProcessHandle processHandle) + public void KphReadVirtualMemoryUnsafe(ProcessHandle processHandle, IntPtr baseAddress, IntPtr buffer, IntPtr bufferSize, out IntPtr numberOfBytesRead) { - int processHandleInt = processHandle; + KphReadVirtualMemoryUnsafeInput input; - _fileHandle.IoControl(CtlCode(Control.ProtectRemove), - (byte*)&processHandleInt, 4, null, 0); + input.ProcessHandle = processHandle; + input.BaseAddress = baseAddress; + input.Buffer = buffer; + input.BufferSize = bufferSize; + input.NumberOfBytesRead = &numberOfBytesRead; + _fileHandle.IoControl(IoCtlReadVirtualMemoryUnsafe, &input, sizeof(KphReadVirtualMemoryUnsafeInput), null, 0); } - public void SetExecuteOptions(ProcessHandle processHandle, MemExecuteOptions executeOptions) + [StructLayout(LayoutKind.Sequential)] + private struct KphQueryInformationProcessInput { - byte* inData = stackalloc byte[8]; - - *(int*)inData = processHandle; - *(int*)(inData + 4) = (int)executeOptions; - - _fileHandle.IoControl(CtlCode(Control.SetExecuteOptions), inData, 8, null, 0); + public IntPtr ProcessHandle; + public KphProcessInformationClass ProcessInformationClass; + public IntPtr ProcessInformation; + public int ProcessInformationLength; + public int* ReturnLength; } - public void SetHandleAttributes(ProcessHandle processHandle, IntPtr handle, HandleFlags flags) + public void KphQueryInformationProcess(ProcessHandle processHandle, KphProcessInformationClass processInformationClass, IntPtr processInformation, int processInformationLength, out int returnLength) { - byte* inData = stackalloc byte[12]; + KphQueryInformationProcessInput input; - *(int*)inData = processHandle; - *(int*)(inData + 4) = handle.ToInt32(); - *(int*)(inData + 8) = (int)flags; - - _fileHandle.IoControl(CtlCode(Control.SetHandleAttributes), inData, 12, null, 0); + input.ProcessHandle = processHandle; + input.ProcessInformationClass = processInformationClass; + input.ProcessInformation = processInformation; + input.ProcessInformationLength = processInformationLength; + input.ReturnLength = returnLength; + _fileHandle.IoControl(IoCtlQueryInformationProcess, &input, sizeof(KphQueryInformationProcessInput), null, 0); } + } - public void SetProcessProtected(int pid, bool protecte) - { - byte* inData = stackalloc byte[5]; + public enum KphSecurityLevel + { + KphSecurityNone = 0, // all clients are allowed + KphSecurityPrivilegeCheck = 1, // require SeDebugPrivilege + KphMaxSecurityLevel + } - *(int*)inData = pid; - inData[4] = (byte)(protecte ? 1 : 0); + public enum KphProcessInformationClass + { + KphProcessProtectionInformation = 1, + KphProcessExecuteFlags = 2, + KphProcessIoPriority = 3, + MaxKphProcessInfoClass + } - _fileHandle.IoControl(CtlCode(Control.SetProcessProtected), inData, 5, null, 0); - } + [StructLayout(LayoutKind.Sequential)] + public struct KphProcessProtectionInformation + { + public byte IsProtectedProcess; + } - public void SetProcessToken(int sourcePid, int targetPid) - { - byte* inData = stackalloc byte[8]; + public enum KphThreadInformationClass + { + KphThreadWin32Thread = 1, + KphThreadImpersonationToken = 2, + KphThreadIoPriority = 3, + MaxKphThreadInfoClass + } - *(int*)inData = sourcePid; - *(int*)(inData + 4) = targetPid; + [StructLayout(LayoutKind.Sequential)] + public struct KphProcessHandle + { + public IntPtr Handle; + public IntPtr Object; + public int GrantedAccess; + public short ObjectTypeIndex; + public short Reserved1; + public int HandleAttributes; + private int Reserved2; + } - _fileHandle.IoControl(CtlCode(Control.SetProcessToken), inData, 8, null, 0); - } + [StructLayout(LayoutKind.Sequential)] + public struct KphProcessHandleInformation + { + public static readonly int HandlesOffset = + Marshal.OffsetOf(typeof(KphProcessHandleInformation), "Handles").ToInt32(); - public IntPtr SsAddProcessIdRule( - KphSsRuleSetEntryHandle ruleSetEntryHandle, - KphSsFilterType filterType, - IntPtr processId - ) - { - byte* inData = stackalloc byte[0xc]; - byte* outData = stackalloc byte[4]; + public int HandleCount; + public KphProcessHandle Handles; + } - *(int*)inData = ruleSetEntryHandle.Handle.ToInt32(); - *(int*)(inData + 0x4) = (int)filterType; - *(int*)(inData + 0x8) = processId.ToInt32(); - - _fileHandle.IoControl(CtlCode(Control.SsAddProcessIdRule), inData, 0xc, outData, 4); - - return (*(int*)outData).ToIntPtr(); - } - - public IntPtr SsAddThreadIdRule( - KphSsRuleSetEntryHandle ruleSetEntryHandle, - KphSsFilterType filterType, - IntPtr threadId - ) - { - byte* inData = stackalloc byte[0xc]; - byte* outData = stackalloc byte[4]; - - *(int*)inData = ruleSetEntryHandle.Handle.ToInt32(); - *(int*)(inData + 0x4) = (int)filterType; - *(int*)(inData + 0x8) = threadId.ToInt32(); - - _fileHandle.IoControl(CtlCode(Control.SsAddThreadIdRule), inData, 0xc, outData, 4); - - return (*(int*)outData).ToIntPtr(); - } - - public IntPtr SsAddPreviousModeRule( - KphSsRuleSetEntryHandle ruleSetEntryHandle, - KphSsFilterType filterType, - KProcessorMode previousMode - ) - { - byte* inData = stackalloc byte[0x9]; - byte* outData = stackalloc byte[4]; - - *(int*)inData = ruleSetEntryHandle.Handle.ToInt32(); - *(int*)(inData + 0x4) = (int)filterType; - *(byte*)(inData + 0x8) = (byte)previousMode; - - _fileHandle.IoControl(CtlCode(Control.SsAddPreviousModeRule), inData, 0x9, outData, 4); - - return (*(int*)outData).ToIntPtr(); - } - - public IntPtr SsAddNumberRule( - KphSsRuleSetEntryHandle ruleSetEntryHandle, - KphSsFilterType filterType, - int number - ) - { - byte* inData = stackalloc byte[0xc]; - byte* outData = stackalloc byte[4]; - - *(int*)inData = ruleSetEntryHandle.Handle.ToInt32(); - *(int*)(inData + 0x4) = (int)filterType; - *(int*)(inData + 0x8) = number; - - _fileHandle.IoControl(CtlCode(Control.SsAddNumberRule), inData, 0xc, outData, 4); - - return (*(int*)outData).ToIntPtr(); - } - - public KphSsClientEntryHandle SsCreateClientEntry( - ProcessHandle processHandle, - SemaphoreHandle readSemaphoreHandle, - SemaphoreHandle writeSemaphoreHandle, - IntPtr bufferBase, - int bufferSize - ) - { - byte* inData = stackalloc byte[0x14]; - byte* outData = stackalloc byte[4]; - - *(int*)inData = processHandle; - *(int*)(inData + 0x4) = readSemaphoreHandle; - *(int*)(inData + 0x8) = writeSemaphoreHandle; - *(int*)(inData + 0xc) = bufferBase.ToInt32(); - *(int*)(inData + 0x10) = bufferSize; - - _fileHandle.IoControl(CtlCode(Control.SsCreateClientEntry), inData, 0x14, outData, 4); - - return new KphSsClientEntryHandle((*(int*)outData).ToIntPtr()); - } - - public KphSsRuleSetEntryHandle SsCreateRuleSetEntry( - KphSsClientEntryHandle clientEntryHandle, - KphSsFilterType defaultFilterType, - KphSsRuleSetAction action - ) - { - byte* inData = stackalloc byte[0xc]; - byte* outData = stackalloc byte[4]; - - *(int*)inData = clientEntryHandle.Handle.ToInt32(); - *(int*)(inData + 0x4) = (int)defaultFilterType; - *(int*)(inData + 0x8) = (int)action; - - _fileHandle.IoControl(CtlCode(Control.SsCreateRuleSetEntry), inData, 0xc, outData, 4); - - return new KphSsRuleSetEntryHandle((*(int*)outData).ToIntPtr()); - } - - public void SsEnableClientEntry( - KphSsClientEntryHandle clientEntryHandle, - bool enable - ) - { - byte* inData = stackalloc byte[5]; - - *(int*)inData = clientEntryHandle.Handle.ToInt32(); - *(byte*)(inData + 4) = (byte)(enable ? 1 : 0); - - _fileHandle.IoControl(CtlCode(Control.SsEnableClientEntry), inData, 5, null, 0); - } - - public void SsQueryClientEntry( - KphSsClientEntryHandle clientEntryHandle, - out KphSsClientInformation clientInformation, - int clientInformationLength, - out int returnLength - ) - { - fixed (KphSsClientInformation *clientInfoPtr = &clientInformation) - fixed (int* retLengthPtr = &returnLength) - { - byte* inData = stackalloc byte[0x10]; - - *(int*)inData = clientEntryHandle.Handle.ToInt32(); - *(int*)(inData + 0x4) = (int)clientInfoPtr; - *(int*)(inData + 0x8) = clientInformationLength; - *(int*)(inData + 0xc) = (int)retLengthPtr; - - _fileHandle.IoControl(CtlCode(Control.SsQueryClientEntry), inData, 0x10, null, 0); - } - } - - public void SsRemoveRule( - KphSsRuleSetEntryHandle ruleSetEntryHandle, - IntPtr ruleEntryHandle - ) - { - byte* inData = stackalloc byte[8]; - - *(int*)inData = ruleSetEntryHandle.Handle.ToInt32(); - *(int*)(inData + 4) = ruleEntryHandle.ToInt32(); - - _fileHandle.IoControl(CtlCode(Control.SsRemoveRule), inData, 8, null, 0); - } - - public void SsRef() - { - _fileHandle.IoControl(CtlCode(Control.SsRef), null, null); - } - - public void SsUnref() - { - _fileHandle.IoControl(CtlCode(Control.SsUnref), null, null); - } - - public NtStatus ZwQueryObject( - ProcessHandle processHandle, - IntPtr handle, - ObjectInformationClass objectInformationClass, - IntPtr buffer, - int bufferLength, - out int returnLength, - out int baseAddress - ) - { - byte* inData = stackalloc byte[12]; - byte[] outData = new byte[bufferLength + 12]; - - *(int*)inData = processHandle; - *(int*)(inData + 4) = handle.ToInt32(); - *(int*)(inData + 8) = (int)objectInformationClass; - - _fileHandle.IoControl(CtlCode(Control.ZwQueryObject), inData, 12, outData); - - NtStatus status; - - fixed (byte* outDataPtr = outData) - { - status = *(NtStatus*)outDataPtr; - returnLength = *(int*)(outDataPtr + 4); - baseAddress = *(int*)(outDataPtr + 8); - } - - if (buffer != IntPtr.Zero) - Marshal.Copy(outData, 12, buffer, bufferLength); - - return status; - } + public enum KphObjectInformationClass + { + KphObjectBasicInformation, + KphObjectNameInformation, + KphObjectTypeInformation, + KphObjectHandleFlagInformation, + KphObjectProcessBasicInformation, + KphObjectThreadBasicInformation, + KphObjectEtwRegBasicInformation, + MaxKphObjectInfoClass } public enum DriverInformationClass { - DriverBasicInformation = 0, + DriverBasicInformation, DriverNameInformation, - DriverServiceKeyNameInformation - } - - public class KphHandle : BaseObject - { - private IntPtr _handle; - - protected KphHandle(IntPtr handle) - { - _handle = handle; - } - - protected override void DisposeObject(bool disposing) - { - KProcessHacker.Instance.ClientCloseHandle(_handle); - } - - public IntPtr Handle - { - get { return _handle; } - } + DriverServiceKeyNameInformation, + MaxDriverInfoClass } [StructLayout(LayoutKind.Sequential)] @@ -1211,19 +506,21 @@ namespace ProcessHacker.Native } [StructLayout(LayoutKind.Sequential)] - public struct ProcessHandleInformation + public struct DriverBasicInformation { - public IntPtr Handle; - public IntPtr Object; - public int GrantedAccess; - public HandleFlags HandleAttributes; // should be an int - private byte Pad1; - private short Pad2; + public UnicodeString DriverName; + } - private void Dummy() - { - Pad1 = 0; - Pad2 = 0; - } + [StructLayout(LayoutKind.Sequential)] + public struct DriverServiceKeyNameInformation + { + public UnicodeString ServiceKeyName; + } + + [StructLayout(LayoutKind.Sequential)] + public struct EtwRegBasicInformation + { + public Guid Guid; + public IntPtr SessionId; } } diff --git a/1.x/trunk/ProcessHacker.Native/Objects/ProcessHandle.cs b/1.x/trunk/ProcessHacker.Native/Objects/ProcessHandle.cs index c3dbd7468..7421e1038 100644 --- a/1.x/trunk/ProcessHacker.Native/Objects/ProcessHandle.cs +++ b/1.x/trunk/ProcessHacker.Native/Objects/ProcessHandle.cs @@ -1431,7 +1431,7 @@ namespace ProcessHacker.Native.Objects /// Gets the handles owned by the process. /// /// An array of handle information structures. - public ProcessHandleInformation[] GetHandles() + public KphProcessHandle[] GetHandles() { int returnLength = 0; int attempts = 0; @@ -1461,10 +1461,10 @@ namespace ProcessHacker.Native.Objects } int handleCount = data.ReadInt32(0); - ProcessHandleInformation[] handles = new ProcessHandleInformation[handleCount]; + KphProcessHandle[] handles = new KphProcessHandle[handleCount]; for (int i = 0; i < handleCount; i++) - handles[i] = data.ReadStruct(sizeof(int), i); + handles[i] = data.ReadStruct(sizeof(int), i); return handles; } diff --git a/1.x/trunk/ProcessHacker.Native/ProcessHacker.Native.csproj b/1.x/trunk/ProcessHacker.Native/ProcessHacker.Native.csproj index b610447fd..e918dbb0b 100644 --- a/1.x/trunk/ProcessHacker.Native/ProcessHacker.Native.csproj +++ b/1.x/trunk/ProcessHacker.Native/ProcessHacker.Native.csproj @@ -3,7 +3,7 @@ Debug AnyCPU - 9.0.30729 + 9.0.21022 2.0 {8A448157-E1A7-4DDF-954E-287F1117832B} Library