计算机软考网络管理:内存的不同用途

来源:微学计算机考试频道发布时间:2008-08-28
栈溢出利用
  To be the apostrophe which changed“Impossible”into“I’m possible”
  ——failwest
  当软件中存在数组越界等问题时,一切皆有可能。您很快就能够领会到把“Impossible”变成“I’m possible”的那一撇是怎样被写进Windows的。
  1 系统栈的工作原理
  1.1 内存的不同用途
  如果您关注过网络安全问题,那么一定听过缓冲区溢出这个术语。简单说来,缓冲区溢出就是在大缓冲区中的数据向小缓冲区复制的过程中,由于没有注意小缓冲区的边界,“撑爆”了较小的缓冲区,从而冲掉了和小缓冲区相邻内存区域的其他数据而引起的内存问题。缓冲溢出是最常见的内存错误之一,也是攻击者入侵系统时所用到的最强大、最经典的一类漏洞利用方式。
  成功地利用缓冲区溢出漏洞可以修改内存中变量的值,甚至可以劫持进程,执行恶意代码,最终获得主机的控制权。要透彻地理解这种攻击方式,我们需要回顾一些计算机体系架构方面的基础知识,搞清楚CPU、寄存器、内存是怎样协同工作而让程序流畅执行的。
  根据不同的操作系统,一个进程可能被分配到不同的内存区域去执行。但是不管什么样的操作系统、什么样的计算机架构,进程使用的内存都可以按照功能大致分成以下4个部分。
  (1)代码区:这个区域存储着被装入执行的二进制机器代码,处理器会到这个区域取指并执行。
  (2)数据区:用于存储全局变量等。
  (3)堆区:进程可以在堆区动态地请求一定大小的内存,并在用完之后归还给堆区。动态分配和回收是堆区的特点。
  (4)栈区:用于动态地存储函数之间的调用关系,以保证被调用函数在返回时恢复到母函数中继续执行。
  题外话:这种简单的内存划分方式是为了让您能够更容易地理解程序的运行机制。《深入理解计算机系统》一书中有更详细的关于内存使用的论述,如有兴趣可参考之。
  在Windows平台下,高级语言写出的程序经过编译链接,最终会变成第2章介绍过的PE文件。当PE文件被装载运行后,就成了所谓的进程。
  PE文件代码段中包含的二进制级别的机器代码会被装入内存的代码区(.text),处理器将到内存的这个区域一条一条地取出指令和操作数,并送入算术逻辑单元进行运算;如果代码中请求开辟动态内存,则会在内存的堆区分配一块大小合适的区域返回给代码区的代码使用;当函数调用发生时,函数的调用关系等信息会动态地保存在内存的栈区,以供处理器在执行完被调用函数的代码时,返回母函数。这个协作过程
  如果把计算机看成一个有条不紊的工厂,我们可以得到如下类比: CPU是完成工作的工人。
  数据区、堆区、栈区等则是用来存放原料、半成品、成品等各种东西的场所。
  存在代码区的指令则告诉CPU要做什么,怎么做,到哪里去领原材料,用什么工具来做,做完以后把成品放到哪个货舱去。
  值得一提的是,栈除了扮演存放原料、半成品的仓库之外,它还是车间调度主任的办公室。
  程序中所使用的缓冲区可以是堆区、栈区和存放静态变量的数据区。缓冲区溢出的利用方法和缓冲区到底属于上面哪个内存区域密不可分,本章主要介绍在系统栈中发生溢出的情形。