/// <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); } } }
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()); } }
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 { } }
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); } }
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(); }
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()); }
/// <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> >()); }
internal FirewallLayer(FWPM_LAYER0 layer, FirewallEngine engine, Func <SecurityInformation, bool, NtResult <SecurityDescriptor> > get_sd) : base(layer.layerKey, layer.displayData, NamedGuidDictionary.LayerGuids.Value, engine, get_sd) { Flags = layer.flags; DefaultSubLayerKey = layer.defaultSubLayerKey; LayerId = layer.layerId; List <FirewallField> fields = new List <FirewallField>(); if (layer.numFields > 0 && layer.field != IntPtr.Zero) { var buffer = new SafeHGlobalBuffer(layer.field, 1, false); buffer.Initialize <FWPM_FIELD0>((uint)layer.numFields); fields.AddRange(buffer.ReadArray <FWPM_FIELD0>(0, layer.numFields).Select(f => new FirewallField(f))); } Fields = fields.AsReadOnly(); }
/// <summary> /// Get a list of registered services. /// </summary> /// <returns>A list of running services with process IDs.</returns> private static IEnumerable <RunningService> GetServices(SERVICE_STATE service_state) { using (SafeServiceHandle scm = OpenSCManager(null, null, ServiceControlManagerAccessRights.Connect | ServiceControlManagerAccessRights.EnumerateService)) { if (scm.IsInvalid) { throw new SafeWin32Exception(); } ServiceType service_types = ServiceType.Win32OwnProcess | ServiceType.Win32ShareProcess; if (!NtObjectUtils.IsWindows81OrLess) { service_types |= ServiceType.UserService; } const int Length = 32 * 1024; using (var buffer = new SafeHGlobalBuffer(Length)) { int resume_handle = 0; while (true) { bool ret = EnumServicesStatusEx(scm, SC_ENUM_TYPE.SC_ENUM_PROCESS_INFO, service_types, service_state, buffer, buffer.Length, out int bytes_needed, out int services_returned, ref resume_handle, null); int error = Marshal.GetLastWin32Error(); if (!ret && error != ERROR_MORE_DATA) { throw new SafeWin32Exception(error); } ENUM_SERVICE_STATUS_PROCESS[] services = new ENUM_SERVICE_STATUS_PROCESS[services_returned]; buffer.ReadArray(0, services, 0, services_returned); foreach (var service in services) { yield return(new RunningService(service)); } if (ret) { break; } } } } }
internal FirewallFilter(FWPM_FILTER0 filter, FirewallEngine engine, Func <SecurityInformation, bool, NtResult <SecurityDescriptor> > get_sd) : base(filter.filterKey, filter.displayData, new NamedGuidDictionary(), engine, get_sd) { ActionType = filter.action.type; if (ActionType.HasFlag(FirewallActionType.Callout)) { CalloutKey = filter.action.action.calloutKey; CalloutKeyName = NamedGuidDictionary.CalloutGuids.Value.GetName(CalloutKey); } else { FilterType = filter.action.action.filterType; } LayerKey = filter.layerKey; LayerKeyName = NamedGuidDictionary.LayerGuids.Value.GetName(LayerKey); SubLayerKey = filter.subLayerKey; SubLayerKeyName = NamedGuidDictionary.SubLayerGuids.Value.GetName(SubLayerKey); Flags = filter.flags; List <FirewallFilterCondition> conditions = new List <FirewallFilterCondition>(); if (filter.numFilterConditions > 0) { var conds = new SafeHGlobalBuffer(filter.filterCondition, 1, false); conds.Initialize <FWPM_FILTER_CONDITION0>((uint)filter.numFilterConditions); conditions.AddRange(conds.ReadArray <FWPM_FILTER_CONDITION0>(0, filter.numFilterConditions).Select(c => new FirewallFilterCondition(c))); } Conditions = conditions.AsReadOnly(); Weight = new FirewallValue(filter.weight, Guid.Empty); EffectiveWeight = new FirewallValue(filter.effectiveWeight, Guid.Empty); if (filter.providerKey != IntPtr.Zero) { ProviderKey = filter.providerKey.ReadGuid() ?? Guid.Empty; } ProviderData = filter.providerData.ToArray(); FilterId = filter.filterId; }
static void DumpTriggers(SafeServiceHandle service) { 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; } SERVICE_TRIGGER_INFO trigger_info = buf.Result; if (trigger_info.cTriggers == 0) { return; } SERVICE_TRIGGER[] trigger_arr; using (SafeHGlobalBuffer triggers = new SafeHGlobalBuffer(trigger_info.pTriggers, trigger_info.cTriggers * Marshal.SizeOf(typeof(SERVICE_TRIGGER)), false)) { trigger_arr = new SERVICE_TRIGGER[trigger_info.cTriggers]; triggers.ReadArray(0, trigger_arr, 0, trigger_arr.Length); } for (int i = 0; i < trigger_arr.Length; ++i) { SERVICE_TRIGGER trigger = trigger_arr[i]; Console.WriteLine("Trigger: {0} - Type: {1} - Action: {2}", i, trigger.dwTriggerType, trigger.dwAction); switch (trigger.dwTriggerType) { case ServiceTriggerType.Custom: Console.WriteLine("Subtype: [ETW UUID] {0:B}", trigger.GetSubType()); break; case ServiceTriggerType.DeviceInterfaceArrival: Console.WriteLine("Subtype: [Interface Class GUID] {0:B}", trigger.GetSubType()); break; case ServiceTriggerType.GroupPolicy: { Guid sub_type = trigger.GetSubType(); if (sub_type == MACHINE_POLICY_PRESENT_GUID) { Console.WriteLine("Subtype: [Machine Policy Present]"); } else if (sub_type == USER_POLICY_PRESENT_GUID) { Console.WriteLine("Subtype: [User Policy Present]"); } else { Console.WriteLine("Subtype: [Unknown Group Policy] {0:B}", sub_type); } } break; case ServiceTriggerType.NetworkEndpoint: { Guid sub_type = trigger.GetSubType(); if (sub_type == RPC_INTERFACE_EVENT_GUID) { Console.WriteLine("Subtype: [RPC Interface]"); } else if (sub_type == NAMED_PIPE_EVENT_GUID) { Console.WriteLine("Subtype: [Named Pipe]"); } else { Console.WriteLine("Subtype: [Unknown Network Endpoint] {0:B}", sub_type); } } break; case ServiceTriggerType.DomainJoin: { Guid sub_type = trigger.GetSubType(); if (sub_type == DOMAIN_JOIN_GUID) { Console.WriteLine("Subtype: [Domain Join]"); } else if (sub_type == DOMAIN_LEAVE_GUID) { Console.WriteLine("Subtype: [Domain Leave]"); } else { Console.WriteLine("Subtype: [Unknown Domain Join] {0:B}", sub_type); } } break; case ServiceTriggerType.IPAddressAvailability: { Guid sub_type = trigger.GetSubType(); if (sub_type == NETWORK_MANAGER_FIRST_IP_ADDRESS_ARRIVAL_GUID) { Console.WriteLine("Subtype: [First IP Address Available]"); } else if (sub_type == NETWORK_MANAGER_LAST_IP_ADDRESS_REMOVAL_GUID) { Console.WriteLine("Subtype: [Last IP Address Available]"); } else { Console.WriteLine("Subtype: [Unknown IP Address Availability] {0:B}", sub_type); } } break; } if (trigger.pDataItems != IntPtr.Zero && trigger.cDataItems > 0) { DumpCustomData(trigger); } } } }
/// <summary> /// Parse the policy from the Local Security Authority. /// </summary> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The list of Central Access Policies.</returns> public static NtResult <CentralAccessPolicy[]> ParseFromLsa(bool throw_on_error) { NtStatus status = SecurityNativeMethods.LsaGetAppliedCAPIDs(null, out SafeLsaMemoryBuffer capids, out int capid_count); if (!status.IsSuccess()) { return(status.CreateResultFromError <CentralAccessPolicy[]>(throw_on_error)); } List <CentralAccessPolicy> ret = new List <CentralAccessPolicy>(); using (capids) { status = SecurityNativeMethods.LsaQueryCAPs(capids.DangerousGetHandle(), capid_count, out SafeLsaMemoryBuffer caps, out uint cap_count); if (!status.IsSuccess()) { return(status.CreateResultFromError <CentralAccessPolicy[]>(throw_on_error)); } caps.Initialize <CENTRAL_ACCESS_POLICY>(cap_count); CENTRAL_ACCESS_POLICY[] policies = new CENTRAL_ACCESS_POLICY[cap_count]; caps.ReadArray(0, policies, 0, policies.Length); foreach (var policy in policies) { SafeHGlobalBuffer buffer = new SafeHGlobalBuffer(policy.CAPEs, policy.CAPECount * IntPtr.Size, false); IntPtr[] rule_entries = new IntPtr[policy.CAPECount]; buffer.ReadArray(0, rule_entries, 0, policy.CAPECount); List <CentralAccessRule> rules = new List <CentralAccessRule>(); foreach (var ptr in rule_entries) { var entry = new SafeStructureInOutBuffer <CENTRAL_ACCESS_POLICY_ENTRY>(ptr, Marshal.SizeOf(typeof(CENTRAL_ACCESS_POLICY_ENTRY)), false); var r = entry.Result; SecurityDescriptor sd = null; SecurityDescriptor staged_sd = null; string applies_to = string.Empty; if (r.LengthSD > 0) { var result = SecurityDescriptor.Parse(r.SD, throw_on_error); if (!result.IsSuccess) { return(result.Cast <CentralAccessPolicy[]>()); } sd = result.Result; } if (r.LengthStagedSD > 0) { var result = SecurityDescriptor.Parse(r.StagedSD, throw_on_error); if (!result.IsSuccess) { return(result.Cast <CentralAccessPolicy[]>()); } staged_sd = result.Result; } if (r.LengthAppliesTo > 0) { byte[] condition = new byte[r.LengthAppliesTo]; Marshal.Copy(r.AppliesTo, condition, 0, r.LengthAppliesTo); var result = NtSecurity.ConditionalAceToString(condition, throw_on_error); if (!result.IsSuccess) { return(result.Cast <CentralAccessPolicy[]>()); } applies_to = result.Result; } rules.Add(new CentralAccessRule(r.Name.ToString(), r.Description.ToString(), sd, staged_sd, applies_to, r.ChangeId.ToString(), r.Flags)); } var capid = Sid.Parse(policy.CAPID, throw_on_error); if (!capid.IsSuccess) { return(capid.Cast <CentralAccessPolicy[]>()); } ret.Add(new CentralAccessPolicy(capid.Result, policy.Flags, policy.Name.ToString(), policy.Description.ToString(), policy.ChangeId.ToString(), rules)); } } return(ret.ToArray().CreateResult()); }