610 字
3 分钟

PWN:关于迁栈

2026-03-06
2026-04-16
浏览量 加载中...

写这个,主要是我觉得迁栈这个知识点,还蛮重要的,然后我目前也不是很懂,再写的过程中加深一下理解。

在栈溢出中,我们通过对stack的观察,可以看见我们输入的数据流到save register,到return address,这边的数据流是根据题目而定的,有时候需要的占用字节多,有时候需要的占用字节少。

而当题目,比如说,我在写orw类型题目时,遇到一题,需要我泄露libc的基地址,然后去找偏移,通过偏移地址调用open,read,write三个函数来完成攻击连,而且还需要用到rop,这样写出来的字节数就很多,而题目的栈又太小了放不下,所以才要迁栈。

https://www.cnblogs.com/Junglezt/p/18246439

根据对文章的理解,迁栈的关键在于leave和ret。

正常函数运行时,程序会开辟出一个栈的空间给函数用,当函数执行完了,不就得将这个栈的空间释放掉,类似c语言里面的动态申请空间存放变量malloc,不用了就会用free释放掉这个变量,节省内存。

而在栈中,leave和ret的作用就是用来清空栈的。

https://www.cnblogs.com/milantgh/p/3931871.html

leave相当于:

MOVE RSP RBP ;将栈底指针的值赋值给栈顶,直接清空了栈。 POP EBP ;这个的作用要讲到在在move之前,程序push rbp,已经将上一个函数的返回地址存了进去,pop一下,就把这个值弹了出来,然后自身的地址再+8。

image-20260306204108683

对应到这边ida的图片里,stack,上面为栈顶,地址小也就是低,下面为栈底,地址大也就是高。

当进行move,即rsp的地址立刻跳为这个0x0000h的rbp栈底,然后pop,即rsp的地址往下跳8字节,+8的意思。

这也是为了后面ret做准备。

ret相当于:

pop rip;(看到这个还挺熟悉的,是rop中常用的指令,用来取用指令地址。) 从rsp指向的地址取走八个字节的数据存入rdi,然后为了程序的继续运行,rsp又会自增8,指向0x10。

搞清楚来了leave和ret后,现在我们就来看看迁栈到底是如何使用这两个指令的。


  • 版权声明:本文由 余林阳 创作,转载请注明出处。

喜欢这篇文章吗?

点击右侧按钮为文章点赞,让更多人看到!

PWN:关于迁栈
https://sliver-yu.cc/posts/pwn/pwn_关于迁栈/
作者
余林阳
发布于
2026-03-06
许可协议
CC BY-NC-SA 4.0

评论区

目录