2

我浏览了很多互联网,但仍然无法理解它的工作方式

此链接也没有成功: NOP 雪橇如何工作?

好的,假设我们char a[8];在函数中有一个缓冲区,foo() 并且堆栈帧foo()看起来像这样(32 位):

在此处输入图像描述

现在,我们要做的是覆盖'return'值,在调用时保存在堆栈foo()

他们说问题是,我们无法预测保存的“返回”值的位置

但为什么?例如,如果函数foo()在所有其他局部变量之前定义了缓冲区,如上图所示,那么我们总是知道我们需要填充分配给缓冲区的 8 个字节,然后是保存的 EBP 的 4 个字节,然后我们得到“返回”
或者,如果在缓冲区之前定义了其他局部变量,比如 2 个整数,那么我们考虑为缓冲区分配 8 个字节,然后是这 2 个本地整数的 8 个字节,然后是保存的 EBP 的 4 个字节,然后我们得到“返回”

我们总是知道从溢出的缓冲区中保存的“返回”有多远,不是吗?:/

如果我们不这样做,请解释一下。这是我的问题1。

我的问题 2 是,好吧,让我们假设我们不知道 'return' 的值保存在哪里。然后,如果我们在 shellcode 之前有大量 NOP,我们很有可能将 NOP(即 0x90)值写入“return”的位置,从而覆盖原始值
现在,当函数foo()返回时,0x90 的值被加载到 EIP(指令指针)中,而不是恢复其正常流程,程序将从地址 0x90 执行,不是吗?
我想我在这里误解了一些东西

请不要关闭我的问题,即使有一个类似的问题,我已经提供了链接,在一开始,我想这个问题会更加全面和清晰

4

1 回答 1

0

首先我们假设没有地址空间随机化并且堆栈是可执行的。

我们总是知道从溢出的缓冲区中保存的“返回”有多远,不是吗?:/

不,我们不知道。在局部变量与保存的 EBP 和返回地址之间存在未指定数量的填充字节。此字节数可能取决于编译器版本。

然后,如果我们在 shellcode 之前有大量 NOP,我们很有可能将 NOP(即 0x90)值写入“return”的位置,从而覆盖原始值

这个想法是在返回地址之后拥有所有 NOP 值。这样我们就可以用堆栈中 shellcode 的“近似”地址覆盖返回地址。确切的 shellcode 地址可能取决于操作系统版本,但也取决于程序参数以及环境变量的大小和数量,因为它们位于堆栈地址空间中。

于 2013-08-04T13:57:32.147 回答