mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-07-17 06:14:59 +00:00
Create and use manifesr version utility
This commit is contained in:
@@ -22,24 +22,17 @@ namespace BurnOutSharp.PackerType
|
||||
byte[] check = new byte[] { 0x53, 0x00, 0x65, 0x00, 0x74, 0x00, 0x75, 0x00, 0x70, 0x00, 0x20, 0x00, 0x46, 0x00, 0x61, 0x00, 0x63, 0x00, 0x74, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x79, 0x00 };
|
||||
if (fileContent.Contains(check, out int position))
|
||||
{
|
||||
// "<?xml"
|
||||
byte[] check2 = new byte[] { 0x3C, 0x3F, 0x78, 0x6D, 0x6C };
|
||||
if (fileContent.Contains(check2, out int position2))
|
||||
{
|
||||
string version = GetVersionXML(fileContent, position2);
|
||||
if (version == null)
|
||||
return $"Setup Factory (Unknown Version)" + (includePosition ? $" (Index {position})" : string.Empty);
|
||||
|
||||
return $"Setup Factory {version}" + (includePosition ? $" (Index {position}, {position2})" : string.Empty);
|
||||
}
|
||||
else
|
||||
{
|
||||
string version = Utilities.GetFileVersion(file);
|
||||
if (version == null)
|
||||
return $"Setup Factory (Unknown Version)" + (includePosition ? $" (Index {position})" : string.Empty);
|
||||
|
||||
// Check the manifest version first
|
||||
string version = Utilities.GetManifestVersion(fileContent);
|
||||
if (!string.IsNullOrEmpty(version))
|
||||
return $"Setup Factory {version}" + (includePosition ? $" (Index {position})" : string.Empty);
|
||||
}
|
||||
|
||||
// Then check the file version
|
||||
version = Utilities.GetFileVersion(file);
|
||||
if (!string.IsNullOrEmpty(version))
|
||||
return $"Setup Factory {version}" + (includePosition ? $" (Index {position})" : string.Empty);
|
||||
|
||||
return $"Setup Factory (Unknown Version)" + (includePosition ? $" (Index {position})" : string.Empty);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -63,36 +56,5 @@ namespace BurnOutSharp.PackerType
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// I was only able to test version detection with version 9.1.0.0 and version 5.0.1.0, but any other versions that use XML or the "File Version" field to store the version number should be detected as well.
|
||||
// Version 5.0.1.0 contains the string "Setup Factory 32-Bit Setup Module 5.00", which adds confusion about the version but may be used as an additional check
|
||||
private static string GetVersionXML(byte[] fileContent, int xmlStartPosition)
|
||||
{
|
||||
|
||||
// </assembly>
|
||||
byte[] check = new byte[] { 0x3C, 0x2F, 0x61, 0x73, 0x73, 0x65, 0x6D, 0x62, 0x6C, 0x79, 0x3E };
|
||||
if (fileContent.Contains(check, out int position, start: xmlStartPosition))
|
||||
{
|
||||
int offset = position + 11 - xmlStartPosition;
|
||||
string xmlString = Encoding.ASCII.GetString(fileContent, xmlStartPosition, offset);
|
||||
|
||||
try
|
||||
{
|
||||
// Load the XML string as a document
|
||||
var xmlDoc = new XmlDocument();
|
||||
xmlDoc.LoadXml(xmlString);
|
||||
|
||||
// Get the version attribute, if possible
|
||||
string xmlVersion = xmlDoc["assembly"]["assemblyIdentity"].GetAttributeNode("version").InnerXml;
|
||||
|
||||
return $"Version {xmlVersion}";
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,26 +19,12 @@ namespace BurnOutSharp.PackerType
|
||||
// WinZip Self-Extractor
|
||||
byte[] check = new byte[] { 0x57, 0x69, 0x6E, 0x5A, 0x69, 0x70, 0x20, 0x53, 0x65, 0x6C, 0x66, 0x2D, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6F, 0x72 };
|
||||
if (fileContent.Contains(check, out int position))
|
||||
{
|
||||
// "<?xml"
|
||||
byte[] check2 = new byte[] { 0x3C, 0x3F, 0x78, 0x6D, 0x6C };
|
||||
if (fileContent.Contains(check2, out int position2))
|
||||
return $"WinZip SFX {GetV3PlusVersion(fileContent, position2)}" + (includePosition ? $" (Index {position}, {position2})" : string.Empty);
|
||||
else
|
||||
return $"WinZip SFX {GetV2Version(fileContent)}" + (includePosition ? $" (Index {position})" : string.Empty);
|
||||
}
|
||||
return $"WinZip SFX {GetVersion(fileContent)}" + (includePosition ? $" (Index {position})" : string.Empty);
|
||||
|
||||
// _winzip_
|
||||
check = new byte[] { 0x5F, 0x77, 0x69, 0x6E, 0x7A, 0x69, 0x70, 0x5F };
|
||||
if (fileContent.Contains(check, out position))
|
||||
{
|
||||
// "<?xml"
|
||||
byte[] check2 = new byte[] { 0x3C, 0x3F, 0x78, 0x6D, 0x6C };
|
||||
if (fileContent.Contains(check2, out int position2))
|
||||
return $"WinZip SFX {GetV3PlusVersion(fileContent, position2)}" + (includePosition ? $" (Index {position}, {position2})" : string.Empty);
|
||||
else
|
||||
return $"WinZip SFX {GetV2Version(fileContent)}" + (includePosition ? $" (Index {position})" : string.Empty);
|
||||
}
|
||||
return $"WinZip SFX {GetVersion(fileContent)}" + (includePosition ? $" (Index {position})" : string.Empty);
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -103,44 +89,14 @@ namespace BurnOutSharp.PackerType
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string GetV3PlusVersion(byte[] fileContent, int xmlStartPosition)
|
||||
private static string GetVersion(byte[] fileContent)
|
||||
{
|
||||
// </assembly>
|
||||
byte[] check = new byte[] { 0x3C, 0x2F, 0x61, 0x73, 0x73, 0x65, 0x6D, 0x62, 0x6C, 0x79, 0x3E };
|
||||
if (fileContent.Contains(check, out int position, start: xmlStartPosition))
|
||||
{
|
||||
int offset = position + 11 - xmlStartPosition;
|
||||
string xmlString = Encoding.ASCII.GetString(fileContent, xmlStartPosition, offset);
|
||||
|
||||
try
|
||||
{
|
||||
// Load the XML string as a document
|
||||
var xmlDoc = new XmlDocument();
|
||||
xmlDoc.LoadXml(xmlString);
|
||||
|
||||
// Get the version attribute, if possible
|
||||
string xmlVersion = xmlDoc["assembly"]["assemblyIdentity"].GetAttributeNode("version").InnerXml;
|
||||
|
||||
// Some version strings don't exactly match the public version number
|
||||
switch (xmlVersion)
|
||||
{
|
||||
case "3.0.7158.0":
|
||||
return "3.0.7158";
|
||||
case "3.1.7556.0":
|
||||
return "3.1.7556";
|
||||
case "3.1.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 Version - {xmlVersion})";
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
// Check the manifest version first
|
||||
string version = Utilities.GetManifestVersion(fileContent);
|
||||
if (!string.IsNullOrEmpty(version))
|
||||
return GetV3PlusVersion(version);
|
||||
|
||||
// Assume an earlier version
|
||||
return GetV2Version(fileContent);
|
||||
}
|
||||
|
||||
@@ -160,7 +116,7 @@ namespace BurnOutSharp.PackerType
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
||||
};
|
||||
if (fileContent.Contains(check, out _))
|
||||
return "Version 2.0 (MS-DOS/16-bit)";
|
||||
return "2.0 (MS-DOS/16-bit)";
|
||||
|
||||
check = new byte[]
|
||||
{
|
||||
@@ -174,7 +130,7 @@ namespace BurnOutSharp.PackerType
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
||||
};
|
||||
if (fileContent.Contains(check, out _))
|
||||
return "Version 2.0 (16-bit)";
|
||||
return "2.0 (16-bit)";
|
||||
|
||||
check = new byte[]
|
||||
{
|
||||
@@ -216,7 +172,7 @@ namespace BurnOutSharp.PackerType
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
||||
};
|
||||
if (fileContent.Contains(check, out _))
|
||||
return "Version 2.1 RC2 (MS-DOS/16-bit)";
|
||||
return "2.1 RC2 (MS-DOS/16-bit)";
|
||||
|
||||
check = new byte[]
|
||||
{
|
||||
@@ -230,7 +186,7 @@ namespace BurnOutSharp.PackerType
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
||||
};
|
||||
if (fileContent.Contains(check, out _))
|
||||
return "Version 2.1 RC2 (16-bit)";
|
||||
return "2.1 RC2 (16-bit)";
|
||||
|
||||
check = new byte[]
|
||||
{
|
||||
@@ -272,7 +228,7 @@ namespace BurnOutSharp.PackerType
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
||||
};
|
||||
if (fileContent.Contains(check, out _))
|
||||
return "Version 2.1 (MS-DOS/16-bit)";
|
||||
return "2.1 (MS-DOS/16-bit)";
|
||||
|
||||
check = new byte[]
|
||||
{
|
||||
@@ -286,7 +242,7 @@ namespace BurnOutSharp.PackerType
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
||||
};
|
||||
if (fileContent.Contains(check, out _))
|
||||
return "Version 2.1 (16-bit)";
|
||||
return "2.1 (16-bit)";
|
||||
|
||||
check = new byte[]
|
||||
{
|
||||
@@ -334,7 +290,7 @@ namespace BurnOutSharp.PackerType
|
||||
0x53, 0x46, 0x58,
|
||||
};
|
||||
if (fileContent.Contains(check, out _))
|
||||
return "Version 2.0 (32-bit)";
|
||||
return "2.0 (32-bit)";
|
||||
|
||||
// .............]<5D>92....<2E>P..............<2E>P..<2E>P..<2E>P..VW95SRE.SFX
|
||||
check = new byte[]
|
||||
@@ -364,7 +320,7 @@ namespace BurnOutSharp.PackerType
|
||||
0x53, 0x46, 0x58,
|
||||
};
|
||||
if (fileContent.Contains(check, out _))
|
||||
return "Version 2.1 RC2 (32-bit)";
|
||||
return "2.1 RC2 (32-bit)";
|
||||
|
||||
// .............<2E><><EFBFBD>3....<2E>P..............<2E>P..<2E>P..<2E>P..VW95SRE.SFX
|
||||
check = new byte[]
|
||||
@@ -394,7 +350,7 @@ namespace BurnOutSharp.PackerType
|
||||
0x53, 0x46, 0x58,
|
||||
};
|
||||
if (fileContent.Contains(check, out _))
|
||||
return "Version 2.1 (32-bit)";
|
||||
return "2.1 (32-bit)";
|
||||
|
||||
// .............{<7B><>3....<2E>P..............<2E>P..<2E>P..<2E>P..VW95SRE.SFX
|
||||
check = new byte[]
|
||||
@@ -427,7 +383,7 @@ namespace BurnOutSharp.PackerType
|
||||
0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
|
||||
};
|
||||
if (fileContent.Contains(check, out _))
|
||||
return "Version 2.2.4003";
|
||||
return "2.2.4003";
|
||||
|
||||
// PE..L.....[:........<2E>........V...*.......?.......p....@.
|
||||
check = new byte[]
|
||||
@@ -447,5 +403,25 @@ namespace BurnOutSharp.PackerType
|
||||
|
||||
return "Unknown Version 2.X";
|
||||
}
|
||||
|
||||
private static string GetV3PlusVersion(string version)
|
||||
{
|
||||
// Some version strings don't exactly match the public version number
|
||||
switch (version)
|
||||
{
|
||||
case "3.0.7158.0":
|
||||
return "3.0.7158";
|
||||
case "3.1.7556.0":
|
||||
return "3.1.7556";
|
||||
case "3.1.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 Version - {version})";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace BurnOutSharp
|
||||
{
|
||||
@@ -232,5 +234,55 @@ namespace BurnOutSharp
|
||||
else
|
||||
return fvinfo.ProductVersion.Replace(", ", ".");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the assembly version as determined by an embedded assembly manifest
|
||||
/// </summary>
|
||||
/// <remarks>TODO: How do we find the manifest specifically better?</remarks>
|
||||
public static string GetManifestVersion(byte[] fileContent)
|
||||
{
|
||||
// <?xml
|
||||
byte[] manifestStart = new byte[] { 0x3C, 0x3F, 0x78, 0x6D, 0x6C };
|
||||
if (!fileContent.Contains(manifestStart, out int manifestStartPosition))
|
||||
return null;
|
||||
|
||||
// </assembly>
|
||||
byte[] manifestEnd = new byte[] { 0x3C, 0x2F, 0x61, 0x73, 0x73, 0x65, 0x6D, 0x62, 0x6C, 0x79, 0x3E };
|
||||
if (!fileContent.Contains(manifestEnd, out int manifestEndPosition, start: manifestStartPosition))
|
||||
return null;
|
||||
|
||||
// Read in the manifest to a string
|
||||
int manifestLength = manifestEndPosition + "</assembly>".Length - manifestStartPosition;
|
||||
string manifestString = Encoding.ASCII.GetString(fileContent, manifestStartPosition, manifestLength);
|
||||
|
||||
// Try to read the XML in from the string
|
||||
try
|
||||
{
|
||||
// Load the XML string as a document
|
||||
var manifestDoc = new XmlDocument();
|
||||
manifestDoc.LoadXml(manifestString);
|
||||
|
||||
// If the XML has no children, it's invalid
|
||||
if (!manifestDoc.HasChildNodes)
|
||||
return null;
|
||||
|
||||
// Try to read the assembly node
|
||||
var assemblyNode = manifestDoc["assembly"];
|
||||
if (assemblyNode == null)
|
||||
return null;
|
||||
|
||||
// Try to read the assemblyIdentity
|
||||
var assemblyIdentityNode = assemblyNode["assemblyIdentity"];
|
||||
if (assemblyIdentityNode == null)
|
||||
return null;
|
||||
|
||||
// Return the version attribute, if possible
|
||||
return assemblyIdentityNode.GetAttribute("version");
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user