From d3191a75fe3b63ceac8786b17006b206a667c321 Mon Sep 17 00:00:00 2001 From: "Richie Gomez (he/him)" Date: Thu, 15 Oct 2026 13:03:40 -0700 Subject: [PATCH 1/2] Fix manifested network decision provider recognition Recognize the OS-manifested Learning Mode network provider alongside the earlier identity, preserve the observed GUID in verbose diagnostics, and cover both identities with regression tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 16300264-31dd-4214-a056-f01395e3179e --- docs/logging-access-denied.md | 6 +- .../core/learning_mode_windows/etl_decode.rs | 84 +++++++++++++++++-- .../core/learning_mode_windows/extractors.rs | 13 +-- .../network_extractors.rs | 10 ++- 4 files changed, 97 insertions(+), 16 deletions(-) diff --git a/docs/logging-access-denied.md b/docs/logging-access-denied.md index 16b2765b8..b4baf88c7 100644 --- a/docs/logging-access-denied.md +++ b/docs/logging-access-denied.md @@ -238,7 +238,9 @@ sandbox policy: Feature-enabled Windows builds can add WFP decisions to the managed Learning Mode ETL through the manifested `Microsoft-Windows-LearningMode-NetworkDecision` provider -(`{71237669-21C3-4101-BD2F-FF38945D725A}`). MXC accepts event ID `1`, +(`{301EC03D-2951-5EFB-6D99-59C64628BBFC}`). MXC also recognizes the earlier +provider identity `{71237669-21C3-4101-BD2F-FF38945D725A}` and retains the +observed GUID in verbose signatures. MXC accepts event ID `1`, `NetworkDecisionV1`, with schema version `1`. The OS Learning Mode broker owns the WFP subscription, runtime-filter lookup, subject scoping, event normalization, queue draining, and ETW flush before the trace is sealed. @@ -421,7 +423,7 @@ to the redaction, timestamp omission, and bounds described below. { "signature": { "provider": "learningModeNetworkDecision", - "providerGuid": "{71237669-21C3-4101-BD2F-FF38945D725A}", + "providerGuid": "{301EC03D-2951-5EFB-6D99-59C64628BBFC}", "eventId": 1, "eventName": "NetworkDecisionV1", "reason": "actionable", diff --git a/src/mxc-sdk/src/core/learning_mode_windows/etl_decode.rs b/src/mxc-sdk/src/core/learning_mode_windows/etl_decode.rs index 33ef9add8..e6c7aa34a 100644 --- a/src/mxc-sdk/src/core/learning_mode_windows/etl_decode.rs +++ b/src/mxc-sdk/src/core/learning_mode_windows/etl_decode.rs @@ -473,6 +473,7 @@ impl<'visitor> Accumulator<'visitor> { fn record_network_outcome( &mut self, + provider: windows::core::GUID, event_id: u16, event_name: Option, analysis: &crate::learning_mode_windows::network_extractors::NetworkDecisionAnalysis, @@ -480,7 +481,9 @@ impl<'visitor> Accumulator<'visitor> { let (access_type, resource_type) = analysis.classification; self.record_capture_signature(CaptureVerboseLoggingSignature { provider: CaptureVerboseLoggingProvider::LearningModeNetworkDecision, - provider_guid: "{71237669-21C3-4101-BD2F-FF38945D725A}".to_string(), + provider_guid: crate::learning_mode_windows::extractors::format_guid_braced_uppercase( + provider, + ), event_id, event_name, reason: analysis.reason, @@ -578,7 +581,8 @@ impl<'visitor> Accumulator<'visitor> { if error.event_kind().is_none() && is_process_scoped_event(provider, event_id) { self.truncated = true; } - if provider == crate::learning_mode_windows::network_extractors::NETWORK_DECISION_PROVIDER { + if crate::learning_mode_windows::network_extractors::is_network_decision_provider(provider) + { let reason = match error.event_kind() { Some(tdh_decode::EventDecodeKind::PayloadMalformed) => { CaptureVerboseLoggingOutcomeReason::EventPayloadMalformed @@ -603,6 +607,7 @@ impl<'visitor> Accumulator<'visitor> { }) .map(|(_, value)| value); self.record_network_outcome( + provider, event_id, event_name, &crate::learning_mode_windows::network_extractors::NetworkDecisionAnalysis { @@ -1099,7 +1104,9 @@ unsafe fn process_event_record(event_record: *mut EVENT_RECORD, acc: &mut Accumu let category = crate::learning_mode_windows::extractors::verbose_logging_provider_for_guid(provider); let is_network = - provider == crate::learning_mode_windows::network_extractors::NETWORK_DECISION_PROVIDER; + crate::learning_mode_windows::network_extractors::is_network_decision_provider( + provider, + ); if category.is_none() && !is_network { // Unrelated provider: unrelated host traffic, ignored entirely // (not aggregated as an excluded Learning Mode outcome). @@ -1127,6 +1134,7 @@ unsafe fn process_event_record(event_record: *mut EVENT_RECORD, acc: &mut Accumu // paying for a TDH decode. if is_network { acc.record_network_outcome( + provider, event_id, None, &crate::learning_mode_windows::network_extractors::NetworkDecisionAnalysis { @@ -1300,8 +1308,9 @@ fn handle_decoded_event( filetime: u64, acc: &mut Accumulator<'_>, ) { - if parts.provider == crate::learning_mode_windows::network_extractors::NETWORK_DECISION_PROVIDER - { + if crate::learning_mode_windows::network_extractors::is_network_decision_provider( + parts.provider, + ) { if !acc.event_in_scope(0, filetime) || !acc.begin_event() { return; } @@ -1309,6 +1318,7 @@ fn handle_decoded_event( crate::learning_mode_windows::network_extractors::analyze_network_decision(parts); let denial = analysis.denial.clone(); acc.record_network_outcome( + parts.provider, parts.event_id, (parts.event_id == crate::learning_mode_windows::network_extractors::NETWORK_DECISION_EVENT_ID) @@ -2689,6 +2699,55 @@ mod tests { ) } + #[test] + fn manifest_network_provider_is_actionable_and_preserves_observed_guid() { + use crate::learning_mode_windows::network_extractors::{ + MANIFEST_NETWORK_DECISION_PROVIDER, NETWORK_DECISION_PROVIDER, + }; + + for provider in [ + NETWORK_DECISION_PROVIDER, + MANIFEST_NETWORK_DECISION_PROVIDER, + ] { + let mut event = network_event( + 777, + 600, + &[ + ("SourceDomain", "2"), + ("Reason", "100"), + ("FieldFlags", "63"), + ("ProviderGuid", "{2F8C6D14-3B7E-4A59-9C08-1D4E7A6B2F30}"), + ("SublayerGuid", "{7B1E9A2C-9D4F-4C8A-B321-5E6D2F8A1C44}"), + ("ApplicationId", r"\Device\HarddiskVolume3\app.exe"), + ("Protocol", "6"), + ("LocalAddress", "192.0.2.1"), + ("LocalPort", "49152"), + ("RemoteAddress", "203.0.113.10"), + ("RemotePort", "443"), + ("IsLoopback", "false"), + ], + ); + event.parts.provider = provider; + assert!(is_learning_mode_event(provider, 1)); + assert!(!is_process_scoped_event(provider, 1)); + assert_eq!( + crate::learning_mode_windows::extractors::effective_event_pid(&event.parts, 777), + Some(0), + ); + let mut accumulator = Accumulator::analyze(); + handle_decoded_event(&event.parts, 777, 600, &mut accumulator); + assert_eq!(accumulator.denials.len(), 1); + assert_eq!(accumulator.denials[0].resource, "tcp://203.0.113.10:443"); + let signature = &accumulator.network_verbose_logging.signatures[0].signature; + assert_eq!( + signature.provider_guid, + crate::learning_mode_windows::extractors::format_guid_braced_uppercase(provider), + ); + assert!(signature.reason.is_actionable()); + assert_eq!(signature.pid, 0); + } + } + #[test] #[ignore = "manual benchmark: run with --release --ignored --nocapture"] fn benchmark_high_cardinality_network_capture() { @@ -3957,7 +4016,12 @@ mod tests { classification: (None, None), properties: vec![("Large".to_string(), "x".repeat(remaining_bytes))], }; - accumulator.record_network_outcome(1, Some("NetworkDecisionV1".to_string()), &analysis); + accumulator.record_network_outcome( + crate::learning_mode_windows::network_extractors::NETWORK_DECISION_PROVIDER, + 1, + Some("NetworkDecisionV1".to_string()), + &analysis, + ); assert_eq!(accumulator.network_verbose_logging.overflow_occurrences, 1); assert!(!accumulator.network_verbose_logging_actionable_only_saturated); @@ -3966,7 +4030,12 @@ mod tests { properties: Vec::new(), ..analysis }; - accumulator.record_network_outcome(2, None, &analysis); + accumulator.record_network_outcome( + crate::learning_mode_windows::network_extractors::NETWORK_DECISION_PROVIDER, + 2, + None, + &analysis, + ); assert_eq!(accumulator.network_verbose_logging.signatures.len(), 1); assert_eq!(accumulator.network_verbose_logging.overflow_occurrences, 1); @@ -4228,6 +4297,7 @@ mod tests { fn network_diagnostics_preserve_observed_event_identity() { let mut unsupported = Accumulator::analyze(); unsupported.record_network_outcome( + crate::learning_mode_windows::network_extractors::NETWORK_DECISION_PROVIDER, 999, None, &crate::learning_mode_windows::network_extractors::NetworkDecisionAnalysis { diff --git a/src/mxc-sdk/src/core/learning_mode_windows/extractors.rs b/src/mxc-sdk/src/core/learning_mode_windows/extractors.rs index c36be16ef..1ee4d6c23 100644 --- a/src/mxc-sdk/src/core/learning_mode_windows/extractors.rs +++ b/src/mxc-sdk/src/core/learning_mode_windows/extractors.rs @@ -70,8 +70,9 @@ pub(crate) const PRIVACY_LEARNING_MODE_PROVIDER: GUID = GUID { data4: [0xad, 0xc0, 0x4b, 0x18, 0x61, 0x70, 0xe7, 0x60], }; -pub(crate) const NETWORK_DECISION_PROVIDER: GUID = - GUID::from_u128(0x71237669_21c3_4101_bd2f_ff38945d725a); +use super::network_extractors::is_network_decision_provider; +#[cfg(test)] +pub(crate) use super::network_extractors::NETWORK_DECISION_PROVIDER; pub(crate) const NETWORK_DECISION_EVENT_ID: u16 = 1; pub(crate) const ACCESS_CHECK_EVENT_ID: u16 = 14; @@ -166,7 +167,7 @@ pub fn extract_denial( pub(crate) fn verbose_logging_classification( parts: &DecodedEventParts, ) -> (Option, Option) { - if parts.provider == super::network_extractors::NETWORK_DECISION_PROVIDER { + if is_network_decision_provider(parts.provider) { return super::network_extractors::verbose_logging_classification(parts); } @@ -235,7 +236,7 @@ pub(crate) fn is_learning_mode_event(provider: GUID, event_id: u16) -> bool { | LEARNING_MODE_VIOLATION_EVENT_ID | PRIVACY_ACCESS_CHECK_EVENT_ID ) - } else if provider == NETWORK_DECISION_PROVIDER { + } else if is_network_decision_provider(provider) { event_id == NETWORK_DECISION_EVENT_ID } else { false @@ -243,11 +244,11 @@ pub(crate) fn is_learning_mode_event(provider: GUID, event_id: u16) -> bool { } pub(crate) fn is_process_scoped_event(provider: GUID, event_id: u16) -> bool { - provider != NETWORK_DECISION_PROVIDER && is_learning_mode_event(provider, event_id) + !is_network_decision_provider(provider) && is_learning_mode_event(provider, event_id) } pub(crate) fn effective_event_pid(parts: &DecodedEventParts, header_pid: u32) -> Option { - if parts.provider == NETWORK_DECISION_PROVIDER { + if is_network_decision_provider(parts.provider) { // Public WFP NetEvents carry package/application identity but no // reliable workload PID. PID 0 is the explicit wire sentinel for // unavailable process identity. diff --git a/src/mxc-sdk/src/core/learning_mode_windows/network_extractors.rs b/src/mxc-sdk/src/core/learning_mode_windows/network_extractors.rs index d15ff32da..95d0e89d0 100644 --- a/src/mxc-sdk/src/core/learning_mode_windows/network_extractors.rs +++ b/src/mxc-sdk/src/core/learning_mode_windows/network_extractors.rs @@ -21,8 +21,15 @@ pub(crate) const NETWORK_DECISION_PROVIDER: GUID = GUID { data3: 0x4101, data4: [0xbd, 0x2f, 0xff, 0x38, 0x94, 0x5d, 0x72, 0x5a], }; +/// Manifest provider registered by Microsoft-Windows-LearningMode-NetworkDecision. +pub(crate) const MANIFEST_NETWORK_DECISION_PROVIDER: GUID = + GUID::from_u128(0x301ec03d_2951_5efb_6d99_59c64628bbfc); pub(crate) const NETWORK_DECISION_EVENT_ID: u16 = 1; +pub(crate) fn is_network_decision_provider(provider: GUID) -> bool { + provider == NETWORK_DECISION_PROVIDER || provider == MANIFEST_NETWORK_DECISION_PROVIDER +} + const SCHEMA_VERSION_V1: u16 = 1; const SOURCE_APP_ISOLATION: u8 = 1; const SOURCE_TESSERA: u8 = 2; @@ -106,7 +113,8 @@ pub(crate) fn analyze_network_decision(parts: &DecodedEventParts) -> NetworkDeci fn analyze_network_decision_inner( parts: &DecodedEventParts, ) -> Result { - if parts.provider != NETWORK_DECISION_PROVIDER || parts.event_id != NETWORK_DECISION_EVENT_ID { + if !is_network_decision_provider(parts.provider) || parts.event_id != NETWORK_DECISION_EVENT_ID + { return Err(CaptureVerboseLoggingOutcomeReason::UnsupportedEventSchema); } if !NETWORK_DECISION_V1_FIELDS From b7efba619c2b4a16424d9ffa66b007170f4799e9 Mon Sep 17 00:00:00 2001 From: "Richie Gomez (he/him)" Date: Thu, 15 Oct 2026 13:13:23 -0700 Subject: [PATCH 2/2] Use only the current network decision provider GUID Replace obsolete GUID values in routing, extraction, output, existing fixtures and documentation. Remove the compatibility implementation so the PR contains only GUID-value replacements. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 16300264-31dd-4214-a056-f01395e3179e --- docs/logging-access-denied.md | 4 +- .../common/capture_output.rs | 2 +- .../learning_mode_core/capture_diagnostics.rs | 4 +- .../core/learning_mode_windows/etl_decode.rs | 90 +++---------------- .../core/learning_mode_windows/extractors.rs | 13 ++- .../network_extractors.rs | 18 ++-- .../src/core/mxc_engine/verbose_telemetry.rs | 4 +- 7 files changed, 27 insertions(+), 108 deletions(-) diff --git a/docs/logging-access-denied.md b/docs/logging-access-denied.md index b4baf88c7..b70017139 100644 --- a/docs/logging-access-denied.md +++ b/docs/logging-access-denied.md @@ -238,9 +238,7 @@ sandbox policy: Feature-enabled Windows builds can add WFP decisions to the managed Learning Mode ETL through the manifested `Microsoft-Windows-LearningMode-NetworkDecision` provider -(`{301EC03D-2951-5EFB-6D99-59C64628BBFC}`). MXC also recognizes the earlier -provider identity `{71237669-21C3-4101-BD2F-FF38945D725A}` and retains the -observed GUID in verbose signatures. MXC accepts event ID `1`, +(`{301EC03D-2951-5EFB-6D99-59C64628BBFC}`). MXC accepts event ID `1`, `NetworkDecisionV1`, with schema version `1`. The OS Learning Mode broker owns the WFP subscription, runtime-filter lookup, subject scoping, event normalization, queue draining, and ETW flush before the trace is sealed. diff --git a/src/mxc-sdk/src/backends/process_container/common/capture_output.rs b/src/mxc-sdk/src/backends/process_container/common/capture_output.rs index f12e1df23..bba1e55fa 100644 --- a/src/mxc-sdk/src/backends/process_container/common/capture_output.rs +++ b/src/mxc-sdk/src/backends/process_container/common/capture_output.rs @@ -372,7 +372,7 @@ mod tests { network_verbose_logging.record_with_byte_budget( CaptureVerboseLoggingSignature { provider: CaptureVerboseLoggingProvider::LearningModeNetworkDecision, - provider_guid: "{71237669-21C3-4101-BD2F-FF38945D725A}".to_string(), + provider_guid: "{301EC03D-2951-5EFB-6D99-59C64628BBFC}".to_string(), event_id: 1, event_name: Some("NetworkDecisionV1".to_string()), reason: CaptureVerboseLoggingOutcomeReason::Actionable, diff --git a/src/mxc-sdk/src/core/learning_mode_core/capture_diagnostics.rs b/src/mxc-sdk/src/core/learning_mode_core/capture_diagnostics.rs index e907679f6..3a2de1882 100644 --- a/src/mxc-sdk/src/core/learning_mode_core/capture_diagnostics.rs +++ b/src/mxc-sdk/src/core/learning_mode_core/capture_diagnostics.rs @@ -838,7 +838,7 @@ mod tests { ) -> CaptureVerboseLoggingSignature { CaptureVerboseLoggingSignature { provider: CaptureVerboseLoggingProvider::LearningModeNetworkDecision, - provider_guid: "{71237669-21C3-4101-BD2F-FF38945D725A}".to_string(), + provider_guid: "{301EC03D-2951-5EFB-6D99-59C64628BBFC}".to_string(), event_id: 1, event_name: Some("NetworkDecisionV1".to_string()), reason, @@ -982,7 +982,7 @@ mod tests { "signatures": [{ "signature": { "provider": "learningModeNetworkDecision", - "providerGuid": "{71237669-21C3-4101-BD2F-FF38945D725A}", + "providerGuid": "{301EC03D-2951-5EFB-6D99-59C64628BBFC}", "eventId": 1, "eventName": "NetworkDecisionV1", "reason": "schemaUnavailable", diff --git a/src/mxc-sdk/src/core/learning_mode_windows/etl_decode.rs b/src/mxc-sdk/src/core/learning_mode_windows/etl_decode.rs index e6c7aa34a..62b552278 100644 --- a/src/mxc-sdk/src/core/learning_mode_windows/etl_decode.rs +++ b/src/mxc-sdk/src/core/learning_mode_windows/etl_decode.rs @@ -473,7 +473,6 @@ impl<'visitor> Accumulator<'visitor> { fn record_network_outcome( &mut self, - provider: windows::core::GUID, event_id: u16, event_name: Option, analysis: &crate::learning_mode_windows::network_extractors::NetworkDecisionAnalysis, @@ -481,9 +480,7 @@ impl<'visitor> Accumulator<'visitor> { let (access_type, resource_type) = analysis.classification; self.record_capture_signature(CaptureVerboseLoggingSignature { provider: CaptureVerboseLoggingProvider::LearningModeNetworkDecision, - provider_guid: crate::learning_mode_windows::extractors::format_guid_braced_uppercase( - provider, - ), + provider_guid: "{301EC03D-2951-5EFB-6D99-59C64628BBFC}".to_string(), event_id, event_name, reason: analysis.reason, @@ -581,8 +578,7 @@ impl<'visitor> Accumulator<'visitor> { if error.event_kind().is_none() && is_process_scoped_event(provider, event_id) { self.truncated = true; } - if crate::learning_mode_windows::network_extractors::is_network_decision_provider(provider) - { + if provider == crate::learning_mode_windows::network_extractors::NETWORK_DECISION_PROVIDER { let reason = match error.event_kind() { Some(tdh_decode::EventDecodeKind::PayloadMalformed) => { CaptureVerboseLoggingOutcomeReason::EventPayloadMalformed @@ -607,7 +603,6 @@ impl<'visitor> Accumulator<'visitor> { }) .map(|(_, value)| value); self.record_network_outcome( - provider, event_id, event_name, &crate::learning_mode_windows::network_extractors::NetworkDecisionAnalysis { @@ -1104,9 +1099,7 @@ unsafe fn process_event_record(event_record: *mut EVENT_RECORD, acc: &mut Accumu let category = crate::learning_mode_windows::extractors::verbose_logging_provider_for_guid(provider); let is_network = - crate::learning_mode_windows::network_extractors::is_network_decision_provider( - provider, - ); + provider == crate::learning_mode_windows::network_extractors::NETWORK_DECISION_PROVIDER; if category.is_none() && !is_network { // Unrelated provider: unrelated host traffic, ignored entirely // (not aggregated as an excluded Learning Mode outcome). @@ -1134,7 +1127,6 @@ unsafe fn process_event_record(event_record: *mut EVENT_RECORD, acc: &mut Accumu // paying for a TDH decode. if is_network { acc.record_network_outcome( - provider, event_id, None, &crate::learning_mode_windows::network_extractors::NetworkDecisionAnalysis { @@ -1308,9 +1300,8 @@ fn handle_decoded_event( filetime: u64, acc: &mut Accumulator<'_>, ) { - if crate::learning_mode_windows::network_extractors::is_network_decision_provider( - parts.provider, - ) { + if parts.provider == crate::learning_mode_windows::network_extractors::NETWORK_DECISION_PROVIDER + { if !acc.event_in_scope(0, filetime) || !acc.begin_event() { return; } @@ -1318,7 +1309,6 @@ fn handle_decoded_event( crate::learning_mode_windows::network_extractors::analyze_network_decision(parts); let denial = analysis.denial.clone(); acc.record_network_outcome( - parts.provider, parts.event_id, (parts.event_id == crate::learning_mode_windows::network_extractors::NETWORK_DECISION_EVENT_ID) @@ -1427,7 +1417,7 @@ mod tests { #[test] fn network_decision_is_retained_only_in_unscoped_native_analysis() { - let provider = windows::core::GUID::from_u128(0x71237669_21c3_4101_bd2f_ff38945d725a); + let provider = windows::core::GUID::from_u128(0x301ec03d_2951_5efb_6d99_59c64628bbfc); assert!(is_learning_mode_event(provider, 1)); for event_id in [0, 2, 14, 28] { assert!(!is_learning_mode_event(provider, event_id)); @@ -1458,7 +1448,7 @@ mod tests { ); assert_eq!( signature.provider_guid, - "{71237669-21C3-4101-BD2F-FF38945D725A}" + "{301EC03D-2951-5EFB-6D99-59C64628BBFC}" ); assert_eq!(signature.pid, 0); assert_eq!( @@ -1519,7 +1509,7 @@ mod tests { fn network_decode_failure_does_not_attribute_the_broker_pid() { let mut accumulator = Accumulator::analyze(); accumulator.record_event_decode_error( - windows::core::GUID::from_u128(0x71237669_21c3_4101_bd2f_ff38945d725a), + windows::core::GUID::from_u128(0x301ec03d_2951_5efb_6d99_59c64628bbfc), 1, SCOPED_PID, tdh_decode::DecodeError::event( @@ -2699,55 +2689,6 @@ mod tests { ) } - #[test] - fn manifest_network_provider_is_actionable_and_preserves_observed_guid() { - use crate::learning_mode_windows::network_extractors::{ - MANIFEST_NETWORK_DECISION_PROVIDER, NETWORK_DECISION_PROVIDER, - }; - - for provider in [ - NETWORK_DECISION_PROVIDER, - MANIFEST_NETWORK_DECISION_PROVIDER, - ] { - let mut event = network_event( - 777, - 600, - &[ - ("SourceDomain", "2"), - ("Reason", "100"), - ("FieldFlags", "63"), - ("ProviderGuid", "{2F8C6D14-3B7E-4A59-9C08-1D4E7A6B2F30}"), - ("SublayerGuid", "{7B1E9A2C-9D4F-4C8A-B321-5E6D2F8A1C44}"), - ("ApplicationId", r"\Device\HarddiskVolume3\app.exe"), - ("Protocol", "6"), - ("LocalAddress", "192.0.2.1"), - ("LocalPort", "49152"), - ("RemoteAddress", "203.0.113.10"), - ("RemotePort", "443"), - ("IsLoopback", "false"), - ], - ); - event.parts.provider = provider; - assert!(is_learning_mode_event(provider, 1)); - assert!(!is_process_scoped_event(provider, 1)); - assert_eq!( - crate::learning_mode_windows::extractors::effective_event_pid(&event.parts, 777), - Some(0), - ); - let mut accumulator = Accumulator::analyze(); - handle_decoded_event(&event.parts, 777, 600, &mut accumulator); - assert_eq!(accumulator.denials.len(), 1); - assert_eq!(accumulator.denials[0].resource, "tcp://203.0.113.10:443"); - let signature = &accumulator.network_verbose_logging.signatures[0].signature; - assert_eq!( - signature.provider_guid, - crate::learning_mode_windows::extractors::format_guid_braced_uppercase(provider), - ); - assert!(signature.reason.is_actionable()); - assert_eq!(signature.pid, 0); - } - } - #[test] #[ignore = "manual benchmark: run with --release --ignored --nocapture"] fn benchmark_high_cardinality_network_capture() { @@ -4016,12 +3957,7 @@ mod tests { classification: (None, None), properties: vec![("Large".to_string(), "x".repeat(remaining_bytes))], }; - accumulator.record_network_outcome( - crate::learning_mode_windows::network_extractors::NETWORK_DECISION_PROVIDER, - 1, - Some("NetworkDecisionV1".to_string()), - &analysis, - ); + accumulator.record_network_outcome(1, Some("NetworkDecisionV1".to_string()), &analysis); assert_eq!(accumulator.network_verbose_logging.overflow_occurrences, 1); assert!(!accumulator.network_verbose_logging_actionable_only_saturated); @@ -4030,12 +3966,7 @@ mod tests { properties: Vec::new(), ..analysis }; - accumulator.record_network_outcome( - crate::learning_mode_windows::network_extractors::NETWORK_DECISION_PROVIDER, - 2, - None, - &analysis, - ); + accumulator.record_network_outcome(2, None, &analysis); assert_eq!(accumulator.network_verbose_logging.signatures.len(), 1); assert_eq!(accumulator.network_verbose_logging.overflow_occurrences, 1); @@ -4297,7 +4228,6 @@ mod tests { fn network_diagnostics_preserve_observed_event_identity() { let mut unsupported = Accumulator::analyze(); unsupported.record_network_outcome( - crate::learning_mode_windows::network_extractors::NETWORK_DECISION_PROVIDER, 999, None, &crate::learning_mode_windows::network_extractors::NetworkDecisionAnalysis { diff --git a/src/mxc-sdk/src/core/learning_mode_windows/extractors.rs b/src/mxc-sdk/src/core/learning_mode_windows/extractors.rs index 1ee4d6c23..8e4f3aaea 100644 --- a/src/mxc-sdk/src/core/learning_mode_windows/extractors.rs +++ b/src/mxc-sdk/src/core/learning_mode_windows/extractors.rs @@ -70,9 +70,8 @@ pub(crate) const PRIVACY_LEARNING_MODE_PROVIDER: GUID = GUID { data4: [0xad, 0xc0, 0x4b, 0x18, 0x61, 0x70, 0xe7, 0x60], }; -use super::network_extractors::is_network_decision_provider; -#[cfg(test)] -pub(crate) use super::network_extractors::NETWORK_DECISION_PROVIDER; +pub(crate) const NETWORK_DECISION_PROVIDER: GUID = + GUID::from_u128(0x301ec03d_2951_5efb_6d99_59c64628bbfc); pub(crate) const NETWORK_DECISION_EVENT_ID: u16 = 1; pub(crate) const ACCESS_CHECK_EVENT_ID: u16 = 14; @@ -167,7 +166,7 @@ pub fn extract_denial( pub(crate) fn verbose_logging_classification( parts: &DecodedEventParts, ) -> (Option, Option) { - if is_network_decision_provider(parts.provider) { + if parts.provider == super::network_extractors::NETWORK_DECISION_PROVIDER { return super::network_extractors::verbose_logging_classification(parts); } @@ -236,7 +235,7 @@ pub(crate) fn is_learning_mode_event(provider: GUID, event_id: u16) -> bool { | LEARNING_MODE_VIOLATION_EVENT_ID | PRIVACY_ACCESS_CHECK_EVENT_ID ) - } else if is_network_decision_provider(provider) { + } else if provider == NETWORK_DECISION_PROVIDER { event_id == NETWORK_DECISION_EVENT_ID } else { false @@ -244,11 +243,11 @@ pub(crate) fn is_learning_mode_event(provider: GUID, event_id: u16) -> bool { } pub(crate) fn is_process_scoped_event(provider: GUID, event_id: u16) -> bool { - !is_network_decision_provider(provider) && is_learning_mode_event(provider, event_id) + provider != NETWORK_DECISION_PROVIDER && is_learning_mode_event(provider, event_id) } pub(crate) fn effective_event_pid(parts: &DecodedEventParts, header_pid: u32) -> Option { - if is_network_decision_provider(parts.provider) { + if parts.provider == NETWORK_DECISION_PROVIDER { // Public WFP NetEvents carry package/application identity but no // reliable workload PID. PID 0 is the explicit wire sentinel for // unavailable process identity. diff --git a/src/mxc-sdk/src/core/learning_mode_windows/network_extractors.rs b/src/mxc-sdk/src/core/learning_mode_windows/network_extractors.rs index 95d0e89d0..9bb3709e9 100644 --- a/src/mxc-sdk/src/core/learning_mode_windows/network_extractors.rs +++ b/src/mxc-sdk/src/core/learning_mode_windows/network_extractors.rs @@ -16,20 +16,13 @@ use windows::core::GUID; use super::extractors::{sanitize_properties, DecodedEventParts, RawDenial}; pub(crate) const NETWORK_DECISION_PROVIDER: GUID = GUID { - data1: 0x7123_7669, - data2: 0x21c3, - data3: 0x4101, - data4: [0xbd, 0x2f, 0xff, 0x38, 0x94, 0x5d, 0x72, 0x5a], + data1: 0x301e_c03d, + data2: 0x2951, + data3: 0x5efb, + data4: [0x6d, 0x99, 0x59, 0xc6, 0x46, 0x28, 0xbb, 0xfc], }; -/// Manifest provider registered by Microsoft-Windows-LearningMode-NetworkDecision. -pub(crate) const MANIFEST_NETWORK_DECISION_PROVIDER: GUID = - GUID::from_u128(0x301ec03d_2951_5efb_6d99_59c64628bbfc); pub(crate) const NETWORK_DECISION_EVENT_ID: u16 = 1; -pub(crate) fn is_network_decision_provider(provider: GUID) -> bool { - provider == NETWORK_DECISION_PROVIDER || provider == MANIFEST_NETWORK_DECISION_PROVIDER -} - const SCHEMA_VERSION_V1: u16 = 1; const SOURCE_APP_ISOLATION: u8 = 1; const SOURCE_TESSERA: u8 = 2; @@ -113,8 +106,7 @@ pub(crate) fn analyze_network_decision(parts: &DecodedEventParts) -> NetworkDeci fn analyze_network_decision_inner( parts: &DecodedEventParts, ) -> Result { - if !is_network_decision_provider(parts.provider) || parts.event_id != NETWORK_DECISION_EVENT_ID - { + if parts.provider != NETWORK_DECISION_PROVIDER || parts.event_id != NETWORK_DECISION_EVENT_ID { return Err(CaptureVerboseLoggingOutcomeReason::UnsupportedEventSchema); } if !NETWORK_DECISION_V1_FIELDS diff --git a/src/mxc-sdk/src/core/mxc_engine/verbose_telemetry.rs b/src/mxc-sdk/src/core/mxc_engine/verbose_telemetry.rs index f20bfcf61..246dda63b 100644 --- a/src/mxc-sdk/src/core/mxc_engine/verbose_telemetry.rs +++ b/src/mxc-sdk/src/core/mxc_engine/verbose_telemetry.rs @@ -177,7 +177,7 @@ fn canonical_provider_guid(provider: CaptureVerboseLoggingProvider) -> &'static "{811A1DDB-2E69-5F25-ADC0-4B186170E760}" } CaptureVerboseLoggingProvider::LearningModeNetworkDecision => { - "{71237669-21C3-4101-BD2F-FF38945D725A}" + "{301EC03D-2951-5EFB-6D99-59C64628BBFC}" } } } @@ -475,7 +475,7 @@ mod tests { fn network_provider_uses_the_canonical_guid() { assert_eq!( canonical_provider_guid(CaptureVerboseLoggingProvider::LearningModeNetworkDecision), - "{71237669-21C3-4101-BD2F-FF38945D725A}" + "{301EC03D-2951-5EFB-6D99-59C64628BBFC}" ); } }