private string GetDevicePathFromInfo(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX info) { if (_pidsToIgnore.Contains(info.UniqueProcessId)) { return(null); } using (DuplicatedObjectHandle handle = new DuplicatedObjectHandle(info.HandleValue, info.UniqueProcessId)) { if (handle.ErrorMessage != null) { if (handle.ErrorMessage == "OpenProcess") { _pidsToIgnore.Add(info.UniqueProcessId); } return(null); } try { return(handle.GetObjectNameFromHandle()); } catch (NtStatusException) { return(null); } } }
/// <summary> /// Enumerates all kernel objects. /// </summary> /// <returns></returns> /// <remarks> /// For an unknown reason NtQuerySystemInformation returns a lot of invalid handles (actually all multiples of 4 to the last valid handle) /// It also returns handles for processes that the current process doesn't have the privileges to duplicate the handle into the current process. /// The SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX struct doesn't seem to indicate, if a handle is invalid, but there are some strong indications: /// GetObjectNameFromHandle() fails or returns an empty string or a string that doesn't start with '\' /// In this case SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX.ObjectTypeIndex often is an arbitrary number that does not match the /// type that GetHandleType will return. /// </remarks> public static IEnumerable <SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX> EnumerateAllObjects() { NT_STATUS ret; int length = 0x10000; // Loop, probing for required memory. do { IntPtr ptr = IntPtr.Zero; RuntimeHelpers.PrepareConstrainedRegions(); try { RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { // CER guarantees that the address of the allocated memory is actually assigned to ptr if an asynchronous exception occurs. ptr = Marshal.AllocHGlobal(length); } int returnLength; ret = NativeMethods.NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS.SystemExtendedHandleInformation, ptr, length, out returnLength); if (ret == NT_STATUS.STATUS_INFO_LENGTH_MISMATCH) { // Round required memory up to the nearest 64KB boundary. length = ((returnLength + 0xffff) & ~0xffff); } else if (ret == NT_STATUS.STATUS_SUCCESS) { int handleCount = Marshal.ReadInt32(ptr); // NtQuerySystemInformation returns SYSTEM_HANDLE_INFORMATION which only consists of ULONG NumberOfHandles and an array of SYSTEM_HANDLE_TABLE_ENTRY_INFO int infoSize = Marshal.SizeOf(typeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX)); int currentOffset = Marshal.SizeOf <int>() * (IntPtr.Size == 4 ? 2 : 4); // the int32 we just read and one(32bit) or three(64bit) reserved uint for _ex version (non-_ex version, does not have any reserved uints) for (int i = 0; i < handleCount; i++) { SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handleEntry = Marshal.PtrToStructure <SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX>(IntPtr.Add(ptr, currentOffset)); yield return(handleEntry); currentOffset += infoSize; } } } finally { // CER guarantees that the allocated memory is freed, if an asynchronous exception occurs. Marshal.FreeHGlobal(ptr); } }while (ret == NT_STATUS.STATUS_INFO_LENGTH_MISMATCH); }
public bool IsMatch(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX info) { return(_objectTypeIndices.Contains(info.ObjectTypeIndex)); }