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;
}
}