Linux堆疊溢位的經典問題

2021-06-09 22:59:04 字數 2445 閱讀 8905

看了一下,linux一站式學習的函式呼叫 ,搞的我熱血沸騰,立馬找你一下這方面的資料看看。終於看到了乙個有關linux堆疊溢位的文章,就拿來試試手了。參考

我的學習linux筆記(一)堆疊

下面來貼一下我的**吧。基本和上篇文章一樣的。

[c-sharp]view plain

copy

#include

void

attack()  

void

yaya()  

void

foo()  

void

main()   

btw,說明一下,我的平台是redhat 9,2.4的核。

直接上圖吧:

先來看一下各個函式的反彙編:

main函式的:

yaya函式的:

attack函式的:

foo函式的哦:

好了,下面一一細說了:

函式main:*(& a_main -1)=(int)yaya;這條語句非常關鍵,因為

(& a_main -1)位址換成了yaya函式的入口位址,那麼

(& a_main -1)原來的是什麼呢?

請看圖:

我們知道,gcc指標都是4位元組對齊的,那麼

(& a_main -1)就是位址0xbfffe2d0,裡面什麼也沒有。只是gcc為了16位元組對齊原則而空著的。具體可見:x86組合語言學習手記

順便說一下,

在執行程式時,作業系統為程序分配一塊棧空間來儲存函式棧幀,在每個函式的棧幀中,ebp指向棧底,而esp指向棧頂,在x86平台上這個棧是從高位址向低位址增長的,我們知道每次呼叫乙個函式都要分配乙個棧幀來儲存引數和區域性變數。(

linux一站式學習的函式呼叫)

下面執行foo函式。

foo函式

關鍵在*(& c_foo +2)=(int)attack;

它的意思就是

本來0xbfffe2cc存放的是main返回的位址0x0804839f,但是改為attack函式的入口位址0x08048328。

這樣就會導致main函式返回時,跑到attack函式繼續執行。

好了,foo函式執行完了,esp依次出棧,就到了

attack函式的入口位址0x08048328。

就attack函式執行完畢以後,此時的esp就為

位址0xbfffe2d0,回想一下,這

位址0xbfffe2d0裡面是什麼?

對了,就是yaya函式的入口位址。

那麼接下來,就是執行yaya函式了。

那麼yaya函式執行完以後,接下來,該怎麼辦麼?

由於main函式丟失了返回位址,導致main函式無法返回,gcc就出現段錯誤!

總結:

1 從上面乙個小小的例子,就可以看到,linux堆疊的分配情況,由於可以看出,如果對記憶體指標進行不小心操作,很可能會導致程式崩潰,甚至會導致溢位攻擊。

2 至於0xbfffe2d0為什麼會是空的,esp為什麼要減0x8,那是因為:

至於為什麼會相差

4位元組,那是因為對於使用者程式的入口函式,即:

main()

,gcc 

一般作16 bytes 

對齊。其它函式,不作

16 bytes 

對齊。3 最後參考的文獻,在什麼都有鏈結,下面就不一一枚舉了。

最後上個堆疊效果圖吧:

4 最後有人要問了,這樣的main函式無法正常返回,那麼如何修改使得main函式可以正常返回呢?

其實很簡單,就是在esp指標處指向main函式返回的位址,就ok了。

具體,參見上面的堆疊示意圖,可以把儲存a_main的位址修改為main函式返回的位址。

**見下:

[c-sharp]view plain

copy

void

foo()  

這樣不會返回段錯誤了,函式也都執行了。

ARM 堆疊溢位問題

今天一大早就有個師弟在qq上問了我乙個問題,先把 貼出來.softwareinterrupt stmfd sp mov r1,sp mrs r3,spsr tst r3,t bit thumb mode ldrneh r0,lr,2 yes,fetch swi no.in thumb mode bi...

c語言之堆疊溢位問題

對於c來說,函式呼叫,系統要做三個工作 這裡多提一下,關於陣列作為形參呼叫函式時,為什麼需要連同陣列長度一起傳進來?這裡是因為,陣列作為引數傳遞的本質只是乙個指標,也就是乙個位址,編譯器並不關心這個位址後邊有多少有用資料,編譯器只看得到指標所指的資料。所以在被呼叫函式中,無法直接知道這個陣列的長度,...

完成埠 堆疊溢位 Zephyr使用的堆疊保護技術

zephyr使用k thread stack define建立的執行緒堆疊,所有的執行緒堆疊會在記憶體中依次放在noinit段內。如下圖所示 zephyr建立了a e五個執行緒相鄰而放,在乙個執行緒堆疊內函式呼叫會占用堆疊,諸如區域性變數,傳遞引數等會放到堆疊內,上圖函式呼叫關係是fun1呼叫fun...