2012-08-06 129 views
3

最近我一直在尋找Window的PE格式,我注意到在大多數例子中, 人傾向於將optional header中的ImageBase偏移值設置爲不合理的高度,如0x400000未映射位於偏移量0的Win32便攜式可執行映像的可能原因是什麼?

什麼可以使它不利不是來映射一個圖像在偏移0x0

+0

提示:x86上的單個PTE條目映射的地址空間量是多少? – 2012-08-06 19:17:56

+0

@RaymondChen 2(技術上4)GB,其中0x400000是1/512。這是如何回答這個問題的? – Kierrow 2012-08-06 19:23:03

+1

一個PDE條目(對不起,我的意思是PDE不是PTE)條目映射0x400000字節(4MB)。 Hans Passant的答案填補了其餘部分。 – 2012-08-06 20:51:01

回答

3

首先,這不是Windows或PE文件格式的默認,它是爲連接器的/ BASE選項的默認,當你用它來鏈接一個EXE。 DLL的默認值是0x10000000。

選擇/ BASE:0將是不錯的選擇,任何程序都在該基地的地址永遠運行。地址空間的前64 KB是保留的,不能映射。主要是爲了捕獲空指針解引用錯誤。並擴展到64KB,以捕捉以16位開始生命並重新編譯爲32位的程序中的指針錯誤。

爲什麼0x40000而不是0x10000默認是歷史事故,至少返回到Windows 95.其中保留了「16位/ MS-DOS兼容性競技場」的前4兆地址空間, 。我不太記得它,Windows 9x在NT上有一個非常不同的16位VM實現。您可以在這個古老的KB article中閱讀更多關於它的內容。這些日子肯定不再相關,64位操作系統將在0x010000和0x400000之間的空間中輕鬆分配堆內存。

更改EXE的/ BASE選項沒有任何意義。但是,有很多點更改它爲DLL。如果它們不重疊並因此不必重新定位,它們將更有效,它們不會在分頁文件中佔用任何空間並可在進程之間共享。 rebase.exe

1

如果將它映射到地址0,那麼這意味着代碼將從地址零開始運行。

對於OS,地址零是NULL,這是一個無效地址。
(不是「根本」,但對於現代的操作系統,它是。)

另外,一般你不想在內存的低16 MIB(甚至虛擬的)東西,出於多種原因。

但是有什麼選擇?它必須映射某處,所以他們選擇0x400000 ...沒有特別的理由,特別是地址,可能。這可能只是方便。

1

微軟選擇了地址通過該PE文件將被內存映射鏈接指定的默認起始地址。鏈接器假定這個地址,並且可以用這個假設優化可執行文件。當文件在內存映射到該地址時,代碼可以運行而不需要修改任何內部偏移量。

如果由於某種原因該文件不能被加載到該位置(另一個EXE/DLL已經加載在那裏)遷移需要將之前的可執行程序可以運行,這將增加加載時間發生。

更低的內存地址通常認爲含有低級別的系統程序和一般單獨留在家中。 ImageBase地址唯一真正的要求是它是0x10000的倍數。

推薦閱讀:

2

實際上,設置/ BASE爲0的影響取決於您的映像的Address Space Layout Randomization (ASLR)設置(鏈接器也提供此設置 - /DYNAMICBASE:NO )。

如果你的圖像有/ BASE:0並且ASLR打開(/ DYNAMICBASE:YES),那麼你的圖像將會啓動並運行,因爲加載器會自動將它加載到「有效」地址。

如果你的圖像的BASE:0和ASLR關閉(/ DYNAMICBASE:NO),那麼你的圖像將不會啓動,因爲加載器不會將其加載到期望的基地址(也就是,如上所述,無效/保留的)。

相關問題