GCC中的pie和fpie選項

2021-05-21 22:53:44 字數 2359 閱讀 2054

gcc中的pie和fpie選項

position-independent-executable是binutils,glibc和gcc的乙個功能,能用來建立介於共享庫和通常可執行**之間的**–能像共享庫一樣可重分配位址的程式,這種程式必須連線到scrt1.o。標準的可執行程式需要固定的位址,並且只有被裝載到這個位址時,程式才能正確執行。pie能使程式像共享庫一樣在主存任何位置裝載,這需要將程式編譯成位置無關,並鏈結為elf共享物件。

引入pie的原因是讓程式能裝載在隨機的位址,通常情況下,核心都在固定的位址執行,如果能改用位置無關,那攻擊者就很難借助系統中的可執行碼實施攻擊了。類似緩衝區溢位之類的攻擊將無法實施。而且這種安全提公升的代價很小

談到pie就不得不說說pax和grsec核心。這兩個東西都是為了構建堅不可摧到安全系統而準備的。pax是linux核心安全增強補丁,它能在兩方面保證安全性,一是aslr(address space layout randomization,位址空間分布隨機化),這是一種將所有資料裝載到記憶體時都隨機化位址的方式,當使用pie選項編譯應用時,pax能將應用的位址做隨機加法;二是能提供不可執行的記憶體空間,這樣就能使得攻擊者放入記憶體中的惡意**不可執行。不過pax官網上能支援的最新核心是2.6.27,已經是一年前的更新了。grsec也時類似的核心補丁,更新較為頻繁能支援最新的2.6.32核心。這兩種方式都能將核心完全位置無關,除了grub和glibc中無法位置無關的彙編碼。

pie最早由redhat的人實現,他在連線起上增加了-pie選項,這樣使用-fpie編譯的物件就能通過聯結器得到位置無關可執行程式。fpie和fpic有些不同。可以參考gcc和open64中的-fpic選項

.gcc中的-fpic選項,使用於在目標機支援時,編譯共享庫時使用。編譯出的**將通過全域性偏移表(global offset table)中的常數字址訪存,動態裝載器將在程式開始執行時解析got表項(注意,動態裝載器作業系統的一部分,聯結器是gcc的一部分).而gcc中的-fpic選項則是針對某些特殊機型做了特殊處理,比如適合動態鏈結並能避免超出got大小限制之類的錯誤。而open64僅僅支援不會導致got表溢位的pic編譯。

gcc中的-fpie和-fpie選項和fpic及fpic很相似,但不同的是,除了生成為位置無關**外,還能假定**是屬於本程式。通常這些選項會和gcc鏈結時的-pie選項一起使用。fpie選項僅能在編譯可執行碼時用,不能用於編譯庫。所以,如果想要pie的程式,需要你除了在gcc增加-fpie選項外,還需要在ld時增加-pie選項才能產生這種**。即gcc -fpie -pie來編譯程式。單獨使用哪乙個都無法達到效果。

你可以使用file命令來檢視當前的可執行檔案是不是pie的。

下面是本博編譯helloword的顯示。可以看出,可執行檔案屬性從executable變成了shared object.

$ gcc  helloworld.c

$ file a.out

a.out: elf 32-bit lsb executable, intel 80386, version 1 (sysv), dynamically linked (uses shared libs), for gnu/linux 2.6.9, not stripped

$ gcc -fpie -pie helloworld.c

$ file a.out

a.out: elf 32-bit lsb shared object, intel 80386, version 1 (sysv), dynamically linked (uses shared libs), for gnu/linux 2.6.9, not stripped

接下來,我們就能實驗了,使用strace命令來檢視這兩個a.out執**況了。關於strace命令,可以參考strace命令介紹

在博主電腦上,有pie時,執行第乙個brk(0)系統呼叫時,返回的位址一直是變化的。而無pie時,brk(o)系統呼叫返回位址一直不變。內容太多,不再貼出。

參考:http://gcc.gnu.org/onlinedocs/gcc/code-gen-options.html

gcc中的 w W和 Wall選項

今天在看乙個makefile時看到了gcc w wall.這句,不明其理,專門檢視了gcc的使用手冊。w的意思是關閉編譯時的警告,也就是編譯後不顯示任何warning,因為有時在編譯之後編譯器會顯示一些例如資料轉換之類的警告,這些警告是我們平時可以忽略的。wall選項意思是編譯後顯示所有警告。w選項...

gcc中的 w W和 Wall選項

今天在看乙個makefile時看到了gcc w wall.這句,不明其理,專門檢視了gcc的使用手冊。w的意思是關閉編譯時的警告,也就是編譯後不顯示任何warning,因為有時在編譯之後編譯器會顯示一些例如資料轉換之類的警告,這些警告是我們平時可以忽略的。wall選項意思是編譯後顯示所有警告。w選項...

gcc中的 D選項

有時候我們想在 c 原始檔中使用 makefile 中定義的某些變數,根據變數的取值做出不同的處理,比如 debug 開關 版本資訊等,這時候我們可以通過 gcc 的 d 選項來滿足這一需求,它等同於在 c 檔案中通過 define 語句定義乙個巨集。比如,我們可以在 makefile 中定義以下變...