Pwn 学习笔记(一)

Windows 下的溢出有很多种,比如格式化溢出、整数溢出、堆栈溢出和堆溢出等。而现实中最常利用的是堆栈溢出和堆溢出。所以学习缓冲区溢出,除了堆栈溢出外,还得学习堆溢出


这里的堆不是《数据结构》里说的堆;《数据结构》里的堆是种抽象结构,要求父结点比子结点的值都大(或小);而这里我们说的堆,是Windows 系统中的一种物理结构,用来动态分配和释放对象,用在事先不知道程序所需对象的数量和大小的情况下,或对象太大而不适合堆栈分配程序的时候。英文就是heap。


堆栈溢出和堆溢出,只相差一个字,但内容却完全不同。

堆栈,在可执行程序的text区,是从高地址向低地址扩展,是存放局部变量的地方,在编译时由编译器静态分配。


堆,是在可执行程序的heap 区,从低地址向高地址扩展,是存放由malloc 等函数动态分配数据的地方。其结构关系在内存中的映射如图下图。当然,还有其他的data 区等。




堆栈溢出

在计算机内部,输入数据通常被存放在一个临时空间内,这个临时存放空间就被称为缓冲区,缓冲区的长度事先已经被程序或者操作系统定义好了。向缓冲区内填充数据,如果数据的长度很长,超过了缓冲区本身的容量,那么就会溢出,数据也会溢出存储空间!而装不下的数据则会覆盖在合法数据上,这就是缓冲区和缓冲区溢出的道理。

在理想的情况下,程序检查每个数据的长度,并且不允许超过缓冲区的长度大小。但有些程序会假设数据长度总是与所分配的存储空间相匹配,而不作检查,从而为缓冲区溢出埋下隐患。



堆溢出:

就是给分配的堆拷字符串时超过了所分配的大小,从而造成的溢出。我们也可利用堆的溢出来实现我们想要的功能。在Windows 下,用户要求分配堆时,可以通过一系列函数来完成。可以使用Win32 的堆调用API 函数,或者C/C++运行期库的函数等。

和“堆”有关的几个API 函数

HeapAlloc 在堆中申请内存空间

HeapCreate 创建一个新的堆对象

HeapDestroy 销毁一个堆对象

HeapFree 释放申请的内存

HeapWalk 枚举堆对象的所有内存块

GetProcessHeap 取得进程的默认堆对象

GetProcessHeaps 取得进程所有的堆对象


以上都是用户态的函数,最终都要调用ntdll 里面的Rtl 相关核心函数。比如,堆分配函数的关系如下图。所以,只用考虑RtlAllocateHeap 的就行了。







评论(2)

热度(1)

©TroubleM3 | Powered by LOFTER