diff --git a/src/AsmResolver.PE/Debug/Builder/DebugDirectoryBuffer.cs b/src/AsmResolver.PE/Debug/Builder/DebugDirectoryBuffer.cs index 2cc85880d..c3a0dc300 100644 --- a/src/AsmResolver.PE/Debug/Builder/DebugDirectoryBuffer.cs +++ b/src/AsmResolver.PE/Debug/Builder/DebugDirectoryBuffer.cs @@ -27,7 +27,7 @@ public class DebugDirectoryBuffer : ISegment public void AddEntry(DebugDataEntry entry) { _headers.Add(entry); - if (entry.Contents != null) + if (entry.Contents is not null and not EmptyDebugDataSegment) _streamsTable.Add(entry.Contents, 4); } diff --git a/src/AsmResolver.PE/Debug/EmptyDebugDataSegment.cs b/src/AsmResolver.PE/Debug/EmptyDebugDataSegment.cs new file mode 100644 index 000000000..402079a8e --- /dev/null +++ b/src/AsmResolver.PE/Debug/EmptyDebugDataSegment.cs @@ -0,0 +1,43 @@ +using System.Diagnostics; +using AsmResolver.IO; + +namespace AsmResolver.PE.Debug; + +/// +/// Represents the contents of an empty debug data entry. +/// +public sealed class EmptyDebugDataSegment : IDebugDataSegment +{ + /// + /// Creates a new empty debug data segment for the provided debug data content. + /// + /// The content type. + public EmptyDebugDataSegment(DebugDataType type) + { + Type = type; + } + + /// + public DebugDataType Type { get; } + + bool ISegment.CanUpdateOffsets => false; + + ulong IOffsetProvider.Offset => 0; + + uint IOffsetProvider.Rva => 0; + + /// + void ISegment.UpdateOffsets(in RelocationParameters parameters) + { + } + + /// + uint IWritable.GetPhysicalSize() => 0; + + /// + uint ISegment.GetVirtualSize() => 0; + + void IWritable.Write(BinaryStreamWriter writer) + { + } +} diff --git a/src/AsmResolver.PE/Debug/SerializedDebugDataEntry.cs b/src/AsmResolver.PE/Debug/SerializedDebugDataEntry.cs index 4711a6063..311adfeaf 100644 --- a/src/AsmResolver.PE/Debug/SerializedDebugDataEntry.cs +++ b/src/AsmResolver.PE/Debug/SerializedDebugDataEntry.cs @@ -43,17 +43,25 @@ public SerializedDebugDataEntry( /// protected override IDebugDataSegment? GetContents() { + BinaryStreamReader reader; + if (_sizeOfData == 0) - return null; + return new EmptyDebugDataSegment(_type); - var reference = _context.File.GetReferenceToRva(_addressOfRawData); - if (!reference.CanRead) + if (_addressOfRawData == 0 || _context.File.MappingMode == File.PEMappingMode.Unmapped) + { + if (!_context.File.TryCreateReaderAtFileOffset(_pointerToRawData, out reader)) + { + _context.BadImage("Debug data entry contains an invalid file offset."); + return null; + } + } + else if (!_context.File.TryCreateReaderAtRva(_addressOfRawData, out reader)) { _context.BadImage("Debug data entry contains an invalid RVA."); return null; } - var reader = reference.CreateReader(); if (_sizeOfData > reader.Length) { _context.BadImage("Debug data entry contains a too large size.");