栈帧
- 栈帧在程序中用于声明局部变量、调用函数,所利用的是EBP(栈帧指针)寄存器来访问栈内局部变量,参数,函数返回地址
- 栈帧结构
PUSH EBP ;函数开始(使用EBP前先把已有的值压入栈)
MOV EBP, ESP ;保存当前的ESP内的值到EBP寄存器中
...... ;函数体(无论ESP怎么变化,EBP不好发生改变)
MOV ESP, EBP ;将函数的起始地址返回ESP中
POP EBP ;出栈EBP
RETN ;函数终止
调试StackFram.exe
StackFram.cpp
#include "stdio.h"
long add(long a, long b)
{
long x = a, y = b;
return (x + y);
}
int main(int argc, char* argv[])
{
long a = 1, b = 2;
printf("%d\n", add(a, b));
return 0;
}
开始调试
附加
- 使用OD打开StackFram.exe
- 按Ctrl + G 转到401000 地址处
*
以上是对于Add() 函数和Main() 函数的汇编代码
开始调试,生成栈帧
- 首先从主函数址里开始执行,地址:0040102
- 下断点,按F9开始运行,观察EBP
- 压入EBP,并且将ESP的数值赋值到EBP(EBP = 0019FF28)
- 生成变量a,b,压栈
- 调用Add() 函数的CALL,压栈CALL的地址
- 注意:此时ESP 已经变动了几次,但是EBP仍然没有变动
- 在add() 函数中,EBP 重新被赋值为0019FF10
- 在执行完成函数后,EBP复原为0019FF28
- 同理调用printf()函数
- 程序执行完成
注:XOR 为异或指令,代码中XOR EAX,EAX 与MOV EAX,0 功能一样,但是XOR 执行更快,通常作为寄存器初始化操作