From 53088b4e60c86abe9fefeda23322e4e04f4beab6 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Fri, 3 Sep 2021 13:26:52 -0700 Subject: [PATCH] Convert SmartE to section based --- BurnOutSharp/ProtectionType/SmartE.cs | 77 ++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 12 deletions(-) diff --git a/BurnOutSharp/ProtectionType/SmartE.cs b/BurnOutSharp/ProtectionType/SmartE.cs index 3d9136f4..b0c8c8c6 100644 --- a/BurnOutSharp/ProtectionType/SmartE.cs +++ b/BurnOutSharp/ProtectionType/SmartE.cs @@ -1,6 +1,10 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; +using System.Linq; +using System.Text; +using BurnOutSharp.ExecutableType.Microsoft; +using BurnOutSharp.ExecutableType.Microsoft.Headers; using BurnOutSharp.Matching; namespace BurnOutSharp.ProtectionType @@ -8,26 +12,54 @@ namespace BurnOutSharp.ProtectionType public class SmartE : IContentCheck, IPathCheck { /// - public List GetContentMatchSets() - { - return new List - { - // BITARTS - new ContentMatchSet(new byte?[] { 0x42, 0x49, 0x54, 0x41, 0x52, 0x54, 0x53 }, "SmartE"), - }; - } + public List GetContentMatchSets() => null; /// - public string CheckContents(string file, byte[] fileContent, bool includeDebug = false) => null; + public string CheckContents(string file, byte[] fileContent, bool includeDebug = false) + { + // Get the sections from the executable, if possible + PortableExecutable pex = PortableExecutable.Deserialize(fileContent, 0); + var sections = pex?.SectionTable; + if (sections == null) + return null; + + // Get the .edata section, if it exists + var edataSection = sections.FirstOrDefault(s => Encoding.ASCII.GetString(s.Name).StartsWith(".edata")); + string match = GetMatchForSection(edataSection, file, fileContent, includeDebug); + if (!string.IsNullOrWhiteSpace(match)) + return match; + + // Get the .idata section, if it exists + var idataSection = sections.FirstOrDefault(s => Encoding.ASCII.GetString(s.Name).StartsWith(".idata")); + match = GetMatchForSection(idataSection, file, fileContent, includeDebug); + if (!string.IsNullOrWhiteSpace(match)) + return match; + + // Get the .rdata section, if it exists + var rdataSection = sections.FirstOrDefault(s => Encoding.ASCII.GetString(s.Name).StartsWith(".rdata")); + match = GetMatchForSection(rdataSection, file, fileContent, includeDebug); + if (!string.IsNullOrWhiteSpace(match)) + return match; + + // Get the .tls section, if it exists + var tlsSection = sections.FirstOrDefault(s => Encoding.ASCII.GetString(s.Name).StartsWith(".tls")); + match = GetMatchForSection(tlsSection, file, fileContent, includeDebug); + if (!string.IsNullOrWhiteSpace(match)) + return match; + + return null; + } /// public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { - // TODO: Verify if these are OR or AND var matchers = new List { - new PathMatchSet(new PathMatch($"{Path.DirectorySeparatorChar}00001.TMP", useEndsWith: true), "SmartE"), - new PathMatchSet(new PathMatch($"{Path.DirectorySeparatorChar}00002.TMP", useEndsWith: true), "SmartE"), + new PathMatchSet(new List + { + new PathMatch($"{Path.DirectorySeparatorChar}00001.TMP", useEndsWith: true), + new PathMatch($"{Path.DirectorySeparatorChar}00002.TMP", useEndsWith: true) + }, "SmartE"), }; return MatchUtil.GetAllMatches(files, matchers, any: true); @@ -44,5 +76,26 @@ namespace BurnOutSharp.ProtectionType return MatchUtil.GetFirstMatch(path, matchers, any: true); } + + /// + /// Check a section for the SmartE string(s) + /// + private string GetMatchForSection(SectionHeader section, string file, byte[] fileContent, bool includeDebug) + { + if (section == null) + return null; + + int sectionAddr = (int)section.PointerToRawData; + int sectionEnd = sectionAddr + (int)section.VirtualSize; + var matchers = new List + { + // BITARTS + new ContentMatchSet( + new ContentMatch(new byte?[] { 0x42, 0x49, 0x54, 0x41, 0x52, 0x54, 0x53 }, start: sectionAddr, end: sectionEnd), + "SmartE"), + }; + + return MatchUtil.GetFirstMatch(file, fileContent, matchers, includeDebug); + } } }