




已阅读5页,还剩47页未读, 继续免费阅读
(计算机软件与理论专业论文)cc程序中内存访问越界的静态检测方法研究.pdf.pdf 免费下载
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
摘要 c 语言的灵活性使得c 程序中存在丈量安全隐患。根据分布式软件系统中各种 安全漏洞的出现频度和危害程度,本文选择c 语言编写的源程序作为分析对象, 分析并检测其中访问控制相关的软件安全漏洞。首先,对数组越界和缓冲区溢出 这两类主要内存访问漏洞的本质特性进行分析,并采用给语法结构添加属性的方 式对安全漏洞进行抽象描述。接着,根据课题的总体解决方案,改进内存访问越 界的已有检测方法,给出了基于静态程序分析的安全检测方法。最后结合程序 分析提供的基本程序信息,实现了检测c 程序中内存访问越界漏洞的安全分析器。 关键词:安全漏洞内存访问数组越界缓冲区溢出静态检测 a b s t r a c t t h e r ea r em a n ys a f e t yf a u l t s i ncp r o g r a m sd u et 0t h ef l e x i b i l i t yo fcl a n g u a g e a c c o r d i n gt ot h ef r e q u e n c ya n dr i s ko fs a f e t yv u l n e r a b i l i t i e si nd i s t r i b u t e ds o f t w a r ea n d s y s t e m ,cs o u i c oc o d ei ss e l e c t e da st h eo b j e c t ,a n dt h es a f e t yv u l n e r a b i l i t i e sr e l a t e dt o a c c e s sc o n t r o la r ea n a l y z e da n dc h e c k e d f i r s t l y , t h es u b s t a n t i a lc h a r a c t e r so ft h et w o k i n d so fp r i m a r ym e m o r ya c c e s sv u i n e r a b i l i t i e sa r ea n a l y z e d ,a n dt h e ni st h ea b s 订a c t d e s c r i p t i o no ft h ev u l n e r a b i l i t i e sb ys y n t a x s t r u c t u r e a p p e n d e d v a r i o u sa t t r i b u t e s s e c o n d l y , t h em e t h o do fv u l n e r a b i l i t i e sc h e c k i n gb a s e do ns t a t i cp r o g r a ma n a l y s i si s p r e s e n t e da c c o r d i n gt ot h ew h o l es c h e m eo ft h ep r o j e c t i t s a ni m p r o v e m e n to ft h e e x i s t i n gp l a n so fm e m o r ya c c e s so v e rb o u n d f i n a l l y , c o m b i n i n gw i t ht h ee s s e n t i a l p r o g r a mi n f o r m a t i o ng i v e nb yp r o g r a ma n a l y s i s ,as a f e t ya n a l y z e ri si m p l e m e n t e dt o d e t e c tm e m o r ya c c e s so v e rb o u n dv u l n e r a b i l i t i e s k e y w o r d s :s a f e t yv u l n e r a b i l i t y b u f f e ro v e r f l o w m e m o r ya c c e s sa r r a yo v e rb o u n d s t a t i cd e t e c t i o n 创新性声明 y 1 0 0 t s 0 7 7 本人声明所呈交的论文是我个人在导师指导下进行的研究工作及取得的研究 成果,尽我所知,除了文中特鄹加以标注和致谢中所罗列的内容以外,论文中不 包台其他入已经发表或撰写过的研究成果;也不包含为获得西安电子科技大学或 其他教育机构的学位或证书雨使用过的材料。与我一同工作的同志对本研究所做 的贡献均已在论文中做了明确的说明并表示了谢意。 申请学位论文与资料若有不实之处,本人承担一切相关责任。 本人签名: 奎! 望 日期 1 扩口妒,o 授权书 本人完全了解西安电子科技大学有关保留和使用学位论文的规定,即:研究 生在校攻读学位期间论文工作的知识产权单位属西安电子科技大学。本人保证毕 业离校后,发表论文或使用论文工作成果时署名单位仍然为西安电子科技大学。 本人授权西安电子科技大学图书馆保存学位论文,本学位论文属于型雠保 密级别) ,在,年解密后适用本授权书,并同意将论文在互联网上发布。 本人签名:歪邀日期: 芝望:! :! ! 导师签名:丝 第一章绪论 第_ 章绪论 1 1 研究背景 随着网络技术的发展和自由软件的广泛使用,软件安全m u 0 l 】已经成为影响计 算机安全的一个重要问题,特别是军事领域中的软件系统对安全性的要求更高。 由于软件系统中总是存在大量的安全隐患,如人为的系统入侵和信息窃取,以及 由于程序设计语言的自身语言机制存在问题而造成的安全漏洞等,使得软件系统 的安全性和可靠性都受到影响。从而,在软件系统的使用过程中会出现意想不到 的软件故障i n n s a 0 2 1 ,对系统本身及外界环境都造成重大损失。 对于自主开发的软件中存在的各种不安全因素,主要的解决方法就是对软件 系统进行测试。这就需要测试人员对软件系统的功能、特性等都必须深刻了解, 测试效率还严重依赖于依据软件系统特性而设计的测试集的完备性。随机出现的 程序错误,使得有限次的程序测试不一定能够成功捕获。软件系统日益庞大,程 序状态空间也随之急剧增长,测试集的设计将越来越难以覆盖程序状态空间和执 行路径。另外,动态测试的方法也不适用于可重用软件。因此,如何在静态( 程 序不运行) 时尽量检测出软件系统中的安全问题,避免不必要的损失,成为当前 计算机软件安全研究领域中的一个重要课题。 由于军事应用领域软件系统要求具有很高的安全性,软件系统安全性分析工具 可以被广泛地应用于军事应用软件分析中,以提高软件系统自身的安全性。本课 题所研究的软件安全分析方法,具有一定的普遍性,可以被其它领域,如程序理 解、信息安全、逆向工程、遗产继承等应用或借鉴。 1 2 总体解决方案 现有的软件安全分析方法中,动态测试是复杂程度最低的,但性能较差,而形 式化验证的方法的抽象层次和复杂程度最高,但检查效率是最好的。最早出现的 形式化验证方法为定理证明【s c h0 0 ( t h e o r e mp r o v i n g ) ,是基于程序逻辑中的公理 和推理规则的形式化验证方法:八十年代初,e c l a r k e 等人提出了基于自动机理 论的模型检验【c l a 蚓( m o d e lc h e c k i n g ) 方法,此形式化方法用于验证程序的正确 性;1 9 9 7 年,卡奈基梅隆大学的g e o r g ec n e c u l a 提出了携带验证代码【n e o ”j ( p i 【斌q 吗面g c o d e ,p c c ) 技术,用于代码提供者和使用者之间的验证;随着网络 技术的发展,出现了一种基于类型推理的信息流验证和检测方法。 目前验证软件安全性的主流方法是基于程序分析的安全性检查,它已成为软件 安全领域研究的熟点。基于程序分析的软件安全性检测方法是将程序分析技术与 c c + + 程序中内存访问越界的静态检测方法研究 软件安全故障模式相互结合发展而来的一种静态检测软件安全故障的方法,利用 词法分析、语法分析处理源程序,提取程序基本信息,在此基础上进行控制流分 析、数据流分析以及依赖分析,建立程序依赖图和系统依赖图作为下一步安全性 分析的基础。通过对分布式环境中出现的各类软件安全漏洞的分析,提取软件安 全故障模式的数学模型和实现模型,并在安全故障模式的指导下,对源程序进行 安全性分析,检测并定位软件系统中的安全隐患。基于程序分析的软件安全性检 测方法的复杂程度和效率都介于动态测试和形式化验证方法之间,具有性能消耗 比高、自动化程度高、对使用人员素质要求低、可检测安全漏洞范围广等特点。 课题研究的安全分析工具采用图1 1 所示的安全分析模型。此模型的特点在于, 它将与安全相关的具体模式从程序分析串剥离船来i 使安全模式相对独立、便于 扩充,也便予以不同的方法解决最适于解决的阀题。 图1 1 简化的安全分析模型 安全性分析工具主要分为程序分析器和安全分析器两部分。程序分析器是整个 分析工具的前端,负责对c c 十+ 源程序进行分析处理,提取其中安全相关的程序 信息,以便于使用的形式提供给安全分析器,并为安全分析器提供程序分析入口。 安全分析器是分析工具的后端,利用程序分析器提供的基本程序信息,在安全模 式的指导下对源程序中潜在的安全漏洞进行检测和定位。课题选择的研究对象为 c c + + 语言,所以分析工具的输入为c c 抖源程序,进行安全分析后的输出结果分 为两部分:安全性分析报告是对输入源程序文件中潜在安全漏洞的总结性报告; 标记后的c c + + 源程序是对源程序中的安全漏洞进行注释性标记后的程序文件。 第一章绪论 1 3 论文的主要工作 分布式环境的软件系统具有多样性和复杂性的特点,这也使得系统中存在各种 各样的软件安全漏洞,要解决所有这些问题几乎是不可能的。根据安全漏洞的表 现形式和出现频度,以及对系统造成的危害程度,课题确定了若干种比较重要和 具有代表性的安全漏洞来进行研究和解决。 本论文所做的工作是“安全分析器”的一部分,主要是研究c 程序中内存访问 越界的静态检测。c 语言具有高度灵活的特性,允许程序员直接对低端内存进行操 作和访问。然而,c 语言在带来灵活的控制能力的同时,也带来一些安全性问题, 如指针的非法使用就会引起内存访问越界等安全漏洞。所以,本文选择c 语言编 写的源程序作为分析的对象,确定程序中类型机制相关的访问控制漏洞,对漏洞 特性进行抽象归纳,并构建安全规则。主要研究内容包括: l 、对c 语言类型机制和访问控制特性的分析 2 、对数组边界检查方法的研究 3 、对缓冲区溢出特性及检测方法的研究 4 、设计并实现c 程序内存访问越界的静态检测方案 另外,本人还对分布式环境相关的信息流问题进行了初步研究,为本课题后续 工作的进行做了一定铺垫。 1 4 论文组织 本文的章节安排如下:第一章对项目研究背景和总体解决方案进行简要介绍, 并对论文的主要工作做了简要描述。第二章是对安全模式的简要介绍,包括安全 模式相关的概念和安全模式在课题中的地位等。第三章描述了内存访问越界的两 种主要形式,即数组或指针访问越界和缓冲区溢出,对问题本质特性进行了分析 和归纳。介绍了当前解决这两种安全问题的关键技术和解决方案,提出了c 程序 中内存访问越界的静态检测方案。第四章是第三章中提出的静态检测方案的实现。 利用程序分析提供的基本程序信息,结合程序分析器实现针对c 程序内存访问越 界的安全分析器。最后是对本文的概括和总结。 第二章安全模式简介 第二章安全模式简介 2 1 不安全的c c + + 程序 c c + + 语言是目前应用最为广泛的程序设计语言,大量的软件都是以它为主要 的程序设计语言。这是因为c 语言具有其它语言不可比拟的特点,如简单灵活、 效率高、可移植性好、硬件控制能力强以及表达和运算能力强等。c 抖语言是对c 语言的扩充,向下兼容c 语言,因此也具有上述特点。在提供足够灵活性的同时, 也要付出一定代价,即c 语言的弱类型机制,这就使语言的安全性能大大降低。 所以,c c + + 源程序与其它语言( 如a r i a 和j a v a ) 的源程序相比,可能存在更多的 安全问题。 软件安全受到的重视程度日益提高,c ,c + + 程序的安全问题也备受关注,特别 是c 语言的弱类型机制和c + + 语言的面向对象机制所带来的安全问题。比如,c 程序中的数组访问越界、内存泄漏、野指针、缓冲区溢出、隐式类型转换等错误, c + + 程序中对象的构造与析构导致的资源泄漏等问题。这些问题都与程序的动态运 行相关,并可能会对系统的正常运行造成重大影响。比如,内存非法读写和内存 泄漏会使程序运行状态不确定,甚至导致系统瘫痪。 在人们提出的各种解决方法中,静态分析就是一种广泛使用的方法。静态分析 是对程序源代码进行静态扫描和检测,以避免运行时检测对系统造成的损失。本 课题就是采用基于程序分析技术的静态检测方法,通过对c c + + 源程序的静态分 析来发现安全问题并给出相应警告或错误信息。因此,本课题开发的静态分析工 具也可以作为动态测试的前期辅助工具,以减少测试路径并避免由于系统的不适 当运行而造成的不必要损失。 2 2 安全模式相关介绍 为了论述的方便和需要,引入如下三个术语:安全漏洞、安全模式和安全漏洞。 源程序中可能造成安全性故障的程序元素被称为安全漏洞;对安全漏洞的形式化 描述被称为安全模式( 实际应为安全故障模式) :安全模式在软件安全模式分析器 中的实现被称为安全规则。下面将对这三个术语分别进行详细说明。 2 2 1 安全漏洞 安全漏洞是指源程序中可能造成安全性故障的程序元素,即存在安全隐患的各 c ,c + + 程序中内存访问越界的静态检测方法研究 种程序表现。比如,数组访问越晃就是编译器能够编译通过,但运行时可能会造 成安全问题的一种安全漏洞,呆例程序如图2 1 所示。 图2 1 中的程序代码就是安全漏洞的实例。程序中定义的整型数组大小为5 , 接下来的代码中,分别出现了给整型变量x 赋值为数组元素g 】和绘数组元素小2 】 赋值为1 0 。此段代码能够经过编译器正常编译,因为c 语言标准规定数组下标( 即 指针) 可以指向数组边界( 或对象空间) 之外。但实际运行时,程序给x 赋以a 8 的内存空间中的随机值并将a 【_ 2 】的地址值修改为1 0 ,前者可能由于程序中其它代 码使用变量x 而使程序运行状态不稳定,后者可能会因为修改了内存中的重要信 息而造成程序运行结果紊乱甚至运行失败。 上述程序实例属于内存访问越界问题,是此类安全漏洞的一种程序表现形式。 内存访问越界是本文研究的重点,也是此课题所考虑解决的重要问题之一。更为 详细的内存访问越界漏洞分类和分析说明见第三章。 课题研究的主导思想不是找出所有的安全问题,而是找出一些有代表性的并且 给出一种解决这些问题的普遍适用的方法,以对今后的工作具有指导意义。根据 大量的需求调研和文献检索,以及软件领域的工程经验,分布式环境下安全漏滴 大多出表现在以下几个方面: ( 1 )与c c + + 类型机制相关的访问控制问题,如数组越界( 缓冲区溢出) 、 指针非法或无效引用、不加限制的类型转换等; ( 2 )与多进程相关的并发控制问题,如共享内存的不一致、超时死等、缺 少异常处理等: ( 3 )与分布式环境相关的信息流问题,如不明信息的流入或大量信息的流 出等。 c c + + 语言源程序中安全漏洞分析是安全模式和安全规则的基础。所以,要针 对上述三方面安全问题,找到c c + + 源程序中对应的表现形式,通过对不同程序 表现的测试和分析认定其安全漏洞本质。为了利于安全模式的抽象和实现,可以 采用如下两种方式对安全漏洞进行分类:首先按照漏洞的产生机理和危害方式分 类,如缓冲区溢出、内存泄漏等,此分类方式是对问题本质特性的归纳和整理, 便于理解和交流;然后在此基础上,按照对各类安全漏洞可能的处理策略涉及的 第二章安全模式简介 不同编译阶段进行分类,以利于之后安全漏洞检测的实现。 2 2 2 安全模式 安全模式,即安全故障模式,是对安全漏洞的形式化描述。安全模式是对安全 漏洞本质的抽象,不同种类的安全漏洞其抽象层次可以不同,理想情况是采用数 学语言对安全模式进行形式化描述。文法产生式和语义属性 a h o8 6 也可以用来抽象 描述安全模式。例如对于语法问题,可以采用文法产生式的方式描述;对于静态 语义问题可以采用语义属性的方式描述;对于动态语义问题,可以采用指称语 义方式描述等等。 形式化描述方式一般是描述一类问题,如对于数组越界问题,可以使用记录 数组总的空间和已经使用的空间的两个属性来描述;对于指针非法使用问题,可 以使用指针状态属性进行描述。例如在函数调用的产生式中: c a l l _ e x p r s t r i d _ n o d e ( a r g _ l i s t ) i f i d _ n o d e n a n 硷= s t r c p yt h e n i f ( s a f e ( i d _ n o d e ,a r g _ l i s t a u o c ,a r g _ l i s t 1 e n ) 。0 ) t h e ns t a t e e r r o r 产报错+ ) 上述产生式描述的是函数调用为c 语言的标准库函数s l x c p y 时,如果对函数 参数的指针属性值的判断结果为不安全,则给出错误警告的问题。 安全模式的建立与安全漏洞的检测方式密切相关,例如c c + + 中的访问控制性 漏洞,可以利用强类型机制建立安全模式,此处可以借鉴a d z 的类型系统;信息 流方面的安全漏洞,可以通过词法确认( 如s o c k e t 的s e n d r e c e i v e 或m a d v - r i t e , c o r b a 的外部对象方法调用) 和流策略建立安全模式等。因此,可以根据对安全 漏洞的处理策略来建立各类安全漏洞的安全模式。 2 2 3 安全规则 安全规则是安全模式在软件安全模式分析器中的实现。 为了便于将不同的解决方法用于不同的安全问题,本课题的安全分析模型采 用了程序分析和安全模式分离的思想,这样不仅使系统结构清晰,便于课题组人 员分工合作,更使得系统具有很好的可扩充性,即在出现新的安全问题时,只需 扩充安全模式和安全规则,而不必对原有系统进行大规模修改。 安全模式和程序分析的分离是抽象层次上的分离,由于安全规则是安全模式 在安全分析器中的实现,所以安全规则与程序分析的分离就是实现意义上的分离。 c c h 程序中内存访问越界的静态检测方法研究 安全规则在安全分析器中的作用,一方面是指导程序分析提取相应的程序信 息,另一方面是利用这些信息进行安全判定,以确定程序中是否存在安全漏洞。 2 3 安全模式在整个项目中的地位和作用 在图1 1 所示的安全分析模型中,可以看到整个安全分析系统的前端是由两部 分组成的,即程序分析和安全模式,后端是两者结合的安全分析器。前端的程序 分析和安全模式是并行工作的,程序分析从分析的源代码中提取程序信息,给安 全分析器提供一个可用信息平台,安全模式对所要检查的安全漏洞进行分析、归 纳和抽象,构建安全模式的实现模型( 即安全规则) ,以指导程序分析提取有用信 息,并对所关注的程序信息加以判断,从而确定安全漏洞燕否存在。1 经予安全分 析系统后端的安全分析器是程序分析和安全模式两部分的集成和实现,起至n 承主 启下的作用,承上即以程序分析分析提供的程序信息和安全模式提供的安全规则 为输入进行判断,启下即对判断结果进行整理输出,包括安全性分析总结报告和 附有注释信息的c c + + 源程序。 安全模式的主要作用就是归纳概括安全漏洞的本质特性,以抽象的数学模型和 具体的实现模型来指导程序分析的信息提取,并使得安全分析器最终完成安全漏 洞的检测。安全模式对于整个课题的作用是非常重要的,因为整个安全分析系统 最终还是要对程序源代码进行安全分析并确定其中是否存在安全漏洞。 安全模式和程序分析是相对独立和彼此联系的。在整个安全分析系统结构的前 端,二者是并行工作、完全分开的,而在后端二者又协调工作、互为依托,共同 完成安全漏洞的检测工作。不过,程序分析和安全模式还是有区别的。程序分析 是对源代码中所表述的基本程序信息的分析和提取,相对安全模式来说稍偏下层。 安全模式是对软件程序中所潜在的安全漏洞的抽象,源代码只是安全漏洞的外在 表现形式,安全模式的设计和实现对抽象能力的要求更高,所以相对程序分析来 说稍偏上层。 第三章内存访问越界的解决方案 第三章内存访问越界的解决方案 本章阐述c 程序中的内存访问越界漏洞,主要讨论数组或指针访问越界以及缓 冲区溢出问题,分析漏洞的本质特性并给出可行的检测方案。 3 1 内存访问越界 速度、效率和灵活性,都是c 语言的设计初衷,这也是c 语言自发明以来就 大受欢迎并广为流传的原因之一。c 语言允许直接访问低端内存和对指针进行算术 运算,从而使程序员编写出高性能的底层程序。但在c 语言提供足够的灵活性的 同时,它本身也存在很多先天性缺陷,如弱类型机制,致使其安全性和可靠性都 大大降低。c 语言对数组和指针引用不提供任何的边界检查,很容易造成内存访问 越界。一切涉及内存边界检查的工作,都需要由程序员自己来完成,而程序员在 编写程序的时候又最容易忽视这些工作。同时,由于这是语言机制本身的特性, 使得许多错误都无法在编译阶段检测到,所以在诸多的c 程序和系统中都或多或 少地存在着这类安全隐患。 在引起内存访问越界的诸多不安全因素中,就出现频率和造成的危害而言,数 组访问越界和缓冲区溢出可以说是c 程序或系统的最大的安全隐患。所以,本文 将重点分析并解决数组访问越界和缓冲区溢出问题。这两类问题的共同点就是通 过对程序内存区域的越界访问,造成程序运行的不稳定。鉴于它们的不同本质特 性,下文将对这两类问题分别进行阐述。 3 2 数组或指针访问越界 本节将介绍c 语言中的数组或指针访问越界问题。首先是对数组或指针访问越 界问题的概要介绍,接着是问题的不同程序表现形式,最后对此类问题的解决现 状进行了简要介绍。 3 2 1 数组或指针访问越界介绍 在具有数组、指针、局部引用或显式的动态存储管理的语言中,很容易出现内 存访阀错误。c 语言正是具有这些特性的语言,并且c 语言没有提供数组边界检 查和指针引用的安全性检查,所以内存地址空间的访问越界问题在c 程序中是很 常见的。数组或指针访问越界是指访问数组元素( 通过数组名加下标的方式) 或 l oc ,c + + 程序中内存访问越界的静态检测方法研究 指针引用时,对内存地址空间的读取和写入操作超出了其内存空间的边界之外。 m a i n ( v o i d ) i n ta 1 0 】; a 【1 5 】23 ; 产e i t o r + m a i n ( v o i d l c h a r p ; p = ( c h a r ) m a l l o e ( 1 ; f r e e ( p ) ; + ( p + 2 ) = a ;+ e l t o r + ) ( a ) 空闻访问错误( b ) 时间访问错误 图3 1 内存访问错误中的空间和时间访阀错误察鲥 当访问超出内存空间的地址边界之外,就造成空间访河错误。比如数组下标超 出数组空间之外就是典型的空间访阎错误。丽当访问超出内存空间的生命期,就 会造成时间访问错误。典型的时间访阀错误就是堆上分配的内存空间释放后再赋 值。图3 1 为空间访问错误和时间访问错误的实例。本文所要讨论的是空间访问错 误,而时间访问错误部分的工作由廉婷丽来完成和阐述。 3 2 ,2 数组或指针访问越界分类 利用数组或指针访问内存地址空间的越界问题,其具体程序表现多种多样,从 不同的角度,可对其归类如下。 根据对内存地址空间的不同访问方式,可以分为读越界和写越界两种。如果越 界读数据,就会得到不相关数据信息( 导致程序运行范围不确定) ,或者以访问非 法内存的错误( 内存不可读错误) 而终止程序。如果越界写数据,就会修改相邻 m a i n ( v o i d ) ( i n t 墨a 1 0 ; x = a 【1 3 】;,读越界+ a t 1 】= 8 ; 写越界+ , m a i n ( v o i d ) ( i n t + p ,a b 0 ; a 【1 1 】= 6 ; 严显式访问越界+ * ( a - 4 ) = 5 ; 一隐式访问越界+ p 2 a : p 【一2 】- 7 ; 产显式访问越界+ + ( p + 1 3 ) ;9 ;+ 隐式访问越界+ , ) ( a ) 读越界和写越界 ( b ) 显式访问越界和隐式访问越界 图3 2 内存访问越界的不同方式 内存空间的数据,或者以访问非法内存的错误( 内存不可读错误) 而终止程序。 第三章内存访问越界的解决方案 具体程序实例参见图3 2 ( a ) 所示。 访问数组元素时,c 编译器是采用基址加变址的方式来寻址的,即把数组名的 地址当作基址,把数组下标当作交址。所以,c 语言中数组名和数组元素名也就意 味着指针。数组元素地址的具体计算公式为: 数组元素的地址= 数组的基址+ 下标数组元素的大小 例如i n ta 【3 ;则a d d r ( a 2 ) = a d d r ( a ) + 2 + s i z e o f ( i n t ) 。 因此,还可以依据内存访问的程序表现形式,把内存越界访问分为显式内存访 问越界和隐式内存访问越界两种。显式内存访问越界是指通过数组名加下标的方 式访问内存地址空间时,超出了其边晃,也可称为“数组下标方式”。隐式内存访 问越界是指通过指向数组名或数组元素的指针加下标的方式访问内存地址空间 时,超出了其边界,也可称为“指针下标方式”。具体程序实例如图3 2 ( b ) 所示。 3 2 3 数组或指针访问越界检测 访问越界的相关检测方法介绍 在对c 语言特性进行研究的过程中,人们针对c 语言的数组和指针边界检查 问题相继提出了很多算法和解决方法。早期有些专门针对数组边界检查的方法, 比如s u z u k i 和i s h i h a t a 在所有的数组元素访问处都插a - - 个逻辑判定 a u s 州,并使 用定理证明技术来验证是否出现数组越界;s c h w a r z 等人【8 c h 删使用静态数据流分 析信息在编译时证明程序中不存在数组越界;c o u s o t 和其他人提出了抽象解释方 澍8 c n “o ,把数组边界检查看作程序属性执行的自动验证实例等。这些定理证明和 抽象解释的方法都存在抽象层次高、运行代价高的缺点。 在同时处理数组和指针越界的方法中,有改变指针表示和不改变指针表示之 分,此外还有采用标记的方法等。改变指针表示是指修改指针在原有编译过程中 的表示形式,根据边界检查的需要,添加额外的信息,以辅助后续的边界检查工 作。k e n d a l l 的b c c 和s t e f f e n 的r t c c ( r u n - t i m ecc h e c k e r ) 都是采用这种方式i a “ 9 4 1 。其工作实质更类似于代码转换器,将原有代码转换为带有辅助信息的代码系统, 然后对其进行边界检查。m j o n e s 和j k e u y 采用的是用伸展树实现的对象表记录 指针信息的方法,没有改变原有指针的表示形式,通过对g e e 编译器相关库函数等 的修改,以g e e 补丁的形式实现了运行时的边界检查”朔。此方法的性能消耗非 常之大,所以也很不实用。此外,e v a n s 等人通过标记向程序中插入约束信息 e v a 0 2 1 的方法实现了s p l i n t 工具 e v a0 3 1 ,通过系统定义不同标记,由用户或程序员在源代 码中插入不同的标记属性来限定程序元素行为的方式,达到边界检查的目的。由 于此方法对程序员的素质要求较高,检查功能有限,因此也没有得到很好的推广 和应用。 1 2c c + + 程序中内存访问越界的静态检测方法研究 在选用某种方法来进行内存访问边界检查时,如果对程序中出现斡每一处数组 引用或指针引用进行检查,其工作量将是非常大的,而且系统的性能也将很低, 尤其是在存在很多循环或者迭代的系统中更是如此。所以,就需要对所采用的边 界检查方法进行优化。 虽然有很多的数组边界检查优化算法,但可以把它们大致分为两类。第一类是 基于冗余边界检查消除的方法,即在每一处数组引用的地方都进行边界检查,如 果此检查是冗余的再把它消除。静态数据流分析是进行此类优化的常用技术,消 除的检查次数依赖于数据流分析的强度。第二类方法基于不可避免检查测试的插 入,即通过使用数组值域分析,在不确定是否需要进行边界检查的地方直接插入 有用的数组边界检查。这是一种自顶向下的分析方法。 第一种方法尝试消除边界检查次数,并降低检查绘系统运行带来的舞销。如果 某检查包含在另一个检查中,就把其消除。分析的复杂性依赖于所采用的不同算 法。这种方法一般都是关注于把边界检查转移到程序中很少被执行的地方,而不 是消除所有的边界检查。比如,使用循环不变量把边界检查提到循环之外,就将 大大减小边界检查对系统性能的影响,但本质上并不能减少程序源代码中的检查 次数。所以就有个问题:当把数组边界检查从循环的最内层提到循环之外时,使 用复杂的值域分析优化从性价比上来看是否值得? 在第二种方法中,如果通过数据流信息,证实某段代码中运行时不会出现数组 越界问题,就没有必要对该段代码进行检查。如果证实可能会出现问题,就要对 代码进行检查。产生的检查次数是有限的,只是在可能会出现越界访问的代码处 才进行边界检查。用来证明不会出现越界访问所需要的信息也许不能在编译时获 得,这是这种方法的难点,如果这样的话,边界检查仍会留在循环内。 访问越界的相关检测工具介绍 此节将简要介绍一些现有的越界检查相关的软件和工具,并对这些工具所采用 的方法和优缺点进行比较说明。 p u r i f y 是个商用的内存访问检查工具包【p u 80 3 】,p u r i f y p l u s 为其后继版本。它是 个运行时分析工具,主要包括四种功能:内存破坏检测,内存泄漏检测,程序性 能模拟和代码覆盖分析。它并不能检测所有的内存访问漏洞,如对于越过数组边 界访问相邻变量,或者释放后内存空间的再访问问题它都不能检查。p 埘母处理程 序二进制代码,即不需要程序源代码,而是以目标代码为输入,并且也只能处理 二进制代码。它通过一张位图来反应当前的内存使用状态,每次对内存的访问都 要修改此位图。对未初始化和未分配空间区域的访问都会撮错。 s t e f f e n 的r t c c ( r u n - t i m ecc h e c k e r ) 扩展了c 语言编译器p c c ,实现了空 间错误检查的功能5 t e9 2 1 。采用的方法同样是给指针添加对象属性,然而它并不检 查时间访问错误,也没有进行检查优化。 第三章内存访问越界的解决方案 r j o n e sa n dp k e l l y 的g c e e x t e n t i o n s 是采用后向兼容的边界检查技术【刖9 7 1 , 通过使用对象表( 用伸展树实现) 记录指针信息,修改g c c 编译器、修改库函数等 而实现的g c c 编译器的扩展程序( 补丁) 。此工具属运行时检测工具,并且性能开 销非常大。因此,其实用性并不大。 如上提到的这些工具中,都有各自的运行条件或运行环境限制,并且大部分工 具的运行开销都很大( 所测试的程序一般都要比原来慢2 3 倍) 。因此,也只是 用来调试程序,而不用于所要发布的产品系统。 3 3 缓冲区溢出 缓冲区溢出是c 语言缺乏边界检查而引起的又一安全漏洞,其危害性非常大, 也日益受到人们的广泛重视。下面将对缓冲区溢出漏洞进行介绍,分析产生缓冲 区溢出的实质,并介绍一些现有的相关防范及检测措施。 3 3 i 缓冲区溢出介绍 很久以来,缓冲区溢出都是一个众所周知的安全问题。最早也最著名的一个例 子,就是在1 9 8 8 年1 1 月出现的网络蠕虫r o b e r tt m o r r i s 感染了成千上万台和互 联网连接的主机,致使网络大面积瘫痪。后来发现其中的主要复制机制之一就是 由f i n g e r d 守护进程中的缓冲区溢出漏洞引起的【( 的w ,实际就是由于系统调用g e t ( ) 时不检验参数的长度而造成的,使得用户控制下的缓冲区溢出。 图3 3c e r t c c 所提议的安全漏洞数目 从那时起,缓冲区溢出就已经成为软件系统的一个重大并且持续的安全隐患。如 果期间有什么变化的话,也只能说这种缓冲区溢出攻击的情况更加严重了。图3 3 1 4c ,c + + 程序中内存访问越界的静态检测方法研究 是c e r t c c ( c e r t c o o r d i n a t i o nc e n t e r ,c e r t 协调委员会是位于匹兹堡的“软 件工程拚会”的一个部门) 给出的过去十年的有关数据。这些数据表明缓冲区溢 出已经占据现如今安全漏洞的百分之五十以上,并且也显示此比率呈现出不断增 长的趋势。 缓冲区溢出之所以如此常见,是由c 语言固有的不安全性造成的。c 语言对数 组和指针引用不进行边界检查和类型安全检查,而是需要程序员自己确保使用的 安全。更重要的是,c 语言库函数所提供的许多字符串操作,比如s t r c p y o 、s t r c a t 0 、 s p r i n t f o 和g e t s ( ) 等都是不安全的。而几乎所有这些字符串函数处理字符串的方式都 是:搜索源字符串,遇到字符串结束标志,就认为到了字符串的尾部。然后, 把这些字符放到目的缓冲区,对目的缓冲区只要求有一个起始地址,而并不关心 其大小。所以要使用这些c 语言函数编写安全的程序代码是非常困难的。因为程 序员要自己负责检查这些函数的使用,确保不会引起缓冲区溢出,而实际情况往 往是程序员要么忽略了这些检查,要么所进行的检查是错误的。所以说,c 语言所 提供的这些字符串操作库函数缺乏边界检查,是造成缓冲区溢出的主要原因。其 他语言中也会出现缓冲区溢出,但很少见。如果出现这种错误,通常不是由开发 人员造成的,而是运行时环境的错误。 要理解大多数缓冲区溢出的本质,还需要理解程序运行时机器中的内存是如何 分配的。在许多系统上,每个进程都有它自己的虚拟地址空间,系统将这些虚拟 地址空间以某种方式映射到实际内存。此处不关心其具体映射机制,只关心理论 上允许寻址大块连续内存的进程。 假定编译器从操作系统得到一块存储区,用于被编译程序的运行。运行时该存 储区可以划分成块,用以保存如下数据信息: ( 1 ) 产生的目标代码; ( 2 ) 数据对象: ( 3 ) 记住过程活动的控制栈。 产生的目标代码的长度在编译时即可确定,所以编译器可以把臣标代码放在静 态确定的区域中,常常是内存的低地址区。同样,某些数据对象的长度也可以在 编译时获得,因此它们也可以放在静态确定的区域中。为数据对象分配内存空间 时,尽可能进行静态分配,其理由是这样做可以使得对象的地址编译到目标代码 中。 c 语言用拓广的控制栈来实现对函数调用的管理。出现函数调用时,当前函数 的执行被中断,有关机器状态的信息,如程序计数器和机器寄存器的值,就保存 在控制栈中。当控制从调用返回时,恢复有关寄存器的值并把程序计数器置回到 函数调用相邻的下个点,原函数能够继续执行。生存期包含在此次函数调用中 的数据对象可以分配在这个栈中,与活动的其他有关信息放在一起。 第三章内存访问越界的解决方案 运行时,另一个单独的内存区域为堆,它用来保存其它信息。c 语言允许程序 进行显式的内存分配管理,其存储空间就是在堆上。数据放在栈上比放在堆上的 开销要小些,这是由它们对数据的分配和释放方式决定的。程序执行时,栈和堆 的大小都会改变,所以栈和堆分剐位于内存的两端,彼此向对方增长。所以,c 低地址 内 存 地 址 增 长 方 向 高地址 代码段c o d e 数据段d a t a b s s 段 堆h e a p t 堆栈s t a c k 命令行参数 和环境变量 图3 4c 程序的存储空间布局 程序运行时,进程地址空间包含几个不同的内存区域,如图3 4 所示: 程序参数和程序环境,包含命令行参数和环境变量。 堆栈( s t a c k ) ,包含局部变量、函数参数和函数返回值,通常在程序执行时 向下朝堆增长。 堆( h e a p ) ,包含函数调用中动态分配的内存,通常也在程序执行时向上朝 堆栈增长。 b s s 段,包含未初始化的全局可用的数据( 如全局变量) 。 数据段( d a t a ) ,包含初始化的全局可用的数据( 全局变量和s t a t i c 变量) 。 代码段( t e x t ) ,包含只读程序代码,即可执行代码。 b s s 、数据段和代码段组成静态数据区,在程序运行之前,这些段的大小已经 是固定的。与静态内存形成对比,堆栈和堆是动态的程序执行时,它们的大 小可以增大或减小。堆栈和堆大小的改变是运行时内存分配的直接结果。有两种 类型的运行对内存分配方式:堆栈分配和堆分配。访问堆的程序接口因语言面异。 在c 中,堆是通过m a u o c 0 和舭e 0 等相关函数来访问的;而在c + + 中,则是通过 n e w 和d e l e t e 运算符访问堆的。 进程的各个区域段中常常只有代码段t e x t 是只读的,其它几个区域段( 包括数 据段d a t a 、b s s 段、堆h e a p 和堆栈s t a c k ) 都是可读可写的。另外,所有这几个内 c ,c + + 程序中内存访问越界的静态检测方法研究 存段通常都是可执行的,即便是其中并不是可执行代码。 3 3 2 缓冲区溢出分类 写入内存缓冲区中的数据超过缓冲区的边界,就造成缓冲区溢出。如果程序中 出现缓冲区溢出,将对程序的数据信息或控制流信息造成破坏。根据缓冲区所开 辟的空间,造成数据破坏的溢出又可分为静态缓冲区溢出和动态堆溢出。破坏程 序控制流的溢出也可以根据攻击者所采用的不同方式而分为代码植入溢出和代码 重定向溢出。图3 5 就是缓冲区溢出一般分类的树型表示形式。 程序的缓冲区在主存中是连续分配的内存块,向缓冲区中写入过多的数据,并 超过缓冲区的边界,就会导致相邻内存空间中的数据被修改。进程的数据存储在 静态缓冲区或动态堆栈中。 静态缓冲区溢出 静态缓冲区的意思是在进程栈中所开辟的固定大小的缓冲区。声明为a u t o m a t i c 的变量存储在进程栈中。所有局部变量、函数参数和函数返回值也都存储在进 程栈中。如果没有边界检查,就会造成缓冲区溢出,进而造成相邻内存空间中 的数据被破坏。 动态堆溢出 运行时动态分配的存储空间是在堆上开辟的。就像静态缓冲区一样,堆分配的 存储空间也是一块连续的内存。如果不对堆上的缓冲区进行边界检查,也会造 成相邻内存块中的数据被破坏。进程栈中,在堆上分配的存储空间一般都比栈 上分配的要大。 破坏数 溢出 静态缓冲区 溢出 区溢出 破坏控制流 溢出 、 动态堆代码植入 代码重定向 溢出溢出溢出 图3 5 缓冲区溢出的分类树 多数缓冲区溢出攻击都试图破坏进程的控制流。比如,攻击者可以执行程序之 外的任意指令,或者改变程序执行的路径。攻击者达到目的的方式,可能是使用 计算机系统本身的部分代码,或者可能会向计算机系统中插入新的代码来攻击系 统。此部分只简要介绍,不作详细讨论。 代码植入溢出 大多数时候,攻击者要在系统本身的代码中找到一段危险的代码来攻击系统是 p 第三章内存访问越界的解决方案 很不可行的。为了达到此目的,他们会通过静态缓冲区溢出向系统中插入攻击 代码,称这类攻击为代码植入攻击。代码植入是利用缓冲区溢出进行攻击的最 常用方式。 代码重定向溢出 攻击者也可以使用已有代码来攻击系统。比如,攻击者会重颏定向程序来执行 程序中使用的某个库函数,但此函数的执行并非实际程序控制流。此类攻击称 为代码重定向。代码重定向常用在已知的缓冲区空间不足以容纳攻击代码时。 程序缓冲区包括进程栈上的静态缓冲区和堆上的动态缓冲区,如图3 4 所示。 按照缓冲区溢出在程序内存中出现的位置,可以把缓冲区分为堆栈溢出、堆溢出、 b s s 段溢出。这三种缓冲区溢出的表现形式是一样的都是通过调用一些库函 数( 如s g c p y 等) 和对指向缓冲区的指针的操作才造成缓冲区溢出的。下面分别 结合c 程序实例进行分析说明。 堆栈溢出: 堆栈溢出是指发生溢出的缓冲区位于堆栈上。这是最常见的缓冲区溢出,也是 最危害最大的。因为堆栈中靠近缓冲区的内存,存有函数的返回地址。程序运行 时遇到函数调用就在堆栈上开辟空间,这时候进程的堆栈结构如图3 6 所示,其中 保存的主要是如下一些可执行函数的信息: - - p a r a m e t e r 传递给函数的参数,即实参; 一r e t函数返回地址 一s f p栈帧指针( s t a c k f r a m e p o i n t e r ) ,恢复调用该函数的函数的栈帧( 即 前一个栈帧p r e v i o u sf l a m ep o i n t e r ) 所需要的数据,其中包含调用 函数的下一条执行指令的地址。 - - b u f f e r为函数中的临时变量和局部变量所开辟的内存缓冲区。 低地址 内 存 地 址 增 长 方 向 高地址 b u f f e rn b u f f e rl s f p r e t p a r a m e t e rl p a r a m e t e rn 图3 6 进程的堆栈结构 进 程 栈 的 增 长 方 向 越 培c ,c + + 程序中内存访问越界的静态检测方法研究 从图3 6 中可以看出,在函数调用时,其堆栈结构中按照从高地址到低地址的顺 序依次为函数参数p a r a
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025广州银行经营机构人才招聘考前自测高频考点模拟试题及1套参考答案详解
- 深圳 离婚协议书
- 购房协议书 离婚
- 协议书用地 集体
- 待岗协议书属于劳动合同
- 扶贫农场协议书
- 律师的保密协议书
- 三方协议书的应聘意见
- 2025打印机委托保养维修服务合同
- 租公寓协议书
- 《化工设备设计原理与实例》课件
- 新版机动车交通事故责任强制保险合同
- T-CTSS 3-2024 茶艺职业技能竞赛技术规程
- 品管圈PDCA案例-普外科提高甲状腺手术患者功能锻炼合格率
- 2022-2024年营养指导员考试真题及答案合集
- 《电工基础(第2版)》中职全套教学课件
- 2024-2025学年江苏省南通市海安市高二(上)月考物理试卷(10月份)(含答案)
- ISO9001-2015质量管理体系内审培训课件
- 初中物理晋升高级(一级)职称水平考试模拟试卷有答案解析共三套
- CJT 340-2016 绿化种植土壤
- 《无线电失效程序》课件
评论
0/150
提交评论