public sealed class ComDescriptorParser
{
public ComDescriptorInfo? Parse(byte[] rawBytes, NtHeaders nt, IReadOnlyList<SectionInfo> sections)
{
if (nt.OptionalHeader.DataDirectories.Count <= 14)
{
return null;
}
var dir = nt.OptionalHeader.DataDirectories[14];
if (dir.VirtualAddress == 0 || dir.Size == 0)
{
return null;
}
var offset = RvaMapper.RvaToFileOffset(dir.VirtualAddress, sections, nt.OptionalHeader.SizeOfHeaders);
if (offset is null || offset.Value + 24 > rawBytes.Length)
{
return null;
}
var pos = offset.Value;
var cb = BitConverter.ToUInt32(rawBytes, pos);
var major = BitConverter.ToUInt16(rawBytes, pos + 4);
var minor = BitConverter.ToUInt16(rawBytes, pos + 6);
var metadataRva = BitConverter.ToUInt32(rawBytes, pos + 8);
var metadataSize = BitConverter.ToUInt32(rawBytes, pos + 12);
var flags = BitConverter.ToUInt32(rawBytes, pos + 16);
var entryPoint = BitConverter.ToUInt32(rawBytes, pos + 20);
return new ComDescriptorInfo(cb, major, minor, new DataDirectory(metadataRva, metadataSize), flags, entryPoint);
}
}