什么是堆栈
- 程序执行过程中要使用的一块内存
- 是程序的心脏,所有的关键数据都会在这里边出现
- 与数据结构的堆栈无关
查看程序的堆栈
把程序拖到OD里,在命令行输入dd (FS对应的地址)即可。
- 程序在使用堆栈的时候,是从顶部往底部存储,空间也就会越存越小,直到存不下的时候,它就崩溃了,这或许就是堆栈溢出吧。
- 寄存器ESP反应的是当前程序在堆栈中的使用情况,也就是告诉你程序运行到这一步它在堆栈中用到了哪里
使用程序的堆栈
当前程序执行到了19C6EC,我们就可以接着往下使用,一直到上图中的程序底部为止。
使用剩下的堆栈可以使用如下指令:
mov DWORD ptr ds:[19C6E4],1 //向目标堆栈中存1
mov DWORD ptr ds:[19C6E0],2 //向目标堆栈中存2
这时一定要告诉堆栈你用到那里了,要让他跟上你的步伐,不然后面的程序会覆盖你向堆栈写入的内容,这时候需要修改寄存器ESP的值,让他指向现在所占用的堆栈,如果你不知道为什么修改ESP的值,可以点这里。
同理,如果不想用了,在mov或者add回去就ok了。
这只是两条数据,如果数据多了,一条一条的来打是非常麻烦的,这时候我们就用到了push指令与pop指令。
push指令(压栈)
功能:
- 向堆栈中(栈顶)压入数据
- 修改栈顶指针ESP寄存器的值(减4)
之前我们是先修改堆栈中的值,然后再去修改栈顶指针ESP的值,现在不需要了,我们只需要push一下,他就会完成前两项操作,例如:
push 666 //这里push的是立即数,也可以是寄存器和内存
运行效果:
pop指令(出栈)
功能:
- 将堆栈中(栈顶)数据存储到寄存器或内存
- 修改栈顶指针ESP的值(加4)
运行效果:
总结
- push是将数据压入到栈顶,并将栈顶指针ESP的值-4
- pop是栈顶将数据压出到寄存器或内存中,并将栈顶指针ESP的值+4
- 这两个指令一般会成对出现,前面有push,后面就一定会有pop
- 压栈与出栈的顺序特点是,先进后出,后进先出