diff --git a/Test/App.config b/Test/App.config
deleted file mode 100644
index ecdcf8a5..00000000
--- a/Test/App.config
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff --git a/Test/Options.cs b/Test/Options.cs
new file mode 100644
index 00000000..1227d1e1
--- /dev/null
+++ b/Test/Options.cs
@@ -0,0 +1,282 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+namespace Test
+{
+ ///
+ /// Set of options for the test executable
+ ///
+ internal sealed class Options
+ {
+ #region Properties
+
+ ///
+ /// Enable debug output for relevant operations
+ ///
+ public bool Debug { get; private set; } = false;
+
+ ///
+ /// Set of input paths to use for operations
+ ///
+ public List InputPaths { get; private set; } = new List();
+
+ #region Extraction
+
+ ///
+ /// Perform archive extraction
+ ///
+ public bool EnableExtraction { get; private set; } = false;
+
+ ///
+ /// Output path for archive extraction
+ ///
+ public string OutputPath { get; private set; } = string.Empty;
+
+ #endregion
+
+ #region Information
+
+ ///
+ /// Perform information printing
+ ///
+ public bool EnableInformation { get; private set; } = false;
+
+#if NET6_0_OR_GREATER
+ ///
+ /// Enable JSON output
+ ///
+ public bool Json { get; private set; } = false;
+#endif
+
+ #endregion
+
+ #region Scanning
+
+ ///
+ /// Perform protection scanning
+ ///
+ public bool EnableScanning { get; private set; } = false;
+
+ ///
+ /// Scan archives during protection scanning
+ ///
+ public bool ScanArchives { get; private set; } = true;
+
+ ///
+ /// Scan file contents during protection scanning
+ ///
+ public bool ScanContents { get; private set; } = true;
+
+ ///
+ /// Scan packers during protection scanning
+ ///
+ public bool ScanPackers { get; private set; } = true;
+
+ ///
+ /// Scan file paths during protection scanning
+ ///
+ public bool ScanPaths { get; private set; } = true;
+
+ #endregion
+
+ #endregion
+
+ ///
+ /// Parse commandline arguments into an Options object
+ ///
+ public static Options ParseOptions(string[] args)
+ {
+ // If we have invalid arguments
+ if (args == null || args.Length == 0)
+ return null;
+
+ // Create an Options object
+ var options = new Options();
+
+ // Parse the features
+ int index = 0;
+ for (; index < args.Length; index++)
+ {
+ string arg = args[index];
+ bool featureFound = false;
+ switch (arg)
+ {
+ case "-?":
+ case "-h":
+ case "--help":
+ return null;
+
+ case "-x":
+ case "--extract":
+ options.EnableExtraction = true;
+ featureFound = true;
+ break;
+
+ case "-i":
+ case "--info":
+ options.EnableInformation = true;
+ featureFound = true;
+ break;
+
+ case "-s":
+ case "--scan":
+ options.EnableScanning = true;
+ featureFound = true;
+ break;
+
+ default:
+ break;
+ }
+
+ // If the flag wasn't a feature
+ if (!featureFound)
+ break;
+ }
+
+ // Parse the options and paths
+ for (; index < args.Length; index++)
+ {
+ string arg = args[index];
+ switch (arg)
+ {
+ case "-d":
+ case "--debug":
+ options.Debug = true;
+ break;
+
+ #region Extraction
+
+ case "-o":
+ case "--outdir":
+ options.OutputPath = index + 1 < args.Length ? args[++index] : null;
+ break;
+
+ #endregion
+
+ #region Information
+
+#if NET6_0_OR_GREATER
+ case "-j":
+ case "--json":
+ options.Json = true;
+ break;
+#endif
+
+ #endregion
+
+ #region Scanning
+
+ case "-na":
+ case "--no-archives":
+ options.ScanArchives = false;
+ break;
+
+ case "-nc":
+ case "--no-contents":
+ options.ScanContents = false;
+ break;
+
+ case "-np":
+ case "--no-packers":
+ options.ScanPackers = false;
+ break;
+
+ case "-ns":
+ case "--no-paths":
+ options.ScanPaths = false;
+ break;
+
+ #endregion
+
+ default:
+ options.InputPaths.Add(arg);
+ break;
+ }
+ }
+
+ // If we have no features set, enable protection scanning
+ if (!options.EnableExtraction && !options.EnableInformation && !options.EnableScanning)
+ options.EnableScanning = true;
+
+ // Validate we have any input paths to work on
+ if (options.InputPaths.Count == 0)
+ {
+ Console.WriteLine("At least one path is required!");
+ return null;
+ }
+
+ // If we have extraction enabled, validate the path
+ if (options.EnableExtraction)
+ {
+ bool validPath = ValidateExtractionPath(options);
+ if (!validPath)
+ return null;
+ }
+
+ return options;
+ }
+
+ ///
+ /// Display help text
+ ///
+ public static void DisplayHelp()
+ {
+ Console.WriteLine("BurnOutSharp Test Program");
+ Console.WriteLine();
+ Console.WriteLine("test.exe file|directory ...");
+ Console.WriteLine();
+ Console.WriteLine("Features:");
+ Console.WriteLine("-x, --extract Extract archive formats");
+ Console.WriteLine("-i, --info Print executable info");
+ Console.WriteLine("-s, --scan Enable protection scanning (default if none)");
+ Console.WriteLine();
+ Console.WriteLine("Common options:");
+ Console.WriteLine("-?, -h, --help Display this help text and quit");
+ Console.WriteLine("-d, --debug Enable debug mode");
+ Console.WriteLine();
+ Console.WriteLine("Extraction options:");
+ Console.WriteLine("-o, --outdir [PATH] Set output path for extraction (required)");
+#if NET6_0_OR_GREATER
+ Console.WriteLine();
+ Console.WriteLine("Information options:");
+ Console.WriteLine("-j, --json Print executable info as JSON");
+#endif
+ Console.WriteLine();
+ Console.WriteLine("Scanning options:");
+ Console.WriteLine("-nc, --no-contents Disable scanning for content checks");
+ Console.WriteLine("-na, --no-archives Disable scanning archives");
+ Console.WriteLine("-np, --no-packers Disable scanning for packers");
+ Console.WriteLine("-ns, --no-paths Disable scanning for path checks");
+ }
+
+ ///
+ /// Validate the extraction path
+ ///
+ private static bool ValidateExtractionPath(Options options)
+ {
+ // Null or empty output path
+ if (string.IsNullOrWhiteSpace(options.OutputPath))
+ {
+ Console.WriteLine("Output directory required for extraction!");
+ Console.WriteLine();
+ return false;
+ }
+
+ // Malformed output path or invalid location
+ try
+ {
+ options.OutputPath = Path.GetFullPath(options.OutputPath);
+ Directory.CreateDirectory(options.OutputPath);
+ }
+ catch
+ {
+ Console.WriteLine("Output directory could not be created!");
+ Console.WriteLine();
+ return false;
+ }
+
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Test/Printer.cs b/Test/Printer.cs
index d18351a1..9c734301 100644
--- a/Test/Printer.cs
+++ b/Test/Printer.cs
@@ -16,20 +16,32 @@ namespace Test
/// File or directory path
/// Enable JSON output, if supported
/// Enable debug output
+#if NET6_0_OR_GREATER
public static void PrintPathInfo(string path, bool json, bool debug)
+#else
+ public static void PrintPathInfo(string path, bool debug)
+#endif
{
Console.WriteLine($"Checking possible path: {path}");
// Check if the file or directory exists
if (File.Exists(path))
{
+#if NET6_0_OR_GREATER
PrintFileInfo(path, json, debug);
+#else
+ PrintFileInfo(path, debug);
+#endif
}
else if (Directory.Exists(path))
{
foreach (string file in Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories))
{
+#if NET6_0_OR_GREATER
PrintFileInfo(file, json, debug);
+#else
+ PrintFileInfo(file, debug);
+#endif
}
}
else
@@ -41,7 +53,11 @@ namespace Test
///
/// Print information for a single file, if possible
///
+#if NET6_0_OR_GREATER
private static void PrintFileInfo(string file, bool json, bool debug)
+#else
+ private static void PrintFileInfo(string file, bool debug)
+#endif
{
Console.WriteLine($"Attempting to print info for {file}");
@@ -260,6 +276,9 @@ namespace Test
// Print the wrapper name
Console.WriteLine($"{wrapperName} wrapper created successfully!");
+ // Get the base info output name
+ string filenameBase = $"info-{DateTime.Now:yyyy-MM-dd_HHmmss.ffff}";
+
#if NET6_0_OR_GREATER
// If we have the JSON flag
if (json)
@@ -269,24 +288,20 @@ namespace Test
Console.WriteLine(serializedData);
// Write the output data
- using (var sw = new StreamWriter(File.OpenWrite($"info-{DateTime.Now:yyyy-MM-dd_HHmmss.ffff}.json")))
+ using (var sw = new StreamWriter(File.OpenWrite($"{filenameBase}.json")))
{
sw.WriteLine(serializedData);
}
}
#endif
- // If we don't have the JSON flag
- if (!json)
- {
- // Create the output data
- StringBuilder builder = wrapper.PrettyPrint();
- Console.WriteLine(builder);
+ // Create the output data
+ StringBuilder builder = wrapper.PrettyPrint();
+ Console.WriteLine(builder);
- // Write the output data
- using (var sw = new StreamWriter(File.OpenWrite($"info-{DateTime.Now:yyyy-MM-dd_HHmmss.ffff}.txt")))
- {
- sw.WriteLine(builder.ToString());
- }
+ // Write the output data
+ using (var sw = new StreamWriter(File.OpenWrite($"{filenameBase}.txt")))
+ {
+ sw.WriteLine(builder.ToString());
}
}
}
diff --git a/Test/Program.cs b/Test/Program.cs
index 6a3467f6..a6fe7d0c 100644
--- a/Test/Program.cs
+++ b/Test/Program.cs
@@ -1,6 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.IO;
using System.Text;
using BurnOutSharp;
@@ -14,164 +12,52 @@ namespace Test
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
// Create progress indicator
- var p = new Progress();
- p.ProgressChanged += Protector.Changed;
+ var fileProgress = new Progress();
+ fileProgress.ProgressChanged += Protector.Changed;
- // Set initial values for scanner flags
- bool debug = false, archives = true, contents = true, json = false, packers = true, paths = true, info = false, extract = false;
- string outputPath = string.Empty;
- var inputPaths = new List();
+ // Get the options from the arguments
+ var options = Options.ParseOptions(args);
- // Loop through the arguments to get the flags
- for (int i = 0; i < args.Length; i++)
+ // If we have an invalid state
+ if (options == null)
{
- string arg = args[i];
-
- switch (arg)
- {
- case "-?":
- case "-h":
- case "--help":
- DisplayHelp();
- Console.WriteLine("Press enter to close the program...");
- Console.ReadLine();
- return;
-
- case "-d":
- case "--debug":
- debug = true;
- break;
-
- case "-na":
- case "--no-archives":
- archives = false;
- break;
-
- case "-nc":
- case "--no-contents":
- contents = false;
- break;
-
-#if NET6_0_OR_GREATER
-
- case "-j":
- case "--json":
- json = true;
- break;
-
-#endif
-
- case "-np":
- case "--no-packers":
- packers = false;
- break;
-
- case "-ns":
- case "--no-paths":
- paths = false;
- break;
-
- case "-i":
- case "--info":
- info = true;
- break;
-
- case "-x":
- case "--extract":
- extract = true;
- break;
-
- case "-o":
- case "--outdir":
- outputPath = i + 1 < args.Length ? args[++i] : null;
- break;
-
- default:
- inputPaths.Add(arg);
- break;
- }
- }
-
- // If we have no arguments, show the help
- if (inputPaths.Count == 0)
- {
- DisplayHelp();
+ Options.DisplayHelp();
Console.WriteLine("Press enter to close the program...");
Console.ReadLine();
return;
}
// Create scanner for all paths
- var scanner = new Scanner(archives, contents, packers, paths, debug, p);
-
- // If we have extraction, check the output path exists and is valid
- if (extract)
- {
- // Null or empty output path
- if (string.IsNullOrWhiteSpace(outputPath))
- {
- Console.WriteLine("Output directory required for extraction!");
- Console.WriteLine();
- DisplayHelp();
- Console.WriteLine("Press enter to close the program...");
- Console.ReadLine();
- return;
- }
-
- // Malformed output path or invalid location
- try
- {
- outputPath = Path.GetFullPath(outputPath);
- Directory.CreateDirectory(outputPath);
- }
- catch
- {
- Console.WriteLine("Output directory could not be created!");
- Console.WriteLine();
- DisplayHelp();
- Console.WriteLine("Press enter to close the program...");
- Console.ReadLine();
- return;
- }
- }
+ var scanner = new Scanner(
+ options.ScanArchives,
+ options.ScanContents,
+ options.ScanPackers,
+ options.ScanPaths,
+ options.Debug,
+ fileProgress);
// Loop through the input paths
- foreach (string inputPath in inputPaths)
+ foreach (string inputPath in options.InputPaths)
{
- if (info)
- Printer.PrintPathInfo(inputPath, json, debug);
- else if (extract)
- Extractor.ExtractPath(inputPath, outputPath);
- else
+ // Extraction
+ if (options.EnableExtraction)
+ Extractor.ExtractPath(inputPath, options.OutputPath);
+
+ // Information printing
+ if (options.EnableInformation)
+#if NET6_0_OR_GREATER
+ Printer.PrintPathInfo(inputPath, options.Json, options.Debug);
+#else
+ Printer.PrintPathInfo(inputPath, options.Debug);
+#endif
+
+ // Scanning
+ if (options.EnableScanning)
Protector.GetAndWriteProtections(scanner, inputPath);
}
Console.WriteLine("Press enter to close the program...");
Console.ReadLine();
}
-
- ///
- /// Display help text
- ///
- private static void DisplayHelp()
- {
- Console.WriteLine("BurnOutSharp Test Program");
- Console.WriteLine();
- Console.WriteLine("test.exe file|directory ...");
- Console.WriteLine();
- Console.WriteLine("Possible options:");
- Console.WriteLine("-?, -h, --help Display this help text and quit");
- Console.WriteLine("-d, --debug Enable debug mode");
- Console.WriteLine("-nc, --no-contents Disable scanning for content checks");
- Console.WriteLine("-na, --no-archives Disable scanning archives");
- Console.WriteLine("-np, --no-packers Disable scanning for packers");
- Console.WriteLine("-ns, --no-paths Disable scanning for path checks");
- Console.WriteLine("-i, --info Print executable info");
-#if NET6_0_OR_GREATER
- Console.WriteLine("-j, --json Print executable info as JSON");
-#endif
- Console.WriteLine("-x, --extract Extract archive formats (Requires -o)");
- Console.WriteLine("-o, --outdir [PATH] Set output path for extraction (Requires -x)");
- }
}
}
diff --git a/Test/Properties/AssemblyInfo.cs b/Test/Properties/AssemblyInfo.cs
deleted file mode 100644
index 55172df6..00000000
--- a/Test/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Test")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Test")]
-[assembly: AssemblyCopyright("Copyright © 2018")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("88735ba2-778d-4192-8eb2-fff6843719e2")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]