Memory 在缓冲区溢出中,新的返回地址如何完美对齐?

Memory 在缓冲区溢出中,新的返回地址如何完美对齐?,memory,x86,stack,buffer-overflow,cybersecurity,Memory,X86,Stack,Buffer Overflow,Cybersecurity,我很困惑,在基于堆栈的缓冲区溢出中,如果我在堆栈删除中用新的目标地址覆盖程序的返回地址,这些地址如何对齐,或者如何确保发生这种情况?例如:假设在堆栈帧中,我在地址0x1处有一个变量元素(尽管0x1太低,无法实现),在地址0x6处有一个返回地址元素。现在,如果在我的处理器中架构是32位的,那么地址将是4字节。因此,如果程序要求我提供一个参数,它将把这个参数放入缓冲区,我提供这个地址重复两次,那么很明显,这个地址元素将有新地址的第二个字节。因此,地址未对齐,程序将崩溃。如何确保地址始终对齐 let

我很困惑,在基于堆栈的缓冲区溢出中,如果我在堆栈删除中用新的目标地址覆盖程序的返回地址,这些地址如何对齐,或者如何确保发生这种情况?例如:假设在堆栈帧中,我在地址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   | ....

你可以选择你所要表达的内容。使其长度正确,以便将返回地址与其所利用的二进制文件堆栈帧中缓冲区的相对位置对齐

这个距离是一个编译时常量(如果是VLA或alloca,则至少
n%16
是常量…),因此可以使用反汇编程序找到它。编译器将选择按161对齐本地数组。或者在不需要16字节堆栈对齐的32位ABI上至少按4。因此,即使您没有试图利用的二进制文件的副本,您仍然可以按照您的建议重复返回地址,在与文件开始位置相对4对齐的位置 缓冲器当然,如果没有二进制文件,知道要使用什么返回地址(对于ROP攻击)可能很困难,除非有一些库没有ASLRed

(例如,x86-64 System V ABI要求所有大于等于16字节的阵列和所有VLA都使用此功能,尽管在单个函数外部看不到专用本地阵列。)