mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-07-12 03:46:49 +00:00
Move packer scans to their own library
This commit is contained in:
659
BinaryObjectScanner.Packer/ASPack.cs
Normal file
659
BinaryObjectScanner.Packer/ASPack.cs
Normal file
@@ -0,0 +1,659 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Matching;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction
|
||||
public class ASPack : IExtractable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Get the .aspack section, if it exists
|
||||
bool aspackSection = pex.ContainsSection(".aspack", exact: true);
|
||||
if (aspackSection)
|
||||
return "ASPack 2.29";
|
||||
|
||||
// TODO: Re-enable all Entry Point checks after implementing
|
||||
// Use the entry point data, if it exists
|
||||
// if (pex.EntryPointRaw != null)
|
||||
// {
|
||||
// var matchers = GenerateMatchers();
|
||||
// string match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug);
|
||||
// if (!string.IsNullOrWhiteSpace(match))
|
||||
// return match;
|
||||
// }
|
||||
|
||||
// Get the .adata* section, if it exists
|
||||
var adataSection = pex.GetFirstSection(".adata", exact: false);
|
||||
if (adataSection != null)
|
||||
{
|
||||
var adataSectionRaw = pex.GetFirstSectionData(Encoding.UTF8.GetString(adataSection.Name));
|
||||
if (adataSectionRaw != null)
|
||||
{
|
||||
var matchers = GenerateMatchers();
|
||||
string match = MatchUtil.GetFirstMatch(file, adataSectionRaw, matchers, includeDebug);
|
||||
if (!string.IsNullOrWhiteSpace(match))
|
||||
return match;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate the set of matchers used for each section
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private List<ContentMatchSet> GenerateMatchers()
|
||||
{
|
||||
return new List<ContentMatchSet>
|
||||
{
|
||||
#region No Wildcards (Long)
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0x92, 0x1A, 0x44, 0x00, 0xB8, 0x8C, 0x1A,
|
||||
0x44, 0x00, 0x03, 0xC5, 0x2B, 0x85, 0xCD, 0x1D,
|
||||
0x44, 0x00, 0x89, 0x85, 0xD9, 0x1D, 0x44, 0x00,
|
||||
0x80, 0xBD, 0xC4, 0x1D, 0x44,
|
||||
}, "ASPack 1.00b -> Solodovnikov Alexey"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0xD2, 0x2A, 0x44, 0x00, 0xB8, 0xCC, 0x2A,
|
||||
0x44, 0x00, 0x03, 0xC5, 0x2B, 0x85, 0xA5, 0x2E,
|
||||
0x44, 0x00, 0x89, 0x85, 0xB1, 0x2E, 0x44, 0x00,
|
||||
0x80, 0xBD, 0x9C, 0x2E, 0x44, 0x00, 0x00, 0x75,
|
||||
0x15, 0xFE, 0x85, 0x9C, 0x2E, 0x44, 0x00, 0xE8,
|
||||
0x1D, 0x00, 0x00, 0x00, 0xE8, 0xE4, 0x01, 0x00,
|
||||
0x00, 0xE8, 0x7A, 0x02, 0x00, 0x00, 0x8B, 0x85,
|
||||
0x9D, 0x2E, 0x44, 0x00, 0x03, 0x85, 0xB1, 0x2E,
|
||||
0x44, 0x00, 0x89, 0x44, 0x24, 0x1C, 0x61, 0xFF
|
||||
}, "ASPack 1.01b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0xD2, 0x2A, 0x44, 0x00, 0xB8, 0xCC, 0x2A,
|
||||
0x44, 0x00, 0x03, 0xC5, 0x2B, 0x85, 0xA5, 0x2E,
|
||||
0x44, 0x00, 0x89, 0x85, 0xB1, 0x2E, 0x44, 0x00,
|
||||
0x80, 0xBD, 0x9C, 0x2E, 0x44
|
||||
}, "ASPack 1.01b -> Solodovnikov Alexey"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0x96, 0x78, 0x43, 0x00, 0xB8, 0x90, 0x78,
|
||||
0x43, 0x00, 0x03, 0xC5, 0x2B, 0x85, 0x7D, 0x7C,
|
||||
0x43, 0x00, 0x89, 0x85, 0x89, 0x7C, 0x43, 0x00,
|
||||
0x80, 0xBD, 0x74, 0x7C, 0x43, 0x00, 0x00, 0x75,
|
||||
0x15, 0xFE, 0x85, 0x74, 0x7C, 0x43, 0x00, 0xE8,
|
||||
0x1D, 0x00, 0x00, 0x00, 0xE8, 0xF7, 0x01, 0x00,
|
||||
0x00, 0xE8, 0x8E, 0x02, 0x00, 0x00, 0x8B, 0x85,
|
||||
0x75, 0x7C, 0x43, 0x00, 0x03, 0x85, 0x89, 0x7C,
|
||||
0x43, 0x00, 0x89, 0x44, 0x24, 0x1C, 0x61, 0xFF
|
||||
}, "ASPack 1.02b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0x96, 0x78, 0x43, 0x00, 0xB8, 0x90, 0x78,
|
||||
0x43, 0x00, 0x03, 0xC5, 0x2B, 0x85, 0x7D, 0x7C,
|
||||
0x43, 0x00, 0x89, 0x85, 0x89, 0x7C, 0x43, 0x00,
|
||||
0x80, 0xBD, 0x74, 0x7C, 0x43, 0x00, 0x00, 0x75,
|
||||
0x15, 0xFE, 0x85, 0x74, 0x7C, 0x43
|
||||
}, "ASPack 1.02b -> Solodovnikov Alexey"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0x8A, 0x1C, 0x40, 0x00, 0xB9, 0x9E, 0x00,
|
||||
0x00, 0x00, 0x8D, 0xBD, 0x4C, 0x23, 0x40, 0x00,
|
||||
0x8B, 0xF7, 0x33
|
||||
}, "ASPack 1.02b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0x96, 0x78, 0x43, 0x00, 0xB8, 0x90, 0x78,
|
||||
0x43, 0x00, 0x03, 0xC5
|
||||
}, "ASPack 1.02b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0xAE, 0x98, 0x43, 0x00, 0xB8, 0xA8, 0x98,
|
||||
0x43, 0x00, 0x03, 0xC5, 0x2B, 0x85, 0x18, 0x9D,
|
||||
0x43, 0x00, 0x89, 0x85, 0x24, 0x9D, 0x43, 0x00,
|
||||
0x80, 0xBD, 0x0E, 0x9D, 0x43
|
||||
}, "ASPack 1.03b -> Solodovnikov Alexey"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0xCE, 0x3A, 0x44, 0x00, 0xB8, 0xC8, 0x3A,
|
||||
0x44, 0x00, 0x03, 0xC5, 0x2B, 0x85, 0xB5, 0x3E,
|
||||
0x44, 0x00, 0x89, 0x85, 0xC1, 0x3E, 0x44, 0x00,
|
||||
0x80, 0xBD, 0xAC, 0x3E, 0x44
|
||||
}, "ASPack 1.05b -> Solodovnikov Alexey"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0xEA, 0xA8, 0x43, 0x00, 0xB8, 0xE4, 0xA8,
|
||||
0x43, 0x00, 0x03, 0xC5, 0x2B, 0x85, 0x78, 0xAD,
|
||||
0x43, 0x00, 0x89, 0x85, 0x84, 0xAD, 0x43, 0x00,
|
||||
0x80, 0xBD, 0x6E, 0xAD, 0x43, 0x00, 0x00, 0x75,
|
||||
0x15, 0xFE, 0x85, 0x6E, 0xAD, 0x43, 0x00, 0xE8,
|
||||
0x1D, 0x00, 0x00, 0x00, 0xE8, 0x73, 0x02, 0x00,
|
||||
0x00, 0xE8, 0x0A, 0x03, 0x00, 0x00, 0x8B, 0x85,
|
||||
0x70, 0xAD, 0x43, 0x00, 0x03, 0x85, 0x84, 0xAD,
|
||||
0x43, 0x00, 0x89, 0x44, 0x24, 0x1C, 0x61, 0xFF
|
||||
}, "ASPack 1.06.01b (DLL)"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0xEA, 0xA8, 0x43, 0x00, 0xB8, 0xE4, 0xA8,
|
||||
0x43, 0x00, 0x03, 0xC5, 0x2B, 0x85, 0x78, 0xAD,
|
||||
0x43, 0x00, 0x89, 0x85, 0x84, 0xAD, 0x43, 0x00,
|
||||
0x80, 0xBD, 0x6E, 0xAD, 0x43, 0x00, 0x00, 0x75,
|
||||
0x15, 0xFE, 0x85, 0x6E, 0xAD, 0x43
|
||||
}, "ASPack 1.06.01b -> Solodovnikov Alexey"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0x3E, 0xD9, 0x43, 0x00, 0xB8, 0x38, 0xD9,
|
||||
0x43, 0x00, 0x03, 0xC5, 0x2B, 0x85, 0x0B, 0xDE,
|
||||
0x43, 0x00, 0x89, 0x85, 0x17, 0xDE, 0x43, 0x00,
|
||||
0x80, 0xBD, 0x01, 0xDE, 0x43, 0x00, 0x00, 0x75,
|
||||
0x15, 0xFE, 0x85, 0x01, 0xDE, 0x43, 0x00, 0xE8,
|
||||
0x1D, 0x00, 0x00, 0x00, 0xE8, 0x79, 0x02, 0x00,
|
||||
0x00, 0xE8, 0x12, 0x03, 0x00, 0x00, 0x8B, 0x85,
|
||||
0x03, 0xDE, 0x43, 0x00, 0x03, 0x85, 0x17, 0xDE,
|
||||
0x43, 0x00, 0x89, 0x44, 0x24, 0x1C, 0x61, 0xFF
|
||||
}, "ASPack 1.07b (DLL)"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xEB, 0x03, 0x5D, 0xFF, 0xE5, 0xE8, 0xF8,
|
||||
0xFF, 0xFF, 0xFF, 0x81, 0xED, 0x1B, 0x6A, 0x44,
|
||||
0x00, 0xBB, 0x10, 0x6A, 0x44, 0x00, 0x03, 0xDD,
|
||||
0x2B, 0x9D, 0x2A
|
||||
}, "ASPack 1.08"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0x0A, 0x4A, 0x44, 0x00, 0xBB, 0x04, 0x4A,
|
||||
0x44, 0x00, 0x03, 0xDD, 0x2B, 0x9D, 0xB1, 0x50,
|
||||
0x44, 0x00, 0x83, 0xBD, 0xAC, 0x50, 0x44, 0x00,
|
||||
0x00, 0x89, 0x9D, 0xBB, 0x4E, 0x44, 0x00, 0x0F,
|
||||
0x85, 0x17, 0x05, 0x00, 0x00, 0x8D, 0x85, 0xD1,
|
||||
0x50, 0x44, 0x00, 0x50, 0xFF, 0x95, 0x94, 0x51,
|
||||
0x44, 0x00, 0x89, 0x85, 0xCD, 0x50, 0x44, 0x00,
|
||||
0x8B, 0xF8, 0x8D, 0x9D, 0xDE, 0x50, 0x44, 0x00,
|
||||
0x53, 0x50, 0xFF, 0x95, 0x90, 0x51, 0x44, 0x00
|
||||
}, "ASPack 1.08.03"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0x0A, 0x4A, 0x44, 0x00, 0xBB, 0x04, 0x4A,
|
||||
0x44, 0x00, 0x03, 0xDD, 0x2B, 0x9D, 0xB1, 0x50,
|
||||
0x44, 0x00, 0x83, 0xBD, 0xAC, 0x50, 0x44, 0x00,
|
||||
0x00, 0x89, 0x9D, 0xBB, 0x4E
|
||||
}, "ASPack 1.08.03"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0x0A, 0x4A, 0x44, 0x00, 0xBB, 0x04, 0x4A,
|
||||
0x44, 0x00, 0x03, 0xDD
|
||||
}, "ASPack 1.08.03"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x72, 0x05, 0x00, 0x00, 0xEB, 0x33,
|
||||
0x87, 0xDB, 0x90, 0x00
|
||||
}, "ASPack 2.00.01"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x03, 0x00, 0x00, 0x00, 0xE9, 0xEB,
|
||||
0x04, 0x5D, 0x45, 0x55, 0xC3, 0xE8, 0x01, 0x00,
|
||||
0x00, 0x00, 0xEB, 0x5D, 0xBB, 0xED, 0xFF, 0xFF,
|
||||
0xFF, 0x03, 0xDD, 0x81, 0xEB
|
||||
}, "ASPack 2.1"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x02, 0x00, 0x00, 0x00, 0xEB, 0x09,
|
||||
0x5D, 0x55, 0x81, 0xED, 0x39, 0x39, 0x44, 0x00,
|
||||
0xC3, 0xE9, 0x3D, 0x04, 0x00, 0x00
|
||||
}, "ASPack 2.11b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x02, 0x00, 0x00, 0x00, 0xEB, 0x09,
|
||||
0x5D, 0x55
|
||||
}, "ASPack 2.11b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x02, 0x00, 0x00, 0x00, 0xEB, 0x09,
|
||||
0x5D, 0x55, 0x81, 0xED, 0x39, 0x39, 0x44, 0x00,
|
||||
0xC3, 0xE9, 0x59, 0x04, 0x00, 0x00
|
||||
}, "ASPack 2.11c"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x02, 0x00, 0x00, 0x00, 0xCD, 0x20,
|
||||
0xE8, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x2B, 0xC9,
|
||||
0x58, 0x74, 0x02
|
||||
}, "ASPack 2.11d"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x03, 0x00, 0x00, 0x00, 0xE9, 0xEB,
|
||||
0x04, 0x5D, 0x45, 0x55, 0xC3, 0xE8, 0x01
|
||||
}, "ASPack 2.12"),
|
||||
|
||||
#endregion
|
||||
|
||||
#region Wildcards (Long)
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
|
||||
0xED, 0x3E, 0xD9, 0x43, null, 0xB8, 0x38, null,
|
||||
null, null, 0x03, 0xC5, 0x2B, 0x85, 0x0B, 0xDE,
|
||||
0x43, null, 0x89, 0x85, 0x17, 0xDE, 0x43, null,
|
||||
0x80, 0xBD, 0x01, 0xDE, 0x43, null, null, 0x75,
|
||||
0x15, 0xFE, 0x85, 0x01, 0xDE, 0x43, null, 0xE8,
|
||||
0x1D, null, null, null, 0xE8, 0x79, 0x02, null,
|
||||
null, 0xE8, 0x12, 0x03, null, null, 0x8B, 0x85,
|
||||
0x03, 0xDE, 0x43, null, 0x03, 0x85, 0x17, 0xDE,
|
||||
0x43, null, 0x89, 0x44, 0x24, 0x1C, 0x61, 0xFF
|
||||
}, "ASPack 1.00b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
|
||||
0xED, 0xD2, 0x2A, 0x44, null, 0xB8, 0xCC, 0x2A,
|
||||
0x44, null, 0x03, 0xC5, 0x2B, 0x85, 0xA5, 0x2E,
|
||||
0x44, null, 0x89, 0x85, 0xB1, 0x2E, 0x44, null,
|
||||
0x80, 0xBD, 0x9C, 0x2E, 0x44
|
||||
}, "ASPack 1.01b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
|
||||
0xED, 0xCE, 0x3A, 0x44, null, 0xB8, 0xC8, 0x3A,
|
||||
0x44, null, 0x03, 0xC5, 0x2B, 0x85, 0xB5, 0x3E,
|
||||
0x44, null, 0x89, 0x85, 0xC1, 0x3E, 0x44, null,
|
||||
0x80, 0xBD, 0xAC, 0x3E, 0x44
|
||||
}, "ASPack 1.01b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, 0x3E, 0xD9, 0x43, 0x00, 0xB8, 0x38, null,
|
||||
null, 0x00, 0x03, 0xC5, 0x2B, 0x85, 0x0B, 0xDE,
|
||||
0x43, 0x00, 0x89, 0x85, 0x17, 0xDE, 0x43, 0x00,
|
||||
0x80, 0xBD, 0x01, 0xDE, 0x43, 0x00, 0x00, 0x75,
|
||||
0x15, 0xFE, 0x85, 0x01, 0xDE, 0x43, 0x00, 0xE8,
|
||||
0x1D, 0x00, 0x00, 0x00, 0xE8, 0x79, 0x02, 0x00,
|
||||
0x00, 0xE8, 0x12, 0x03, 0x00, 0x00, 0x8B, 0x85,
|
||||
0x03, 0xDE, 0x43, 0x00, 0x03, 0x85, 0x17, 0xDE,
|
||||
0x43, 0x00, 0x89, 0x44, 0x24, 0x1C, 0x61, 0xFF
|
||||
}, "ASPack 1.02a -> Solodovnikov Alexey"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
|
||||
0xED, 0x06, null, null, null, 0x64, 0xA0, 0x23
|
||||
}, "ASPack 1.02a"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
|
||||
0xED, 0x96, 0x78, 0x43, null, 0xB8, 0x90, 0x78,
|
||||
0x43, null, 0x03, 0xC5, 0x2B, 0x85, 0x7D, 0x7C,
|
||||
0x43, null, 0x89, 0x85, 0x89, 0x7C, 0x43, null,
|
||||
0x80, 0xBD, 0x74, 0x7C, 0x43
|
||||
}, "ASPack 1.02b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
|
||||
0xED, 0xAE, 0x98, 0x43, null, 0xB8, 0xA8, 0x98,
|
||||
0x43, null, 0x03, 0xC5, 0x2B, 0x85, 0x18, 0x9D,
|
||||
0x43, null, 0x89, 0x85, 0x24, 0x9D, 0x43, null,
|
||||
0x80, 0xBD, 0x0E, 0x9D, 0x43
|
||||
}, "ASPack 1.03b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
|
||||
0xED, null, null, null, null, 0xE8, 0x0D, null,
|
||||
null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, 0x58
|
||||
}, "ASPack 1.03b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81,
|
||||
0xED, null, null, null, 0x00, 0xB8, null, null,
|
||||
null, 0x00, 0x03, 0xC5, 0x2B, 0x85, null, 0x12,
|
||||
0x9D, null, 0x89, 0x85, 0x1E, 0x9D, null, 0x00,
|
||||
0x80, 0xBD, 0x08, 0x9D, null, 0x00, 0x00
|
||||
}, "ASPack 1.04b -> Solodovnikov Alexey"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
|
||||
0xED, null, null, null, null, 0xB8, null, null,
|
||||
null, null, 0x03, 0xC5, 0x2B, 0x85, null, 0x12,
|
||||
0x9D, null, 0x89, 0x85, 0x1E, 0x9D, null, null,
|
||||
0x80, 0xBD, 0x08, 0x9D
|
||||
}, "ASPack 1.04b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
|
||||
0xED, null, null, null, null, 0xB8, null, null,
|
||||
null, null, 0x03, 0xC5, 0x2B, 0x85, null, 0x0B,
|
||||
0xDE, null, 0x89, 0x85, 0x17, 0xDE, null, null,
|
||||
0x80, 0xBD, 0x01, 0xDE
|
||||
}, "ASPack 1.04b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
|
||||
0xED, 0xEA, 0xA8, 0x43, null, 0xB8, 0xE4, 0xA8,
|
||||
0x43, null, 0x03, 0xC5, 0x2B, 0x85, 0x78, 0xAD,
|
||||
0x43, null, 0x89, 0x85, 0x84, 0xAD, 0x43, null,
|
||||
0x80, 0xBD, 0x6E, 0xAD, 0x43
|
||||
}, "ASPack 1.06.1b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x90, 0x61, 0xBE, null, null, null, null, 0x8D,
|
||||
0xBE, null, null, null, null, 0x57, 0x83, 0xCD,
|
||||
0xFF
|
||||
}, "ASPack 1.06.1b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, null,
|
||||
null, null, null, null, null, 0xB8, null, null,
|
||||
null, null, 0x03, 0xC5
|
||||
}, "ASPack 1.07b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, null, null, null, null, 0x5D, 0x81,
|
||||
0xED, null, null, null, null, 0x60, 0xE8, 0x2B,
|
||||
0x03, 0x00, 0x00
|
||||
}, "ASPack 1.07b"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xEB, 0x0A, 0x5D, 0xEB, 0x02, 0xFF, 0x25,
|
||||
0x45, 0xFF, 0xE5, 0xE8, 0xE9, 0xE8, 0xF1, 0xFF,
|
||||
0xFF, 0xFF, 0xE9, 0x81, null, null, null, 0x44,
|
||||
0x00, 0xBB, 0x10, null, 0x44, 0x00, 0x03, 0xDD,
|
||||
0x2B, 0x9D
|
||||
}, "ASPack 1.08.01"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xEB, 0x0A, 0x5D, 0xEB, 0x02, 0xFF, 0x25,
|
||||
0x45, 0xFF, 0xE5, 0xE8, 0xE9, 0xE8, 0xF1, 0xFF,
|
||||
0xFF, 0xFF, 0xE9, 0x81, null, null, null, 0x44,
|
||||
null, 0xBB, 0x10, null, 0x44, null, 0x03, 0xDD,
|
||||
0x2B, 0x9D
|
||||
}, "ASPack 1.08.01"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xEB, 0x0A, 0x5D, 0xEB, 0x02, 0xFF, 0x25,
|
||||
0x45, 0xFF, 0xE5, 0xE8, 0xE9, 0xE8, 0xF1, 0xFF,
|
||||
0xFF, 0xFF, 0xE9, 0x81, 0xED, 0x23, 0x6A, 0x44,
|
||||
0x00, 0xBB, 0x10, null, 0x44, 0x00, 0x03, 0xDD,
|
||||
0x2B, 0x9D, 0x72
|
||||
}, "ASPack 1.08.02"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, null,
|
||||
null, null, null, null, null, 0xBB, null, null,
|
||||
null, null, 0x03, 0xDD, 0x2B, 0x9D, 0xB1, 0x50,
|
||||
0x44, 0x00, 0x83, 0xBD, 0xAC, 0x50, 0x44, 0x00,
|
||||
0x00, 0x89, 0x9D, 0xBB, 0x4E
|
||||
}, "ASPack 1.08.03"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, null,
|
||||
null, null, null, null, null, 0xBB, null, null,
|
||||
null, null, 0x03, 0xDD
|
||||
}, "ASPack 1.08.03"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x55, 0x57, 0x51, 0x53, 0xE8, null, null, null,
|
||||
null, 0x5D, 0x8B, 0xC5, 0x81, 0xED, null, null,
|
||||
null, null, 0x2B, 0x85, null, null, null, null,
|
||||
0x83, 0xE8, 0x09, 0x89, 0x85, null, null, null,
|
||||
null, 0x0F, 0xB6
|
||||
}, "ASPack 1.08.03"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE9, null, null, null, null, 0xEF, 0x40,
|
||||
0x03, 0xA7, 0x07, 0x8F, 0x07, 0x1C, 0x37, 0x5D,
|
||||
0x43, 0xA7, 0x04, 0xB9, 0x2C, 0x3A
|
||||
}, "ASPack 1.08.x"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x02, 0x00, 0x00, 0x00, 0xEB, 0x09,
|
||||
0x5D, 0x55, 0x81, 0xED, 0x39, 0x39, 0x44, 0x00,
|
||||
0xC3, 0xE9, null, 0x04, 0x00, 0x00
|
||||
}, "ASPack 2.11.x -> Alexey Solodovnikov"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
null, 0xE8, 0x03, 0x00, 0x00, 0x00, 0xE9, 0xEB,
|
||||
0x04, 0x5D, 0x45, 0x55, 0xC3, 0xE8, 0x01
|
||||
}, "ASPack 2.12 (without Poly) -> Solodovnikov Alexey"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
null, 0x60, 0xE8, 0x03, 0x00, 0x00, 0x00, 0xE9,
|
||||
0xEB, 0x04, 0x5D, 0x45, 0x55, 0xC3, 0xE8, 0x01,
|
||||
0x00, 0x00, 0x00, 0xEB, 0x5D, 0xBB, 0xEC, 0xFF,
|
||||
0xFF, 0xFF, 0x03, 0xDD, 0x81, 0xEB, 0x00, null,
|
||||
null, 0x00, 0x83, 0xBD, 0x22, 0x04, 0x00, 0x00,
|
||||
0x00, 0x89, 0x9D, 0x22, 0x04, 0x00, 0x00, 0x0F,
|
||||
0x85, 0x65, 0x03, 0x00, 0x00, 0x8D, 0x85, 0x2E,
|
||||
0x04, 0x00, 0x00, 0x50, 0xFF, 0x95, 0x4C, 0x0F,
|
||||
0x00, 0x00, 0x89, 0x85, 0x26, 0x04, 0x00, 0x00,
|
||||
0x8B, 0xF8, 0x8D, 0x5D, 0x5E, 0x53, 0x50, 0xFF,
|
||||
0x95, 0x48, 0x0F, 0x00, 0x00, 0x89, 0x85, 0x4C,
|
||||
0x05, 0x00, 0x00, 0x8D, 0x5D, 0x6B, 0x53, 0x57,
|
||||
0xFF, 0x95, 0x48, 0x0F
|
||||
}, "ASPack 2.12b -> Solodovnikov Alexey"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x60, 0xE8, 0x03, 0x00, 0x00, 0x00, 0xE9, 0xEB,
|
||||
0x04, 0x5D, 0x45, 0x55, 0xC3, 0xE8, 0x01, 0x00,
|
||||
0x00, 0x00, 0xEB, 0x5D, 0xBB, 0xED, 0xFF, 0xFF,
|
||||
0xFF, 0x03, 0xDD, null, null, null, null, null,
|
||||
null, 0x83, 0xBD, 0x7D, 0x04, 0x00, 0x00, 0x00,
|
||||
0x89, 0x9D, 0x7D, 0x04, 0x00, 0x00, 0x0F, 0x85,
|
||||
0xC0, 0x03, 0x00, 0x00, 0x8D, 0x85, 0x89, 0x04,
|
||||
0x00, 0x00, 0x50, 0xFF, 0x95, 0x09, 0x0F, 0x00,
|
||||
0x00, 0x89, 0x85, 0x81, 0x04, 0x00, 0x00, 0x8B,
|
||||
0xF0, 0x8D, 0x7D, 0x51, 0x57, 0x56, 0xFF, 0x95,
|
||||
0x05, 0x0F, 0x00, 0x00, 0xAB, 0xB0, 0x00, 0xAE,
|
||||
0x75, 0xFD, 0x38, 0x07, 0x75, 0xEE, 0x8D, 0x45,
|
||||
0x7A, 0xFF, 0xE0, 0x56, 0x69, 0x72, 0x74, 0x75,
|
||||
0x61, 0x6C, 0x41, 0x6C, 0x6C, 0x6F, 0x63, 0x00,
|
||||
0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6C, 0x46,
|
||||
0x72, 0x65, 0x65, 0x00, 0x56, 0x69, 0x72, 0x74,
|
||||
0x75, 0x61, 0x6C, 0x50, 0x72, 0x6F, 0x74, 0x65,
|
||||
0x63, 0x74, 0x00, 0x00, 0x8B, 0x9D, 0x8D, 0x05,
|
||||
0x00, 0x00, 0x0B, 0xDB, 0x74, 0x0A, 0x8B, 0x03,
|
||||
0x87, 0x85, 0x91, 0x05, 0x00, 0x00, 0x89, 0x03,
|
||||
0x8D, 0xB5, 0xBD, 0x05, 0x00, 0x00, 0x83, 0x3E,
|
||||
0x00, 0x0F, 0x84, 0x15, 0x01, 0x00, 0x00, 0x6A,
|
||||
0x04, 0x68, 0x00, 0x10, 0x00, 0x00, 0x68, 0x00,
|
||||
0x18, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0x55, 0x51,
|
||||
0x89, 0x85, 0x53, 0x01, 0x00, 0x00, 0x8B, 0x46,
|
||||
0x04, 0x05, 0x0E, 0x01, 0x00, 0x00, 0x6A, 0x04,
|
||||
0x68, 0x00, 0x10, 0x00, 0x00, 0x50, 0x6A, 0x00,
|
||||
0xFF, 0x55, 0x51, 0x89, 0x85, 0x4F, 0x01, 0x00,
|
||||
0x00, 0x56, 0x8B, 0x1E, 0x03, 0x9D, 0x7D, 0x04,
|
||||
0x00, 0x00, 0xFF, 0xB5, 0x53, 0x01, 0x00, 0x00,
|
||||
0xFF, 0x76, 0x04, 0x50, 0x53, 0xE8, 0x2D, 0x05,
|
||||
0x00, 0x00, 0xB3, 0x00, 0x80, 0xFB, 0x00, 0x75,
|
||||
0x5E, 0xFE, 0x85, 0xE9, 0x00, 0x00, 0x00, 0x8B,
|
||||
0x3E, 0x03, 0xBD, 0x7D, 0x04, 0x00, 0x00, 0xFF,
|
||||
0x37, 0xC6, 0x07, 0xC3, 0xFF, 0xD7, 0x8F, 0x07,
|
||||
0x50, 0x51, 0x56, 0x53, 0x8B, 0xC8, 0x83, 0xE9,
|
||||
0x06, 0x8B, 0xB5, 0x4F, 0x01, 0x00, 0x00, 0x33,
|
||||
0xDB, 0x0B, 0xC9, 0x74, 0x2E, 0x78, 0x2C, 0xAC,
|
||||
0x3C, 0xE8, 0x74, 0x0A, 0xEB, 0x00, 0x3C, 0xE9,
|
||||
0x74, 0x04, 0x43, 0x49, 0xEB, 0xEB, 0x8B, 0x06,
|
||||
0xEB, 0x00, null, null, null, 0x75, 0xF3, 0x24,
|
||||
0x00, 0xC1, 0xC0, 0x18, 0x2B, 0xC3, 0x89, 0x06,
|
||||
0x83, 0xC3, 0x05, 0x83, 0xC6, 0x04, 0x83, 0xE9,
|
||||
0x05, 0xEB, 0xCE, 0x5B, 0x5E, 0x59, 0x58, 0xEB,
|
||||
0x08
|
||||
}, "ASPack 2.2 -> Alexey Solodovnikov & StarForce * 2009408"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
null, 0x60, 0xE8, 0x03, 0x00, 0x00, 0x00, 0xE9,
|
||||
0xEB, 0x04, 0x5D, 0x45, 0x55, 0xC3, 0xE8, 0x01,
|
||||
0x00, 0x00, 0x00, 0xEB, 0x5D, 0xBB, 0xEC, 0xFF,
|
||||
0xFF, 0xFF, 0x03, 0xDD, 0x81, 0xEB, 0x00, 0x40,
|
||||
0x1C, 0x00
|
||||
}, "ASPack 2.x (without Poly) -> Solodovnikov Alexey"),
|
||||
|
||||
#endregion
|
||||
|
||||
#region 2.xx (Long)
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0xA8, 0x03, 0x00, 0x00, 0x61, 0x75, 0x08, 0xB8,
|
||||
0x01, 0x00, 0x00, 0x00, 0xC2, 0x0C, 0x00, 0x68,
|
||||
0x00, 0x00, 0x00, 0x00, 0xC3, 0x8B, 0x85, 0x26,
|
||||
0x04, 0x00, 0x00, 0x8D, 0x8D, 0x3B, 0x04, 0x00,
|
||||
0x00, 0x51, 0x50, 0xFF, 0x95
|
||||
}, "ASPack 2.xx"),
|
||||
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0xA8, 0x03, null, null, 0x61, 0x75, 0x08, 0xB8,
|
||||
0x01, null, null, null, 0xC2, 0x0C, null, 0x68,
|
||||
null, null, null, null, 0xC3, 0x8B, 0x85, 0x26,
|
||||
0x04, null, null, 0x8D, 0x8D, 0x3B, 0x04, null,
|
||||
null, 0x51, 0x50, 0xFF, 0x95
|
||||
}, "ASPack 2.xx"),
|
||||
|
||||
#endregion
|
||||
|
||||
#region Short
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x75, 0x00, 0xE9 }, "ASPack 1.05b"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x90, 0x75, 0x00, 0xE9 }, "ASPack 1.06.1b"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x75, 0x00, 0xE9 }, "ASPack 1.06.1b"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x75, 0x00, 0xE9 }, "ASPack 1.06.1b"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x90, 0x75, null, 0xE9 }, "ASPack 1.07b"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x75, null, 0xE9 }, "ASPack 1.07b"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x75, null, 0xE9 }, "ASPack 1.07b"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x90, 0x75, 0x01, 0x90, 0xE9 }, "ASPack 1.08"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x90, 0x75, 0x01, 0xFF, 0xE9 }, "ASPack 1.08"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x75, 0x01, 0xFF, 0xE9 }, "ASPack 1.08"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x75, 0x01, 0xFF, 0xE9 }, "ASPack 1.08"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x90, 0x75, null, 0x90, 0xE9 }, "ASPack 1.08.01"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x75, null, 0x90, 0xE9 }, "ASPack 1.08.01"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x75, null, 0x90, 0xE9 }, "ASPack 1.08.01"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x90, 0x75, 0x01, 0x90, 0xE9 }, "ASPack 1.08.02"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x90, 0x75, 0x01, 0x90, 0xE9 }, "ASPack 1.08.02"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x60, 0xE8, 0x41, 0x06, 0x00, 0x00, 0xEB, 0x41 }, "ASPack 1.08.04"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x60, 0xE8, null, null, null, null, 0xEB }, "ASPack 1.08.04"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x60, 0xE8, 0x70, 0x05, 0x00, 0x00, 0xEB, 0x4C }, "ASPack 2.00.00"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x60, 0xE8, 0x48, 0x11, 0x00, 0x00, 0xC3, 0x83 }, "ASPack 2.00.00"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x60, 0xE8, 0x72, 0x05, 0x00, 0x00, 0xEB, 0x4C }, "ASPack 2.00.01"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x60, 0xE8, null, 0x05, 0x00, 0x00, 0xEB, 0x4C }, "ASPack 2.00.x -> Alexey Solodovnikov"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x60, 0xE9, 0x3D, 0x04, 0x00, 0x00 }, "ASPack 2.11"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x60, 0xE8, 0xF9, 0x11, 0x00, 0x00, 0xC3, 0x83 }, "ASPack 2.11"),
|
||||
|
||||
new ContentMatchSet(new byte?[] { 0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x81, 0xED }, "ASPack 1.02b/1.08.03"),
|
||||
|
||||
#endregion
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
50
BinaryObjectScanner.Packer/AdvancedInstaller.cs
Normal file
50
BinaryObjectScanner.Packer/AdvancedInstaller.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction
|
||||
// TODO: Verify that all versions are detected
|
||||
public class AdvancedInstaller : IExtractable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Get the .rdata section strings, if they exist
|
||||
List<string> strs = pex.GetFirstSectionStrings(".rdata");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("Software\\Caphyon\\Advanced Installer")))
|
||||
return "Caphyon Advanced Installer";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
60
BinaryObjectScanner.Packer/Armadillo.cs
Normal file
60
BinaryObjectScanner.Packer/Armadillo.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction
|
||||
// TODO: Add version checking, if possible
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class Armadillo : IExtractable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Get the .nicode section, if it exists
|
||||
bool nicodeSection = pex.ContainsSection(".nicode", exact: true);
|
||||
if (nicodeSection)
|
||||
return "Armadillo";
|
||||
|
||||
// Loop through all "extension" sections -- usually .data1 or .text1
|
||||
foreach (var sectionName in pex.SectionNames.Where(s => s != null && s.EndsWith("1")))
|
||||
{
|
||||
// Get the section strings, if they exist
|
||||
List<string> strs = pex.GetFirstSectionStrings(sectionName);
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("ARMDEBUG")))
|
||||
return "Armadillo";
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
69
BinaryObjectScanner.Packer/AutoPlayMediaStudio.cs
Normal file
69
BinaryObjectScanner.Packer/AutoPlayMediaStudio.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// Created by IndigoRose (creators of Setup Factory), primarily to be used to create autorun menus for various media.
|
||||
// Official website: https://www.autoplay.org/
|
||||
// TODO: Add extraction
|
||||
public class AutoPlayMediaStudio : IExtractable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Known to detect versions 5.0.0.3 - 8.1.0.0
|
||||
string name = pex.ProductName;
|
||||
if (name?.StartsWith("AutoPlay Media Studio", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"AutoPlay Media Studio {GetVersion(pex)}";
|
||||
|
||||
// Currently too vague, may be re-enabled in the future
|
||||
/*
|
||||
name = Utilities.GetLegalCopyright(pex);
|
||||
if (name?.StartsWith("Runtime Engine", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"AutoPlay Media Studio {GetVersion(pex)}";
|
||||
*/
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
private string GetVersion(PortableExecutable pex)
|
||||
{
|
||||
// Check the product version explicitly
|
||||
string version = pex.ProductVersion;
|
||||
if (!string.IsNullOrEmpty(version))
|
||||
return version;
|
||||
|
||||
// Check the internal versions
|
||||
version = pex.GetInternalVersion();
|
||||
if (!string.IsNullOrEmpty(version))
|
||||
return version;
|
||||
|
||||
return "(Unknown Version)";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,10 @@
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="WiseUnpacker" Version="1.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\BinaryObjectScanner.Interfaces\BinaryObjectScanner.Interfaces.csproj" />
|
||||
<ProjectReference Include="..\BinaryObjectScanner.Matching\BinaryObjectScanner.Matching.csproj" />
|
||||
|
||||
144
BinaryObjectScanner.Packer/CExe.cs
Normal file
144
BinaryObjectScanner.Packer/CExe.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Compression;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Matching;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
using ICSharpCode.SharpZipLib.Zip.Compression;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// The official website for CExe also includes the source code (which does have to be retrieved by the Wayback Machine)
|
||||
// http://www.scottlu.com/Content/CExe.html
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class CExe : IExtractable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// If there are exactly 2 resources with type 99
|
||||
if (pex.FindResourceByNamedType("99, ").Count() == 2)
|
||||
return "CExe";
|
||||
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x25, 0x57, 0x6F, 0xC1, 0x61, 0x36, 0x01, 0x92,
|
||||
0x61, 0x36, 0x01, 0x92, 0x61, 0x36, 0x01, 0x92,
|
||||
0x61, 0x36, 0x00, 0x92, 0x7B, 0x36, 0x01, 0x92,
|
||||
0x03, 0x29, 0x12, 0x92, 0x66, 0x36, 0x01, 0x92,
|
||||
0x89, 0x29, 0x0A, 0x92, 0x60, 0x36, 0x01, 0x92,
|
||||
0xD9, 0x30, 0x07, 0x92, 0x60, 0x36, 0x01, 0x92
|
||||
}, "CExe")
|
||||
};
|
||||
|
||||
string match = MatchUtil.GetFirstMatch(file, pex.StubExecutableData, matchers, includeDebug);
|
||||
if (!string.IsNullOrWhiteSpace(match))
|
||||
return match;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Parse into an executable again for easier extraction
|
||||
PortableExecutable 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();
|
||||
if (payload == null || payload.Length == 0)
|
||||
return null;
|
||||
|
||||
// Determine which compression was used
|
||||
bool zlib = pex.FindResourceByNamedType("99, 1").Any();
|
||||
|
||||
// Create the output data buffer
|
||||
byte[] data;
|
||||
|
||||
// If we had the decompression DLL included, it's zlib
|
||||
if (zlib)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Inflate the data into the buffer
|
||||
Inflater inflater = new Inflater();
|
||||
inflater.SetInput(payload);
|
||||
data = new byte[payload.Length * 4];
|
||||
int read = inflater.Inflate(data);
|
||||
|
||||
// Trim the buffer to the proper size
|
||||
data = new ReadOnlySpan<byte>(data, 0, read).ToArray();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Reset the data
|
||||
data = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, LZ is used via the Windows API
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
data = LZ.Decompress(payload);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Reset the data
|
||||
data = null;
|
||||
}
|
||||
}
|
||||
|
||||
// If we have no data
|
||||
if (data == null)
|
||||
return null;
|
||||
|
||||
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(tempPath);
|
||||
|
||||
// Create the temp filename
|
||||
string tempFile = string.IsNullOrEmpty(file) ? "temp.sxe" : $"{Path.GetFileNameWithoutExtension(file)}.sxe";
|
||||
tempFile = Path.Combine(tempPath, tempFile);
|
||||
|
||||
// Write the file data to a temp file
|
||||
using (Stream tempStream = File.Open(tempFile, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
|
||||
{
|
||||
tempStream.Write(data, 0, data.Length);
|
||||
}
|
||||
|
||||
return tempPath;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
95
BinaryObjectScanner.Packer/EXEStealth.cs
Normal file
95
BinaryObjectScanner.Packer/EXEStealth.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Matching;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Figure out how to more granularly determine versions like PiD
|
||||
// TODO: Detect 3.15 and up (maybe looking for `Metamorphism`)
|
||||
// TODO: Add extraction
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class EXEStealth : IContentCheck, IExtractable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckContents(string file, byte[] fileContent, bool includeDebug)
|
||||
{
|
||||
// TODO: Obtain a sample to find where this string is in a typical executable
|
||||
if (includeDebug)
|
||||
{
|
||||
var contentMatchSets = new List<ContentMatchSet>
|
||||
{
|
||||
// ??[[__[[_ + (char)0x00 + {{ + (char)0x0 + (char)0x00 + {{ + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x0 + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + ?;??;??
|
||||
new ContentMatchSet(new byte?[]
|
||||
{
|
||||
0x3F, 0x3F, 0x5B, 0x5B, 0x5F, 0x5F, 0x5B, 0x5B,
|
||||
0x5F, 0x00, 0x7B, 0x7B, 0x00, 0x00, 0x7B, 0x7B,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x20, 0x3F, 0x3B, 0x3F, 0x3F, 0x3B, 0x3F,
|
||||
0x3F
|
||||
}, "EXE Stealth"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(file, fileContent, contentMatchSets, includeDebug);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// The ExeS/EXES/*mtw sections seem to map to the Import Table
|
||||
// 2.6/2.51
|
||||
// `ExeStealth - www.webtoolmaster.com`
|
||||
// 2.72/2.73
|
||||
// `Shareware - ExeStealth`
|
||||
// `www.webtoolmaster.com`
|
||||
// 2.74
|
||||
// `Shareware - ExeStealth`
|
||||
// 2.76
|
||||
// `ExeStealth V2 Shareware not for public - This text not in registered version - www.webtoolmaster.com`
|
||||
|
||||
// Get the ExeS/EXES section, if it exists
|
||||
bool exesSection = pex.ContainsSection("ExeS", exact: true) || pex.ContainsSection("EXES", exact: true);
|
||||
if (exesSection)
|
||||
return "EXE Stealth 2.41-2.75";
|
||||
|
||||
// Get the mtw section, if it exists
|
||||
bool mtwSection = pex.ContainsSection("mtw", exact: true);
|
||||
if (mtwSection)
|
||||
return "EXE Stealth 1.1";
|
||||
|
||||
// Get the rsrr section, if it exists
|
||||
bool rsrrSection = pex.ContainsSection("rsrr", exact: true);
|
||||
if (rsrrSection)
|
||||
return "EXE Stealth 2.76";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
95
BinaryObjectScanner.Packer/EmbeddedExecutable.cs
Normal file
95
BinaryObjectScanner.Packer/EmbeddedExecutable.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Matching;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
/// <summary>
|
||||
/// Though not technically a packer, this detection is for any executables that include
|
||||
/// others in their resources in some uncompressed manner to be used at runtime.
|
||||
/// </summary>
|
||||
public class EmbeddedExecutable : IExtractable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Get the resources that have an executable signature
|
||||
if (pex.ResourceData?.Any(kvp => kvp.Value is byte[] ba && ba.StartsWith(BinaryObjectScanner.Models.MSDOS.Constants.SignatureBytes)) == true)
|
||||
return "Embedded Executable";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Parse into an executable again for easier extraction
|
||||
PortableExecutable 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(BinaryObjectScanner.Models.MSDOS.Constants.SignatureBytes))
|
||||
.ToList();
|
||||
|
||||
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(tempPath);
|
||||
|
||||
for (int i = 0; i < resources.Count; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Get the resource data
|
||||
var resource = resources[i];
|
||||
byte[] data = resource.Value as byte[];
|
||||
|
||||
// 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))
|
||||
{
|
||||
tempStream.Write(data, 0, data.Length);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
|
||||
return tempPath;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
53
BinaryObjectScanner.Packer/GenteeInstaller.cs
Normal file
53
BinaryObjectScanner.Packer/GenteeInstaller.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class GenteeInstaller : IExtractable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Get the .data/DATA section strings, if they exist
|
||||
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("Gentee installer")))
|
||||
return "Gentee Installer";
|
||||
|
||||
if (strs.Any(s => s.Contains("ginstall.dll")))
|
||||
return "Gentee Installer";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
52
BinaryObjectScanner.Packer/HyperTechCrackProof.cs
Normal file
52
BinaryObjectScanner.Packer/HyperTechCrackProof.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// CrackProof is a packer/obfuscator created by Japanese company HyperTech (https://www.hypertech.co.jp/products/windows/).
|
||||
// It is known to be used along with other DRM, such as Shury2 (Redump entry 97135) and BDL.
|
||||
// https://www.reddit.com/r/riseofincarnates/comments/m3vbnm/subreddit_revival_does_anyone_still_have_rise_of/
|
||||
// https://steamcommunity.com/app/310950/discussions/0/4224890554455490819/
|
||||
// https://github.com/horsicq/Detect-It-Easy/blob/63a1aa8bb23ca02d8a7fd5936db8dbc5c5d52dea/db/PE/HyperTech%20Crackproof.2.sg
|
||||
public class HyperTechCrackProof : IExtractable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.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.ImportTable?.ImportDirectoryTable?.Any(idte => idte.Name == "KeRnEl32.dLl") ?? false);
|
||||
|
||||
if (peCSection && importTableMatch)
|
||||
return "HyperTech CrackProof";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
101
BinaryObjectScanner.Packer/InnoSetup.cs
Normal file
101
BinaryObjectScanner.Packer/InnoSetup.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Matching;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction - https://github.com/dscharrer/InnoExtract
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class InnoSetup : IExtractable, INewExecutableCheck, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
|
||||
{
|
||||
// Check we have a valid executable
|
||||
if (nex == null)
|
||||
return null;
|
||||
|
||||
// Check for "Inno" in the reserved words
|
||||
if (nex.Stub_Reserved2[4] == 0x6E49 && nex.Stub_Reserved2[5] == 0x6F6E)
|
||||
{
|
||||
string version = GetOldVersion(file, nex);
|
||||
if (!string.IsNullOrWhiteSpace(version))
|
||||
return $"Inno Setup {version}";
|
||||
|
||||
return "Inno Setup (Unknown Version)";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Get the .data/DATA section strings, if they exist
|
||||
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
|
||||
if (strs != null)
|
||||
{
|
||||
string str = strs.FirstOrDefault(s => s.StartsWith("Inno Setup Setup Data"));
|
||||
if (str != null)
|
||||
{
|
||||
return str.Replace("Inno Setup Setup Data", "Inno Setup")
|
||||
.Replace("(u)", "[Unicode]")
|
||||
.Replace("(", string.Empty)
|
||||
.Replace(")", string.Empty)
|
||||
.Replace("[Unicode]", "(Unicode)");
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string GetOldVersion(string file, NewExecutable nex)
|
||||
{
|
||||
// Notes:
|
||||
// Look into `SETUPLDR` in the resident-name table
|
||||
// Look into `SETUPLDR.EXE` in the nonresident-name table
|
||||
|
||||
// TODO: Don't read entire file
|
||||
// TODO: Only 64 bytes at the end of the file is needed
|
||||
var data = nex.ReadArbitraryRange();
|
||||
if (data != null)
|
||||
{
|
||||
var matchers = new List<ContentMatchSet>
|
||||
{
|
||||
// "rDlPtS02" + (char)0x87 + "eVx"
|
||||
new ContentMatchSet(new byte?[] { 0x72, 0x44, 0x6C, 0x50, 0x74, 0x53, 0x30, 0x32, 0x87, 0x65, 0x56, 0x78 }, "1.2.16 or earlier"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(file, data, matchers, false) ?? "Unknown 1.X";
|
||||
}
|
||||
|
||||
return "Unknown 1.X";
|
||||
}
|
||||
}
|
||||
}
|
||||
59
BinaryObjectScanner.Packer/InstallAnywhere.cs
Normal file
59
BinaryObjectScanner.Packer/InstallAnywhere.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction, which may be possible with the current libraries but needs to be investigated further.
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class InstallAnywhere : IExtractable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
string name = pex.FileDescription;
|
||||
if (name?.StartsWith("InstallAnywhere Self Extractor", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"InstallAnywhere {GetVersion(pex)}";
|
||||
|
||||
name = pex.ProductName;
|
||||
if (name?.StartsWith("InstallAnywhere", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"InstallAnywhere {GetVersion(pex)}";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
private string GetVersion(PortableExecutable pex)
|
||||
{
|
||||
// Check the internal versions
|
||||
string version = pex.GetInternalVersion();
|
||||
if (!string.IsNullOrEmpty(version))
|
||||
return version;
|
||||
|
||||
return "(Unknown Version)";
|
||||
}
|
||||
}
|
||||
}
|
||||
51
BinaryObjectScanner.Packer/InstallerVISE.cs
Normal file
51
BinaryObjectScanner.Packer/InstallerVISE.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction - https://github.com/Bioruebe/UniExtract2
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class InstallerVISE : IExtractable, IPortableExecutableCheck
|
||||
{
|
||||
//TODO: Add exact version detection for Windows builds, make sure versions before 3.X are detected as well, and detect the Mac builds.
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Get the .data/DATA section strings, if they exist
|
||||
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("ViseMain")))
|
||||
return "Installer VISE";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
54
BinaryObjectScanner.Packer/IntelInstallationFramework.cs
Normal file
54
BinaryObjectScanner.Packer/IntelInstallationFramework.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction, seems to primarily use MSZip compression.
|
||||
public class IntelInstallationFramework : IExtractable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
string name = pex.FileDescription;
|
||||
if (name?.Equals("Intel(R) Installation Framework", StringComparison.OrdinalIgnoreCase) == true
|
||||
|| name?.Equals("Intel Installation Framework", StringComparison.OrdinalIgnoreCase) == true)
|
||||
{
|
||||
return $"Intel Installation Framework {pex.GetInternalVersion()}";
|
||||
}
|
||||
|
||||
name = pex.ProductName;
|
||||
if (name?.Equals("Intel(R) Installation Framework", StringComparison.OrdinalIgnoreCase) == true
|
||||
|| name?.Equals("Intel Installation Framework", StringComparison.OrdinalIgnoreCase) == true)
|
||||
{
|
||||
return $"Intel Installation Framework {pex.GetInternalVersion()}";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
79
BinaryObjectScanner.Packer/MicrosoftCABSFX.cs
Normal file
79
BinaryObjectScanner.Packer/MicrosoftCABSFX.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction, which should be possible with LibMSPackN, but it refuses to extract due to SFX files lacking the typical CAB identifiers.
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class MicrosoftCABSFX : IExtractable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
string name = pex.InternalName;
|
||||
if (name?.Equals("Wextract", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"Microsoft CAB SFX {GetVersion(pex)}";
|
||||
|
||||
name = pex.OriginalFilename;
|
||||
if (name?.Equals("WEXTRACT.EXE", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"Microsoft CAB SFX {GetVersion(pex)}";
|
||||
|
||||
// Get the .data/DATA section strings, if they exist
|
||||
List<string> strs = pex.GetFirstSectionStrings(".data") ?? pex.GetFirstSectionStrings("DATA");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("wextract_cleanup")))
|
||||
return $"Microsoft CAB SFX {GetVersion(pex)}";
|
||||
}
|
||||
|
||||
// Get the .text section strings, if they exist
|
||||
strs = pex.GetFirstSectionStrings(".text");
|
||||
if (strs != null)
|
||||
{
|
||||
// This detects a different but similar type of SFX that uses Microsoft CAB files.
|
||||
// Further research is needed to see if it's just a different version or entirely separate.
|
||||
if (strs.Any(s => s.Contains("MSCFu")))
|
||||
return $"Microsoft CAB SFX {GetVersion(pex)}";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
private string GetVersion(PortableExecutable pex)
|
||||
{
|
||||
// Check the internal versions
|
||||
string version = pex.GetInternalVersion();
|
||||
if (!string.IsNullOrWhiteSpace(version))
|
||||
return $"v{version}";
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
53
BinaryObjectScanner.Packer/NSIS.cs
Normal file
53
BinaryObjectScanner.Packer/NSIS.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction
|
||||
public class NSIS : IExtractable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
string 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");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("NullsoftInst")))
|
||||
return "NSIS";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
62
BinaryObjectScanner.Packer/PECompact.cs
Normal file
62
BinaryObjectScanner.Packer/PECompact.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Better version detection - https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
// TODO: Add extraction
|
||||
public class PECompact : IExtractable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// 0x4F434550 is "PECO"
|
||||
if (pex.PointerToSymbolTable == 0x4F434550)
|
||||
return "PE Compact v1.x";
|
||||
|
||||
// TODO: Get more granular version detection. PiD is somehow able to detect version ranges based
|
||||
// on the data in the file. This may be related to information in other fields
|
||||
|
||||
// Get the pec1 section, if it exists
|
||||
bool pec1Section = pex.ContainsSection("pec1", exact: true);
|
||||
if (pec1Section)
|
||||
return "PE Compact v1.x";
|
||||
|
||||
// Get the PEC2 section, if it exists -- TODO: Verify this comment since it's pulling the .text section
|
||||
var textSection = pex.GetFirstSection(".text", exact: true);
|
||||
if (textSection != null && textSection.PointerToRelocations == 0x32434550)
|
||||
{
|
||||
if (textSection.PointerToLinenumbers != 0)
|
||||
return $"PE Compact v{textSection.PointerToLinenumbers} (internal version)";
|
||||
|
||||
return "PE Compact v2.x (or newer)";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
45
BinaryObjectScanner.Packer/Petite.cs
Normal file
45
BinaryObjectScanner.Packer/Petite.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class PEtite : IExtractable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Get the .petite section, if it exists -- TODO: Is there a version number that can be found?
|
||||
bool petiteSection = pex.ContainsSection(".petite", exact: true);
|
||||
if (petiteSection)
|
||||
return "PEtite";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
74
BinaryObjectScanner.Packer/SetupFactory.cs
Normal file
74
BinaryObjectScanner.Packer/SetupFactory.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction, which is possible but the only tools available that can
|
||||
// do this seem to be Universal Extractor 2 and InstallExplorer (https://totalcmd.net/plugring/InstallExplorer.html)
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class SetupFactory : IExtractable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Known to detect versions 7.0.5.1 - 9.1.0.0
|
||||
string name = pex.LegalCopyright;
|
||||
if (name?.StartsWith("Setup Engine", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"Setup Factory {GetVersion(pex)}";
|
||||
|
||||
name = pex.ProductName;
|
||||
if (name?.StartsWith("Setup Factory", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"Setup Factory {GetVersion(pex)}";
|
||||
|
||||
// Known to detect version 5.0.1 - 6.0.1.3
|
||||
name = pex.FileDescription;
|
||||
if (name?.StartsWith("Setup Factory", StringComparison.OrdinalIgnoreCase) == true)
|
||||
return $"Setup Factory {GetVersion(pex)}";
|
||||
|
||||
// Longer version of the check that can be used if false positves become an issue:
|
||||
// "Setup Factory is a trademark of Indigo Rose Corporation"
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
private string GetVersion(PortableExecutable pex)
|
||||
{
|
||||
// Check the product version explicitly
|
||||
string version = pex.ProductVersion;
|
||||
if (!string.IsNullOrEmpty(version))
|
||||
return version;
|
||||
|
||||
// Check the internal versions
|
||||
version = pex.GetInternalVersion();
|
||||
if (!string.IsNullOrEmpty(version))
|
||||
return version;
|
||||
|
||||
return "(Unknown Version)";
|
||||
}
|
||||
}
|
||||
}
|
||||
66
BinaryObjectScanner.Packer/SevenZipSFX.cs
Normal file
66
BinaryObjectScanner.Packer/SevenZipSFX.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction
|
||||
public class SevenZipSFX : IExtractable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Get the assembly description, if possible
|
||||
if (pex.AssemblyDescription?.StartsWith("7-Zip Self-extracting Archive") == true)
|
||||
return $"7-Zip SFX {pex.AssemblyDescription.Substring("7-Zip Self-extracting Archive ".Length)}";
|
||||
|
||||
// Get the file description, if it exists
|
||||
if (pex.FileDescription?.Equals("7z SFX") == true)
|
||||
return "7-Zip SFX";
|
||||
if (pex.FileDescription?.Equals("7z Self-Extract Setup") == true)
|
||||
return "7-Zip SFX";
|
||||
|
||||
// Get the original filename, if it exists
|
||||
if (pex.OriginalFilename?.Equals("7z.sfx.exe") == true)
|
||||
return "7-Zip SFX";
|
||||
else if (pex.OriginalFilename?.Equals("7zS.sfx") == true)
|
||||
return "7-Zip SFX";
|
||||
|
||||
// Get the internal name, if it exists
|
||||
if (pex.InternalName?.Equals("7z.sfx") == true)
|
||||
return "7-Zip SFX";
|
||||
else if (pex.InternalName?.Equals("7zS.sfx") == true)
|
||||
return "7-Zip SFX";
|
||||
|
||||
// If any dialog boxes match
|
||||
if (pex.FindDialogByTitle("7-Zip self-extracting archive").Any())
|
||||
return "7-Zip SFX";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
46
BinaryObjectScanner.Packer/Shrinker.cs
Normal file
46
BinaryObjectScanner.Packer/Shrinker.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System.IO;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class Shrinker : IExtractable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Get the .shrink0 and .shrink2 sections, if they exist -- TODO: Confirm if both are needed or either/or is fine
|
||||
bool shrink0Section = pex.ContainsSection(".shrink0", true);
|
||||
bool shrink2Section = pex.ContainsSection(".shrink2", true);
|
||||
if (shrink0Section || shrink2Section)
|
||||
return "Shrinker";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
113
BinaryObjectScanner.Packer/UPX.cs
Normal file
113
BinaryObjectScanner.Packer/UPX.cs
Normal file
@@ -0,0 +1,113 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class UPX : IExtractable, IPortableExecutableCheck
|
||||
{
|
||||
private static readonly Regex _oldUpxVersionMatch = new Regex(@"\$Id: UPX (.*?) Copyright \(C\)", RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex _upxVersionMatch = new Regex(@"^([0-9]\.[0-9]{2})$", RegexOptions.Compiled);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Check header padding strings
|
||||
if (pex.HeaderPaddingStrings?.Any() == true)
|
||||
{
|
||||
string match = pex.HeaderPaddingStrings.FirstOrDefault(s => s.Contains("UPX!"));
|
||||
//if (match != null)
|
||||
// return "UPX";
|
||||
|
||||
match = pex.HeaderPaddingStrings.FirstOrDefault(s => s.StartsWith("$Id: UPX"));
|
||||
if (match != null)
|
||||
{
|
||||
var regexMatch = _oldUpxVersionMatch.Match(match);
|
||||
if (regexMatch.Success)
|
||||
return $"UPX {regexMatch.Groups[1].Value}";
|
||||
else
|
||||
return "UPX (Unknown Version)";
|
||||
}
|
||||
|
||||
match = pex.HeaderPaddingStrings.FirstOrDefault(s => _upxVersionMatch.IsMatch(s));
|
||||
if (pex.HeaderPaddingStrings.Any(s => s == "UPX!" && match != null))
|
||||
{
|
||||
var regexMatch = _upxVersionMatch.Match(match);
|
||||
if (regexMatch.Success)
|
||||
return $"UPX {regexMatch.Groups[1].Value}";
|
||||
else
|
||||
return "UPX (Unknown Version)";
|
||||
}
|
||||
else if (pex.HeaderPaddingStrings.Any(s => s == "NOS " && match != null))
|
||||
{
|
||||
var regexMatch = _upxVersionMatch.Match(match);
|
||||
if (regexMatch.Success)
|
||||
return $"UPX (NOS Variant) {regexMatch.Groups[1].Value}";
|
||||
else
|
||||
return "UPX (NOS Variant) (Unknown Version)";
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public static string GetVersion(string file, byte[] fileContent, List<int> positions)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Check the normal version location first
|
||||
int index = positions[0] - 5;
|
||||
string versionString = Encoding.ASCII.GetString(fileContent, index, 4);
|
||||
if (char.IsNumber(versionString[0]))
|
||||
return versionString;
|
||||
|
||||
// Check for the old-style string
|
||||
//
|
||||
// Example:
|
||||
// $Info: This file is packed with the UPX executable packer http://upx.tsx.org $
|
||||
// $Id: UPX 1.02 Copyright (C) 1996-2000 the UPX Team. All Rights Reserved. $
|
||||
// UPX!
|
||||
index = positions[0] - 67;
|
||||
versionString = Encoding.ASCII.GetString(fileContent, index, 4);
|
||||
if (char.IsNumber(versionString[0]))
|
||||
return versionString;
|
||||
|
||||
return "(Unknown Version)";
|
||||
}
|
||||
catch
|
||||
{
|
||||
return "(Unknown Version)";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
82
BinaryObjectScanner.Packer/WinRARSFX.cs
Normal file
82
BinaryObjectScanner.Packer/WinRARSFX.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
using SharpCompress.Archives;
|
||||
using SharpCompress.Archives.Rar;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
public class WinRARSFX : IExtractable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
string name = pex.AssemblyDescription;
|
||||
if (name?.Contains("WinRAR archiver") == true)
|
||||
return "WinRAR SFX";
|
||||
|
||||
var resources = pex.FindDialogByTitle("WinRAR self-extracting archive");
|
||||
if (resources.Any())
|
||||
return "WinRAR SFX";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
try
|
||||
{
|
||||
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(tempPath);
|
||||
|
||||
// Should be using stream instead of file, but stream fails to extract anything. My guess is that the executable portion of the archive is causing stream to fail, but not file.
|
||||
using (RarArchive zipFile = RarArchive.Open(file, new SharpCompress.Readers.ReaderOptions() { LookForHeader = true }))
|
||||
{
|
||||
foreach (var entry in zipFile.Entries)
|
||||
{
|
||||
try
|
||||
{
|
||||
// If we have a directory, skip it
|
||||
if (entry.IsDirectory)
|
||||
continue;
|
||||
|
||||
string tempFile = Path.Combine(tempPath, entry.Key);
|
||||
entry.WriteToFile(tempFile);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tempPath;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
877
BinaryObjectScanner.Packer/WinZipSFX.cs
Normal file
877
BinaryObjectScanner.Packer/WinZipSFX.cs
Normal file
@@ -0,0 +1,877 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
using SharpCompress.Archives;
|
||||
using SharpCompress.Archives.Zip;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
public class WinZipSFX : IExtractable, INewExecutableCheck, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
|
||||
{
|
||||
// Check we have a valid executable
|
||||
if (nex == null)
|
||||
return null;
|
||||
|
||||
// If the resident-name table doesnt exist
|
||||
if (nex.ResidentNameTable == null)
|
||||
return null;
|
||||
|
||||
// Check for the WinZip name string
|
||||
bool winZipNameFound = nex.ResidentNameTable.Where(rnte => rnte?.NameString != null)
|
||||
.Select(rnte => Encoding.ASCII.GetString(rnte.NameString))
|
||||
.Any(s => s.Contains("WZ-SE-01"));
|
||||
|
||||
// If we didn't find it
|
||||
if (!winZipNameFound)
|
||||
return null;
|
||||
|
||||
// Try to get a known version
|
||||
string version = GetNEHeaderVersion(nex);
|
||||
if (!string.IsNullOrWhiteSpace(version))
|
||||
return $"WinZip SFX {version}";
|
||||
|
||||
return $"WinZip SFX Unknown Version (16-bit)";
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Check the export directory table, if it exists
|
||||
if (pex.ExportTable?.ExportDirectoryTable != null)
|
||||
{
|
||||
string version = GetPEExportDirectoryVersion(pex);
|
||||
if (!string.IsNullOrWhiteSpace(version))
|
||||
return $"WinZip SFX {version}";
|
||||
}
|
||||
|
||||
// Get the _winzip_ section, if it exists
|
||||
if (pex.ContainsSection("_winzip_", exact: true))
|
||||
return "WinZip SFX Unknown Version (32-bit)";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO: Find a way to generically detect 2.X versions and improve exact version detection for SFX PE versions bundled with WinZip 11+
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
try
|
||||
{
|
||||
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(tempPath);
|
||||
|
||||
// Should be using stream instead of file, but stream fails to extract anything. My guess is that the executable portion of the archive is causing stream to fail, but not file.
|
||||
using (ZipArchive zipFile = ZipArchive.Open(file))
|
||||
{
|
||||
foreach (var entry in zipFile.Entries)
|
||||
{
|
||||
try
|
||||
{
|
||||
// If we have a directory, skip it
|
||||
if (entry.IsDirectory)
|
||||
continue;
|
||||
|
||||
string tempFile = Path.Combine(tempPath, entry.Key);
|
||||
entry.WriteToFile(tempFile);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tempPath;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the version from the NE header value combinations
|
||||
/// </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
|
||||
private string GetNEHeaderVersion(NewExecutable nex)
|
||||
{
|
||||
#region 2.0 Variants
|
||||
|
||||
// 2.0 (MS-DOS/16-bit)
|
||||
if (nex.LinkerVersion == 0x11
|
||||
&& nex.LinkerRevision == 0x20
|
||||
&& nex.EntryTableOffset == 0x0086
|
||||
&& nex.EntryTableSize == 0x0002
|
||||
&& nex.CrcChecksum == 0x00000000
|
||||
&& nex.FlagWord == (BinaryObjectScanner.Models.NewExecutable.HeaderFlag.MULTIPLEDATA
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.ProtectedModeOnly
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.FullScreen
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.WindowsPMCompatible)
|
||||
&& nex.AutomaticDataSegmentNumber == 0x0003
|
||||
&& nex.InitialHeapAlloc == 0x2000
|
||||
&& nex.InitialStackAlloc == 0x4000
|
||||
&& nex.InitialCSIPSetting == 0x00012BE6
|
||||
&& nex.InitialSSSPSetting == 0x00030000
|
||||
&& nex.FileSegmentCount == 0x0003
|
||||
&& nex.ModuleReferenceTableSize == 0x0004
|
||||
&& nex.NonResidentNameTableSize == 0x004B
|
||||
&& nex.SegmentTableOffset == 0x0040
|
||||
&& nex.ResourceTableOffset == 0x0058
|
||||
&& nex.ResidentNameTableOffset == 0x0058
|
||||
&& nex.ModuleReferenceTableOffset == 0x0064
|
||||
&& nex.ImportedNamesTableOffset == 0x006C
|
||||
&& nex.NonResidentNamesTableOffset == 0x000044B8
|
||||
&& nex.MovableEntriesCount == 0x0000
|
||||
&& nex.SegmentAlignmentShiftCount == 0x0001
|
||||
&& nex.ResourceEntriesCount == 0x0000
|
||||
&& nex.TargetOperatingSystem == BinaryObjectScanner.Models.NewExecutable.OperatingSystem.WINDOWS
|
||||
&& nex.AdditionalFlags == 0x00
|
||||
&& nex.ReturnThunkOffset == 0x0000
|
||||
&& nex.SegmentReferenceThunkOffset == 0x0000
|
||||
&& nex.MinCodeSwapAreaSize == 0x0000
|
||||
&& nex.WindowsSDKRevision == 0x00
|
||||
&& nex.WindowsSDKVersion == 0x03)
|
||||
return "2.0 (MS-DOS/16-bit)";
|
||||
|
||||
// 2.0 (16-bit)
|
||||
if (nex.LinkerVersion == 0x11
|
||||
&& nex.LinkerRevision == 0x20
|
||||
&& nex.EntryTableOffset == 0x0086
|
||||
&& nex.EntryTableSize == 0x0002
|
||||
&& nex.CrcChecksum == 0x00000000
|
||||
&& nex.FlagWord == (BinaryObjectScanner.Models.NewExecutable.HeaderFlag.MULTIPLEDATA
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.ProtectedModeOnly
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.FullScreen
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.WindowsPMCompatible)
|
||||
&& nex.AutomaticDataSegmentNumber == 0x0003
|
||||
&& nex.InitialHeapAlloc == 0x2000
|
||||
&& nex.InitialStackAlloc == 0x4000
|
||||
&& nex.InitialCSIPSetting == 0x00013174
|
||||
&& nex.InitialSSSPSetting == 0x00030000
|
||||
&& nex.FileSegmentCount == 0x0003
|
||||
&& nex.ModuleReferenceTableSize == 0x0004
|
||||
&& nex.NonResidentNameTableSize == 0x004B
|
||||
&& nex.SegmentTableOffset == 0x0040
|
||||
&& nex.ResourceTableOffset == 0x0058
|
||||
&& nex.ResidentNameTableOffset == 0x0058
|
||||
&& nex.ModuleReferenceTableOffset == 0x0064
|
||||
&& nex.ImportedNamesTableOffset == 0x006C
|
||||
&& nex.NonResidentNamesTableOffset == 0x00000198
|
||||
&& nex.MovableEntriesCount == 0x0000
|
||||
&& nex.SegmentAlignmentShiftCount == 0x0001
|
||||
&& nex.ResourceEntriesCount == 0x0000
|
||||
&& nex.TargetOperatingSystem == BinaryObjectScanner.Models.NewExecutable.OperatingSystem.WINDOWS
|
||||
&& nex.AdditionalFlags == 0x00
|
||||
&& nex.ReturnThunkOffset == 0x0000
|
||||
&& nex.SegmentReferenceThunkOffset == 0x0000
|
||||
&& nex.MinCodeSwapAreaSize == 0x0000
|
||||
&& nex.WindowsSDKRevision == 0x00
|
||||
&& nex.WindowsSDKVersion == 0x03)
|
||||
return "2.0 (16-bit)";
|
||||
|
||||
// Compact 2.0 (16-bit)
|
||||
if (nex.LinkerVersion == 0x11
|
||||
&& nex.LinkerRevision == 0x20
|
||||
&& nex.EntryTableOffset == 0x0080
|
||||
&& nex.EntryTableSize == 0x0002
|
||||
&& nex.CrcChecksum == 0x00000000
|
||||
&& nex.FlagWord == (BinaryObjectScanner.Models.NewExecutable.HeaderFlag.MULTIPLEDATA
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.ProtectedModeOnly
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.FullScreen
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.WindowsPMCompatible)
|
||||
&& nex.AutomaticDataSegmentNumber == 0x0003
|
||||
&& nex.InitialHeapAlloc == 0x2000
|
||||
&& nex.InitialStackAlloc == 0x4000
|
||||
&& nex.InitialCSIPSetting == 0x000124A0
|
||||
&& nex.InitialSSSPSetting == 0x00030000
|
||||
&& nex.FileSegmentCount == 0x0003
|
||||
&& nex.ModuleReferenceTableSize == 0x0003
|
||||
&& nex.NonResidentNameTableSize == 0x004B
|
||||
&& nex.SegmentTableOffset == 0x0040
|
||||
&& nex.ResourceTableOffset == 0x0058
|
||||
&& nex.ResidentNameTableOffset == 0x0058
|
||||
&& nex.ModuleReferenceTableOffset == 0x0064
|
||||
&& nex.ImportedNamesTableOffset == 0x006A
|
||||
&& nex.NonResidentNamesTableOffset == 0x00000192
|
||||
&& nex.MovableEntriesCount == 0x0000
|
||||
&& nex.SegmentAlignmentShiftCount == 0x0001
|
||||
&& nex.ResourceEntriesCount == 0x0000
|
||||
&& nex.TargetOperatingSystem == BinaryObjectScanner.Models.NewExecutable.OperatingSystem.WINDOWS
|
||||
&& nex.AdditionalFlags == 0x00
|
||||
&& nex.ReturnThunkOffset == 0x0000
|
||||
&& nex.SegmentReferenceThunkOffset == 0x0000
|
||||
&& nex.MinCodeSwapAreaSize == 0x0000
|
||||
&& nex.WindowsSDKRevision == 0x00
|
||||
&& nex.WindowsSDKVersion == 0x03)
|
||||
return "Compact 2.0 (16-bit)";
|
||||
|
||||
// Software Installation 2.0 (16-bit)
|
||||
if (nex.LinkerVersion == 0x11
|
||||
&& nex.LinkerRevision == 0x20
|
||||
&& nex.EntryTableOffset == 0x00CD
|
||||
&& nex.EntryTableSize == 0x0002
|
||||
&& nex.CrcChecksum == 0x00000000
|
||||
&& nex.FlagWord == (BinaryObjectScanner.Models.NewExecutable.HeaderFlag.MULTIPLEDATA
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.FullScreen
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.WindowsPMCompatible)
|
||||
&& nex.AutomaticDataSegmentNumber == 0x0003
|
||||
&& nex.InitialHeapAlloc == 0x2000
|
||||
&& nex.InitialStackAlloc == 0x4000
|
||||
&& nex.InitialCSIPSetting == 0x000136FA
|
||||
&& nex.InitialSSSPSetting == 0x00030000
|
||||
&& nex.FileSegmentCount == 0x0003
|
||||
&& nex.ModuleReferenceTableSize == 0x0005
|
||||
&& nex.NonResidentNameTableSize == 0x004B
|
||||
&& nex.SegmentTableOffset == 0x0040
|
||||
&& nex.ResourceTableOffset == 0x0058
|
||||
&& nex.ResidentNameTableOffset == 0x0097
|
||||
&& nex.ModuleReferenceTableOffset == 0x00A3
|
||||
&& nex.ImportedNamesTableOffset == 0x00AD
|
||||
&& nex.NonResidentNamesTableOffset == 0x000001DF
|
||||
&& nex.MovableEntriesCount == 0x0000
|
||||
&& nex.SegmentAlignmentShiftCount == 0x0001
|
||||
&& nex.ResourceEntriesCount == 0x0000
|
||||
&& nex.TargetOperatingSystem == BinaryObjectScanner.Models.NewExecutable.OperatingSystem.WINDOWS
|
||||
&& nex.AdditionalFlags == 0x00
|
||||
&& nex.ReturnThunkOffset == 0x0000
|
||||
&& nex.SegmentReferenceThunkOffset == 0x0000
|
||||
&& nex.MinCodeSwapAreaSize == 0x0000
|
||||
&& nex.WindowsSDKRevision == 0x00
|
||||
&& nex.WindowsSDKVersion == 0x03)
|
||||
return "Software Installation 2.0 (16-bit)";
|
||||
|
||||
#endregion
|
||||
|
||||
#region 2.1 RC2 Variants
|
||||
|
||||
// 2.1 RC2 (MS-DOS/16-bit)
|
||||
if (nex.LinkerVersion == 0x11
|
||||
&& nex.LinkerRevision == 0x20
|
||||
&& nex.EntryTableOffset == 0x0086
|
||||
&& nex.EntryTableSize == 0x0002
|
||||
&& nex.CrcChecksum == 0x00000000
|
||||
&& nex.FlagWord == (BinaryObjectScanner.Models.NewExecutable.HeaderFlag.MULTIPLEDATA
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.ProtectedModeOnly
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.FullScreen
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.WindowsPMCompatible)
|
||||
&& nex.AutomaticDataSegmentNumber == 0x0003
|
||||
&& nex.InitialHeapAlloc == 0x2000
|
||||
&& nex.InitialStackAlloc == 0x4000
|
||||
&& nex.InitialCSIPSetting == 0x00013386
|
||||
&& nex.InitialSSSPSetting == 0x00030000
|
||||
&& nex.FileSegmentCount == 0x0003
|
||||
&& nex.ModuleReferenceTableSize == 0x0004
|
||||
&& nex.NonResidentNameTableSize == 0x004B
|
||||
&& nex.SegmentTableOffset == 0x0040
|
||||
&& nex.ResourceTableOffset == 0x0058
|
||||
&& nex.ResidentNameTableOffset == 0x0058
|
||||
&& nex.ModuleReferenceTableOffset == 0x0064
|
||||
&& nex.ImportedNamesTableOffset == 0x006C
|
||||
&& nex.NonResidentNamesTableOffset == 0x000043C8
|
||||
&& nex.MovableEntriesCount == 0x0000
|
||||
&& nex.SegmentAlignmentShiftCount == 0x0001
|
||||
&& nex.ResourceEntriesCount == 0x0000
|
||||
&& nex.TargetOperatingSystem == BinaryObjectScanner.Models.NewExecutable.OperatingSystem.WINDOWS
|
||||
&& nex.AdditionalFlags == 0x00
|
||||
&& nex.ReturnThunkOffset == 0x0000
|
||||
&& nex.SegmentReferenceThunkOffset == 0x0000
|
||||
&& nex.MinCodeSwapAreaSize == 0x0000
|
||||
&& nex.WindowsSDKRevision == 0x00
|
||||
&& nex.WindowsSDKVersion == 0x03)
|
||||
return "2.1 RC2 (MS-DOS/16-bit)";
|
||||
|
||||
// 2.1 RC2 (16-bit)
|
||||
if (nex.LinkerVersion == 0x11
|
||||
&& nex.LinkerRevision == 0x20
|
||||
&& nex.EntryTableOffset == 0x00BE
|
||||
&& nex.EntryTableSize == 0x0002
|
||||
&& nex.CrcChecksum == 0x00000000
|
||||
&& nex.FlagWord == (BinaryObjectScanner.Models.NewExecutable.HeaderFlag.MULTIPLEDATA
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.FullScreen
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.WindowsPMCompatible)
|
||||
&& nex.AutomaticDataSegmentNumber == 0x0003
|
||||
&& nex.InitialHeapAlloc == 0x2000
|
||||
&& nex.InitialStackAlloc == 0x4000
|
||||
&& nex.InitialCSIPSetting == 0x00013E56
|
||||
&& nex.InitialSSSPSetting == 0x00030000
|
||||
&& nex.FileSegmentCount == 0x0003
|
||||
&& nex.ModuleReferenceTableSize == 0x0004
|
||||
&& nex.NonResidentNameTableSize == 0x004B
|
||||
&& nex.SegmentTableOffset == 0x0040
|
||||
&& nex.ResourceTableOffset == 0x0058
|
||||
&& nex.ResidentNameTableOffset == 0x0090
|
||||
&& nex.ModuleReferenceTableOffset == 0x009C
|
||||
&& nex.ImportedNamesTableOffset == 0x00A4
|
||||
&& nex.NonResidentNamesTableOffset == 0x000001D0
|
||||
&& nex.MovableEntriesCount == 0x0000
|
||||
&& nex.SegmentAlignmentShiftCount == 0x0001
|
||||
&& nex.ResourceEntriesCount == 0x0000
|
||||
&& nex.TargetOperatingSystem == BinaryObjectScanner.Models.NewExecutable.OperatingSystem.WINDOWS
|
||||
&& nex.AdditionalFlags == 0x00
|
||||
&& nex.ReturnThunkOffset == 0x0000
|
||||
&& nex.SegmentReferenceThunkOffset == 0x0000
|
||||
&& nex.MinCodeSwapAreaSize == 0x0000
|
||||
&& nex.WindowsSDKRevision == 0x00
|
||||
&& nex.WindowsSDKVersion == 0x03)
|
||||
return "2.1 RC2 (16-bit)";
|
||||
|
||||
// Compact 2.1 RC2 (16-bit)
|
||||
if (nex.LinkerVersion == 0x11
|
||||
&& nex.LinkerRevision == 0x20
|
||||
&& nex.EntryTableOffset == 0x0080
|
||||
&& nex.EntryTableSize == 0x0002
|
||||
&& nex.CrcChecksum == 0x00000000
|
||||
&& nex.FlagWord == (BinaryObjectScanner.Models.NewExecutable.HeaderFlag.MULTIPLEDATA
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.ProtectedModeOnly
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.FullScreen
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.WindowsPMCompatible)
|
||||
&& nex.AutomaticDataSegmentNumber == 0x0003
|
||||
&& nex.InitialHeapAlloc == 0x2000
|
||||
&& nex.InitialStackAlloc == 0x4000
|
||||
&& nex.InitialCSIPSetting == 0x00012B84
|
||||
&& nex.InitialSSSPSetting == 0x00030000
|
||||
&& nex.FileSegmentCount == 0x0003
|
||||
&& nex.ModuleReferenceTableSize == 0x0003
|
||||
&& nex.NonResidentNameTableSize == 0x004B
|
||||
&& nex.SegmentTableOffset == 0x0040
|
||||
&& nex.ResourceTableOffset == 0x0058
|
||||
&& nex.ResidentNameTableOffset == 0x0058
|
||||
&& nex.ModuleReferenceTableOffset == 0x0064
|
||||
&& nex.ImportedNamesTableOffset == 0x006A
|
||||
&& nex.NonResidentNamesTableOffset == 0x00000192
|
||||
&& nex.MovableEntriesCount == 0x0000
|
||||
&& nex.SegmentAlignmentShiftCount == 0x0001
|
||||
&& nex.ResourceEntriesCount == 0x0000
|
||||
&& nex.TargetOperatingSystem == BinaryObjectScanner.Models.NewExecutable.OperatingSystem.WINDOWS
|
||||
&& nex.AdditionalFlags == 0x00
|
||||
&& nex.ReturnThunkOffset == 0x0000
|
||||
&& nex.SegmentReferenceThunkOffset == 0x0000
|
||||
&& nex.MinCodeSwapAreaSize == 0x0000
|
||||
&& nex.WindowsSDKRevision == 0x00
|
||||
&& nex.WindowsSDKVersion == 0x03)
|
||||
return "Compact 2.1 RC2 (16-bit)";
|
||||
|
||||
// Software Installation 2.1 RC2 (16-bit)
|
||||
if (nex.LinkerVersion == 0x11
|
||||
&& nex.LinkerRevision == 0x20
|
||||
&& nex.EntryTableOffset == 0x00BE
|
||||
&& nex.EntryTableSize == 0x0002
|
||||
&& nex.CrcChecksum == 0x00000000
|
||||
&& nex.FlagWord == (BinaryObjectScanner.Models.NewExecutable.HeaderFlag.MULTIPLEDATA
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.FullScreen
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.WindowsPMCompatible)
|
||||
&& nex.AutomaticDataSegmentNumber == 0x0003
|
||||
&& nex.InitialHeapAlloc == 0x2000
|
||||
&& nex.InitialStackAlloc == 0x4000
|
||||
&& nex.InitialCSIPSetting == 0x000143AC
|
||||
&& nex.InitialSSSPSetting == 0x00030000
|
||||
&& nex.FileSegmentCount == 0x0003
|
||||
&& nex.ModuleReferenceTableSize == 0x0004
|
||||
&& nex.NonResidentNameTableSize == 0x004B
|
||||
&& nex.SegmentTableOffset == 0x0040
|
||||
&& nex.ResourceTableOffset == 0x0058
|
||||
&& nex.ResidentNameTableOffset == 0x0090
|
||||
&& nex.ModuleReferenceTableOffset == 0x009C
|
||||
&& nex.ImportedNamesTableOffset == 0x00A4
|
||||
&& nex.NonResidentNamesTableOffset == 0x000001D0
|
||||
&& nex.MovableEntriesCount == 0x0000
|
||||
&& nex.SegmentAlignmentShiftCount == 0x0001
|
||||
&& nex.ResourceEntriesCount == 0x0000
|
||||
&& nex.TargetOperatingSystem == BinaryObjectScanner.Models.NewExecutable.OperatingSystem.WINDOWS
|
||||
&& nex.AdditionalFlags == 0x00
|
||||
&& nex.ReturnThunkOffset == 0x0000
|
||||
&& nex.SegmentReferenceThunkOffset == 0x0000
|
||||
&& nex.MinCodeSwapAreaSize == 0x0000
|
||||
&& nex.WindowsSDKRevision == 0x00
|
||||
&& nex.WindowsSDKVersion == 0x03)
|
||||
return "Software Installation 2.1 RC2 (16-bit)";
|
||||
|
||||
#endregion
|
||||
|
||||
#region 2.1 Variants
|
||||
|
||||
// 2.1 (MS-DOS/16-bit)
|
||||
if (nex.LinkerVersion == 0x11
|
||||
&& nex.LinkerRevision == 0x20
|
||||
&& nex.EntryTableOffset == 0x0086
|
||||
&& nex.EntryTableSize == 0x0002
|
||||
&& nex.CrcChecksum == 0x00000000
|
||||
&& nex.FlagWord == (BinaryObjectScanner.Models.NewExecutable.HeaderFlag.MULTIPLEDATA
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.ProtectedModeOnly
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.FullScreen
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.WindowsPMCompatible)
|
||||
&& nex.AutomaticDataSegmentNumber == 0x0003
|
||||
&& nex.InitialHeapAlloc == 0x2000
|
||||
&& nex.InitialStackAlloc == 0x3A00
|
||||
&& nex.InitialCSIPSetting == 0x00013396
|
||||
&& nex.InitialSSSPSetting == 0x00030000
|
||||
&& nex.FileSegmentCount == 0x0003
|
||||
&& nex.ModuleReferenceTableSize == 0x0004
|
||||
&& nex.NonResidentNameTableSize == 0x004B
|
||||
&& nex.SegmentTableOffset == 0x0040
|
||||
&& nex.ResourceTableOffset == 0x0058
|
||||
&& nex.ResidentNameTableOffset == 0x0058
|
||||
&& nex.ModuleReferenceTableOffset == 0x0064
|
||||
&& nex.ImportedNamesTableOffset == 0x006C
|
||||
&& nex.NonResidentNamesTableOffset == 0x000043C8
|
||||
&& nex.MovableEntriesCount == 0x0000
|
||||
&& nex.SegmentAlignmentShiftCount == 0x0001
|
||||
&& nex.ResourceEntriesCount == 0x0000
|
||||
&& nex.TargetOperatingSystem == BinaryObjectScanner.Models.NewExecutable.OperatingSystem.WINDOWS
|
||||
&& nex.AdditionalFlags == 0x00
|
||||
&& nex.ReturnThunkOffset == 0x0000
|
||||
&& nex.SegmentReferenceThunkOffset == 0x0000
|
||||
&& nex.MinCodeSwapAreaSize == 0x0000
|
||||
&& nex.WindowsSDKRevision == 0x00
|
||||
&& nex.WindowsSDKVersion == 0x03)
|
||||
return "2.1 (MS-DOS/16-bit)";
|
||||
|
||||
// 2.1 (16-bit)
|
||||
if (nex.LinkerVersion == 0x11
|
||||
&& nex.LinkerRevision == 0x20
|
||||
&& nex.EntryTableOffset == 0x00BE
|
||||
&& nex.EntryTableSize == 0x0002
|
||||
&& nex.CrcChecksum == 0x00000000
|
||||
&& nex.FlagWord == (BinaryObjectScanner.Models.NewExecutable.HeaderFlag.MULTIPLEDATA
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.FullScreen
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.WindowsPMCompatible)
|
||||
&& nex.AutomaticDataSegmentNumber == 0x0003
|
||||
&& nex.InitialHeapAlloc == 0x2000
|
||||
&& nex.InitialStackAlloc == 0x3A00
|
||||
&& nex.InitialCSIPSetting == 0x00013E7E
|
||||
&& nex.InitialSSSPSetting == 0x00030000
|
||||
&& nex.FileSegmentCount == 0x0003
|
||||
&& nex.ModuleReferenceTableSize == 0x0004
|
||||
&& nex.NonResidentNameTableSize == 0x004B
|
||||
&& nex.SegmentTableOffset == 0x0040
|
||||
&& nex.ResourceTableOffset == 0x0058
|
||||
&& nex.ResidentNameTableOffset == 0x0090
|
||||
&& nex.ModuleReferenceTableOffset == 0x009C
|
||||
&& nex.ImportedNamesTableOffset == 0x00A4
|
||||
&& nex.NonResidentNamesTableOffset == 0x000001D0
|
||||
&& nex.MovableEntriesCount == 0x0000
|
||||
&& nex.SegmentAlignmentShiftCount == 0x0001
|
||||
&& nex.ResourceEntriesCount == 0x0000
|
||||
&& nex.TargetOperatingSystem == BinaryObjectScanner.Models.NewExecutable.OperatingSystem.WINDOWS
|
||||
&& nex.AdditionalFlags == 0x00
|
||||
&& nex.ReturnThunkOffset == 0x0000
|
||||
&& nex.SegmentReferenceThunkOffset == 0x0000
|
||||
&& nex.MinCodeSwapAreaSize == 0x0000
|
||||
&& nex.WindowsSDKRevision == 0x00
|
||||
&& nex.WindowsSDKVersion == 0x03)
|
||||
return "2.1 (16-bit)";
|
||||
|
||||
// Compact 2.1 (16-bit)
|
||||
if (nex.LinkerVersion == 0x11
|
||||
&& nex.LinkerRevision == 0x20
|
||||
&& nex.EntryTableOffset == 0x0080
|
||||
&& nex.EntryTableSize == 0x0002
|
||||
&& nex.CrcChecksum == 0x00000000
|
||||
&& nex.FlagWord == (BinaryObjectScanner.Models.NewExecutable.HeaderFlag.MULTIPLEDATA
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.ProtectedModeOnly
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.FullScreen
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.WindowsPMCompatible)
|
||||
&& nex.AutomaticDataSegmentNumber == 0x0003
|
||||
&& nex.InitialHeapAlloc == 0x2000
|
||||
&& nex.InitialStackAlloc == 0x3A00
|
||||
&& nex.InitialCSIPSetting == 0x00012B90
|
||||
&& nex.InitialSSSPSetting == 0x00030000
|
||||
&& nex.FileSegmentCount == 0x0003
|
||||
&& nex.ModuleReferenceTableSize == 0x0003
|
||||
&& nex.NonResidentNameTableSize == 0x004B
|
||||
&& nex.SegmentTableOffset == 0x0040
|
||||
&& nex.ResourceTableOffset == 0x0058
|
||||
&& nex.ResidentNameTableOffset == 0x0058
|
||||
&& nex.ModuleReferenceTableOffset == 0x0064
|
||||
&& nex.ImportedNamesTableOffset == 0x006A
|
||||
&& nex.NonResidentNamesTableOffset == 0x00000192
|
||||
&& nex.MovableEntriesCount == 0x0000
|
||||
&& nex.SegmentAlignmentShiftCount == 0x0001
|
||||
&& nex.ResourceEntriesCount == 0x0000
|
||||
&& nex.TargetOperatingSystem == BinaryObjectScanner.Models.NewExecutable.OperatingSystem.WINDOWS
|
||||
&& nex.AdditionalFlags == 0x00
|
||||
&& nex.ReturnThunkOffset == 0x0000
|
||||
&& nex.SegmentReferenceThunkOffset == 0x0000
|
||||
&& nex.MinCodeSwapAreaSize == 0x0000
|
||||
&& nex.WindowsSDKRevision == 0x00
|
||||
&& nex.WindowsSDKVersion == 0x03)
|
||||
return "Compact 2.1 (16-bit)";
|
||||
|
||||
// Software Installation 2.1 (16-bit)
|
||||
if (nex.LinkerVersion == 0x11
|
||||
&& nex.LinkerRevision == 0x20
|
||||
&& nex.EntryTableOffset == 0x00BE
|
||||
&& nex.EntryTableSize == 0x0002
|
||||
&& nex.CrcChecksum == 0x00000000
|
||||
&& nex.FlagWord == (BinaryObjectScanner.Models.NewExecutable.HeaderFlag.MULTIPLEDATA
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.FullScreen
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.WindowsPMCompatible)
|
||||
&& nex.AutomaticDataSegmentNumber == 0x0003
|
||||
&& nex.InitialHeapAlloc == 0x2000
|
||||
&& nex.InitialStackAlloc == 0x3A00
|
||||
&& nex.InitialCSIPSetting == 0x00014408
|
||||
&& nex.InitialSSSPSetting == 0x00030000
|
||||
&& nex.FileSegmentCount == 0x0003
|
||||
&& nex.ModuleReferenceTableSize == 0x0004
|
||||
&& nex.NonResidentNameTableSize == 0x004B
|
||||
&& nex.SegmentTableOffset == 0x0040
|
||||
&& nex.ResourceTableOffset == 0x0058
|
||||
&& nex.ResidentNameTableOffset == 0x0090
|
||||
&& nex.ModuleReferenceTableOffset == 0x009C
|
||||
&& nex.ImportedNamesTableOffset == 0x00A4
|
||||
&& nex.NonResidentNamesTableOffset == 0x000001D0
|
||||
&& nex.MovableEntriesCount == 0x0000
|
||||
&& nex.SegmentAlignmentShiftCount == 0x0001
|
||||
&& nex.ResourceEntriesCount == 0x0000
|
||||
&& nex.TargetOperatingSystem == BinaryObjectScanner.Models.NewExecutable.OperatingSystem.WINDOWS
|
||||
&& nex.AdditionalFlags == 0x00
|
||||
&& nex.ReturnThunkOffset == 0x0000
|
||||
&& nex.SegmentReferenceThunkOffset == 0x0000
|
||||
&& nex.MinCodeSwapAreaSize == 0x0000
|
||||
&& nex.WindowsSDKRevision == 0x00
|
||||
&& nex.WindowsSDKVersion == 0x03)
|
||||
return "Software Installation 2.1 (16-bit)";
|
||||
|
||||
#endregion
|
||||
|
||||
#region Misc. Variants
|
||||
|
||||
// Personal Edition (16-bit)
|
||||
if (nex.LinkerVersion == 0x11
|
||||
&& nex.LinkerRevision == 0x20
|
||||
&& nex.EntryTableOffset == 0x0086
|
||||
&& nex.EntryTableSize == 0x0002
|
||||
&& nex.CrcChecksum == 0x00000000
|
||||
&& nex.FlagWord == (BinaryObjectScanner.Models.NewExecutable.HeaderFlag.MULTIPLEDATA
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.ProtectedModeOnly
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.FullScreen
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.WindowsPMCompatible)
|
||||
&& nex.AutomaticDataSegmentNumber == 0x0003
|
||||
&& nex.InitialHeapAlloc == 0x2000
|
||||
&& nex.InitialStackAlloc == 0x4000
|
||||
&& nex.InitialCSIPSetting == 0x0001317C
|
||||
&& nex.InitialSSSPSetting == 0x00030000
|
||||
&& nex.FileSegmentCount == 0x0003
|
||||
&& nex.ModuleReferenceTableSize == 0x0004
|
||||
&& nex.NonResidentNameTableSize == 0x004B
|
||||
&& nex.SegmentTableOffset == 0x0040
|
||||
&& nex.ResourceTableOffset == 0x0058
|
||||
&& nex.ResidentNameTableOffset == 0x0058
|
||||
&& nex.ModuleReferenceTableOffset == 0x0064
|
||||
&& nex.ImportedNamesTableOffset == 0x006C
|
||||
&& nex.NonResidentNamesTableOffset == 0x00000198
|
||||
&& nex.MovableEntriesCount == 0x0000
|
||||
&& nex.SegmentAlignmentShiftCount == 0x0001
|
||||
&& nex.ResourceEntriesCount == 0x0000
|
||||
&& nex.TargetOperatingSystem == BinaryObjectScanner.Models.NewExecutable.OperatingSystem.WINDOWS
|
||||
&& nex.AdditionalFlags == 0x00
|
||||
&& nex.ReturnThunkOffset == 0x0000
|
||||
&& nex.SegmentReferenceThunkOffset == 0x0000
|
||||
&& nex.MinCodeSwapAreaSize == 0x0000
|
||||
&& nex.WindowsSDKRevision == 0x00
|
||||
&& nex.WindowsSDKVersion == 0x03)
|
||||
return "Personal Edition (16-bit)";
|
||||
|
||||
// Personal Edition 32-bit (16-bit)
|
||||
if (nex.LinkerVersion == 0x11
|
||||
&& nex.LinkerRevision == 0x20
|
||||
&& nex.EntryTableOffset == 0x00BE
|
||||
&& nex.EntryTableSize == 0x0002
|
||||
&& nex.CrcChecksum == 0x00000000
|
||||
&& nex.FlagWord == (BinaryObjectScanner.Models.NewExecutable.HeaderFlag.MULTIPLEDATA
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.FullScreen
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.WindowsPMCompatible)
|
||||
&& nex.AutomaticDataSegmentNumber == 0x0003
|
||||
&& nex.InitialHeapAlloc == 0x2000
|
||||
&& nex.InitialStackAlloc == 0x3C00
|
||||
&& nex.InitialCSIPSetting == 0x00013E7C
|
||||
&& nex.InitialSSSPSetting == 0x00030000
|
||||
&& nex.FileSegmentCount == 0x0003
|
||||
&& nex.ModuleReferenceTableSize == 0x0004
|
||||
&& nex.NonResidentNameTableSize == 0x004B
|
||||
&& nex.SegmentTableOffset == 0x0040
|
||||
&& nex.ResourceTableOffset == 0x0058
|
||||
&& nex.ResidentNameTableOffset == 0x0090
|
||||
&& nex.ModuleReferenceTableOffset == 0x009C
|
||||
&& nex.ImportedNamesTableOffset == 0x00A4
|
||||
&& nex.NonResidentNamesTableOffset == 0x000001D0
|
||||
&& nex.MovableEntriesCount == 0x0000
|
||||
&& nex.SegmentAlignmentShiftCount == 0x0001
|
||||
&& nex.ResourceEntriesCount == 0x0000
|
||||
&& nex.TargetOperatingSystem == BinaryObjectScanner.Models.NewExecutable.OperatingSystem.WINDOWS
|
||||
&& nex.AdditionalFlags == 0x00
|
||||
&& nex.ReturnThunkOffset == 0x0000
|
||||
&& nex.SegmentReferenceThunkOffset == 0x0000
|
||||
&& nex.MinCodeSwapAreaSize == 0x0000
|
||||
&& nex.WindowsSDKRevision == 0x00
|
||||
&& nex.WindowsSDKVersion == 0x03)
|
||||
return "Personal Edition 32-bit (16-bit)";
|
||||
|
||||
// Personal Edition 32-bit Build 1260/1285 (16-bit)
|
||||
if (nex.LinkerVersion == 0x11
|
||||
&& nex.LinkerRevision == 0x20
|
||||
&& nex.EntryTableOffset == 0x00C6
|
||||
&& nex.EntryTableSize == 0x0002
|
||||
&& nex.CrcChecksum == 0x00000000
|
||||
&& nex.FlagWord == (BinaryObjectScanner.Models.NewExecutable.HeaderFlag.MULTIPLEDATA
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.FullScreen
|
||||
| BinaryObjectScanner.Models.NewExecutable.HeaderFlag.WindowsPMCompatible)
|
||||
&& nex.AutomaticDataSegmentNumber == 0x0003
|
||||
&& nex.InitialHeapAlloc == 0x43DC
|
||||
&& nex.InitialStackAlloc == 0x2708
|
||||
&& nex.InitialCSIPSetting == 0x00014ADC
|
||||
&& nex.InitialSSSPSetting == 0x00030000
|
||||
&& nex.FileSegmentCount == 0x0003
|
||||
&& nex.ModuleReferenceTableSize == 0x0005
|
||||
&& nex.NonResidentNameTableSize == 0x004B
|
||||
&& nex.SegmentTableOffset == 0x0040
|
||||
&& nex.ResourceTableOffset == 0x0058
|
||||
&& nex.ResidentNameTableOffset == 0x0090
|
||||
&& nex.ModuleReferenceTableOffset == 0x009C
|
||||
&& nex.ImportedNamesTableOffset == 0x00A6
|
||||
&& nex.NonResidentNamesTableOffset == 0x000001D8
|
||||
&& nex.MovableEntriesCount == 0x0000
|
||||
&& nex.SegmentAlignmentShiftCount == 0x0001
|
||||
&& nex.ResourceEntriesCount == 0x0000
|
||||
&& nex.TargetOperatingSystem == BinaryObjectScanner.Models.NewExecutable.OperatingSystem.WINDOWS
|
||||
&& nex.AdditionalFlags == 0x00
|
||||
&& nex.ReturnThunkOffset == 0x0000
|
||||
&& nex.SegmentReferenceThunkOffset == 0x0000
|
||||
&& nex.MinCodeSwapAreaSize == 0x0000
|
||||
&& nex.WindowsSDKRevision == 0x00
|
||||
&& nex.WindowsSDKVersion == 0x03)
|
||||
return "Personal Edition 32-bit Build 1260/1285 (16-bit)";
|
||||
|
||||
#endregion
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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
|
||||
private string GetPEExportDirectoryVersion(PortableExecutable pex)
|
||||
{
|
||||
string sfxFileName = pex.ExportTable.ExportDirectoryTable.Name;
|
||||
uint sfxTimeDateStamp = pex.ExportTable.ExportDirectoryTable.TimeDateStamp;
|
||||
string assemblyVersion = pex.AssemblyVersion ?? "Unknown Version";
|
||||
|
||||
// Standard
|
||||
if (sfxFileName == "VW95SE.SFX" || sfxFileName == "ST32E.SFX"
|
||||
|| sfxFileName == "WZIPSE32.exe" || sfxFileName == "SI32LPG.SFX"
|
||||
|| sfxFileName == "ST32E.WZE")
|
||||
{
|
||||
switch (sfxTimeDateStamp)
|
||||
{
|
||||
case 842636344:
|
||||
return "2.0 (32-bit)";
|
||||
case 865370756:
|
||||
return "2.1 RC2 (32-bit)";
|
||||
case 869059925:
|
||||
return "2.1 (32-bit)";
|
||||
case 979049321:
|
||||
return "2.2.4003";
|
||||
case 1149714685:
|
||||
return "3.0.7158";
|
||||
case 1185211734:
|
||||
return "3.1.7556";
|
||||
case 1185211920:
|
||||
return "3.1.7556";
|
||||
case 1235490556:
|
||||
return "4.0.8421";
|
||||
case 1235490757:
|
||||
return "4.0.8421";
|
||||
case 1235490687:
|
||||
return "4.0.8421"; // 3.1.8421.0, SI32LPG?
|
||||
case 1257193383:
|
||||
return "4.0.8672"; // 3.1.8672.0
|
||||
case 1257193543:
|
||||
return "4.0.8672";
|
||||
case 1470410848:
|
||||
return "4.0.12218"; // 4.0.1221.0
|
||||
default:
|
||||
return $"{assemblyVersion} (32-bit)";
|
||||
}
|
||||
}
|
||||
|
||||
// Personal Edition
|
||||
if (sfxFileName == "VW95LE.SFX" || sfxFileName == "PE32E.SFX"
|
||||
|| sfxFileName == "wzsepe32.exe" || sfxFileName == "SI32PE.SFX"
|
||||
|| sfxFileName == "SI32LPE.SFX")
|
||||
{
|
||||
switch (sfxTimeDateStamp)
|
||||
{
|
||||
case 845061601:
|
||||
return "Personal Edition (32-bit)"; // TODO: Find version
|
||||
case 868303343:
|
||||
return "Personal Edition (32-bit)"; // TODO: Find version
|
||||
case 868304170:
|
||||
return "Personal Edition (32-bit)"; // TODO: Find version
|
||||
case 906039079:
|
||||
return "Personal Edition 2.2.1260 (32-bit)";
|
||||
case 906040543:
|
||||
return "Personal Edition 2.2.1260 (32-bit)";
|
||||
case 908628435:
|
||||
return "Personal Edition 2.2.1285 (32-bit)";
|
||||
case 908628785:
|
||||
return "Personal Edition 2.2.1285 (32-bit)";
|
||||
case 956165981:
|
||||
return "Personal Edition 2.2.3063";
|
||||
case 956166038:
|
||||
return "Personal Edition 2.2.3063";
|
||||
case 1006353695:
|
||||
return "Personal Edition 2.2.4325";
|
||||
case 1006353714:
|
||||
return "Personal Edition 2.2.4325"; // 8.1.0.0
|
||||
case 1076515698:
|
||||
return "Personal Edition 2.2.6028";
|
||||
case 1076515784:
|
||||
return "Personal Edition 2.2.6028"; // 9.0.6028.0
|
||||
case 1092688561:
|
||||
return "Personal Edition 2.2.6224";
|
||||
case 1092688645:
|
||||
return "Personal Edition 2.2.6224"; // 9.0.6224.0
|
||||
case 1125074095:
|
||||
return "Personal Edition 2.2.6604";
|
||||
case 1125074162:
|
||||
return "Personal Edition 2.2.6604"; // 10.0.6604.0
|
||||
case 1130153399:
|
||||
return "Personal Edition 2.2.6663";
|
||||
case 1130153428:
|
||||
return "Personal Edition 2.2.6663"; // 10.0.6663.0
|
||||
case 1149714176:
|
||||
return "Personal Edition 3.0.7158";
|
||||
case 1163137967:
|
||||
return "Personal Edition 3.0.7305";
|
||||
case 1163137994:
|
||||
return "Personal Edition 3.0.7313"; // 11.0.7313.0
|
||||
case 1176345383:
|
||||
return "Personal Edition 3.0.7452";
|
||||
case 1176345423:
|
||||
return "Personal Edition 3.1.7466"; // 11.1.7466.0
|
||||
case 1184106698:
|
||||
return "Personal Edition 3.1.7556";
|
||||
case 1207280880:
|
||||
return "Personal Edition 4.0.8060"; // 2.3.7382.0
|
||||
case 1207280892:
|
||||
return "Personal Edition 4.0.8094"; // 11.2.8094.0
|
||||
case 1220904506:
|
||||
return "Personal Edition 4.0.8213"; // 2.3.7382.0
|
||||
case 1220904518:
|
||||
return "Personal Edition 4.0.8252"; // 12.0.8252.0
|
||||
case 1235490648:
|
||||
return "Personal Edition 4.0.8421"; // 3.1.8421.0
|
||||
case 1242049399:
|
||||
return "Personal Edition 4.0.8497"; // 12.1.8497.0
|
||||
case 1257193469:
|
||||
return "Personal Edition 4.0.8672"; // 3.1.8672.0, SI32LPE?
|
||||
default:
|
||||
return $"Personal Edition {assemblyVersion} (32-bit)";
|
||||
}
|
||||
}
|
||||
|
||||
// Software Installation
|
||||
else if (sfxFileName == "VW95SRE.SFX" || sfxFileName == "SI32E.SFX"
|
||||
|| sfxFileName == "SI32E.WZE")
|
||||
{
|
||||
switch (sfxTimeDateStamp)
|
||||
{
|
||||
case 842636381:
|
||||
return "Software Installation 2.0 (32-bit)";
|
||||
case 865370800:
|
||||
return "Software Installation 2.1 RC2 (32-bit)";
|
||||
case 869059963:
|
||||
return "Software Installation 2.1 (32-bit)";
|
||||
case 893107697:
|
||||
return "Software Installation 2.2.1110 (32-bit)";
|
||||
case 952007369:
|
||||
return "Software Installation 2.2.3063";
|
||||
case 1006352634:
|
||||
return "Software Installation 2.2.4325"; // +Personal Edition?
|
||||
case 979049345:
|
||||
return "Software Installation 2.2.4403";
|
||||
case 1026227373:
|
||||
return "Software Installation 2.2.5196"; // +Personal Edition?
|
||||
case 1090582390:
|
||||
return "Software Installation 2.2.6202"; // +Personal Edition?
|
||||
case 1149714757:
|
||||
return "Software Installation 3.0.7158";
|
||||
case 1154357628:
|
||||
return "Software Installation 3.0.7212";
|
||||
case 1175234637:
|
||||
return "Software Installation 3.0.7454";
|
||||
case 1185211802:
|
||||
return "Software Installation 3.1.7556";
|
||||
case 1470410906:
|
||||
return "Software Installation 4.0.12218"; // 4.0.1221.0
|
||||
default:
|
||||
return $"Software Installation {assemblyVersion} (32-bit)";
|
||||
}
|
||||
}
|
||||
|
||||
switch (sfxFileName)
|
||||
{
|
||||
// Standard
|
||||
case "VW95SE.SFX":
|
||||
return "Unknown Version (32-bit)"; // TODO: Find starting version
|
||||
case "ST32E.SFX":
|
||||
return "Unknown Version (32-bit)"; // TODO: Find starting version
|
||||
case "WZIPSE32.exe":
|
||||
return "Unknown Version (32-bit)"; // TODO: Find starting version
|
||||
case "SI32LPG.SFX":
|
||||
return "Unknown Version (32-bit)"; // TODO: Find starting version
|
||||
case "ST32E.WZE":
|
||||
return "Unknown Version (32-bit)"; // TODO: Find starting version
|
||||
|
||||
// Personal Edition
|
||||
case "VW95LE.SFX":
|
||||
return "Unknown Version before Personal Edition Build 1285 (32-bit)";
|
||||
case "PE32E.SFX":
|
||||
return "Unknown Version after Personal Edition Build 1285 (32-bit)";
|
||||
case "wzsepe32.exe":
|
||||
return "Unknown Version Personal Edition (32-bit)"; // TODO: Find starting version
|
||||
case "SI32PE.SFX":
|
||||
return "Unknown Version Personal Edition (32-bit)"; // TODO: Find starting version
|
||||
case "SI32LPE.SFX":
|
||||
return "Unknown Version Personal Edition (32-bit)"; // TODO: Find starting version
|
||||
|
||||
// Software Installation
|
||||
case "VW95SRE.SFX":
|
||||
return "Unknown Version before Software Installation 2.1 (32-bit)";
|
||||
case "SI32E.SFX":
|
||||
return "Unknown Version after Software Installation 2.1 (32-bit)";
|
||||
case "SI32E.WZE":
|
||||
return "Unknown Version Software Installation (32-bit)"; // TODO: Find starting version
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
390
BinaryObjectScanner.Packer/WiseInstaller.cs
Normal file
390
BinaryObjectScanner.Packer/WiseInstaller.cs
Normal file
@@ -0,0 +1,390 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Matching;
|
||||
using BinaryObjectScanner.Utilities;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
using Wise = WiseUnpacker.WiseUnpacker;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt
|
||||
public class WiseInstaller : IExtractable, INewExecutableCheck, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckNewExecutable(string file, NewExecutable nex, bool includeDebug)
|
||||
{
|
||||
/// 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";
|
||||
|
||||
// TODO: Investigate STUB.EXE in nonresident-name table
|
||||
|
||||
// TODO: Don't read entire file
|
||||
var data = nex.ReadArbitraryRange();
|
||||
if (data == null)
|
||||
return null;
|
||||
|
||||
var neMatchSets = new List<ContentMatchSet>
|
||||
{
|
||||
// WiseInst
|
||||
new ContentMatchSet(new byte?[] { 0x57, 0x69, 0x73, 0x65, 0x49, 0x6E, 0x73, 0x74 }, "Wise Installation Wizard Module"),
|
||||
|
||||
// WiseMain
|
||||
new ContentMatchSet(new byte?[] { 0x57, 0x69, 0x73, 0x65, 0x4D, 0x61, 0x69, 0x6E }, "Wise Installation Wizard Module"),
|
||||
};
|
||||
|
||||
return MatchUtil.GetFirstMatch(file, data, neMatchSets, includeDebug);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// If we match a known header
|
||||
if (GetPEFormat(pex) != null)
|
||||
return "Wise Installation Wizard Module";
|
||||
|
||||
// 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");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("WiseMain")))
|
||||
return "Wise Installation Wizard Module";
|
||||
}
|
||||
|
||||
// Get the .rdata section strings, if they exist
|
||||
strs = pex.GetFirstSectionStrings(".rdata");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("WiseMain")))
|
||||
return "Wise Installation Wizard Module";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Try to parse as a New Executable
|
||||
NewExecutable nex = NewExecutable.Create(stream);
|
||||
if (nex != null)
|
||||
return ExtractNewExecutable(nex, file, includeDebug);
|
||||
|
||||
// Try to parse as a Portable Executable
|
||||
PortableExecutable pex = PortableExecutable.Create(stream);
|
||||
if (pex != null)
|
||||
return ExtractPortableExecutable(pex, file, includeDebug);
|
||||
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks an NE header to see if it matches a known signature
|
||||
/// </summary>
|
||||
/// <param name="nex">New executable to check</param>
|
||||
/// <returns>True if it matches a known version, false otherwise</returns>
|
||||
private FormatProperty MatchesNEVersion(NewExecutable nex)
|
||||
{
|
||||
// TODO: Offset is _not_ the EXE header address, rather where the data starts. Fix this.
|
||||
switch (nex.Stub_NewExeHeaderAddr)
|
||||
{
|
||||
case 0x84b0:
|
||||
return new FormatProperty { Dll = false, ArchiveStart = 0x11, ArchiveEnd = -1, InitText = false, FilenamePosition = 0x04, NoCrc = true };
|
||||
|
||||
case 0x3e10:
|
||||
return new FormatProperty { Dll = false, ArchiveStart = 0x1e, ArchiveEnd = -1, InitText = false, FilenamePosition = 0x04, NoCrc = false };
|
||||
|
||||
case 0x3e50:
|
||||
return new FormatProperty { Dll = false, ArchiveStart = 0x1e, ArchiveEnd = -1, InitText = false, FilenamePosition = 0x04, NoCrc = false };
|
||||
|
||||
case 0x3c20:
|
||||
return new FormatProperty { Dll = false, ArchiveStart = 0x1e, ArchiveEnd = -1, InitText = false, FilenamePosition = 0x04, NoCrc = false };
|
||||
|
||||
case 0x3c30:
|
||||
return new FormatProperty { Dll = false, ArchiveStart = 0x22, ArchiveEnd = -1, InitText = false, FilenamePosition = 0x04, NoCrc = false };
|
||||
|
||||
case 0x3660:
|
||||
return new FormatProperty { Dll = false, ArchiveStart = 0x40, ArchiveEnd = 0x3c, InitText = false, FilenamePosition = 0x04, NoCrc = false };
|
||||
|
||||
case 0x36f0:
|
||||
return new FormatProperty { Dll = false, ArchiveStart = 0x48, ArchiveEnd = 0x44, InitText = false, FilenamePosition = 0x1c, NoCrc = false };
|
||||
|
||||
case 0x3770:
|
||||
return new FormatProperty { Dll = false, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false };
|
||||
|
||||
case 0x3780:
|
||||
return new FormatProperty { Dll = true, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false };
|
||||
|
||||
case 0x37b0:
|
||||
return new FormatProperty { Dll = true, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false };
|
||||
|
||||
case 0x37d0:
|
||||
return new FormatProperty { Dll = true, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false };
|
||||
|
||||
case 0x3c80:
|
||||
return new FormatProperty { Dll = true, ArchiveStart = 0x5a, ArchiveEnd = 0x4c, InitText = true, FilenamePosition = 0x1c, NoCrc = false };
|
||||
|
||||
case 0x3bd0:
|
||||
return new FormatProperty { Dll = true, ArchiveStart = 0x5a, ArchiveEnd = 0x4c, InitText = true, FilenamePosition = 0x1c, NoCrc = false };
|
||||
|
||||
case 0x3c10:
|
||||
return new FormatProperty { Dll = true, ArchiveStart = 0x5a, ArchiveEnd = 0x4c, InitText = true, FilenamePosition = 0x1c, NoCrc = false };
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks a PE header to see if it matches a known signature
|
||||
/// </summary>
|
||||
/// <param name="pex">Portable executable to check</param>
|
||||
/// <returns>True if it matches a known version, false otherwise</returns>
|
||||
private FormatProperty GetPEFormat(PortableExecutable pex)
|
||||
{
|
||||
if (pex.OverlayAddress == 0x6e00
|
||||
&& pex.GetFirstSection(".text")?.VirtualSize == 0x3cf4
|
||||
&& pex.GetFirstSection(".data")?.VirtualSize == 0x1528)
|
||||
return new FormatProperty { Dll = false, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false };
|
||||
|
||||
else if (pex.OverlayAddress == 0x6e00
|
||||
&& pex.GetFirstSection(".text")?.VirtualSize == 0x3cf4
|
||||
&& pex.GetFirstSection(".data")?.VirtualSize == 0x1568)
|
||||
return new FormatProperty { Dll = false, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false };
|
||||
|
||||
else if (pex.OverlayAddress == 0x6e00
|
||||
&& pex.GetFirstSection(".text")?.VirtualSize == 0x3d54)
|
||||
return new FormatProperty { Dll = false, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false };
|
||||
|
||||
else if (pex.OverlayAddress == 0x6e00
|
||||
&& pex.GetFirstSection(".text")?.VirtualSize == 0x3d44)
|
||||
return new FormatProperty { Dll = false, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false };
|
||||
|
||||
else if (pex.OverlayAddress == 0x6e00
|
||||
&& pex.GetFirstSection(".text")?.VirtualSize == 0x3d04)
|
||||
return new FormatProperty { Dll = false, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false };
|
||||
|
||||
// Found in Binary.WiseCustomCalla
|
||||
else if (pex.OverlayAddress == 0x6200)
|
||||
return new FormatProperty { Dll = true, ArchiveStart = 0x62, ArchiveEnd = 0x4c, InitText = true, FilenamePosition = 0x1c, NoCrc = false };
|
||||
|
||||
else if (pex.OverlayAddress == 0x3000)
|
||||
return new FormatProperty { Dll = false, ArchiveStart = 0x50, ArchiveEnd = 0x4c, InitText = false, FilenamePosition = 0x1c, NoCrc = false };
|
||||
|
||||
else if (pex.OverlayAddress == 0x3800)
|
||||
return new FormatProperty { Dll = true, ArchiveStart = 0x5a, ArchiveEnd = 0x4c, InitText = true, FilenamePosition = 0x1c, NoCrc = false };
|
||||
|
||||
else if (pex.OverlayAddress == 0x3a00)
|
||||
return new FormatProperty { Dll = true, ArchiveStart = 0x5a, ArchiveEnd = 0x4c, InitText = true, FilenamePosition = 0x1c, NoCrc = false };
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempt to extract Wise data from a New Executable
|
||||
/// </summary>
|
||||
/// <param name="nex">New executable to check</param>
|
||||
/// <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>
|
||||
private string ExtractNewExecutable(NewExecutable nex, string file, bool includeDebug)
|
||||
{
|
||||
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(tempPath);
|
||||
|
||||
try
|
||||
{
|
||||
// TODO: Try to find where the file data lives and how to get it
|
||||
Wise unpacker = new Wise();
|
||||
unpacker.ExtractTo(file, tempPath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
return null;
|
||||
}
|
||||
|
||||
return tempPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempt to extract Wise data from a Portable Executable
|
||||
/// </summary>
|
||||
/// <param name="pex">Portable executable to check</param>
|
||||
/// <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>
|
||||
private string ExtractPortableExecutable(PortableExecutable pex, string file, bool includeDebug)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Get the matching PE format
|
||||
var format = GetPEFormat(pex);
|
||||
if (format == null)
|
||||
return null;
|
||||
|
||||
// Get the overlay data for easier reading
|
||||
int overlayOffset = 0, dataStart = 0;
|
||||
byte[] overlayData = pex.OverlayData;
|
||||
if (overlayData == null)
|
||||
return null;
|
||||
|
||||
// Skip over the additional DLL name, if we expect it
|
||||
if (format.Dll)
|
||||
{
|
||||
// Read the name length
|
||||
byte dllNameLength = overlayData.ReadByte(ref overlayOffset);
|
||||
dataStart++;
|
||||
|
||||
// Read the name, if it exists
|
||||
if (dllNameLength != 0)
|
||||
{
|
||||
// Ignore the name for now
|
||||
_ = overlayData.ReadBytes(ref overlayOffset, dllNameLength);
|
||||
dataStart += dllNameLength;
|
||||
|
||||
// Named DLLs also have a DLL length that we ignore
|
||||
_ = overlayData.ReadUInt32(ref overlayOffset);
|
||||
dataStart += 4;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if flags are consistent
|
||||
if (!format.NoCrc)
|
||||
{
|
||||
// Unlike WiseUnpacker, we ignore the flag value here
|
||||
_ = overlayData.ReadUInt32(ref overlayOffset);
|
||||
}
|
||||
|
||||
// Ensure that we have an archive end
|
||||
if (format.ArchiveEnd > 0)
|
||||
{
|
||||
overlayOffset = dataStart + format.ArchiveEnd;
|
||||
int archiveEndLoaded = overlayData.ReadInt32(ref overlayOffset);
|
||||
if (archiveEndLoaded != 0)
|
||||
format.ArchiveEnd = archiveEndLoaded;
|
||||
}
|
||||
|
||||
// Skip to the start of the archive
|
||||
overlayOffset = dataStart + format.ArchiveStart;
|
||||
|
||||
// Skip over the initialization text, if we expect it
|
||||
if (format.InitText)
|
||||
{
|
||||
int initTextLength = overlayData.ReadByte(ref overlayOffset);
|
||||
_ = overlayData.ReadBytes(ref overlayOffset, initTextLength);
|
||||
}
|
||||
|
||||
// Cache the current offset in the overlay as the "start of data"
|
||||
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' });
|
||||
|
||||
string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(tempPath);
|
||||
|
||||
// If we have PKZIP
|
||||
if (pkzip)
|
||||
{
|
||||
string tempFile = Path.Combine(tempPath, "WISEDATA.zip");
|
||||
using (Stream tempStream = File.Open(tempFile, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
|
||||
{
|
||||
tempStream.Write(overlayData, overlayOffset, overlayData.Length - overlayOffset);
|
||||
}
|
||||
}
|
||||
|
||||
// If we have DEFLATE -- TODO: Port implementation here or use DeflateStream
|
||||
else
|
||||
{
|
||||
Wise unpacker = new Wise();
|
||||
unpacker.ExtractTo(file, tempPath);
|
||||
}
|
||||
|
||||
return tempPath;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (includeDebug) Console.WriteLine(ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class representing the properties of each recognized Wise installer format
|
||||
/// </summary>
|
||||
/// <see href="https://github.com/mnadareski/WiseUnpacker/blob/master/WiseUnpacker/FormatProperty.cs"/>
|
||||
private class FormatProperty
|
||||
{
|
||||
/// <summary>
|
||||
/// Offset to the executable data
|
||||
/// </summary>
|
||||
public int ExecutableOffset { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if this format includes a DLL at the start or not
|
||||
/// </summary>
|
||||
public bool Dll { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Offset within the data where the archive starts
|
||||
/// </summary>
|
||||
public int ArchiveStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Position in the archive head of the archive end
|
||||
/// </summary>
|
||||
public int ArchiveEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Format includes initialization text
|
||||
/// </summary>
|
||||
public bool InitText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Position of the filename within the data
|
||||
/// </summary>
|
||||
public int FilenamePosition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Format does not include a CRC
|
||||
/// </summary>
|
||||
public bool NoCrc { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
49
BinaryObjectScanner.Packer/dotFuscator.cs
Normal file
49
BinaryObjectScanner.Packer/dotFuscator.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BinaryObjectScanner.Interfaces;
|
||||
using BinaryObjectScanner.Wrappers;
|
||||
|
||||
namespace BinaryObjectScanner.Packer
|
||||
{
|
||||
// TODO: Add extraction
|
||||
public class dotFuscator : IExtractable, IPortableExecutableCheck
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug)
|
||||
{
|
||||
// Get the sections from the executable, if possible
|
||||
var sections = pex?.SectionTable;
|
||||
if (sections == null)
|
||||
return null;
|
||||
|
||||
// Get the .text section strings, if they exist
|
||||
List<string> strs = pex.GetFirstSectionStrings(".text");
|
||||
if (strs != null)
|
||||
{
|
||||
if (strs.Any(s => s.Contains("DotfuscatorAttribute")))
|
||||
return "dotFuscator";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(string file, bool includeDebug)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return null;
|
||||
|
||||
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return Extract(fs, file, includeDebug);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Extract(Stream stream, string file, bool includeDebug)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user