c++debuggingprocessportable-executablecffile

How can we map RVA (Relative Virtual Address) of a location to PE file offset?


I need to map RVA (Relative virtual address that's taken from pdb file) to PE file(EXE) offset when reading PE file from a disk location. For this I need to convert RVA to file offset so that I can read out GUIDS(CLSID,IID's) from that location.

Regards Usman


Solution

  • template <class T> LPVOID GetPtrFromRVA(
       DWORD rva,
       T* pNTHeader,
       PBYTE imageBase ) // 'T' = PIMAGE_NT_HEADERS
    {
       PIMAGE_SECTION_HEADER pSectionHdr;
       INT delta;
    
       pSectionHdr = GetEnclosingSectionHeader( rva, pNTHeader);
       if ( !pSectionHdr )
          return 0;
    
       delta = (INT)(pSectionHdr->VirtualAddress-pSectionHdr->PointerToRawData);
       return (PVOID) ( imageBase + rva - delta );
    }
    
    template <class T> PIMAGE_SECTION_HEADER GetEnclosingSectionHeader(
       DWORD rva,
       T* pNTHeader)   // 'T' == PIMAGE_NT_HEADERS
    {
        PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(pNTHeader);
        unsigned i;
    
        for ( i=0; i < pNTHeader->FileHeader.NumberOfSections; i++, section++ )
        {
          // This 3 line idiocy is because Watcom's linker actually sets the
          // Misc.VirtualSize field to 0.  (!!! - Retards....!!!)
          DWORD size = section->Misc.VirtualSize;
          if ( 0 == size )
             size = section->SizeOfRawData;
    
            // Is the RVA within this section?
            if ( (rva >= section->VirtualAddress) &&
                 (rva < (section->VirtualAddress + size)))
                return section;
        }
    
        return 0;
    }
    

    should do the trick...