public static List <HandleInfo> GetHandles() { List <HandleInfo> handleInfos = new List <HandleInfo>(); // Attempt to retrieve the handle information int length = 0x10000; IntPtr ptr = IntPtr.Zero; try { while (true) { ptr = Marshal.AllocHGlobal(length); int wantedLength; var result = NtDll.NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS.SystemHandleInformation, ptr, length, out wantedLength); if (result == NT_STATUS.STATUS_INFO_LENGTH_MISMATCH) { length = Math.Max(length, wantedLength); Marshal.FreeHGlobal(ptr); ptr = IntPtr.Zero; } else if (result == NT_STATUS.STATUS_SUCCESS) { break; } else { throw new Exception("Failed to retrieve system handle information."); } } long handleCount = IntPtr.Size == 4 ? Marshal.ReadInt32(ptr) : (int)Marshal.ReadInt64(ptr); long offset = IntPtr.Size; int size = Marshal.SizeOf(typeof(SystemHandleEntry)); for (int i = 0; i < handleCount; i++) { var struc = (SystemHandleEntry)Marshal.PtrToStructure((IntPtr)((long)ptr + offset), typeof(SystemHandleEntry)); var handler = new HandleInfo(struc.OwnerProcessId, struc.Handle, struc.GrantedAccess, struc.ObjectTypeNumber); handleInfos.Add(handler); offset += size; } } finally { if (ptr != IntPtr.Zero) { Marshal.FreeHGlobal(ptr); } } return(handleInfos); }
private void initTypeAndName() { if (_typeAndNameAttempted) { return; } _typeAndNameAttempted = true; IntPtr sourceProcessHandle = IntPtr.Zero; IntPtr handleDuplicate = IntPtr.Zero; try { sourceProcessHandle = Kernel32.OpenProcess(0x40 /* dup_handle */, true, ProcessId); // To read info about a handle owned by another process we must duplicate it into ours // For simplicity, current process handles will also get duplicated; remember that process handles cannot be compared for equality if (!Kernel32.DuplicateHandle(sourceProcessHandle, (IntPtr)Handle, Kernel32.GetCurrentProcess(), out handleDuplicate, 0, false, 2 /* same_access */)) { return; } // Query the object type if (_rawTypeMap.ContainsKey(RawType)) { _typeStr = _rawTypeMap[RawType]; } else { int length; NtDll.NtQueryObject(handleDuplicate, OBJECT_INFORMATION_CLASS.ObjectTypeInformation, IntPtr.Zero, 0, out length); IntPtr ptr = IntPtr.Zero; try { ptr = Marshal.AllocHGlobal(length); if (NtDll.NtQueryObject(handleDuplicate, OBJECT_INFORMATION_CLASS.ObjectTypeInformation, ptr, length, out length) != NT_STATUS.STATUS_SUCCESS) { return; } _typeStr = Marshal.PtrToStringUni((IntPtr)((long)ptr + 0x58 + 2 * IntPtr.Size)); _rawTypeMap[RawType] = _typeStr; } finally { Marshal.FreeHGlobal(ptr); } } _type = HandleTypeFromString(_typeStr); // Query the object name if (_typeStr != null && GrantedAccess != 0x0012019f && GrantedAccess != 0x00120189 && GrantedAccess != 0x120089) // dont query some objects that could get stuck { int length; NtDll.NtQueryObject(handleDuplicate, OBJECT_INFORMATION_CLASS.ObjectNameInformation, IntPtr.Zero, 0, out length); IntPtr ptr = IntPtr.Zero; try { ptr = Marshal.AllocHGlobal(length); if (NtDll.NtQueryObject(handleDuplicate, OBJECT_INFORMATION_CLASS.ObjectNameInformation, ptr, length, out length) != NT_STATUS.STATUS_SUCCESS) { return; } _name = Marshal.PtrToStringUni((IntPtr)((long)ptr + 2 * IntPtr.Size)); if (_typeStr == "File" || _typeStr == "Directory") { _name = GetRegularFileNameFromDevice(_name); } } finally { Marshal.FreeHGlobal(ptr); } } } finally { Kernel32.CloseHandle(sourceProcessHandle); if (handleDuplicate != IntPtr.Zero) { Kernel32.CloseHandle(handleDuplicate); } } }