目录

逆向入门噩梦之堆栈

目录

逆向入门噩梦之堆栈(软件安全攻防反汇编反调试)

微尘网络安全

什么是堆栈

其实 堆 和 栈是2个概念 ,在内存中 堆是在有一段存放的空间的 x86当中 大概占1M左右。而栈呢是 每次准备进入call 之前在内存中开辟的一段地址空间。我们说的堆栈其实指得是栈 ,就像我们说土狗 他是狗 ,说老婆饼 他是饼 一样的意思

在计算机领域,堆栈是一个不容忽视的概念,堆栈是一种数据结构。堆栈都是一种数据项按序排列的数据结构

为什么要学习堆栈

经常有学员来问咱们这个问题 ,这个这么复杂这么难,我为啥要学他!! 可以跳过嘛

咱们在实战当中 经常要求分析代码 正向程序员写代码肯定是多层调用的 10几层call 更是常有的事,不学习堆栈 你都没发追数据了,而且你对程序的结构 内存的理解程度是一个很大的缺失部分,没有这样的理解 恐怕后面是很难往下学习的

拆解堆栈

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/960934055ed6e9bb4054239f9bb5199af5c88ec7.png@942w_243h_progressive.png

如上 一个最简单的c++的 加法函数,咱们看他的反汇编代码

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/d352bf7fe283e78c9b941eead51cfe5d70470511.png@357w_213h_progressive.png

这里有个细节要注意一下 我们发现他参数压入堆栈的顺序 是从右往左的

那他为啥不是从左往右呢,这里其实涉及到函数调用约定的问题,咱们后面的课程都有讲到的,这里 从右向左压栈,不是规定,也不是因为栈先进后出的特性。在《c和指针》中已经说明了从右向左压栈的原因,这样可以保证生成汇编语言时这些参数相对于BP指向的栈位置的偏移量是固定的。

C方式参数入栈顺序(从右至左)的好处就是可以动态变化参数个数。

我们在进入call内部去看

https://i0.hdslb.com/bfs/article/8d7ba79f7853da262c6221ae0bf07b92f1aba963.png@500w_270h_progressive.png

第一步 把ebp压栈

第二部 mov ebp,esp

第三部 提升堆栈空间,用来存放本层call的局部变量

第四部 保存各个寄存器,因为接下来本层call就要使用这些寄存器了,先把他压入栈中

第五部 执行本层call的代码了

咱们在来继续看后面的

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/5871d74a2c01afd0dd86e36ffb7fd7d13a885883.png@647w_251h_progressive.png

第六步 还原寄存器 因为本层call的代码执行完了 寄存器的任务也完成了,就把刚进来时候的寄存器的值从堆栈里面弹出来吧,因为咱们要出去 返回到之前的堆栈空间了去了 咱们进来时候寄存器是啥样 出去的时候 还得啥样 需要还原回来 不然寄存器就崩溃了

第七步 任务完成了 咱们把刚进call时候开辟的堆栈空间也拉下来 还原回来

第八步 mov esp ,ebp 同样是还原回来

第九步 弹出ebp 同上

第十步 ret回上一层了

这样就完美的 走完了一个call了,从进入call 到出call 寄存器 堆栈地址并没发生任何变化,就跟没进去过一样 不留下一片云彩。其中还是有好几个细节要注意的,大家需要自己做一遍才能深刻体会!

微尘网络安全专注分享网络安全 x64 c++ 逆向 反汇编 反调试 HOOK 注入 封包 内存等技术公众号