diff --git a/1.x/trunk/ProcessHacker.Native/KProcessHacker.cs b/1.x/trunk/ProcessHacker.Native/KProcessHacker.cs
index 79650b406..2d3d6b06c 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-2011 wj32
+ * Copyright (C) 2009 wj32
*
* This file is part of Process Hacker.
*
@@ -48,55 +48,87 @@ namespace ProcessHacker.Native
set { _instance = value; }
}
- public static int KphCtlCode(int x)
+ ///
+ /// A control code used by KProcessHacker to represent a specific function.
+ ///
+ private enum Control : uint
{
- return Win32.CtlCode(KphDeviceType, 0x800 + x, DeviceControlMethod.Neither, DeviceControlAccess.Any);
+ 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,
}
- 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
{
- None = 0 // none so far
+ PsTerminateProcess = 0x1,
+ PspTerminateThreadByPointer = 0x2
}
private string _deviceName;
private FileHandle _fileHandle;
+ private uint _baseControlNumber;
private KphFeatures _features;
///
/// Creates a connection to KProcessHacker.
///
public KProcessHacker()
- : this("KProcessHacker2")
+ : this("KProcessHacker")
{ }
///
@@ -116,6 +148,9 @@ namespace ProcessHacker.Native
{
_deviceName = deviceName;
+ if (OSVersion.Architecture != OSArch.I386)
+ throw new NotSupportedException("KProcessHacker does not support 64-bit Windows.");
+
try
{
_fileHandle = new FileHandle(
@@ -138,7 +173,7 @@ namespace ProcessHacker.Native
try
{
- using (shandle = new ServiceHandle(deviceName, ServiceAccess.Start))
+ using (shandle = new ServiceHandle("KProcessHacker", ServiceAccess.Start))
{
shandle.Start();
}
@@ -187,7 +222,18 @@ namespace ProcessHacker.Native
}
_fileHandle.SetHandleFlags(Win32HandleFlags.ProtectFromClose, Win32HandleFlags.ProtectFromClose);
- _features = this.KphGetFeatures();
+
+ byte[] bytes = _fileHandle.Read(4);
+
+ fixed (byte* bytesPtr = bytes)
+ _baseControlNumber = *(uint*)bytesPtr;
+
+ try
+ {
+ _features = this.GetFeatures();
+ }
+ catch
+ { }
}
public string DeviceName
@@ -200,6 +246,11 @@ namespace ProcessHacker.Native
get { return _features; }
}
+ private int CtlCode(Control ctl)
+ {
+ return (int)(_baseControlNumber + ((uint)ctl * 4));
+ }
+
///
/// Closes the connection to KProcessHacker.
///
@@ -209,292 +260,946 @@ namespace ProcessHacker.Native
_fileHandle.Dispose();
}
- [StructLayout(LayoutKind.Sequential)]
- private struct KphGetFeaturesInput
+ public void ClientCloseHandle(IntPtr handle)
{
- public int* Features;
+ byte* inData = stackalloc byte[4];
+
+ *(int*)inData = handle.ToInt32();
+
+ _fileHandle.IoControl(CtlCode(Control.ClientCloseHandle), inData, 4, null, 0);
}
- public KphFeatures KphGetFeatures()
+ public KphFeatures GetFeatures()
{
- KphGetFeaturesInput input;
- int features;
+ byte* outData = stackalloc byte[4];
- input.Features = &features;
- _fileHandle.IoControl(IoCtlGetFeatures, &input, sizeof(KphGetFeaturesInput), null, 0);
+ _fileHandle.IoControl(CtlCode(Control.GetFeatures), null, 0, outData, 4);
- return (KphFeatures)features;
+ return (KphFeatures)(*(int*)outData);
}
- [StructLayout(LayoutKind.Sequential)]
- private struct KphOpenProcessInput
+ public string GetHandleObjectName(ProcessHandle processHandle, IntPtr handle)
{
- public IntPtr* ProcessHandle;
- public int DesiredAccess;
- public ClientId* ClientId;
+ 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 KphOpenProcess(int pid, ProcessAccess desiredAccess)
+ public bool GetProcessProtected(int pid)
{
- KphOpenProcessInput input;
- IntPtr processHandle;
- ClientId clientId;
+ byte[] result = new byte[1];
- clientId.ProcessId = pid;
- clientId.ThreadId = 0;
+ _fileHandle.IoControl(CtlCode(Control.GetProcessProtected),
+ (byte*)&pid, 4, result);
- input.ProcessHandle = &processHandle;
- input.DesiredAccess = (int)desiredAccess;
- input.ClientId = &clientId;
- _fileHandle.IoControl(IoCtlOpenProcess, &input, sizeof(KphOpenProcessInput), null, 0);
-
- return processHandle;
+ return result[0] != 0;
}
- [StructLayout(LayoutKind.Sequential)]
- private struct KphOpenProcessTokenInput
+ public uint GetThreadStartAddress(ThreadHandle threadHandle)
{
- public IntPtr ProcessHandle;
- public int DesiredAccess;
- public IntPtr* TokenHandle;
+ byte* outData = stackalloc byte[4];
+ int threadHandleInt = threadHandle;
+
+ _fileHandle.IoControl(CtlCode(Control.GetThreadStartAddress),
+ (byte*)&threadHandleInt, 4, outData, 4);
+
+ return *(uint*)outData;
}
- public IntPtr KphOpenProcessToken(ProcessHandle processHandle, TokenAccess desiredAccess)
+ public void KphAssignImpersonationToken(ThreadHandle threadHandle, TokenHandle tokenHandle)
{
- KphOpenProcessTokenInput input;
- IntPtr tokenHandle;
+ byte* inData = stackalloc byte[8];
- input.ProcessHandle = processHandle;
- input.DesiredAccess = (int)desiredAccess;
- input.TokenHandle = &tokenHandle;
- _fileHandle.IoControl(IoCtlOpenProcessToken, &input, sizeof(KphOpenProcessTokenInput), null, 0);
+ *(int*)inData = threadHandle;
+ *(int*)(inData + 4) = tokenHandle;
- return tokenHandle;
+ _fileHandle.IoControl(CtlCode(Control.KphAssignImpersonationToken), inData, 8, null, 0);
}
- [StructLayout(LayoutKind.Sequential)]
- private struct KphOpenProcessJobInput
+ public unsafe int KphCaptureStackBackTraceThread(
+ ThreadHandle threadHandle,
+ int framesToSkip,
+ int framesToCapture,
+ IntPtr[] backTrace,
+ out int backTraceHash
+ )
{
- public IntPtr ProcessHandle;
- public int DesiredAccess;
- public IntPtr* JobHandle;
+ 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 KphOpenProcessJob(ProcessHandle processHandle, TokenAccess desiredAccess)
+ public void KphDangerousTerminateThread(ThreadHandle threadHandle, NtStatus exitStatus)
{
- KphOpenProcessJobInput input;
- IntPtr jobHandle;
+ byte* inData = stackalloc byte[8];
- input.ProcessHandle = processHandle;
- input.DesiredAccess = (int)desiredAccess;
- input.JobHandle = &jobHandle;
- _fileHandle.IoControl(IoCtlOpenProcessJob, &input, sizeof(KphOpenProcessJobInput), null, 0);
+ *(int*)inData = threadHandle;
+ *(int*)(inData + 4) = (int)exitStatus;
- return jobHandle;
+ _fileHandle.IoControl(CtlCode(Control.KphDangerousTerminateThread), inData, 8, null, 0);
}
- [StructLayout(LayoutKind.Sequential)]
- private struct KphSuspendProcessInput
+ public void KphDuplicateObject(
+ int sourceProcessHandle,
+ int sourceHandle,
+ int targetProcessHandle,
+ out int targetHandle,
+ int desiredAccess,
+ HandleFlags handleAttributes,
+ DuplicateOptions options
+ )
{
- public IntPtr ProcessHandle;
+ int handle;
+
+ KphDuplicateObject(
+ sourceProcessHandle,
+ sourceHandle,
+ targetProcessHandle,
+ (int)&handle,
+ desiredAccess,
+ handleAttributes,
+ options
+ );
+
+ targetHandle = handle;
}
- public void KphSuspendProcess(ProcessHandle processHandle)
+ public void KphDuplicateObject(
+ int sourceProcessHandle,
+ int sourceHandle,
+ int targetProcessHandle,
+ int targetHandle,
+ int desiredAccess,
+ HandleFlags handleAttributes,
+ DuplicateOptions options
+ )
{
- KphSuspendProcessInput input;
+ byte[] data = new byte[7 * sizeof(int)];
- input.ProcessHandle = processHandle;
- _fileHandle.IoControl(IoCtlSuspendProcess, &input, sizeof(KphSuspendProcessInput), null, 0);
+ 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);
+ }
}
- [StructLayout(LayoutKind.Sequential)]
- private struct KphResumeProcessInput
+ public void KphGetContextThread(ThreadHandle threadHandle, Context* context)
{
- public IntPtr ProcessHandle;
+ 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)
{
- KphResumeProcessInput input;
+ int processHandleInt = processHandle;
- input.ProcessHandle = processHandle;
- _fileHandle.IoControl(IoCtlResumeProcess, &input, sizeof(KphResumeProcessInput), null, 0);
+ _fileHandle.IoControl(CtlCode(Control.KphResumeProcess),
+ (byte*)&processHandleInt, 4, null, 0);
}
- [StructLayout(LayoutKind.Sequential)]
- private struct KphTerminateProcessInput
+ public void KphSetContextThread(ThreadHandle threadHandle, Context* context)
{
- public IntPtr ProcessHandle;
- public NtStatus ExitStatus;
+ 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 void KphSuspendProcess(ProcessHandle processHandle)
+ {
+ int processHandleInt = processHandle;
+
+ _fileHandle.IoControl(CtlCode(Control.KphSuspendProcess),
+ (byte*)&processHandleInt, 4, null, 0);
}
public void KphTerminateProcess(ProcessHandle processHandle, NtStatus exitStatus)
{
- KphTerminateProcessInput input;
+ byte* inData = stackalloc byte[8];
- input.ProcessHandle = processHandle;
- input.ExitStatus = exitStatus;
- _fileHandle.IoControl(IoCtlTerminateProcess, &input, sizeof(KphTerminateProcessInput), null, 0);
+ *(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;
+ }
}
- [StructLayout(LayoutKind.Sequential)]
- private struct KphReadVirtualMemoryInput
+ public void KphTerminateThread(ThreadHandle threadHandle, NtStatus exitStatus)
{
- public IntPtr ProcessHandle;
- public IntPtr BaseAddress;
- public IntPtr Buffer;
- public IntPtr BufferSize;
- public IntPtr* NumberOfBytesRead;
+ 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 void KphReadVirtualMemory(ProcessHandle processHandle, IntPtr baseAddress, IntPtr buffer, IntPtr bufferSize, out IntPtr numberOfBytesRead)
+ public void KphWriteVirtualMemory(ProcessHandle processHandle, int baseAddress, byte[] buffer, int length, out int 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);
+ fixed (byte* bufferPtr = buffer)
+ this.KphWriteVirtualMemory(processHandle, baseAddress, new IntPtr(bufferPtr), length, out bytesWritten);
}
- [StructLayout(LayoutKind.Sequential)]
- private struct KphWriteVirtualMemoryInput
+ public void KphWriteVirtualMemory(ProcessHandle processHandle, int baseAddress, IntPtr buffer, int length, out int bytesWritten)
{
- public IntPtr ProcessHandle;
- public IntPtr BaseAddress;
- public IntPtr Buffer;
- public IntPtr BufferSize;
- public IntPtr* NumberOfBytesWritten;
+ 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 void KphWriteVirtualMemory(ProcessHandle processHandle, IntPtr baseAddress, IntPtr buffer, IntPtr bufferSize, out IntPtr numberOfBytesWritten)
+ public void ProtectAdd(ProcessHandle processHandle, bool allowKernelMode, ProcessAccess ProcessAllowMask, ThreadAccess ThreadAllowMask)
{
- KphWriteVirtualMemoryInput input;
+ byte* inData = stackalloc byte[16];
- input.ProcessHandle = processHandle;
- input.BaseAddress = baseAddress;
- input.Buffer = buffer;
- input.BufferSize = bufferSize;
- input.NumberOfBytesWritten = &numberOfBytesWritten;
- _fileHandle.IoControl(IoCtlWriteVirtualMemory, &input, sizeof(KphWriteVirtualMemoryInput), null, 0);
+ *(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);
}
- [StructLayout(LayoutKind.Sequential)]
- private struct KphReadVirtualMemoryUnsafeInput
+ public void ProtectQuery(ProcessHandle processHandle, out bool AllowKernelMode, out ProcessAccess ProcessAllowMask, out ThreadAccess ThreadAllowMask)
{
- public IntPtr ProcessHandle;
- public IntPtr BaseAddress;
- public IntPtr Buffer;
- public IntPtr BufferSize;
- public IntPtr* NumberOfBytesRead;
+ 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 void KphReadVirtualMemoryUnsafe(ProcessHandle processHandle, IntPtr baseAddress, IntPtr buffer, IntPtr bufferSize, out IntPtr numberOfBytesRead)
+ public void ProtectRemove(ProcessHandle processHandle)
{
- KphReadVirtualMemoryUnsafeInput input;
+ int processHandleInt = processHandle;
- input.ProcessHandle = processHandle;
- input.BaseAddress = baseAddress;
- input.Buffer = buffer;
- input.BufferSize = bufferSize;
- input.NumberOfBytesRead = &numberOfBytesRead;
- _fileHandle.IoControl(IoCtlReadVirtualMemoryUnsafe, &input, sizeof(KphReadVirtualMemoryUnsafeInput), null, 0);
+ _fileHandle.IoControl(CtlCode(Control.ProtectRemove),
+ (byte*)&processHandleInt, 4, null, 0);
}
- [StructLayout(LayoutKind.Sequential)]
- private struct KphQueryInformationProcessInput
+ public void SetExecuteOptions(ProcessHandle processHandle, MemExecuteOptions executeOptions)
{
- public IntPtr ProcessHandle;
- public KphProcessInformationClass ProcessInformationClass;
- public IntPtr ProcessInformation;
- public int ProcessInformationLength;
- public int* ReturnLength;
+ byte* inData = stackalloc byte[8];
+
+ *(int*)inData = processHandle;
+ *(int*)(inData + 4) = (int)executeOptions;
+
+ _fileHandle.IoControl(CtlCode(Control.SetExecuteOptions), inData, 8, null, 0);
}
- public void KphQueryInformationProcess(ProcessHandle processHandle, KphProcessInformationClass processInformationClass, IntPtr processInformation, int processInformationLength, out int returnLength)
+ public void SetHandleAttributes(ProcessHandle processHandle, IntPtr handle, HandleFlags flags)
{
- KphQueryInformationProcessInput input;
+ byte* inData = stackalloc byte[12];
- input.ProcessHandle = processHandle;
- input.ProcessInformationClass = processInformationClass;
- input.ProcessInformation = processInformation;
- input.ProcessInformationLength = processInformationLength;
- input.ReturnLength = returnLength;
- _fileHandle.IoControl(IoCtlQueryInformationProcess, &input, sizeof(KphQueryInformationProcessInput), null, 0);
+ *(int*)inData = processHandle;
+ *(int*)(inData + 4) = handle.ToInt32();
+ *(int*)(inData + 8) = (int)flags;
+
+ _fileHandle.IoControl(CtlCode(Control.SetHandleAttributes), inData, 12, null, 0);
}
- }
- public enum KphSecurityLevel
- {
- KphSecurityNone = 0, // all clients are allowed
- KphSecurityPrivilegeCheck = 1, // require SeDebugPrivilege
- KphMaxSecurityLevel
- }
+ public void SetProcessProtected(int pid, bool protecte)
+ {
+ byte* inData = stackalloc byte[5];
- public enum KphProcessInformationClass
- {
- KphProcessProtectionInformation = 1,
- KphProcessExecuteFlags = 2,
- KphProcessIoPriority = 3,
- MaxKphProcessInfoClass
- }
+ *(int*)inData = pid;
+ inData[4] = (byte)(protecte ? 1 : 0);
- [StructLayout(LayoutKind.Sequential)]
- public struct KphProcessProtectionInformation
- {
- public byte IsProtectedProcess;
- }
+ _fileHandle.IoControl(CtlCode(Control.SetProcessProtected), inData, 5, null, 0);
+ }
- public enum KphThreadInformationClass
- {
- KphThreadWin32Thread = 1,
- KphThreadImpersonationToken = 2,
- KphThreadIoPriority = 3,
- MaxKphThreadInfoClass
- }
+ public void SetProcessToken(int sourcePid, int targetPid)
+ {
+ byte* inData = stackalloc byte[8];
- [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;
- }
+ *(int*)inData = sourcePid;
+ *(int*)(inData + 4) = targetPid;
- [StructLayout(LayoutKind.Sequential)]
- public struct KphProcessHandleInformation
- {
- public static readonly int HandlesOffset =
- Marshal.OffsetOf(typeof(KphProcessHandleInformation), "Handles").ToInt32();
+ _fileHandle.IoControl(CtlCode(Control.SetProcessToken), inData, 8, null, 0);
+ }
- public int HandleCount;
- public KphProcessHandle Handles;
- }
+ public IntPtr SsAddProcessIdRule(
+ KphSsRuleSetEntryHandle ruleSetEntryHandle,
+ KphSsFilterType filterType,
+ IntPtr processId
+ )
+ {
+ byte* inData = stackalloc byte[0xc];
+ byte* outData = stackalloc byte[4];
- public enum KphObjectInformationClass
- {
- KphObjectBasicInformation,
- KphObjectNameInformation,
- KphObjectTypeInformation,
- KphObjectHandleFlagInformation,
- KphObjectProcessBasicInformation,
- KphObjectThreadBasicInformation,
- KphObjectEtwRegBasicInformation,
- MaxKphObjectInfoClass
+ *(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 DriverInformationClass
{
- DriverBasicInformation,
+ DriverBasicInformation = 0,
DriverNameInformation,
- DriverServiceKeyNameInformation,
- MaxDriverInfoClass
+ 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; }
+ }
}
[StructLayout(LayoutKind.Sequential)]
@@ -506,21 +1211,19 @@ namespace ProcessHacker.Native
}
[StructLayout(LayoutKind.Sequential)]
- public struct DriverBasicInformation
+ public struct ProcessHandleInformation
{
- public UnicodeString DriverName;
- }
+ public IntPtr Handle;
+ public IntPtr Object;
+ public int GrantedAccess;
+ public HandleFlags HandleAttributes; // should be an int
+ private byte Pad1;
+ private short Pad2;
- [StructLayout(LayoutKind.Sequential)]
- public struct DriverServiceKeyNameInformation
- {
- public UnicodeString ServiceKeyName;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public struct EtwRegBasicInformation
- {
- public Guid Guid;
- public IntPtr SessionId;
+ private void Dummy()
+ {
+ Pad1 = 0;
+ Pad2 = 0;
+ }
}
}
diff --git a/1.x/trunk/ProcessHacker.Native/Objects/ProcessHandle.cs b/1.x/trunk/ProcessHacker.Native/Objects/ProcessHandle.cs
index 7421e1038..c3dbd7468 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 KphProcessHandle[] GetHandles()
+ public ProcessHandleInformation[] GetHandles()
{
int returnLength = 0;
int attempts = 0;
@@ -1461,10 +1461,10 @@ namespace ProcessHacker.Native.Objects
}
int handleCount = data.ReadInt32(0);
- KphProcessHandle[] handles = new KphProcessHandle[handleCount];
+ ProcessHandleInformation[] handles = new ProcessHandleInformation[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 e918dbb0b..b610447fd 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.21022
+ 9.0.30729
2.0
{8A448157-E1A7-4DDF-954E-287F1117832B}
Library