diff --git a/BurnOutSharp/Tools/Utilities.cs b/BurnOutSharp/Tools/Utilities.cs
index 469d1acd..34503cd8 100644
--- a/BurnOutSharp/Tools/Utilities.cs
+++ b/BurnOutSharp/Tools/Utilities.cs
@@ -4,8 +4,10 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
-using System.Text;
using System.Xml;
+using BurnOutSharp.ExecutableType.Microsoft;
+using BurnOutSharp.ExecutableType.Microsoft.Sections;
+using BurnOutSharp.ExecutableType.Microsoft.Tables;
using BurnOutSharp.Matching;
namespace BurnOutSharp.Tools
@@ -307,8 +309,14 @@ namespace BurnOutSharp.Tools
/// Version string, null on error
public static string GetManifestVersion(byte[] fileContent)
{
+ // If we don't have a PE executable, just return null
+ PortableExecutable pex = PortableExecutable.Deserialize(fileContent, 0);
+ var resourceSection = pex?.ResourceSection;
+ if (resourceSection == null)
+ return null;
+
// Read in the manifest to a string
- string manifestString = GetEmbeddedAssemblyManifest(fileContent);
+ string manifestString = FindAssemblyManifest(pex.ResourceSection);
if (string.IsNullOrWhiteSpace(manifestString))
return null;
@@ -341,8 +349,14 @@ namespace BurnOutSharp.Tools
/// Version string, null on error
public static string GetManifestDescription(byte[] fileContent)
{
+ // If we don't have a PE executable, just return null
+ PortableExecutable pex = PortableExecutable.Deserialize(fileContent, 0);
+ var resourceSection = pex?.ResourceSection;
+ if (resourceSection == null)
+ return null;
+
// Read in the manifest to a string
- string manifestString = GetEmbeddedAssemblyManifest(fileContent);
+ string manifestString = FindAssemblyManifest(pex.ResourceSection);
if (string.IsNullOrWhiteSpace(manifestString))
return null;
@@ -368,29 +382,59 @@ namespace BurnOutSharp.Tools
}
///
- /// Get the embedded assembly manifest
+ /// Find the assembly manifest from a resource section, if possible
///
- /// Byte array representing the file contents
- /// Embedded assembly manifest as a string, if possible
- ///
- /// TODO: How do we find the manifest specifically better
- /// TODO: This should be derived specifically in the .rsrc section
- ///
- private static string GetEmbeddedAssemblyManifest(byte[] fileContent)
+ /// ResourceSection from the executable
+ /// Full assembly manifest, null on error
+ private static string FindAssemblyManifest(ResourceSection rs)
{
- //
- byte?[] manifestEnd = new byte?[] { 0x3C, 0x2F, 0x61, 0x73, 0x73, 0x65, 0x6D, 0x62, 0x6C, 0x79, 0x3E };
- if (!fileContent.FirstPosition(manifestEnd, out int manifestEndPosition, start: manifestStartPosition))
+ return FindAssemblyManifest(rs.ResourceDirectoryTable);
+ }
+
+ ///
+ /// Find the assembly manifest from a resource directory table, if possible
+ ///
+ /// ResourceDirectoryTable representing a layer
+ /// Full assembly manifest, null on error
+ private static string FindAssemblyManifest(ResourceDirectoryTable rdt)
+ {
+ if (rdt == null)
return null;
- // Read in the manifest to a string
- int manifestLength = manifestEndPosition + "".Length - manifestStartPosition;
- return Encoding.ASCII.GetString(fileContent, manifestStartPosition, manifestLength);
+ foreach (var rdte in rdt.NamedEntries)
+ {
+ if (rdte.IsResourceDataEntry() && rdte.DataEntry != null)
+ {
+ if (rdte.DataEntry.EncodedData.StartsWith("
@@ -417,7 +461,7 @@ namespace BurnOutSharp.Tools
// Try to read the assembly node
return manifestDoc["assembly"];
}
- catch
+ catch (Exception ex)
{
return null;
}