Skip to content

Commit

Permalink
BUGFIX: Support reading/writing unaligned metadata directories.
Browse files Browse the repository at this point in the history
  • Loading branch information
Washi1337 committed Feb 26, 2024
1 parent 2bae91a commit af2e49d
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 7 deletions.
4 changes: 3 additions & 1 deletion src/AsmResolver.PE/DotNet/Metadata/Metadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,11 @@ protected virtual void WriteStreamHeaders(IBinaryStreamWriter writer, MetadataSt
var header = headers[i];
writer.WriteUInt32(header.Offset);
writer.WriteUInt32(header.Size);

ulong nameOffset = writer.Offset;
writer.WriteAsciiString(header.Name);
writer.WriteByte(0);
writer.Align(4);
writer.AlignRelative(4, nameOffset);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/AsmResolver.PE/DotNet/Metadata/MetadataStreamHeader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public static MetadataStreamHeader FromReader(ref BinaryStreamReader reader)
uint offset = reader.ReadUInt32();
uint size = reader.ReadUInt32();
string name = reader.ReadAsciiString();
reader.Align(4);
reader.AlignRelative(4);
return new MetadataStreamHeader(offset, size, name);
}

Expand Down
14 changes: 11 additions & 3 deletions src/AsmResolver/IO/IBinaryStreamWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,18 @@ public static void WriteAsciiString(this IBinaryStreamWriter writer, string valu
/// </summary>
/// <param name="writer">The writer to align.</param>
/// <param name="align">The boundary to use.</param>
public static void Align(this IBinaryStreamWriter writer, uint align)
public static void Align(this IBinaryStreamWriter writer, uint align) => writer.AlignRelative(align, 0);

/// <summary>
/// Aligns the writer to a specified boundary, relative to the provided start offset..
/// </summary>
/// <param name="writer">The writer to align.</param>
/// <param name="align">The boundary to use.</param>
/// <param name="startOffset">The starting offset to consider the alignment boundaries from.</param>
public static void AlignRelative(this IBinaryStreamWriter writer, uint align, ulong startOffset)
{
ulong currentPosition = writer.Offset;
writer.WriteZeroes((int) (currentPosition.Align(align) - writer.Offset));
ulong currentPosition = writer.Offset - startOffset;
writer.WriteZeroes((int) (currentPosition.Align(align) - currentPosition));
}

/// <summary>
Expand Down
13 changes: 11 additions & 2 deletions test/AsmResolver.PE.Tests/DotNet/Metadata/MetadataTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,17 @@ public void CorrectStreamHeaders()
var peImage = PEImage.FromBytes(Properties.Resources.HelloWorld);
var metadata = peImage.DotNetDirectory!.Metadata!;

var expectedNames = new[] {"#~", "#Strings", "#US", "#GUID", "#Blob"};
string[] expectedNames = new[] {"#~", "#Strings", "#US", "#GUID", "#Blob"};
Assert.Equal(expectedNames, metadata.Streams.Select(s => s.Name));
}

[Fact]
public void CorrectStreamHeadersUnalignedMetadataDirectory()
{
var peImage = PEImage.FromBytes(Properties.Resources.HelloWorld_UnalignedMetadata);
var metadata = peImage.DotNetDirectory!.Metadata!;

string[] expectedNames = new[] {"#~", "#Strings", "#US", "#GUID", "#Blob"};
Assert.Equal(expectedNames, metadata.Streams.Select(s => s.Name));
}

Expand Down Expand Up @@ -188,6 +198,5 @@ public void SelectFirstUserStringsStreamInEnCMetadata()
{
AssertCorrectStreamIsSelected<UserStringsStream>(Properties.Resources.HelloWorld_DoubleUserStringsStream_EnC, true);
}

}
}
7 changes: 7 additions & 0 deletions test/AsmResolver.PE.Tests/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions test/AsmResolver.PE.Tests/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@
<data name="HelloWorld_ReadyToRun" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\HelloWorld.ReadyToRun.dll;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="HelloWorld_UnalignedMetadata" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\HelloWorld.UnalignedMetadata.exe;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="HelloWorldPortablePdb" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\HelloWorld.pdb;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
Expand Down
Binary file not shown.

0 comments on commit af2e49d

Please sign in to comment.