Rewrite WinZip SFX PE checks

This commit is contained in:
Matt Nadareski
2022-12-07 22:52:49 -08:00
parent d47707c433
commit 52d190e339

View File

@@ -1,11 +1,9 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using BurnOutSharp.Interfaces;
using BurnOutSharp.Matching;
using BurnOutSharp.Tools;
using BurnOutSharp.Wrappers;
using SharpCompress.Archives;
@@ -54,77 +52,17 @@ namespace BurnOutSharp.PackerType
if (sections == null)
return null;
// Get the .rdata section, if it exists
if (pex.ContainsSection(".rdata"))
// Check the export directory table, if it exists
if (pex.ExportTable?.ExportDirectoryTable != null)
{
string version = GetSFXSectionDataVersion(file, pex.GetFirstSectionData(".rdata"), includeDebug);
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))
{
string version = GetPEHeaderVersion(pex);
if (!string.IsNullOrWhiteSpace(version))
return $"WinZip SFX {version}";
version = GetAdjustedManifestVersion(pex);
if (!string.IsNullOrWhiteSpace(version))
return $"WinZip SFX {version}";
return "WinZip SFX Unknown Version (32-bit)";
}
#region Unknown Version checks
// Get the .rdata section, if it exists
if (pex.ContainsSection(".rdata"))
{
string version = GetSFXSectionDataUnknownVersion(file, pex.GetFirstSectionData(".rdata"), includeDebug);
if (!string.IsNullOrWhiteSpace(version))
return $"WinZip SFX {version}";
}
// Get the .data/DATA section, if it exists
var dataSectionRaw = pex.GetFirstSectionData(".data") ?? pex.GetFirstSectionData("DATA");
if (dataSectionRaw != null)
{
var matchers = new List<ContentMatchSet>
{
// WinZip Self-Extractor header corrupt.
new ContentMatchSet(new byte?[]
{
0x57, 0x69, 0x6E, 0x5A, 0x69, 0x70, 0x20, 0x53,
0x65, 0x6C, 0x66, 0x2D, 0x45, 0x78, 0x74, 0x72,
0x61, 0x63, 0x74, 0x6F, 0x72, 0x20, 0x68, 0x65,
0x61, 0x64, 0x65, 0x72, 0x20, 0x63, 0x6F, 0x72,
0x72, 0x75, 0x70, 0x74, 0x2E,
}, "Unknown Version (32-bit)"),
// winzip\shell\open\command
new ContentMatchSet(new byte?[]
{
0x77, 0x69, 0x6E, 0x7A, 0x69, 0x70, 0x5C, 0x73,
0x68, 0x65, 0x6C, 0x6C, 0x5C, 0x6F, 0x70, 0x65,
0x6E, 0x5C, 0x63, 0x6F, 0x6D, 0x6D, 0x61, 0x6E,
0x64,
}, "Unknown Version (32-bit)"),
};
string version = MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".data"), matchers, false);
if (!string.IsNullOrWhiteSpace(version))
{
// Try to grab the value from the manifest, if possible
string manifestVersion = GetAdjustedManifestVersion(pex);
if (!string.IsNullOrWhiteSpace(manifestVersion))
return $"WinZip SFX {manifestVersion}";
return $"WinZip SFX {version}";
}
}
#endregion
return null;
}
@@ -200,53 +138,6 @@ namespace BurnOutSharp.PackerType
return null;
}
/// <summary>
/// Get the version from the assembly manifest, correcting where possible
/// </summary>
private static string GetAdjustedManifestVersion(PortableExecutable pex)
{
// Get the manifest information, if possible
string description = pex.AssemblyDescription;
string version = pex.AssemblyVersion;
// Either an incorrect description or empty version mean we can't match
if (description != "WinZip Self-Extractor")
return null;
else if (string.IsNullOrEmpty(version))
return null;
// Some version strings don't exactly match the public version number
switch (version)
{
case "2.3.6594.0":
return "Personal Edition Build 6604";
case "2.3.6602.0":
return "Personal Edition Build 6663";
case "2.3.7305.0":
return "Personal Edition Build 7305";
case "2.3.7382.0":
return "Personal Edition Build 7452+";
case "3.0.7158.0":
return "3.0.7158";
case "3.0.7454.0":
return "3.0.7454+";
case "3.0.7212.0":
return "3.0.7212";
case "3.1.7556.0":
return "3.1.7556";
case "3.1.8421.0":
return "4.0.8421";
case "4.0.8421.0":
return "4.0.8421";
case "3.1.8672.0":
return "4.0.8672";
case "4.0.1221.0":
return "4.0.12218";
default:
return $"(Unknown - internal version {version})";
}
}
/// <summary>
/// Get the version from the NE header value combinations
/// </summary>
@@ -807,414 +698,204 @@ namespace BurnOutSharp.PackerType
}
/// <summary>
/// Get the version from the PE header value combinations
/// Get the version from the PE export directory table 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 GetPEHeaderVersion(PortableExecutable pex)
private string GetPEExportDirectoryVersion(PortableExecutable pex)
{
// 2.2.3063
if (pex.Machine == Models.PortableExecutable.MachineType.IMAGE_FILE_MACHINE_I386
&& pex.NumberOfSections == 0x0005
&& pex.TimeDateStamp == 0x38BE7AC9
&& pex.PointerToSymbolTable == 0x00000000
&& pex.NumberOfSymbols == 0x00000000
&& pex.SizeOfOptionalHeader == 0x00E0
&& (ushort)pex.Characteristics == 0x010F
string sfxFileName = pex.ExportTable.ExportDirectoryTable.Name;
uint sfxTimeDateStamp = pex.ExportTable.ExportDirectoryTable.TimeDateStamp;
string assemblyVersion = pex.AssemblyVersion ?? "Unknown Version";
&& pex.OH_Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32
&& pex.OH_MajorLinkerVersion == 0x05
&& pex.OH_MinorLinkerVersion == 0x0A
&& pex.OH_SizeOfCode == 0x00005C00
&& pex.OH_SizeOfInitializedData == 0x00004C00
&& pex.OH_SizeOfUninitializedData == 0x00000000
&& pex.OH_AddressOfEntryPoint == 0x00003E71
&& pex.OH_BaseOfCode == 0x00001000
&& pex.OH_BaseOfData == 0x00007000
&& pex.OH_ImageBase == 0x00400000)
return "2.2.3063";
// 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)";
}
}
// 2.2.4003
if (pex.Machine == Models.PortableExecutable.MachineType.IMAGE_FILE_MACHINE_I386
&& pex.NumberOfSections == 0x0005
&& pex.TimeDateStamp == 0x3A5B1B69
&& pex.PointerToSymbolTable == 0x00000000
&& pex.NumberOfSymbols == 0x00000000
&& pex.SizeOfOptionalHeader == 0x00E0
&& (ushort)pex.Characteristics == 0x010F
// 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)";
}
}
&& pex.OH_Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32
&& pex.OH_MajorLinkerVersion == 0x05
&& pex.OH_MinorLinkerVersion == 0x0A
&& pex.OH_SizeOfCode == 0x00004A00
&& pex.OH_SizeOfInitializedData == 0x00002A00
&& pex.OH_SizeOfUninitializedData == 0x00000000
&& pex.OH_AddressOfEntryPoint == 0x000039D8
&& pex.OH_BaseOfCode == 0x00001000
&& pex.OH_BaseOfData == 0x00006000
&& pex.OH_ImageBase == 0x00400000)
return "2.2.4003";
// 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)";
}
}
// Software Installation 2.2.4003
if (pex.Machine == Models.PortableExecutable.MachineType.IMAGE_FILE_MACHINE_I386
&& pex.NumberOfSections == 0x0005
&& pex.TimeDateStamp == 0x3A5B1B81
&& pex.PointerToSymbolTable == 0x00000000
&& pex.NumberOfSymbols == 0x00000000
&& pex.SizeOfOptionalHeader == 0x00E0
&& (ushort)pex.Characteristics == 0x010F
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
&& pex.OH_Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32
&& pex.OH_MajorLinkerVersion == 0x05
&& pex.OH_MinorLinkerVersion == 0x0A
&& pex.OH_SizeOfCode == 0x00005600
&& pex.OH_SizeOfInitializedData == 0x00002A00
&& pex.OH_SizeOfUninitializedData == 0x00000000
&& pex.OH_AddressOfEntryPoint == 0x00003F8F
&& pex.OH_BaseOfCode == 0x00001000
&& pex.OH_BaseOfData == 0x00007000
&& pex.OH_ImageBase == 0x00400000)
return "Software Installation 2.2.4003";
// 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
// 2.2.4325
if (pex.Machine == Models.PortableExecutable.MachineType.IMAGE_FILE_MACHINE_I386
&& pex.NumberOfSections == 0x0005
&& pex.TimeDateStamp == 0x3BFBB8FA
&& pex.PointerToSymbolTable == 0x00000000
&& pex.NumberOfSymbols == 0x00000000
&& pex.SizeOfOptionalHeader == 0x00E0
&& (ushort)pex.Characteristics == 0x010F
&& pex.OH_Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32
&& pex.OH_MajorLinkerVersion == 0x06
&& pex.OH_MinorLinkerVersion == 0x00
&& pex.OH_SizeOfCode == 0x00006000
&& pex.OH_SizeOfInitializedData == 0x0000F000
&& pex.OH_SizeOfUninitializedData == 0x00000000
&& pex.OH_AddressOfEntryPoint == 0x00003EF0
&& pex.OH_BaseOfCode == 0x00001000
&& pex.OH_BaseOfData == 0x00007000
&& pex.OH_ImageBase == 0x00400000
&& pex.OH_SectionAlignment == 0x00001000
&& pex.OH_FileAlignment == 0x00001000)
return "2.2.4325";
// 2.2.5196
if (pex.Machine == Models.PortableExecutable.MachineType.IMAGE_FILE_MACHINE_I386
&& pex.NumberOfSections == 0x0005
&& pex.TimeDateStamp == 0x3D2AFCAD
&& pex.PointerToSymbolTable == 0x00000000
&& pex.NumberOfSymbols == 0x00000000
&& pex.SizeOfOptionalHeader == 0x00E0
&& (ushort)pex.Characteristics == 0x010F
&& pex.OH_Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32
&& pex.OH_MajorLinkerVersion == 0x07
&& pex.OH_MinorLinkerVersion == 0x00
&& pex.OH_SizeOfCode == 0x00007000
&& pex.OH_SizeOfInitializedData == 0x00010000
&& pex.OH_SizeOfUninitializedData == 0x00000000
&& pex.OH_AddressOfEntryPoint == 0x00004554
&& pex.OH_BaseOfCode == 0x00001000
&& pex.OH_BaseOfData == 0x00008000
&& pex.OH_ImageBase == 0x00400000
&& pex.OH_SectionAlignment == 0x00001000
&& pex.OH_FileAlignment == 0x00001000)
return "2.2.5196";
// 2.2.6202
if (pex.Machine == Models.PortableExecutable.MachineType.IMAGE_FILE_MACHINE_I386
&& pex.NumberOfSections == 0x0005
&& pex.TimeDateStamp == 0x4100F776
&& pex.PointerToSymbolTable == 0x00000000
&& pex.NumberOfSymbols == 0x00000000
&& pex.SizeOfOptionalHeader == 0x00E0
&& (ushort)pex.Characteristics == 0x010F
&& pex.OH_Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32
&& pex.OH_MajorLinkerVersion == 0x07
&& pex.OH_MinorLinkerVersion == 0x00
&& pex.OH_SizeOfCode == 0x00007000
&& pex.OH_SizeOfInitializedData == 0x00010000
&& pex.OH_SizeOfUninitializedData == 0x00000000
&& pex.OH_AddressOfEntryPoint == 0x00004603
&& pex.OH_BaseOfCode == 0x00001000
&& pex.OH_BaseOfData == 0x00008000
&& pex.OH_ImageBase == 0x00400000)
return "2.2.6202";
// 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;
}
/// <summary>
/// Get the version from the .rdata SFX header data
/// </summary>
/// TODO: Research to see if the versions are embedded elsewhere in these files
private string GetSFXSectionDataVersion(string file, byte[] sectionContent, bool includeDebug)
{
var matchers = new List<ContentMatchSet>
{
// .............8<EFBFBD>92....<2E>P..............<2E>P..<2E>P..<2E>P..VW95SE.SFX
new ContentMatchSet(new byte?[]
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x9C, 0x39,
0x32, 0x00, 0x00, 0x00, 0x00, 0x88, 0x50, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x50, 0x00,
0x00, 0x88, 0x50, 0x00, 0x00, 0x88, 0x50, 0x00,
0x00, 0x56, 0x57, 0x39, 0x35, 0x53, 0x45, 0x2E,
0x53, 0x46, 0x58,
}, "2.0 (32-bit)"),
// .............]<5D>92....<2E>P..............<2E>P..<2E>P..<2E>P..VW95SRE.SFX
new ContentMatchSet(new byte?[]
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x9C, 0x39,
0x32, 0x00, 0x00, 0x00, 0x00, 0x88, 0x50, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x50, 0x00,
0x00, 0x88, 0x50, 0x00, 0x00, 0x88, 0x50, 0x00,
0x00, 0x56, 0x57, 0x39, 0x35, 0x53, 0x52, 0x45,
0x2E, 0x53, 0x46, 0x58,
}, "Software Installation 2.0 (32-bit)"),
// .............<2E><><EFBFBD>3....<2E>P..............<2E>P..<2E>P..<2E>P..VW95SE.SFX
new ContentMatchSet(new byte?[]
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x82, 0x94,
0x33, 0x00, 0x00, 0x00, 0x00, 0x88, 0x50, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x50, 0x00,
0x00, 0x88, 0x50, 0x00, 0x00, 0x88, 0x50, 0x00,
0x00, 0x56, 0x57, 0x39, 0x35, 0x53, 0x45, 0x2E,
0x53, 0x46, 0x58,
}, "2.1 RC2 (32-bit)"),
// .............<2E><><EFBFBD>3....<2E>P..............<2E>P..<2E>P..<2E>P..VW95SRE.SFX
new ContentMatchSet(new byte?[]
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x82, 0x94,
0x33, 0x00, 0x00, 0x00, 0x00, 0x88, 0x50, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x50, 0x00,
0x00, 0x88, 0x50, 0x00, 0x00, 0x88, 0x50, 0x00,
0x00, 0x56, 0x57, 0x39, 0x35, 0x53, 0x52, 0x45,
0x2E, 0x53, 0x46, 0x58,
}, "Software Installation 2.1 RC2 (32-bit)"),
// .............U<><55>3....<2E>P..............<2E>P..<2E>P..<2E>P..VW95SE.SFX
new ContentMatchSet(new byte?[]
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xCD, 0xCC,
0x33, 0x00, 0x00, 0x00, 0x00, 0x88, 0x50, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x50, 0x00,
0x00, 0x88, 0x50, 0x00, 0x00, 0x88, 0x50, 0x00,
0x00, 0x56, 0x57, 0x39, 0x35, 0x53, 0x45, 0x2E,
0x53, 0x46, 0x58,
}, "2.1 (32-bit)"),
// .............{<7B><>3....<2E>P..............<2E>P..<2E>P..<2E>P..VW95SRE.SFX
new ContentMatchSet(new byte?[]
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7B, 0xCD, 0xCC,
0x33, 0x00, 0x00, 0x00, 0x00, 0x88, 0x50, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x50, 0x00,
0x00, 0x88, 0x50, 0x00, 0x00, 0x88, 0x50, 0x00,
0x00, 0x56, 0x57, 0x39, 0x35, 0x53, 0x52, 0x45,
0x2E, 0x53, 0x46, 0x58,
}, "Software Installation 2.1 (32-bit)"),
// .............ñ½;5....ˆ`..............ˆ`..ˆ`..ˆ`..SI32E.SFX
new ContentMatchSet(new byte?[]
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF1, 0xBD, 0x3B,
0x35, 0x00, 0x00, 0x00, 0x00, 0x88, 0x60, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x60, 0x00,
0x00, 0x88, 0x60, 0x00, 0x00, 0x88, 0x60, 0x00,
0x00, 0x53, 0x49, 0x33, 0x32, 0x45, 0x2E, 0x53,
0x46, 0x58,
}, "Software Installation 2.2.1110 (32-bit)"),
// .............á.^2....ˆP..............ˆP..ˆP..ˆP..VW95LE.SFX
new ContentMatchSet(new byte?[]
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xE1, 0x9D, 0x5E,
0x32, 0x00, 0x00, 0x00, 0x00, 0x88, 0x50, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x50, 0x00,
0x00, 0x88, 0x50, 0x00, 0x00, 0x88, 0x50, 0x00,
0x00, 0x56, 0x57, 0x39, 0x35, 0x4C, 0x45, 0x2E,
0x53, 0x46, 0x58,
}, "Personal Edition (32-bit)"),
// .............ïAÁ3....ˆP..............ˆP..ˆP..ˆP..VW95LE.SFX
new ContentMatchSet(new byte?[]
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0x41, 0xC1,
0x33, 0x00, 0x00, 0x00, 0x00, 0x88, 0x50, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x50, 0x00,
0x00, 0x88, 0x50, 0x00, 0x00, 0x88, 0x50, 0x00,
0x00, 0x56, 0x57, 0x39, 0x35, 0x4C, 0x45, 0x2E,
0x53, 0x46, 0x58,
}, "Personal Edition 32-bit (32-bit)"),
// .............'..6....ˆ`..............ˆ`..ˆ`..ˆ`..PE32E.SFX
new ContentMatchSet(new byte?[]
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x0F, 0x01,
0x36, 0x00, 0x00, 0x00, 0x00, 0x88, 0x60, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x60, 0x00,
0x00, 0x88, 0x60, 0x00, 0x00, 0x88, 0x60, 0x00,
0x00, 0x50, 0x45, 0x33, 0x32, 0x45, 0x2E, 0x53,
0x46, 0x58,
}, "Personal Edition 32-bit Build 1260 (32-bit)"),
// .............Ó‘(6....ˆ`..............ˆ`..ˆ`..ˆ`..PE32E.SFX
new ContentMatchSet(new byte?[]
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x91, 0x28,
0x36, 0x00, 0x00, 0x00, 0x00, 0x88, 0x60, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x60, 0x00,
0x00, 0x88, 0x60, 0x00, 0x00, 0x88, 0x60, 0x00,
0x00, 0x50, 0x45, 0x33, 0x32, 0x45, 0x2E, 0x53,
0x46, 0x58,
}, "Personal Edition 32-bit Build 1285 (32-bit)"),
// ......]ïý8....˜z..............˜z..˜z..˜z..PE32E.SFX
new ContentMatchSet(new byte?[]
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xEF,
0xFD, 0x38, 0x00, 0x00, 0x00, 0x00, 0x98, 0x7A,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x7A,
0x00, 0x00, 0x98, 0x7A, 0x00, 0x00, 0x98, 0x7A,
0x00, 0x00, 0x50, 0x45, 0x33, 0x32, 0x45, 0x2E,
0x53, 0x46, 0x58,
}, "Personal Edition 32-bit Build 3063"),
// ...................½û;....ˆj..............ˆj..ˆj..ˆj..PE32E.SFX
new ContentMatchSet(new byte?[]
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1F, 0xBD, 0xFB, 0x3B, 0x00, 0x00,
0x00, 0x00, 0x88, 0x6A, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x88, 0x6A, 0x00, 0x00, 0x88, 0x6A,
0x00, 0x00, 0x88, 0x6A, 0x00, 0x00, 0x50, 0x45,
0x33, 0x32, 0x45, 0x2E, 0x53, 0x46, 0x58,
}, "Personal Edition 32-bit Build 4325"),
// ................rS*@....Xƒ..............Xƒ..Xƒ..Xƒ..PE32E.SFX
new ContentMatchSet(new byte?[]
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x72, 0x53, 0x2A, 0x40, 0x00, 0x00, 0x00, 0x00,
0x58, 0x83, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x58, 0x83, 0x00, 0x00, 0x58, 0x83, 0x00, 0x00,
0x58, 0x83, 0x00, 0x00, 0x50, 0x45, 0x33, 0x32,
0x45, 0x2E, 0x53, 0x46, 0x58,
}, "Personal Edition 32-bit Build 6028"),
// ................±.!A....Xƒ..............Xƒ..Xƒ..Xƒ..PE32E.SFX
new ContentMatchSet(new byte?[]
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xB1, 0x1A, 0x21, 0x41, 0x00, 0x00, 0x00, 0x00,
0x58, 0x83, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x58, 0x83, 0x00, 0x00, 0x58, 0x83, 0x00, 0x00,
0x58, 0x83, 0x00, 0x00, 0x50, 0x45, 0x33, 0x32,
0x45, 0x2E, 0x53, 0x46, 0x58,
}, "Personal Edition 32-bit Build 6224"),
// ................¯D.C....x„..............x„..x„..x„..PE32E.SFX
new ContentMatchSet(new byte?[]
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xAF, 0x44, 0x0F, 0x43, 0x00, 0x00, 0x00, 0x00,
0x78, 0x84, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x78, 0x84, 0x00, 0x00, 0x78, 0x84, 0x00, 0x00,
0x78, 0x84, 0x00, 0x00, 0x50, 0x45, 0x33, 0x32,
0x45, 0x2E, 0x53, 0x46,
}, "Personal Edition 32-bit Build 6604"),
//................·Å\C....x„..............x„..x„..x„..PE32E.SFX
new ContentMatchSet(new byte?[]
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xB7, 0xC5, 0x5C, 0x43, 0x00, 0x00, 0x00, 0x00,
0x78, 0x84, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x78, 0x84, 0x00, 0x00, 0x78, 0x84, 0x00, 0x00,
0x78, 0x84, 0x00, 0x00, 0x50, 0x45, 0x33, 0x32,
0x45, 0x2E, 0x53, 0x46, 0x58,
}, "Personal Edition 32-bit Build 6663"),
};
return MatchUtil.GetFirstMatch(file, sectionContent, matchers, includeDebug);
}
/// <summary>
/// Get the unknown version from the .rdata SFX header data
/// </summary>
private string GetSFXSectionDataUnknownVersion(string file, byte[] sectionContent, bool includeDebug)
{
var matchers = new List<ContentMatchSet>
{
// VW95SE.SFX
new ContentMatchSet(new byte?[]
{
0x56, 0x57, 0x39, 0x35, 0x53, 0x45, 0x2E, 0x53,
0x46, 0x58,
}, "Unknown Version (32-bit)"),
// VW95SRE.SFX
new ContentMatchSet(new byte?[]
{
0x56, 0x57, 0x39, 0x35, 0x53, 0x52, 0x45, 0x2E,
0x53, 0x46, 0x58,
}, "Unknown Version Software Installation (32-bit)"),
// VW95LE.SFX
new ContentMatchSet(new byte?[]
{
0x56, 0x57, 0x39, 0x35, 0x4C, 0x45, 0x2E, 0x53,
0x46, 0x58,
}, "Unknown Version before build 1285 Personal Edition (32-bit)"),
// PE32E.SFX
new ContentMatchSet(new byte?[]
{
0x50, 0x45, 0x33, 0x32, 0x45, 0x2E, 0x53, 0x46,
0x58,
}, "Unknown Version after 1285 Personal Edition (32-bit)"),
};
return MatchUtil.GetFirstMatch(file, sectionContent, matchers, includeDebug);
}
}
}