public sealed class DebugDirectoryParser
{
    public IReadOnlyList<DebugDirectoryInfo> Parse(byte[] rawBytes, NtHeaders nt, IReadOnlyList<SectionInfo> sections)
    {
        if (nt.OptionalHeader.DataDirectories.Count <= 6)
        {
            return Array.Empty<DebugDirectoryInfo>();
        }

        var dir = nt.OptionalHeader.DataDirectories[6];
        if (dir.VirtualAddress == 0 || dir.Size == 0)
        {
            return Array.Empty<DebugDirectoryInfo>();
        }

        var offset = RvaMapper.RvaToFileOffset(dir.VirtualAddress, sections, nt.OptionalHeader.SizeOfHeaders);
        if (offset is null)
        {
            return Array.Empty<DebugDirectoryInfo>();
        }

        var results = new List<DebugDirectoryInfo>();
        var count = (int)(dir.Size / 28);
        for (var i = 0; i < count; i++)
        {
            var pos = offset.Value + i * 28;
            if (pos + 28 > rawBytes.Length)
            {
                break;
            }

            results.Add(new DebugDirectoryInfo(
                BitConverter.ToUInt32(rawBytes, pos),
                BitConverter.ToUInt32(rawBytes, pos + 4),
                BitConverter.ToUInt16(rawBytes, pos + 8),
                BitConverter.ToUInt16(rawBytes, pos + 10),
                BitConverter.ToUInt32(rawBytes, pos + 12),
                BitConverter.ToUInt32(rawBytes, pos + 16),
                BitConverter.ToUInt32(rawBytes, pos + 20),
                BitConverter.ToUInt32(rawBytes, pos + 24)));
        }

        return results;
    }
}