编程中堆栈溢出和缓冲区溢出有什么不同?
堆栈溢出特指执行堆栈超出为其保留的内存的情况。例如,如果调用一个递归调用自身而没有终止的函数,则会导致堆栈溢出,因为每个函数调用都会创建一个新的堆栈帧,并且堆栈最终将消耗比为其保留的内存更多的内存。
缓冲区溢出是指程序写入超出为任何缓冲区分配的内存末尾(包括在堆上,而不仅仅在堆栈上)的任何情况。例如,如果您写入从堆分配的数组的末尾,则会导致缓冲区溢出。
关键的区别在于知道堆栈和缓冲区之间的区别。
堆栈是为执行程序执行而保留的空间。当您调用函数时,它的参数和返回信息将被放置在堆栈中。
缓冲区是用于单一目的的通用内存块。例如,字符串是缓冲区。它可以通过向字符串写入比分配的更多数据来过度运行。
堆栈溢出:你已经在堆栈上为分配给当前线程的内存放了太多东西
缓冲区溢出:您已超出当前分配的缓冲区的大小,并且未调整大小以适应(或无法进一步调整大小)。
stackoverflow是指线程堆栈的大小超过该线程的最大允许堆栈大小。
缓冲区溢出是指将值写入当前未由程序分配的内存中。
缓冲区溢出通常代表任何时候访问内存缓冲区超出它的边界,无论是堆栈还是堆。堆栈溢出意味着堆栈已超出其分配限制,并且在大多数计算机/ OS上运行堆。
你不是要说“堆栈和缓冲区之间有什么区别?” - 这将使您更快地获得更多洞察力。一旦你走得那么远,那么你可以考虑溢出这些东西意味着什么。
1.基于堆栈的缓冲区溢出•当程序写入程序的调用堆栈上的目标数据结构之外的存储器地址时发生 - 固定长度缓冲区。 •基于堆栈的编程的特征1.“堆栈”是分配自动变量的存储空间。 2.函数参数在堆栈上分配,不会被系统自动初始化,因此在初始化之前它们会有垃圾。 3.一旦函数完成其循环,就会删除对堆栈中变量的引用。 (即,如果多次调用函数,则每次调用和退出函数时都会重新创建和销毁其局部变量和参数。) •攻击者利用基于堆栈的缓冲区溢出通过覆盖以各种方式操作程序 1.一个局部变量,靠近堆栈内存中的缓冲区,用于更改可能使攻击者受益的程序行为。 2.返回堆栈帧中的地址。一旦函数返回,执行将在攻击者指定的返回地址处恢复,通常是用户输入填充的缓冲区。 3.随后执行的函数指针或异常处理程序。 •克服这些漏洞的因素有: 1.地址中的空字节2. shell代码位置的可变性3.环境之间的差异Shell代码是用于利用软件漏洞的一小段代码。
2.堆缓冲区溢出
•在堆数据区域中发生。 •当应用程序将更多数据复制到缓冲区而不是缓冲区设计为包含时,会发生溢出。 •如果将数据复制到缓冲区而不首先验证源是否适合目标,则易于利用。 •基于堆栈和基于堆的编程的特征:•“堆”是一个“自由存储”,它是分配动态对象时的内存空间。 •堆是动态分配new(),malloc()和calloc()函数的内存空间。 •动态创建的变量(即声明的变量)在执行之前在堆上创建并存储在内存中,直到对象的生命周期完成。 •执行利用•通过破坏数据来覆盖内部结构,例如链表指针。 •指针交换以覆盖程序功能
大多数提到缓冲区溢出的人都意味着堆栈溢出。但是,溢出可能发生在任何区域,不仅限于堆栈。如堆或bss。堆栈溢出仅限于覆盖堆栈上的返回地址,但是不会覆盖返回地址的正常溢出可能只会覆盖其他局部变量。