在執行乙個pe檔案的時候,windows 並不在一開始就將整個檔案讀入記憶體的,二十採用與記憶體對映檔案類似的機制。也就是說,windows 裝載器在裝載的時候僅僅建立好虛擬位址和pe檔案之間的對映關係。
當且僅當真正執行到某個記憶體頁中的指令或者訪問某一頁中的資料時,這個頁面才會被從磁碟提交到物理記憶體,這種機制使檔案裝入的速度和檔案大小沒有太大的關係。
但是要注意的是,系統裝載可執行檔案的方法又不完全等同於記憶體對映檔案。
當使用記憶體對映檔案的時候,系統對「原著」相當忠實,如果將磁碟檔案和記憶體映像比較的話,可以發現不管是資料本身還是資料之間的相對位置它丫丫的都是完全相同的。
而我們知道,在裝載可執行檔案的時候,有些資料在裝入前會被預處理,如重定位等,正因此,裝入以後,資料之間的相對位置可能發生微妙的變化。
windows 裝載器在裝載dos部分、pe檔案頭部分和節表(區塊表)部分是不進行任何特殊處理的,而在裝載節(區塊)的時候則會自動按節(區塊)的屬性做不同的處理。
一般情況下,它會處理以下幾個方面的內容:
記憶體頁的屬性:
對於磁碟對映檔案來說,所有的頁都是按照磁碟對映檔案函式指定的屬性設定的。但是在裝載可執行檔案時,與節對應的記憶體頁屬性要按照節的屬性來設定。所以,在同屬於乙個模組的記憶體頁中,從不同節對映過來的的記憶體頁的屬性是不同的。
節的起始位址在磁碟檔案中是按照 image_optional_header32 結構的 filealignment 欄位的值進行對齊的,而當被載入到記憶體中時是按照同一結構中的 sectionalignment 欄位的值對其的,兩者的值可能不同,所以乙個節被裝入記憶體後相對於檔案頭的偏移和在磁碟檔案中的偏移可能是不同的。
在磁碟中就沒有這個**,因為在磁碟中排放是以什麼為主?肯定是以空間為主導,在磁碟只是存放,不是使用,所以不用設定那麼詳細的屬性。試想想看,如果在磁碟中都是以4kb為大小對齊的話,不夠就用0來填充,那麼乙個只佔20位元組的資料就要消耗4kb的空間來存放,是不是浪費?有木有??
節的尺寸:
對節的尺寸的處理主要分為兩個方面:
第乙個方面,正如剛剛我們所講的,由於磁碟映像和記憶體映像中節對齊儲存單位的不同而導致了長度擴充套件不同(填充的0數量不同嘛~);
第二個方面,是對於包含未初始化資料的節的處理問題。既然是未初始化,那麼沒有必要為其在磁碟中浪費空間資源,但在記憶體中不同,因為程式一執行,之前未初始化的資料便有可能要被賦值初始化,那麼就必須為他們留下空間。
不進行對映的節:
有些節並不需要被對映到記憶體中,例如.reloc節,重定位資料對於檔案的執行**來說是透明的,無作用的,它只是提供windows 裝載器使用,執行**根本不會去訪問到它們,所以沒有必要將他們對映到物理記憶體中。
好了,上邊的一些知識相信又是對我們之前學習的一點補充和擴充套件。大家可能對上邊的知識覺得又是眼熟,但又覺得有幾分陌生。那是當然哈,小甲魚教學遵循的思路就是今天的知識今天學好它,明天的東西明天再學!一下子你肯定不能接受那麼深的東西,像上邊的東西如果放在第一講來講解,那麼恐怕很多朋友不會繼續往下看(一頭霧水看下去只能兩頭霧水,哈~),所以咱學習要遵循迴圈漸進,有些重點分開來重複講解,雖然重複,但每次都會往下加深一點來讓大家容易接受哈。
我們可以繼續了,接下來是節表,也稱為區塊表:
節表(區塊表):
pe檔案中所有節的屬性都被定義在節表中,節表由一系列的image_section_header結構排列而成,每個結構用來描述乙個節,結構的排列順序和它們描述的節在檔案中的排列順序是一致的。全部有效結構的最後以乙個空的image_section_header結構作為結束,所以節表中總的image_section_header結構數量等於節的數量加一。節表總是被存放在緊接在pe檔案頭的地方。
另外,節表中 image_section_header 結構的總數總是由pe檔案頭 image_nt_headers 結構中的 fileheader.numberofsections 欄位來指定的。
typedef struct _image_section_header
byte name[image_sizeof_short_name]; // 節表名稱,如「.text」
//image_sizeof_short_name=8
union
misc;
dword virtualaddress; // 節區的 rva 位址
dword sizeofrawdata; // 在檔案中對齊後的尺寸
dword pointertorawdata; // 在檔案中的偏移量
dword pointertorelocations; // 在obj檔案中使用,重定位的偏移
dword pointertolinenumbers; // 行號表的偏移(供除錯使用地)
word numberofrelocations; // 在obj檔案中使用,重定位項數目
word numberoflinenumbers; // 行號表中行號的數目
dword characteristics; // 節屬性如可讀,可寫,可執行等} image_section_header, *pimage_section_header;
mysql直接記憶體對映檔案 PE檔案到記憶體的對映
在執行乙個pe檔案的時候,windows 並不在一開始就將整個檔案讀入記憶體的,二十採用與記憶體對映檔案類似的機制。也就是說,windows 裝載器在裝載的時候僅僅建立好虛擬位址和pe檔案之間的對映關係。當且僅當真正執行到某個記憶體頁中的指令或者訪問某一頁中的資料時,這個頁面才會被從磁碟提交到物理記...
PE檔案的記憶體對映
如果想要理解pe檔案與虛擬記憶體之間的對映關係,首先要理解一些概念 1.檔案偏移位址 file offset pe檔案資料在硬碟中存放的位址就叫做檔案偏移位址。用winhex程式檢視檔案時的offset就是檔案偏移位址了。檔案偏移位址就是指檔案在磁碟上存放時相對於檔案開頭的偏移。2.裝載基址 ima...
載入PE檔案 記憶體對映檔案
將程式安裝記憶體對齊的方式讀取到記憶體有兩種方法 1 記憶體對映檔案 2 pe載入器模擬法 1 記憶體對映檔案 lpheader所指記憶體是唯讀的,儘管是page readwrite include stdafx.h include include int main int argc,char ar...