mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-07-09 02:16:46 +00:00
Start using ProtectionDictionary
This commit is contained in:
@@ -10,7 +10,6 @@ using System.Threading.Tasks;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Utilities;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
using static BinaryObjectScanner.Utilities.Dictionary;
|
||||
|
||||
namespace BinaryObjectScanner
|
||||
{
|
||||
@@ -49,18 +48,10 @@ namespace BinaryObjectScanner
|
||||
/// <param name="path">Path of the file or directory to check</param>
|
||||
/// <param name="scanner">Scanner object to use for options and scanning</param>
|
||||
/// <returns>Set of protections in file, null on error</returns>
|
||||
#if NET20 || NET35
|
||||
public static Dictionary<string, Queue<string>> HandlePathChecks(string path, IEnumerable<string>? files)
|
||||
#else
|
||||
public static ConcurrentDictionary<string, ConcurrentQueue<string>> HandlePathChecks(string path, IEnumerable<string>? files)
|
||||
#endif
|
||||
public static ProtectionDictionary HandlePathChecks(string path, IEnumerable<string>? files)
|
||||
{
|
||||
// Create the output dictionary
|
||||
#if NET20 || NET35
|
||||
var protections = new Dictionary<string, Queue<string>>();
|
||||
#else
|
||||
var protections = new ConcurrentDictionary<string, ConcurrentQueue<string>>();
|
||||
#endif
|
||||
var protections = new ProtectionDictionary();
|
||||
|
||||
// Preprocess the list of files
|
||||
files = files?.Select(f => f.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar))?.ToList();
|
||||
@@ -74,7 +65,7 @@ namespace BinaryObjectScanner
|
||||
{
|
||||
var subProtections = checkClass?.PerformCheck(path, files);
|
||||
if (subProtections != null)
|
||||
AppendToDictionary(protections, path, subProtections);
|
||||
protections.Append(path, subProtections);
|
||||
#if NET20 || NET35
|
||||
}
|
||||
#else
|
||||
@@ -114,11 +105,7 @@ namespace BinaryObjectScanner
|
||||
/// <param name="stream">Stream to scan the contents of</param>
|
||||
/// <param name="scanner">Scanner object to use on extractable contents</param>
|
||||
/// <returns>Set of protections in file, null on error</returns>
|
||||
#if NET20 || NET35
|
||||
public static Dictionary<string, Queue<string>>? HandleExtractable(IExtractable impl, string fileName, Stream? stream, Scanner scanner)
|
||||
#else
|
||||
public static ConcurrentDictionary<string, ConcurrentQueue<string>>? HandleExtractable(IExtractable impl, string fileName, Stream? stream, Scanner scanner)
|
||||
#endif
|
||||
public static ProtectionDictionary? HandleExtractable(IExtractable impl, string fileName, Stream? stream, Scanner scanner)
|
||||
{
|
||||
// If the extractable file itself fails
|
||||
try
|
||||
@@ -142,8 +129,8 @@ namespace BinaryObjectScanner
|
||||
}
|
||||
|
||||
// Prepare the returned protections
|
||||
StripFromKeys(subProtections, tempPath);
|
||||
PrependToKeys(subProtections, fileName);
|
||||
subProtections.StripFromKeys(tempPath);
|
||||
subProtections.PrependToKeys(fileName);
|
||||
return subProtections;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -162,11 +149,7 @@ namespace BinaryObjectScanner
|
||||
/// <param name="mz">MSDOS to scan the contents of</param>
|
||||
/// <param name="scanner">Scanner object to use on extractable contents</param>
|
||||
/// <returns>Set of protections in file, null on error</returns>
|
||||
#if NET20 || NET35
|
||||
public static Dictionary<string, Queue<string>>? HandleExtractable(IExtractableMSDOSExecutable impl, string fileName, MSDOS mz, Scanner scanner)
|
||||
#else
|
||||
public static ConcurrentDictionary<string, ConcurrentQueue<string>>? HandleExtractable(IExtractableMSDOSExecutable impl, string fileName, MSDOS mz, Scanner scanner)
|
||||
#endif
|
||||
public static ProtectionDictionary? HandleExtractable(IExtractableMSDOSExecutable impl, string fileName, MSDOS mz, Scanner scanner)
|
||||
{
|
||||
// If the extractable file itself fails
|
||||
try
|
||||
@@ -190,8 +173,8 @@ namespace BinaryObjectScanner
|
||||
}
|
||||
|
||||
// Prepare the returned protections
|
||||
StripFromKeys(subProtections, tempPath);
|
||||
PrependToKeys(subProtections, fileName);
|
||||
subProtections.StripFromKeys(tempPath);
|
||||
subProtections.PrependToKeys(fileName);
|
||||
return subProtections;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -210,11 +193,7 @@ namespace BinaryObjectScanner
|
||||
/// <param name="lex">LinearExecutable to scan the contents of</param>
|
||||
/// <param name="scanner">Scanner object to use on extractable contents</param>
|
||||
/// <returns>Set of protections in file, null on error</returns>
|
||||
#if NET20 || NET35
|
||||
public static Dictionary<string, Queue<string>>? HandleExtractable(IExtractableLinearExecutable impl, string fileName, LinearExecutable lex, Scanner scanner)
|
||||
#else
|
||||
public static ConcurrentDictionary<string, ConcurrentQueue<string>>? HandleExtractable(IExtractableLinearExecutable impl, string fileName, LinearExecutable lex, Scanner scanner)
|
||||
#endif
|
||||
public static ProtectionDictionary? HandleExtractable(IExtractableLinearExecutable impl, string fileName, LinearExecutable lex, Scanner scanner)
|
||||
{
|
||||
// If the extractable file itself fails
|
||||
try
|
||||
@@ -238,8 +217,8 @@ namespace BinaryObjectScanner
|
||||
}
|
||||
|
||||
// Prepare the returned protections
|
||||
StripFromKeys(subProtections, tempPath);
|
||||
PrependToKeys(subProtections, fileName);
|
||||
subProtections.StripFromKeys(tempPath);
|
||||
subProtections.PrependToKeys(fileName);
|
||||
return subProtections;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -258,11 +237,7 @@ namespace BinaryObjectScanner
|
||||
/// <param name="nex">NewExecutable to scan the contents of</param>
|
||||
/// <param name="scanner">Scanner object to use on extractable contents</param>
|
||||
/// <returns>Set of protections in file, null on error</returns>
|
||||
#if NET20 || NET35
|
||||
public static Dictionary<string, Queue<string>>? HandleExtractable(IExtractableNewExecutable impl, string fileName, NewExecutable nex, Scanner scanner)
|
||||
#else
|
||||
public static ConcurrentDictionary<string, ConcurrentQueue<string>>? HandleExtractable(IExtractableNewExecutable impl, string fileName, NewExecutable nex, Scanner scanner)
|
||||
#endif
|
||||
public static ProtectionDictionary? HandleExtractable(IExtractableNewExecutable impl, string fileName, NewExecutable nex, Scanner scanner)
|
||||
{
|
||||
// If the extractable file itself fails
|
||||
try
|
||||
@@ -286,8 +261,8 @@ namespace BinaryObjectScanner
|
||||
}
|
||||
|
||||
// Prepare the returned protections
|
||||
StripFromKeys(subProtections, tempPath);
|
||||
PrependToKeys(subProtections, fileName);
|
||||
subProtections.StripFromKeys(tempPath);
|
||||
subProtections.PrependToKeys(fileName);
|
||||
return subProtections;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -306,11 +281,7 @@ namespace BinaryObjectScanner
|
||||
/// <param name="pex">PortableExecutable to scan the contents of</param>
|
||||
/// <param name="scanner">Scanner object to use on extractable contents</param>
|
||||
/// <returns>Set of protections in file, null on error</returns>
|
||||
#if NET20 || NET35
|
||||
public static Dictionary<string, Queue<string>>? HandleExtractable(IExtractablePortableExecutable impl, string fileName, PortableExecutable pex, Scanner scanner)
|
||||
#else
|
||||
public static ConcurrentDictionary<string, ConcurrentQueue<string>>? HandleExtractable(IExtractablePortableExecutable impl, string fileName, PortableExecutable pex, Scanner scanner)
|
||||
#endif
|
||||
public static ProtectionDictionary? HandleExtractable(IExtractablePortableExecutable impl, string fileName, PortableExecutable pex, Scanner scanner)
|
||||
{
|
||||
// If the extractable file itself fails
|
||||
try
|
||||
@@ -334,8 +305,8 @@ namespace BinaryObjectScanner
|
||||
}
|
||||
|
||||
// Prepare the returned protections
|
||||
StripFromKeys(subProtections, tempPath);
|
||||
PrependToKeys(subProtections, fileName);
|
||||
subProtections.StripFromKeys(tempPath);
|
||||
subProtections.PrependToKeys(fileName);
|
||||
return subProtections;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace BinaryObjectScanner.Interfaces
|
||||
/// <param name="files">Enumerable of strings representing files in a directory</param>
|
||||
/// <remarks>This can do some limited content checking as well, but it's suggested to use a content check instead, if possible</remarks>
|
||||
#if NET20 || NET35
|
||||
Queue<string> CheckDirectoryPath(string path, IEnumerable<string>? files);
|
||||
List<string> CheckDirectoryPath(string path, IEnumerable<string>? files);
|
||||
#else
|
||||
ConcurrentQueue<string> CheckDirectoryPath(string path, IEnumerable<string>? files);
|
||||
#endif
|
||||
|
||||
@@ -48,8 +48,8 @@ namespace BinaryObjectScanner
|
||||
|
||||
// Add the key if needed and then append the lists
|
||||
#if NET20 || NET35
|
||||
if (!original.ContainsKey(key))
|
||||
original[key] = new Queue<string>();
|
||||
if (!ContainsKey(key))
|
||||
this[key] = new Queue<string>();
|
||||
#else
|
||||
TryAdd(key, new ConcurrentQueue<string>());
|
||||
#endif
|
||||
@@ -72,8 +72,8 @@ namespace BinaryObjectScanner
|
||||
|
||||
// Add the key if needed and then append the lists
|
||||
#if NET20 || NET35
|
||||
if (!original.ContainsKey(key))
|
||||
original[key] = new Queue<string>();
|
||||
if (!ContainsKey(key))
|
||||
this[key] = new Queue<string>();
|
||||
#else
|
||||
TryAdd(key, new ConcurrentQueue<string>());
|
||||
#endif
|
||||
@@ -94,8 +94,8 @@ namespace BinaryObjectScanner
|
||||
foreach (string key in addition.Keys)
|
||||
{
|
||||
#if NET20 || NET35
|
||||
if (!original.ContainsKey(key))
|
||||
original[key] = new Queue<string>();
|
||||
if (!ContainsKey(key))
|
||||
this[key] = new Queue<string>();
|
||||
#else
|
||||
TryAdd(key, new ConcurrentQueue<string>());
|
||||
#endif
|
||||
|
||||
@@ -17,7 +17,6 @@ using BinaryObjectScanner.Utilities;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
using SabreTools.Serialization.Wrappers;
|
||||
using static BinaryObjectScanner.Utilities.Dictionary;
|
||||
|
||||
namespace BinaryObjectScanner
|
||||
{
|
||||
@@ -92,24 +91,14 @@ namespace BinaryObjectScanner
|
||||
/// </summary>
|
||||
/// <param name="path">Path to scan</param>
|
||||
/// <returns>Dictionary of list of strings representing the found protections</returns>
|
||||
#if NET20 || NET35
|
||||
public Dictionary<string, Queue<string>>? GetProtections(string path)
|
||||
#else
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>>? GetProtections(string path)
|
||||
#endif
|
||||
{
|
||||
return GetProtections([path]);
|
||||
}
|
||||
public ProtectionDictionary? GetProtections(string path)
|
||||
=> GetProtections([path]);
|
||||
|
||||
/// <summary>
|
||||
/// Scan the list of paths and get all found protections
|
||||
/// </summary>
|
||||
/// <returns>Dictionary of list of strings representing the found protections</returns>
|
||||
#if NET20 || NET35
|
||||
public Dictionary<string, Queue<string>>? GetProtections(List<string>? paths)
|
||||
#else
|
||||
public ConcurrentDictionary<string, ConcurrentQueue<string>>? GetProtections(List<string>? paths)
|
||||
#endif
|
||||
public ProtectionDictionary? GetProtections(List<string>? paths)
|
||||
{
|
||||
// If we have no paths, we can't scan
|
||||
if (paths == null || !paths.Any())
|
||||
@@ -126,11 +115,7 @@ namespace BinaryObjectScanner
|
||||
string tempFilePathWithGuid = Path.Combine(tempFilePath, Guid.NewGuid().ToString());
|
||||
|
||||
// Loop through each path and get the returned values
|
||||
#if NET20 || NET35
|
||||
var protections = new Dictionary<string, Queue<string>>();
|
||||
#else
|
||||
var protections = new ConcurrentDictionary<string, ConcurrentQueue<string>>();
|
||||
#endif
|
||||
var protections = new ProtectionDictionary();
|
||||
foreach (string path in paths)
|
||||
{
|
||||
// Directories scan each internal file individually
|
||||
@@ -143,7 +128,7 @@ namespace BinaryObjectScanner
|
||||
if (ScanPaths)
|
||||
{
|
||||
var directoryPathProtections = Handler.HandlePathChecks(path, files);
|
||||
AppendToDictionary(protections, directoryPathProtections);
|
||||
protections.Append(directoryPathProtections);
|
||||
}
|
||||
|
||||
// Scan each file in directory separately
|
||||
@@ -164,25 +149,14 @@ namespace BinaryObjectScanner
|
||||
if (ScanPaths)
|
||||
{
|
||||
var filePathProtections = Handler.HandlePathChecks(file, files: null);
|
||||
AppendToDictionary(protections, filePathProtections);
|
||||
if (filePathProtections != null && filePathProtections.Any())
|
||||
protections.Append(filePathProtections);
|
||||
}
|
||||
|
||||
// Scan for content-detectable protections
|
||||
var fileProtections = GetInternalProtections(file);
|
||||
if (fileProtections != null && fileProtections.Any())
|
||||
{
|
||||
foreach (string key in fileProtections.Keys)
|
||||
{
|
||||
if (!protections.ContainsKey(key))
|
||||
#if NET20 || NET35
|
||||
protections[key] = new Queue<string>();
|
||||
#else
|
||||
protections[key] = new ConcurrentQueue<string>();
|
||||
#endif
|
||||
|
||||
protections[key].AddRange(fileProtections[key]);
|
||||
}
|
||||
}
|
||||
protections.Append(fileProtections);
|
||||
|
||||
// Checkpoint
|
||||
protections.TryGetValue(file, out var fullProtectionList);
|
||||
@@ -206,25 +180,14 @@ namespace BinaryObjectScanner
|
||||
if (ScanPaths)
|
||||
{
|
||||
var filePathProtections = Handler.HandlePathChecks(path, files: null);
|
||||
AppendToDictionary(protections, filePathProtections);
|
||||
if (filePathProtections != null && filePathProtections.Any())
|
||||
protections.Append(filePathProtections);
|
||||
}
|
||||
|
||||
// Scan for content-detectable protections
|
||||
var fileProtections = GetInternalProtections(path);
|
||||
if (fileProtections != null && fileProtections.Any())
|
||||
{
|
||||
foreach (string key in fileProtections.Keys)
|
||||
{
|
||||
if (!protections.ContainsKey(key))
|
||||
#if NET20 || NET35
|
||||
protections[key] = new Queue<string>();
|
||||
#else
|
||||
protections[key] = new ConcurrentQueue<string>();
|
||||
#endif
|
||||
|
||||
protections[key].AddRange(fileProtections[key]);
|
||||
}
|
||||
}
|
||||
protections.Append(fileProtections);
|
||||
|
||||
// Checkpoint
|
||||
protections.TryGetValue(path, out var fullProtectionList);
|
||||
@@ -241,7 +204,7 @@ namespace BinaryObjectScanner
|
||||
}
|
||||
|
||||
// Clear out any empty keys
|
||||
ClearEmptyKeys(protections);
|
||||
protections.ClearEmptyKeys();
|
||||
|
||||
// If we're in debug, output the elasped time to console
|
||||
if (IncludeDebug)
|
||||
@@ -255,11 +218,7 @@ namespace BinaryObjectScanner
|
||||
/// </summary>
|
||||
/// <param name="file">Path to the file to scan</param>
|
||||
/// <returns>Dictionary of list of strings representing the found protections</returns>
|
||||
#if NET20 || NET35
|
||||
private Dictionary<string, Queue<string>>? GetInternalProtections(string file)
|
||||
#else
|
||||
private ConcurrentDictionary<string, ConcurrentQueue<string>>? GetInternalProtections(string file)
|
||||
#endif
|
||||
private ProtectionDictionary? GetInternalProtections(string file)
|
||||
{
|
||||
// Quick sanity check before continuing
|
||||
if (!File.Exists(file))
|
||||
@@ -275,13 +234,9 @@ namespace BinaryObjectScanner
|
||||
{
|
||||
if (IncludeDebug) Console.WriteLine(ex);
|
||||
|
||||
#if NET20 || NET35
|
||||
var protections = new Dictionary<string, Queue<string>>();
|
||||
#else
|
||||
var protections = new ConcurrentDictionary<string, ConcurrentQueue<string>>();
|
||||
#endif
|
||||
AppendToDictionary(protections, file, IncludeDebug ? ex.ToString() : "[Exception opening file, please try again]");
|
||||
ClearEmptyKeys(protections);
|
||||
var protections = new ProtectionDictionary();
|
||||
protections.Append(file, IncludeDebug ? ex.ToString() : "[Exception opening file, please try again]");
|
||||
protections.ClearEmptyKeys();
|
||||
return protections;
|
||||
}
|
||||
}
|
||||
@@ -292,22 +247,14 @@ namespace BinaryObjectScanner
|
||||
/// <param name="fileName">Name of the source file of the stream, for tracking</param>
|
||||
/// <param name="stream">Stream to scan the contents of</param>
|
||||
/// <returns>Dictionary of list of strings representing the found protections</returns>
|
||||
#if NET20 || NET35
|
||||
private Dictionary<string, Queue<string>>? GetInternalProtections(string fileName, Stream stream)
|
||||
#else
|
||||
private ConcurrentDictionary<string, ConcurrentQueue<string>>? GetInternalProtections(string fileName, Stream stream)
|
||||
#endif
|
||||
private ProtectionDictionary? GetInternalProtections(string fileName, Stream stream)
|
||||
{
|
||||
// Quick sanity check before continuing
|
||||
if (stream == null || !stream.CanRead || !stream.CanSeek)
|
||||
return null;
|
||||
|
||||
// Initialize the protections found
|
||||
#if NET20 || NET35
|
||||
var protections = new Dictionary<string, Queue<string>>();
|
||||
#else
|
||||
var protections = new ConcurrentDictionary<string, ConcurrentQueue<string>>();
|
||||
#endif
|
||||
var protections = new ProtectionDictionary();
|
||||
|
||||
// Get the extension for certain checks
|
||||
string extension = Path.GetExtension(fileName).ToLower().TrimStart('.');
|
||||
@@ -349,7 +296,7 @@ namespace BinaryObjectScanner
|
||||
executable.IncludePackers = ScanPackers;
|
||||
var subProtections = ProcessExecutable(executable, fileName, stream);
|
||||
if (subProtections != null)
|
||||
AppendToDictionary(protections, subProtections);
|
||||
protections.Append(subProtections);
|
||||
}
|
||||
|
||||
// Otherwise, use the default implementation
|
||||
@@ -357,7 +304,7 @@ namespace BinaryObjectScanner
|
||||
{
|
||||
var subProtections = Handler.HandleDetectable(detectable, fileName, stream, IncludeDebug);
|
||||
if (subProtections != null)
|
||||
AppendToDictionary(protections, fileName, subProtections);
|
||||
protections.Append(fileName, subProtections);
|
||||
}
|
||||
|
||||
var subProtection = detectable.Detect(stream, fileName, IncludeDebug);
|
||||
@@ -367,11 +314,11 @@ namespace BinaryObjectScanner
|
||||
if (subProtection.Contains(';'))
|
||||
{
|
||||
var splitProtections = subProtection!.Split(';');
|
||||
AppendToDictionary(protections, fileName, splitProtections);
|
||||
protections.Append(fileName, splitProtections);
|
||||
}
|
||||
else
|
||||
{
|
||||
AppendToDictionary(protections, fileName, subProtection!);
|
||||
protections.Append(fileName, subProtection!);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -388,7 +335,7 @@ namespace BinaryObjectScanner
|
||||
{
|
||||
var subProtections = Handler.HandleExtractable(extractable, fileName, stream, this);
|
||||
if (subProtections != null)
|
||||
AppendToDictionary(protections, subProtections);
|
||||
protections.Append(subProtections);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -396,11 +343,11 @@ namespace BinaryObjectScanner
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (IncludeDebug) Console.WriteLine(ex);
|
||||
AppendToDictionary(protections, fileName, IncludeDebug ? ex.ToString() : "[Exception opening file, please try again]");
|
||||
protections.Append(fileName, IncludeDebug ? ex.ToString() : "[Exception opening file, please try again]");
|
||||
}
|
||||
|
||||
// Clear out any empty keys
|
||||
ClearEmptyKeys(protections);
|
||||
protections.ClearEmptyKeys();
|
||||
|
||||
return protections;
|
||||
}
|
||||
@@ -419,11 +366,7 @@ namespace BinaryObjectScanner
|
||||
/// Ideally, we wouldn't need to circumvent the proper handling of file types just for Executable,
|
||||
/// but due to the complexity of scanning, this is not currently possible.
|
||||
/// </remarks>
|
||||
#if NET20 || NET35
|
||||
private Dictionary<string, Queue<string>>? ProcessExecutable(Executable executable, string fileName, Stream stream)
|
||||
#else
|
||||
private ConcurrentDictionary<string, ConcurrentQueue<string>>? ProcessExecutable(Executable executable, string fileName, Stream stream)
|
||||
#endif
|
||||
private ProtectionDictionary? ProcessExecutable(Executable executable, string fileName, Stream stream)
|
||||
{
|
||||
// Try to create a wrapper for the proper executable type
|
||||
IWrapper? wrapper;
|
||||
@@ -440,18 +383,14 @@ namespace BinaryObjectScanner
|
||||
}
|
||||
|
||||
// Create the output dictionary
|
||||
#if NET20 || NET35
|
||||
var protections = new Dictionary<string, Queue<string>>();
|
||||
#else
|
||||
var protections = new ConcurrentDictionary<string, ConcurrentQueue<string>>();
|
||||
#endif
|
||||
var protections = new ProtectionDictionary();
|
||||
|
||||
// Only use generic content checks if we're in debug mode
|
||||
if (IncludeDebug)
|
||||
{
|
||||
var subProtections = executable.RunContentChecks(fileName, stream, IncludeDebug);
|
||||
if (subProtections != null)
|
||||
AppendToDictionary(protections, fileName, subProtections.Values.ToArray());
|
||||
protections.Append(fileName, subProtections.Values.ToArray());
|
||||
}
|
||||
|
||||
if (wrapper is MSDOS mz)
|
||||
@@ -461,12 +400,12 @@ namespace BinaryObjectScanner
|
||||
return protections;
|
||||
|
||||
// Append the returned values
|
||||
AppendToDictionary(protections, fileName, subProtections.Values.ToArray());
|
||||
protections.Append(fileName, subProtections.Values.ToArray());
|
||||
|
||||
// If we have any extractable packers
|
||||
var extractedProtections = HandleExtractableProtections(subProtections.Keys, fileName, mz);
|
||||
if (extractedProtections != null)
|
||||
AppendToDictionary(protections, extractedProtections);
|
||||
protections.Append(extractedProtections);
|
||||
}
|
||||
else if (wrapper is LinearExecutable lex)
|
||||
{
|
||||
@@ -475,12 +414,12 @@ namespace BinaryObjectScanner
|
||||
return protections;
|
||||
|
||||
// Append the returned values
|
||||
AppendToDictionary(protections, fileName, subProtections.Values.ToArray());
|
||||
protections.Append(fileName, subProtections.Values.ToArray());
|
||||
|
||||
// If we have any extractable packers
|
||||
var extractedProtections = HandleExtractableProtections(subProtections.Keys, fileName, lex);
|
||||
if (extractedProtections != null)
|
||||
AppendToDictionary(protections, extractedProtections);
|
||||
protections.Append(extractedProtections);
|
||||
}
|
||||
else if (wrapper is NewExecutable nex)
|
||||
{
|
||||
@@ -489,12 +428,12 @@ namespace BinaryObjectScanner
|
||||
return protections;
|
||||
|
||||
// Append the returned values
|
||||
AppendToDictionary(protections, fileName, subProtections.Values.ToArray());
|
||||
protections.Append(fileName, subProtections.Values.ToArray());
|
||||
|
||||
// If we have any extractable packers
|
||||
var extractedProtections = HandleExtractableProtections(subProtections.Keys, fileName, nex);
|
||||
if (extractedProtections != null)
|
||||
AppendToDictionary(protections, extractedProtections);
|
||||
protections.Append(extractedProtections);
|
||||
}
|
||||
else if (wrapper is PortableExecutable pex)
|
||||
{
|
||||
@@ -503,12 +442,12 @@ namespace BinaryObjectScanner
|
||||
return protections;
|
||||
|
||||
// Append the returned values
|
||||
AppendToDictionary(protections, fileName, subProtections.Values.ToArray());
|
||||
protections.Append(fileName, subProtections.Values.ToArray());
|
||||
|
||||
// If we have any extractable packers
|
||||
var extractedProtections = HandleExtractableProtections(subProtections.Keys, fileName, pex);
|
||||
if (extractedProtections != null)
|
||||
AppendToDictionary(protections, extractedProtections);
|
||||
protections.Append(extractedProtections);
|
||||
}
|
||||
|
||||
return protections;
|
||||
@@ -522,9 +461,9 @@ namespace BinaryObjectScanner
|
||||
/// <param name="mz">MSDOS to scan the contents of</param>
|
||||
/// <returns>Set of protections found from extraction, null on error</returns>
|
||||
#if NET20 || NET35
|
||||
private Dictionary<string, Queue<string>>? HandleExtractableProtections<T>(Dictionary<T, string>.KeyCollection? classes, string fileName, MSDOS mz)
|
||||
private ProtectionDictionary? HandleExtractableProtections<T>(Dictionary<T, string>.KeyCollection? classes, string fileName, MSDOS mz)
|
||||
#else
|
||||
private ConcurrentDictionary<string, ConcurrentQueue<string>>? HandleExtractableProtections(IEnumerable<object>? classes, string fileName, MSDOS mz)
|
||||
private ProtectionDictionary? HandleExtractableProtections(IEnumerable<object>? classes, string fileName, MSDOS mz)
|
||||
#endif
|
||||
{
|
||||
// If we have an invalid set of classes
|
||||
@@ -532,11 +471,7 @@ namespace BinaryObjectScanner
|
||||
return null;
|
||||
|
||||
// Create the output dictionary
|
||||
#if NET20 || NET35
|
||||
var protections = new Dictionary<string, Queue<string>>();
|
||||
#else
|
||||
var protections = new ConcurrentDictionary<string, ConcurrentQueue<string>>();
|
||||
#endif
|
||||
var protections = new ProtectionDictionary();
|
||||
|
||||
// If we have any extractable packers
|
||||
var extractables = classes.Where(c => c is IExtractableMSDOSExecutable).Select(c => c as IExtractableMSDOSExecutable);
|
||||
@@ -557,7 +492,7 @@ namespace BinaryObjectScanner
|
||||
// Get the protection for the class, if possible
|
||||
var extractedProtections = Handler.HandleExtractable(extractable, fileName, mz, this);
|
||||
if (extractedProtections != null)
|
||||
AppendToDictionary(protections, extractedProtections);
|
||||
protections.Append(extractedProtections);
|
||||
#if NET20 || NET35
|
||||
}
|
||||
#else
|
||||
@@ -575,9 +510,9 @@ namespace BinaryObjectScanner
|
||||
/// <param name="lex">LinearExecutable to scan the contents of</param>
|
||||
/// <returns>Set of protections found from extraction, null on error</returns>
|
||||
#if NET20 || NET35
|
||||
private Dictionary<string, Queue<string>>? HandleExtractableProtections<T>(Dictionary<T, string>.KeyCollection? classes, string fileName, LinearExecutable lex)
|
||||
private ProtectionDictionary? HandleExtractableProtections<T>(Dictionary<T, string>.KeyCollection? classes, string fileName, LinearExecutable lex)
|
||||
#else
|
||||
private ConcurrentDictionary<string, ConcurrentQueue<string>>? HandleExtractableProtections(IEnumerable<object>? classes, string fileName, LinearExecutable lex)
|
||||
private ProtectionDictionary? HandleExtractableProtections(IEnumerable<object>? classes, string fileName, LinearExecutable lex)
|
||||
#endif
|
||||
{
|
||||
// If we have an invalid set of classes
|
||||
@@ -585,11 +520,7 @@ namespace BinaryObjectScanner
|
||||
return null;
|
||||
|
||||
// Create the output dictionary
|
||||
#if NET20 || NET35
|
||||
var protections = new Dictionary<string, Queue<string>>();
|
||||
#else
|
||||
var protections = new ConcurrentDictionary<string, ConcurrentQueue<string>>();
|
||||
#endif
|
||||
var protections = new ProtectionDictionary();
|
||||
|
||||
// If we have any extractable packers
|
||||
var extractables = classes.Where(c => c is IExtractableLinearExecutable).Select(c => c as IExtractableLinearExecutable);
|
||||
@@ -610,7 +541,7 @@ namespace BinaryObjectScanner
|
||||
// Get the protection for the class, if possible
|
||||
var extractedProtections = Handler.HandleExtractable(extractable, fileName, lex, this);
|
||||
if (extractedProtections != null)
|
||||
AppendToDictionary(protections, extractedProtections);
|
||||
protections.Append(extractedProtections);
|
||||
#if NET20 || NET35
|
||||
}
|
||||
#else
|
||||
@@ -628,9 +559,9 @@ namespace BinaryObjectScanner
|
||||
/// <param name="nex">NewExecutable to scan the contents of</param>
|
||||
/// <returns>Set of protections found from extraction, null on error</returns>
|
||||
#if NET20 || NET35
|
||||
private Dictionary<string, Queue<string>>? HandleExtractableProtections<T>(Dictionary<T, string>.KeyCollection? classes, string fileName, NewExecutable nex)
|
||||
private ProtectionDictionary? HandleExtractableProtections<T>(Dictionary<T, string>.KeyCollection? classes, string fileName, NewExecutable nex)
|
||||
#else
|
||||
private ConcurrentDictionary<string, ConcurrentQueue<string>>? HandleExtractableProtections(IEnumerable<object>? classes, string fileName, NewExecutable nex)
|
||||
private ProtectionDictionary? HandleExtractableProtections(IEnumerable<object>? classes, string fileName, NewExecutable nex)
|
||||
#endif
|
||||
{
|
||||
// If we have an invalid set of classes
|
||||
@@ -638,11 +569,7 @@ namespace BinaryObjectScanner
|
||||
return null;
|
||||
|
||||
// Create the output dictionary
|
||||
#if NET20 || NET35
|
||||
var protections = new Dictionary<string, Queue<string>>();
|
||||
#else
|
||||
var protections = new ConcurrentDictionary<string, ConcurrentQueue<string>>();
|
||||
#endif
|
||||
var protections = new ProtectionDictionary();
|
||||
|
||||
// If we have any extractable packers
|
||||
var extractables = classes.Where(c => c is IExtractableNewExecutable).Select(c => c as IExtractableNewExecutable);
|
||||
@@ -663,7 +590,7 @@ namespace BinaryObjectScanner
|
||||
// Get the protection for the class, if possible
|
||||
var extractedProtections = Handler.HandleExtractable(extractable, fileName, nex, this);
|
||||
if (extractedProtections != null)
|
||||
AppendToDictionary(protections, extractedProtections);
|
||||
protections.Append(extractedProtections);
|
||||
#if NET20 || NET35
|
||||
}
|
||||
#else
|
||||
@@ -681,9 +608,9 @@ namespace BinaryObjectScanner
|
||||
/// <param name="pex">PortableExecutable to scan the contents of</param>
|
||||
/// <returns>Set of protections found from extraction, null on error</returns>
|
||||
#if NET20 || NET35
|
||||
private Dictionary<string, Queue<string>>? HandleExtractableProtections<T>(Dictionary<T, string>.KeyCollection? classes, string fileName, PortableExecutable pex)
|
||||
private ProtectionDictionary? HandleExtractableProtections<T>(Dictionary<T, string>.KeyCollection? classes, string fileName, PortableExecutable pex)
|
||||
#else
|
||||
private ConcurrentDictionary<string, ConcurrentQueue<string>>? HandleExtractableProtections(IEnumerable<object>? classes, string fileName, PortableExecutable pex)
|
||||
private ProtectionDictionary? HandleExtractableProtections(IEnumerable<object>? classes, string fileName, PortableExecutable pex)
|
||||
#endif
|
||||
{
|
||||
// If we have an invalid set of classes
|
||||
@@ -691,11 +618,7 @@ namespace BinaryObjectScanner
|
||||
return null;
|
||||
|
||||
// Create the output dictionary
|
||||
#if NET20 || NET35
|
||||
var protections = new Dictionary<string, Queue<string>>();
|
||||
#else
|
||||
var protections = new ConcurrentDictionary<string, ConcurrentQueue<string>>();
|
||||
#endif
|
||||
var protections = new ProtectionDictionary();
|
||||
|
||||
// If we have any extractable packers
|
||||
var extractables = classes.Where(c => c is IExtractablePortableExecutable).Select(c => c as IExtractablePortableExecutable);
|
||||
@@ -716,7 +639,7 @@ namespace BinaryObjectScanner
|
||||
// Get the protection for the class, if possible
|
||||
var extractedProtections = Handler.HandleExtractable(extractable, fileName, pex, this);
|
||||
if (extractedProtections != null)
|
||||
AppendToDictionary(protections, extractedProtections);
|
||||
protections.Append(extractedProtections);
|
||||
#if NET20 || NET35
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -1,238 +0,0 @@
|
||||
using System;
|
||||
#if NET20 || NET35
|
||||
using System.Collections.Generic;
|
||||
#else
|
||||
using System.Collections.Concurrent;
|
||||
#endif
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace BinaryObjectScanner.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Dictionary manipulation methods
|
||||
/// </summary>
|
||||
public static class Dictionary
|
||||
{
|
||||
/// <summary>
|
||||
/// Append one result to a results dictionary
|
||||
/// </summary>
|
||||
/// <param name="original">Dictionary to append to</param>
|
||||
/// <param name="key">Key to add information to</param>
|
||||
/// <param name="value">String value to add</param>
|
||||
#if NET20 || NET35
|
||||
public static void AppendToDictionary(Dictionary<string, Queue<string>> original, string key, string value)
|
||||
#else
|
||||
public static void AppendToDictionary(ConcurrentDictionary<string, ConcurrentQueue<string>> original, string key, string value)
|
||||
#endif
|
||||
{
|
||||
// If the value is empty, don't add it
|
||||
if (string.IsNullOrEmpty(value))
|
||||
return;
|
||||
|
||||
#if NET20 || NET35
|
||||
var values = new Queue<string>();
|
||||
#else
|
||||
var values = new ConcurrentQueue<string>();
|
||||
#endif
|
||||
values.Enqueue(value);
|
||||
AppendToDictionary(original, key, values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Append one set of results to a results dictionary
|
||||
/// </summary>
|
||||
/// <param name="original">Dictionary to append to</param>
|
||||
/// <param name="key">Key to add information to</param>
|
||||
/// <param name="values">String value array to add</param>
|
||||
#if NET20 || NET35
|
||||
public static void AppendToDictionary(Dictionary<string, Queue<string>> original, string key, string[] values)
|
||||
#else
|
||||
public static void AppendToDictionary(ConcurrentDictionary<string, ConcurrentQueue<string>> original, string key, string[] values)
|
||||
#endif
|
||||
{
|
||||
// If the dictionary is null, just return
|
||||
if (original == null)
|
||||
return;
|
||||
|
||||
// Use a placeholder value if the key is null
|
||||
key ??= "NO FILENAME";
|
||||
|
||||
// Add the key if needed and then append the lists
|
||||
#if NET20 || NET35
|
||||
if (!original.ContainsKey(key))
|
||||
original[key] = new Queue<string>();
|
||||
#else
|
||||
original.TryAdd(key, new ConcurrentQueue<string>());
|
||||
#endif
|
||||
original[key].AddRange(values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Append one set of results to a results dictionary
|
||||
/// </summary>
|
||||
/// <param name="original">Dictionary to append to</param>
|
||||
/// <param name="key">Key to add information to</param>
|
||||
/// <param name="value">String value to add</param>
|
||||
#if NET20 || NET35
|
||||
public static void AppendToDictionary(Dictionary<string, Queue<string>> original, string key, Queue<string> values)
|
||||
#else
|
||||
public static void AppendToDictionary(ConcurrentDictionary<string, ConcurrentQueue<string>> original, string key, ConcurrentQueue<string> values)
|
||||
#endif
|
||||
{
|
||||
// If the dictionary is null, just return
|
||||
if (original == null)
|
||||
return;
|
||||
|
||||
// Use a placeholder value if the key is null
|
||||
key ??= "NO FILENAME";
|
||||
|
||||
// Add the key if needed and then append the lists
|
||||
#if NET20 || NET35
|
||||
if (!original.ContainsKey(key))
|
||||
original[key] = new Queue<string>();
|
||||
#else
|
||||
original.TryAdd(key, new ConcurrentQueue<string>());
|
||||
#endif
|
||||
original[key].AddRange(values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Append one results dictionary to another
|
||||
/// </summary>
|
||||
/// <param name="original">Dictionary to append to</param>
|
||||
/// <param name="addition">Dictionary to pull from</param>
|
||||
#if NET20 || NET35
|
||||
public static void AppendToDictionary(Dictionary<string, Queue<string>> original, Dictionary<string, Queue<string>> addition)
|
||||
#else
|
||||
public static void AppendToDictionary(ConcurrentDictionary<string, ConcurrentQueue<string>> original, ConcurrentDictionary<string, ConcurrentQueue<string>> addition)
|
||||
#endif
|
||||
{
|
||||
// If either dictionary is missing, just return
|
||||
if (original == null || addition == null)
|
||||
return;
|
||||
|
||||
// Loop through each of the addition keys and add accordingly
|
||||
foreach (string key in addition.Keys)
|
||||
{
|
||||
#if NET20 || NET35
|
||||
if (!original.ContainsKey(key))
|
||||
original[key] = new Queue<string>();
|
||||
#else
|
||||
original.TryAdd(key, new ConcurrentQueue<string>());
|
||||
#endif
|
||||
original[key].AddRange(addition[key]);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove empty or null keys from a results dictionary
|
||||
/// </summary>
|
||||
/// <param name="original">Dictionary to clean</param>
|
||||
#if NET20 || NET35
|
||||
public static void ClearEmptyKeys(Dictionary<string, Queue<string>> original)
|
||||
#else
|
||||
public static void ClearEmptyKeys(ConcurrentDictionary<string, ConcurrentQueue<string>> original)
|
||||
#endif
|
||||
{
|
||||
// If the dictionary is missing, we can't do anything
|
||||
if (original == null)
|
||||
return;
|
||||
|
||||
// Get a list of all of the keys
|
||||
var keys = original.Keys.ToList();
|
||||
|
||||
// Iterate and reset keys
|
||||
for (int i = 0; i < keys.Count; i++)
|
||||
{
|
||||
// Get the current key
|
||||
string key = keys[i];
|
||||
|
||||
// If the key is empty, remove it
|
||||
if (original[key] == null || !original[key].Any())
|
||||
#if NET20 || NET35
|
||||
original.Remove(key);
|
||||
#else
|
||||
original.TryRemove(key, out _);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prepend a parent path from dictionary keys, if possible
|
||||
/// </summary>
|
||||
/// <param name="original">Dictionary to strip values from</param>
|
||||
/// <param name="pathToPrepend">Path to strip from the keys</param>
|
||||
#if NET20 || NET35
|
||||
public static void PrependToKeys(Dictionary<string, Queue<string>>? original, string pathToPrepend)
|
||||
#else
|
||||
public static void PrependToKeys(ConcurrentDictionary<string, ConcurrentQueue<string>>? original, string pathToPrepend)
|
||||
#endif
|
||||
{
|
||||
// If the dictionary is missing, we can't do anything
|
||||
if (original == null)
|
||||
return;
|
||||
|
||||
// Use a placeholder value if the path is null
|
||||
pathToPrepend = (pathToPrepend ?? "ARCHIVE").TrimEnd(Path.DirectorySeparatorChar);
|
||||
|
||||
// Get a list of all of the keys
|
||||
var keys = original.Keys.ToList();
|
||||
|
||||
// Iterate and reset keys
|
||||
for (int i = 0; i < keys.Count; i++)
|
||||
{
|
||||
// Get the current key
|
||||
string currentKey = keys[i];
|
||||
|
||||
// Otherwise, get the new key name and transfer over
|
||||
string newKey = $"{pathToPrepend}{Path.DirectorySeparatorChar}{currentKey.Trim(Path.DirectorySeparatorChar)}";
|
||||
original[newKey] = original[currentKey];
|
||||
#if NET20 || NET35
|
||||
original.Remove(currentKey);
|
||||
#else
|
||||
original.TryRemove(currentKey, out _);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Strip a parent path from dictionary keys, if possible
|
||||
/// </summary>
|
||||
/// <param name="original">Dictionary to strip values from</param>
|
||||
/// <param name="pathToStrip">Path to strip from the keys</param>
|
||||
#if NET20 || NET35
|
||||
public static void StripFromKeys(Dictionary<string, Queue<string>>? original, string? pathToStrip)
|
||||
#else
|
||||
public static void StripFromKeys(ConcurrentDictionary<string, ConcurrentQueue<string>>? original, string? pathToStrip)
|
||||
#endif
|
||||
{
|
||||
// If either is missing, we can't do anything
|
||||
if (original == null || string.IsNullOrEmpty(pathToStrip))
|
||||
return;
|
||||
|
||||
// Get a list of all of the keys
|
||||
var keys = original.Keys.ToList();
|
||||
|
||||
// Iterate and reset keys
|
||||
for (int i = 0; i < keys.Count; i++)
|
||||
{
|
||||
// Get the current key
|
||||
string currentKey = keys[i];
|
||||
|
||||
// If the key doesn't start with the path, don't touch it
|
||||
if (!currentKey.StartsWith(pathToStrip, StringComparison.OrdinalIgnoreCase))
|
||||
continue;
|
||||
|
||||
// Otherwise, get the new key name and transfer over
|
||||
string newKey = currentKey.Substring(pathToStrip!.Length);
|
||||
original[newKey] = original[currentKey];
|
||||
#if NET20 || NET35
|
||||
original.Remove(currentKey);
|
||||
#else
|
||||
original.TryRemove(currentKey, out _);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,11 +43,7 @@ namespace Test
|
||||
/// </summary>
|
||||
/// <param name="path">File or directory path</param>
|
||||
/// <param name="protections">Dictionary of protections found, if any</param>
|
||||
#if NET20 || NET35
|
||||
private static void WriteProtectionResultFile(string path, Dictionary<string, Queue<string>>? protections)
|
||||
#else
|
||||
private static void WriteProtectionResultFile(string path, ConcurrentDictionary<string, ConcurrentQueue<string>>? protections)
|
||||
#endif
|
||||
private static void WriteProtectionResultFile(string path, ProtectionDictionary? protections)
|
||||
{
|
||||
if (protections == null)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user