private static IEnumerable <string> GetServiceRequiredPrivileges(SafeServiceHandle service) { using (var buf = new SafeHGlobalBuffer(8192)) { if (!Win32NativeMethods.QueryServiceConfig2(service, SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO, buf, buf.Length, out int needed)) { return(new string[0]); } IntPtr str_pointer = buf.Read <IntPtr>(0); if (str_pointer == IntPtr.Zero) { return(new string[0]); } SafeHGlobalBuffer str_buffer = new SafeHGlobalBuffer(str_pointer, 8192 - 8, false); ulong offset = 0; List <string> privs = new List <string>(); while (offset < str_buffer.ByteLength) { string s = str_buffer.ReadNulTerminatedUnicodeString(offset); if (s.Length == 0) { break; } privs.Add(s); offset += (ulong)(s.Length + 1) * 2; } return(privs.AsReadOnly()); } }
static void ReadArray <T>(IntPtr ptr, int count, out T[] ret) where T : struct { ret = new T[count]; using (SafeHGlobalBuffer buffer = new SafeHGlobalBuffer(ptr, count * Marshal.SizeOf(typeof(T)), false)) { buffer.ReadArray(0, ret, 0, count); } }
private static NtResult <string[]> GetAppIds(string full_name) { var result = Win32NativeMethods.OpenPackageInfoByFullName(full_name, 0, out IntPtr package_info); if (result != Win32Error.SUCCESS) { return(result.CreateResultFromDosError <string[]>(false)); } try { int length = 0; result = Win32NativeMethods.GetPackageApplicationIds(package_info, ref length, SafeHGlobalBuffer.Null, out int count); if (result != Win32Error.ERROR_INSUFFICIENT_BUFFER) { return(result.CreateResultFromDosError <string[]>(false)); } using (var buffer = new SafeHGlobalBuffer(length)) { return(Win32NativeMethods.GetPackageApplicationIds(package_info, ref length, buffer, out count) .CreateWin32Result(false, () => ReadStrings(buffer, count))); } } finally { if (package_info != IntPtr.Zero) { Win32NativeMethods.ClosePackageInfo(package_info); } } }
private void ParseDebugData() { try { _debug_data = new DllDebugData(); IntPtr debug_data = Win32NativeMethods.ImageDirectoryEntryToData(handle, MappedAsImage, IMAGE_DIRECTORY_ENTRY_DEBUG, out int size); if (debug_data == IntPtr.Zero) { return; } SafeHGlobalBuffer buffer = new SafeHGlobalBuffer(debug_data, size, false); int count = size / Marshal.SizeOf(typeof(ImageDebugDirectory)); ImageDebugDirectory[] entries = new ImageDebugDirectory[count]; buffer.ReadArray(0, entries, 0, count); foreach (var debug_dir in entries) { if (debug_dir.Type == IMAGE_DEBUG_TYPE_CODEVIEW && debug_dir.AddressOfRawData != 0) { var codeview = new SafeHGlobalBuffer(RvaToVA(debug_dir.AddressOfRawData), debug_dir.SizeOfData, false); _debug_data = new DllDebugData(codeview); break; } } } catch { } }
internal Credential(CREDENTIAL cred) { Flags = cred.Flags; Type = cred.Type; TargetName = cred.TargetName ?? string.Empty; Comment = cred.Comment ?? string.Empty; LastWritten = cred.LastWritten.ToDateTime(); Persist = cred.Persist; TargetAlias = cred.TargetAlias ?? string.Empty; UserName = cred.UserName ?? string.Empty; if (cred.CredentialBlob == IntPtr.Zero || cred.CredentialBlobSize <= 0) { _credblob = new byte[0]; } else { _credblob = new byte[cred.CredentialBlobSize]; Marshal.Copy(cred.CredentialBlob, _credblob, 0, _credblob.Length); } var attrs = new List <CredentialAttribute>(); if (cred.AttributeCount > 0 && cred.Attributes != IntPtr.Zero) { var buffer = new SafeHGlobalBuffer(cred.Attributes, 1, false); attrs.AddRange(buffer.DangerousReadArray <CREDENTIAL_ATTRIBUTE>(0, cred.AttributeCount).Select(a => new CredentialAttribute(a))); } Attributes = attrs.AsReadOnly(); }
/// <summary> /// Sets UI restrictions. /// </summary> /// <param name="uiRestrictionsClass">The restriction class for the UI.</param> public void SetUiRestrictions(JOB_OBJECT_UILIMIT_FLAGS uiRestrictionsClass = JOB_OBJECT_UILIMIT_FLAGS.ALL) { this.tracer.Trace(nameof(JobObject), "Setting UI restrictions"); var uiRestrictions = new JOBOBJECT_BASIC_UI_RESTRICTIONS { UIRestrictionsClass = uiRestrictionsClass, }; using (var nativeUiRestrictions = new SafeHGlobalBuffer(Marshal.SizeOf(typeof(JOBOBJECT_BASIC_UI_RESTRICTIONS)))) { Marshal.StructureToPtr( uiRestrictions, nativeUiRestrictions.DangerousGetHandle(), false /* fDeleteOld */); if (!Methods.SetInformationJobObject( this.handle, JOB_OBJECT_INFO_CLASS.JobObjectBasicUIRestrictions, nativeUiRestrictions.DangerousGetHandle(), nativeUiRestrictions.Size)) { throw new SandboxException( "Unable to set job object basic ui restrictions", new Win32Exception()); } } }
static IEnumerable <ServiceTriggerInformation> GetTriggersForService(SafeServiceHandle service) { List <ServiceTriggerInformation> triggers = new List <ServiceTriggerInformation>(); using (var buf = new SafeStructureInOutBuffer <SERVICE_TRIGGER_INFO>(8192, false)) { int required = 0; if (!QueryServiceConfig2(service, SERVICE_CONFIG_TRIGGER_INFO, buf, 8192, out required)) { return(triggers.AsReadOnly()); } SERVICE_TRIGGER_INFO trigger_info = buf.Result; if (trigger_info.cTriggers == 0) { return(triggers.AsReadOnly()); } SERVICE_TRIGGER[] trigger_arr; using (SafeHGlobalBuffer trigger_buffer = new SafeHGlobalBuffer(trigger_info.pTriggers, trigger_info.cTriggers * Marshal.SizeOf(typeof(SERVICE_TRIGGER)), false)) { trigger_arr = new SERVICE_TRIGGER[trigger_info.cTriggers]; trigger_buffer.ReadArray(0, trigger_arr, 0, trigger_arr.Length); } for (int i = 0; i < trigger_arr.Length; ++i) { triggers.Add(new ServiceTriggerInformation(trigger_arr[i])); } return(triggers.AsReadOnly()); } }
public SecurityInformationImpl(string obj_name, NtObject handle, Dictionary <uint, string> names, GenericMapping generic_mapping, bool read_only) { _mapping = generic_mapping; _handle = handle; _obj_name = new SafeStringBuffer(obj_name); _access_map = new SafeHGlobalBuffer(Marshal.SizeOf(typeof(SiAccess)) * names.Count); SiAccess[] sis = new SiAccess[names.Count]; IntPtr current_ptr = _access_map.DangerousGetHandle(); _names = new DisposableList <SafeStringBuffer>(); int i = 0; foreach (KeyValuePair <uint, string> pair in names) { _names.Add(new SafeStringBuffer(pair.Value)); SiAccess si = new SiAccess(); si.dwFlags = SiAccessFlags.SI_ACCESS_SPECIFIC | SiAccessFlags.SI_ACCESS_GENERAL; si.mask = pair.Key; si.pszName = _names[i].DangerousGetHandle(); sis[i] = si; i++; } _access_map.WriteArray(0, sis, 0, names.Count); _read_only = read_only; }
/// <summary> /// Get the list of registered trace GUIDs. /// </summary> /// <returns>The list of trace GUIDs.</returns> public static IEnumerable <Guid> GetTraceGuids() { int curr_length = 1024; while (true) { using (var buffer = new SafeHGlobalBuffer(curr_length)) { Win32Error error = Win32NativeMethods.EnumerateTraceGuidsEx(TRACE_QUERY_INFO_CLASS.TraceGuidQueryList, SafeHGlobalBuffer.Null, 0, buffer, buffer.Length, out int return_length); if (error == Win32Error.ERROR_INSUFFICIENT_BUFFER) { curr_length = return_length; continue; } error.ToNtException(); int count = return_length / 16; Guid[] ret = new Guid[count]; buffer.ReadArray(0, ret, 0, count); return(ret); } } }
public void AddAttribute(IntPtr attribute, SafeHGlobalBuffer value) { if (!UpdateProcThreadAttribute(handle, 0, attribute, value.DangerousGetHandle(), new IntPtr(value.Length), IntPtr.Zero, IntPtr.Zero)) { throw new SafeWin32Exception(); } }
/// <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)); } }
internal IkeSecurityAssociation(IKEEXT_SA_DETAILS1 sa_details) { Id = sa_details.saId; KeyModuleType = sa_details.keyModuleType; LocalAddress = FirewallUtils.GetAddress(sa_details.ikeTraffic.ipVersion, sa_details.ikeTraffic.localAddress); RemoteAddress = FirewallUtils.GetAddress(sa_details.ikeTraffic.ipVersion, sa_details.ikeTraffic.remoteAddress); InitiatorCookie = sa_details.cookiePair.initiator; ResponderCookie = sa_details.cookiePair.responder; IkePolicyKey = sa_details.ikePolicyKey; VirtualIfTunnelId = sa_details.virtualIfTunnelId; CorrelationKey = sa_details.correlationKey.ToArray(); CipherAlgorithm = sa_details.ikeProposal.cipherAlgorithm.algoIdentifier; KeyLength = sa_details.ikeProposal.cipherAlgorithm.keyLen; Rounds = sa_details.ikeProposal.cipherAlgorithm.rounds; IntegrityAlgorithm = sa_details.ikeProposal.integrityAlgorithm.algoIdentifier; MaxLifetime = sa_details.ikeProposal.maxLifetimeSeconds; DiffieHellmanGroup = sa_details.ikeProposal.dhGroup; QuickModeLimit = sa_details.ikeProposal.quickModeLimit; List <IkeCredentialPair> credentials = new List <IkeCredentialPair>(); if (sa_details.ikeCredentials.numCredentials > 0) { SafeHGlobalBuffer buf = new SafeHGlobalBuffer(sa_details.ikeCredentials.credentials, 1, false); buf.Initialize <IKEEXT_CREDENTIAL_PAIR1>((uint)sa_details.ikeCredentials.numCredentials); var arr = buf.ReadArray <IKEEXT_CREDENTIAL_PAIR1>(0, sa_details.ikeCredentials.numCredentials); credentials.AddRange(arr.Select(c => new IkeCredentialPair(c))); } Credentials = credentials.AsReadOnly(); }
/// <summary> /// Logon user using S4U /// </summary> /// <param name="user">The username.</param> /// <param name="realm">The user's realm.</param> /// <param name="type">The type of logon token.</param> /// <param name="auth_package">The name of the auth package to user.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The logged on token.</returns> public static NtResult <NtToken> LsaLogonS4U(string user, string realm, SecurityLogonType type, string auth_package, bool throw_on_error) { if (user is null) { throw new ArgumentNullException(nameof(user)); } if (realm is null) { throw new ArgumentNullException(nameof(realm)); } byte[] user_bytes = Encoding.Unicode.GetBytes(user); byte[] realm_bytes = Encoding.Unicode.GetBytes(realm); using (var buffer = new SafeStructureInOutBuffer <KERB_S4U_LOGON>(user_bytes.Length + realm_bytes.Length, true)) { KERB_S4U_LOGON logon_struct = new KERB_S4U_LOGON { MessageType = KERB_LOGON_SUBMIT_TYPE.KerbS4ULogon }; SafeHGlobalBuffer data_buffer = buffer.Data; logon_struct.ClientUpn.Buffer = data_buffer.DangerousGetHandle(); data_buffer.WriteArray(0, user_bytes, 0, user_bytes.Length); logon_struct.ClientUpn.Length = (ushort)user_bytes.Length; logon_struct.ClientUpn.MaximumLength = (ushort)user_bytes.Length; logon_struct.ClientRealm.Buffer = data_buffer.DangerousGetHandle() + user_bytes.Length; data_buffer.WriteArray((ulong)user_bytes.Length, realm_bytes, 0, realm_bytes.Length); logon_struct.ClientRealm.Length = (ushort)realm_bytes.Length; logon_struct.ClientRealm.MaximumLength = (ushort)realm_bytes.Length; buffer.Result = logon_struct; return(LsaLogonUser(type, auth_package, "S4U", buffer, null, throw_on_error)); } }
private void ParseDelayImports(bool is_64bit) { try { IntPtr imports = Win32NativeMethods.ImageDirectoryEntryToData(handle, MappedAsImage, IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT, out int size); if (imports == IntPtr.Zero) { return; } SafeHGlobalBuffer buffer = new SafeHGlobalBuffer(imports, size, false); ulong ofs = 0; ImageDelayImportDescriptor import_desc = buffer.Read <ImageDelayImportDescriptor>(ofs); while (import_desc.szName != 0) { _imports.Add(ParseSingleImport(import_desc.szName, import_desc.pINT, import_desc.pIAT, is_64bit, true)); ofs += (ulong)Marshal.SizeOf(typeof(ImageDelayImportDescriptor)); import_desc = buffer.Read <ImageDelayImportDescriptor>(ofs); } } catch { } }
internal EventTraceLog(long handle, Guid session_guid, string session_name, SafeHGlobalBuffer properties) { _handle = handle; SessionGuid = session_guid; SessionName = session_name; _properties = properties.Detach(); _providers = new List <EnabledProvider>(); }
/// <summary> /// Send a message to the filter. /// </summary> /// <param name="input">The input buffer.</param> /// <param name="max_output_length">The maximum size of the output buffer.</param> /// <param name="throw_on_error">true to throw on error.</param> /// <returns>The output buffer.</returns> public NtResult <byte[]> SendMessage(byte[] input, int max_output_length, bool throw_on_error) { using (var input_buffer = input?.ToBuffer()) { using (var output_buffer = new SafeHGlobalBuffer(max_output_length)) { return(SendMessage(input_buffer, output_buffer, throw_on_error).Map(i => output_buffer.ReadBytes(i))); } } }
internal ImageSection(ImageSectionHeader header, bool mapped_as_image, IntPtr base_ptr) { Name = header.GetName(); int data_offset = mapped_as_image ? header.VirtualAddress : header.PointerToRawData; int data_size = mapped_as_image ? header.VirtualSize : header.SizeOfRawData; Data = new SafeHGlobalBuffer(base_ptr + data_offset, data_size, false); RelativeVirtualAddress = header.VirtualAddress; }
internal DllDebugData(SafeHGlobalBuffer buffer) : this() { Magic = buffer.Read <uint>(0); if (Magic == CV_RSDS_MAGIC) { Id = new Guid(buffer.ReadBytes(4, 16)); Age = buffer.Read <int>(20); PdbPath = buffer.ReadNulTerminatedAnsiString(24, Encoding.UTF8); IdentiferPath = $"{Id:N}{Age:X}".ToUpper(); } }
private static IReadOnlyList <UserGroup> ReadSids(IntPtr ptr, int count) { if (ptr == IntPtr.Zero || count == 0) { return(new List <UserGroup>().AsReadOnly()); } SafeHGlobalBuffer buffer = new SafeHGlobalBuffer(ptr, 1, false); buffer.Initialize <SidAndAttributes>((uint)count); return(buffer.ReadArray <SidAndAttributes>(0, count).Select(s => s.ToUserGroup()).ToList().AsReadOnly()); }
public static extern int NtDeviceIoControlFile( SafeFileHandle FileHandle, IntPtr Event, IntPtr ApcRoutine, IntPtr ApcContext, [In][Out] IoStatusBlock IoStatusBlock, uint IoControlCode, SafeHGlobalBuffer InputBuffer, int InputBufferLength, SafeHGlobalBuffer OutputBuffer, int OutputBufferLength );
private static IEnumerable <string> GetServiceRequiredPrivileges(SafeServiceHandle service) { using (var buf = new SafeHGlobalBuffer(8192)) { if (!Win32NativeMethods.QueryServiceConfig2(service, SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO, buf, buf.Length, out int needed)) { return(new string[0]); } return(buf.Read <IntPtr>(0).GetMultiString()); } }
internal ImageSection(ImageSectionHeader header, bool mapped_as_image, IntPtr base_ptr) { Name = header.GetName(); int data_offset = mapped_as_image ? header.VirtualAddress : header.PointerToRawData; int data_size = mapped_as_image ? header.VirtualSize : header.SizeOfRawData; Data = new SafeHGlobalBuffer(base_ptr + data_offset, data_size, false); RelativeVirtualAddress = header.VirtualAddress; Characteristics = (ImageSectionCharacteristics)(uint)header.Characteristics; Characteristics &= ImageSectionCharacteristics.Code | ImageSectionCharacteristics.Execute | ImageSectionCharacteristics.InitiailizedData | ImageSectionCharacteristics.Read | ImageSectionCharacteristics.Shared | ImageSectionCharacteristics.UninitializedData | ImageSectionCharacteristics.Write; }
internal static extern bool EnumServicesStatusEx( SafeServiceHandle hSCManager, SC_ENUM_TYPE InfoLevel, ServiceType dwServiceType, SERVICE_STATE dwServiceState, SafeHGlobalBuffer lpServices, int cbBufSize, out int pcbBytesNeeded, out int lpServicesReturned, ref int lpResumeHandle, string pszGroupName );
/// <summary> /// Sets limits. /// </summary> /// <param name="activeProcessLimit">The number of processes that can be added to the job object.</param> /// <param name="jobMemoryLimitInBytes">The total amount of memory that can be consumed by all processes in the job object.</param> /// <param name="limitFlags">The limits that are in effect.</param> /// <param name="processMemoryLimitInBytes">The maximum number of bytes a process can consume.</param> public void SetLimits( uint? activeProcessLimit = null, ulong? jobMemoryLimitInBytes = null, JOB_OBJECT_LIMIT_FLAGS limitFlags = JOB_OBJECT_LIMIT_FLAGS.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE, ulong? processMemoryLimitInBytes = null) { this.tracer.Trace(nameof(JobObject), "Setting limits"); var extendedLimitInformation = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION { BasicLimitInformation = { LimitFlags = limitFlags, }, }; if (activeProcessLimit.HasValue) { extendedLimitInformation.BasicLimitInformation.ActiveProcessLimit = activeProcessLimit.GetValueOrDefault(); extendedLimitInformation.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_FLAGS.JOB_OBJECT_LIMIT_ACTIVE_PROCESS; } if (jobMemoryLimitInBytes.HasValue) { extendedLimitInformation.JobMemoryLimit = new UIntPtr(jobMemoryLimitInBytes.GetValueOrDefault()); extendedLimitInformation.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_FLAGS.JOB_OBJECT_LIMIT_JOB_MEMORY; } if (processMemoryLimitInBytes.HasValue) { extendedLimitInformation.ProcessMemoryLimit = new UIntPtr(processMemoryLimitInBytes.GetValueOrDefault()); extendedLimitInformation.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_FLAGS.JOB_OBJECT_LIMIT_PROCESS_MEMORY; } // Apply the limits to the job object. using (var nativeExtendedLimitInformation = new SafeHGlobalBuffer(Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)))) { Marshal.StructureToPtr(extendedLimitInformation, nativeExtendedLimitInformation.DangerousGetHandle(), fDeleteOld: false); if (!Methods.SetInformationJobObject( this.handle, JOB_OBJECT_INFO_CLASS.JobObjectExtendedLimitInformation, nativeExtendedLimitInformation.DangerousGetHandle(), nativeExtendedLimitInformation.Size)) { throw new SandboxException( "Unable to set job object limit information", new Win32Exception()); } } }
public static NtToken LogonS4U(string user, string realm, SecurityLogonType type) { SafeLsaHandle hlsa = null; LsaString pkgName = new LsaString("Negotiate"); LsaConnectUntrusted(out hlsa).ToNtException(); using (hlsa) { uint authnPkg; LsaLookupAuthenticationPackage(hlsa, pkgName, out authnPkg).ToNtException(); byte[] user_bytes = Encoding.Unicode.GetBytes(user); byte[] realm_bytes = Encoding.Unicode.GetBytes(realm); using (var buffer = new SafeStructureInOutBuffer <KERB_S4U_LOGON>(user_bytes.Length + realm_bytes.Length, true)) { KERB_S4U_LOGON logon_struct = new KERB_S4U_LOGON(); logon_struct.MessageType = KERB_LOGON_SUBMIT_TYPE.KerbS4ULogon; SafeHGlobalBuffer data_buffer = buffer.Data; logon_struct.ClientUpn.Buffer = data_buffer.DangerousGetHandle(); data_buffer.WriteArray(0, user_bytes, 0, user_bytes.Length); logon_struct.ClientUpn.Length = (ushort)user_bytes.Length; logon_struct.ClientUpn.MaximumLength = (ushort)user_bytes.Length; logon_struct.ClientRealm.Buffer = data_buffer.DangerousGetHandle() + user_bytes.Length; data_buffer.WriteArray((ulong)user_bytes.Length, realm_bytes, 0, realm_bytes.Length); logon_struct.ClientRealm.Length = (ushort)realm_bytes.Length; logon_struct.ClientRealm.MaximumLength = (ushort)realm_bytes.Length; Marshal.StructureToPtr(logon_struct, buffer.DangerousGetHandle(), false); TOKEN_SOURCE tokenSource = new TOKEN_SOURCE("NtLmSsp"); AllocateLocallyUniqueId(out tokenSource.SourceIdentifier); LsaString originName = new LsaString("S4U"); IntPtr profile; int cbProfile; Luid logon_id; NtStatus subStatus; QUOTA_LIMITS quota_limits; SafeKernelObjectHandle token_handle; LsaLogonUser(hlsa, originName, type, authnPkg, buffer, buffer.Length, IntPtr.Zero, tokenSource, out profile, out cbProfile, out logon_id, out token_handle, out quota_limits, out subStatus).ToNtException(); LsaFreeReturnBuffer(profile); return(NtToken.FromHandle(token_handle)); } } }
private static IEnumerable <UsnJournalRecord> ReadJournal(NtFile volume, ulong start_usn, ulong end_usn, UsnJournalReasonFlags reason_mask, bool unprivileged) { if (volume is null) { throw new ArgumentNullException(nameof(volume)); } NtIoControlCode ioctl = unprivileged ? NtWellKnownIoControlCodes.FSCTL_READ_UNPRIVILEGED_USN_JOURNAL : NtWellKnownIoControlCodes.FSCTL_READ_USN_JOURNAL; Dictionary <long, Tuple <string, string> > ref_paths = new Dictionary <long, Tuple <string, string> >(); var data = QueryUsnJournalData(volume); end_usn = Math.Min(end_usn, data.NextUsn); using (var buffer = new SafeHGlobalBuffer(64 * 1024)) { while (start_usn < end_usn) { READ_USN_JOURNAL_DATA_V0 read_journal = new READ_USN_JOURNAL_DATA_V0 { ReasonMask = reason_mask, StartUsn = start_usn, UsnJournalID = data.UsnJournalID }; using (var in_buffer = read_journal.ToBuffer()) { int length = volume.FsControl(ioctl, in_buffer, buffer); int offset = 8; if (length < 8) { yield break; } start_usn = buffer.Read <ulong>(0); while (offset < length) { var header = buffer.Read <USN_RECORD_COMMON_HEADER>((ulong)offset); if (header.MajorVersion == 2 && header.MinorVersion == 0) { var entry = new UsnJournalRecord(buffer.GetStructAtOffset <USN_RECORD_V2>(offset), volume, ref_paths); if (entry.Usn >= end_usn) { break; } yield return(entry); } offset += header.RecordLength; } } } } }
/// <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> >()); }
private static void CheckForFault(SafeHGlobalBuffer buffer, LRPC_MESSAGE_TYPE message_type) { var header = buffer.Read <LRPC_HEADER>(0); if (header.MessageType != LRPC_MESSAGE_TYPE.lmtFault && header.MessageType != message_type) { throw new ArgumentException($"Invalid response message type {header.MessageType}"); } if (header.MessageType == LRPC_MESSAGE_TYPE.lmtFault) { var fault = buffer.GetStructAtOffset <LRPC_FAULT_MESSAGE>(0); throw new RpcFaultException(fault); } }
private static NtResult <SafeHGlobalBuffer> GetClassProperty(Guid class_guid, CmClassType flags, DEVPROPKEY key, out DEVPROPTYPE type, bool throw_on_error) { int length = 0; var result = DeviceNativeMethods.CM_Get_Class_PropertyW(class_guid, key, out type, SafeHGlobalBuffer.Null, ref length, flags); if (result != CrError.BUFFER_SMALL) { return(result.ToNtStatus().CreateResultFromError <SafeHGlobalBuffer>(throw_on_error)); } using (var buffer = new SafeHGlobalBuffer(length)) { return(DeviceNativeMethods.CM_Get_Class_PropertyW(class_guid, key, out type, buffer, ref length, flags).ToNtStatus().CreateResult(throw_on_error, () => buffer.Detach())); } }
private static NtResult <SafeHGlobalBuffer> GetDeviceInterfaceProperty(string device_instance, DEVPROPKEY key, out DEVPROPTYPE type, bool throw_on_error) { int length = 0; var result = DeviceNativeMethods.CM_Get_Device_Interface_PropertyW(device_instance, key, out type, SafeHGlobalBuffer.Null, ref length, 0); if (result != CrError.BUFFER_SMALL) { return(result.ToNtStatus().CreateResultFromError <SafeHGlobalBuffer>(throw_on_error)); } using (var buffer = new SafeHGlobalBuffer(length)) { return(DeviceNativeMethods.CM_Get_Device_Interface_PropertyW(device_instance, key, out type, buffer, ref length, 0).ToNtStatus().CreateResult(throw_on_error, () => buffer.Detach())); } }
/// <summary> /// Constructor /// </summary> /// <param name="security_descriptor">Binary form of security descriptor</param> public SecurityDescriptor(byte[] security_descriptor) { using (SafeHGlobalBuffer buffer = new SafeHGlobalBuffer(security_descriptor)) { ParseSecurityDescriptor(buffer); } }
/// <summary> /// Convert security descriptor to a byte array /// </summary> /// <returns>The binary security descriptor</returns> public byte[] ToByteArray() { SafeStructureInOutBuffer<SecurityDescriptorStructure> sd_buffer = null; SafeHGlobalBuffer dacl_buffer = null; SafeHGlobalBuffer sacl_buffer = null; SafeSidBufferHandle owner_buffer = null; SafeSidBufferHandle group_buffer = null; try { sd_buffer = new SafeStructureInOutBuffer<SecurityDescriptorStructure>(); NtRtl.RtlCreateSecurityDescriptor(sd_buffer, Revision).ToNtException(); SecurityDescriptorControl control = Control & SecurityDescriptorControl.ValidControlSetMask; NtRtl.RtlSetControlSecurityDescriptor(sd_buffer, control, control).ToNtException(); if (Dacl != null) { if (!Dacl.NullAcl) { dacl_buffer = new SafeHGlobalBuffer(Dacl.ToByteArray()); } else { dacl_buffer = new SafeHGlobalBuffer(IntPtr.Zero, 0, false); } NtRtl.RtlSetDaclSecurityDescriptor(sd_buffer, true, dacl_buffer.DangerousGetHandle(), Dacl.Defaulted).ToNtException(); } if (Sacl != null) { if (!Sacl.NullAcl) { sacl_buffer = new SafeHGlobalBuffer(Sacl.ToByteArray()); } else { sacl_buffer = new SafeHGlobalBuffer(IntPtr.Zero, 0, false); } NtRtl.RtlSetSaclSecurityDescriptor(sd_buffer, true, sacl_buffer.DangerousGetHandle(), Sacl.Defaulted).ToNtException(); } if (Owner != null) { owner_buffer = Owner.Sid.ToSafeBuffer(); NtRtl.RtlSetOwnerSecurityDescriptor(sd_buffer, owner_buffer.DangerousGetHandle(), Owner.Defaulted); } if (Group != null) { group_buffer = Group.Sid.ToSafeBuffer(); NtRtl.RtlSetGroupSecurityDescriptor(sd_buffer, group_buffer.DangerousGetHandle(), Group.Defaulted); } int total_length = 0; NtStatus status = NtRtl.RtlAbsoluteToSelfRelativeSD(sd_buffer, new SafeHGlobalBuffer(IntPtr.Zero, 0, false), ref total_length); if (status != NtStatus.STATUS_BUFFER_TOO_SMALL) { status.ToNtException(); } using (SafeHGlobalBuffer relative_sd = new SafeHGlobalBuffer(total_length)) { NtRtl.RtlAbsoluteToSelfRelativeSD(sd_buffer, relative_sd, ref total_length).ToNtException(); return relative_sd.ToArray(); } } finally { if (sd_buffer != null) { sd_buffer.Close(); } if (dacl_buffer != null) { dacl_buffer.Close(); } if (sacl_buffer != null) { sacl_buffer.Close(); } if (owner_buffer != null) { owner_buffer.Close(); } if (group_buffer != null) { group_buffer.Close(); } } }
/// <summary> /// Get a list of handles /// </summary> /// <param name="pid">A process ID to filter on. If -1 will get all handles</param> /// <param name="allow_query">True to allow the handles returned to query for certain properties</param> /// <returns>The list of handles</returns> public static IEnumerable<NtHandle> GetHandles(int pid, bool allow_query) { SafeHGlobalBuffer handleInfo = new SafeHGlobalBuffer(0x10000); try { NtStatus status = 0; int return_length = 0; while ((status = NtSystemCalls.NtQuerySystemInformation(SystemInformationClass.SystemHandleInformation, handleInfo.DangerousGetHandle(), handleInfo.Length, out return_length)) == NtStatus.STATUS_INFO_LENGTH_MISMATCH) { int length = handleInfo.Length * 2; handleInfo.Close(); handleInfo = new SafeHGlobalBuffer(length); } status.ToNtException(); IntPtr handleInfoBuf = handleInfo.DangerousGetHandle(); int handle_count = Marshal.ReadInt32(handleInfoBuf); List<NtHandle> ret = new List<NtHandle>(); handleInfoBuf += IntPtr.Size; for (int i = 0; i < handle_count; ++i) { SystemHandleTableInfoEntry entry = (SystemHandleTableInfoEntry)Marshal.PtrToStructure(handleInfoBuf, typeof(SystemHandleTableInfoEntry)); if (pid == -1 || entry.UniqueProcessId == pid) { ret.Add(new NtHandle(entry, allow_query)); } handleInfoBuf += Marshal.SizeOf(typeof(SystemHandleTableInfoEntry)); } return ret; } finally { handleInfo.Close(); } }
/// <summary> /// Constructor from an manged buffer. /// </summary> /// <param name="sid">A buffer containing a valid SID.</param> /// <exception cref="NtException">Thrown if the buffer is not valid.</exception> public Sid(byte[] sid) { using (SafeHGlobalBuffer buffer = new SafeHGlobalBuffer(sid)) { InitializeFromPointer(buffer.DangerousGetHandle()); } }
public SecurityInformationImpl(string obj_name, NtObject handle, Dictionary<uint, string> names, GenericMapping generic_mapping) { _mapping = generic_mapping; _handle = handle; _obj_name = new SafeStringBuffer(obj_name); _access_map = new SafeHGlobalBuffer(Marshal.SizeOf(typeof(SiAccess)) * names.Count); SiAccess[] sis = new SiAccess[names.Count]; IntPtr current_ptr = _access_map.DangerousGetHandle(); _names = new DisposableList<SafeStringBuffer>(); int i = 0; foreach (KeyValuePair<uint, string> pair in names) { _names.Add(new SafeStringBuffer(pair.Value)); SiAccess si = new SiAccess(); si.dwFlags = SiAccessFlags.SI_ACCESS_SPECIFIC | SiAccessFlags.SI_ACCESS_GENERAL; si.mask = pair.Key; si.pszName = _names[i].DangerousGetHandle(); sis[i] = si; i++; } _access_map.WriteArray(0, sis, 0, names.Count); }