堆和棧的區別 4

2021-05-23 15:53:54 字數 2174 閱讀 3432

;如果是「__cdecl」的話,這裡是「ret」,堆疊將由呼叫者恢復 

;-------------------函式結束------------------------- 

;--------------主程式呼叫func函式的**-------------- 

:00401080 6a03 push 00000003 //壓入引數param3 

:00401082 6a02 push 00000002 //壓入引數param2 

:00401084 6a01 push 00000001 //壓入引數param1 

:00401086 e875ffffff call 00401000 //呼叫func函式 

;如果是「__cdecl」的話,將在這裡恢復堆疊,「add esp, 0000000c」 

聰明的讀者看到這裡,差不多就明白緩衝溢位的原理了。先來看下面的**: 

#include 

#include 

void __stdcall func() 

int main() 

編譯後執行一下回怎麼樣?哈,「"0x00414141"指令引用的"0x00000000"記憶體。該記憶體不能為"read"。」,「非法操作」嘍!"41"就是"a"的16進製制的ascii碼了,那明顯就是strcat這句出的問題了。"lpbuff"的大小只有8位元組,算進結尾的/0,那strcat最多只能寫入7個"a",但程式實際寫入了11個"a"外加1個/0。再來看看上面那幅圖,多出來的4個位元組正好覆蓋了ret的所在的記憶體空間,導致函式返回到乙個錯誤的記憶體位址,執行了錯誤的指令。如果能精心構造這個字串,使它分成三部分,前一部份僅僅是填充的無意義資料以達到溢位的目的,接著是乙個覆蓋ret的資料,緊接著是一段shellcode,那只要著個ret位址能指向這段shellcode的第乙個指令,那函式返回時就能執行shellcode了。但是軟體的不同版本和不同的執行環境都可能影響這段shellcode在記憶體中的位置,那麼要構造這個ret是十分困難的。一般都在ret和shellcode之間填充大量的nop指令,使得exploit有更強的通用性。 

├———————┤<—低端記憶體區域 

│ …… │ 

├———————┤<—由exploit填入資料的開始 

│ │ 

│ buffer │<—填入無用的資料 

│ │ 

├———————┤ 

│ ret │<—指向shellcode,或nop指令的範圍 

├———————┤ 

│ nop │ 

│ …… │<—填入的nop指令,是ret可指向的範圍 

│ nop │ 

├———————┤ 

│ │ 

│ shellcode │ 

│ │ 

├———————┤<—由exploit填入資料的結束 

│ …… │ 

├———————┤<—高階記憶體區域 

windows下的動態資料除了可存放在棧中,還可以存放在堆中。了解c++的朋友都知道,c++可以使用new關鍵字來動態分配記憶體。來看下面的c++**: 

#include 

#include 

#include 

void func() 

void main() 

程式執行結果為: 

0x004107d0 

0x0012ff04 

0x004068c0 

可以發現用new關鍵字分配的記憶體即不在棧中,也不在靜態資料區。vc編譯器是通過windows下的「堆(heap)」來實現new關鍵字的記憶體動態分配。在講「堆」之前,先來了解一下和「堆」有關的幾個api函式: 

heapalloc 在堆中申請記憶體空間 

heapcreate 建立乙個新的堆物件 

heapdestroy 銷毀乙個堆物件 

heapfree 釋放申請的記憶體 

heapwalk 列舉堆物件的所有記憶體塊 

getprocessheap 取得程序的預設堆物件 

getprocessheaps 取得程序所有的堆物件 

localalloc 

globalalloc 

當程序初始化時,系統會自動為程序建立乙個預設堆,這個堆預設所佔記憶體的大小為1m。堆物件由系統進行管理,它在記憶體中以鏈式結構存在。通過下面的**可以通過堆動態申請記憶體空間:

堆和棧區別

一 預備知識 程式的記憶體分配 乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放 存放函式的引數值,區域性變數的值等。其 操作方式類似於資料結構中的棧。2 堆區 heap 一般由程式設計師分配釋放,若程式設計師不釋放,程式結束時可能由os回 收 注意它...

堆和棧區別

管理方式 棧由編譯器自動管理 堆由程式設計師控制,使用方便,但易產生記憶體洩露。生長方向 棧向低位址擴充套件 即 向下生長 是連續的記憶體區域 堆向高位址擴充套件 即 向上生長 是不連續的記憶體區域。這是由於系統用鍊錶來儲存空閒記憶體位址,自然不連續,而鍊錶從低位址向高位址遍歷。空間大小 棧頂位址和...

堆和棧區別

一 預備知識 程式的記憶體分配 乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放 存放函式的引數值,區域性變數的值等。其 操作方式類似於資料結構中的棧。2 堆區 heap 一般由程式設計師分配釋放,若程式設計師不釋放,程式結束時可能由os回 收 注意它...