C 語言緩衝區溢出的實戰

該內容源碼參考了 <深刻理解計算機系統>[3.10.3]

學習該章節以前,一直有個疑問,Segmentation fault 這樣的錯誤會具體引起的緣由是啥, 可不能夠從彙編代碼的層面進行一個學習和了解. 全部就有了這篇文章, 純屬我的學習研究.

完整的測試源碼
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*


*/
char* gets(char* s)
{
        int c;
        char *dest  = s;


        // read c char write to dest memory;
        while((c = getchar()) != '\n' && c != EOF)
        {
                *dest++= c;
        }

        if(c == EOF && dest == s)
        {
                return NULL;
        }

        *dest++ ='\0';
        return s;
}


void echo(){
        char buf[8];
        gets(buf);
        puts(buf);
}

int main()
{

        echo();

        return 0;
}

編譯過程,
shell>gcc -g  demo.c -o demo


程序編譯成功後,隨便輸入幾個字符, 能夠正常的回顯, 可是超過某個長度就會出現文章開始的問題, 那麼新的問題來了, 
這個長度是否是就是代碼中定義的buf的長度呢,  會不會有其餘問題發生, 

驗證思路:
1 經過彙編代碼, 查看寄存器地址中的內容, 直接明瞭的去觀察, 那麼就存在一個對比的過程, 
  第一遍的時候是正常的輸入, 不會發生錯誤, 
  第二遍會輸入較長的內容,  對比寄存器中的值.

正常輸入時,
在沒有輸入任何字符的時候, 相關的寄存器的值,
這個是在程序調用getchar() 函數前寄存器的值.

(gdb) i	r ebp
ebp    	       0xbfffea68	0xbfffea68
(gdb) x/16cb 0xbfffea68
0xbfffea68:	120 'x'	-22 '\352'	-1 '\377'	-65 '\277'	100 'd'	-124 '\204'	4 '\004'
8 '\b'
0xbfffea70:	0 '\000'        -106 '\226'	117 'u'	0 '\000'        -112 '\220'	-22 '\352'	-1 '\377
'	-65 '\277'


(gdb) i r esp
esp    	       0xbfffea50	0xbfffea50
(gdb) x/16cb 0xbfffea50
0xbfffea50:	-12 '\364'	-1 '\377'	-118 '\212'	0 '\000'        4 '\004'        -30 '\342'
-118 '\212'	0 '\000'
0xbfffea58:	-120 '\210'	-22 '\352'	-1 '\377'	-65 '\277'	-87 '\251'	-124 '\204'
4 '\004'        8 '\b'

(gdb) i r eax
eax    	       0xbfffea60	0xbfffea60
(gdb) x/16cb 0xbfffea60
0xbfffea60:	37 '%'	-98 '\236'	121 'y'	0 '\000'        28 '\034'	-21 '\353'	-1 '\377'
-65 '\277'
0xbfffea68:	120 'x'	-22 '\352'	-1 '\377'	-65 '\277'	100 'd'	-124 '\204'	4 '\004'
8 '\b'


開始調用getchar() 函數
此時有個隱藏的信息是, gets() 函數中, 參數s的地址是 0xbfffea60, 這個須要知道, 就是這個參數出現了問題,
gdb> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

在輸入完成後, 
再次查看寄存器的內容,

(gdb) x/16cb 0xbfffea68
0xbfffea68:	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'
0xbfffea70:	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'


(gdb) x/32cb 0xbfffea50
0xbfffea50:	96 '`'	-22 '\352'	-1 '\377'	-65 '\277'	4 '\004'        -30 '\342'	-118 '\2
12'	0 '\000'
0xbfffea58:	-120 '\210'	-22 '\352'	-1 '\377'	-65 '\277'	-87 '\251'	-124 '\204'
4 '\004'        8 '\b'
0xbfffea60:	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'
0xbfffea68:	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'



(gdb) x/16cb 0xbfffea60
0xbfffea60:	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'
0xbfffea68:	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'

對比發現 0xbfffea68 地址中的內容被改寫了, 這個地址是程序被調用時的入棧地址, 在gets()函數內部把值改寫了, 
致使程序返回的時候,出現了問題,


若是用戶輸入了緩衝區大小內的內容後, 則器寄存器中的值爲
(gdb) x/16cb 0xbfffea60
0xbfffea60:	97 'a'	97 'a'	97 'a'	97 'a'	97 'a'	0 '\000'        -1 '\377'	-65 '\277'
0xbfffea68:	120 'x'	-22 '\352'	-1 '\377'	-65 '\277'	100 'd'	-124 '\204'	4 '\004'
8 '\b'
能夠發現 0xbfffea68地址中的值和原來的值是一致的, 此時程序退出則是正常的,

具體能夠使用的空間的大小的問題, 何時,會觸發返回地址被改寫.
相關文章
相關標籤/搜索