这段时间工作比较忙就一直没精力更,之后的时间比较多所以会加快更文频率,尽快把这个系列讲完,多谢大家这段时间的理解与支持。上篇文章我们讲了OD的基本运用,与函数执行前的内存的准备流程,这篇就真正接触到缓冲区溢出的核心内容-压栈与弹栈。
前文回顾:
0x00 入栈出栈原理
1. 先入后出,后入先出
入栈出栈的过程就像我们把子弹装入弹夹然后再发射出去的过程。这个过程遵循着先入后出,后入先出的原则,就像我们开枪时,打出的第一颗子弹实际是我们最后压入弹夹的子弹。当然也有人把这个过程比喻为摞盘子,我们正常情况下肯定是从一摞盘子的顶部开始取用盘子,而最上面的盘子肯定是最后放上去的。
2. 从高址向低质增长
这个没什么好解释的,算是约定俗称的,我们记住就好,只不过刚开始容易混淆ESP和EBP,时间长了就习惯了。
上边这张图片看时间长了会疯,不知道你们看时有什么感觉。
0x01 OD中调用MassageBoxA是栈调用的入栈过程
上节课我们运行到了0x0040152E的位置,如果前边还没看懂的朋友,也不用在意,到这里我们才真正接触到核心位置,这里能看明白基本就可以进行缓冲区溢出的利用。
按F8(单步步过)让黑色指针停到0x0040153A的位置,也就是call Eax的位置上:
按F7(单步步入)进入到执行MassageBoxA的进程中,我们会看到如下界面:
看到一堆push才是真正压栈的过程,我们一路F8(单步步过)来到0x76721F79的位置,让我们看看我们压入栈的到底是什么东西。
这里我们要关注我们的栈底(EBP)0x006FFE78,栈顶(ESP)0x006FFE70:
继续F8第一个参数,不!应该说最后一个参数入栈,可入栈的是什么呢,注释说是EBP+14,那我们算一下0x006FFE78+0x14果断请出计算器结果如下,理论上接下来入栈的应该就是0x006FFE8C所指向的值也就是0x000000。
继续F8验证一下我们的猜想,如图所示我们猜想是对的,栈顶的值被压入了0x000000。
根据上面总结的经验我们大概猜到了,下一个入栈的值应该就是EBP+0x10所指向的值,让我们验证一下,结果不出所料。
以此类推接下来两个参数入栈也是一样的原理。
0x02 OD中调用MassageBoxA是栈调用的出栈过程
弹栈呢对缓冲区溢出影响不大,这里就不着重讲。另外就是MessageBoxA这个程序选的有点复杂,不利于讲弹栈,如果我在0x76721F85的地方再次步入,那将有很多的分支,继续入栈出栈,就进入了死循环,所以在这里偷个懒。我们直接步过我们把pop EBP简单看作一次弹栈就好,以后真正讲溢出时有机会给大家看看弹栈。
当我们看到弹出框时其实参数都已经出栈,现在EBP和ESP是重合的,再pop EBP 这段函数就结束了他的使命。
0x03 返回地址
这是今天最重要的内容,也是缓冲区溢出利用关键所在,大家要反复的琢磨一下。
当我们pop EBP 后就只剩一个return了,那我们返回到哪里呢。其实这个返回地址就在EBP的下面,现在EBP是0x06FFE78,那么0x06FFE7C所指向的值就是要返回的地址。
现在返回地址的值是0x0040153C 我们F8看看能否返回到这个地址。
上图这个界面是不是很熟悉,程序又回到了CALL EAX时的代码段。现在只需要记住怎么找这个return的地址就好,这里卖个官司以后我再给大家讲他的重要之处。
最后给大家一张函数执行流程图,希望大家对函数执行流程有深入的了解。
*本文作者:kaliking,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。
来源:freebuf.com 2019-06-28 09:00:36 by: kaliking
请登录后发表评论
注册