一丶熟悉PE的總體結構學習
從下面依次網上看.能夠得出PE結構操作系統
其中DOS頭有DOS頭結構 也就是 IMAGE_DOS_HEADER3d
關於結構體的各項屬性.前邊已經寫過了.本系列博客就是加深PE印象.理解複雜的原理.blog
IMAGE_DOS_HEADER 大小 64個字節 十六進制 0x40字節內存
IMAGE_FILE_HEADER 大小 20個字節 十六進制 0x14字節博客
IAMGE_OPTIONAL_HEADER 224個字節 十六進制 0xE0原理
IMAGE_SECTION_HEADER 40個字節 十六進制 0x28擴展
二丶學習DOS頭file
根據上面獲得DOS頭所佔用大小是0x40. 也就是說一個按照16進製爲一行的PE文件.4行正好就是一個DOS頭大小.im
例如: 使用Winhex查看.
DOS結構體重要的成員就兩個.
1.MZ頭
2.指向PE偏移.
MZ頭就是標出來的 4D 5A 大小是兩個字節. 操做系統會以檢查這個標識.判斷是不是PE文件.
PE偏移 0x00000138 大小是4個字節.指向PE頭. NT頭中的PE標識.操做系統不光檢查MZ 也檢查PE.
三丶DOS stub
Dos stub 大小是不肯定的,他的大小是 PE頭減掉 DOS頭大小.其中成員都是Dos stub.
四丶肯定文件頭
根據咱們文件頭大小. 0x14 大小.那麼PE後面就是文件頭
五丶肯定擴展頭
咱們的擴展頭很大.32位64不同.咱們文件頭下面就是這個擴展頭.
注意,咱們這個頭的大小也在文件頭中存儲着. 咱們能夠更改的.若是更改.那麼咱們的擴展頭就要更改.
例如文件頭中存儲着擴展頭大小
而文件頭下面的這些成員都是擴展頭
六丶節表
節表是很重要的.咱們真正的數據就是存在節表裏面.
節表大小 十進制 40個字節,十六進制 0x28
能夠看出節表大小. 裏面第一個是text節.第二個是rdata節...
在咱們的擴展頭中.有一個成員是記錄着 DOS頭 + NT頭(文件+擴展 在一塊兒稱爲NT) + 節表的大小. 按照文件對齊存放着.
sizeofHeaders 按照文件對齊.存儲着 頭+ 節表的大小.
fileAlignment 是擴展頭中的文件對齊值.
具體屬性後面會詳解.
七丶節數據
咱們的節表存放着節數據的信息.好比節在哪裏開始.數據在哪裏存放. 而咱們的 頭+ 節表 按照文件對齊事後.下面就是節數據了.
例如:
填寫AAAA的地方是對其後沒有使用的.因此咱們若是熟悉PE能夠添加任何成員進去.
八丶PE中的兩種狀態
根據上面簡單了介紹了一下PE的存儲結構.也知道了節數據跟節數據之間.都是根據文件對齊存放的.
可是咱們的PE是能夠運行的.(exe. dll也是.sys也是...這裏指EXE) 因此在內存中狀態也會改變.也就是偏移會改變.
例以下圖:
在文件中咱們的對齊是按照 0x200存放的. 而在內存中就是按照0x1000.假設是1000. 多餘的地方補0
咱們 的DOS頭 + NT頭 + 節表.按照文件對齊以後存放着. 節的數據是從400開始.也就是上圖.
可是在內存中就不同了. 若是按照0x1000對齊.那麼在內存中就是1000位置開始是節數據了.
首先內存中的位置不同
PE中 DOS頭 + NT頭 + 節表. 無論內存中仍是文件中成員都是同樣的.而由於對齊值不一樣.節數據開始位置也不一樣.
由於一個在文件中存放.一個在內存中展開.
好比咱們在文件中 偏移 0x400位置.是節數據.在內存中就不會有了.
以下圖所示:
由於內存是按照0x1000進行對齊的 對齊方式0x1000也會有成員存儲着.下面幾講複習的時候會講到.
因此在內存中1000偏移位置纔是節數據.以下圖
九丶總結PE中的兩種狀態.
PE分爲文件狀態.跟內存狀態.
文件狀態下. 根據擴展頭下面的文件對齊值. 以及記錄對其頭的大小進行存放的.
內存狀態下.根據擴展頭中內存對齊值.以及對其頭大小進行存放的.
好比:
文件對齊值爲0x200 DOS頭 + NT頭 + 節表 = 0x301大小. 可是文件對齊值是200.好比要整除200. 因此 對齊頭打下不是0x301. 而是 0x400. 也就是0x400位置存放的是節數據.
內存同上.只不過對齊值不一樣.