/// <summary> /// Enumerates the handles opened by every running process. /// </summary> /// <returns>An array containing information about the handles.</returns> public static SystemHandleEntry[] GetHandles() { int retLength = 0; int handleCount = 0; SystemHandleEntry[] returnHandles; if (_handlesBuffer == null) { _handlesBuffer = new MemoryAlloc(0x1000); } MemoryAlloc data = _handlesBuffer; NtStatus status; // This is needed because NtQuerySystemInformation with SystemHandleInformation doesn't // actually give a real return length when called with an insufficient buffer. This code // tries repeatedly to call the function, doubling the buffer size each time it fails. while ((status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemHandleInformation, data, data.Size, out retLength) ) == NtStatus.InfoLengthMismatch) { data.ResizeNew(data.Size * 2); // Fail if we've resized it to over 16MB - protect from infinite resizing if (data.Size > 16 * 1024 * 1024) { throw new OutOfMemoryException(); } } if (status >= NtStatus.Error) { Win32.Throw(status); } // The structure of the buffer is the handle count plus an array of SYSTEM_HANDLE_INFORMATION // structures. handleCount = data.ReadStruct <SystemHandleInformation>().NumberOfHandles; returnHandles = new SystemHandleEntry[handleCount]; // Unsafe code for speed. unsafe { SystemHandleEntry *handlesPtr = (SystemHandleEntry *)((byte *)data.Memory + SystemHandleInformation.HandlesOffset); for (int i = 0; i < handleCount; i++) { //returnHandles[i] = data.ReadStruct<SystemHandleEntry>(SystemHandleInformation.HandlesOffset, i); returnHandles[i] = handlesPtr[i]; } } return(returnHandles); }
/// <summary> /// Gets the page files currently active. /// </summary> /// <returns>A collection of page file information structures.</returns> public static SystemPagefile[] GetPagefiles() { int retLength; List <SystemPagefile> pagefiles = new List <SystemPagefile>(); using (MemoryAlloc data = new MemoryAlloc(0x200)) { NtStatus status; while ((status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemPageFileInformation, data, data.Size, out retLength) ) == NtStatus.InfoLengthMismatch) { data.ResizeNew(data.Size * 2); // Fail if we've resized it to over 16MB - protect from infinite resizing if (data.Size > 16 * 1024 * 1024) { throw new OutOfMemoryException(); } } if (status >= NtStatus.Error) { Win32.Throw(status); } pagefiles = new List <SystemPagefile>(2); int i = 0; SystemPagefileInformation currentPagefile; do { currentPagefile = data.ReadStruct <SystemPagefileInformation>(i, 0); pagefiles.Add(new SystemPagefile( currentPagefile.TotalSize, currentPagefile.TotalInUse, currentPagefile.PeakUsage, FileUtils.GetFileName(currentPagefile.PageFileName.Read()) )); i += currentPagefile.NextEntryOffset; } while (currentPagefile.NextEntryOffset != 0); return(pagefiles.ToArray()); } }
private static string GetObjectNameNt(ProcessHandle process, IntPtr handle, GenericHandle dupHandle) { int retLength; int baseAddress = 0; if (KProcessHacker.Instance != null) { KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectNameInformation, IntPtr.Zero, 0, out retLength, out baseAddress); } else { Win32.NtQueryObject(dupHandle, ObjectInformationClass.ObjectNameInformation, IntPtr.Zero, 0, out retLength); } if (retLength > 0) { using (MemoryAlloc oniMem = new MemoryAlloc(retLength)) { if (KProcessHacker.Instance != null) { if (KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectNameInformation, oniMem, oniMem.Size, out retLength, out baseAddress) >= NtStatus.Error) { throw new Exception("ZwQueryObject failed."); } } else { if (Win32.NtQueryObject(dupHandle, ObjectInformationClass.ObjectNameInformation, oniMem, oniMem.Size, out retLength) >= NtStatus.Error) { throw new Exception("NtQueryObject failed."); } } var oni = oniMem.ReadStruct <ObjectNameInformation>(); var str = oni.Name; if (KProcessHacker.Instance != null) { str.Buffer = str.Buffer.Increment(oniMem.Memory.Decrement(baseAddress)); } return(str.Read()); } } throw new Exception("NtQueryObject failed."); }
public static ObjectBasicInformation GetBasicInfo(this SystemHandleEntry thisHandle, ProcessHandle process) { NtStatus status = NtStatus.Success; IntPtr handle = new IntPtr(thisHandle.Handle); IntPtr objectHandleI; GenericHandle objectHandle = null; int retLength; int baseAddress; if (KProcessHacker.Instance == null) { if ((status = Win32.NtDuplicateObject( process, handle, ProcessHandle.Current, out objectHandleI, 0, 0, 0)) >= NtStatus.Error) { Win32.Throw(); } objectHandle = new GenericHandle(objectHandleI); } try { using (var data = new MemoryAlloc(Marshal.SizeOf(typeof(ObjectBasicInformation)))) { if (KProcessHacker.Instance != null) { KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectBasicInformation, data, data.Size, out retLength, out baseAddress); } else { status = Win32.NtQueryObject(objectHandle, ObjectInformationClass.ObjectBasicInformation, data, data.Size, out retLength); } if (status >= NtStatus.Error) { Win32.Throw(status); } return(data.ReadStruct <ObjectBasicInformation>()); } } finally { if (objectHandle != null) { objectHandle.Dispose(); } } }
public static ObjectBasicInformation GetBasicInfo(this SystemHandleEntry thisHandle, ProcessHandle process) { NtStatus status = NtStatus.Success; IntPtr handle = new IntPtr(thisHandle.Handle); IntPtr objectHandleI; GenericHandle objectHandle = null; int retLength; int baseAddress; if (KProcessHacker.Instance == null) { if ((status = Win32.NtDuplicateObject( process, handle, ProcessHandle.Current, out objectHandleI, 0, 0, 0)) >= NtStatus.Error) Win32.Throw(); objectHandle = new GenericHandle(objectHandleI); } try { using (var data = new MemoryAlloc(Marshal.SizeOf(typeof(ObjectBasicInformation)))) { if (KProcessHacker.Instance != null) { KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectBasicInformation, data, data.Size, out retLength, out baseAddress); } else { status = Win32.NtQueryObject(objectHandle, ObjectInformationClass.ObjectBasicInformation, data, data.Size, out retLength); } if (status >= NtStatus.Error) Win32.Throw(status); return data.ReadStruct<ObjectBasicInformation>(); } } finally { if (objectHandle != null) objectHandle.Dispose(); } }
/// <summary> /// Gets a dictionary containing the services on the system. /// </summary> /// <returns>A dictionary, indexed by service name.</returns> public static Dictionary <string, EnumServiceStatusProcess> GetServices() { using (ServiceManagerHandle manager = new ServiceManagerHandle(ScManagerAccess.EnumerateService)) { int requiredSize; int servicesReturned; int resume = 0; if (_servicesBuffer == null) { _servicesBuffer = new MemoryAlloc(0x10000); } MemoryAlloc data = _servicesBuffer; if (!Win32.EnumServicesStatusEx(manager, IntPtr.Zero, ServiceQueryType.Win32 | ServiceQueryType.Driver, ServiceQueryState.All, data, data.Size, out requiredSize, out servicesReturned, ref resume, null)) { // resize buffer data.ResizeNew(requiredSize); if (!Win32.EnumServicesStatusEx(manager, IntPtr.Zero, ServiceQueryType.Win32 | ServiceQueryType.Driver, ServiceQueryState.All, data, data.Size, out requiredSize, out servicesReturned, ref resume, null)) { Win32.Throw(); } } var dictionary = new Dictionary <string, EnumServiceStatusProcess>(servicesReturned); for (int i = 0; i < servicesReturned; i++) { var service = data.ReadStruct <EnumServiceStatusProcess>(i); dictionary.Add(service.ServiceName, service); } return(dictionary); } }
public static ObjectBasicInformation GetBasicInfo(this SystemHandleEntry thisHandle, ProcessHandle process) { IntPtr handle = new IntPtr(thisHandle.Handle); IntPtr objectHandleI; GenericHandle objectHandle = null; int retLength; Win32.NtDuplicateObject( process, handle, ProcessHandle.Current, out objectHandleI, 0, 0, 0 ).ThrowIf(); try { objectHandle = new GenericHandle(objectHandleI); using (MemoryAlloc data = new MemoryAlloc(ObjectBasicInformation.SizeOf)) { Win32.NtQueryObject( objectHandle, ObjectInformationClass.ObjectBasicInformation, data, data.Size, out retLength ).ThrowIf(); return(data.ReadStruct <ObjectBasicInformation>()); } } finally { if (objectHandle != null) { objectHandle.Dispose(); } } }
public static ObjectBasicInformation GetBasicInfo(this SystemHandleEntry thisHandle, ProcessHandle process) { IntPtr handle = new IntPtr(thisHandle.Handle); IntPtr objectHandleI; GenericHandle objectHandle = null; int retLength; Win32.NtDuplicateObject( process, handle, ProcessHandle.Current, out objectHandleI, 0, 0, 0 ).ThrowIf(); try { objectHandle = new GenericHandle(objectHandleI); using (MemoryAlloc data = new MemoryAlloc(ObjectBasicInformation.SizeOf)) { Win32.NtQueryObject( objectHandle, ObjectInformationClass.ObjectBasicInformation, data, data.Size, out retLength ).ThrowIf(); return data.ReadStruct<ObjectBasicInformation>(); } } finally { if (objectHandle != null) objectHandle.Dispose(); } }
private static string GetObjectNameNt(ProcessHandle process, IntPtr handle, GenericHandle dupHandle) { int retLength; Win32.NtQueryObject( dupHandle, ObjectInformationClass.ObjectNameInformation, IntPtr.Zero, 0, out retLength ); if (retLength > 0) { using (MemoryAlloc oniMem = new MemoryAlloc(retLength)) { Win32.NtQueryObject( dupHandle, ObjectInformationClass.ObjectNameInformation, oniMem, oniMem.Size, out retLength ).ThrowIf(); ObjectNameInformation oni = oniMem.ReadStruct <ObjectNameInformation>(); UnicodeString str = oni.Name; //if (KProcessHacker.Instance != null) //str.Buffer = str.Buffer.Increment(oniMem.Memory.Decrement(baseAddress)); return(str.Text); } } throw new Exception("NtQueryObject failed."); }
private static string GetObjectNameNt(ProcessHandle process, IntPtr handle, GenericHandle dupHandle) { int retLength; int baseAddress = 0; if (KProcessHacker.Instance != null) { KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectNameInformation, IntPtr.Zero, 0, out retLength, out baseAddress); } else { Win32.NtQueryObject(dupHandle, ObjectInformationClass.ObjectNameInformation, IntPtr.Zero, 0, out retLength); } if (retLength > 0) { using (MemoryAlloc oniMem = new MemoryAlloc(retLength)) { if (KProcessHacker.Instance != null) { if (KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectNameInformation, oniMem, oniMem.Size, out retLength, out baseAddress) >= NtStatus.Error) throw new Exception("ZwQueryObject failed."); } else { if (Win32.NtQueryObject(dupHandle, ObjectInformationClass.ObjectNameInformation, oniMem, oniMem.Size, out retLength) >= NtStatus.Error) throw new Exception("NtQueryObject failed."); } var oni = oniMem.ReadStruct<ObjectNameInformation>(); var str = oni.Name; if (KProcessHacker.Instance != null) str.Buffer = str.Buffer.Increment(oniMem.Memory.Decrement(baseAddress)); return str.Read(); } } throw new Exception("NtQueryObject failed."); }
public static ObjectInformation GetHandleInfo(this SystemHandleEntry thisHandle, ProcessHandle process, bool getName) { IntPtr handle = new IntPtr(thisHandle.Handle); IntPtr objectHandleI; int retLength; GenericHandle objectHandle = null; if (thisHandle.Handle == 0 || thisHandle.Handle == -1 || thisHandle.Handle == -2) { throw new WindowsException(NtStatus.InvalidHandle); } // Duplicate the handle if we're not using KPH //if (KProcessHacker.Instance == null) { Win32.NtDuplicateObject( process, handle, ProcessHandle.Current, out objectHandleI, 0, 0, 0 ).ThrowIf(); objectHandle = new GenericHandle(objectHandleI); } ObjectInformation info = new ObjectInformation(); // If the cache contains the object type's name, use it. Otherwise, query the type // for its name. Windows.ObjectTypesLock.AcquireShared(); try { if (Windows.ObjectTypes.ContainsKey(thisHandle.ObjectTypeNumber)) { info.TypeName = Windows.ObjectTypes[thisHandle.ObjectTypeNumber]; } } finally { Windows.ObjectTypesLock.ReleaseShared(); } if (string.IsNullOrEmpty(info.TypeName)) { Win32.NtQueryObject( objectHandle, ObjectInformationClass.ObjectTypeInformation, IntPtr.Zero, 0, out retLength ); if (retLength > 0) { using (MemoryAlloc otiMem = new MemoryAlloc(retLength)) { Win32.NtQueryObject( objectHandle, ObjectInformationClass.ObjectTypeInformation, otiMem, otiMem.Size, out retLength ).ThrowIf(); ObjectTypeInformation oti = otiMem.ReadStruct <ObjectTypeInformation>(); UnicodeString str = oti.Name; //if (KProcessHacker.Instance != null) //str.Buffer = str.Buffer.Increment(otiMem.Memory.Decrement(baseAddress)); info.TypeName = str.Text; Windows.ObjectTypesLock.AcquireExclusive(); try { if (!Windows.ObjectTypes.ContainsKey(thisHandle.ObjectTypeNumber)) { Windows.ObjectTypes.Add(thisHandle.ObjectTypeNumber, info.TypeName); } } finally { Windows.ObjectTypesLock.ReleaseExclusive(); } } } } if (!getName) { return(info); } // Get the object's name. If the object is a file we must take special // precautions so that we don't hang. if (string.Equals(info.TypeName, "File", StringComparison.OrdinalIgnoreCase)) { //if (KProcessHacker.Instance != null) //{ // // Use KProcessHacker for files to avoid hangs. // info.OrigName = KProcessHacker.Instance.GetHandleObjectName(process, handle); //} //else { // 0: No hack, query the thing normally. // 1: No hack, use NProcessHacker. // 2: Hack. int hackLevel = 1; // If we already tried to use NPH but it wasn't present, // skip to level 2. if (NphNotAvailable) { hackLevel = 2; } // Can't use NPH because XP had a bug where a thread hanging // on NtQueryObject couldn't be terminated. if (OSVersion.IsBelowOrEqual(WindowsVersion.XP)) { hackLevel = 2; } // On Windows 7 and above the hanging bug appears to have // been fixed. Query the object normally. // UPDATE: Not so. It still happens. //if (OSVersion.IsAboveOrEqual(WindowsVersion.Seven)) // hackLevel = 0; if (hackLevel == 1) { try { // Use NProcessHacker. using (MemoryAlloc oniMem = new MemoryAlloc(0x4000)) { NProcessHacker.PhQueryNameFileObject( objectHandle, oniMem, oniMem.Size, out retLength ).ThrowIf(); var oni = oniMem.ReadStruct <ObjectNameInformation>(); info.OrigName = oni.Name.Text; } } catch (DllNotFoundException) { hackLevel = 2; NphNotAvailable = true; } } if (hackLevel == 0) { info.OrigName = GetObjectNameNt(process, handle, objectHandle); } else if (hackLevel == 2) { // KProcessHacker and NProcessHacker not available. Fall back to using hack // (i.e. not querying the name at all if the access is 0x0012019f). if (thisHandle.GrantedAccess != 0x0012019f) { info.OrigName = GetObjectNameNt(process, handle, objectHandle); } } } } else { // Not a file. Query the object normally. info.OrigName = GetObjectNameNt(process, handle, objectHandle); } // Get a better name for the handle. try { switch (info.TypeName) { case "File": // Resolves \Device\HarddiskVolume1 into C:, for example. if (!string.IsNullOrEmpty(info.OrigName)) { info.BestName = FileUtils.GetFileName(info.OrigName); } break; case "Key": info.BestName = NativeUtils.FormatNativeKeyName(info.OrigName); break; case "Process": { int processId; using (NativeHandle <ProcessAccess> processHandle = new NativeHandle <ProcessAccess>(process, handle, OSVersion.MinProcessQueryInfoAccess)) { if ((processId = Win32.GetProcessId(processHandle)) == 0) { Win32.Throw(); } } info.BestName = (new ClientId(processId, 0)).GetName(false); } break; case "Thread": { int processId; int threadId; using (var threadHandle = new NativeHandle <ThreadAccess>(process, handle, OSVersion.MinThreadQueryInfoAccess)) { var basicInfo = ThreadHandle.FromHandle(threadHandle).GetBasicInformation(); threadId = basicInfo.ClientId.ThreadId; processId = basicInfo.ClientId.ProcessId; } info.BestName = (new ClientId(processId, threadId)).GetName(true); } break; case "TmEn": { using (NativeHandle <EnlistmentAccess> enHandleDup = new NativeHandle <EnlistmentAccess>(process, handle, EnlistmentAccess.QueryInformation)) using (EnlistmentHandle enHandle = EnlistmentHandle.FromHandle(enHandleDup)) { info.BestName = enHandle.BasicInformation.EnlistmentId.ToString("B"); } } break; case "TmRm": { using (var rmHandleDup = new NativeHandle <ResourceManagerAccess>(process, handle, ResourceManagerAccess.QueryInformation)) { var rmHandle = ResourceManagerHandle.FromHandle(rmHandleDup); info.BestName = rmHandle.Description; if (string.IsNullOrEmpty(info.BestName)) { info.BestName = rmHandle.Guid.ToString("B"); } } } break; case "TmTm": { using (NativeHandle <TmAccess> tmHandleDup = new NativeHandle <TmAccess>(process, handle, TmAccess.QueryInformation)) using (TmHandle tmHandle = TmHandle.FromHandle(tmHandleDup)) { info.BestName = FileUtils.GetFileName(FileUtils.GetFileName(tmHandle.LogFileName)); if (string.IsNullOrEmpty(info.BestName)) { info.BestName = tmHandle.BasicInformation.TmIdentity.ToString("B"); } } } break; case "TmTx": { using (var transactionHandleDup = new NativeHandle <TransactionAccess>(process, handle, TransactionAccess.QueryInformation)) { TransactionHandle transactionHandle = TransactionHandle.FromHandle(transactionHandleDup); info.BestName = transactionHandle.Description; if (string.IsNullOrEmpty(info.BestName)) { info.BestName = transactionHandle.BasicInformation.TransactionId.ToString("B"); } } } break; case "Token": { using (var tokenHandleDup = new NativeHandle <TokenAccess>(process, handle, TokenAccess.Query)) using (TokenHandle tokenHandle = TokenHandle.FromHandle(tokenHandleDup)) using (tokenHandle.User) { info.BestName = tokenHandle.User.GetFullName(true) + ": 0x" + tokenHandle.Statistics.AuthenticationId; } } break; default: if (!string.IsNullOrEmpty(info.OrigName)) { info.BestName = info.OrigName; } else { info.BestName = null; } break; } } catch { if (!string.IsNullOrEmpty(info.OrigName)) { info.BestName = info.OrigName; } else { info.BestName = null; } } if (objectHandle != null) { objectHandle.Dispose(); } return(info); }
/// <summary> /// Gets a dictionary containing the threads owned by the specified process. /// </summary> /// <param name="pid">A process ID.</param> /// <returns>A dictionary, indexed by thread ID.</returns> public static Dictionary <int, SystemThreadInformation> GetProcessThreads(int pid) { int retLength; if (_processesBuffer == null) { _processesBuffer = new MemoryAlloc(0x10000); } MemoryAlloc data = _processesBuffer; NtStatus status; int attempts = 0; while (true) { attempts++; if ((status = Win32.NtQuerySystemInformation(SystemInformationClass.SystemProcessInformation, data.Memory, data.Size, out retLength)) >= NtStatus.Error) { if (attempts > 3) { Win32.ThrowLastError(status); } data.Resize(retLength); } else { break; } } int i = 0; SystemProcessInformation process; do { process = data.ReadStruct <SystemProcessInformation>(i, 0); if (process.ProcessId == pid) { var threads = new Dictionary <int, SystemThreadInformation>(); for (int j = 0; j < process.NumberOfThreads; j++) { var thread = data.ReadStruct <SystemThreadInformation>(i + Marshal.SizeOf(typeof(SystemProcessInformation)), j); threads.Add(thread.ClientId.ThreadId, thread); } return(threads); } i += process.NextEntryOffset; } while (process.NextEntryOffset != 0); return(null); }
public static ObjectInformation GetHandleInfo(this SystemHandleEntry thisHandle, ProcessHandle process, bool getName) { IntPtr handle = new IntPtr(thisHandle.Handle); IntPtr objectHandleI; int retLength = 0; GenericHandle objectHandle = null; if (thisHandle.Handle == 0 || thisHandle.Handle == -1 || thisHandle.Handle == -2) throw new WindowsException(NtStatus.InvalidHandle); if (KProcessHacker.Instance == null) { NtStatus status; if ((status = Win32.NtDuplicateObject( process, handle, ProcessHandle.Current, out objectHandleI, 0, 0, 0)) >= NtStatus.Error) Win32.ThrowLastError(status); objectHandle = new GenericHandle(objectHandleI); } ObjectInformation info = new ObjectInformation(); lock (Windows.ObjectTypes) { if (Windows.ObjectTypes.ContainsKey(thisHandle.ObjectTypeNumber)) { info.TypeName = Windows.ObjectTypes[thisHandle.ObjectTypeNumber]; } else { int baseAddress = 0; if (KProcessHacker.Instance != null) { KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectTypeInformation, IntPtr.Zero, 0, out retLength, out baseAddress); } else { Win32.NtQueryObject(objectHandle, ObjectInformationClass.ObjectTypeInformation, IntPtr.Zero, 0, out retLength); } if (retLength > 0) { using (MemoryAlloc otiMem = new MemoryAlloc(retLength)) { if (KProcessHacker.Instance != null) { if (KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectTypeInformation, otiMem, otiMem.Size, out retLength, out baseAddress) >= NtStatus.Error) throw new Exception("ZwQueryObject failed."); } else { if (Win32.NtQueryObject(objectHandle, ObjectInformationClass.ObjectTypeInformation, otiMem, otiMem.Size, out retLength) >= NtStatus.Error) throw new Exception("NtQueryObject failed."); } var oti = otiMem.ReadStruct<ObjectTypeInformation>(); var str = oti.Name; if (KProcessHacker.Instance != null) str.Buffer = str.Buffer.Increment(otiMem.Memory.Decrement(baseAddress)); info.TypeName = str.Read(); Windows.ObjectTypes.Add(thisHandle.ObjectTypeNumber, info.TypeName); } } } } if (!getName) return info; if (info.TypeName == "File") { if (KProcessHacker.Instance != null) { info.OrigName = KProcessHacker.Instance.GetHandleObjectName(process, handle); } else { int hackLevel = 1; if (OSVersion.IsBelowOrEqual(WindowsVersion.XP)) hackLevel = 2; if (hackLevel == 1) { try { using (MemoryAlloc oniMem = new MemoryAlloc(0x4000)) { if (NProcessHacker.PhQueryNameFileObject( objectHandle, oniMem, oniMem.Size, out retLength) >= NtStatus.Error) throw new Exception("PhQueryNameFileObject failed."); var oni = oniMem.ReadStruct<ObjectNameInformation>(); info.OrigName = oni.Name.Read(); } } catch (DllNotFoundException) { hackLevel = 2; } } if (hackLevel == 0) { info.OrigName = GetObjectNameNt(process, handle, objectHandle); } else if (hackLevel == 2) { if ((int)thisHandle.GrantedAccess != 0x0012019f) info.OrigName = GetObjectNameNt(process, handle, objectHandle); } } } else { info.OrigName = GetObjectNameNt(process, handle, objectHandle); } try { switch (info.TypeName) { case "File": if (!string.IsNullOrEmpty(info.OrigName)) info.BestName = FileUtils.GetFileName(info.OrigName); break; case "Key": info.BestName = NativeUtils.FormatNativeKeyName(info.OrigName); break; case "Process": { int processId; if (KProcessHacker.Instance != null) { processId = KProcessHacker.Instance.KphGetProcessId(process, handle); if (processId == 0) throw new Exception("Invalid PID"); } else { using (var processHandle = new NativeHandle<ProcessAccess>(process, handle, OSVersion.MinProcessQueryInfoAccess)) { if ((processId = Win32.GetProcessId(processHandle)) == 0) Win32.ThrowLastError(); } } info.BestName = (new ClientId(processId, 0)).GetName(false); } break; case "Thread": { int processId; int threadId; if (KProcessHacker.Instance != null) { threadId = KProcessHacker.Instance.KphGetThreadId(process, handle, out processId); if (threadId == 0 || processId == 0) throw new Exception("Invalid TID or PID"); } else { using (var threadHandle = new NativeHandle<ThreadAccess>(process, handle, OSVersion.MinThreadQueryInfoAccess)) { var basicInfo = ThreadHandle.FromHandle(threadHandle).GetBasicInformation(); threadId = basicInfo.ClientId.ThreadId; processId = basicInfo.ClientId.ProcessId; } } info.BestName = (new ClientId(processId, threadId)).GetName(true); } break; case "TmEn": { using (var enHandleDup = new NativeHandle<EnlistmentAccess>(process, handle, EnlistmentAccess.QueryInformation)) { var enHandle = EnlistmentHandle.FromHandle(enHandleDup); info.BestName = enHandle.GetBasicInformation().EnlistmentId.ToString("B"); } } break; case "TmRm": { using (var rmHandleDup = new NativeHandle<ResourceManagerAccess>(process, handle, ResourceManagerAccess.QueryInformation)) { var rmHandle = ResourceManagerHandle.FromHandle(rmHandleDup); info.BestName = rmHandle.GetDescription(); if (string.IsNullOrEmpty(info.BestName)) info.BestName = rmHandle.GetGuid().ToString("B"); } } break; case "TmTm": { using (var tmHandleDup = new NativeHandle<TmAccess>(process, handle, TmAccess.QueryInformation)) { var tmHandle = TmHandle.FromHandle(tmHandleDup); info.BestName = FileUtils.GetFileName(FileUtils.GetFileName(tmHandle.GetLogFileName())); if (string.IsNullOrEmpty(info.BestName)) info.BestName = tmHandle.GetBasicInformation().TmIdentity.ToString("B"); } } break; case "TmTx": { using (var transactionHandleDup = new NativeHandle<TransactionAccess>(process, handle, TransactionAccess.QueryInformation)) { var transactionHandle = TransactionHandle.FromHandle(transactionHandleDup); info.BestName = transactionHandle.GetDescription(); if (string.IsNullOrEmpty(info.BestName)) info.BestName = transactionHandle.GetBasicInformation().TransactionId.ToString("B"); } } break; case "Token": { using (var tokenHandleDup = new NativeHandle<TokenAccess>(process, handle, TokenAccess.Query)) { var tokenHandle = TokenHandle.FromHandle(tokenHandleDup); var sid = tokenHandle.GetUser(); using (sid) info.BestName = sid.GetFullName(true) + ": 0x" + tokenHandle.GetStatistics().AuthenticationId.ToString(); } } break; default: if (info.OrigName != null && info.OrigName != "") { info.BestName = info.OrigName; } else { info.BestName = null; } break; } } catch { if (info.OrigName != null && info.OrigName != "") { info.BestName = info.OrigName; } else { info.BestName = null; } } if (objectHandle != null) objectHandle.Dispose(); return info; }
public static ObjectInformation GetHandleInfo(this SystemHandleEntry thisHandle, ProcessHandle process, bool getName) { IntPtr handle = new IntPtr(thisHandle.Handle); IntPtr objectHandleI; int retLength = 0; GenericHandle objectHandle = null; if (thisHandle.Handle == 0 || thisHandle.Handle == -1 || thisHandle.Handle == -2) throw new WindowsException(NtStatus.InvalidHandle); // Duplicate the handle if we're not using KPH if (KProcessHacker.Instance == null) { NtStatus status; if ((status = Win32.NtDuplicateObject( process, handle, ProcessHandle.Current, out objectHandleI, 0, 0, 0)) >= NtStatus.Error) Win32.Throw(status); objectHandle = new GenericHandle(objectHandleI); } ObjectInformation info = new ObjectInformation(); // If the cache contains the object type's name, use it. Otherwise, query the type // for its name. Windows.ObjectTypesLock.AcquireShared(); try { if (Windows.ObjectTypes.ContainsKey(thisHandle.ObjectTypeNumber)) { info.TypeName = Windows.ObjectTypes[thisHandle.ObjectTypeNumber]; } } finally { Windows.ObjectTypesLock.ReleaseShared(); } if (info.TypeName == null) { int baseAddress = 0; if (KProcessHacker.Instance != null) { KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectTypeInformation, IntPtr.Zero, 0, out retLength, out baseAddress); } else { Win32.NtQueryObject(objectHandle, ObjectInformationClass.ObjectTypeInformation, IntPtr.Zero, 0, out retLength); } if (retLength > 0) { using (MemoryAlloc otiMem = new MemoryAlloc(retLength)) { if (KProcessHacker.Instance != null) { if (KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectTypeInformation, otiMem, otiMem.Size, out retLength, out baseAddress) >= NtStatus.Error) throw new Exception("ZwQueryObject failed."); } else { if (Win32.NtQueryObject(objectHandle, ObjectInformationClass.ObjectTypeInformation, otiMem, otiMem.Size, out retLength) >= NtStatus.Error) throw new Exception("NtQueryObject failed."); } var oti = otiMem.ReadStruct<ObjectTypeInformation>(); var str = oti.Name; if (KProcessHacker.Instance != null) str.Buffer = str.Buffer.Increment(otiMem.Memory.Decrement(baseAddress)); info.TypeName = str.Read(); Windows.ObjectTypesLock.AcquireExclusive(); try { if (!Windows.ObjectTypes.ContainsKey(thisHandle.ObjectTypeNumber)) Windows.ObjectTypes.Add(thisHandle.ObjectTypeNumber, info.TypeName); } finally { Windows.ObjectTypesLock.ReleaseExclusive(); } } } } if (!getName) return info; // Get the object's name. If the object is a file we must take special // precautions so that we don't hang. if (info.TypeName == "File") { if (KProcessHacker.Instance != null) { // Use KProcessHacker for files to avoid hangs. info.OrigName = KProcessHacker.Instance.GetHandleObjectName(process, handle); } else { // 0: No hack, query the thing normally. // 1: No hack, use NProcessHacker. // 2: Hack. int hackLevel = 1; // If we already tried to use NPH but it wasn't present, // skip to level 2. if (NphNotAvailable) hackLevel = 2; // Can't use NPH because XP had a bug where a thread hanging // on NtQueryObject couldn't be terminated. if (OSVersion.IsBelowOrEqual(WindowsVersion.XP)) hackLevel = 2; // On Windows 7 and above the hanging bug appears to have // been fixed. Query the object normally. // UPDATE: Not so. It still happens. //if (OSVersion.IsAboveOrEqual(WindowsVersion.Seven)) // hackLevel = 0; if (hackLevel == 1) { try { // Use NProcessHacker. using (MemoryAlloc oniMem = new MemoryAlloc(0x4000)) { if (NProcessHacker.PhQueryNameFileObject( objectHandle, oniMem, oniMem.Size, out retLength) >= NtStatus.Error) throw new Exception("PhQueryNameFileObject failed."); var oni = oniMem.ReadStruct<ObjectNameInformation>(); info.OrigName = oni.Name.Read(); } } catch (DllNotFoundException) { hackLevel = 2; NphNotAvailable = true; } } if (hackLevel == 0) { info.OrigName = GetObjectNameNt(process, handle, objectHandle); } else if (hackLevel == 2) { // KProcessHacker and NProcessHacker not available. Fall back to using hack // (i.e. not querying the name at all if the access is 0x0012019f). if ((int)thisHandle.GrantedAccess != 0x0012019f) info.OrigName = GetObjectNameNt(process, handle, objectHandle); } } } else { // Not a file. Query the object normally. info.OrigName = GetObjectNameNt(process, handle, objectHandle); } // Get a better name for the handle. try { switch (info.TypeName) { case "File": // Resolves \Device\HarddiskVolume1 into C:, for example. if (!string.IsNullOrEmpty(info.OrigName)) info.BestName = FileUtils.GetFileName(info.OrigName); break; case "Key": info.BestName = NativeUtils.FormatNativeKeyName(info.OrigName); break; case "Process": { int processId; if (KProcessHacker.Instance != null) { processId = KProcessHacker.Instance.KphGetProcessId(process, handle); if (processId == 0) throw new Exception("Invalid PID"); } else { using (var processHandle = new NativeHandle<ProcessAccess>(process, handle, OSVersion.MinProcessQueryInfoAccess)) { if ((processId = Win32.GetProcessId(processHandle)) == 0) Win32.Throw(); } } info.BestName = (new ClientId(processId, 0)).GetName(false); } break; case "Thread": { int processId; int threadId; if (KProcessHacker.Instance != null) { threadId = KProcessHacker.Instance.KphGetThreadId(process, handle, out processId); if (threadId == 0 || processId == 0) throw new Exception("Invalid TID or PID"); } else { using (var threadHandle = new NativeHandle<ThreadAccess>(process, handle, OSVersion.MinThreadQueryInfoAccess)) { var basicInfo = ThreadHandle.FromHandle(threadHandle).GetBasicInformation(); threadId = basicInfo.ClientId.ThreadId; processId = basicInfo.ClientId.ProcessId; } } info.BestName = (new ClientId(processId, threadId)).GetName(true); } break; case "TmEn": { using (var enHandleDup = new NativeHandle<EnlistmentAccess>(process, handle, EnlistmentAccess.QueryInformation)) { var enHandle = EnlistmentHandle.FromHandle(enHandleDup); info.BestName = enHandle.GetBasicInformation().EnlistmentId.ToString("B"); } } break; case "TmRm": { using (var rmHandleDup = new NativeHandle<ResourceManagerAccess>(process, handle, ResourceManagerAccess.QueryInformation)) { var rmHandle = ResourceManagerHandle.FromHandle(rmHandleDup); info.BestName = rmHandle.GetDescription(); if (string.IsNullOrEmpty(info.BestName)) info.BestName = rmHandle.GetGuid().ToString("B"); } } break; case "TmTm": { using (var tmHandleDup = new NativeHandle<TmAccess>(process, handle, TmAccess.QueryInformation)) { var tmHandle = TmHandle.FromHandle(tmHandleDup); info.BestName = FileUtils.GetFileName(FileUtils.GetFileName(tmHandle.GetLogFileName())); if (string.IsNullOrEmpty(info.BestName)) info.BestName = tmHandle.GetBasicInformation().TmIdentity.ToString("B"); } } break; case "TmTx": { using (var transactionHandleDup = new NativeHandle<TransactionAccess>(process, handle, TransactionAccess.QueryInformation)) { var transactionHandle = TransactionHandle.FromHandle(transactionHandleDup); info.BestName = transactionHandle.GetDescription(); if (string.IsNullOrEmpty(info.BestName)) info.BestName = transactionHandle.GetBasicInformation().TransactionId.ToString("B"); } } break; case "Token": { using (var tokenHandleDup = new NativeHandle<TokenAccess>(process, handle, TokenAccess.Query)) { var tokenHandle = TokenHandle.FromHandle(tokenHandleDup); var sid = tokenHandle.GetUser(); using (sid) info.BestName = sid.GetFullName(true) + ": 0x" + tokenHandle.GetStatistics().AuthenticationId.ToString(); } } break; default: if (info.OrigName != null && info.OrigName != "") { info.BestName = info.OrigName; } else { info.BestName = null; } break; } } catch { if (info.OrigName != null && info.OrigName != "") { info.BestName = info.OrigName; } else { info.BestName = null; } } if (objectHandle != null) objectHandle.Dispose(); return info; }
/// <summary> /// Gets the network connections currently active. /// </summary> /// <returns>A dictionary of network connections.</returns> public static Dictionary<int, List<NetworkConnection>> GetNetworkConnections() { var retDict = new Dictionary<int, List<NetworkConnection>>(); int length = 0; // TCP IPv4 Win32.GetExtendedTcpTable(IntPtr.Zero, ref length, false, AiFamily.INet, TcpTableClass.OwnerPidAll, 0); using (MemoryAlloc mem = new MemoryAlloc(length)) { if (Win32.GetExtendedTcpTable(mem, ref length, false, AiFamily.INet, TcpTableClass.OwnerPidAll, 0) != 0) Win32.Throw(); int count = mem.ReadInt32(0); for (int i = 0; i < count; i++) { MibTcpRowOwnerPid struc = mem.ReadStruct<MibTcpRowOwnerPid>(sizeof(int), MibTcpRowOwnerPid.SizeOf, i); if (!retDict.ContainsKey(struc.OwningProcessId)) retDict.Add(struc.OwningProcessId, new List<NetworkConnection>()); retDict[struc.OwningProcessId].Add(new NetworkConnection { Protocol = NetworkProtocol.Tcp, Local = new IPEndPoint(struc.LocalAddress, ((ushort)struc.LocalPort).Reverse()), Remote = new IPEndPoint(struc.RemoteAddress, ((ushort)struc.RemotePort).Reverse()), State = struc.State, Pid = struc.OwningProcessId }); } } // UDP IPv4 length = 0; Win32.GetExtendedUdpTable(IntPtr.Zero, ref length, false, AiFamily.INet, UdpTableClass.OwnerPid, 0); using (MemoryAlloc mem = new MemoryAlloc(length)) { if (Win32.GetExtendedUdpTable(mem, ref length, false, AiFamily.INet, UdpTableClass.OwnerPid, 0) != 0) Win32.Throw(); int count = mem.ReadInt32(0); for (int i = 0; i < count; i++) { MibUdpRowOwnerPid struc = mem.ReadStruct<MibUdpRowOwnerPid>(sizeof(int), MibUdpRowOwnerPid.SizeOf, i); if (!retDict.ContainsKey(struc.OwningProcessId)) retDict.Add(struc.OwningProcessId, new List<NetworkConnection>()); retDict[struc.OwningProcessId].Add(new NetworkConnection { Protocol = NetworkProtocol.Udp, Local = new IPEndPoint(struc.LocalAddress, ((ushort)struc.LocalPort).Reverse()), Pid = struc.OwningProcessId }); } } // TCP IPv6 length = 0; Win32.GetExtendedTcpTable(IntPtr.Zero, ref length, false, AiFamily.INet6, TcpTableClass.OwnerPidAll, 0); using (MemoryAlloc mem = new MemoryAlloc(length)) { if (Win32.GetExtendedTcpTable(mem, ref length, false, AiFamily.INet6, TcpTableClass.OwnerPidAll, 0) == 0) { int count = mem.ReadInt32(0); for (int i = 0; i < count; i++) { MibTcp6RowOwnerPid struc = mem.ReadStruct<MibTcp6RowOwnerPid>(sizeof(int), MibTcp6RowOwnerPid.SizeOf, i); if (!retDict.ContainsKey(struc.OwningProcessId)) retDict.Add(struc.OwningProcessId, new List<NetworkConnection>()); retDict[struc.OwningProcessId].Add(new NetworkConnection { Protocol = NetworkProtocol.Tcp6, Local = new IPEndPoint(new IPAddress(struc.LocalAddress, struc.LocalScopeId), ((ushort)struc.LocalPort).Reverse()), Remote = new IPEndPoint(new IPAddress(struc.RemoteAddress, struc.RemoteScopeId), ((ushort)struc.RemotePort).Reverse()), State = struc.State, Pid = struc.OwningProcessId }); } } } // UDP IPv6 length = 0; Win32.GetExtendedUdpTable(IntPtr.Zero, ref length, false, AiFamily.INet6, UdpTableClass.OwnerPid, 0); using (MemoryAlloc mem = new MemoryAlloc(length)) { if (Win32.GetExtendedUdpTable(mem, ref length, false, AiFamily.INet6, UdpTableClass.OwnerPid, 0) == 0) { int count = mem.ReadInt32(0); for (int i = 0; i < count; i++) { MibUdp6RowOwnerPid struc = mem.ReadStruct<MibUdp6RowOwnerPid>(sizeof(int), MibUdp6RowOwnerPid.SizeOf, i); if (!retDict.ContainsKey(struc.OwningProcessId)) retDict.Add(struc.OwningProcessId, new List<NetworkConnection>()); retDict[struc.OwningProcessId].Add(new NetworkConnection { Protocol = NetworkProtocol.Udp6, Local = new IPEndPoint(new IPAddress(struc.LocalAddress, struc.LocalScopeId), ((ushort)struc.LocalPort).Reverse()), Pid = struc.OwningProcessId }); } } } return retDict; }
/// <summary> /// Gets the network connections currently active. /// </summary> /// <returns>A dictionary of network connections.</returns> public static Dictionary <int, List <NetworkConnection> > GetNetworkConnections() { var retDict = new Dictionary <int, List <NetworkConnection> >(); int length; // TCP IPv4 length = 0; Win32.GetExtendedTcpTable(IntPtr.Zero, ref length, false, AiFamily.INet, TcpTableClass.OwnerPidAll, 0); using (var mem = new MemoryAlloc(length)) { if (Win32.GetExtendedTcpTable(mem, ref length, false, AiFamily.INet, TcpTableClass.OwnerPidAll, 0) != 0) { Win32.Throw(); } int count = mem.ReadInt32(0); for (int i = 0; i < count; i++) { var struc = mem.ReadStruct <MibTcpRowOwnerPid>(sizeof(int), i); if (!retDict.ContainsKey(struc.OwningProcessId)) { retDict.Add(struc.OwningProcessId, new List <NetworkConnection>()); } retDict[struc.OwningProcessId].Add(new NetworkConnection() { Protocol = NetworkProtocol.Tcp, Local = new IPEndPoint(struc.LocalAddress, ((ushort)struc.LocalPort).Reverse()), Remote = new IPEndPoint(struc.RemoteAddress, ((ushort)struc.RemotePort).Reverse()), State = struc.State, Pid = struc.OwningProcessId }); } } // UDP IPv4 length = 0; Win32.GetExtendedUdpTable(IntPtr.Zero, ref length, false, AiFamily.INet, UdpTableClass.OwnerPid, 0); using (var mem = new MemoryAlloc(length)) { if (Win32.GetExtendedUdpTable(mem, ref length, false, AiFamily.INet, UdpTableClass.OwnerPid, 0) != 0) { Win32.Throw(); } int count = mem.ReadInt32(0); for (int i = 0; i < count; i++) { var struc = mem.ReadStruct <MibUdpRowOwnerPid>(sizeof(int), i); if (!retDict.ContainsKey(struc.OwningProcessId)) { retDict.Add(struc.OwningProcessId, new List <NetworkConnection>()); } retDict[struc.OwningProcessId].Add( new NetworkConnection() { Protocol = NetworkProtocol.Udp, Local = new IPEndPoint(struc.LocalAddress, ((ushort)struc.LocalPort).Reverse()), Pid = struc.OwningProcessId }); } } // TCP IPv6 length = 0; Win32.GetExtendedTcpTable(IntPtr.Zero, ref length, false, AiFamily.INet6, TcpTableClass.OwnerPidAll, 0); using (var mem = new MemoryAlloc(length)) { if (Win32.GetExtendedTcpTable(mem, ref length, false, AiFamily.INet6, TcpTableClass.OwnerPidAll, 0) == 0) { int count = mem.ReadInt32(0); for (int i = 0; i < count; i++) { var struc = mem.ReadStruct <MibTcp6RowOwnerPid>(sizeof(int), i); if (!retDict.ContainsKey(struc.OwningProcessId)) { retDict.Add(struc.OwningProcessId, new List <NetworkConnection>()); } retDict[struc.OwningProcessId].Add(new NetworkConnection() { Protocol = NetworkProtocol.Tcp6, Local = new IPEndPoint(new IPAddress(struc.LocalAddress, struc.LocalScopeId), ((ushort)struc.LocalPort).Reverse()), Remote = new IPEndPoint(new IPAddress(struc.RemoteAddress, struc.RemoteScopeId), ((ushort)struc.RemotePort).Reverse()), State = struc.State, Pid = struc.OwningProcessId }); } } } // UDP IPv6 length = 0; Win32.GetExtendedUdpTable(IntPtr.Zero, ref length, false, AiFamily.INet6, UdpTableClass.OwnerPid, 0); using (var mem = new MemoryAlloc(length)) { if (Win32.GetExtendedUdpTable(mem, ref length, false, AiFamily.INet6, UdpTableClass.OwnerPid, 0) == 0) { int count = mem.ReadInt32(0); for (int i = 0; i < count; i++) { var struc = mem.ReadStruct <MibUdp6RowOwnerPid>(sizeof(int), i); if (!retDict.ContainsKey(struc.OwningProcessId)) { retDict.Add(struc.OwningProcessId, new List <NetworkConnection>()); } retDict[struc.OwningProcessId].Add( new NetworkConnection() { Protocol = NetworkProtocol.Udp6, Local = new IPEndPoint(new IPAddress(struc.LocalAddress, struc.LocalScopeId), ((ushort)struc.LocalPort).Reverse()), Pid = struc.OwningProcessId }); } } } return(retDict); }
public static string GetDeviceName(FileHandle fhandle) { using (var data = new MemoryAlloc(600)) { fhandle.IoControl(IoCtlQueryDeviceName, IntPtr.Zero, 0, data, data.Size); MountDevName name = data.ReadStruct<MountDevName>(); return data.ReadUnicodeString(MountDevName.NameOffset, name.NameLength / 2); } }
public static ObjectInformation GetHandleInfo(this SystemHandleEntry thisHandle, ProcessHandle process, bool getName) { IntPtr handle = new IntPtr(thisHandle.Handle); IntPtr objectHandleI; int retLength = 0; GenericHandle objectHandle = null; if (thisHandle.Handle == 0 || thisHandle.Handle == -1 || thisHandle.Handle == -2) { throw new WindowsException(NtStatus.InvalidHandle); } // Duplicate the handle if we're not using KPH if (KProcessHacker.Instance == null) { NtStatus status; if ((status = Win32.NtDuplicateObject( process, handle, ProcessHandle.Current, out objectHandleI, 0, 0, 0)) >= NtStatus.Error) { Win32.ThrowLastError(status); } objectHandle = new GenericHandle(objectHandleI); } ObjectInformation info = new ObjectInformation(); // If the cache contains the object type's name, use it. Otherwise, query the type // for its name. lock (Windows.ObjectTypes) { if (Windows.ObjectTypes.ContainsKey(thisHandle.ObjectTypeNumber)) { info.TypeName = Windows.ObjectTypes[thisHandle.ObjectTypeNumber]; } else { int baseAddress = 0; if (KProcessHacker.Instance != null) { KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectTypeInformation, IntPtr.Zero, 0, out retLength, out baseAddress); } else { Win32.NtQueryObject(objectHandle, ObjectInformationClass.ObjectTypeInformation, IntPtr.Zero, 0, out retLength); } if (retLength > 0) { using (MemoryAlloc otiMem = new MemoryAlloc(retLength)) { if (KProcessHacker.Instance != null) { if (KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectTypeInformation, otiMem, otiMem.Size, out retLength, out baseAddress) >= NtStatus.Error) { throw new Exception("ZwQueryObject failed."); } } else { if (Win32.NtQueryObject(objectHandle, ObjectInformationClass.ObjectTypeInformation, otiMem, otiMem.Size, out retLength) >= NtStatus.Error) { throw new Exception("NtQueryObject failed."); } } var oti = otiMem.ReadStruct <ObjectTypeInformation>(); var str = oti.Name; if (KProcessHacker.Instance != null) { str.Buffer = str.Buffer.Increment(otiMem.Memory.Decrement(baseAddress)); } info.TypeName = str.Read(); Windows.ObjectTypes.Add(thisHandle.ObjectTypeNumber, info.TypeName); } } } } if (!getName) { return(info); } // Get the object's name. If the object is a file we must take special // precautions so that we don't hang. if (info.TypeName == "File") { if (KProcessHacker.Instance != null) { // Use KProcessHacker for files to avoid hangs. info.OrigName = KProcessHacker.Instance.GetHandleObjectName(process, handle); } else { // 0: No hack, query the thing normally. // 1: No hack, use NProcessHacker. // 2: Hack. int hackLevel = 1; // Can't use NPH because XP had a bug where a thread hanging // on NtQueryObject couldn't be terminated. if (OSVersion.IsBelowOrEqual(WindowsVersion.XP)) { hackLevel = 2; } // On Windows 7 and above the hanging bug appears to have // been fixed. Query the object normally. // UPDATE: Not so. It still happens. //if (OSVersion.IsAboveOrEqual(WindowsVersion.Seven)) // hackLevel = 0; if (hackLevel == 1) { try { // Use NProcessHacker. using (MemoryAlloc oniMem = new MemoryAlloc(0x4000)) { if (NProcessHacker.PhQueryNameFileObject( objectHandle, oniMem, oniMem.Size, out retLength) >= NtStatus.Error) { throw new Exception("PhQueryNameFileObject failed."); } var oni = oniMem.ReadStruct <ObjectNameInformation>(); info.OrigName = oni.Name.Read(); } } catch (DllNotFoundException) { hackLevel = 2; } } if (hackLevel == 0) { info.OrigName = GetObjectNameNt(process, handle, objectHandle); } else if (hackLevel == 2) { // KProcessHacker and NProcessHacker not available. Fall back to using hack // (i.e. not querying the name at all if the access is 0x0012019f). if ((int)thisHandle.GrantedAccess != 0x0012019f) { info.OrigName = GetObjectNameNt(process, handle, objectHandle); } } } } else { // Not a file. Query the object normally. info.OrigName = GetObjectNameNt(process, handle, objectHandle); } // Get a better name for the handle. try { switch (info.TypeName) { case "File": // Resolves \Device\Harddisk1 into C:, for example. if (!string.IsNullOrEmpty(info.OrigName)) { info.BestName = FileUtils.GetFileName(info.OrigName); } break; case "Key": info.BestName = NativeUtils.FormatNativeKeyName(info.OrigName); break; case "Process": { int processId; if (KProcessHacker.Instance != null) { processId = KProcessHacker.Instance.KphGetProcessId(process, handle); if (processId == 0) { throw new Exception("Invalid PID"); } } else { using (var processHandle = new NativeHandle <ProcessAccess>(process, handle, OSVersion.MinProcessQueryInfoAccess)) { if ((processId = Win32.GetProcessId(processHandle)) == 0) { Win32.ThrowLastError(); } } } info.BestName = (new ClientId(processId, 0)).GetName(false); } break; case "Thread": { int processId; int threadId; if (KProcessHacker.Instance != null) { threadId = KProcessHacker.Instance.KphGetThreadId(process, handle, out processId); if (threadId == 0 || processId == 0) { throw new Exception("Invalid TID or PID"); } } else { using (var threadHandle = new NativeHandle <ThreadAccess>(process, handle, OSVersion.MinThreadQueryInfoAccess)) { var basicInfo = ThreadHandle.FromHandle(threadHandle).GetBasicInformation(); threadId = basicInfo.ClientId.ThreadId; processId = basicInfo.ClientId.ProcessId; } } info.BestName = (new ClientId(processId, threadId)).GetName(true); } break; case "TmEn": { using (var enHandleDup = new NativeHandle <EnlistmentAccess>(process, handle, EnlistmentAccess.QueryInformation)) { var enHandle = EnlistmentHandle.FromHandle(enHandleDup); info.BestName = enHandle.GetBasicInformation().EnlistmentId.ToString("B"); } } break; case "TmRm": { using (var rmHandleDup = new NativeHandle <ResourceManagerAccess>(process, handle, ResourceManagerAccess.QueryInformation)) { var rmHandle = ResourceManagerHandle.FromHandle(rmHandleDup); info.BestName = rmHandle.GetDescription(); if (string.IsNullOrEmpty(info.BestName)) { info.BestName = rmHandle.GetGuid().ToString("B"); } } } break; case "TmTm": { using (var tmHandleDup = new NativeHandle <TmAccess>(process, handle, TmAccess.QueryInformation)) { var tmHandle = TmHandle.FromHandle(tmHandleDup); info.BestName = FileUtils.GetFileName(FileUtils.GetFileName(tmHandle.GetLogFileName())); if (string.IsNullOrEmpty(info.BestName)) { info.BestName = tmHandle.GetBasicInformation().TmIdentity.ToString("B"); } } } break; case "TmTx": { using (var transactionHandleDup = new NativeHandle <TransactionAccess>(process, handle, TransactionAccess.QueryInformation)) { var transactionHandle = TransactionHandle.FromHandle(transactionHandleDup); info.BestName = transactionHandle.GetDescription(); if (string.IsNullOrEmpty(info.BestName)) { info.BestName = transactionHandle.GetBasicInformation().TransactionId.ToString("B"); } } } break; case "Token": { using (var tokenHandleDup = new NativeHandle <TokenAccess>(process, handle, TokenAccess.Query)) { var tokenHandle = TokenHandle.FromHandle(tokenHandleDup); var sid = tokenHandle.GetUser(); using (sid) info.BestName = sid.GetFullName(true) + ": 0x" + tokenHandle.GetStatistics().AuthenticationId.ToString(); } } break; default: if (info.OrigName != null && info.OrigName != "") { info.BestName = info.OrigName; } else { info.BestName = null; } break; } } catch { if (info.OrigName != null && info.OrigName != "") { info.BestName = info.OrigName; } else { info.BestName = null; } } if (objectHandle != null) { objectHandle.Dispose(); } return(info); }
public static string GetVolumeName(string deviceName) { using (var data = new MemoryAlloc(MountMgrMountPoint.Size + deviceName.Length * 2)) { MountMgrMountPoint mountPoint = new MountMgrMountPoint(); mountPoint.DeviceNameLength = (ushort)(deviceName.Length * 2); mountPoint.DeviceNameOffset = MountMgrMountPoint.Size; data.WriteStruct<MountMgrMountPoint>(mountPoint); data.WriteUnicodeString(mountPoint.DeviceNameOffset, deviceName); using (var fhandle = OpenMountManager((FileAccess)StandardRights.Synchronize)) { NtStatus status; int retLength; using (var outData = new MemoryAlloc(0x100)) { while (true) { status = fhandle.IoControl( IoCtlQueryPoints, data.Memory, data.Size, outData.Memory, outData.Size, out retLength ); if (status == NtStatus.BufferOverflow) { outData.ResizeNew(Marshal.ReadInt32(outData.Memory)); // read Size field continue; } else { break; } } if (status >= NtStatus.Error) Win32.Throw(status); MountMgrMountPoints mountPoints = outData.ReadStruct<MountMgrMountPoints>(); // Go through the mount points given and return the first symbolic link that seems // to be a volume name. for (int i = 0; i < mountPoints.NumberOfMountPoints; i++) { MountMgrMountPoint mp = outData.ReadStruct<MountMgrMountPoint>( MountMgrMountPoints.MountPointsOffset, i ); string symLinkName; symLinkName = Marshal.PtrToStringUni( outData.Memory.Increment(mp.SymbolicLinkNameOffset), mp.SymbolicLinkNameLength / 2 ); if (IsVolumePath(symLinkName)) return symLinkName; } return null; } } } }
private static string GetReparsePointTarget(FileHandle fhandle) { using (var data = new MemoryAlloc(FileSystem.MaximumReparseDataBufferSize)) { fhandle.IoControl(FileSystem.FsCtlGetReparsePoint, IntPtr.Zero, 0, data, data.Size); FileSystem.ReparseDataBuffer buffer = data.ReadStruct<FileSystem.ReparseDataBuffer>(); // Make sure it is in fact a mount point. if (buffer.ReparseTag != (uint)IoReparseTag.MountPoint) Win32.Throw(NtStatus.InvalidParameter); return data.ReadUnicodeString( FileSystem.ReparseDataBuffer.MountPointPathBuffer + buffer.SubstituteNameOffset, buffer.SubstituteNameLength / 2 ); } }
/// <summary> /// Gets a dictionary containing the currently running processes. /// </summary> /// <param name="getThreads">Whether to get thread information.</param> /// <returns>A dictionary, indexed by process ID.</returns> public static Dictionary <int, SystemProcess> GetProcesses(bool getThreads) { int retLength; Dictionary <int, SystemProcess> returnProcesses; if (_processesBuffer == null) { _processesBuffer = new MemoryAlloc(0x10000); } MemoryAlloc data = _processesBuffer; NtStatus status; int attempts = 0; while (true) { attempts++; if ((status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemProcessInformation, data, data.Size, out retLength )) >= NtStatus.Error) { if (attempts > 3) { Win32.Throw(status); } data.ResizeNew(retLength); } else { break; } } returnProcesses = new Dictionary <int, SystemProcess>(32); // 32 processes on a computer? int i = 0; SystemProcess currentProcess = new SystemProcess(); do { //currentProcess.Process = data.ReadStruct<SystemProcessInformation>(i, 0); unsafe { currentProcess.Process = *(SystemProcessInformation *)((byte *)data.Memory + i); } currentProcess.Name = currentProcess.Process.ImageName.Read(); if (getThreads && currentProcess.Process.ProcessId != 0) { currentProcess.Threads = new Dictionary <int, SystemThreadInformation>(); for (int j = 0; j < currentProcess.Process.NumberOfThreads; j++) { var thread = data.ReadStruct <SystemThreadInformation>(i + Marshal.SizeOf(typeof(SystemProcessInformation)), j); currentProcess.Threads.Add(thread.ClientId.ThreadId, thread); } } returnProcesses.Add(currentProcess.Process.ProcessId, currentProcess); i += currentProcess.Process.NextEntryOffset; } while (currentProcess.Process.NextEntryOffset != 0); return(returnProcesses); }
/// <summary> /// Gets a dictionary containing the threads owned by the specified process. /// </summary> /// <param name="pid">A process ID.</param> /// <returns>A dictionary, indexed by thread ID.</returns> public static Dictionary <int, SystemThreadInformation> GetProcessThreads(int pid) { int retLength; if (_processesBuffer == null) { _processesBuffer = new MemoryAlloc(0x10000); } MemoryAlloc data = _processesBuffer; NtStatus status; int attempts = 0; while (true) { attempts++; if ((status = Win32.NtQuerySystemInformation(SystemInformationClass.SystemProcessInformation, data.Memory, data.Size, out retLength)) >= NtStatus.Error) { if (attempts > 3) { Win32.Throw(status); } data.ResizeNew(retLength); } else { break; } } int i = 0; SystemProcessInformation process; do { unsafe { //process = data.ReadStruct<SystemProcessInformation>(i, 0); process = *(SystemProcessInformation *)((byte *)data.Memory + i); } if (process.ProcessId == pid) { var threads = new Dictionary <int, SystemThreadInformation>(); for (int j = 0; j < process.NumberOfThreads; j++) { var thread = data.ReadStruct <SystemThreadInformation>(i + Marshal.SizeOf(typeof(SystemProcessInformation)), j); if (pid != 0) { threads.Add(thread.ClientId.ThreadId, thread); } else { // Fix System Idle Process threads. // There is one thread per CPU, but they // all have a TID of 0. Assign unique TIDs. threads.Add(j, thread); } } return(threads); } i += process.NextEntryOffset; } while (process.NextEntryOffset != 0); return(null); }
/// <summary> /// Gets the page files currently active. /// </summary> /// <returns>A collection of page file information structures.</returns> public static SystemPagefile[] GetPagefiles() { int retLength; using (MemoryAlloc data = new MemoryAlloc(0x200)) { NtStatus status; while ((status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemPageFileInformation, data, data.Size, out retLength) ) == NtStatus.InfoLengthMismatch) { data.ResizeNew(data.Size * 2); // Fail if we've resized it to over 16MB - protect from infinite resizing if (data.Size > 16 * 1024 * 1024) throw new OutOfMemoryException(); } status.ThrowIf(); List<SystemPagefile> pagefiles = new List<SystemPagefile>(2); int i = 0; SystemPagefileInformation currentPagefile; do { currentPagefile = data.ReadStruct<SystemPagefileInformation>(i, SystemPagefileInformation.SizeOf, 0); pagefiles.Add(new SystemPagefile( currentPagefile.TotalSize, currentPagefile.TotalInUse, currentPagefile.PeakUsage, FileUtils.GetFileName(currentPagefile.PageFileName.Text) )); i += currentPagefile.NextEntryOffset; } while (currentPagefile.NextEntryOffset != 0); return pagefiles.ToArray(); } }
private static string GetObjectNameNt(ProcessHandle process, IntPtr handle, GenericHandle dupHandle) { int retLength; Win32.NtQueryObject( dupHandle, ObjectInformationClass.ObjectNameInformation, IntPtr.Zero, 0, out retLength ); if (retLength > 0) { using (MemoryAlloc oniMem = new MemoryAlloc(retLength)) { Win32.NtQueryObject( dupHandle, ObjectInformationClass.ObjectNameInformation, oniMem, oniMem.Size, out retLength ).ThrowIf(); ObjectNameInformation oni = oniMem.ReadStruct<ObjectNameInformation>(); UnicodeString str = oni.Name; //if (KProcessHacker.Instance != null) //str.Buffer = str.Buffer.Increment(oniMem.Memory.Decrement(baseAddress)); return str.Text; } } throw new Exception("NtQueryObject failed."); }