OS:XP SP3
編譯器: DEV C++ 4.9.9.2
工具:
OD (ollydbg)
大家可以去先查詢一下 組合語言(32位元)方面的知識,然後至少要了解 stack區常用的指令 PUSH 跟 POP,與EIP寄存器 不用了解全部章節。
#include <stdio.h>
#include <stdlib.h>
void func(void);
//全域變數
int g1=0;
int g2=1;
int main()
{
//區域變數
int a=2;
int b=3;
func();
system("pause");
return 0;
}
void func(void)
{
//區域變數
int x=7;
int y=8;
}
關於組合語言的知識一偏文肯定講不完。所以這次給大家簡單的方式說明。
stack 區域是一個公共空間,任何函數都可以使用,但是每個函數都有自己的空間,所以使用前,要先規定自己的基底,這個基底的標記就是 寄存器(EBP)。
函數的基底 EBP 規劃好後 可以開始往上佔領其他空間了。
而這個工作需要交給寄存器 (ESP)
你可以先在 main 函數 裡面隨便找個地方 按F2設中斷 然後F9執行 接下來一直F7走過每一條指令透過觀察發現,esp 一直在變動。 ebp 則不會。
1.Ctrl + F2 重新載入
2.找到 main 函數 調用 func函數(call)那行按下F2
3.找到 func 函數 LEAVE 那行按下F2
4.按下F9 跑到 main函數的中斷 觀察 stack 區
可以看到 EBP 到 ESP 的空間 就是目前函數正在使用的空間
5.在按下F9就會跑到 func函數的中斷 觀察 stack 區
leave = mov esp,ebp ### pop ebp
retn = pop eip
這兩條指令又稱為 Function Epilogue 也就是函數的結尾,目的是在釋放自己的領土,然後歸還給 main 函數
push ebp # 儲存 main數的 ebp到堆疊
mov ebp,esp # 規劃自己的基底
call 推入下一行(004012CD)到堆疊
push ebp # 儲存 main數的 ebp到堆疊
mov ebp,esp # 規劃自己的基底
leave = mov esp,ebp (釋放自己的領土回到基底) ### pop ebp (歸還 main的ebp)
retn = pop eip (回到004012CD)
如果有任何問題歡迎指教,謝謝。