日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

栈溢出笔记1.1 函数调用过程

發布時間:2025/3/15 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 栈溢出笔记1.1 函数调用过程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

選擇從棧溢出開始學習Shellcode的編寫,是因為在沒有保護機制(棧Cookie,ASLR,DEP,SafeSEH)的系統中使用棧溢出是一件很簡單的事情。棧區隨著函數調用動態變化,每個函數調用時在棧上占用的空間稱為棧幀。用一個示例來說明棧上保存的內容及動態變化的過程。?
下面是一個程序,生成一個對話框顯示一條“Hello World!”消息。下面是該程序的C代碼:?
?
在VS2008中用Debug版編譯之后,拖入Immunity Debugger中:?
?
圖1 example_1.exe入口點

與用匯編直接編寫的程序不同,VS在真正進入main函數之前加入了很多其它的代碼,入口點停在了一條跳轉指令上(如圖1),因此,需要找到真實的main函數。調試別的軟件時由于不知道具體細節,需要跟蹤判斷以及一些特殊方法。但由于是我們自己編寫的程序,就不用了,直接“bp MessageBoxA”在MessageBoxA函數下斷點,然后使用回溯法,即可快速找到main函數。下面是真實的main函數:?
?
圖2 真正的main函數入口

這里可以看到調用MessageBoxA函數。

我們要跟蹤函數MessageBoxA的調用過程,在004113C0的PUSH 0指令處下斷點。Windows API函數的調用方式為stdcall,即參數從右向左入棧,被調用者負責清棧。MessageBoxA函數來自于user32.dll,函數原型如下:

/*********************************************************/ int WINAPI MessageBoxA(_In_opt_ HWND hWnd,_In_opt_ LPCTSTR lpText,_In_opt_ LPCTSTR lpCaption,_In_ UINT uType ); /*********************************************************/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

示例example_1中調用所給的參數如下:

/*********************************************************/ MessageBox( NULL, "HelloWorld", "example_1", MB_OK ); /*********************************************************/
  • 1
  • 2
  • 3

從在004113C0的PUSH 0開始的四條PUSH語句,就是參數的入棧過程。

執行PUSH 0之前,先記一下當前棧的內容:?
?
圖3

下面執行四條PUSH語句,直到CALL處停住,看棧的內容:?
?
圖4

看到參數從右向左都已入棧。?
下面是CALL語句,按F7跟蹤進函數MessageBoxA,注意棧的變化:?
?
圖5?
執行PUSH EBP之前,看當前棧:?
?
圖6?
棧上多了一個值:004113D4,這個值正是CALL MessageBoxA下一條語句的地址(見圖2),這正是CALL指令的作用。將下一條指令(返回地址)入棧,然后跳轉到函數執行。這個地址是棧溢出利用的重點,因為它在函數返回的時刻將被放入EIP,作為指令地址。

下面接著執行MessageBoxA函數中的下一條指令PUSH EBP。下面兩條指令:

/*********************************************************/ PUSH EBP MOV EBP, ESP /*********************************************************/
  • 1
  • 2
  • 3
  • 4

標志著函數棧幀的建立,也就是說,函數現在開始接手棧,它開始圈出自己的一塊地(開辟新的棧基址EBP和棧范圍ESP),使用這一塊地來保存自己的局部變量,保存自己的信息。函數RET 之前還有POP EBP,表示函數自己的棧幀使用完了,可以清理掉了。因此,在調用函數的過程中,棧內容分布如下:?
?
圖7

函數返回的過程不再跟蹤。下面看圖7,開始說棧溢出的內容。

前面說到函數在棧上開辟自己的棧幀,用來保存自己的變量,正常情況下,函數應該使用它自己圈出來的地(棧幀),而不應該越界,因為一旦它越界,就會破壞調用者保存在棧上的內容(返回地址,參數,以及調用者的局部變量等)。調用者所保存的這些內容中有一個最重要的內容:返回地址,因為它控制著程序的流程,一旦它被破壞,程序就不再受調用者控制(再也回不到調用者指令流程中了)。因此,一旦有棧溢出漏洞,黑客們就可能利用它來控制程序流程,做壞事。

總結

以上是生活随笔為你收集整理的栈溢出笔记1.1 函数调用过程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。