[摘要]文本区 +--------------------------------------+ (内存低址) 这里需要说明的是: i) 随着函数调用层数的增加, 函数栈帧是一块块地向内存低地址方向延伸的....
文本区
+--------------------------------------+
(内存低址)
这里需要说明的是:
i) 随着函数调用层数的增加, 函数栈帧是一块块地向内存低地址方向延伸的.
随着进程中函数调用层数的减少, 即各函数调用的返回, 栈帧会一块块地
被遗弃而向内存的高址方向回缩.
各函数的栈帧大小随着函数的性质的不同而不等, 由函数的局部变量的数目决定.
ii) 进程对内存的动态申请是发生在Heap(堆)里的. 也就是说, 随着系统动态分
配给进程的内存数量的增加, Heap(堆)有可能向高址或低址延伸, 依赖于不
同CPU的实现. 但一般来说是向内存的高地址方向增长的.
iii) 在BSS数据或者Stack(栈)的增长耗尽了系统分配给进程的自由内存的情况下,
进程将会被阻塞, 重新被操作系统用更大的内存模块来调度运行.
(虽然和exploit没有关系, 但是知道一下还是有好处的)
iv) 函数的栈帧里包含了函数的参数(至于被调用函数的参数是放在调用函数的栈
帧还是被调用函数栈帧, 则依赖于不同系统的实现),
它的局部变量以及恢复调用该函数的函数的栈帧(也就是前一个栈帧)所需要的
数据, 其中包含了调用函数的下一条执行指令的地址.
v) 非初始化数据(BSS)区用于存放程序的静态变量, 这部分内存都是被初始化为零的.
初始化数据区用于存放可执行文件里的初始化数据.
这两个区统称为数据区.
vi) Text(文本区)是个只读区, 任何尝试对该区的写操作会导致段违法出错. 文本区
是被多个运行该可执行文件的进程所共享的. 文本区存放了程序的代码.
2) 函数的栈帧.
函数调用时所建立的栈帧包含了下面的信息:
i) 函数的返回地址. 返回地址是存放在调用函数的栈帧还是被调用函数的栈帧里,
取决于不同系统的实现.
ii) 调用函数的栈帧信息, 即栈顶和栈底.
iii) 为函数的局部变量分配的空间
iv) 为被调用函数的参数分配的空间--取决于不同系统的实现.
3) 缓冲区溢出的利用.
从函数的栈帧结构可以看出:
由于函数的局部变量的内存分配是发生在栈帧里的, 所以如果我们在某一个函数里定义
了缓冲区变量, 则这个缓冲区变量所占用的内存空间是在该函数被调用时所建立的栈帧里.
由于对缓冲区的潜在操作(比如字串的复制)都是从内存低址到高址的, 而内存中所保存
的函数调用返回地址往往就在该缓冲区的上方(高地址)--这是由于栈的特性决定的, 这
就为复盖函数的返回地址提供了条件. 当我们有机会用大于目标缓冲区大小的内容来向
缓冲区进行填充时, 就有可以改写函数保存在函数栈帧中的返回地址, 从而使程序的执
行流程随着我们的意图而转移. 换句话来说, 进程接受了我们的控制. 我们可以让进程
改变原来的执行流程, 去执行我们准备好的代码.
这是冯.诺曼计算机体系结构的缺陷.
下面是缓冲区溢出利用的示意图:
i) 函数对字串缓冲区的操作, 方向一般都是从内存低址向高址的.
如: strcpy(s, "AAA.....");
s s+1 s+2 s+3 ...
+---+---+---+--------+---+...+
(内存低址)
关键词:编写自己的缓冲区溢出运用程序