public sealed class DelayImportDirectoryParser
{
public IReadOnlyList<DelayImportInfo> Parse(byte[] rawBytes, NtHeaders nt, IReadOnlyList<SectionInfo> sections)
{
if (nt.OptionalHeader.DataDirectories.Count <= 13)
{
return Array.Empty<DelayImportInfo>();
}
var dir = nt.OptionalHeader.DataDirectories[13];
if (dir.VirtualAddress == 0 || dir.Size == 0)
{
return Array.Empty<DelayImportInfo>();
}
var offset = RvaMapper.RvaToFileOffset(dir.VirtualAddress, sections, nt.OptionalHeader.SizeOfHeaders);
if (offset is null)
{
return Array.Empty<DelayImportInfo>();
}
var items = new List<DelayImportInfo>();
var pos = offset.Value;
while (pos + 32 <= rawBytes.Length)
{
var attributes = BitConverter.ToUInt32(rawBytes, pos);
var nameRva = BitConverter.ToUInt32(rawBytes, pos + 4);
var moduleHandle = BitConverter.ToUInt32(rawBytes, pos + 8);
var iat = BitConverter.ToUInt32(rawBytes, pos + 12);
var intRva = BitConverter.ToUInt32(rawBytes, pos + 16);
var biat = BitConverter.ToUInt32(rawBytes, pos + 20);
var uiat = BitConverter.ToUInt32(rawBytes, pos + 24);
var tds = BitConverter.ToUInt32(rawBytes, pos + 28);
if (attributes == 0 && nameRva == 0 && moduleHandle == 0 && iat == 0 && intRva == 0 && biat == 0 && uiat == 0 && tds == 0)
{
break;
}
var dllName = DirectoryParserHelpers.ReadAsciiAtRva(rawBytes, nameRva, nt, sections, 512);
items.Add(new DelayImportInfo(dllName, attributes, nameRva, moduleHandle, iat, intRva, biat, uiat, tds));
pos += 32;
}
return items;
}
}