看下面**:
#include int cp (char *p)
int main()
else
}return 0;
}
在vs2008下面建個工程,我輸入「1234567」的時候輸出是「congralations」,程式是正確的,但是當我輸入是「12345678」的時候,崩潰了,於是我把gs關了,結果輸出竟然也是「congralations」。我開始的時候很奇怪,於是我再試了下還是輸出「congralations」。於是用od除錯了下····
這個是子函式cp ()裡面的反彙編,程式停在了strcpy之後,這時候eax(函式執行完的返回值)是0,下面的圖是堆疊的情況,字元1對應的16進製制是31,由於我是intel的cpu,所以是小端模式(高位元組存在地位,低位元組存在高位),[ebp-12]到[ebp-4]是陣列b[8]的記憶體位址,從低到高依次存放了「1234567」和』\0′,而[ebp-4]存的是a的值,作為返回值,如果是0那麼就代表密碼輸入正確,否則就失敗。輸入是「1234567」的情況下,結果子函式返回的是0,輸出結果也是正確的。
這下就奇怪了,我們看暫存器eax的值,竟然也是0!真是奇怪了,「12345678」明明比「1234567」大啊,strcmp返回的結果肯定是要比0大的額,再看看[ebp-4]的值也是0額(是它賦值給eax的),這就意味著返回值a是0啊,按照正常結果返回值應該是大於0的數啊,奇怪了!我們再看看堆疊情況(下圖),[ebp-12]到[ebp-4]是陣列b[8]的記憶體位址,從低到高依次存放了「12345678」,那麼『\0』呢?這裡已經是棧溢位了,b[8]只有八個位元組,只能訪問7個字元+』\0′,現在訪問了八個位元組+』\0′,肯定溢位了。cpu訪問的時候是從低位址到高位址的,也就是說[ebp-4]這個位元組裡面存的應該是』\0′,但是[ebp-4]本來存的是strcmp的返回值啊,原本是大於0 的數,這下
被strcpy執行的時候的』\0′覆蓋了
,所以[ebp-4]這個位元組就變成了0。自然程式輸出就有問題了。
按照上面的推論,輸入」123456789″的時候,在子函式裡,[ebp-12]到[ebp-4]是陣列b[8]的記憶體位址,從低到高依次存放了「12345678」,而[ebp-4]位元組裡面存的應該是』9′的十六進製制39,[ebp-3]訪問的是』\0′的十六進製制0,再後面兩個位元組也是0。那麼cpu讀取的時候從高到底低讀取,讀出來的結果就是00000039,也就是39,那麼返回值也就是39。下面實際的結果:
呵呵,果然如此!這下就搞明白了~~~
上面的程式也只是乙個例子來演示棧溢位的結果,實際上,在溢位的時候甚至可以覆蓋你的eip,然後馬上hook到自己的惡意程式,所以一定要小心棧溢位!
博主新位址www.firefoxbug.net
乙個小程式的棧溢位
看下面 include int cp char p int main else return 0 在vs2008下面建個工程,我輸入 1234567 的時候輸出是 congralations 程式是正確的,但是當我輸入是 12345678 的時候,崩潰了,於是我把gs關了,結果輸出竟然也是 cong...
乙個棧溢位的BUG
const unsigned len 10 1u 20 char data len data 0 a return 0 讀取資源限制 soft limit hard limit 是由系統呼叫getrlimit完成的,getrlimit在核心中的入口是sys getrlimit,如下 asmlinka...
乙個簡單的溢位程式解析
下面是一段包含緩衝區溢位的 include using namespace std void attacker cout attacker is running.該程式的執行結果如下 可以看到,主函式中並沒有呼叫attacker這個函式,但是在執行時卻看到了attacker這個函式在執行,這就是我通...