mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-07-12 11:56:56 +00:00
Use UPX as a guinea pig for new exe handling
This commit is contained in:
@@ -1,53 +1,60 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using BurnOutSharp.ExecutableType.Microsoft;
|
||||
using BurnOutSharp.Matching;
|
||||
using BurnOutSharp.Tools;
|
||||
|
||||
namespace BurnOutSharp.PackerType
|
||||
{
|
||||
public class UPX : IContentCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public List<ContentMatchSet> GetContentMatchSets()
|
||||
{
|
||||
return new List<ContentMatchSet>
|
||||
{
|
||||
// UPX!
|
||||
new ContentMatchSet(new byte?[] { 0x55, 0x50, 0x58, 0x21 }, GetVersion, "UPX"),
|
||||
|
||||
// NOS
|
||||
new ContentMatchSet(
|
||||
new ContentMatch(new byte?[] { 0x4E, 0x4F, 0x53, 0x20 }, end: 2048),
|
||||
GetVersion,
|
||||
"UPX (NOS Variant)"),
|
||||
|
||||
new ContentMatchSet(
|
||||
new List<byte?[]>
|
||||
{
|
||||
// UPX0
|
||||
new byte?[] { 0x55, 0x50, 0x58, 0x30 },
|
||||
|
||||
// UPX1
|
||||
new byte?[] { 0x55, 0x50, 0x58, 0x31 },
|
||||
},
|
||||
"UPX (Unknown Version)"
|
||||
),
|
||||
|
||||
new ContentMatchSet(
|
||||
new List<byte?[]>
|
||||
{
|
||||
// NOS0
|
||||
new byte?[] { 0x4E, 0x4F, 0x53, 0x30 },
|
||||
|
||||
// NOS1
|
||||
new byte?[] { 0x4E, 0x4F, 0x53, 0x31 },
|
||||
},
|
||||
"UPX (NOS Variant) (Unknown Version)"
|
||||
),
|
||||
};
|
||||
}
|
||||
public List<ContentMatchSet> GetContentMatchSets() => null;
|
||||
|
||||
/// <inheritdoc/>
|
||||
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
|
||||
PEExecutable pex = PEExecutable.Deserialize(fileContent, 0);
|
||||
var sections = pex?.SectionHeaders;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Standard UPX
|
||||
int foundPosition = FindData(fileContent, sections, "UPX");
|
||||
if (foundPosition > -1)
|
||||
{
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
// UPX!
|
||||
new ContentMatchSet(
|
||||
new ContentMatch(new byte?[] { 0x55, 0x50, 0x58, 0x21 }, end: foundPosition),
|
||||
GetVersion,
|
||||
"UPX"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(file, fileContent, matchers, includeDebug);
|
||||
}
|
||||
|
||||
// NOS Variant
|
||||
foundPosition = FindData(fileContent, sections, "NOS");
|
||||
if (foundPosition > -1)
|
||||
{
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
// NOS
|
||||
new ContentMatchSet(
|
||||
new ContentMatch(new byte?[] { 0x4E, 0x4F, 0x53, 0x20 }, end: foundPosition),
|
||||
GetVersion,
|
||||
"UPX (NOS Variant)"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(file, fileContent, matchers, includeDebug);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static string GetVersion(string file, byte[] fileContent, List<int> positions)
|
||||
{
|
||||
@@ -66,5 +73,26 @@ namespace BurnOutSharp.PackerType
|
||||
return "(Unknown Version)";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find the location of the first matched section, if possible
|
||||
/// </summary>
|
||||
/// <param name="fileContent">Byte array representing the file contents</param>
|
||||
/// <param name="sections">Array of sections to check against</param>
|
||||
/// <param name="sectionPrefix">Prefix of the sections to check for</param>
|
||||
/// <returns>Real address of the section data, -1 on error</returns>
|
||||
private int FindData(byte[] fileContent, IMAGE_SECTION_HEADER[] sections, string sectionPrefix)
|
||||
{
|
||||
// Get the two matching sections, if possible
|
||||
var firstSection = sections.FirstOrDefault(s => Encoding.ASCII.GetString(s.Name).StartsWith($"{sectionPrefix}0"));
|
||||
var secondSection = sections.FirstOrDefault(s => Encoding.ASCII.GetString(s.Name).StartsWith($"{sectionPrefix}1"));
|
||||
|
||||
// If either section is null, we can't do anything
|
||||
if (firstSection == null || secondSection == null)
|
||||
return -1;
|
||||
|
||||
// Return the first section address
|
||||
return (int)EVORE.ConvertVirtualAddress(firstSection.VirtualAddress, sections);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user