C語言棧與調用慣例


1、前言

  最近在再看《程序員的自我修養》這本書,對程序的鏈接、裝載與庫有了更深入的認識。關於這本書的評價可以去豆瓣看看http://book.douban.com/subject/3652388/,強烈推薦給每一位程序員哈。今天看了第十章內存,主要講的是棧和堆的管理。主要問題是:函數在棧中是如何布局的,如何通過緩沖區溢出來調用另外一個函數,即堆棧溢出攻擊。

2、基本概念

  棧(stack):我第一次接觸棧是從數據結構中,此時的棧是一種基本數據結構,棧的基本屬性是先進后出(FILO)。

  在計算機系統中,棧是一個具有先進后出屬性的動態內存區域。程序可以將數據壓入棧,也可以將數據從棧頂彈出。棧的增長方向是向下增長,即由高地址向低地址方向。在i386下,esp寄存器定位棧頂,ebp寄存器定位棧底(棧指針)。esp始終指向棧頂,隨着函數的執行,esp不斷的變化,而ebp固定在棧底位置不變。

3、棧的作用

  用於維護函數調用的上下文,離開了棧函數調用沒法實現。棧中保存了一個函數調用所需要的維護信息,通常稱為堆棧幀或活動記錄。

  堆棧棧包括的內容:

  (1)函數的返回地址和參數

  (2)臨時變量

  (3)保存的上下文,例如函數調用前后保持不變的寄存器。

4、函數調用過程

  (1)把所有的參數壓入棧

  (2)把當前指令的下一條指令的地址壓入棧中(函數的返回地址)[可以實現堆棧溢出攻擊]

  (3)跳轉到函數體執行

   其中(2)(3)由指令call一起執行的。

例如下圖所示的程序:

匯編代碼如下圖所示:

5、堆棧溢出攻擊

  通過堆棧溢出改變函數的返回地址,調用另外一個過程。例如下面的程序:

匯編程序如下所示:

程序輸出結果如下所示:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM