天天看點

關于 [棧溢出後jmp esp執行shellcode] 原理分析

    網上關于棧溢出後用jmp esp執行shellcode的文章有很多,感覺分析的都沒有戳到點,是以想結合自己調試的經曆寫下自己的想法。

正常情況下,函數棧分布圖如下:

---->棧記憶體由低向高方向----->
|------------棧變量----------|----ebp----|------傳回位址------|函數形參|      

發生溢出後,以上棧空間的内容被覆寫,可能從上面的布局變成這樣:

---->棧記憶體由低向高方向----->
|------------x90x90x90x90x90|x90x90x90..|shellcode緩存區的位址|x90x90.|      

即,傳回位址被改為一段緩存區的位址。當函數執行結束,從棧中取傳回位址準備執行時,取到的是shellcode的位址,最終跳進shellcode執行。這段shellcode的位址一般被寫死為某個位址,這個位址可以存在于程式空間的任何地方,隻要有執行權限。

就像寫代碼時用絕對路徑讀取配置檔案的内容,偶爾會出錯一樣,為了解決這種錯誤,可能會用相對程式運作時的路徑去擷取配置檔案的内容。寫死shellcode的位址也會出錯,于是先人提出一種相對定位shellcode位址的方法,這就是jmp esp。

這用到了棧指針esp的一個特性:當函數執行ret指令後,Eip寄存器發生了跳轉,但Esp還指向函數形參在棧中的位址。如示意圖:

ret傳回前 esp的位置:

---->棧記憶體由低向高方向----->
|------------棧變量----------|----ebp----|------傳回位址------|函數形參|
                                        ^
                                        |
                                       esp指向這個位置      

ret傳回後 esp的位置

---->棧記憶體由低向高方向----->
|------------棧變量----------|----ebp----|------傳回位址------|函數形參|
                                                            ^
                                                            |
                                                           esp指向這個位置      

繼續閱讀