棧在程式中的應用 棧溢位

2021-10-10 19:05:44 字數 1204 閱讀 5450

我的理解

在程式執行過程中,當要呼叫某個子函式時:

將子函式的相關引數壓入棧中、將call指令的下一條指令的位址作為返回位址壓入棧中、將當前ebp入棧、使ebp指向esp所指的位置(重新定位棧底)、將esp指向的位址+***h(在棧上分配***位元組的空間)(可選)、將某些暫存器中的值入棧(可選)、將某些暫存器中的值出棧(可選)、使esp指向ebp所指向的位置(恢復esp同時**區域性變數的空間)、彈出之前壓入的ebp位址到ebp(恢復ebp)(彈出ebp位址時會使esp+4h指向返回位址即棧頂)、如果有返回值那麼將返回值傳入eax、執行ret指令回到主函式繼續執行指令,子函式呼叫引數並不是用「pop」指令而是引用(如:「mov eax,4(ebp)"),在恢復棧的同時會釋放子函式所相對的棧空間。

i386函式體的開頭一般是這樣的:

push ebp;儲存呼叫前的ebp值

mov ebp,esp;ebp指向棧中儲存呼叫前ebp值的位置

sub esp,***;在棧上分配***位元組的空間,這個是可選的

push ***;儲存***暫存器的值,這個也是可選的

在函式返回時,一般是這樣的:

pop ***;恢復暫存器的值;如果開頭有push ***

mov esp,ebp;恢復esp,同時**區域性變數的空間

pop ebp;恢復呼叫前ebp的值

mov eax,***;如果函式有返回值,那麼返回值一般放在eax中

ret;從棧中取回返回位址,並跳轉到該位置

棧溢位指的是程式向棧中某個變數中寫入的位元組數超過了這個變數本身所申請的位元組數,因而導致與其相鄰的棧中的變數的值被改變。

因為在記憶體中寫入資料是由低位址向高位址寫入而棧是由高位址向低位址生長,所以當向棧中某個變數寫入的位元組數超過這個變數本身所申請的位元組數時會覆蓋該變數後面的資料,當覆蓋的是main函式的ebp時會修改ebp使得棧不平衡、改變了棧底,當覆蓋的是返回位址時會使得程式執行非原指令、可使覆蓋返回位址的資料是攻擊**的位址來獲取shell。

棧的概念以及棧溢位

對每個程式來說,棧能使用的記憶體是有限的,一般是 1m 8m,這在編譯時就已經決定了,程式執行期間不能再改變。如果程式使用的棧記憶體超出最大值,就會發生棧溢位 stack overflow 錯誤。乙個程式可以包含多個執行緒,每個執行緒都有自己的棧,嚴格來說,棧的最大值是針對執行緒來說的,而不是針對程...

在Linux應用程式中列印函式呼叫棧

在linux中列印函式呼叫棧 要求在linux系統的應用程式中寫乙個函式print stackframe 用於獲取當前位置的函式呼叫棧資訊 方法execinfo.h庫下的函式backtrace可以得到當前執行緒的函式呼叫棧指標和呼叫棧深度,backtrace symbols可以將呼叫棧指標轉化為字串...

VC中棧溢位 Stack overflow怎麼辦?

看了以下文章你就清楚該怎麼辦了!1 通過這篇文章我發現在大陣列 二維陣列前加static是解決方法!當然因為不管是靜態全域性變數,還是靜態區域性變數,一旦被建立,都只能在程式結束時被釋放,所以最終的程式還是要用malloc來動態分配堆記憶體!這樣才能使程式節省記憶體!具體的程式見我的博文 當然因於m...