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); } }
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> >()); }
/// <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()); } }
/// <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)); } } }
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); }
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++; } }); }