diff --git a/src/AsmResolver.PE.File/Headers/SectionHeader.cs b/src/AsmResolver.PE.File/Headers/SectionHeader.cs
index f2a72e7d0..a5de4f389 100644
--- a/src/AsmResolver.PE.File/Headers/SectionHeader.cs
+++ b/src/AsmResolver.PE.File/Headers/SectionHeader.cs
@@ -19,35 +19,6 @@ public class SectionHeader : SegmentBase, IOffsetConverter
private string _name;
- ///
- /// Reads a single section header at the current position of the provided input stream.
- ///
- /// The input stream to read from.
- /// The section header that was read.
- public static SectionHeader FromReader(ref BinaryStreamReader reader)
- {
- ulong offset = reader.Offset;
- uint rva = reader.Rva;
-
- var nameBytes = new byte[8];
- reader.ReadBytes(nameBytes, 0, nameBytes.Length);
-
- return new SectionHeader(Encoding.UTF8.GetString(nameBytes).Replace("\0", ""), 0)
- {
- Offset = offset,
- Rva = rva,
- VirtualSize = reader.ReadUInt32(),
- VirtualAddress = reader.ReadUInt32(),
- SizeOfRawData = reader.ReadUInt32(),
- PointerToRawData = reader.ReadUInt32(),
- PointerToRelocations = reader.ReadUInt32(),
- PointerToLineNumbers = reader.ReadUInt32(),
- NumberOfRelocations = reader.ReadUInt16(),
- NumberOfLineNumbers = reader.ReadUInt16(),
- Characteristics = (SectionFlags) reader.ReadUInt32()
- };
- }
-
///
/// Creates a new section header with the provided name.
///
@@ -194,6 +165,46 @@ public SectionFlags Characteristics
set;
}
+ ///
+ /// Reads a single section header at the current position of the provided input stream.
+ ///
+ /// The input stream to read from.
+ /// The section header that was read.
+ public static SectionHeader FromReader(ref BinaryStreamReader reader)
+ {
+ ulong offset = reader.Offset;
+ uint rva = reader.Rva;
+
+ // Read name field.
+ byte[] nameBytes = new byte[8];
+ reader.ReadBytes(nameBytes, 0, nameBytes.Length);
+
+ // Interpret as UTF-8, discarding all invalid UTF-8 characters.
+ string name = Encoding.UTF8.GetString(nameBytes).Replace("\xfffd", "");
+
+ // Trim to last null-byte if it exists.
+ int index = name.IndexOf('\0');
+ if (index >= 0)
+ name = name.Remove(index);
+
+ return new SectionHeader(name, 0)
+ {
+ Offset = offset,
+ Rva = rva,
+
+ // Read remainder of section header.
+ VirtualSize = reader.ReadUInt32(),
+ VirtualAddress = reader.ReadUInt32(),
+ SizeOfRawData = reader.ReadUInt32(),
+ PointerToRawData = reader.ReadUInt32(),
+ PointerToRelocations = reader.ReadUInt32(),
+ PointerToLineNumbers = reader.ReadUInt32(),
+ NumberOfRelocations = reader.ReadUInt16(),
+ NumberOfLineNumbers = reader.ReadUInt16(),
+ Characteristics = (SectionFlags) reader.ReadUInt32()
+ };
+ }
+
///
public override uint GetPhysicalSize() => SectionHeaderSize;
diff --git a/test/AsmResolver.PE.File.Tests/PEFileTest.cs b/test/AsmResolver.PE.File.Tests/PEFileTest.cs
index 7a1c47463..5ce0a2b96 100644
--- a/test/AsmResolver.PE.File.Tests/PEFileTest.cs
+++ b/test/AsmResolver.PE.File.Tests/PEFileTest.cs
@@ -240,5 +240,19 @@ public void RemoveExistingEofData()
var newFile = PEFile.FromBytes(newFileBytes);
Assert.Null(newFile.EofData);
}
+
+ [Fact]
+ public void ReadSections()
+ {
+ var file = PEFile.FromBytes(Properties.Resources.HelloWorld);
+ Assert.Equal(new[] {".text", ".rsrc", ".reloc"}, file.Sections.Select(x => x.Name));
+ }
+
+ [Fact]
+ public void ReadInvalidSectionName()
+ {
+ var file = PEFile.FromBytes(Properties.Resources.HelloWorld_InvalidSectionName);
+ Assert.Equal(new[] {".text", ".rsrc", ".reloc"}, file.Sections.Select(x => x.Name));
+ }
}
}
diff --git a/test/AsmResolver.PE.File.Tests/Properties/Resources.Designer.cs b/test/AsmResolver.PE.File.Tests/Properties/Resources.Designer.cs
index f2f817fd5..57a37ab19 100644
--- a/test/AsmResolver.PE.File.Tests/Properties/Resources.Designer.cs
+++ b/test/AsmResolver.PE.File.Tests/Properties/Resources.Designer.cs
@@ -90,6 +90,16 @@ public static byte[] HelloWorld_EOF {
}
}
+ ///
+ /// Looks up a localized resource of type System.Byte[].
+ ///
+ public static byte[] HelloWorld_InvalidSectionName {
+ get {
+ object obj = ResourceManager.GetObject("HelloWorld_InvalidSectionName", resourceCulture);
+ return ((byte[])(obj));
+ }
+ }
+
///
/// Looks up a localized resource of type System.Byte[].
///
diff --git a/test/AsmResolver.PE.File.Tests/Properties/Resources.resx b/test/AsmResolver.PE.File.Tests/Properties/Resources.resx
index c33ee0174..b075ab67e 100644
--- a/test/AsmResolver.PE.File.Tests/Properties/Resources.resx
+++ b/test/AsmResolver.PE.File.Tests/Properties/Resources.resx
@@ -127,7 +127,10 @@
..\Resources\HelloWorld.EOF.exe;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- ..\Resources\NativeMemoryDemos.exe;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
+
+ ..\Resources\HelloWorld.InvalidSectionName.exe;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ ..\Resources\NativeMemoryDemos.exe;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
diff --git a/test/AsmResolver.PE.File.Tests/Resources/HelloWorld.InvalidSectionName.exe b/test/AsmResolver.PE.File.Tests/Resources/HelloWorld.InvalidSectionName.exe
new file mode 100644
index 000000000..8947b3b63
Binary files /dev/null and b/test/AsmResolver.PE.File.Tests/Resources/HelloWorld.InvalidSectionName.exe differ