From 7789f7c3d7ddddce87fa2a600749076a1ae7f4e7 Mon Sep 17 00:00:00 2001 From: Washi Date: Wed, 21 Jun 2023 14:45:22 +0200 Subject: [PATCH 1/3] BUGFIX: Align every table in VersionInfo to 4-byte alignment. --- .../Version/StringTable.cs | 94 +++++++++---------- .../Version/VersionInfoResource.cs | 60 ++++++------ 2 files changed, 78 insertions(+), 76 deletions(-) diff --git a/src/AsmResolver.PE.Win32Resources/Version/StringTable.cs b/src/AsmResolver.PE.Win32Resources/Version/StringTable.cs index 3d88a0b1a..0db9a0e10 100644 --- a/src/AsmResolver.PE.Win32Resources/Version/StringTable.cs +++ b/src/AsmResolver.PE.Win32Resources/Version/StringTable.cs @@ -73,6 +73,53 @@ public class StringTable : VersionTableEntry, IEnumerable public const string SpecialBuildKey = "SpecialBuild"; + private readonly Dictionary _entries = new(); + + /// + /// Creates a new string table. + /// + /// The language identifier. + /// The code page. + public StringTable(ushort languageIdentifier, ushort codePage) + { + LanguageIdentifier = languageIdentifier; + CodePage = codePage; + } + + /// + public override string Key => $"{LanguageIdentifier:x4}{CodePage:x4}"; + + /// + /// Gets or sets the language identifier of this string table. + /// + public ushort LanguageIdentifier + { + get; + set; + } + + /// + /// Gets or sets the code page of this string table. + /// + public ushort CodePage + { + get; + set; + } + + /// + protected override VersionTableValueType ValueType => VersionTableValueType.Binary; + + /// + /// Gets or sets the value of a single field in the string table. + /// + /// The name of the field in the string table. + public string this[string key] + { + get => _entries[key]; + set => _entries[key] = value; + } + /// /// Reads a single StringTable structure from the provided input stream. /// @@ -122,53 +169,6 @@ private static KeyValuePair ReadEntry(ref BinaryStreamReader rea return new KeyValuePair(header.Key, value); } - private readonly Dictionary _entries = new Dictionary(); - - /// - /// Creates a new string table. - /// - /// The language identifier. - /// The code page. - public StringTable(ushort languageIdentifier, ushort codePage) - { - LanguageIdentifier = languageIdentifier; - CodePage = codePage; - } - - /// - public override string Key => $"{LanguageIdentifier:X4}{CodePage:X4}"; - - /// - /// Gets or sets the language identifier of this string table. - /// - public ushort LanguageIdentifier - { - get; - set; - } - - /// - /// Gets or sets the code page of this string table. - /// - public ushort CodePage - { - get; - set; - } - - /// - protected override VersionTableValueType ValueType => VersionTableValueType.Binary; - - /// - /// Gets or sets the value of a single field in the string table. - /// - /// The name of the field in the string table. - public string this[string key] - { - get => _entries[key]; - set => _entries[key] = value; - } - /// /// Adds (or overrides) a field to the string table. /// diff --git a/src/AsmResolver.PE.Win32Resources/Version/VersionInfoResource.cs b/src/AsmResolver.PE.Win32Resources/Version/VersionInfoResource.cs index 666591d7c..f27a38e74 100644 --- a/src/AsmResolver.PE.Win32Resources/Version/VersionInfoResource.cs +++ b/src/AsmResolver.PE.Win32Resources/Version/VersionInfoResource.cs @@ -15,6 +15,34 @@ public class VersionInfoResource : VersionTableEntry, IWin32Resource /// public const string VsVersionInfoKey = "VS_VERSION_INFO"; + private FixedVersionInfo _fixedVersionInfo = new FixedVersionInfo(); + private readonly Dictionary _entries = new Dictionary(); + + /// + public override string Key => VsVersionInfoKey; + + /// + protected override VersionTableValueType ValueType => VersionTableValueType.Binary; + + /// + /// Gets the fixed version info stored in this version resource. + /// + public FixedVersionInfo FixedVersionInfo + { + get => _fixedVersionInfo; + set => _fixedVersionInfo = value ?? throw new ArgumentNullException(nameof(value)); + } + + /// + /// Gets or sets a version table entry by its name. + /// + /// The name of the child. + public VersionTableEntry this[string name] + { + get => _entries[name]; + set => _entries[name] = value; + } + /// /// Obtains the version info resource from the provided root win32 resources directory. /// @@ -97,34 +125,6 @@ private static VersionTableEntry ReadNextEntry(ref BinaryStreamReader reader) }; } - private FixedVersionInfo _fixedVersionInfo = new FixedVersionInfo(); - private readonly Dictionary _entries = new Dictionary(); - - /// - public override string Key => VsVersionInfoKey; - - /// - protected override VersionTableValueType ValueType => VersionTableValueType.Binary; - - /// - /// Gets the fixed version info stored in this version resource. - /// - public FixedVersionInfo FixedVersionInfo - { - get => _fixedVersionInfo; - set => _fixedVersionInfo = value ?? throw new ArgumentNullException(nameof(value)); - } - - /// - /// Gets or sets a version table entry by its name. - /// - /// The name of the child. - public VersionTableEntry this[string name] - { - get => _entries[name]; - set => _entries[name] = value; - } - /// /// Gets a collection of entries stored in the version resource. /// @@ -181,9 +181,11 @@ public override uint GetPhysicalSize() protected override void WriteValue(IBinaryStreamWriter writer) { FixedVersionInfo.Write(writer); - writer.Align(4); foreach (var entry in _entries.Values) + { + writer.Align(4); entry.Write(writer); + } } /// From cfc81fc501dd81d7c3c5148ef75bb82c4a89ea44 Mon Sep 17 00:00:00 2001 From: Washi Date: Wed, 21 Jun 2023 16:59:52 +0200 Subject: [PATCH 2/3] Add unit test for padded version info. --- ...AsmResolver.PE.Win32Resources.Tests.csproj | 5 +- .../Properties/Resources.Designer.cs | 7 +++ .../Properties/Resources.resx | 7 ++- .../HelloWorld.PaddedVersionInfo.exe | Bin 0 -> 72192 bytes .../Version/VersionInfoResourceTest.cs | 49 +++++++++++++++++- 5 files changed, 61 insertions(+), 7 deletions(-) create mode 100644 test/AsmResolver.PE.Win32Resources.Tests/Resources/HelloWorld.PaddedVersionInfo.exe diff --git a/test/AsmResolver.PE.Win32Resources.Tests/AsmResolver.PE.Win32Resources.Tests.csproj b/test/AsmResolver.PE.Win32Resources.Tests/AsmResolver.PE.Win32Resources.Tests.csproj index ff33ce493..ba9f10fa3 100644 --- a/test/AsmResolver.PE.Win32Resources.Tests/AsmResolver.PE.Win32Resources.Tests.csproj +++ b/test/AsmResolver.PE.Win32Resources.Tests/AsmResolver.PE.Win32Resources.Tests.csproj @@ -23,6 +23,7 @@ + @@ -40,8 +41,4 @@ - - - - diff --git a/test/AsmResolver.PE.Win32Resources.Tests/Properties/Resources.Designer.cs b/test/AsmResolver.PE.Win32Resources.Tests/Properties/Resources.Designer.cs index 866341677..3c3cd2021 100644 --- a/test/AsmResolver.PE.Win32Resources.Tests/Properties/Resources.Designer.cs +++ b/test/AsmResolver.PE.Win32Resources.Tests/Properties/Resources.Designer.cs @@ -51,5 +51,12 @@ internal static byte[] HelloWorld { return ((byte[])(obj)); } } + + internal static byte[] HelloWorld_PaddedVersionInfo { + get { + object obj = ResourceManager.GetObject("HelloWorld_PaddedVersionInfo", resourceCulture); + return ((byte[])(obj)); + } + } } } diff --git a/test/AsmResolver.PE.Win32Resources.Tests/Properties/Resources.resx b/test/AsmResolver.PE.Win32Resources.Tests/Properties/Resources.resx index 4a49ff593..e6b342ebd 100644 --- a/test/AsmResolver.PE.Win32Resources.Tests/Properties/Resources.resx +++ b/test/AsmResolver.PE.Win32Resources.Tests/Properties/Resources.resx @@ -3,7 +3,7 @@ - + @@ -21,4 +21,7 @@ ..\Resources\HelloWorld.exe;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - \ No newline at end of file + + ..\Resources\HelloWorld.PaddedVersionInfo.exe;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/test/AsmResolver.PE.Win32Resources.Tests/Resources/HelloWorld.PaddedVersionInfo.exe b/test/AsmResolver.PE.Win32Resources.Tests/Resources/HelloWorld.PaddedVersionInfo.exe new file mode 100644 index 0000000000000000000000000000000000000000..4391dfd46fd53c9341063e1f558787412196f6bc GIT binary patch literal 72192 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 literal 0 HcmV?d00001 diff --git a/test/AsmResolver.PE.Win32Resources.Tests/Version/VersionInfoResourceTest.cs b/test/AsmResolver.PE.Win32Resources.Tests/Version/VersionInfoResourceTest.cs index a9699d22b..296f352fd 100644 --- a/test/AsmResolver.PE.Win32Resources.Tests/Version/VersionInfoResourceTest.cs +++ b/test/AsmResolver.PE.Win32Resources.Tests/Version/VersionInfoResourceTest.cs @@ -2,13 +2,24 @@ using System.IO; using AsmResolver.IO; using AsmResolver.PE.DotNet.Builder; +using AsmResolver.PE.File; +using AsmResolver.PE.File.Headers; +using AsmResolver.PE.Win32Resources.Builder; using AsmResolver.PE.Win32Resources.Version; +using AsmResolver.Tests.Runners; using Xunit; namespace AsmResolver.PE.Win32Resources.Tests.Version { - public class VersionInfoSegmentTest + public class VersionInfoResourceTest : IClassFixture { + private readonly TemporaryDirectoryFixture _fixture; + + public VersionInfoResourceTest(TemporaryDirectoryFixture fixture) + { + _fixture = fixture; + } + [Fact] public void ReadFixedVersion() { @@ -192,5 +203,41 @@ public void PersistentVersionResource() Assert.Equal(versionInfo.FixedVersionInfo.ProductVersion, newVersionInfo.FixedVersionInfo.ProductVersion); } + [Fact] + public void VersionInfoAlignment() + { + // https://github.com/Washi1337/AsmResolver/issues/202 + + // Open dummy + var file = PEFile.FromBytes(Properties.Resources.HelloWorld_PaddedVersionInfo); + var image = PEImage.FromFile(file); + + // Update version info. + var versionInfo = VersionInfoResource.FromDirectory(image.Resources!)!; + var info = versionInfo.GetChild(StringFileInfo.StringFileInfoKey); + info.Tables[0][StringTable.FileDescriptionKey] = "This is a test application"; + versionInfo.WriteToDirectory(image.Resources!); + + // Replace section. + var resourceBuffer = new ResourceDirectoryBuffer(); + resourceBuffer.AddDirectory(image.Resources!); + + var section = file.GetSectionContainingRva(file.OptionalHeader.GetDataDirectory(DataDirectoryIndex.ResourceDirectory).VirtualAddress); + section.Contents = resourceBuffer; + + file.UpdateHeaders(); + file.OptionalHeader.SetDataDirectory(DataDirectoryIndex.ResourceDirectory, + new DataDirectory(resourceBuffer.Rva, resourceBuffer.GetPhysicalSize())); + + // Rebuild + using var stream = new MemoryStream(); + file.Write(stream); + + // Reopen and verify. + var newImage = PEImage.FromBytes(stream.ToArray()); + var newVersionInfo = VersionInfoResource.FromDirectory(newImage.Resources!)!; + var newInfo = newVersionInfo.GetChild(StringFileInfo.StringFileInfoKey); + Assert.Equal("This is a test application", newInfo.Tables[0][StringTable.FileDescriptionKey]); + } } } From f39b806b47100fec7b7080e4813355bcef0807bd Mon Sep 17 00:00:00 2001 From: Washi Date: Sat, 24 Jun 2023 14:47:03 +0200 Subject: [PATCH 3/3] Default to 1033 language ID for new win32 resources. --- src/AsmResolver.PE.Win32Resources/Icon/IconResource.cs | 2 +- .../Version/VersionInfoResource.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/AsmResolver.PE.Win32Resources/Icon/IconResource.cs b/src/AsmResolver.PE.Win32Resources/Icon/IconResource.cs index 9904b1a1a..0a97b0fe2 100644 --- a/src/AsmResolver.PE.Win32Resources/Icon/IconResource.cs +++ b/src/AsmResolver.PE.Win32Resources/Icon/IconResource.cs @@ -98,7 +98,7 @@ public void WriteToDirectory(IResourceDirectory rootDirectory) foreach (var (groupEntry, iconEntry) in entry.Value.GetIconEntries()) { newIconDirectory.Entries.Add(new ResourceDirectory(groupEntry.Id) - {Entries = {new ResourceData(0u, iconEntry)}}); + {Entries = {new ResourceData(1033, iconEntry)}}); } } diff --git a/src/AsmResolver.PE.Win32Resources/Version/VersionInfoResource.cs b/src/AsmResolver.PE.Win32Resources/Version/VersionInfoResource.cs index f27a38e74..5839d2f07 100644 --- a/src/AsmResolver.PE.Win32Resources/Version/VersionInfoResource.cs +++ b/src/AsmResolver.PE.Win32Resources/Version/VersionInfoResource.cs @@ -15,8 +15,8 @@ public class VersionInfoResource : VersionTableEntry, IWin32Resource /// public const string VsVersionInfoKey = "VS_VERSION_INFO"; - private FixedVersionInfo _fixedVersionInfo = new FixedVersionInfo(); - private readonly Dictionary _entries = new Dictionary(); + private FixedVersionInfo _fixedVersionInfo = new(); + private readonly Dictionary _entries = new(); /// public override string Key => VsVersionInfoKey; @@ -198,7 +198,7 @@ public void WriteToDirectory(IResourceDirectory rootDirectory) { new ResourceDirectory(1) { - Entries = {new ResourceData(0u, this)} + Entries = {new ResourceData(1033, this)} } } };