Windows Pe 第三章 PE头文件-EX-相关编程-2(RVA_FOA转换)
生活随笔
收集整理的這篇文章主要介紹了
Windows Pe 第三章 PE头文件-EX-相关编程-2(RVA_FOA转换)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
RVA-FOA之間轉換
?
1.首先PE頭加載到內存之后是和文件頭內容一樣的,就算是偏移不同,一個是磁盤扇區大小(400H)另一個是內存頁大小(1000H),但是因為兩個都是開頭位置,所以相同。
?
2.看下IMAGE_SECTION_HEADER定義
?
也就是這樣:
?
然后就可以算了(RVA->FOA)
?
(1)?RVA20 < RVA < RVA30 可以知道在第二節
(2)?然后 off = RVA - RVA20 ,得出距離第二節的偏移off
(3)?FOA = FOA 20 + off 求出FOA
計算FOA->RVA也是同理...
?
/************************************************************************/ /* 功能:虛擬內存相對地址和文件偏移的轉換 參數:stRVA: 虛擬內存相對偏移地址lpFileBuf: 文件起始地址 返回:轉換后的文件偏移地址 */ /************************************************************************/ size_t RVAToOffset(size_t stRVA,PVOID lpFileBuf) { PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpFileBuf; size_t stPEHeadAddr = (size_t)lpFileBuf + pDos ->e_lfanew; PIMAGE_NT_HEADERS32 pNT = (PIMAGE_NT_HEADERS32)stPEHeadAddr; //區段數 DWORD dwSectionCount = pNT->FileHeader.NumberOfSections; //內存對齊大小 DWORD dwMemoruAil = pNT->OptionalHeader.SectionAlignment; PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNT); //距離命中節的起始虛擬地址的偏移值。 DWORD dwDiffer = 0; for (DWORD i = 0; i < dwSectionCount; i++) { //模擬內存對齊機制 DWORD dwBlockCount = pSection[i].SizeOfRawData/dwMemoruAil; dwBlockCount += pSection[i].SizeOfRawData%dwMemoruAil? 1 : 0; DWORD dwBeginVA = pSection[i].VirtualAddress; DWORD dwEndVA = pSection[i].VirtualAddress + dwBlockCount * dwMemoruAil; //如果stRVA在某個區段中 if (stRVA >= dwBeginVA && stRVA < dwEndVA) { dwDiffer = stRVA - dwBeginVA; return pSection[i].PointerToRawData + dwDiffer; } else if (stRVA < dwBeginVA)//在文件頭中直接返回 { return stRVA; } } return 0; } /************************************************************************/ /* 功能:文件偏移地址和虛擬地址的轉換 參數:stOffset:文件偏移地址lpFileBuf:虛擬內存起始地址 返回:轉換后的虛擬地址 */ /************************************************************************/ size_t Offset2VA(size_t stOffset, PVOID lpFileBuf) { //獲取DOS頭 PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpFileBuf; //獲取PE頭 //e_lfanew:PE頭相對于文件的偏移地址 size_t stPEHeadAddr = (size_t)lpFileBuf + pDos ->e_lfanew; PIMAGE_NT_HEADERS32 pNT = (PIMAGE_NT_HEADERS32)stPEHeadAddr; //區段數 DWORD dwSectionCount = pNT->FileHeader.NumberOfSections; //映像地址 DWORD dwImageBase = pNT->OptionalHeader.ImageBase; //區段頭 PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNT); //相對大小 DWORD dwDiffer = 0; for (DWORD i = 0; i < dwSectionCount; i++) { //區段的起始地址和結束地址 DWORD dwBeginVA = pSection[i].PointerToRawData; DWORD dwEndVA = pSection[i].PointerToRawData + pSection[i].SizeOfRawData; //如果文件偏移地址在dwBeginVA和dwEndVA之間 if (stOffset >= dwBeginVA && stOffset < dwEndVA) { //相對大小 dwDiffer = stOffset - dwBeginVA; //進程的起始地址 + 區段的相對地址 + 相對區段的大小 //return dwImageBase + pSection[i].VirtualAddress + dwDiffer; return pSection[i].VirtualAddress + dwDiffer;} else if (stOffset < dwBeginVA) //如果文件偏移地址不在區段中 { return dwImageBase + stOffset; } } return 0; }測試了上面兩個函數,沒發現什么問題,測試結果:
?
隨手寫了個簡單的工具,直接控制臺寫的,功能簡單,懶得寫界面了。源碼在:
http://download.csdn.net/detail/u013761036/9643230
運行效果:
總結
以上是生活随笔為你收集整理的Windows Pe 第三章 PE头文件-EX-相关编程-2(RVA_FOA转换)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows Pe 第三章 PE头文件
- 下一篇: svchost服务(DLL服务)