private static string GetHandleTypeToken(IntPtr handle, int processId) { var currentProcess = NativeMethods.GetCurrentProcess(); var remote = (processId != NativeMethods.GetProcessId(currentProcess)); SafeProcessHandle processHandle = null; SafeObjectHandle objectHandle = null; try { if (remote) { processHandle = NativeMethods.OpenProcess(ProcessAccessRights.PROCESS_DUP_HANDLE, true, processId); if (NativeMethods.DuplicateHandle(processHandle.DangerousGetHandle(), handle, currentProcess, out objectHandle, 0, false, DuplicateHandleOptions.DUPLICATE_SAME_ACCESS)) { handle = objectHandle.DangerousGetHandle(); } } return(GetHandleTypeToken(handle)); } finally { if (remote) { if (processHandle != null) { processHandle.Close(); } if (objectHandle != null) { objectHandle.Close(); } } } }
private static bool GetHandleInfo(IntPtr handle, int processId, out HandleInfo handleInfo) { SafeProcessHandle processHandle = null; SafeObjectHandle objectHandle = null; var currentProcess = NativeMethods.GetCurrentProcess(); handleInfo = null; try { processHandle = NativeMethods.OpenProcess(ProcessAccessRights.PROCESS_DUP_HANDLE, true, processId); if (NativeMethods.DuplicateHandle(processHandle.DangerousGetHandle(), handle, currentProcess, out objectHandle, 0, false, DuplicateHandleOptions.DUPLICATE_SAME_ACCESS)) { handle = objectHandle.DangerousGetHandle(); int length; NativeMethods.NtQueryObject(handle, OBJECT_INFORMATION_CLASS.ObjectTypeInformation, IntPtr.Zero, 0, out length); IntPtr ptrObjectType = IntPtr.Zero; try { if (length > 0) { ptrObjectType = Marshal.AllocHGlobal(length); if (NativeMethods.NtQueryObject(handle, OBJECT_INFORMATION_CLASS.ObjectTypeInformation, ptrObjectType, length, out length) == NT_STATUS.STATUS_SUCCESS) { var token = Marshal.PtrToStringUni((IntPtr)((int)ptrObjectType + 0x60)); HandleType handleType; if (GetHandleTypeFromToken(token, out handleType)) { IntPtr ptrObjectName = IntPtr.Zero; NT_STATUS returnValue; string objectName = null; try { length = 0x200; // 512 bytes ptrObjectName = Marshal.AllocHGlobal(length); returnValue = NativeMethods.NtQueryObject(handle, OBJECT_INFORMATION_CLASS.ObjectNameInformation, ptrObjectName, length, out length); if (returnValue == NT_STATUS.STATUS_BUFFER_OVERFLOW) { RuntimeHelpers.PrepareConstrainedRegions(); Marshal.FreeHGlobal(ptrObjectName); ptrObjectName = Marshal.AllocHGlobal(length); returnValue = NativeMethods.NtQueryObject(handle, OBJECT_INFORMATION_CLASS.ObjectNameInformation, ptrObjectName, length, out length); } if (returnValue == NT_STATUS.STATUS_SUCCESS) { objectName = Marshal.PtrToStringUni((IntPtr)((int)ptrObjectName + 8), (length - 9) / 2); } } finally { Marshal.FreeHGlobal(ptrObjectName); } handleInfo = new HandleInfo { Handle = handle, HandleType = handleType, ObjectName = objectName }; return(true); } } } } finally { Marshal.FreeHGlobal(ptrObjectType); } } } finally { if (processHandle != null) { processHandle.Close(); } if (objectHandle != null) { objectHandle.Close(); } } return(false); }