using System; using System.Collections.Generic; using System.IO; using BinaryObjectScanner; namespace ProtectionScan { class Program { static void Main(string[] args) { #if NET462_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER // Register the codepages System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); #endif // Create progress indicator var fileProgress = new Progress(); fileProgress.ProgressChanged += Changed; // Get the options from the arguments var options = Options.ParseOptions(args); // If we have an invalid state if (options == null) { Options.DisplayHelp(); return; } // Create scanner for all paths var scanner = new Scanner( options.ScanArchives, options.ScanContents, options.ScanPaths, options.ScanSubdirectories, options.Debug, fileProgress); // Loop through the input paths foreach (string inputPath in options.InputPaths) { GetAndWriteProtections(scanner, inputPath); } } /// /// Wrapper to get and log protections for a single path /// /// Scanner object to use /// File or directory path private static void GetAndWriteProtections(Scanner scanner, string path) { // Normalize by getting the full path path = Path.GetFullPath(path); // An invalid path can't be scanned if (!Directory.Exists(path) && !File.Exists(path)) { Console.WriteLine($"{path} does not exist, skipping..."); return; } try { var protections = scanner.GetProtections(path); WriteProtectionResultFile(path, protections); } catch (Exception ex) { try { using var sw = new StreamWriter(File.OpenWrite($"exception-{DateTime.Now:yyyy-MM-dd_HHmmss.ffff}.txt")); sw.WriteLine(ex); } catch { Console.WriteLine("Could not open exception log file for writing. See original message below:"); Console.WriteLine(ex); } } } /// /// Write the protection results from a single path to file, if possible /// /// File or directory path /// Dictionary of protections found, if any private static void WriteProtectionResultFile(string path, Dictionary> protections) { if (protections == null) { Console.WriteLine($"No protections found for {path}"); return; } // Attempt to open a protection file for writing StreamWriter? sw = null; try { sw = new StreamWriter(File.OpenWrite($"protection-{DateTime.Now:yyyy-MM-dd_HHmmss.ffff}.txt")); } catch { Console.WriteLine("Could not open protection log file for writing. Only a console log will be provided."); } // Sort the keys for consistent output string[] keys = [.. protections.Keys]; Array.Sort(keys); // Loop over all keys foreach (string key in keys) { // Skip over files with no protection var value = protections[key]; if (value.Count == 0) continue; // Sort the detected protections for consistent output string[] fileProtections = [.. value]; Array.Sort(fileProtections); // Format and output the line string line = $"{key}: {string.Join(", ", fileProtections)}"; Console.WriteLine(line); sw?.WriteLine(line); } // Dispose of the writer sw?.Dispose(); } /// /// Protection progress changed handler /// private static void Changed(object? source, ProtectionProgress value) { string prefix = string.Empty; for (int i = 0; i < value.Depth; i++) { prefix += "--> "; } Console.WriteLine($"{prefix}{value.Percentage * 100:N2}%: {value.Filename} - {value.Protection}"); } } }