在缓冲区溢出中,新的返回地址如何完美对齐?
Posted
技术标签:
【中文标题】在缓冲区溢出中,新的返回地址如何完美对齐?【英文标题】:In buffer overflow, how new return address aligns perfectly? 【发布时间】:2021-04-14 15:54:38 【问题描述】:我很困惑,在基于堆栈的缓冲区溢出中,如果我用该堆栈元素中的新目标地址覆盖程序的返回地址,这些地址如何对齐或如何确保发生这种情况?例如:假设在堆栈帧中,我在地址 0x1 处有一个变量元素(尽管假设 0x1 太低而不会发生),并且我在地址 0x6 处有一个返回地址元素。现在,如果我的处理器中的体系结构是 32 位的,那么地址将是 4 个字节。因此,如果程序要求我输入一个将放入该缓冲区的参数,并且我重复两次提供该地址,那么显然该地址元素将具有新地址的第二个字节。因此地址未对齐,程序将崩溃。如何确保地址始终对齐?
let new address = 0x bf ff ff 3c
address from buffer to return address element: | 0x1 | 0x2 | 0x3 | 0x4 | 0x5 | 0x6 | ....
| | | | | | |
newly written return address layout in memory: | 3c | ff | ff | bf | 3c | ff | ....
【问题讨论】:
【参考方案1】:您可以选择溢出的内容。使其长度合适,以便将返回地址与其相对于您正在利用的二进制堆栈帧中缓冲区的位置对齐。
这个距离是一个编译时常量(或者至少n%16
是一个常量,如果它是一个 VLA 或 alloca...)所以你可以用反汇编程序找到它。编译器甚至会选择将本地数组对齐 161。或者在不需要 16 字节堆栈对齐的 32 位 ABI 上至少增加 4 个。因此,即使您没有尝试利用的二进制文件的副本,您仍然可以按照您的建议重复返回地址,在相对于开头对齐 4 的位置处
缓冲。当然,如果没有二进制文件,知道使用哪个返回地址(用于 ROP 攻击)可能会很困难,除非有一些库不是 ASLRed。
(例如,x86-64 System V ABI 要求所有 >=16 字节的数组和所有 VLA,尽管私有本地数组在单个函数之外不可见。)
【讨论】:
以上是关于在缓冲区溢出中,新的返回地址如何完美对齐?的主要内容,如果未能解决你的问题,请参考以下文章
python 中的out of memory是怎么回事,内存不够吗?