2013-10-18 14 views
1

我可以將elf中的默認虛擬地址(ph_vaddr)更改爲0x0。這將允許訪問空指針?或者內核不允許在地址0加載?是否將elf標頭中的默認虛擬地址更改爲0?

我只想知道,如果我將某些節的p_vaddr改爲.text爲0x0,linux是否允許這樣做?虛擬地址只能在某個值後才能啓動嗎?每當我嘗試設置.text vaddr使用ld --section-start 0到9999之間的任何地方時,它都會被殺死。我想知道發生了什麼?

+0

請解釋** ! –

+0

我正在閱讀精靈格式,然後我開始玩p_vaddr以更好地理解它。此時我迷路了,所以我來到了這裏。 – mohit

回答

2

我可以將elf中的默認虛擬地址(ph_vaddr)更改爲0x0。

是的,實際上,PIE(位置無關)可執行文件通常是如何鏈接的。

echo "int main() { return 0; }" | gcc -xc - -fPIE -pie -o a.out 
readelf -l a.out | grep LOAD | head -1 

LOAD   0x0000000000000000 0x0000000000000000 0x0000000000000000 

注:上面使得可執行即ET_DYN類型。

這將允許訪問空指針嗎?

號當內核發現該.e_type == ET_DYN的可執行文件,它會重新定位其所有段的其他地方。

您也可以ET_EXEC類型的可執行文件.p_vaddr == 0,就像這樣:

echo "int main() { return 0; }" | gcc -xc - -o a.out -Wl,-Ttext=0 
readelf -l a.out | grep LOAD | head -1 
    LOAD   0x0000000000200000 0x0000000000000000 0x0000000000000000 

內核會拒絕運行它:你爲什麼要問

./a.out 
Killed 
+0

謝謝。這回答了這個問題。 – mohit

+0

@EmployedRussian:「否。當內核發現可執行文件的第一個加載段的.p_vaddr == 0時,它會將其重定位到其他位置。」可以? AFAIK,它在ELF文件的類型是'ET_DYN'時重新定位(至少這是ELF規範中的預期)。 – ysdx

+0

@ysdx我們正在討論的'PIE'二進制*是*'ET_DYN',正如答案中已經討論的那樣。 –

0

您可能mmap(2)MAP_FIXED段起始於(void*)0但我認爲你不應該。

我不知道如果更改elf(5)中的虛擬地址將做相應的操作。您是否在談到p_vaddr的某些細分市場?

實際上,在Linux的應用程序代碼中,實際上不應該使用NULL地址,尤其是如果某些代碼使用C語言編寫的,因爲NULL指針具有非常特殊的含義,包括編譯器。特別是,根據NULL不可忽略的事實完成一些優化。

衆所周知的是GCC不優化,例如,

x = *p; 
if (!p) goto wasnull; 

逼到x= *p;,因爲如果p已取消引用它不能NULL; GCC正在對應用程序代碼進行優化(不適用於獨立應用程序)。

另外內核通常在做Address Space Layout Randomization

+0

我編輯了這個問題的更多細節。 – mohit