From 6abb879776c577fd5ef18d84347a675fcecdffb2 Mon Sep 17 00:00:00 2001 From: mjeong92 <38798976+mjeong92@users.noreply.github.com> Date: Wed, 2 May 2018 14:36:58 -0700 Subject: [PATCH] Add filtering by primitive types (#45) * Add filtering by primitive types Add filtering by Boolean, Int16, Int32, and Int64. * Remove boolean filter and add unit tests * Fix test errors and add unsigned types * Remove all filters except UInt32 --- O365.Security.Native.ETW/Filtering/Fluent.hpp | 13 +++++++ tests/ManagedETWTests/EtwTestsCS.csproj | 2 + tests/ManagedETWTests/Events/LogonEvent.cs | 31 +++++++++++++++ .../Filtering/describe_Fluent.cs | 39 +++++++++++++++++++ 4 files changed, 85 insertions(+) create mode 100644 tests/ManagedETWTests/Events/LogonEvent.cs create mode 100644 tests/ManagedETWTests/Filtering/describe_Fluent.cs diff --git a/O365.Security.Native.ETW/Filtering/Fluent.hpp b/O365.Security.Native.ETW/Filtering/Fluent.hpp index 325d02f..00ff590 100644 --- a/O365.Security.Native.ETW/Filtering/Fluent.hpp +++ b/O365.Security.Native.ETW/Filtering/Fluent.hpp @@ -90,5 +90,18 @@ namespace O365 { namespace Security { namespace ETW { { return Predicate::make_predicate(processId); } + + /// + /// Used to verify that an event was emitted with a specific UInt32 property. + /// + /// the name of the property to match on + /// the value of the property to match on + /// a predicate that matches events of the specified UInt32 property + static Predicate ^IsUInt32(String ^propertyName, UInt32 value) + { + return gcnew Predicate(krabs::predicates::property_is( + msclr::interop::marshal_as(propertyName), + value)); + } }; } } } diff --git a/tests/ManagedETWTests/EtwTestsCS.csproj b/tests/ManagedETWTests/EtwTestsCS.csproj index b619402..65b4be6 100644 --- a/tests/ManagedETWTests/EtwTestsCS.csproj +++ b/tests/ManagedETWTests/EtwTestsCS.csproj @@ -75,7 +75,9 @@ + + diff --git a/tests/ManagedETWTests/Events/LogonEvent.cs b/tests/ManagedETWTests/Events/LogonEvent.cs new file mode 100644 index 0000000..5660a60 --- /dev/null +++ b/tests/ManagedETWTests/Events/LogonEvent.cs @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using O365.Security.ETW.Testing; + +namespace EtwTestsCS.Events +{ + public static class LogonEvent + { + public readonly static string TargetUserName = "TargetUserName"; + public readonly static string LogonType = "LogonType"; + + public readonly static Guid ProviderId = Guid.Parse("199FE037-2B82-40A9-82AC-E1D46C792B99"); + public readonly static int EventId = 301; + public readonly static int Version = 0; + + public static SynthRecord CreateRecord( + string username, + uint logonType) + { + using (var rb = new RecordBuilder(ProviderId, EventId, Version)) + { + rb.AddUnicodeString(TargetUserName, username); + rb.AddValue(LogonType, logonType); + + return rb.PackIncomplete(); + } + } + } +} diff --git a/tests/ManagedETWTests/Filtering/describe_Fluent.cs b/tests/ManagedETWTests/Filtering/describe_Fluent.cs new file mode 100644 index 0000000..3e40cd1 --- /dev/null +++ b/tests/ManagedETWTests/Filtering/describe_Fluent.cs @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using O365.Security.ETW; + +namespace EtwTestsCS.Filtering +{ + using Events; + + [TestClass] + public class describe_Fluent + { + // IsUInt32 + [TestMethod] + public void when_int32_values_are_same_is_should_match() + { + UInt32 data = 5; + var query = data; + var record = LogonEvent.CreateRecord(String.Empty, data); + var predicate = Filter.IsUInt32(LogonEvent.LogonType, query); + + Assert.IsTrue(predicate.Test(record)); + } + + [TestMethod] + public void when_int32_values_are_not_same_is_should_not_match() + { + UInt32 data = 0; + UInt32 query = 1; + var record = LogonEvent.CreateRecord(String.Empty, data); + var predicate = Filter.IsUInt32(LogonEvent.LogonType, query); + + Assert.IsFalse(predicate.Test(record)); + } + } +}