-
-
[原创] 唯有逆向,夯实基础
-
发表于:
2020-1-9 22:04
8933
-
详情:
① 程序返回地址(EBP+4)的重要性
最近复现漏洞让我乐此不疲,是真的好玩!内心的激动简直无法形容,先来看第一个程序:定义了一个Attack函数,里面有一个死循环;main函数里定义了一个整型数组,大小为5个字节,并且全都赋值为0,也叫初始化;后面将Attack(地址值)这个值赋给 arr[6]。
其中有趣的是主函数中并没有去调用Attack函数去执行,但结果令人意外。这个程序竟然可以运行起来,而且它恰好执行了Attack函数,到底发生了什么呢,一探究竟之。
为了知根知底,需要回到汇编层面去研究它,这里列出整个过程,并配以解释。以下是它的反汇编,下面的演示说明都是基于此;
首先,为了了解程序到底干了什么,逆向一般会一步一步解析代码的执行过程,也就是去画堆栈图;
这也是很多野路子突破上层的限制时,寻找突破口的关键。
第一步,记录原始堆栈结构,EBP(栈底)、ESP(栈顶),将这个图想象成没有盖的杯子
第二步,下图中紫色的地方就是我们所熟悉的缓冲区,像缓冲区溢出攻击也就是针对这个区间的,在逆向中,我们总结的经验是( EBP -4) 以下是局部变量,(EBP + 8) 以上是函数参数;这里是说存储的位置
第三步,局部变量初始化
第四步,从下图中,可以发现用红框标注的地方就是重要的点,它就是 EBP + 4 (函数的返回地址),还记得最开始
程序中的那行代码么? arr[6] = (int)Attack; 就是由于这行代码导致在程序执行的过程中,将Attack函数所在程序的地址
提前压入了堆栈,导致在程序快结束时,由于RETN命令将堆栈里的值弹出来了(RETN的作用如图所示),而且正好就是EIP,即CPU;
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)