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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

PE 学习之路 —— 区块表

發布時間:2024/4/17 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PE 学习之路 —— 区块表 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 前述

在 NT 頭結束后,緊接著就是區塊表,區塊表包含每個塊在映象中的信息,分別指向不同的區塊實體。

2. 區塊表

區塊表是一個 IMAGE_SECTION_HEADER 結構數組,這個結構包含區塊的信息,比如位置、長度、屬性等,區塊的數目是由 NT 頭中的文件頭里的?NumberOfSections?給出。以下為 `IMAGE_SECTION_HEADER` 結構:

在上述圖中,有兩個字段比較重要,分別為 `VirtualAddress`、`PointerToRawData`,這兩個字段用于將相對虛擬地址或虛擬地址轉換為文件偏移地址,以下為 RVA 轉 FOA 函數:

DWORD RVAtoFOA(DWORD dwRva) {// 獲取區段表的數量DWORD dwCounts = g_NtHeader->FileHeader.NumberOfSections;// 獲取區段表數組的首元素auto Sections = IMAGE_FIRST_SECTION(g_NtHeader);// 遍歷所有的區段表找到符合要求的區段for (DWORD i = 0; i < dwCounts; ++i){// 要求:RVA >= 區段的首地址 并且 RVA < 區段的結尾的地址if (dwRva >= Sections[i].VirtualAddress &&(Sections[i].VirtualAddress + Sections[i].SizeOfRawData)){// FOA = VA - ImageBase - (所在區段的 RVA - 所在區段的 FOA)// FOA = RVA - 所在區段的 RVA + 所在區段的 FOAreturn dwRva - Sections[i].VirtualAddress + Sections[i].PointerToRawData;}}// 如果找不到就返回 -1return -1; }

計算公式為:`FOA = VA - ImageBase - (所在區段的 RVA - 所在區段的 FOA)` 或 `FOA = RVA - 所在區段的 RVA + 所在區段的 FOA`。在上述代碼中,有一個為 `IMAGE_FIRST_SECTION`,我們來看下它的定義,如下:

其實 `IMAGE_FIRST_SECTION` 為一個宏,它主要由三部分相加組成,作用是獲取到第一個區段的首地址,參數為 NT 頭。你可以把這個首地址理解成數組名,數組的首地址。在獲取到了地址后,下面的 for 循環遍歷所有的區段表找到符合要求的區段。這三部分內容具體如下:

  • IMAGE_NT_HEADERS 的起始地址
  • IMAGE_OPTIONAL_HEADER32 (PE 擴展頭)在 IMAGE_NT_HEADERS 中的偏移
  • IMAGE_OPTIONAL_HEADER32 的大小

?其中后兩個加起來的大小恰好就是 IMAGE_NT_HEADERS 的大小,再跟第一個相加就得到區段表的地址了。看到這你可以會問,為什么不直接加上 `IMAGE_NT_HEADERS` 的大小呢?因為 `IMAGE_OPTIONAL_HEADER32` 大小不固定,32 位下該值為 0x00E0H,64 位下該值為 0x00F0H,并且用戶還可以自定義其大小。

?3. 額外說明

擴展頭大小是由文件頭中 `SizeOfOptionalHeader` 字段給出,`FIELD_OFFSET` 這個是給出 `OptionalHeader` 在 `IMAGE_NT_HEADERS` 結構中的偏移,如下:

(本小節完)

轉載于:https://www.cnblogs.com/importthis/p/10192523.html

總結

以上是生活随笔為你收集整理的PE 学习之路 —— 区块表的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。