Fix templated nullability issues

This commit is contained in:
Matt Nadareski
2023-09-17 22:37:01 -04:00
parent 1bd9f3fd88
commit a0b13a6e6f
120 changed files with 1390 additions and 442 deletions

View File

@@ -11,10 +11,14 @@ namespace BinaryObjectScanner.Packer
public class ASPack : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
@@ -28,7 +32,7 @@ namespace BinaryObjectScanner.Packer
// if (pex.EntryPointRaw != null)
// {
// var matchers = GenerateMatchers();
// string match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug);
// var match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug);
// if (!string.IsNullOrWhiteSpace(match))
// return match;
// }
@@ -37,11 +41,15 @@ namespace BinaryObjectScanner.Packer
var adataSection = pex.GetFirstSection(".adata", exact: false);
if (adataSection != null)
{
#if NET48
var adataSectionRaw = pex.GetFirstSectionData(Encoding.UTF8.GetString(adataSection.Name));
#else
var adataSectionRaw = pex.GetFirstSectionData(Encoding.UTF8.GetString(adataSection.Name!));
#endif
if (adataSectionRaw != null)
{
var matchers = GenerateMatchers();
string match = MatchUtil.GetFirstMatch(file, adataSectionRaw, matchers, includeDebug);
var match = MatchUtil.GetFirstMatch(file, adataSectionRaw, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
return match;
}

View File

@@ -11,15 +11,19 @@ namespace BinaryObjectScanner.Packer
public class AdvancedInstaller : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Get the .rdata section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".rdata");
var strs = pex.GetFirstSectionStrings(".rdata");
if (strs != null)
{
if (strs.Any(s => s.Contains("Software\\Caphyon\\Advanced Installer")))

View File

@@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.IO;
using System.IO;
using System.Linq;
using BinaryObjectScanner.Interfaces;
using SabreTools.Serialization.Wrappers;
@@ -12,10 +11,14 @@ namespace BinaryObjectScanner.Packer
public class Armadillo : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
@@ -25,14 +28,17 @@ namespace BinaryObjectScanner.Packer
return "Armadillo";
// Loop through all "extension" sections -- usually .data1 or .text1
foreach (var sectionName in pex.SectionNames.Where(s => s != null && s.EndsWith("1")))
if (pex.SectionNames != null)
{
// Get the section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(sectionName);
if (strs != null)
foreach (var sectionName in pex.SectionNames.Where(s => s != null && s.EndsWith("1")))
{
if (strs.Any(s => s.Contains("ARMDEBUG")))
return "Armadillo";
// Get the section strings, if they exist
var strs = pex.GetFirstSectionStrings(sectionName);
if (strs != null)
{
if (strs.Any(s => s.Contains("ARMDEBUG")))
return "Armadillo";
}
}
}

View File

@@ -11,15 +11,19 @@ namespace BinaryObjectScanner.Packer
public class AutoPlayMediaStudio : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Known to detect versions 5.0.0.3 - 8.1.0.0
string name = pex.ProductName;
var name = pex.ProductName;
if (name?.StartsWith("AutoPlay Media Studio", StringComparison.OrdinalIgnoreCase) == true)
return $"AutoPlay Media Studio {GetVersion(pex)}";
@@ -58,11 +62,15 @@ namespace BinaryObjectScanner.Packer
{
return null;
}
private string GetVersion(PortableExecutable pex)
{
// Check the product version explicitly
#if NET48
string version = pex.ProductVersion;
#else
string? version = pex.ProductVersion;
#endif
if (!string.IsNullOrEmpty(version))
return version;

View File

@@ -16,10 +16,14 @@ namespace BinaryObjectScanner.Packer
public class CExe : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
@@ -27,7 +31,9 @@ namespace BinaryObjectScanner.Packer
if (pex.FindResourceByNamedType("99, ").Count() == 2)
return "CExe";
var matchers = new List<ContentMatchSet>
if (pex.StubExecutableData != null)
{
var matchers = new List<ContentMatchSet>
{
new ContentMatchSet(new byte?[]
{
@@ -40,9 +46,10 @@ namespace BinaryObjectScanner.Packer
}, "CExe")
};
string match = MatchUtil.GetFirstMatch(file, pex.StubExecutableData, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
return match;
var match = MatchUtil.GetFirstMatch(file, pex.StubExecutableData, matchers, includeDebug);
if (!string.IsNullOrWhiteSpace(match))
return match;
}
return null;
}
@@ -73,12 +80,12 @@ namespace BinaryObjectScanner.Packer
try
{
// Parse into an executable again for easier extraction
PortableExecutable pex = PortableExecutable.Create(stream);
var pex = PortableExecutable.Create(stream);
if (pex == null)
return null;
// Get the first resource of type 99 with index 2
byte[] payload = pex.FindResourceByNamedType("99, 2").FirstOrDefault();
var payload = pex.FindResourceByNamedType("99, 2").FirstOrDefault();
if (payload == null || payload.Length == 0)
return null;
@@ -86,7 +93,7 @@ namespace BinaryObjectScanner.Packer
bool zlib = pex.FindResourceByNamedType("99, 1").Any();
// Create the output data buffer
byte[] data;
var data = new byte[0];
// If we had the decompression DLL included, it's zlib
if (zlib)

View File

@@ -13,7 +13,11 @@ namespace BinaryObjectScanner.Packer
public class EXEStealth : IContentCheck, IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckContents(string file, byte[] fileContent, bool includeDebug)
#else
public string? CheckContents(string file, byte[] fileContent, bool includeDebug)
#endif
{
// TODO: Obtain a sample to find where this string is in a typical executable
if (includeDebug)
@@ -38,10 +42,14 @@ namespace BinaryObjectScanner.Packer
}
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;

View File

@@ -14,10 +14,14 @@ namespace BinaryObjectScanner.Packer
public class EmbeddedExecutable : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
@@ -54,14 +58,15 @@ namespace BinaryObjectScanner.Packer
try
{
// Parse into an executable again for easier extraction
PortableExecutable pex = PortableExecutable.Create(stream);
var pex = PortableExecutable.Create(stream);
if (pex?.ResourceData == null)
return null;
// Get the resources that have an executable signature
var resources = pex.ResourceData
.Where(kvp => kvp.Value != null && kvp.Value is byte[])
.Where(kvp => (kvp.Value as byte[]).StartsWith(SabreTools.Models.MSDOS.Constants.SignatureBytes))
.Select(kvp => kvp.Value as byte[])
.Where(b => b != null && b.StartsWith(SabreTools.Models.MSDOS.Constants.SignatureBytes))
.ToList();
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
@@ -72,17 +77,19 @@ namespace BinaryObjectScanner.Packer
try
{
// Get the resource data
var resource = resources[i];
byte[] data = resource.Value as byte[];
var data = resources[i];
if (data == null)
continue;
// Create the temp filename
string tempFile = $"embedded_resource_{i}.bin";
tempFile = Path.Combine(tempPath, tempFile);
// Write the resource data to a temp file
using (Stream tempStream = File.Open(tempFile, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
using (var tempStream = File.Open(tempFile, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
{
tempStream.Write(data, 0, data.Length);
if (tempStream != null)
tempStream.Write(data, 0, data.Length);
}
}
catch (Exception ex)

View File

@@ -11,15 +11,19 @@ namespace BinaryObjectScanner.Packer
public class GenteeInstaller : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Get the .data/DATA section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
if (strs != null)
{
if (strs.Any(s => s.Contains("Gentee installer")))

View File

@@ -13,17 +13,21 @@ namespace BinaryObjectScanner.Packer
public class HyperTechCrackProof : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// This check may be overly limiting, as it excludes the sample provided to DiE (https://github.com/horsicq/Detect-It-Easy/issues/102).
// TODO: Find further samples and invesitgate if the "peC" section is only present on specific versions.
bool peCSection = pex.ContainsSection("peC", exact: true);
bool importTableMatch = (pex.Model.ImportTable?.ImportDirectoryTable?.Any(idte => idte.Name == "KeRnEl32.dLl") ?? false);
bool importTableMatch = (pex.Model.ImportTable?.ImportDirectoryTable?.Any(idte => idte?.Name == "KeRnEl32.dLl") ?? false);
if (peCSection && importTableMatch)
return "HyperTech CrackProof";

View File

@@ -12,14 +12,14 @@ namespace BinaryObjectScanner.Packer
public class InnoSetup : IExtractable, INewExecutableCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
#else
public string? CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
#endif
{
// Check we have a valid executable
if (nex == null)
return null;
// Check for "Inno" in the reserved words
if (nex.Model.Stub?.Header?.Reserved2[4] == 0x6E49 && nex.Model.Stub?.Header?.Reserved2[5] == 0x6F6E)
if (nex.Model.Stub?.Header?.Reserved2?[4] == 0x6E49 && nex.Model.Stub?.Header?.Reserved2?[5] == 0x6F6E)
{
string version = GetOldVersion(file, nex);
if (!string.IsNullOrWhiteSpace(version))
@@ -32,18 +32,22 @@ namespace BinaryObjectScanner.Packer
}
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Get the .data/DATA section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
if (strs != null)
{
string str = strs.FirstOrDefault(s => s.StartsWith("Inno Setup Setup Data"));
var str = strs.FirstOrDefault(s => s.StartsWith("Inno Setup Setup Data"));
if (str != null)
{
return str.Replace("Inno Setup Setup Data", "Inno Setup")

View File

@@ -10,14 +10,18 @@ namespace BinaryObjectScanner.Packer
public class InstallAnywhere : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
string name = pex.FileDescription;
var name= pex.FileDescription;
if (name?.StartsWith("InstallAnywhere Self Extractor", StringComparison.OrdinalIgnoreCase) == true)
return $"InstallAnywhere {GetVersion(pex)}";
@@ -57,7 +61,7 @@ namespace BinaryObjectScanner.Packer
private string GetVersion(PortableExecutable pex)
{
// Check the internal versions
string version = pex.GetInternalVersion();
var version = pex.GetInternalVersion();
if (!string.IsNullOrEmpty(version))
return version;

View File

@@ -12,15 +12,19 @@ namespace BinaryObjectScanner.Packer
{
//TODO: Add exact version detection for Windows builds, make sure versions before 3.X are detected as well, and detect the Mac builds.
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Get the .data/DATA section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
if (strs != null)
{
if (strs.Any(s => s.Contains("ViseMain")))

View File

@@ -9,14 +9,18 @@ namespace BinaryObjectScanner.Packer
public class IntelInstallationFramework : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
string name = pex.FileDescription;
var name= pex.FileDescription;
if (name?.Equals("Intel(R) Installation Framework", StringComparison.OrdinalIgnoreCase) == true
|| name?.Equals("Intel Installation Framework", StringComparison.OrdinalIgnoreCase) == true)
{

View File

@@ -12,14 +12,18 @@ namespace BinaryObjectScanner.Packer
public class MicrosoftCABSFX : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
string name = pex.InternalName;
var name= pex.InternalName;
if (name?.Equals("Wextract", StringComparison.OrdinalIgnoreCase) == true)
return $"Microsoft CAB SFX {GetVersion(pex)}";
@@ -28,7 +32,7 @@ namespace BinaryObjectScanner.Packer
return $"Microsoft CAB SFX {GetVersion(pex)}";
// Get the .data/DATA section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
if (strs != null)
{
if (strs.Any(s => s.Contains("wextract_cleanup")))
@@ -77,7 +81,7 @@ namespace BinaryObjectScanner.Packer
private string GetVersion(PortableExecutable pex)
{
// Check the internal versions
string version = pex.GetInternalVersion();
var version = pex.GetInternalVersion();
if (!string.IsNullOrWhiteSpace(version))
return $"v{version}";

View File

@@ -10,19 +10,23 @@ namespace BinaryObjectScanner.Packer
public class NSIS : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
string description = pex.AssemblyDescription;
var description = pex.AssemblyDescription;
if (!string.IsNullOrWhiteSpace(description) && description.StartsWith("Nullsoft Install System"))
return $"NSIS {description.Substring("Nullsoft Install System".Length).Trim()}";
// Get the .data/DATA section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
if (strs != null)
{
if (strs.Any(s => s.Contains("NullsoftInst")))

View File

@@ -18,10 +18,14 @@ namespace BinaryObjectScanner.Packer
{
// TODO: Find samples of NeoLite 1.X.
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;

View File

@@ -9,10 +9,14 @@ namespace BinaryObjectScanner.Packer
public class PECompact : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;

View File

@@ -9,10 +9,14 @@ namespace BinaryObjectScanner.Packer
public class PEtite : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;

View File

@@ -11,15 +11,19 @@ namespace BinaryObjectScanner.Packer
public class SetupFactory : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Known to detect versions 7.0.5.1 - 9.1.0.0
string name = pex.LegalCopyright;
var name = pex.LegalCopyright;
if (name?.StartsWith("Setup Engine", StringComparison.OrdinalIgnoreCase) == true)
return $"Setup Factory {GetVersion(pex)}";
@@ -67,7 +71,7 @@ namespace BinaryObjectScanner.Packer
private string GetVersion(PortableExecutable pex)
{
// Check the product version explicitly
string version = pex.ProductVersion;
var version = pex.ProductVersion;
if (!string.IsNullOrEmpty(version))
return version;

View File

@@ -9,10 +9,14 @@ namespace BinaryObjectScanner.Packer
public class SevenZipSFX : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;

View File

@@ -9,10 +9,14 @@ namespace BinaryObjectScanner.Packer
public class Shrinker : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;

View File

@@ -17,17 +17,21 @@ namespace BinaryObjectScanner.Packer
private static readonly Regex _upxVersionMatch = new Regex(@"^([0-9]\.[0-9]{2})$", RegexOptions.Compiled);
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Check header padding strings
if (pex.HeaderPaddingStrings?.Any() == true)
{
string match = pex.HeaderPaddingStrings.FirstOrDefault(s => s.Contains("UPX!"));
var match = pex.HeaderPaddingStrings.FirstOrDefault(s => s.Contains("UPX!"));
//if (match != null)
// return "UPX";
@@ -42,7 +46,7 @@ namespace BinaryObjectScanner.Packer
}
match = pex.HeaderPaddingStrings.FirstOrDefault(s => _upxVersionMatch.IsMatch(s));
if (pex.HeaderPaddingStrings.Any(s => s == "UPX!" && match != null))
if (match != null && pex.HeaderPaddingStrings.Any(s => s == "UPX!"))
{
var regexMatch = _upxVersionMatch.Match(match);
if (regexMatch.Success)
@@ -50,7 +54,7 @@ namespace BinaryObjectScanner.Packer
else
return "UPX (Unknown Version)";
}
else if (pex.HeaderPaddingStrings.Any(s => s == "NOS " && match != null))
else if (match != null && pex.HeaderPaddingStrings.Any(s => s == "NOS "))
{
var regexMatch = _upxVersionMatch.Match(match);
if (regexMatch.Success)

View File

@@ -12,14 +12,18 @@ namespace BinaryObjectScanner.Packer
public class WinRARSFX : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
string name = pex.AssemblyDescription;
var name = pex.AssemblyDescription;
if (name?.Contains("WinRAR archiver") == true)
return "WinRAR SFX";

View File

@@ -12,19 +12,19 @@ namespace BinaryObjectScanner.Packer
public class WinZipSFX : IExtractable, INewExecutableCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
#else
public string? CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
#endif
{
// Check we have a valid executable
if (nex == null)
return null;
// If the resident-name table doesnt exist
if (nex.Model.ResidentNameTable == null)
return null;
// Check for the WinZip name string
bool winZipNameFound = nex.Model.ResidentNameTable.Where(rnte => rnte?.NameString != null)
.Select(rnte => Encoding.ASCII.GetString(rnte.NameString))
bool winZipNameFound = nex.Model.ResidentNameTable
.Select(rnte => rnte?.NameString == null ? string.Empty : Encoding.ASCII.GetString(rnte.NameString))
.Any(s => s.Contains("WZ-SE-01"));
// If we didn't find it
@@ -32,7 +32,7 @@ namespace BinaryObjectScanner.Packer
return null;
// Try to get a known version
string version = GetNEHeaderVersion(nex);
var version = GetNEHeaderVersion(nex);
if (!string.IsNullOrWhiteSpace(version))
return $"WinZip SFX {version}";
@@ -40,17 +40,21 @@ namespace BinaryObjectScanner.Packer
}
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Check the export directory table, if it exists
if (pex.Model.ExportTable?.ExportDirectoryTable != null)
{
string version = GetPEExportDirectoryVersion(pex);
var version = GetPEExportDirectoryVersion(pex);
if (!string.IsNullOrWhiteSpace(version))
return $"WinZip SFX {version}";
}
@@ -130,7 +134,11 @@ namespace BinaryObjectScanner.Packer
/// </summary>
/// TODO: Reduce the checks to only the ones that differ between versions
/// TODO: Research to see if the versions are embedded elsewhere in these files
#if NET48
private string GetNEHeaderVersion(NewExecutable nex)
#else
private string? GetNEHeaderVersion(NewExecutable nex)
#endif
{
#region 2.0 Variants
@@ -688,10 +696,14 @@ namespace BinaryObjectScanner.Packer
/// Get the version from the PE export directory table value combinations
/// </summary>
/// TODO: Research to see if the versions are embedded elsewhere in these files
#if NET48
private string GetPEExportDirectoryVersion(PortableExecutable pex)
#else
private string? GetPEExportDirectoryVersion(PortableExecutable pex)
#endif
{
string sfxFileName = pex.Model.ExportTable.ExportDirectoryTable.Name;
uint sfxTimeDateStamp = pex.Model.ExportTable.ExportDirectoryTable.TimeDateStamp;
string sfxFileName = pex.Model.ExportTable?.ExportDirectoryTable?.Name ?? string.Empty;
uint sfxTimeDateStamp = pex.Model.ExportTable?.ExportDirectoryTable?.TimeDateStamp ?? uint.MaxValue;
string assemblyVersion = pex.AssemblyVersion ?? "Unknown Version";
// Standard

View File

@@ -14,12 +14,12 @@ namespace BinaryObjectScanner.Packer
public class WiseInstaller : IExtractable, INewExecutableCheck, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
#else
public string? CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
#endif
{
/// Check we have a valid executable
if (nex == null)
return null;
// If we match a known header
if (MatchesNEVersion(nex) != null)
return "Wise Installation Wizard Module";
@@ -44,10 +44,14 @@ namespace BinaryObjectScanner.Packer
}
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
@@ -58,7 +62,7 @@ namespace BinaryObjectScanner.Packer
// TODO: Investigate STUB32.EXE in export directory table
// Get the .data/DATA section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
var strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
if (strs != null)
{
if (strs.Any(s => s.Contains("WiseMain")))
@@ -102,12 +106,12 @@ namespace BinaryObjectScanner.Packer
try
{
// Try to parse as a New Executable
NewExecutable nex = NewExecutable.Create(stream);
var nex = NewExecutable.Create(stream);
if (nex != null)
return ExtractNewExecutable(nex, file, includeDebug);
// Try to parse as a Portable Executable
PortableExecutable pex = PortableExecutable.Create(stream);
var pex = PortableExecutable.Create(stream);
if (pex != null)
return ExtractPortableExecutable(pex, file, includeDebug);
@@ -125,7 +129,11 @@ namespace BinaryObjectScanner.Packer
/// </summary>
/// <param name="nex">New executable to check</param>
/// <returns>True if it matches a known version, false otherwise</returns>
#if NET48
private FormatProperty MatchesNEVersion(NewExecutable nex)
#else
private FormatProperty? MatchesNEVersion(NewExecutable nex)
#endif
{
// TODO: Offset is _not_ the EXE header address, rather where the data starts. Fix this.
switch (nex.Model.Stub?.Header?.NewExeHeaderAddr)
@@ -182,7 +190,11 @@ namespace BinaryObjectScanner.Packer
/// </summary>
/// <param name="pex">Portable executable to check</param>
/// <returns>True if it matches a known version, false otherwise</returns>
#if NET48
private FormatProperty GetPEFormat(PortableExecutable pex)
#else
private FormatProperty? GetPEFormat(PortableExecutable pex)
#endif
{
if (pex.OverlayAddress == 0x6e00
&& pex.GetFirstSection(".text")?.VirtualSize == 0x3cf4
@@ -229,7 +241,11 @@ namespace BinaryObjectScanner.Packer
/// <param name="file">Path to the input file</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>True if it matches a known version, false otherwise</returns>
#if NET48
private string ExtractNewExecutable(NewExecutable nex, string file, bool includeDebug)
#else
private string? ExtractNewExecutable(NewExecutable nex, string file, bool includeDebug)
#endif
{
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);
@@ -268,7 +284,11 @@ namespace BinaryObjectScanner.Packer
/// <param name="file">Path to the input file</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>True if it matches a known version, false otherwise</returns>
#if NET48
private string ExtractPortableExecutable(PortableExecutable pex, string file, bool includeDebug)
#else
private string? ExtractPortableExecutable(PortableExecutable pex, string file, bool includeDebug)
#endif
{
try
{
@@ -279,7 +299,7 @@ namespace BinaryObjectScanner.Packer
// Get the overlay data for easier reading
int overlayOffset = 0, dataStart = 0;
byte[] overlayData = pex.OverlayData;
var overlayData = pex.OverlayData;
if (overlayData == null)
return null;
@@ -333,8 +353,8 @@ namespace BinaryObjectScanner.Packer
int offsetReal = overlayOffset;
// If the first entry is PKZIP, we assume it's an embedded zipfile
byte[] magic = overlayData.ReadBytes(ref overlayOffset, 4); overlayOffset -= 4;
bool pkzip = magic.StartsWith(new byte?[] { (byte)'P', (byte)'K' });
var magic = overlayData.ReadBytes(ref overlayOffset, 4); overlayOffset -= 4;
bool pkzip = magic?.StartsWith(new byte?[] { (byte)'P', (byte)'K' }) ?? false;
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempPath);

View File

@@ -10,15 +10,19 @@ namespace BinaryObjectScanner.Packer
public class dotFuscator : IExtractable, IPortableExecutableCheck
{
/// <inheritdoc/>
#if NET48
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#else
public string? CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
#endif
{
// Get the sections from the executable, if possible
var sections = pex?.Model.SectionTable;
var sections = pex.Model.SectionTable;
if (sections == null)
return null;
// Get the .text section strings, if they exist
List<string> strs = pex.GetFirstSectionStrings(".text");
var strs = pex.GetFirstSectionStrings(".text");
if (strs != null)
{
if (strs.Any(s => s.Contains("DotfuscatorAttribute")))