一.栈帧
简言之,栈帧就是利用EBP(栈帧指针,请注意不是ESP)寄存器访问栈内局部变量、参数、 函数返回地址等的手段。
ESP寄存器承担着栈顶指针 的作用,而EBP寄存器则负责行使栈帧指针的职能。
程序运行中,ESP寄存器的值随时变化,访 问栈中函数的局部变量、参数时,若以ESP值为基准编写程序会十分困难,并且也很难使CPU引 用到准确的地址。
所以,调用某函数时,先要把用作基准点(函数起始地址)的ESP值保存到EBP, 并维持在函数内部。
这样,无论ESP的值如何变化,以EBP的值为基准(base )能够安全访问到 相关函数的局部变量、参数、返回地址,这就是EBP寄存器作为栈帧指针的作用。
EAX 是"累加器"(accumulator), 它是很多加法乘法指令的缺省寄存器。
EBX 是"基地址"(base)寄存器, 在内存寻址时存放基地址。
ECX 是计数器(counter), 是重复(REP)前缀指令和LOOP指令的内定计数器。
EDX 则总是被用来放整数除法产生的余数。
ESI/EDI分别叫做"源/目标索引寄存器"(source/destination index),因为在很多字符串操作指令中, DS:ESI指向源串,而ES:EDI指向目标串.

EBP是"基址指针"(BASE POINTER), 它最经常被用作高级语言函数调用的"框架指针"(frame pointer). 在破解的时候,经常可以看见一个标准的函数起始代码:
push ebp ;保存当前ebp
mov ebp,esp ;EBP设为当前堆栈指针
sub esp, xxx ;预留xxx字节给函数临时变量.
二.调试示例
#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;
}
注意注意注意(重要的事情说三遍)把软件的自动优化给关掉!!!!!
项目——>属性(最后那个)
三.使用OllyDbg调试工具打开StackFrame.exe文件
四.找main()函数
EIP:Extended Instruction Pointer,扩展指令指针
看EIP的位置,这个位置我看有些大佬,找到后就说是main的位置,然后就F2断点再F9,
我看我的位置,这也不是main的位置呀
问了老师,了解了EIP是在main的前面,可以在EIP断点,然后一步一步执行找到main
也可以根据反汇编语言的注释,比如
来定位main所在的位置
五.开始执行main()函数
根据EIP一步一步的找,实在是太麻烦了
我们还是利用注释吧
在55哪里开始F2断点
F9开始运行
F7进入函数
F8一步一步向下执行
看栈的变化过程
到这里 EAX的值就固定了
再往后就结束了