函式的呼叫過程:如果 a() 呼叫 b(),a() 先將 b() 的引數逆序壓棧,然後將呼叫完 b() 後的下一條指令的位址 eip 壓棧。進入 b() 後,b() 先將 a() 的棧底 ebp 壓棧,然後建立自己的棧。b() 結束後,可將 a() 的 ebp 彈出,恢復 a() 的棧底,然後彈出 a() 的下一條指令位址 eip,a() 得以繼續執行。
ollydbg 用法:
比賽中不會給出原始碼:
#include#includeint stack_over_flow()
; gets(password);
return 0;
}void readfile()
; printf("you've got the flag:\n");
if (fp = fopen("flag.txt", "r"))
else
printf("file error!\n");
exit(0);
}int main()
先用 ida 按 f5 檢視反編譯。
用 ollydbg 開啟編譯後的 c.exe:
f7 進入 call c.00401014
f8 繼續
進入到 main() ,入口位址是 0x00401180
f8 一直到達 call c.0x0040100a 行後,f7 進入
雙擊 jmp c.readfile,檢視 readfile() 的入口位址為:0x004010a0
繼續 f8
進入到 stack_over_flow() ,入口位址是 0x00401040
f8 到 call c.gets,輸入 8 個 『a』(16 進製為 0x41),棧為:
20 個位元組中:
以下 16 位元組為棧空間:
41414141
41414141
00000000
00000000
0019ff40 為之前儲存的 ebp
004011b7 為函式的返回位址
可以輸入 20 個 a,然後用 readfile() 的入口位址覆蓋返回位址 004011b7,這樣當程式返回時就從棧中取出 readfile() 的入口位址作為 eip 暫存器的內容,於是程式跳到了 eip 處,讀取檔案顯示 flag。
找到 readfile() ,其入口位址,是 0x004010a0
可借助 python 輸出重定向輸入一些不能從鍵盤列印出的字元:
由於沒有寫 flag.txt,所以會出現 file error!
參考天樞 ctf-pwn 入門指導與學習路線
**函式呼叫棧
棧溢位和棧記憶體溢位
棧記憶體溢位是指使用者棧的大小最多為8 10mb,分配超過棧大小的變數則會導致棧記憶體溢位。如char c 1024102411 11mb 棧溢位指的是程式向棧中某個變數中寫入的位元組數超過了這個變數本身所申請的位元組數,因而導致與其相鄰的棧中的變數的值被改變。如char c 10 memset c...
棧溢位,記憶體溢位
對於一台伺服器而言,每乙個使用者請求,都會產生乙個執行緒來處理這個請求,每乙個執行緒對應著乙個棧,棧會分配記憶體,此時如果請求過多,這時候記憶體不夠了,就會發生棧記憶體溢位。棧溢位是指不斷的呼叫方法,不斷的壓棧,最終超出了棧允許的棧深度,就會發生棧溢位,比如遞迴操作沒有終止,死迴圈。可以把記憶體比作...
棧溢位攻擊c語言 棧溢位攻擊
我們先來看下面的乙個例子 include int main gets str printf str s n str return 0 在 main 函式內部定義乙個字元陣列,並通過 gets 為它賦值。在vs2010 debug模式下執行程式,當輸入的字元不超過10個時,可以正確輸出,但是當輸入的字...