public sealed class ExceptionDirectoryParser
{
public IReadOnlyList<ExceptionEntryInfo> Parse(byte[] rawBytes, NtHeaders nt, IReadOnlyList<SectionInfo> sections)
{
if (nt.OptionalHeader.DataDirectories.Count <= 3)
{
return Array.Empty<ExceptionEntryInfo>();
}
var dir = nt.OptionalHeader.DataDirectories[3];
if (dir.VirtualAddress == 0 || dir.Size == 0)
{
return Array.Empty<ExceptionEntryInfo>();
}
var offset = RvaMapper.RvaToFileOffset(dir.VirtualAddress, sections, nt.OptionalHeader.SizeOfHeaders);
if (offset is null)
{
return Array.Empty<ExceptionEntryInfo>();
}
var items = new List<ExceptionEntryInfo>();
var entrySize = 12;
var count = (int)(dir.Size / entrySize);
for (var i = 0; i < count; i++)
{
var pos = offset.Value + i * entrySize;
if (pos + entrySize > rawBytes.Length)
{
break;
}
items.Add(new ExceptionEntryInfo(
BitConverter.ToUInt32(rawBytes, pos),
BitConverter.ToUInt32(rawBytes, pos + 4),
BitConverter.ToUInt32(rawBytes, pos + 8)));
}
return items;
}
}