題目說明
將內存偏移RVA轉成文件偏移FOA的函數;
思路是遍歷節表,比較節內存偏移VirtualAddress和RVA,確定RVA所在的節之後,計算RVA距離所在節首地址的偏移offset,然後返回offset+PointerToRawData.
以xp的notepad.exe爲例
.text節的文件偏移是400h,內存偏移是1000h,調用函數結果如下:
printf("%x\n", RvaToFileOffset(pFileBuffer, 0x1000));
函數源碼
// 內存偏移RVA轉成文件偏移FOA
// 返回轉換後FOA的值,失敗返回0
DWORD RvaToFileOffset(IN LPVOID pFileBuffer,IN DWORD dwRva)
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
int i = 0;
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)(pDosHeader->e_lfanew + (DWORD)pFileBuffer);
pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pNTHeader + 0x18);
// 遍歷節表,確定偏移屬於哪一個節
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);
for (i = 0; i < pPEHeader->NumberOfSections; i++)
{
if (dwRva >= pSectionHeader->VirtualAddress && \
dwRva < pSectionHeader->VirtualAddress + pSectionHeader->Misc.VirtualSize)
{
int offset = dwRva - pSectionHeader->VirtualAddress;
return pSectionHeader->PointerToRawData + offset;
}
pSectionHeader++;
}
return 0;
}