Files
BinaryObjectScanner/BurnOutSharp/FileType/Executable.cs

171 lines
6.6 KiB
C#
Raw Normal View History

using System;
using System.Collections.Concurrent;
using System.IO;
using System.Text;
using System.Threading.Tasks;
2022-05-01 17:41:50 -07:00
using BurnOutSharp.Interfaces;
2023-03-07 16:59:14 -05:00
using BinaryObjectScanner.Wrappers;
2023-03-07 12:04:48 -05:00
using static BinaryObjectScanner.Utilities.Dictionary;
namespace BurnOutSharp.FileType
{
/// <summary>
/// Executable or library
/// </summary>
public class Executable : IScannable
{
2021-02-26 09:26:23 -08:00
/// <inheritdoc/>
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, string file)
2021-02-26 09:26:23 -08:00
{
if (!File.Exists(file))
return null;
2022-12-22 22:03:32 -08:00
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
2021-02-26 09:26:23 -08:00
{
return Scan(scanner, fs, file);
}
}
/// <inheritdoc/>
public ConcurrentDictionary<string, ConcurrentQueue<string>> Scan(Scanner scanner, Stream stream, string file)
{
// Files can be protected in multiple ways
var protections = new ConcurrentDictionary<string, ConcurrentQueue<string>>();
2022-03-15 12:39:22 -07:00
// Load the current file content for debug only
byte[] fileContent = null;
2022-03-15 12:39:22 -07:00
if (scanner.IncludeDebug)
{
2022-03-15 12:39:22 -07:00
try
{
2022-03-15 12:39:22 -07:00
using (BinaryReader br = new BinaryReader(stream, Encoding.Default, true))
{
fileContent = br.ReadBytes((int)stream.Length);
}
}
2022-05-15 20:58:27 -07:00
catch (Exception ex)
2022-03-15 12:39:22 -07:00
{
2022-05-15 20:58:27 -07:00
if (scanner.IncludeDebug) Console.WriteLine(ex);
2023-01-17 20:21:25 -08:00
// Enable for odd files, keep disabled otherwise
// AppendToDictionary(protections, file, "[Out of memory attempting to open]");
// return protections;
}
}
2021-09-10 16:15:20 -07:00
2023-01-18 08:36:16 -08:00
// Get the wrapper for the appropriate executable type
2023-01-18 10:56:19 -08:00
WrapperBase wrapper = Tools.Utilities.DetermineExecutableType(stream);
2023-01-18 08:36:16 -08:00
if (wrapper == null)
return protections;
2021-09-10 21:45:34 -07:00
2022-03-14 10:49:02 -07:00
// Iterate through all generic content checks
if (fileContent != null)
2021-02-26 09:26:23 -08:00
{
2022-05-01 14:46:01 -07:00
Parallel.ForEach(ScanningClasses.ContentCheckClasses, contentCheckClass =>
2021-02-26 09:26:23 -08:00
{
2022-05-01 17:17:15 -07:00
string protection = contentCheckClass.CheckContents(file, fileContent, scanner.IncludeDebug);
2022-05-01 14:27:04 -07:00
if (ShouldAddProtection(contentCheckClass, scanner.ScanPackers, protection))
2022-12-15 00:13:24 -08:00
AppendToDictionary(protections, file, protection);
2022-03-15 12:39:22 -07:00
// If we have an IScannable implementation
if (contentCheckClass is IScannable scannable)
{
2022-03-15 12:39:22 -07:00
if (file != null && !string.IsNullOrEmpty(protection))
{
2022-12-27 22:11:01 -08:00
var subProtections = scannable.Scan(scanner, file);
2022-12-15 00:13:24 -08:00
PrependToKeys(subProtections, file);
AppendToDictionary(protections, subProtections);
2022-03-15 12:39:22 -07:00
}
}
});
}
2021-02-26 09:26:23 -08:00
2023-01-18 08:36:16 -08:00
// If we have an MS-DOS executable
if (wrapper is MSDOS mz)
{
// No-op
}
// If we have a New Executable
2023-01-18 08:39:27 -08:00
else if (wrapper is NewExecutable nex)
2022-03-14 10:49:02 -07:00
{
2022-05-01 17:17:15 -07:00
Parallel.ForEach(ScanningClasses.NewExecutableCheckClasses, contentCheckClass =>
2022-03-14 10:49:02 -07:00
{
// Check using custom content checks first
2022-05-01 17:17:15 -07:00
string protection = contentCheckClass.CheckNewExecutable(file, nex, scanner.IncludeDebug);
2022-05-01 14:27:04 -07:00
if (ShouldAddProtection(contentCheckClass, scanner.ScanPackers, protection))
2022-12-15 00:13:24 -08:00
AppendToDictionary(protections, file, protection);
2022-03-14 10:49:02 -07:00
// If we have an IScannable implementation
if (contentCheckClass is IScannable scannable)
{
if (file != null && !string.IsNullOrEmpty(protection))
{
2022-12-27 22:11:01 -08:00
var subProtections = scannable.Scan(scanner, file);
2022-12-15 00:13:24 -08:00
PrependToKeys(subProtections, file);
AppendToDictionary(protections, subProtections);
2022-03-14 10:49:02 -07:00
}
}
});
}
2023-01-18 08:36:16 -08:00
// If we have a Linear Executable
else if (wrapper is LinearExecutable lex)
{
// No-op
}
// If we have a Portable Executable
else if (wrapper is PortableExecutable pex)
2022-03-14 10:49:02 -07:00
{
2022-05-01 17:17:15 -07:00
Parallel.ForEach(ScanningClasses.PortableExecutableCheckClasses, contentCheckClass =>
2022-03-14 10:49:02 -07:00
{
// Check using custom content checks first
2022-05-01 17:17:15 -07:00
string protection = contentCheckClass.CheckPortableExecutable(file, pex, scanner.IncludeDebug);
2022-05-01 14:27:04 -07:00
if (ShouldAddProtection(contentCheckClass, scanner.ScanPackers, protection))
2022-12-15 00:13:24 -08:00
AppendToDictionary(protections, file, protection);
2022-03-14 10:49:02 -07:00
// If we have an IScannable implementation
if (contentCheckClass is IScannable scannable)
{
if (file != null && !string.IsNullOrEmpty(protection))
{
2022-12-27 22:11:01 -08:00
var subProtections = scannable.Scan(scanner, file);
2022-12-15 00:13:24 -08:00
PrependToKeys(subProtections, file);
AppendToDictionary(protections, subProtections);
2022-03-14 10:49:02 -07:00
}
}
});
}
2023-01-18 08:39:27 -08:00
// No other executable formats currently identified or supported
return protections;
}
2021-03-23 10:04:09 -07:00
2022-03-14 10:49:02 -07:00
#region Helpers
/// <summary>
/// Check to see if a protection should be added or not
/// </summary>
2022-05-01 14:24:46 -07:00
/// <param name="checkClass">Class that was last used to check</param>
2022-05-01 14:27:04 -07:00
/// <param name="scanPackers">Determines if packers should be included in the output</param>
/// <param name="protection">The protection result to be checked</param>
2022-05-01 14:27:04 -07:00
private bool ShouldAddProtection(object checkClass, bool scanPackers, string protection)
{
2022-05-01 14:28:28 -07:00
// If we have an invalid protection
if (string.IsNullOrWhiteSpace(protection))
return false;
// If we have a valid content check based on settings
2022-05-01 14:27:04 -07:00
if (scanPackers || !checkClass.GetType().Namespace.ToLowerInvariant().Contains("packertype"))
2022-05-01 14:28:28 -07:00
return true;
2022-03-14 10:49:02 -07:00
2022-05-01 14:28:28 -07:00
// Everything else fails
2022-03-14 10:49:02 -07:00
return false;
}
#endregion
}
}