/// <summary> /// Query security of an event. /// </summary> /// <param name="guid">The event GUID to query.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The event security descriptor.</returns> public static NtResult <SecurityDescriptor> QueryTraceSecurity(Guid guid, bool throw_on_error) { int length = 0; Win32Error error = Win32NativeMethods.EventAccessQuery(ref guid, SafeHGlobalBuffer.Null, ref length); if (error == Win32Error.ERROR_FILE_NOT_FOUND && guid != TraceKnownGuids.DefaultTraceSecurity) { return(QueryTraceSecurity(TraceKnownGuids.DefaultTraceSecurity, throw_on_error)); } if (error != Win32Error.ERROR_MORE_DATA) { return(error.CreateResultFromDosError <SecurityDescriptor>(throw_on_error)); } using (var buffer = new SafeHGlobalBuffer(length)) { error = Win32NativeMethods.EventAccessQuery(ref guid, buffer, ref length); if (error != Win32Error.SUCCESS) { return(error.CreateResultFromDosError <SecurityDescriptor>(throw_on_error)); } return(SecurityDescriptor.Parse(buffer, NtType.GetTypeByType <NtEtwRegistration>(), throw_on_error)); } }
/// <summary> /// Query the socket security information. /// </summary> /// <param name="socket">The socket to query.</param> /// <param name="peer_address">Optional peer address. Only needed for datagram sockets.</param> /// <param name="desired_access">Optional desired access for peer tokens. If set to None then no tokens will be returned.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The socket security information.</returns> public static NtResult <SocketSecurityInformation> QuerySecurity(this Socket socket, IPEndPoint peer_address, TokenAccessRights desired_access, bool throw_on_error) { var query = new SOCKET_SECURITY_QUERY_TEMPLATE_IPSEC2 { SecurityProtocol = SOCKET_SECURITY_PROTOCOL.IPsec2, PeerAddress = peer_address.ToSocketStorage(), PeerTokenAccessMask = desired_access, FieldMask = SocketSecurityQueryFieldMask.MmSaId | SocketSecurityQueryFieldMask.QmSaId }; using (var template = query.ToBuffer()) { int length = 0; SocketNativeMethods.WSAQuerySocketSecurity(socket.Handle, template, template.Length, SafeHGlobalBuffer.Null, ref length, IntPtr.Zero, IntPtr.Zero); Win32Error error = SocketNativeMethods.WSAGetLastError(); if (error != Win32Error.WSAEMSGSIZE) { return(error.CreateResultFromDosError <SocketSecurityInformation>(throw_on_error)); } using (var buffer = new SafeStructureInOutBuffer <SOCKET_SECURITY_QUERY_INFO>(length, false)) { return(SocketNativeMethods.WSAQuerySocketSecurity(socket.Handle, template, template.Length, buffer, ref length, IntPtr.Zero, IntPtr.Zero).CreateWSAResult(throw_on_error, () => new SocketSecurityInformation(buffer))); } } }
internal static NtResult <T> CreateWin32Result <T>(this Win32Error result, bool throw_on_error, Func <T> create_func) { if (result == Win32Error.SUCCESS) { return(create_func().CreateResult()); } return(result.CreateResultFromDosError <T>(throw_on_error)); }
/// <summary> /// Get certificates from a PE file. /// </summary> /// <param name="file">The PE file.</param> /// <param name="throw_on_error">True the throw on error.</param> /// <returns>The list of authenticode certificate entries.</returns> public static NtResult <IReadOnlyList <AuthenticodeCertificate> > GetCertificates(NtFile file, bool throw_on_error) { List <AuthenticodeCertificate> certs = new List <AuthenticodeCertificate>(); Win32Error error = Win32NativeMethods.ImageEnumerateCertificates(file.Handle, WinCertType.WIN_CERT_TYPE_ANY, out int count, null, 0).GetLastWin32Error(); if (error != Win32Error.SUCCESS) { return(error.CreateResultFromDosError <IReadOnlyList <AuthenticodeCertificate> >(throw_on_error)); } for (int i = 0; i < count; ++i) { int size = 0; error = Win32NativeMethods.ImageGetCertificateData(file.Handle, i, SafeHGlobalBuffer.Null, ref size).GetLastWin32Error(); if (error != Win32Error.ERROR_INSUFFICIENT_BUFFER) { return(error.CreateResultFromDosError <IReadOnlyList <AuthenticodeCertificate> >(throw_on_error)); } using (var buffer = new SafeStructureInOutBuffer <WIN_CERTIFICATE>(size, true)) { error = Win32NativeMethods.ImageGetCertificateData(file.Handle, i, buffer, ref size).GetLastWin32Error(); if (error != Win32Error.SUCCESS) { return(error.CreateResultFromDosError <IReadOnlyList <AuthenticodeCertificate> >(throw_on_error)); } var result = buffer.Result; if (result.wCertificateType != WinCertType.WIN_CERT_TYPE_PKCS_SIGNED_DATA) { continue; } var cert = AuthenticodeCertificate.Parse(buffer.Data.ReadBytes(result.dwLength), throw_on_error); if (!cert.IsSuccess) { return(cert.Cast <IReadOnlyList <AuthenticodeCertificate> >()); } certs.Add(cert.Result); } } return(certs.AsReadOnly().CreateResult().Cast <IReadOnlyList <AuthenticodeCertificate> >()); }
/// <summary> /// Create from a package full name. /// </summary> /// <param name="package_full_name">The package full name.</param> /// <param name="full_information">Query for full information (needs to be installed for the current user).</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The package identity.</returns> public static NtResult <PackageIdentity> CreateFromFullName(string package_full_name, bool full_information, bool throw_on_error) { PackageFlags flags = full_information ? PackageFlags.Full : PackageFlags.Basic; var staged_path = GetPackagePath(package_full_name, Win32NativeMethods.GetStagedPackagePathByFullName, throw_on_error); if (!staged_path.IsSuccess) { return(staged_path.Cast <PackageIdentity>()); } Win32Error result = _get_staged_package_origin(package_full_name, out PackageOrigin origin); if (result != Win32Error.SUCCESS) { return(result.CreateResultFromDosError <PackageIdentity>(throw_on_error)); } int length = 0; result = Win32NativeMethods.PackageIdFromFullName(package_full_name, flags, ref length, SafeHGlobalBuffer.Null); if (result != Win32Error.ERROR_INSUFFICIENT_BUFFER) { return(result.CreateResultFromDosError <PackageIdentity>(throw_on_error)); } using (var buffer = new SafeStructureInOutBuffer <PACKAGE_ID>(length, false)) { result = Win32NativeMethods.PackageIdFromFullName(package_full_name, flags, ref length, buffer); if (result != Win32Error.SUCCESS) { return(result.CreateResultFromDosError <PackageIdentity>(throw_on_error)); } return(new PackageIdentity(package_full_name, buffer.Result, origin, staged_path.Result, GetAppIds(package_full_name).GetResultOrDefault()).CreateResult()); } }
/// <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> >()); }