using System; using System.Collections.Generic; namespace X86Disassembler.PE { /// /// Utility class for PE format operations /// public class PEUtility { private readonly List _sectionHeaders; private readonly uint _sizeOfHeaders; /// /// Initialize a new instance of the PEUtility class /// /// The section headers /// The size of the headers public PEUtility(List sectionHeaders, uint sizeOfHeaders) { _sectionHeaders = sectionHeaders; _sizeOfHeaders = sizeOfHeaders; } /// /// Converts a Relative Virtual Address (RVA) to a file offset /// /// The RVA to convert /// The corresponding file offset public uint RvaToOffset(uint rva) { if (rva == 0) { return 0; } foreach (var section in _sectionHeaders) { // Check if the RVA is within this section if (rva >= section.VirtualAddress && rva < section.VirtualAddress + section.VirtualSize) { // Calculate the offset within the section uint offsetInSection = rva - section.VirtualAddress; // Make sure we don't exceed the raw data size if (offsetInSection < section.SizeOfRawData) { return section.PointerToRawData + offsetInSection; } } } // If the RVA is not within any section, it might be in the headers if (rva < _sizeOfHeaders) { return rva; } throw new ArgumentException($"RVA {rva:X8} is not within any section"); } } }