| 439 | } |
| 440 | |
| 441 | std::uint32_t PeLib::ImageLoader::getFileOffsetFromRva(std::uint32_t rva) const |
| 442 | { |
| 443 | // If we have sections loaded, then we calculate the file offset from section headers |
| 444 | if(sections.size()) |
| 445 | { |
| 446 | // Check whether the rva goes into any section |
| 447 | for(auto & sectHdr : sections) |
| 448 | { |
| 449 | // Only if the pointer to raw data is not zero |
| 450 | if(sectHdr.PointerToRawData != 0 && sectHdr.SizeOfRawData != 0) |
| 451 | { |
| 452 | std::uint32_t realPointerToRawData = sectHdr.PointerToRawData; |
| 453 | std::uint32_t sectionRvaStart = sectHdr.VirtualAddress; |
| 454 | std::uint32_t virtualSize = (sectHdr.VirtualSize != 0) ? sectHdr.VirtualSize : sectHdr.SizeOfRawData; |
| 455 | |
| 456 | // For multi-section images, real pointer to raw data is aligned down to sector size |
| 457 | if(optionalHeader.SectionAlignment >= PELIB_PAGE_SIZE) |
| 458 | realPointerToRawData = realPointerToRawData & ~(PELIB_SECTOR_SIZE - 1); |
| 459 | |
| 460 | // Is the RVA inside that section? |
| 461 | if(sectionRvaStart <= rva && rva < (sectionRvaStart + virtualSize)) |
| 462 | { |
| 463 | // Make sure we round the pointer to raw data down to PELIB_SECTOR_SIZE. |
| 464 | // In case when PointerToRawData is less than 0x200, it maps to the header! |
| 465 | return realPointerToRawData + (rva - sectionRvaStart); |
| 466 | } |
| 467 | } |
| 468 | } |
| 469 | |
| 470 | // Check if the rva goes into the header |
| 471 | return (rva < optionalHeader.SizeOfHeaders) ? rva : UINT32_MAX; |
| 472 | } |
| 473 | |
| 474 | // The rva maps directly to the file offset |
| 475 | return rva; |
| 476 | } |
| 477 | |
| 478 | // similar to getFileOffsetFromRva, but the offset is within the real file and not memory image |
| 479 | std::uint32_t PeLib::ImageLoader::getValidOffsetFromRva(std::uint32_t rva) const |
no test coverage detected