2016-07-24 38 views
1

ELF可執行文件具有固定的加載地址(32位x86 Linux二進制文件爲0x804800,64位x86_64二進制文件爲0x40000)。爲什麼ELF可執行文件具有固定的加載地址?

我讀了關於這些特定地址的歷史原因的SO答案(例如,this one)。我仍然不明白的是爲什麼要使用固定的加載地址,而不是隨機化的地址(給定一些範圍需要隨機化)?

+1

我不太瞭解ELF,但通常它至少有一次加載的機會而不需要重新定位。 –

回答

2

爲什麼要使用傳統認爲現在是可執行的工作固定負載地址,而不是隨機一個

  1. 。如果你想要一個隨機加載地址,用-fPIE-pie標誌建立一個PIE二進制文件(這實際上是一個共享庫的特例,其中包含啓動代碼)。
  2. 使用-fPIE構建時會引入運行時間開銷,在某些情況下,性能降低可能會達到10%,如果您擁有大型集羣或者需要性能的每一位,則這可能無法容忍。
+1

您可以詳細闡述運行時間開銷或提供一些鏈接嗎? –

4

ELF是UNIX派生操作系統使用的文件格式,包括POSIX(IOS)和POSIX(IOS)等文件格式,不知道我是否理解你的問題是正確的,類Unix(Linux)。

和elf格式只是聲明,必須有一些解析和絕對的虛擬地址,該代碼被加載到並開始運行,從... ,只是這就是文件格式是如何,以及由於歷史原因,不能被改變......你不能只是將可執行文件「拋出」到任何內存地址,並在90年代ELF格式引入時成功運行,例如調用帶虛擬表的函數決定小精靈格式將有絕對地址。

而且仔細想想,看看ELF格式 - https://en.wikipedia.org/wiki/Executable_and_Linkable_Format 你會如何設計一個OS可執行文件加載器將能夠處理可執行加載到任何所需的虛擬地址,並已成功運行的代碼,而不實際上不得不改變二進制本身...如果你想要做這樣的事情,你需要大大地改變輸出編譯器生成或格式本身,這又不是可能的

隨着時間的流逝,位置獨立執行(PIE/PIC)的要求已經提出並共享了我們引入的對象,以便允許和ASLR(地址空間佈局隨機化) - 這意味着可以拋出代碼在任何內存地址中,仍然能夠執行,只需確保代碼本身內的所有調用都與執行的指令的當前地址相關,並且在共享對象加載時,OS加載器必須如果數據改變不是可執行指令(RE),而是實際數據(RW,例如.data段),則通過調用某些「跳轉表」中的函數來實現二進制中的某些數據(這些數據將在加載時更改時間),例如PLT/GOT ....這些共享對象允許代碼加載到的地址的絕對隨機化,如果您想要執行一些更「安全」的代碼,則必須將其編譯爲共享對象,動態鏈接它和加載時間或運行時間..

(希望我已經清除了一些東西:))

相關問題