private MaximumAccess GetMaxAccess(TokenEntry token, NtObject obj, ulong obj_address, Dictionary <ulong, MaximumAccess> max_access)
        {
            if (max_access.ContainsKey(obj_address))
            {
                return(max_access[obj_address]);
            }

            NtType type = obj.NtType;

            if (!type.SecurityRequired && string.IsNullOrEmpty(GetObjectName(obj)))
            {
                max_access[obj_address] = new MaximumAccess(type.GenericMapping.GenericAll, string.Empty);
                return(max_access[obj_address]);
            }

            var result = obj.GetSecurityDescriptor(SecurityInformation.AllBasic, false);

            if (!result.IsSuccess && !obj.IsAccessMaskGranted(GenericAccessRights.ReadControl))
            {
                // Try and duplicate handle to see if we can just ask for ReadControl.
                using (var dup_obj = obj.DuplicateObject(GenericAccessRights.ReadControl, AttributeFlags.None,
                                                         DuplicateObjectOptions.None, false))
                {
                    if (dup_obj.IsSuccess)
                    {
                        result = dup_obj.Result.GetSecurityDescriptor(SecurityInformation.AllBasic, false);
                    }
                }
            }

            MaximumAccess access = null;

            if (result.IsSuccess)
            {
                access = new MaximumAccess(NtSecurity.GetMaximumAccess(result.Result, token.Token, type.GenericMapping), result.Result.ToSddl());
            }
            else if (type.CanOpen)
            {
                using (var new_obj = ReopenUnderImpersonation(token, type, obj))
                {
                    if (new_obj.IsSuccess)
                    {
                        access = new MaximumAccess(new_obj.Result.GrantedAccessMask, string.Empty);
                    }
                }
            }

            max_access[obj_address] = access;
            return(access);
        }
 internal HandleAccessCheckResult(MaximumAccess maximum_access, NtHandle handle, string name, string type_name, AccessMask granted_access,
                                  GenericMapping generic_mapping, string sddl, Type enum_type, bool is_directory, TokenInformation token_info)
     : base(name, type_name, granted_access, generic_mapping,
            !string.IsNullOrWhiteSpace(sddl) ? new SecurityDescriptor(sddl) : null,
            enum_type, is_directory, token_info)
 {
     if (maximum_access != null)
     {
         MaximumAccess   = maximum_access.Access;
         DifferentAccess = (granted_access & MaximumAccess) != granted_access;
     }
     ProcessId = handle.ProcessId;
     Handle    = handle.Handle;
     Object    = handle.Object;
 }
        private void CheckHandles(TokenEntry token, HashSet <string> type_filter,
                                  Dictionary <ulong, MaximumAccess> max_access, NtProcess process, IEnumerable <NtHandle> handles)
        {
            foreach (NtHandle handle in handles)
            {
                if (Stopping)
                {
                    return;
                }

                using (var result = NtGeneric.DuplicateFrom(process, new IntPtr(handle.Handle), 0, DuplicateObjectOptions.SameAccess, false))
                {
                    if (!result.IsSuccess)
                    {
                        continue;
                    }

                    using (NtObject obj = result.Result.ToTypedObject())
                    {
                        NtType type = obj.NtType;
                        if (!IsTypeFiltered(type.Name, type_filter))
                        {
                            continue;
                        }

                        string full_path = GetObjectName(obj);

                        MaximumAccess           maximum_access = GetMaxAccess(token, obj, handle.Object, max_access);
                        HandleAccessCheckResult access         = new HandleAccessCheckResult(maximum_access, handle,
                                                                                             full_path, type.Name, handle.GrantedAccess, type.GenericMapping,
                                                                                             maximum_access != null ? maximum_access.SecurityDescriptor : string.Empty, type.AccessRightsType, false, token.Information);
                        WriteObject(access);
                    }
                }
            }
        }