RvaToFileOffset 內存偏移轉成文件偏移(滴水課後作業)

題目說明

將內存偏移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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章