最常見的兩種exploit是:緩沖區溢出,格式化字元串
CPU(Intel,x86)各主要寄存器的一般用途:
寄存器 | 用途 |
---|---|
EAX | 存儲器:用于執行計算,并用于存儲函數的傳回值。基本操作,如加、減、比較的時候使用這個通用寄存器 |
EBX | 存儲資料 |
ECX | 計數器:常用于計數循環的次數。 |
EDX | 資料 |
ESP | 棧頂指針 |
EBP | 基指針(常用來表示一個函數幀的底部) |
ESI | 源操作數指針 |
EDI | 目的位址指針 |
EIP | 指令指針 |
注意: 棧是從低位址向高位址,堆是高位址向低位址生長
x86處理器采用的是小端序(低位在前面,例如0x123456->0x563412)
程式存儲器分為(按照記憶體中的順序排列)
名字 | 類型 |
---|---|
text | 禁用寫權限,固定大小 |
data | 存儲全局變量,靜态變量。存儲的是已經初始化的,可以改寫,固定大小 |
bss | 存儲全局變量,靜态變量。存儲的是未初始化的,可以改寫,固定大小 |
heap | 用于其他的變量(moonife:動态申請的)(比如malloc操作等等,配置設定的空間在heap裡面)。大小可變,對從存儲器的低位址向高位址增長 |
stack | 大小可變,函數調用時作為中間結果暫存器。存儲所有傳遞的變量,以及函數執行後的EIP的傳回位址 |
函數參數以及局部變量的入棧順序
void test(int a,int b,int c,int d){
char flag;
char buffer[10];
}
void main(){
test(1,2,3,4);
}
棧頂 | … |
---|---|
buffer | 低位址 |
flag | |
SFP | |
ret | |
a/1 | |
b/2 | |
c/3 | |
d/4 | 高位址 |
棧底 |
調用的時候4321這樣入棧
使用者程序空間映像如下圖所示:
當函數 Do_Something(param 1)被調用,有以下步驟:
- Push param 1
- Call Do_Something 的同時 push EIP(傳回位址)
- Push EBP,這是必須的 ,因為我們需要改變 EBP 的值來引用棧中的值,這是通過 mov ebp,esp
- 來實作的,是以棧中的資料,很容易被引用。
- 最後,局部變量被壓入棧,在我們這個例子是:do_something::buffer[128]。
- 是以,當函數結束的時候,将傳回main函數。