Walter.IO 2024.10.28.1605

Prefix Reserved
There is a newer version of this package available.
See the version list below for details.
dotnet add package Walter.IO --version 2024.10.28.1605                
NuGet\Install-Package Walter.IO -Version 2024.10.28.1605                
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.10.28.1605" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Walter.IO --version 2024.10.28.1605                
#r "nuget: Walter.IO, 2024.10.28.1605"                
#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.10.28.1605

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

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.20.644 302 11/21/2024
2024.11.15.421 273 11/15/2024
2024.11.11.1334 197 11/14/2024
2024.11.6.1222 271 11/6/2024
2024.10.28.1605 303 10/28/2024
2024.10.28.1335 305 10/28/2024
2024.10.19.1525 256 10/20/2024
2024.10.18.1315 295 10/18/2024
2024.9.27.1406 281 9/27/2024
2024.9.17.1417 333 9/17/2024
2024.9.12.1923 378 9/12/2024
2024.9.6.1352 380 9/7/2024
2024.9.1.1159 386 9/1/2024
2024.8.26.1150 420 8/26/2024
2024.8.19.1411 421 8/19/2024
2024.8.17.1000 397 8/17/2024
2024.8.12.1622 370 8/13/2024
2024.8.5.1010 291 8/5/2024
2024.8.1.1545 410 8/16/2024
2024.7.28.629 231 7/28/2024
2024.7.26.1512 223 7/26/2024
2024.7.26.828 201 7/26/2024
2024.7.11.1604 361 7/11/2024
2024.7.9.1520 345 7/9/2024
2024.7.4.1425 378 7/4/2024
2024.7.3.1249 358 7/3/2024
2024.7.2.1536 403 7/2/2024
2024.6.28.953 376 6/28/2024
2024.6.6.1320 222 6/8/2024
2024.5.15.1634 181 5/15/2024
2024.5.14.829 106 5/14/2024
2024.5.8.1005 179 5/8/2024
2024.4.4.2102 212 4/4/2024
2024.3.26.1111 130 3/26/2024
2024.3.19.2310 106 3/19/2024
2024.3.12.1022 122 3/12/2024
2024.3.7.1756 124 3/7/2024
2023.11.13.1117 1,481 11/13/2023
2023.10.26.1502 1,344 10/29/2023
2023.10.12.1926 1,472 10/12/2023
2023.9.14.812 1,565 9/14/2023
2023.9.7.1748 1,590 9/7/2023
2023.9.7.1241 1,567 9/7/2023
2023.9.6.1001 1,537 9/6/2023
2023.9.5.1246 1,571 9/5/2023
2023.9.5.1032 1,556 9/5/2023
2023.8.31.1522 1,625 8/31/2023
2023.8.29.1040 1,598 8/29/2023
2023.8.17.901 1,680 8/17/2023
2023.8.9.1314 1,772 8/9/2023
2023.8.2.750 1,824 8/2/2023
2023.7.12.830 1,785 7/12/2023
2023.7.5.1419 1,900 7/6/2023
2023.6.14.1628 1,933 6/14/2023
2023.6.11.1304 2,060 6/11/2023
2023.5.30.1640 2,039 5/30/2023
2023.5.4.1552 2,110 5/4/2023
2023.5.1.1524 2,069 5/1/2023
2023.4.29.910 2,315 4/29/2023
2023.4.12.1236 2,301 4/12/2023
2023.3.22.1456 2,480 3/22/2023
2023.3.14.1356 2,579 3/14/2023
2023.3.1.810 2,609 3/1/2023
2023.2.25.11857 2,615 2/25/2023
2023.2.22.27 2,621 2/22/2023
2023.2.15.1413 2,712 2/15/2023
2023.2.11.1628 2,768 2/11/2023
2023.1.11.534 2,929 1/11/2023
2022.12.30.711 3,006 12/30/2022
2022.12.16.1536 1,068 12/16/2022
2022.12.15.1241 1,034 12/16/2022
2022.12.15.1108 3,186 12/15/2022
2022.12.14.648 3,196 12/14/2022
2022.11.27.1059 3,167 11/27/2022
2022.11.21.338 3,260 11/21/2022
2022.11.14.1819 3,356 11/14/2022
2022.11.13.917 3,365 11/13/2022
2022.11.7.1632 1,038 11/13/2022
2022.10.31.740 6,453 11/1/2022
2022.10.15.652 7,116 10/15/2022
2022.10.1.810 7,502 10/1/2022
2022.9.26.1444 7,575 9/26/2022
2022.9.14.1508 7,692 9/14/2022
2022.9.14.809 7,726 9/14/2022
2022.9.8.1009 7,883 9/8/2022
2022.8.20.1007 7,806 8/20/2022
2022.8.1.1 7,890 7/31/2022
2022.7.1300 8,088 7/1/2022
2022.7.31.1016 7,967 7/31/2022
2022.7.15.841 8,004 7/15/2022
2022.6.21.647 8,003 6/21/2022
2022.5.18.638 8,032 5/19/2022
2022.5.16.853 8,115 5/19/2022
2022.5.16.816 8,080 5/16/2022
2022.5.4.1010 8,004 5/4/2022
2022.4.10.947 8,529 4/10/2022
2022.4.10.925 8,579 4/10/2022
2022.4.10.828 8,426 4/10/2022
2022.4.1.1545 8,665 4/1/2022
2022.3.31.823 7,657 3/31/2022
2022.3.26.1103 8,724 3/26/2022
2022.3.26.820 8,476 3/26/2022
2022.3.25.840 7,771 3/26/2022
2022.3.24.1701 2,186 3/25/2022
2022.2.16.1131 8,839 2/17/2022
2022.2.16.834 8,764 2/17/2022
2022.2.15.824 3,115 2/17/2022
2022.2.11.1452 3,912 2/17/2022
2022.2.11.931 1,732 2/17/2022
2022.2.5.1114 9,065 2/5/2022
2022.1.17.1158 8,745 1/17/2022
2022.1.10.1505 8,922 1/10/2022
2022.1.10.537 8,323 1/10/2022
2022.1.5.1139 7,928 1/8/2022
2021.12.28.1452 8,905 12/28/2021
2021.12.16.812 8,664 12/16/2021
2021.11.23.1528 14,826 11/24/2021
2021.11.21.925 14,271 11/22/2021
2021.11.19.1503 1,454 11/22/2021
2021.11.19.847 9,551 11/19/2021
2021.11.18.1824 9,175 11/16/2021
2021.11.10.852 9,700 11/10/2021
2021.11.9.2021 9,417 11/9/2021
2021.11.8.2109 7,319 11/9/2021
2021.11.8.1612 7,821 11/8/2021
2021.11.7.1021 7,981 11/8/2021
2021.11.3.1612 8,032 11/4/2021
2021.11.1.1102 6,747 11/1/2021
2021.10.25.1206 8,274 10/25/2021
2021.10.23.1310 8,124 10/25/2021
2021.10.19.1522 8,193 10/19/2021
2021.10.16.1325 8,182 10/18/2021
2021.10.9.1119 297 10/9/2024
2021.10.6.1546 8,243 10/6/2021
2021.10.5.1450 8,263 10/5/2021
2021.10.4.1155 8,336 10/5/2021
2021.10.4.807 1,715 10/5/2021
2021.10.1.753 8,346 10/1/2021
2021.9.27.1005 7,736 9/28/2021
2021.9.26.1913 8,466 9/26/2021
2021.9.19.1015 8,338 9/19/2021
2021.9.17.1702 5,175 9/17/2021
2021.9.17.1449 10,860 9/17/2021
2021.9.13.1600 6,423 9/13/2021
2021.9.12.1100 4,931 9/13/2021
2021.9.11.2004 7,662 9/11/2021
2021.9.9.1110 8,142 9/9/2021
2021.9.7.1901 8,296 9/8/2021
2021.9.7.1121 8,393 9/7/2021
2021.9.7.927 1,714 9/7/2021
2021.9.6.1518 7,925 9/7/2021
2021.9.4.1124 8,285 9/4/2021
2021.9.2.708 7,943 9/4/2021
2021.9.0.1259 7,921 9/2/2021
2021.8.21.1230 22,068 8/22/2021
2021.8.18.1500 8,391 8/18/2021
2021.8.18.930 8,315 8/18/2021
2021.8.14.1600 8,296 8/16/2021
2021.8.14.829 4,311 8/14/2021
2021.8.9.1105 8,284 8/9/2021
2021.8.8.1612 8,052 8/8/2021
2021.8.8.1138 7,353 8/8/2021
2021.8.6.1044 8,120 8/6/2021
2021.8.4.1355 8,595 8/5/2021
2021.7.30.2118 8,578 7/31/2021
2021.7.27.926 8,570 7/28/2021
2021.7.23.931 8,710 7/26/2021
2021.7.22.1456 8,159 7/23/2021
2021.7.15.1547 8,308 7/15/2021
2021.7.13.812 8,159 7/13/2021
2021.7.8.1527 8,384 7/10/2021
2021.7.5.1649 7,524 7/5/2021
2021.6.29.1453 8,697 6/30/2021
2021.6.26.1753 8,918 6/27/2021
2021.6.25.1849 8,594 6/25/2021
2021.6.24.1518 8,502 6/24/2021
2021.6.20.729 9,210 6/20/2021
2021.6.15.2006 8,559 6/15/2021
2021.6.14.2025 9,081 6/15/2021
2021.6.13.2035 9,267 6/14/2021
2021.6.12.1154 8,686 6/13/2021
2021.6.9.1120 8,964 6/9/2021
2021.6.7.2103 1,736 6/7/2021
2021.6.3.1509 8,649 6/3/2021
2021.5.31.1533 8,882 5/31/2021
2021.5.31.1415 8,905 5/31/2021
2021.5.25.1732 7,866 5/25/2021
2021.5.24.1128 8,581 5/24/2021
2021.5.24.1019 8,364 5/24/2021
2021.5.12.1054 8,480 5/12/2021
2021.5.12.637 6,746 5/12/2021
2021.5.10.1442 7,872 5/11/2021
2021.5.8.1226 8,303 5/8/2021
2021.5.6.2037 7,342 5/6/2021
2021.5.5.1901 8,562 5/6/2021
2021.5.3.1621 8,622 5/4/2021
2021.5.1.905 8,929 5/1/2021
2021.4.28.1511 8,718 4/28/2021
2021.4.20.1520 9,277 4/21/2021
2021.4.16.738 9,183 4/21/2021
2021.4.14.1216 8,982 4/16/2021
2021.4.9.1538 8,798 4/13/2021
2021.4.8.947 8,834 4/13/2021
2021.4.6.1235 8,835 4/6/2021
2021.4.5.1653 8,601 4/5/2021
2021.4.1.913 8,850 4/1/2021
2021.3.31.2003 8,677 4/1/2021
2021.3.18.1622 9,165 3/18/2021
2021.3.3.1259 7,864 3/3/2021
2021.3.2.1415 8,365 3/2/2021
2021.3.1.11 7,737 2/28/2021
2021.3.1.1 8,127 2/27/2021
2021.3.1 7,792 2/27/2021
2021.2.23.6 7,089 2/23/2021
2021.2.21.1 8,219 2/21/2021
2021.2.20.1 7,851 2/20/2021
2021.2.19.2 7,581 2/19/2021
2021.2.18.6 6,530 2/19/2021
2021.2.17.1 7,621 2/17/2021
2021.2.16.1 8,047 2/16/2021
2021.2.15.3 8,038 2/15/2021
2021.2.15.1 7,955 2/14/2021
2021.2.14.3 7,436 2/14/2021
2021.2.12.6 7,774 2/12/2021
2021.2.12.2 7,933 2/12/2021
2021.2.11.1 6,315 2/11/2021
2021.2.10.1 7,399 2/10/2021
2021.2.8.1 7,853 2/9/2021
2021.2.7.1 14,537 2/6/2021
2020.12.27.6 8,160 12/27/2020
2020.12.27.1 7,531 12/27/2020
2020.12.26.7 7,287 12/27/2020
2020.12.26.5 8,060 12/27/2020
2020.12.26.3 8,061 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