《如何解决内存溢出问题.doc

  1. 1、本文档共5页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
《如何解决内存溢出问题

如何解决内存溢出问题? 2004-12-2 17:07:28 在程序员设计的代码中包含的“内存溢出”漏洞实在太多了。本文将给大家介绍内存溢出问题的产生根源、巨大危害和解决途径。? 一、为什么会出现内存溢出问题?? 导致内存溢出问题的原因有很多,比如:? (1)?使用非类型安全(non-type-safe)的语言如?C/C++?等。? (2)?以不可靠的方式存取或者复制内存缓冲区。? (3)?编译器设置的内存缓冲区太靠近关键数据结构。? 下面来分析这些因素:? 1.?内存溢出问题是?C?语言或者?C++?语言所固有的缺陷,它们既不检查数组边界,又不检查类型可靠性(type-safety)。众所周知,用?C/C++?语言开发的程序由于目标代码非常接近机器内核,因而能够直接访问内存和寄存器,这种特性大大提升了?C/C++?语言代码的性能。只要合理编码,C/C++?应用程序在执行效率上必然优于其它高级语言。然而,C/C++?语言导致内存溢出问题的可能性也要大许多。其他语言也存在内容溢出问题,但它往往不是程序员的失误,而是应用程序的运行时环境出错所致。? 2.?当应用程序读取用户(也可能是恶意攻击者)数据,试图复制到应用程序开辟的内存缓冲区中,却无法保证缓冲区的空间足够时(换言之,假设代码申请了?N?字节大小的内存缓冲区,随后又向其中复制超过?N?字节的数据)。内存缓冲区就可能会溢出。想一想,如果你向?12?盎司的玻璃杯中倒入?16?盎司水,那么多出来的?4?盎司水怎么办?当然会满到玻璃杯外面了!? 3.?最重要的是,C/C++?编译器开辟的内存缓冲区常常邻近重要的数据结构。现在假设某个函数的堆栈紧接在在内存缓冲区后面时,其中保存的函数返回地址就会与内存缓冲区相邻。此时,恶意攻击者就可以向内存缓冲区复制大量数据,从而使得内存缓冲区溢出并覆盖原先保存于堆栈中的函数返回地址。这样,函数的返回地址就被攻击者换成了他指定的数值;一旦函数调用完毕,就会继续执行“函数返回地址”处的代码。非但如此,C++?的某些其它数据结构,比如?v-table?、例外事件处理程序、函数指针等,也可能受到类似的攻击。? 好,闲话少说,现在来看一个具体的例子。? 请思考:以下代码有何不妥之处?? void?CopyData(char?*szData)?{? char?cDest[32];? strcpy(cDest,szData);? //?处理?cDest? ...? }?? 奇怪,这段代码好象没什么不对劲啊!确实,只有调用上述?CopyData()?才会出问题。例如:这样使用?CopyData()?是安全的:? char?*szNames[]?=?{Michael,Cheryl,Blake};? CopyData(szName[1]);? 为什么呢?因为数组中的姓名(Michael、Cheryl、Blake)都是字符串常量,而且长度都不超过?32?个字符,用它们做?strcpy()?的参数总是安全的。再假设?CopyData?的唯一参数?szData?来自?socket?套接字或者文件等不可靠的数据源。由于?strcpy?并不在乎数据来源,只要没遇上空字符,它就会一个字符一个字符地复制?szData?的内容。此时,复制到?cDest?的字符串就可能超过?32?字符,进而导致内存缓冲区?cDest?的溢出;溢出的字符就会取代内存缓冲区后面的数据。不幸的是,CopyData?函数的返回地址也在其中!于是,当?CopyData?函数调用完毕以后,程序就会转入攻击者给出的“返回地址”,从而落入攻击者的圈套!授人以柄,惨!? 前面提到的其它数据结构也可能受到类似的攻击。假设有人利用内存溢出漏洞覆盖了下列?C++?类中的?v-table?:? void?CopyData(char?*szData)?{? char?cDest[32];? CFoo?foo;? strcpy(cDest,szData);? foo.Init();? }? 与其它?C++?类一样,这里的?CFoo?类也对应一个所谓的?v-table,即用于保存一个类的全部方法地址的列表。若攻击者利用内存溢出漏洞偷换了?v-table?的内容,则?CFoo?类中的所有方法,包括上述?Init()?方法,都会指向攻击者给出的地址,而不是原先?v-table?中的方法地址。顺便说一句,即使你在某个?C++?类的源代码中没有调用任何方法,也不能认为这个类是安全的,因为它在运行时至少需要调用一个内部方法——析构器(destructor)!当然,如果真有一个类没有调用任何方法,那么它的存在意义也就值得怀疑了。? 二、解决内存溢出问题? 不要太悲观,下面讨论内存溢出问题的解决和预防措施。? 1、改用受控代码?? 2002?

您可能关注的文档

文档评论(0)

1974wangpeng + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档