public static class RvaMapper
{
public static int? RvaToFileOffset(uint rva, IReadOnlyList<SectionInfo> sections, uint sizeOfHeaders)
{
if (rva < sizeOfHeaders)
{
return (int)rva;
}
foreach (var section in sections)
{
var virtualSize = Math.Max(section.VirtualSize, section.SizeOfRawData);
var start = section.VirtualAddress;
var end = start + virtualSize;
if (rva >= start && rva < end)
{
var delta = rva - start;
if (delta >= section.SizeOfRawData)
{
return null;
}
return checked((int)(section.PointerToRawData + delta));
}
}
return null;
}
public static uint? FileOffsetToRva(uint fileOffset, IReadOnlyList<SectionInfo> sections, uint sizeOfHeaders)
{
if (fileOffset < sizeOfHeaders)
{
return fileOffset;
}
foreach (var section in sections)
{
var start = section.PointerToRawData;
var end = start + section.SizeOfRawData;
if (fileOffset >= start && fileOffset < end)
{
var delta = fileOffset - start;
return section.VirtualAddress + delta;
}
}
return null;
}
}