コード例 #1
0
        private static string GetHandleTypeToken(IntPtr handle)
        {
            int length;

            NativeMethods.NtQueryObject(
                handle, ObjectInformationClass.ObjectTypeInformation, IntPtr.Zero, 0,
                out length
                );

            using (SmartPtr sptr = new SmartPtr())
            {
                sptr.Allocate(length);
                if (NativeMethods.NtQueryObject(
                        handle, ObjectInformationClass.ObjectTypeInformation,
                        sptr.Pointer, length, out length
                        ) == NtStatus.Success
                    )
                {
                    ObjectTypeInformation oti =
                        (ObjectTypeInformation)Marshal.PtrToStructure(sptr.Pointer, typeof(ObjectTypeInformation));
                    UnicodeString unicodeType = oti.Name;
                    string        typeName    = unicodeType.GetValue();
                    return(typeName);
                }
            }
            return(string.Empty);
        }
コード例 #2
0
ファイル: FileUsageService.cs プロジェクト: laptou/tsa-2017
        public static async Task <IEnumerable <string> > GetOpenFiles(int pid)
        {
            List <string> files = new List <string>();

            Parallel.ForEach(
                await GetHandles(pid),
                myHandle =>
            {
                NTStatus status;

                IntPtr myProcessHandle      = OpenProcess(ProcessAccessFlags.DuplicateHandle, false, myHandle.GetPid());
                IntPtr currentProcessHandle = GetCurrentProcess();
                IntPtr targetHandle         = Marshal.AllocHGlobal(Marshal.SizeOf <uint>());
                status = NtDuplicateObject(myProcessHandle, myHandle.HandleValue, currentProcessHandle, targetHandle, 0, 0, 0);
                CloseHandle(myProcessHandle);
                CloseHandle(currentProcessHandle);

                if (status != NTStatus.Success)
                {
                    Marshal.FreeHGlobal(targetHandle);
                    return;
                }

                IntPtr handle = Marshal.PtrToStructure <IntPtr>(targetHandle);
                Marshal.FreeHGlobal(targetHandle);

                IntPtr objectTypeInfo = Marshal.AllocHGlobal(Marshal.SizeOf <ObjectTypeInformation>());
                uint returnLength     = 0;
                status = NtQueryObject(
                    handle,
                    ObjectInformationClass.ObjectTypeInformation,
                    objectTypeInfo,
                    (uint)Marshal.SizeOf <ObjectTypeInformation>(),
                    ref returnLength);

                if (status != NTStatus.Success)
                {
                    objectTypeInfo = Marshal.ReAllocHGlobal(objectTypeInfo, (IntPtr)returnLength);
                    status         = NtQueryObject(
                        handle,
                        ObjectInformationClass.ObjectTypeInformation,
                        objectTypeInfo,
                        returnLength,
                        ref returnLength);

                    if (status != NTStatus.Success)
                    {
                        Marshal.FreeHGlobal(objectTypeInfo);
                        CloseHandle(handle);
                        return;
                    }
                }

                ObjectTypeInformation oti = Marshal.PtrToStructure <ObjectTypeInformation>(objectTypeInfo);
                string typeName           = oti.Name.ToString();
                Marshal.FreeHGlobal(objectTypeInfo);

                IntPtr objectNameInfo = Marshal.AllocHGlobal(Marshal.SizeOf <ObjectNameInformation>());
                returnLength          = (uint)Marshal.SizeOf <ObjectNameInformation>();
                status = NtQueryObject(
                    handle,
                    ObjectInformationClass.ObjectNameInformation,
                    objectNameInfo,
                    (uint)Marshal.SizeOf <ObjectNameInformation>(),
                    ref returnLength);

                if (status != NTStatus.Success)
                {
                    objectNameInfo = Marshal.ReAllocHGlobal(objectNameInfo, (IntPtr)returnLength);
                    status         = NtQueryObject(
                        handle,
                        ObjectInformationClass.ObjectNameInformation,
                        objectNameInfo,
                        returnLength,
                        ref returnLength);
                    if (status != NTStatus.Success)
                    {
                        Marshal.FreeHGlobal(objectNameInfo);
                        CloseHandle(handle);
                        return;
                    }
                }

                ObjectNameInformation oni = Marshal.PtrToStructure <ObjectNameInformation>(objectNameInfo);
                string objName            = oni.Name.ToString();
                Marshal.FreeHGlobal(objectNameInfo);

                if (typeName.Equals("File"))
                {
                    uint fnLength    = 0;
                    StringBuilder sb = new StringBuilder(0);
                    fnLength         = GetFinalPathNameByHandle(handle, sb, fnLength, 0);
                    sb.Capacity      = (int)fnLength;

                    if (GetFinalPathNameByHandle(handle, sb, fnLength, 0) > 1)
                    {
                        files.Add(sb.ToString());
                    }
                }

                CloseHandle(handle);
            });
            return(files);
        }
コード例 #3
0
        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);
        }