堆栈溢出和缓冲区溢出的区别是什么?

在编程中堆栈溢出和缓冲区溢出的区别是什么?

49557 次浏览

堆栈溢出特指执行堆栈超出为其保留的内存的情况。例如,如果您调用一个不终止递归调用本身的函数,您将导致堆栈溢出,因为每个函数调用都会创建一个新的堆栈帧,堆栈最终将消耗比为其保留的更多的内存。

缓冲区溢出是指程序写入超出为任何缓冲区(包括堆,而不仅仅是堆栈)分配的内存结束的任何情况。例如,如果写入超过从堆中分配的数组的末尾,就会导致缓冲区溢出。

堆栈溢出是指线程的堆栈大小超过该线程的最大允许堆栈大小。

缓冲区溢出是指当一个值被写入内存时,程序当前没有分配这个值。

堆栈溢出: 对于分配给当前线程的内存,您在堆栈上放置了太多内容

缓冲区溢出: 您已经超过当前分配的缓冲区的大小,并且没有调整其大小以适应(或者无法进一步调整其大小)。

比你想知道的还要多:

堆栈溢出

缓冲区溢出

缓冲区溢出通常表示内存缓冲区在堆栈或堆之外被访问的任何时候。堆栈溢出意味着堆栈已经超出了它的分配限制,并且在大多数机器/操作系统上都在堆上运行。

关键的区别在于知道堆栈和缓冲区之间的区别。

堆栈是为执行程序保留的空间。当你调用一个函数时,它的参数和返回信息被放置在堆栈上。

缓冲区是用于单一目的的一般内存块。例如,字符串是一个缓冲区。通过向字符串写入比分配给它的数据更多的数据,它可能会超负荷运行。

你的意思难道不是“堆栈和缓冲区的区别是什么?”这会让你更快地洞察事物。一旦你做到了这一点,那么你就可以思考一下溢出这些东西意味着什么。

大多数提到缓冲区溢出的人指的是堆栈溢出。但是,溢出可能发生在不仅限于堆栈的任何区域。比如堆或者 bss。堆栈溢出仅限于覆盖堆栈上的返回地址,但是不覆盖返回地址的正常溢出可能只覆盖其他局部变量。

1. 基于堆栈的缓冲区溢出 当程序写入程序调用堆栈上的内存地址超出预期的数据结构固定长度缓冲区时发生。 · 基于堆栈的编程特点 1. “堆栈”是一个分配自动变量的内存空间。 2.函数参数是在堆栈上分配的,系统不会自动初始化它们,所以在初始化之前它们都是垃圾。 3.一旦函数完成其循环,对堆栈中变量的引用将被删除。(也就是说,如果函数被多次调用,那么它的局部变量和参数将在每次调用和退出函数时被重新创建和销毁。)
•攻击者利用基于堆栈的缓冲区溢出,通过覆盖以各种方式操纵程序
1.一个局部变量,位于堆栈内存中的缓冲区附近,用于改变程序的行为,从而使攻击者受益。
2.堆栈帧中的返回地址。一旦函数返回,执行将在攻击者指定的返回地址恢复,通常是用户输入填充的缓冲区。 函数指针或异常处理程序,随后执行。 ‧克服这些漏洞的因素如下:
1. 地址中的字节为空 2. shell 代码位置的可变性 3. 环境 Shell 代码之间的差异是利用软件漏洞的一小部分代码。

堆缓冲区溢出

在堆数据区域中发生。 •当应用程序向缓冲区复制的数据多于设计缓冲区所包含的数据时,就会发生溢出。 •如果在没有首先核实数据源是否适合目的地的情况下将数据拷贝到缓冲区,则容易受到利用。 基于堆栈和基于堆的编程的特点: •“堆”是分配动态对象时的“空闲存储”,即内存空间。 堆是动态分配的 new ()、 malloc ()和 calloc ()函数的内存空间。 •动态创建的变量(即声明的变量)在执行前在堆上创建,并存储在内存中,直到对象的生命周期结束。 •进行剥削 通过破坏数据来覆盖内部结构,例如链表指针。 •交换指针以覆盖程序功能

让我用一个更简单的方法来解释 RAM 的示意图。在开始阅读之前,我建议先阅读 StackFrame,堆内存。

正如您所看到的,假设它是堆栈,堆栈将向下增长(以箭头显示)。内核代码、文本、数据都是静态数据,因此它们是固定的。动态堆部分向上增长(用箭头显示)。

enter image description here