Walter.IO 2024.11.6.1222

Prefix Reserved
dotnet add package Walter.IO --version 2024.11.6.1222                
NuGet\Install-Package Walter.IO -Version 2024.11.6.1222                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Walter.IO" Version="2024.11.6.1222" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Walter.IO --version 2024.11.6.1222                
#r "nuget: Walter.IO, 2024.11.6.1222"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Walter.IO as a Cake Addin
#addin nuget:?package=Walter.IO&version=2024.11.6.1222

// Install Walter.IO as a Cake Tool
#tool nuget:?package=Walter.IO&version=2024.11.6.1222                

WALTER

Introducing the WALTER Framework: Workable Algorithms for Location-aware Transmission, Encryption Response. Designed for modern developers, WALTER is a groundbreaking suite of NuGet packages crafted for excellence in .NET Standard 2.0, 2.1, Core 3.1, and .NET 6, 7, 8, as well as C++ environments. Emphasizing 100% AoT support and reflection-free operations, this framework is the epitome of performance and stability.

Whether you're tackling networking, encryption, or secure communication, WALTER offers unparalleled efficiency and precision in processing, making it an essential tool for developers who prioritize speed and memory management in their applications.

About the Walter.IO Package

Basically there a 2 main interfaces in the Nuget package

  • IDiskGuard
  • FileInfo extensions

IDiskGuard

The IDiskGuard monitors and alerts if there are any uncontrolled disk activities where data is altered.

Features

  • Real-Time Disk Activity Monitoring: IDiskGuard actively watches specified directories for changes, including file creations, modifications, and deletions.
  • Event-Driven Alerts: Triggers events when unauthorized disk manipulations are detected, allowing for immediate response.
  • Flexible Monitoring: Supports monitoring specific directories with customizable file filters and the option to include subdirectories.
  • Easy Integration: While demonstrated with IDiskGuard is designed for broad applicability across various types of applications.

Getting Started

The bellow sample show you one of many ways that you can integrate and configure IDiskGuard.


using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.IO;
using Walter.BOM;
using Walter.IO;

namespace YourNamespace
{
    public static class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddHostedService<DiskMonitorService>();
                    services.AddSecureDiskMonitor();
                });
    }

    public class DiskMonitorService : BackgroundService
    {
        private readonly IDiskGuard _diskGuard;

        public DiskMonitorService(IDiskGuard diskGuard)
        {
            _diskGuard = diskGuard;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            var monitoredDirectory = @"path\to\monitored\directory";

            // Start monitoring the directory
            _diskGuard.StartMonitoring(new DirectoryInfo(monitoredDirectory), "*.*", true);
            _diskGuard.OnDiskManipulation += DiskGuard_OnDiskManipulation;

            stoppingToken.Register(() => 
            {
                // Cleanup code when the service is stopping
                _diskGuard.StopMonitoring(new DirectoryInfo(monitoredDirectory), "*.*");
            });

            while (!stoppingToken.IsCancellationRequested)
            {
                // The service will keep running, monitoring disk activities.
                // Implement any additional periodic checks or maintenance tasks here.

                await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
            }
        }

        private void DiskGuard_OnDiskManipulation(object sender, DiskManipulationEventArgs e)
        {
            // Example padding check for manipulated files
            var fileInfo = new FileInfo(e.Violation.Path);
            if (fileInfo.Exists && fileInfo.CountPaddingBytesChunked() > 0)
            {
                // Handle detection of significant padding in the manipulated file
                Console.WriteLine($"Unauthorized manipulation with padding detected on file: {e.Violation.Path}");
            }
            // Implement additional handling logic for detected disk manipulations
        }
    }
}

Key Components:

  • Program: Sets up the host builder and configures services, registering DiskMonitorService as a hosted service and adding IDiskGuard to the DI container.
  • DiskMonitorService: A background service that starts disk monitoring on application start and keeps running until the application shuts down. It listens for IDiskGuard's OnDiskManipulation event to detect and respond to unauthorized disk manipulations, including checking for significant padding in altered files.

Steps to Use

  • Replace "path\to\monitored\directory" with the actual path of the directory you want to monitor.
  • Implement any additional logic you require in the DiskGuard_OnDiskManipulation method, especially for handling detected unauthorized disk manipulations and padding analysis.

This setup allows IDiskGuard to continuously monitor specified directories in the background, making it an efficient solution for detecting and responding to potential security threats or unauthorized changes in real-time, without requiring direct interaction with user-facing components like controllers.

FileInfo Extension Methods Overview

The Walter.IO package enriches your application with powerful FileInfo extension methods, designed to enhance file analysis and security measures. Among these, two standout methods provide essential capabilities for detecting potential security threats and ensuring data integrity:

CountPaddingBytesChunked()

This method efficiently calculates the number of padding bytes present at the end of a file. By leveraging chunked reading strategies, it optimizes performance and minimizes memory usage, making it exceptionally well-suited for processing large files. This capability is crucial for analyzing file structures and detecting anomalies that could signify data corruption or tampering.

Key Benefits:
  • Performance-Optimized: Tailored for large files with minimal performance impact.
  • Security Analysis: Aids in the identification of file tampering or corruption.

ContainsMoreThanOrEqualTo(percentage)

Evaluates whether the padding within a file constitutes a specified percentage (or more) of the file's total size. This method is instrumental in uncovering files that may have been deliberately modified to circumvent malware detection mechanisms through the introduction of excessive padding. Such modifications can alter a file's hash signature, enabling it to evade traditional detection techniques based on known signatures.

Key Benefits:
  • Malware Detection: Helps identify files potentially altered to bypass hash-based malware detection.
  • Customizable Threshold: Allows specification of the padding percentage threshold for targeted analysis.

Practical Applications

Detecting excessive padding in files is more than just a matter of maintaining data integrity. It's a critical security practice. Malicious actors often manipulate file padding to change hash signatures, thereby evading detection by antivirus programs and intrusion detection systems. By employing the ContainsMoreThanOrEqualTo method, developers and security professionals can pinpoint files with unusual padding patterns, flagging them for further investigation or automated responses.

Example Usage:

Detecting a file with excessive padding could be as straightforward as:

FileInfo suspiciousFile = new FileInfo("path/to/suspect/file.exe");

// Check if the file has padding exceeding 30% of its total size
bool isAltered = suspiciousFile.ContainsMoreThanOrEqualTo(30);

if (isAltered)
{
    Console.WriteLine($"File: {suspiciousFile.Name} may have been altered to evade malware detection.");
}

By integrating these FileInfo extensions into your security protocols, you can enhance your application's resilience against sophisticated cyber threats and ensure a higher level of data integrity and reliability.

Comparing File Padding Changes Between Scans

This example demonstrates how to monitor files for changes in padding, which could indicate tampering or unauthorized alterations aimed at evading detection.

using System;
using System.Collections.Generic;
using System.IO;
using Walter.IO;

public class PaddingMonitor
{
    private Dictionary<string, long> _lastScanResults = new Dictionary<string, long>();

    public void ScanDirectoryForPaddingChanges(string directoryPath)
    {
        DirectoryInfo directory = new DirectoryInfo(directoryPath);
        FileInfo[] files = directory.GetFiles("*.*", SearchOption.AllDirectories);

        foreach (var file in files)
        {
            long currentPadding = file.CountPaddingBytesChunked();
            if (_lastScanResults.TryGetValue(file.FullName, out long lastPadding))
            {
                if (currentPadding != lastPadding)
                {
                    Console.WriteLine($"Padding change detected in {file.Name}. Previous: {lastPadding}, Current: {currentPadding}");
                }
            }
            else
            {
                Console.WriteLine($"New file detected: {file.Name} with {currentPadding} padding bytes.");
            }

            // Update the last scan results
            _lastScanResults[file.FullName] = currentPadding;
        }
    }
}

Instantiate PaddingMonitor and call ScanDirectoryForPaddingChanges periodically or upon specific triggers to check for padding changes in the monitored directory.

File Comparison Extension: FileIsEqualToIgnoringPadding

The FileIsEqualToIgnoringPadding extension method is an invaluable tool in the Walter.IO package designed to enhance file integrity checks by comparing the binary content of two files, ignoring any trailing padding. This method is particularly useful for identifying files that have been altered to evade hash-based detection mechanisms by adding or modifying padding.

Use Case

In cybersecurity, verifying the integrity of files is crucial, especially for system-critical executables like powershell.exe. Malicious actors might duplicate and slightly alter such executables (e.g., by adding padding) to bypass security checks. The FileIsEqualToIgnoringPadding method enables developers to detect such tampering by comparing the core content of files, excluding padding variations.

Example: Comparing PowerShell Executable

This example demonstrates how to use FileIsEqualToIgnoringPadding to compare a downloaded file with the system's powershell.exe, focusing on their content while ignoring padding differences.

using System;
using System.IO;
using Walter.IO;

class Program
{
    static void Main(string[] args)
    {
    
        FileInfo originalPowerShell = new FileInfo(@"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe");
        FileInfo downloadedFile = new FileInfo(@"path\to\downloaded\file.exe"); // Update with the actual file path

        // Compare the original PowerShell executable with a downloaded file, ignoring padding
        bool areFilesEqual = originalPowerShell.FileIsEqualToIgnoringPadding(downloadedFile);

        if (areFilesEqual)
        {
            Console.WriteLine("The downloaded file is identical to powershell.exe, ignoring padding.");
        }
        else
        {
            Console.WriteLine("The downloaded file differs from powershell.exe or does not exist.");
        }
    }
}


### Yuu can use this method to see if malware is using hash signature changes in order to evaid malware detection signatures

```c#
using Walter.IO;

public static partial class Program
{
    public static void Main(string[] args)
    {
        // Define the path to the folder you want to scan. Here, using the Downloads folder as an example.
        string folderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Downloads");

        // Ensure the folder exists
        if (!Directory.Exists(folderPath))
        {
            Console.WriteLine("The specified folder does not exist.");
            return;
        }
        // Create a "poison" file with a specific amount of padding
        var poisonFilePath = Path.Combine(folderPath, $"sample_{DateTime.Now:yy-MM-dd-HH-mm-ss-fff}.bin");
        long totalFileSizeInBytes = 1024 * 1024; // 1 MB total size
        int paddingPercentage = 20; // Target 20% of the file size as padding
        FileWithPaddingCreator.CreateFileWithPadding(poisonFilePath, totalFileSizeInBytes, paddingPercentage);

        // Get all files in the folder
        FileInfo[] files = new DirectoryInfo(folderPath).GetFiles();

        
        

        Console.WriteLine("Scanning files for significant padding...");

        // Use Parallel.ForEach for efficient multi-threaded processing
        Parallel.ForEach(files, (file) =>
        {
            long fileSize = file.Length;
            if (fileSize == 0) return; // Skip empty files

            // Calculate the padding threshold based on the file size (e.g., 20% of the file size)


            // Use the extension method to count padding bytes
            long paddingBytesCount = file.CountPaddingBytesChunked();
            var padding = file.CountPaddingBytes();


            if (padding > 0)
            {
                decimal percentagePadding = (decimal)padding / file.Length * 100; // Correct percentage calculation
                if (paddingBytesCount > 0)
                {
                    Console.WriteLine($"Padding {file.Name} ({file.Age()} age): {padding:N0} bytes of padding ({percentagePadding:N2}%)");
                }
            }

        });
        if(File.Exists(poisonFilePath)) 
        {
            File.Delete(poisonFilePath);
        }
        Console.WriteLine("Scanning complete.");

#if !DEBUG
        Console.WriteLine("Press any to to exit..");
        Console.ReadKey();
#endif
    }
}
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Walter.IO:

Package Downloads
Walter.DataTools.MsSql

Package used by Firewall products for interacting with sql server and is used to create and apply updates to database DDL objects This package will be re-factored in the future separating base classes into a new package and have the MSSQL and MySql in their own packages.

Walter.Web.FireWall

Enhance .NET applications with a robust firewall, designed as middleware and IActionFilter, protecting against CVE attacks, web scraping, and phishing. Configurable via annotations and a rule engine services.AddFireWall(FireWallTrial.License, FireWallTrial.DomainKey , domainName: new Uri("https://www.your-domain.com", UriKind.Absolute) , options => { //your options }); Have a look at the GitHub samples at https://github.com/ASP-WAF/FireWall and https://github.com/ASP-WAF/FireWall/wiki to see how to use the firewall in applications. You can view the firewall in action using https://www.asp-waf.com/Firewall You can get started with the firewall using the samples shown in https://www.asp-waf.com/download/ASP-WAF-FireWall-Getting-Started.pdf as well as the on line documentation at https://firewallapi.asp-waf.com/

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
2024.11.6.1222 103 11/6/2024
2024.10.28.1605 294 10/28/2024
2024.10.28.1335 276 10/28/2024
2024.10.19.1525 249 10/20/2024
2024.10.18.1315 288 10/18/2024
2024.9.27.1406 278 9/27/2024
2024.9.17.1417 330 9/17/2024
2024.9.12.1923 375 9/12/2024
2024.9.6.1352 377 9/7/2024
2024.9.1.1159 383 9/1/2024
2024.8.26.1150 417 8/26/2024
2024.8.19.1411 418 8/19/2024
2024.8.17.1000 394 8/17/2024
2024.8.12.1622 367 8/13/2024
2024.8.5.1010 288 8/5/2024
2024.8.1.1545 406 8/16/2024
2024.7.28.629 228 7/28/2024
2024.7.26.1512 220 7/26/2024
2024.7.26.828 198 7/26/2024
2024.7.11.1604 358 7/11/2024
2024.7.9.1520 341 7/9/2024
2024.7.4.1425 374 7/4/2024
2024.7.3.1249 354 7/3/2024
2024.7.2.1536 399 7/2/2024
2024.6.28.953 372 6/28/2024
2024.6.6.1320 218 6/8/2024
2024.5.15.1634 177 5/15/2024
2024.5.14.829 102 5/14/2024
2024.5.8.1005 175 5/8/2024
2024.4.4.2102 207 4/4/2024
2024.3.26.1111 126 3/26/2024
2024.3.19.2310 102 3/19/2024
2024.3.12.1022 118 3/12/2024
2024.3.7.1756 119 3/7/2024
2023.11.13.1117 1,478 11/13/2023
2023.10.26.1502 1,342 10/29/2023
2023.10.12.1926 1,470 10/12/2023
2023.9.14.812 1,562 9/14/2023
2023.9.7.1748 1,585 9/7/2023
2023.9.7.1241 1,565 9/7/2023
2023.9.6.1001 1,534 9/6/2023
2023.9.5.1246 1,569 9/5/2023
2023.9.5.1032 1,553 9/5/2023
2023.8.31.1522 1,623 8/31/2023
2023.8.29.1040 1,596 8/29/2023
2023.8.17.901 1,678 8/17/2023
2023.8.9.1314 1,770 8/9/2023
2023.8.2.750 1,822 8/2/2023
2023.7.12.830 1,783 7/12/2023
2023.7.5.1419 1,898 7/6/2023
2023.6.14.1628 1,930 6/14/2023
2023.6.11.1304 2,057 6/11/2023
2023.5.30.1640 2,037 5/30/2023
2023.5.4.1552 2,107 5/4/2023
2023.5.1.1524 2,067 5/1/2023
2023.4.29.910 2,313 4/29/2023
2023.4.12.1236 2,299 4/12/2023
2023.3.22.1456 2,478 3/22/2023
2023.3.14.1356 2,574 3/14/2023
2023.3.1.810 2,602 3/1/2023
2023.2.25.11857 2,613 2/25/2023
2023.2.22.27 2,619 2/22/2023
2023.2.15.1413 2,710 2/15/2023
2023.2.11.1628 2,766 2/11/2023
2023.1.11.534 2,924 1/11/2023
2022.12.30.711 3,003 12/30/2022
2022.12.16.1536 1,066 12/16/2022
2022.12.15.1241 1,032 12/16/2022
2022.12.15.1108 3,184 12/15/2022
2022.12.14.648 3,193 12/14/2022
2022.11.27.1059 3,163 11/27/2022
2022.11.21.338 3,258 11/21/2022
2022.11.14.1819 3,354 11/14/2022
2022.11.13.917 3,363 11/13/2022
2022.11.7.1632 1,036 11/13/2022
2022.10.31.740 6,451 11/1/2022
2022.10.15.652 7,114 10/15/2022
2022.10.1.810 7,500 10/1/2022
2022.9.26.1444 7,573 9/26/2022
2022.9.14.1508 7,689 9/14/2022
2022.9.14.809 7,723 9/14/2022
2022.9.8.1009 7,880 9/8/2022
2022.8.20.1007 7,803 8/20/2022
2022.8.1.1 7,888 7/31/2022
2022.7.1300 8,085 7/1/2022
2022.7.31.1016 7,964 7/31/2022
2022.7.15.841 8,001 7/15/2022
2022.6.21.647 8,000 6/21/2022
2022.5.18.638 8,030 5/19/2022
2022.5.16.853 8,112 5/19/2022
2022.5.16.816 8,078 5/16/2022
2022.5.4.1010 8,002 5/4/2022
2022.4.10.947 8,526 4/10/2022
2022.4.10.925 8,576 4/10/2022
2022.4.10.828 8,424 4/10/2022
2022.4.1.1545 8,663 4/1/2022
2022.3.31.823 7,654 3/31/2022
2022.3.26.1103 8,722 3/26/2022
2022.3.26.820 8,474 3/26/2022
2022.3.25.840 7,769 3/26/2022
2022.3.24.1701 2,184 3/25/2022
2022.2.16.1131 8,837 2/17/2022
2022.2.16.834 8,762 2/17/2022
2022.2.15.824 3,113 2/17/2022
2022.2.11.1452 3,910 2/17/2022
2022.2.11.931 1,730 2/17/2022
2022.2.5.1114 9,063 2/5/2022
2022.1.17.1158 8,743 1/17/2022
2022.1.10.1505 8,920 1/10/2022
2022.1.10.537 8,321 1/10/2022
2022.1.5.1139 7,926 1/8/2022
2021.12.28.1452 8,903 12/28/2021
2021.12.16.812 8,662 12/16/2021
2021.11.23.1528 14,824 11/24/2021
2021.11.21.925 14,269 11/22/2021
2021.11.19.1503 1,452 11/22/2021
2021.11.19.847 9,549 11/19/2021
2021.11.18.1824 9,172 11/16/2021
2021.11.10.852 9,698 11/10/2021
2021.11.9.2021 9,415 11/9/2021
2021.11.8.2109 7,317 11/9/2021
2021.11.8.1612 7,819 11/8/2021
2021.11.7.1021 7,979 11/8/2021
2021.11.3.1612 8,029 11/4/2021
2021.11.1.1102 6,745 11/1/2021
2021.10.25.1206 8,272 10/25/2021
2021.10.23.1310 8,122 10/25/2021
2021.10.19.1522 8,191 10/19/2021
2021.10.16.1325 8,180 10/18/2021
2021.10.9.1119 289 10/9/2024
2021.10.6.1546 8,240 10/6/2021
2021.10.5.1450 8,261 10/5/2021
2021.10.4.1155 8,334 10/5/2021
2021.10.4.807 1,713 10/5/2021
2021.10.1.753 8,343 10/1/2021
2021.9.27.1005 7,734 9/28/2021
2021.9.26.1913 8,463 9/26/2021
2021.9.19.1015 8,336 9/19/2021
2021.9.17.1702 5,173 9/17/2021
2021.9.17.1449 10,858 9/17/2021
2021.9.13.1600 6,421 9/13/2021
2021.9.12.1100 4,929 9/13/2021
2021.9.11.2004 7,659 9/11/2021
2021.9.9.1110 8,140 9/9/2021
2021.9.7.1901 8,294 9/8/2021
2021.9.7.1121 8,391 9/7/2021
2021.9.7.927 1,711 9/7/2021
2021.9.6.1518 7,923 9/7/2021
2021.9.4.1124 8,275 9/4/2021
2021.9.2.708 7,941 9/4/2021
2021.9.0.1259 7,919 9/2/2021
2021.8.21.1230 22,043 8/22/2021
2021.8.18.1500 8,389 8/18/2021
2021.8.18.930 8,313 8/18/2021
2021.8.14.1600 8,281 8/16/2021
2021.8.14.829 4,309 8/14/2021
2021.8.9.1105 8,282 8/9/2021
2021.8.8.1612 8,050 8/8/2021
2021.8.8.1138 7,351 8/8/2021
2021.8.6.1044 8,117 8/6/2021
2021.8.4.1355 8,593 8/5/2021
2021.7.30.2118 8,575 7/31/2021
2021.7.27.926 8,568 7/28/2021
2021.7.23.931 8,708 7/26/2021
2021.7.22.1456 8,157 7/23/2021
2021.7.15.1547 8,306 7/15/2021
2021.7.13.812 8,157 7/13/2021
2021.7.8.1527 8,382 7/10/2021
2021.7.5.1649 7,522 7/5/2021
2021.6.29.1453 8,694 6/30/2021
2021.6.26.1753 8,916 6/27/2021
2021.6.25.1849 8,592 6/25/2021
2021.6.24.1518 8,500 6/24/2021
2021.6.20.729 9,208 6/20/2021
2021.6.15.2006 8,556 6/15/2021
2021.6.14.2025 9,078 6/15/2021
2021.6.13.2035 9,265 6/14/2021
2021.6.12.1154 8,684 6/13/2021
2021.6.9.1120 8,962 6/9/2021
2021.6.7.2103 1,734 6/7/2021
2021.6.3.1509 8,647 6/3/2021
2021.5.31.1533 8,879 5/31/2021
2021.5.31.1415 8,903 5/31/2021
2021.5.25.1732 7,864 5/25/2021
2021.5.24.1128 8,578 5/24/2021
2021.5.24.1019 8,362 5/24/2021
2021.5.12.1054 8,477 5/12/2021
2021.5.12.637 6,744 5/12/2021
2021.5.10.1442 7,870 5/11/2021
2021.5.8.1226 8,301 5/8/2021
2021.5.6.2037 7,339 5/6/2021
2021.5.5.1901 8,560 5/6/2021
2021.5.3.1621 8,620 5/4/2021
2021.5.1.905 8,927 5/1/2021
2021.4.28.1511 8,716 4/28/2021
2021.4.20.1520 9,275 4/21/2021
2021.4.16.738 9,180 4/21/2021
2021.4.14.1216 8,979 4/16/2021
2021.4.9.1538 8,796 4/13/2021
2021.4.8.947 8,830 4/13/2021
2021.4.6.1235 8,833 4/6/2021
2021.4.5.1653 8,599 4/5/2021
2021.4.1.913 8,848 4/1/2021
2021.3.31.2003 8,675 4/1/2021
2021.3.18.1622 9,163 3/18/2021
2021.3.3.1259 7,858 3/3/2021
2021.3.2.1415 8,359 3/2/2021
2021.3.1.11 7,735 2/28/2021
2021.3.1.1 8,125 2/27/2021
2021.3.1 7,790 2/27/2021
2021.2.23.6 7,087 2/23/2021
2021.2.21.1 8,217 2/21/2021
2021.2.20.1 7,848 2/20/2021
2021.2.19.2 7,576 2/19/2021
2021.2.18.6 6,528 2/19/2021
2021.2.17.1 7,618 2/17/2021
2021.2.16.1 8,045 2/16/2021
2021.2.15.3 8,036 2/15/2021
2021.2.15.1 7,951 2/14/2021
2021.2.14.3 7,434 2/14/2021
2021.2.12.6 7,772 2/12/2021
2021.2.12.2 7,931 2/12/2021
2021.2.11.1 6,311 2/11/2021
2021.2.10.1 7,397 2/10/2021
2021.2.8.1 7,848 2/9/2021
2021.2.7.1 14,535 2/6/2021
2020.12.27.6 8,158 12/27/2020
2020.12.27.1 7,529 12/27/2020
2020.12.26.7 7,284 12/27/2020
2020.12.26.5 8,057 12/27/2020
2020.12.26.3 8,057 12/27/2020

3  March 2024
- Migrate to .net 8 (including AoT)
- Make trimmable

17 November 2023
- Integrate .Net 8

12 October 2023
- Build using SDK-7.0.402 and SDK-6.0.415
- Update Package references

14 September 2023
- SDK 7.0.401/SDK 6.0.414
- Update to new NuGet Packages

12 July 2023
- Update to SDK SP 6.0.412. and 7.0.306
- Update package references
...

23 December 2020
- Initial release