总结一下我学习过程中遇到的一些理解误区
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构筑的图表,让我的笔记记得很顺畅