public sealed class TlsDirectoryParser
{
public TlsDirectoryInfo? Parse(byte[] rawBytes, NtHeaders nt, IReadOnlyList<SectionInfo> sections)
{
if (nt.OptionalHeader.DataDirectories.Count <= 9)
{
return null;
}
var dir = nt.OptionalHeader.DataDirectories[9];
if (dir.VirtualAddress == 0 || dir.Size == 0)
{
return null;
}
var offset = RvaMapper.RvaToFileOffset(dir.VirtualAddress, sections, nt.OptionalHeader.SizeOfHeaders);
if (offset is null)
{
return null;
}
var pos = offset.Value;
if (!nt.OptionalHeader.IsPe32Plus)
{
BoundsChecker.EnsureRange(pos, 24, rawBytes.Length, "TLS directory");
return new TlsDirectoryInfo(
BitConverter.ToUInt32(rawBytes, pos),
BitConverter.ToUInt32(rawBytes, pos + 4),
BitConverter.ToUInt32(rawBytes, pos + 8),
BitConverter.ToUInt32(rawBytes, pos + 12),
BitConverter.ToUInt32(rawBytes, pos + 16),
BitConverter.ToUInt32(rawBytes, pos + 20));
}
BoundsChecker.EnsureRange(pos, 40, rawBytes.Length, "TLS directory");
return new TlsDirectoryInfo(
BitConverter.ToUInt64(rawBytes, pos),
BitConverter.ToUInt64(rawBytes, pos + 8),
BitConverter.ToUInt64(rawBytes, pos + 16),
BitConverter.ToUInt64(rawBytes, pos + 24),
BitConverter.ToUInt32(rawBytes, pos + 32),
BitConverter.ToUInt32(rawBytes, pos + 36));
}
}