日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

Windows Pe 第三章 PE头文件-EX-相关编程-2(RVA_FOA转换)

發(fā)布時間:2025/6/17 windows 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windows Pe 第三章 PE头文件-EX-相关编程-2(RVA_FOA转换) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

RVA-FOA之間轉(zhuǎn)換

?

1.首先PE頭加載到內(nèi)存之后是和文件頭內(nèi)容一樣的,就算是偏移不同,一個是磁盤扇區(qū)大小(400H)另一個是內(nèi)存頁大小(1000H),但是因為兩個都是開頭位置,所以相同。

?

2.看下IMAGE_SECTION_HEADER定義

?

也就是這樣:

?

然后就可以算了(RVA->FOA)

?

(1)?RVA20 < RVA < RVA30 可以知道在第二節(jié)

(2)?然后 off = RVA - RVA20 ,得出距離第二節(jié)的偏移off

(3)?FOA = FOA 20 + off 求出FOA

計算FOA->RVA也是同理...

?

/************************************************************************/ /* 功能:虛擬內(nèi)存相對地址和文件偏移的轉(zhuǎn)換 參數(shù):stRVA: 虛擬內(nèi)存相對偏移地址lpFileBuf: 文件起始地址 返回:轉(zhuǎn)換后的文件偏移地址 */ /************************************************************************/ 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; //區(qū)段數(shù) DWORD dwSectionCount = pNT->FileHeader.NumberOfSections; //內(nèi)存對齊大小 DWORD dwMemoruAil = pNT->OptionalHeader.SectionAlignment; PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNT); //距離命中節(jié)的起始虛擬地址的偏移值。 DWORD dwDiffer = 0; for (DWORD i = 0; i < dwSectionCount; i++) { //模擬內(nè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在某個區(qū)段中 if (stRVA >= dwBeginVA && stRVA < dwEndVA) { dwDiffer = stRVA - dwBeginVA; return pSection[i].PointerToRawData + dwDiffer; } else if (stRVA < dwBeginVA)//在文件頭中直接返回 { return stRVA; } } return 0; } /************************************************************************/ /* 功能:文件偏移地址和虛擬地址的轉(zhuǎn)換 參數(shù):stOffset:文件偏移地址lpFileBuf:虛擬內(nèi)存起始地址 返回:轉(zhuǎn)換后的虛擬地址 */ /************************************************************************/ 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; //區(qū)段數(shù) DWORD dwSectionCount = pNT->FileHeader.NumberOfSections; //映像地址 DWORD dwImageBase = pNT->OptionalHeader.ImageBase; //區(qū)段頭 PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNT); //相對大小 DWORD dwDiffer = 0; for (DWORD i = 0; i < dwSectionCount; i++) { //區(qū)段的起始地址和結(jié)束地址 DWORD dwBeginVA = pSection[i].PointerToRawData; DWORD dwEndVA = pSection[i].PointerToRawData + pSection[i].SizeOfRawData; //如果文件偏移地址在dwBeginVA和dwEndVA之間 if (stOffset >= dwBeginVA && stOffset < dwEndVA) { //相對大小 dwDiffer = stOffset - dwBeginVA; //進程的起始地址 + 區(qū)段的相對地址 + 相對區(qū)段的大小 //return dwImageBase + pSection[i].VirtualAddress + dwDiffer; return pSection[i].VirtualAddress + dwDiffer;} else if (stOffset < dwBeginVA) //如果文件偏移地址不在區(qū)段中 { return dwImageBase + stOffset; } } return 0; }

測試了上面兩個函數(shù),沒發(fā)現(xiàn)什么問題,測試結(jié)果:

?

隨手寫了個簡單的工具,直接控制臺寫的,功能簡單,懶得寫界面了。源碼在:

http://download.csdn.net/detail/u013761036/9643230

運行效果:


總結(jié)

以上是生活随笔為你收集整理的Windows Pe 第三章 PE头文件-EX-相关编程-2(RVA_FOA转换)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。