欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

緩沖區(qū)溢出解密一

互聯(lián)網(wǎng)   發(fā)布時間:2008-10-08 19:04:09   作者:佚名   我要評論
緩沖溢出弱點誕生于70年代。Morris Worm(80年代)可以認為是它們的第一次公開應(yīng)用。從90年代開始,相關(guān)的文檔,如著名的Aleph1的”Smashing the Stack for Fun and Profit”和代碼已經(jīng)在互聯(lián)網(wǎng)上公開。 這篇文章是關(guān)于某種需要非常重視的主題的系列文

好了,我們說將被放到EIP中的值是CPU自身計算出來的。如果我們JMP到一個函數(shù)又是什么樣子的呢?函數(shù)中指令的地址將在內(nèi)存中的其它地方。它們執(zhí)行后,CPU是如何知道到哪里繼續(xù)調(diào)用程序執(zhí)行呢?為了這個目的,在我們JMP到函數(shù)前,我們在一個臨時寄存器中保存下一個指令地址,比如說在EDX中;并且在從函數(shù)返回之前,我們又把EDX中的地址寫回EIP。如果我們使用JMP來跳轉(zhuǎn)到函數(shù)地址,那將可能實際上是一個非常煩人的工作。
然而,ix86處理器家族給我們提供了兩個指令:CALL和RET,使我們的生活簡單!CALL指令把”函數(shù)返回后下個要被執(zhí)行的指令”寫入堆棧。它PUSH地址到堆棧,并且把函數(shù)地址寫入EIP。因而,一個函數(shù)調(diào)用就產(chǎn)生了。另一方面,RET指令從堆棧中POP出”返回地址”,并且把地址寫入EIP。因而,我們將從函數(shù)安全地返回,而且繼續(xù)了程序的下一步執(zhí)行。
讓我們看看下面的代碼片段:
x = 0;
function(1, 2, 3);
x = 1;
在幾個匯編指令運行(x=0)之后,我們需要到function()所在的內(nèi)存位置。就如我前面所說的,為了實現(xiàn)這一目標,首先我們拷貝返回地址的地址(在這個例子里是x=1的指令地址。)到一些臨時空間(可能是一個寄存器)用JMP跳轉(zhuǎn)到函數(shù)的地址空間,而且,在函數(shù)結(jié)束時我們恢復我們將要拷貝到EIP的返回地址。
感謝上帝,所有這些麻煩的操作都由CPU自身通過CALL和RET為我們做了,而你能從上面的篇章中得到相關(guān)細節(jié)。 一般地,程序堆棧區(qū)域能夠象這樣表示:
|_parameter_I____| ESP 8
|_parameter II___| ESP 4
|_return address_| ESP
Figure X : Stack
ESP,EBP
如我們已經(jīng)說過的,堆棧同樣被用來存儲動態(tài)變量。動態(tài)地,程序請求新的空間時,CPU PUSH一些數(shù)據(jù)而我們的程序釋放一些數(shù)據(jù)時它就POP一些數(shù)據(jù)。為了給內(nèi)存編址,我們使用”相對尋址”。也就是說,我們在我們的堆棧中給數(shù)據(jù)編址,與一些標準相關(guān)。而這個標準就是ESP,它是Extended Stack Pointer首字母縮寫。這個寄存器指向堆棧的頂端??紤]這個:
void f()
{
int a;
}
可以看出,在f()函數(shù)中,我們?yōu)橐粋€名為a的整型變量分配空間。整型變量a的空間將在堆棧中分配。而計算機將引用它的地址作為ESP- 的一些字節(jié)。因此堆棧指針對程序執(zhí)行是非常重要的。若我們調(diào)用一個函數(shù)呢?這個調(diào)用的函數(shù)有一個堆棧,它有一些局部變量,意味著它將要利用堆棧指針寄存器。同樣地,內(nèi)部被調(diào)用的函數(shù)將有局部變量而且它也將需要堆棧指針。
為了克服這個,我們保存老的堆棧指針。就象我們對返回地址所做的那樣,我們PUSH老的ESP到堆棧,并且利用另外一個名為EBP的寄存器來引用被調(diào)用函數(shù)的局部變量。

相關(guān)文章

最新評論