2018.04.18
CPU 發(fā)出指令把硬盤程序指令搬到內(nèi)存,操作系統(tǒng)給程序指令分配內(nèi)存。然后操作系統(tǒng)會告訴 CPU 「程序入口點」,也就是第一條指令地址。
CPU 從內(nèi)存出取得的指令一般是這三類:
- 把數(shù)據(jù)從內(nèi)存運到 CPU 寄存器。
- 對寄存器數(shù)據(jù)進行運算。
- 把寄存器數(shù)據(jù)寫入到內(nèi)存。
x86 體系機器:每次函數(shù)調(diào)用都會創(chuàng)建一個幀。
幀,內(nèi)存中一段連續(xù)空間。

多個函數(shù)幀在內(nèi)存里排起來, 就像一個先進后出的棧一樣。
但這個棧與普通的棧不一樣,這個棧的棧底在上面,從上往下生長(從高地址往低地址生長)。
4 個字節(jié)為單位,4 個字節(jié)內(nèi)從低地址往高地址生長。
ebp,CPU 特殊寄存器,指向棧中當前函數(shù)幀的起始地址。
esp,CPU 特殊寄存器,指向棧中當前函數(shù)幀的尾地址。

下面是 CPU 向內(nèi)存取的函數(shù)調(diào)用指令。
把 ebp 的值壓入棧中。(CPU -> 內(nèi)存)
這時,地址 800~804 的內(nèi)容是 1000,esp 指向地址 800 。把 esp 的值賦給 ebp 。(CPU)
這時,esp、ebp 同時指向地址 800,一個新的函數(shù)幀誕生!
函數(shù)幀的起始地址是 800, 里邊的內(nèi)容是1000 。把 esp 的值減去 24 。(CPU)
esp 指向地址 776,這是為準備函數(shù)實參騰出空間。
減去 24 是為了數(shù)據(jù)對齊。24 + 4(入棧的 ebp) + 4(返回地址) = 32 。
x86 編程規(guī)定函數(shù)幀是 16 的整數(shù)倍。把 10 放到 ebp 減去 4 的地址,把 20 放到 ebp 減去8的地址。(CPU -> 內(nèi)存)
其實就是:int x=10; int y=20 。把 x 地址放到 esp 指向的地址,把 y 地址放到 esp+4 指向的地址。
其實就是準備實參 &x, &y 。

- 把地址 100 壓入棧中。
這是調(diào)用函數(shù)之前,調(diào)用方下一條指令地址(函數(shù)返回地址)壓入棧。
int sum = add(&x, &y);
printf("the sum is %d\n",sum); // 假設這條指令的地址是 100

- 函數(shù)調(diào)用前的保護現(xiàn)場,以便返回時恢復現(xiàn)場。 (CPU -> 內(nèi)存)
把寄存器 ebp 的值壓到棧里去
把 esp 的值賦給 ebp
把寄存器 ebx 的值壓入棧

- CPU 取出數(shù)據(jù)計算。(CPU)
int add(int *xp , int *yp){
int x = *xp;
int y = *yp;
return x+y
}
把 ebp 加 8 的數(shù)據(jù)取出來放到 edx 寄存器。取得 xp 。
把 ebp 加 12 的數(shù)據(jù)取出來放到 ecx 寄存器。取得 yp 。
把 edx 指向的內(nèi)存地址的數(shù)據(jù)取出來,放到 ebx 寄存器。取得 *xp 放入 ebx 。
把 ecx 指向的內(nèi)存地址的數(shù)據(jù)取出來,放到 eax 寄存器。取得 *yp 放入 eax 。
把 ebx 和 eax 的值加起來,放到 eax 寄存器中。取得 *xp+*yp,放入 eax 。
- 恢復現(xiàn)場。(內(nèi)存 -> CPU)
把 esp 指向的數(shù)據(jù)彈出的 ebx 寄存器。
把 esp 指向的數(shù)據(jù)彈出到 ebp 寄存器。

- 返回。
CPU 取出返回地址 100,去那里找到指令繼續(xù)執(zhí)行。
函數(shù)調(diào)用總結(jié)
把參數(shù)和返回地址準備好。
新建函數(shù)幀:
把寄存器 ebp 的值壓入棧。
把 esp 的值賦給 ebp。函數(shù)調(diào)用完后, 重置 ebp 和 esp,讓他們重新指向調(diào)用方的函數(shù)幀。
內(nèi)存緩沖區(qū)溢出
用戶輸入的數(shù)據(jù)是從低地址向高地址存放的。
黑客輸入精心設計的數(shù)據(jù)過多以至于覆蓋了返回地址,讓返回地址指向惡意代碼入口地址。
輸入函數(shù)有邊界檢查就可避免攻擊。
參考文檔:
http://mp.weixin.qq.com/s/hX8tHnoq4gdkhcLHUGzEbg
http://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg==&mid=2665513039&idx=1&sn=381c1b8c7f86906c4838050b8c1db2bb&scene=21#wechat_redirect