2014-02-23 42 views
3

看一看這個主:ASD在ASLR和地址

int 
main() 
{ 
    int asd = 10; 
    printf("%p\n", &asd); 
    return 0; 
} 

地址在給定時刻:

0x7ffff5f7c16c 

的主要地址(總是相同):

(gdb) disass main 
Dump of assembler code for function main: 
    0x00000000004005b4 <+0>: push %rbp 

爲什麼常規c程序的變量地址在每次執行時都會改變,而程序本身的起始地址總是s ame(假設它不是位置獨立的)? 我看到地址變化是由ASLR模式引起的,但它爲什麼隻影響程序變量,並不影響代碼的分配位置?這是否與作爲代碼部分ro的事實有關,如果不是絕對必要的,它是沒有意義的隨機化的?

此外,爲什麼會出現主的tarting地址和可變ASD的地址之間的巨大差距?

+0

的[它是如何,主要功能是始終在同一地址加載,而變量具有不同的地址大部分時間?(http://stackoverflow.com/questions/3699845/how-is-it-可能重複主要功能是永遠加載在同一地址,而變異) –

+0

問題是一樣的,但我所尋找的是稍有不同。我想知道爲什麼文本部分和堆棧之間存在這種差異,可能是什麼原因(如果有的話),而不是爲什麼會發生。 – badnack

回答

4

ASLR大多在mmap(2)時有發生。主線程的堆棧段分配在execve(2)時間(您的程序) - 但可能是「隨機」定位的。您的main的初始堆棧指針還取決於各種因素(特別是您的環境 - 請參閱environ(7))。

堆棧指針設置爲execve時間。它通過例如定義的約定傳遞給crt0.o啓動對象文件(其調用main)。 x86-64 ABI規格。

main的地址是固定的ELF可執行文件內。除非你的代碼是position independent code(即用-fPIE-fPIC等編譯),它不能被移動(因爲那需要特定的relocation)。在您的badnack可執行文件上使用objdump -f badnack來查明。你的程序也是pmap。而PIC有一個小的成本(它使用更多的寄存器)。

+0

我明白了,但假設程序不是位置獨立的,爲什麼堆棧可能是隨機分配的,而main不是? – badnack

+0

因爲移動'main'需要重定位代碼。 –

+0

爲什麼堆棧被移動呢? – badnack