Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code refactor, performance improvements, internalizing types in AppControl Manager #632

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions AppControl Manager/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ public App()
// to handle unhandled exceptions
this.UnhandledException += App_UnhandledException;

// Subscribe to FirstChanceException events
// AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;

// Subscribe to UnobservedTaskException events
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;

Logger.Write($"App Startup, .NET runtime version: {Environment.Version}");

// Give beautiful outline to the UI elements when using the tab key and keyboard for navigation
Expand Down Expand Up @@ -106,6 +112,43 @@ private void OnSoundSettingChanged(object? sender, SoundSettingChangedEventArgs
}


/*

/// <summary>
/// Event handler for FirstChanceException events.
/// This event is raised as soon as an exception is thrown, before any catch blocks are executed.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void CurrentDomain_FirstChanceException(object? sender, FirstChanceExceptionEventArgs e)
{
// Log the first chance exception details.
// Note: FirstChanceExceptions are raised for all exceptions, even if they are handled later.
Logger.Write($"FirstChanceException caught: {e.Exception.Message}");
}

*/


/// <summary>
/// Event handler for UnobservedTaskException events.
/// This event is raised when a faulted Task's exception is not observed.
/// UnobservedTaskException doesn't help for exceptions thrown in event handlers.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void TaskScheduler_UnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e)
{
// Log the unobserved task exception details.
Logger.Write($"UnobservedTaskException caught: {e.Exception.Message}");

// Mark the exception as observed to prevent the process from terminating.
e.SetObserved();

await ShowErrorDialogAsync(e.Exception);
}


/// <summary>
/// Invoked when the application is launched.
/// </summary>
Expand Down
32 changes: 22 additions & 10 deletions AppControl Manager/AppControl Manager.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,17 @@

<!-- There should be absolutely no trim warnings before this can be enabled
Otherwise there is no guarantee that the app will work as expected at all times -->
<!-- https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/trimming-options -->
<!-- https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/trimming-options -->
<PublishTrimmed>True</PublishTrimmed>
<TrimMode>full</TrimMode>
<EnableTrimAnalyzer>true</EnableTrimAnalyzer>
<SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>
<ILLinkTreatWarningsAsErrors>true</ILLinkTreatWarningsAsErrors>
<TrimmerSingleWarn>false</TrimmerSingleWarn>
<TrimmerRemoveSymbols>true</TrimmerRemoveSymbols>
<!-- WASDK isn't a .NET libary so it can't use these features and cannot be affected
We won't get warnings for these in compile time if a code or library relies on them.
We can get NotSupportedException exception during runtime instead. -->
<EnableUnsafeUTF7Encoding>false</EnableUnsafeUTF7Encoding>
<EnableUnsafeBinaryFormatterSerialization>false</EnableUnsafeBinaryFormatterSerialization>
<XmlResolverIsNetworkingEnabledByDefault>false</XmlResolverIsNetworkingEnabledByDefault>
Expand All @@ -137,35 +140,44 @@
https://devblogs.microsoft.com/nuget/introducing-transitive-dependencies-in-visual-studio/
-->
<ItemGroup>
<PackageReference Include="CommunityToolkit.Common" Version="8.4.0" />

<!-- Main Packages - Without these packages, there will be compilaton errors related to missing types -->
<PackageReference Include="CommunityToolkit.WinUI.Animations" Version="8.2.250129-preview2" />
<PackageReference Include="CommunityToolkit.WinUI.Controls.Primitives" Version="8.2.250129-preview2" />
<PackageReference Include="CommunityToolkit.WinUI.Controls.RadialGauge" Version="8.2.250129-preview2" />
<PackageReference Include="CommunityToolkit.WinUI.Controls.Segmented" Version="8.2.250129-preview2" />
<PackageReference Include="CommunityToolkit.WinUI.Controls.SettingsControls" Version="8.2.250129-preview2" />
<PackageReference Include="CommunityToolkit.WinUI.Controls.Sizers" Version="8.2.250129-preview2" />
<PackageReference Include="CommunityToolkit.WinUI.Extensions" Version="8.2.250129-preview2" />
<PackageReference Include="CommunityToolkit.WinUI.Helpers" Version="8.2.250129-preview2" />
<PackageReference Include="CommunityToolkit.WinUI.Lottie" Version="8.1.240821" />
<PackageReference Include="CommunityToolkit.WinUI.Triggers" Version="8.2.250129-preview2" />
<PackageReference Include="Microsoft.Graphics.Win2D" Version="1.3.2" />
<PackageReference Include="Microsoft.Identity.Client" Version="4.68.0" />
<PackageReference Include="Microsoft.IdentityModel.Abstractions" Version="8.6.0" />
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3065.39" />
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.183">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Windows.CsWinRT" Version="2.2.0" />
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.6.250205002" />
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="9.0.2" />
<PackageReference Include="System.Diagnostics.EventLog" Version="9.0.2" />
<PackageReference Include="CommunityToolkit.WinUI.Behaviors" Version="8.2.250129-preview2" />

<!-- Transitive Packages - Without these packages, there will not be compilation error related to missing types -->
<PackageReference Include="CommunityToolkit.WinUI.Extensions" Version="8.2.250129-preview2" />
<PackageReference Include="CommunityToolkit.WinUI.Helpers" Version="8.2.250129-preview2" />
<PackageReference Include="CommunityToolkit.Common" Version="8.4.0" />
<PackageReference Include="Microsoft.IdentityModel.Abstractions" Version="8.6.0" />
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3065.39" />
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.1742" />
<PackageReference Include="Microsoft.Windows.SDK.Win32Docs" Version="0.1.42-alpha" />
<PackageReference Include="Microsoft.Windows.SDK.Win32Metadata" Version="63.0.31-preview" />
<PackageReference Include="Microsoft.Windows.WDK.Win32Metadata" Version="0.13.25-experimental" />
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.6.250205002" />
<PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="3.0.0" />
<PackageReference Include="CommunityToolkit.WinUI.Behaviors" Version="8.2.250129-preview2" />
<PackageReference Include="System.Diagnostics.EventLog" Version="9.0.2" />
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="9.0.2" />
<PackageReference Include="runtime.win-arm64.Microsoft.DotNet.ILCompiler" Version="9.0.2" />
<PackageReference Include="runtime.win-x64.Microsoft.DotNet.ILCompiler" Version="9.0.2" />
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="6.0.1" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.1.0" />

</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,6 @@ internal CustomPatternBasedFilePath()

internal sealed class FilePathPatternExample
{
public string? Example;
public string? Description;
internal string? Example;
internal string? Description;
}
2 changes: 1 addition & 1 deletion AppControl Manager/IntelGathering/EventAction.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace AppControlManager.IntelGathering;

public enum EventAction
internal enum EventAction
{
Audit,
Block
Expand Down
78 changes: 39 additions & 39 deletions AppControl Manager/IntelGathering/FileIdentity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,71 +4,71 @@

namespace AppControlManager.IntelGathering;

public sealed class FileIdentity
internal sealed class FileIdentity
{
// The origin of this File Identity object, where it came from and how it was compiled
public FileIdentityOrigin Origin { get; set; }
internal FileIdentityOrigin Origin { get; set; }

// Whether the file is signed or unsigned
public SignatureStatus SignatureStatus { get; set; }
internal SignatureStatus SignatureStatus { get; set; }

// Properties related to logs
public EventAction Action { get; set; }
public int EventID { get; set; }
public DateTime? TimeCreated { get; set; }
public string? ComputerName { get; set; }
public Guid? PolicyGUID { get; set; }
public bool? UserWriteable { get; set; }
public string? ProcessName { get; set; }
public string? RequestedSigningLevel { get; set; }
public string? ValidatedSigningLevel { get; set; }
public string? Status { get; set; }
public long? USN { get; set; }
public string? PolicyName { get; set; }
public string? PolicyID { get; set; }
public string? PolicyHash { get; set; }
public string? UserID { get; set; }
internal EventAction Action { get; set; }
internal int EventID { get; set; }
internal DateTime? TimeCreated { get; set; }
internal string? ComputerName { get; set; }
internal Guid? PolicyGUID { get; set; }
internal bool? UserWriteable { get; set; }
internal string? ProcessName { get; set; }
internal string? RequestedSigningLevel { get; set; }
internal string? ValidatedSigningLevel { get; set; }
internal string? Status { get; set; }
internal long? USN { get; set; }
internal string? PolicyName { get; set; }
internal string? PolicyID { get; set; }
internal string? PolicyHash { get; set; }
internal string? UserID { get; set; }


// Properties applicable to files in general
public string? FilePath { get; set; }
public string? FileName { get; set; }
public string? SHA1Hash { get; set; } // SHA1 Authenticode Hash with fallback to Flat hash for incompatible files
public string? SHA256Hash { get; set; } // SHA256 Authenticode Hash with fallback to Flat hash for incompatible files
public string? SHA1PageHash { get; set; } // 1st Page hash - Local file scanning provides this
public string? SHA256PageHash { get; set; } // 1st Page hash - Local file scanning provides this
public string? SHA1FlatHash { get; set; } // Flat file hashes - Event logs provide this
public string? SHA256FlatHash { get; set; } // Flat file hashes - Event logs provide this
public int SISigningScenario { get; set; } // 1 for user mode files - 0 for kernel mode files
public string? OriginalFileName { get; set; }
public string? InternalName { get; set; }
public string? FileDescription { get; set; }
public string? ProductName { get; set; }
public Version? FileVersion { get; set; }
public string? PackageFamilyName { get; set; }
internal string? FilePath { get; set; }
internal string? FileName { get; set; }
internal string? SHA1Hash { get; set; } // SHA1 Authenticode Hash with fallback to Flat hash for incompatible files
internal string? SHA256Hash { get; set; } // SHA256 Authenticode Hash with fallback to Flat hash for incompatible files
internal string? SHA1PageHash { get; set; } // 1st Page hash - Local file scanning provides this
internal string? SHA256PageHash { get; set; } // 1st Page hash - Local file scanning provides this
internal string? SHA1FlatHash { get; set; } // Flat file hashes - Event logs provide this
internal string? SHA256FlatHash { get; set; } // Flat file hashes - Event logs provide this
internal int SISigningScenario { get; set; } // 1 for user mode files - 0 for kernel mode files
internal string? OriginalFileName { get; set; }
internal string? InternalName { get; set; }
internal string? FileDescription { get; set; }
internal string? ProductName { get; set; }
internal Version? FileVersion { get; set; }
internal string? PackageFamilyName { get; set; }

// Signer and certificate information with a custom comparer to ensure data with the same PublisherTBSHash and IssuerTBSHash do not exist
public HashSet<FileSignerInfo> FileSignerInfos { get; set; } = new HashSet<FileSignerInfo>(new FileSignerInfoComparer());
internal HashSet<FileSignerInfo> FileSignerInfos { get; set; } = new HashSet<FileSignerInfo>(new FileSignerInfoComparer());


// Just for display purposes, only contains CNs of the signers
// FileSignerInfos is the one that has actual signing data.
public HashSet<string> FilePublishers { get; set; } = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
internal HashSet<string> FilePublishers { get; set; } = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

// Computed property to join FilePublishers into a comma-separated string
public string FilePublishersToDisplay => string.Join(", ", FilePublishers);
internal string FilePublishersToDisplay => string.Join(", ", FilePublishers);

// If the file has a WHQL signer
public bool? HasWHQLSigner { get; set; }
internal bool? HasWHQLSigner { get; set; }


// Determines whether the file is signed by ECC algorithm or not
// AppControl does not support ECC Signed files yet
public bool? IsECCSigned { get; set; }
internal bool? IsECCSigned { get; set; }


// Computed property to gather all OPUSInfo from FileSignerInfos and save them in a comma-separated string for displaying purposes only
public string Opus => string.Join(", ", FileSignerInfos
internal string Opus => string.Join(", ", FileSignerInfos
.Where(signerInfo => !string.IsNullOrEmpty(signerInfo.OPUSInfo))
.Select(signerInfo => signerInfo.OPUSInfo));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace AppControlManager.IntelGathering;
/// This comparer is used to determine the uniqueness of FileIdentity instances
/// based on specific properties.
/// </summary>
public sealed class FileIdentityComparer : IEqualityComparer<FileIdentity>
internal sealed class FileIdentityComparer : IEqualityComparer<FileIdentity>
{
/// <summary>
/// Determines whether two FileIdentity instances are equal.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,23 @@ namespace AppControlManager.IntelGathering;
/// prioritizing items with IsECCSigned set to true over others when adding items
/// with identical properties, based on the custom equality comparer.
/// </summary>
public sealed class FileIdentityECCBasedHashSet
internal sealed class FileIdentityECCBasedHashSet
{
// A HashSet to store FileIdentity objects with a custom comparer.
private readonly HashSet<FileIdentity> _set;

/// <summary>
/// Initializes a new instance of the FileIdentityECCBasedHashSet class.
/// </summary>
public FileIdentityECCBasedHashSet()
internal FileIdentityECCBasedHashSet()
{
_set = new HashSet<FileIdentity>(new FileIdentityComparer());
}

/// <summary>
/// Expose the internal HashSet so we can access it directly.
/// </summary>
public HashSet<FileIdentity> FileIdentitiesInternal => _set;
internal HashSet<FileIdentity> FileIdentitiesInternal => _set;

/// <summary>
/// Adds a FileIdentity item to the set, replacing an item if it exists and is less preferred.
Expand Down
2 changes: 1 addition & 1 deletion AppControl Manager/IntelGathering/FileIdentityOrigin.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace AppControlManager.IntelGathering;

public enum FileIdentityOrigin
internal enum FileIdentityOrigin
{
EventLog,
MDEAdvancedHunting,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace AppControlManager.IntelGathering;
/// If the existing item is unsigned and the new item is signed: The unsigned item is removed, and the signed item is added to the set.
/// If the existing item is already signed: The new item, signed or unsigned, will simply not be added because they are considered equal according to the FileIdentityComparer.
/// </summary>
public sealed class FileIdentitySignatureBasedHashSet
internal sealed class FileIdentitySignatureBasedHashSet
{
// A HashSet to store FileIdentity objects with a custom comparer.
// This comparer defines equality based on selected properties in that comparer, ignoring SignatureStatus for now.
Expand All @@ -22,15 +22,15 @@ public sealed class FileIdentitySignatureBasedHashSet
/// <summary>
/// Initializes a new instance of the FileIdentitySignatureBasedHashSet class.
/// </summary>
public FileIdentitySignatureBasedHashSet()
internal FileIdentitySignatureBasedHashSet()
{
_set = new HashSet<FileIdentity>(new FileIdentityComparer());
}

/// <summary>
/// Expose the internal HashSet so we can access it directly.
/// </summary>
public HashSet<FileIdentity> FileIdentitiesInternal => _set;
internal HashSet<FileIdentity> FileIdentitiesInternal => _set;

/// <summary>
/// Adds a FileIdentity item to the set.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace AppControlManager.IntelGathering;
/// If the existing item is newer or has the same timestamp, the new item will not be added
/// because they are considered equal or the existing one is preferred.
/// </summary>
public sealed class FileIdentityTimeBasedHashSet
internal sealed class FileIdentityTimeBasedHashSet
{
// A HashSet to store FileIdentity objects with a custom comparer.
// This comparer defines equality based on selected properties in that comparer, ignoring TimeCreated for now.
Expand All @@ -25,15 +25,15 @@ public sealed class FileIdentityTimeBasedHashSet
/// <summary>
/// Initializes a new instance of the FileIdentityTimeBasedHashSet class.
/// </summary>
public FileIdentityTimeBasedHashSet()
internal FileIdentityTimeBasedHashSet()
{
_set = new HashSet<FileIdentity>(new FileIdentityComparer());
}

/// <summary>
/// Expose the internal HashSet so we can access it directly.
/// </summary>
public HashSet<FileIdentity> FileIdentitiesInternal => _set;
internal HashSet<FileIdentity> FileIdentitiesInternal => _set;

/// <summary>
/// Adds a FileIdentity item to the set, replacing an older equivalent item if it exists.
Expand Down
38 changes: 19 additions & 19 deletions AppControl Manager/IntelGathering/FileSignerInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@

namespace AppControlManager.IntelGathering;

public sealed class FileSignerInfo
internal sealed class FileSignerInfo
{
public int? TotalSignatureCount { get; set; }
public int? Signature { get; set; }
public string? Hash { get; set; }
public bool? PageHash { get; set; }
public string? SignatureType { get; set; }
public string? ValidatedSigningLevel { get; set; }
public string? VerificationError { get; set; }
public int? Flags { get; set; }
public DateTime? NotValidBefore { get; set; }
public DateTime? NotValidAfter { get; set; }
public string? PublisherName { get; set; }
public string? IssuerName { get; set; }
public string? PublisherTBSHash { get; set; }
public string? IssuerTBSHash { get; set; }
public string? OPUSInfo { get; set; }
public string? EKUs { get; set; }
public int? KnownRoot { get; set; }
public bool? IsWHQL { get; set; }
internal int? TotalSignatureCount { get; set; }
internal int? Signature { get; set; }
internal string? Hash { get; set; }
internal bool? PageHash { get; set; }
internal string? SignatureType { get; set; }
internal string? ValidatedSigningLevel { get; set; }
internal string? VerificationError { get; set; }
internal int? Flags { get; set; }
internal DateTime? NotValidBefore { get; set; }
internal DateTime? NotValidAfter { get; set; }
internal string? PublisherName { get; set; }
internal string? IssuerName { get; set; }
internal string? PublisherTBSHash { get; set; }
internal string? IssuerTBSHash { get; set; }
internal string? OPUSInfo { get; set; }
internal string? EKUs { get; set; }
internal int? KnownRoot { get; set; }
internal bool? IsWHQL { get; set; }
}
Loading