private static IEnumerable <DeviceNode> GetDeviceList(OptionalGuid class_guid, string enumerator, DiGetClassFlags flags)
        {
            var devices = new List <DeviceNode>();

            DeviceNativeMethods.CM_Locate_DevNodeW(out int root, null, 0).ToNtStatus().ToNtException();
            using (var p = DeviceNativeMethods.SetupDiGetClassDevsW(class_guid, enumerator, IntPtr.Zero, flags))
            {
                if (p.IsInvalid)
                {
                    Win32Utils.GetLastWin32Error().ToNtException();
                }
                int             index    = 0;
                int             size     = Marshal.SizeOf(typeof(SP_DEVINFO_DATA));
                SP_DEVINFO_DATA dev_info = new SP_DEVINFO_DATA()
                {
                    cbSize = size
                };
                while (DeviceNativeMethods.SetupDiEnumDeviceInfo(p, index++, ref dev_info))
                {
                    if (dev_info.DevInst != root)
                    {
                        devices.Add(new DeviceNode(dev_info.DevInst));
                    }
                    dev_info.cbSize = size;
                }

                return(devices.AsReadOnly());
            }
        }
        /// <summary>
        /// Backup a user's credentials.
        /// </summary>
        /// <param name="token">The user's token.</param>
        /// <param name="key">The key for the data, typically a unicode password. Optional</param>
        /// <param name="key_encoded">True if the key is already encoded.</param>
        /// <remarks>Caller needs SeTrustedCredmanAccessPrivilege enabled.</remarks>
        public static byte[] Backup(NtToken token, byte[] key, bool key_encoded)
        {
            string target_path = Path.GetTempFileName();
            IntPtr ptr         = IntPtr.Zero;

            try
            {
                int length = (key?.Length * 2) ?? 0;

                if (length > 0)
                {
                    ptr = Marshal.AllocHGlobal(key.Length);
                    Marshal.Copy(key, 0, ptr, key.Length);
                }
                if (!SecurityNativeMethods.CredBackupCredentials(token.Handle, target_path,
                                                                 ptr, length, key_encoded ? 1 : 0))
                {
                    Win32Utils.GetLastWin32Error().ToNtException();
                }

                return(ProtectedData.Unprotect(File.ReadAllBytes(target_path),
                                               null, DataProtectionScope.CurrentUser));
            }
            finally
            {
                if (ptr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(ptr);
                }
                File.Delete(target_path);
            }
        }
Example #3
0
 private NtStatus PrivatePostMessage(Func <IntPtr, int, IntPtr, IntPtr, bool> func, int message, IntPtr wparam, IntPtr lparam, bool throw_on_error)
 {
     if (!func(Handle, message, wparam, lparam))
     {
         return(Win32Utils.GetLastWin32Error().ToNtException(throw_on_error));
     }
     return(NtStatus.STATUS_SUCCESS);
 }
        /// <summary>
        /// Get the Win32 services for the SCM.
        /// </summary>
        /// <param name="service_state">The state of the services to return.</param>
        /// <param name="service_types">The types of services to return.</param>
        /// <param name="throw_on_error">True throw on error.</param>
        /// <returns>The list of services.</returns>
        /// <remarks>SCM must have been opened with EnumerateService access.</remarks>
        public NtResult <IEnumerable <Win32Service> > GetServices(ServiceState service_state, ServiceType service_types, bool throw_on_error)
        {
            SERVICE_STATE state;

            switch (service_state)
            {
            case ServiceState.All:
                state = SERVICE_STATE.SERVICE_STATE_ALL;
                break;

            case ServiceState.Active:
                state = SERVICE_STATE.SERVICE_ACTIVE;
                break;

            case ServiceState.InActive:
                state = SERVICE_STATE.SERVICE_INACTIVE;
                break;

            default:
                throw new ArgumentException("Invalid service state", nameof(service_state));
            }

            List <Win32Service> ret_services = new List <Win32Service>();
            const int           Length       = 32 * 1024;

            using (var buffer = new SafeHGlobalBuffer(Length))
            {
                int resume_handle = 0;
                while (true)
                {
                    bool ret = Win32NativeMethods.EnumServicesStatusEx(_handle, SC_ENUM_TYPE.SC_ENUM_PROCESS_INFO,
                                                                       service_types, state, buffer, buffer.Length, out int bytes_needed, out int services_returned,
                                                                       ref resume_handle, null);
                    Win32Error error = Win32Utils.GetLastWin32Error();
                    if (!ret && error != Win32Error.ERROR_MORE_DATA)
                    {
                        return(error.CreateResultFromDosError <IEnumerable <Win32Service> >(throw_on_error));
                    }

                    ENUM_SERVICE_STATUS_PROCESS[] services = new ENUM_SERVICE_STATUS_PROCESS[services_returned];
                    buffer.ReadArray(0, services, 0, services_returned);
                    ret_services.AddRange(services.Select(s => new Win32Service(_machine_name, s)));
                    if (ret)
                    {
                        break;
                    }
                }
            }
            return(ret_services.CreateResult().Cast <IEnumerable <Win32Service> >());
        }
Example #5
0
 /// <summary>
 /// Write memory to a process.
 /// </summary>
 /// <param name="process">The process to write to.</param>
 /// <param name="base_address">The base address in the process.</param>
 /// <param name="data">The data to write.</param>
 /// <returns>The number of bytes written to the location</returns>
 /// <exception cref="NtException">Thrown on error.</exception>
 public static int WriteMemory(SafeKernelObjectHandle process, long base_address, byte[] data)
 {
     using (SafeHGlobalBuffer buffer = new SafeHGlobalBuffer(data))
     {
         if (!Win32MemoryNativeMethods.WriteProcessMemory(process,
                                                          new IntPtr(base_address), buffer, buffer.LengthIntPtr, out IntPtr return_length))
         {
             Win32Error error = Win32Utils.GetLastWin32Error();
             if (error != Win32Error.ERROR_PARTIAL_COPY)
             {
                 error.ToNtException();
             }
         }
         return(return_length.ToInt32());
     }
 }
Example #6
0
        /// <summary>
        /// Query ELAM information from a driver's resource section.
        /// </summary>
        /// <param name="path">The path to the file.</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The ELAM information if present.</returns>
        public static NtResult <IReadOnlyList <ElamInformation> > GetElamInformation(string path, bool throw_on_error)
        {
            using (var lib = SafeLoadLibraryHandle.LoadLibrary(path, LoadLibraryFlags.LoadLibraryAsDataFile, throw_on_error))
            {
                if (!lib.IsSuccess)
                {
                    return(lib.Cast <IReadOnlyList <ElamInformation> >());
                }
                var ptr = Win32NativeMethods.FindResource(lib.Result, "MicrosoftElamCertificateInfo", "MSElamCertInfoID");
                if (ptr == IntPtr.Zero)
                {
                    return(Win32Utils.GetLastWin32Error().CreateResultFromDosError <IReadOnlyList <ElamInformation> >(throw_on_error));
                }

                IntPtr hResource = Win32NativeMethods.LoadResource(lib.Result, ptr);
                IntPtr buf       = Win32NativeMethods.LockResource(hResource);
                int    size      = Win32NativeMethods.SizeofResource(lib.Result, ptr);

                if (size <= 0)
                {
                    return(NtStatus.STATUS_INVALID_BUFFER_SIZE.CreateResultFromError <IReadOnlyList <ElamInformation> >(throw_on_error));
                }

                byte[] elam_info = new byte[size];

                Marshal.Copy(buf, elam_info, 0, size);
                MemoryStream stm    = new MemoryStream(elam_info);
                BinaryReader reader = new BinaryReader(stm, Encoding.Unicode);
                try
                {
                    List <ElamInformation> ret = new List <ElamInformation>();
                    int count = reader.ReadUInt16();
                    for (int i = 0; i < count; ++i)
                    {
                        string        cert_hash = reader.ReadNulTerminated();
                        HashAlgorithm algorithm = (HashAlgorithm)reader.ReadUInt16();
                        string[]      ekus      = reader.ReadNulTerminated().Split(';');
                        ret.Add(new ElamInformation(cert_hash, algorithm, ekus));
                    }
                    return(ret.AsReadOnly().CreateResult().Cast <IReadOnlyList <ElamInformation> >());
                }
                catch (EndOfStreamException)
                {
                    return(NtStatus.STATUS_END_OF_FILE.CreateResultFromError <IReadOnlyList <ElamInformation> >(throw_on_error));
                }
            }
        }
Example #7
0
        private NtResult <SafeStructureInOutBuffer <T> > QueryBuffer <T>(AUTHZ_CONTEXT_INFORMATION_CLASS info_class, bool throw_on_error) where T : new()
        {
            if (SecurityNativeMethods.AuthzGetInformationFromContext(_handle, info_class, 0, out int required_size, SafeHGlobalBuffer.Null))
            {
                return(NtStatus.STATUS_INVALID_PARAMETER.CreateResultFromError <SafeStructureInOutBuffer <T> >(throw_on_error));
            }

            var err = Win32Utils.GetLastWin32Error();

            if (err != Win32Error.ERROR_INSUFFICIENT_BUFFER)
            {
                return(err.CreateResultFromDosError <SafeStructureInOutBuffer <T> >(throw_on_error));
            }

            using (var buffer = new SafeStructureInOutBuffer <T>(required_size, false)) {
                return(SecurityNativeMethods.AuthzGetInformationFromContext(_handle, info_class,
                                                                            buffer.Length, out required_size, buffer).CreateWin32Result(throw_on_error, () => buffer.Detach()));
            }
        }
        internal NtStatus SetSecurityDescriptor(SecurityInformation security_information, SecurityDescriptor security_descriptor, bool throw_on_error)
        {
            security_information &= DEFAULT_SECURITY_INFORMATION;

            if (IsInvalid || IsClosed)
            {
                return(NtStatus.STATUS_INVALID_HANDLE.ToNtException(throw_on_error));
            }

            if (security_descriptor is null)
            {
                throw new ArgumentNullException(nameof(security_descriptor));
            }

            if (!Win32NativeMethods.SetServiceObjectSecurity(this, security_information, security_descriptor.ToByteArray()))
            {
                return(Win32Utils.GetLastWin32Error().ToNtException(throw_on_error));
            }

            return(NtStatus.STATUS_SUCCESS);
        }
Example #9
0
        private List <string> QueryLocalParameterNames(long address, SymbolLoadedModule module)
        {
            List <string> ret = new List <string>();

            if (address == 0)
            {
                return(ret);
            }
            IMAGEHLP_STACK_FRAME frame = new IMAGEHLP_STACK_FRAME {
                InstructionOffset = address
            };

            if (!_sym_set_context(Handle, ref frame, IntPtr.Zero))
            {
                if (Win32Utils.GetLastWin32Error() != Win32Error.SUCCESS)
                {
                    return(ret);
                }
            }
            _sym_enum_symbols(Handle, 0, null, (s, z, x) => GetLocalParameterName(ret, s, module), IntPtr.Zero);
            return(ret);
        }
        private static void ProcessImports(string executable, ILogger logger, Func <string, bool> predicate)
        {
            ParsePeFile(executable, logger, (image) =>
            {
                bool shouldContinue = true;
                uint size           = 0u;

                var directoryEntry = (IMAGE_IMPORT_DESCRIPTOR *)NativeMethods.ImageDirectoryEntryToData(image.MappedAddress, 0, NativeMethods.IMAGE_DIRECTORY_ENTRY_IMPORT, &size);
                if (directoryEntry == null)
                {
                    logger.DebugWarning($"Error while parsing imports of {executable}: {Win32Utils.GetLastWin32Error()}");
                    return;
                }

                while (shouldContinue && directoryEntry->OriginalFirstThunk != 0u)
                {
                    shouldContinue = predicate(GetString(image, directoryEntry->Name));
                    directoryEntry++;
                }
            });
        }