小巧思

总结一下我学习过程中遇到的一些理解误区

1. 返回地址的存储位置 vs 返回地址的值

返回地址的存储位置:栈中的某个内存地址,例如 0x7fffffffe000。

返回地址的值:保存在这个位置的内容,例如原本是 0x401200,现在被我们覆盖成 0x401186

2. 在栈溢出的问题中,各个寄存器是怎么工作的

当执行call vuln时,rsp指向返回地址

低地址
┌────────────────────┐
│ 返回地址 │ ← rsp
├────────────────────┤
│ 调用者原有栈数据 │
└────────────────────┘
高地址

cpu再次把栈帧基准放入栈顶,由rsp指向栈顶(push rbp 的意义,就是保存调用者原来的栈帧位置,以便当前函数执行结束后,能够恢复调用者的工作环境。)

低地址
┌────────────────────┐
│ main 的旧 rbp │ ← rsp
├────────────────────┤
│ 返回 main 的地址 │
├────────────────────┤
│ main 原有栈数据 │
└────────────────────┘
高地址

rbp 成为了 vuln 的栈帧基准,指向 vuln 保存旧 rbp 的位置。注意:main 原来的 rbp 数值仍然保存在这块内存里,并没有丢失,这一步要好好理解!!!

低地址
┌────────────────────┐
│ main 的旧 rbp │ ← rsp、rbp
├────────────────────┤
│ 返回 main 的地址 │
├────────────────────┤
│ main 原有栈数据 │
└────────────────────┘
高地址

建立vuln的栈帧(rsp一直追随栈顶)

低地址
┌────────────────────┐
│ │
│ │
│ buf[32] │ ← rsp
│ │
│ │
├────────────────────┤
│ main 的旧 rbp │ ← rbp
├────────────────────┤
│ 返回 main 的地址 │
├────────────────────┤
│ main 原有栈数据 │
└────────────────────┘
高地址

恶意数据从 buf 的低地址开始,向高地址连续写入

低地址
┌────────────────────┐
│ AAAAAAAAAAAAAAAA │ ← rsp
│ AAAAAAAAAAAAAAAA │
│ buf[32] 被填满 │
├────────────────────┤
│ AAAAAAAA │ ← rbp
│ 旧 rbp 被覆盖 │
├────────────────────┤
│ win 函数的地址 │
│ 原返回地址被覆盖 │
├────────────────────┤
│ main 原有栈数据 │
└────────────────────┘
高地址

数据写入方向 ↓

紧接着vuln 执行 leave,让 rsp = rbp,CPU做两件事,1.将AAAAAAAA—被破坏的旧 rbp 的值重新放入 RBP 寄存器(从指向旧rbp位置的指针地址变成了旧 rbp的值)2.将 RSP 增加 8 字节(我当时还好奇为什么是8字节,因为x86-64 中,一个地址占 8 字节)
于是rsp 指向我们伪造的返回地址

低地址
┌────────────────────┐
│ AAAAAAAAAAAAAAAA │
│ AAAAAAAAAAAAAAAA │
│ buf[32] │
├────────────────────┤
│ AAAAAAAA │
│ 被覆盖的旧 rbp │
├────────────────────┤
│ win 函数的地址 │ ← rsp
├────────────────────┤
│ main 原有栈数据 │
└────────────────────┘
高地址

vuln 执行 ret(注意:ret不是寄存器,是指令!!!)
ret 从 rsp 指向的位置读取地址。

低地址
┌────────────────────┐
│ buf[32] │
├────────────────────┤
│ 被覆盖的旧 rbp │
├────────────────────┤
│ win 函数的地址 │ ← ret 读取这里
├────────────────────┤
│ main 原有栈数据 │ ← ret 后的 rsp
└────────────────────┘
高地址

于是CPU 跳转到 win,执行其中的指令。

在数据结构的知识没掌握之前,我认为我的这个小巧思可以带来很大的帮助,当然,系统学习了数据结构后,这些都好理解

tips:感谢gpt构筑的图表,让我的笔记记得很顺畅