缓冲区溢出保护方法

文档序号:9667698阅读:541来源:国知局
缓冲区溢出保护方法
【技术领域】
[0001] 本发明涉及计算机技术领域,具体涉及一种缓冲区溢出保护方法。
【背景技术】
[0002] 堆栈作为程序中必不可少的内容,程序在运行时,内存中会开辟出一块连续的栈 空间,用于维护函数调用时所必须的上下文信息,包括旧的帧指针、返回地址、调用参数和 局部变量等。程序可以将上下文信息压栈,也可以从栈顶弹出。然而缓冲区一旦分配完成, 大小和地址便固定下来。当使用缓冲区时,如果操作超出缓冲区边界的区域,便可能会发生 栈缓冲区域溢出。缓冲区溢出攻击包括栈溢出、堆溢出、格式化字符串攻击等攻击类型。其 防护手段包括静态的数组边界检查、堆栈的不可执行、动态的缓冲区溢出监测以及库函数 的安全增强等。而相比堆缓冲区溢出和格式化字符串攻击的漏洞,栈缓冲区溢出漏洞仍占 多数,且攻击者利用栈缓冲区溢出漏洞的手段多样化,攻击更隐蔽。
[0003] 栈溢出一般会导致函数返回地址、栈帧指针等改变,进而导致程序控制流篡改、系 统宕机等。针对此问题,目前提出的普遍做法是通过在栈中添加栈保护(StackGuard)标签 来保证栈的完整性、建立双栈结构将控制流信息和数据流信息完全分离、栈帧指针加密等。
[0004] 但是,目前堆栈信息的保护大多都是基于缓冲区溢出攻击中的某一种进行保护, 不能全面的解决缓冲区溢出问题。再者目前的双栈结构等其在兼容性和性能方面仍然是一 个很大的不足,有时会导致性能等方面的大幅下降。

【发明内容】

[0005] 本发明所要解决的技术问题是针对现有技术中存在上述缺陷,提供一种兼容安 全、高效、全面的缓冲区溢出保护方法。
[0006] 根据本发明,提供了一种缓冲区溢出保护方法,包括:根据原始栈形成一个备份 栈,其中备份栈备份了函数返回地址和堆栈帧指针,而且备份栈在调用函数入口处备份控 制流信息;在函数调用返回时通过比较原始栈与备份栈信息来判断是否有溢出发生。
[0007] 优选地,所有进程都有共享库中代码;在基础库链接过程中,不把所述共享库拷贝 到输出文件,而是使得所有进程共享一份它们用到的共享库中的例程的拷贝。
[0008] 优选地,通过设计一个库来实现在调用函数入口处备份控制流信息。
[0009 ]优选地,所述库中定义了一个静态数组用于保存控制流信息。
[0010]优选地,所述库中的函数实现栈的压入和弹出操作,以及监测到控制流信息被修 改时的处理机制。
[0011]优选地,所述库包括第一函数和第二函数;其中第一函数在被编译程序的每个函 数的入口处被调用,第一函数的输入为当前函数的帧指针指向的内存位置的内容和返回地 址;第二函数在被编译程序的每个函数的出口处被调用,其中第二函数的输入为当前函数 的帧指针指向的内存位置的内容和返回地址。
[0012]优选地,第一函数和第二函数被插入在目标函数的头部和尾部的第一条指令前和 最后一条指令后。
[0013] 本发明提出的采用备份控制流信息方案的缓冲区溢出保护方法,既对堆栈中关键 的控制流信息做了保护,又保证了不同平台的兼容性问题,并且也保证了程序的性能问题。
【附图说明】
[0014] 结合附图,并通过参考下面的详细描述,将会更容易地对本发明有更完整的理解 并且更容易地理解其伴随的优点和特征,其中:
[0015]图1示意性地示出了根据本发明优选实施例的缓冲区溢出保护方法的流程图。 [0016]图2a和图2b示意性地示出了根据本发明优选实施例的缓冲区溢出保护方法采用 的备份控制流信息的示意图。
[0017] 需要说明的是,附图用于说明本发明,而非限制本发明。注意,表示结构的附图可 能并非按比例绘制。并且,附图中,相同或者类似的元件标有相同或者类似的标号。
【具体实施方式】
[0018] 为了使本发明的内容更加清楚和易懂,下面结合具体实施例和附图对本发明的内 容进行详细描述。
[0019] 本发明提出方案是对关键的控制流信息进行备份,在程序运行时比较备份值和原 始值来判断是否有攻击行为产生。
[0020] 具体地,图1示意性地示出了根据本发明优选实施例的缓冲区溢出保护方法的流 程图。
[0021] 如图1所示,根据本发明优选实施例的缓冲区溢出保护方法包括:
[0022] 第一步骤S1:根据原始栈(例如图2a所示的原始栈),形成一个备份栈(例如图2b所 示的备份栈),其中备份栈备份了函数返回地址和堆栈帧指针,而且备份栈在调用函数入口 处备份控制流信息;
[0023] 第二步骤S2:在函数调用返回时通过比较原始栈与备份栈信息来判断是否有溢出 发生。
[0024] 在本发明的【具体实施方式】中,可以通过设计一个库来实现备份关键的控制流信 息。库中定义了一个静态数组__retarray保存控制流信息,库中的函数实现栈的压入和弹 出操作,以及监测到控制流信息被修改时的处理机制。其主要函数实现示例可以如算法1和 算法2所示。
[0025] 下面给出具体的算法示例。
[0026] 备份函数入口处实现的算法具体实现算法如算法1:
[0027]
[0028] 备份函数出口处实现的算法具体如算法2:
[0029]
[0030]
[0031] 函数__retarray_p;rolog在被编译程序的每个函数的入口处被调用,其输入为当 前函数的帧指针指向的内存位置的内容和返回地址。__retarray_epilog函数在被编译程 序的每个函数的出口处被调用。__retarray_epi1og函数输入为当前函数的帧指针指向的 内存位置的内容和返回地址,将该输入与数组_retarray中保存的内容做比较,如果相同, 则表明堆栈中控制流信息未被篡改,否则有攻击行为发生。
[0032] 本方法能够以动态库方式实现,其中所有进程都有共享库中代码;基础库链接过 程中并不把共享库拷贝到输出文件,而是所有进程共享一份它们用到的共享库例程的拷 贝,从而可以节省大量的存储空间。而若某个进程修改了全局变量_retarray,则该进程获 得该变量的一个副本,副本中保存了其对应变量的私有数据信息。这样,即使是某个函数的 控制流信息被篡改,也不会影响其它函数对应保存的信息。因此,备份栈__ retarray不会有各进程之间冲突的问题。而攻击者要想突破此种防御机制,必须同时修改 当前堆栈中的备份信息以及_retarray中对应的备份信息,这显然增加了攻击的难度。
[0033] 以具体程序为实例,左边是程序设计人员正常编写的程序。而右边的程序则是编 译器使用了控制流信息备份补丁后得到的代码布局情况,其是对程序设计人员透明地在每 个函数的头部和尾部的第一条指令前和最后一条指令后自动插入retarray_prolog和 retarray_epilog两个函数调用。
[0035] 本发明的特征之一是:提出了部分控制流信息备份的方法,将原始堆栈中一些关 键的控制流信息保存在一个备份栈中。程序运行至每个函数的入口处,把栈中存放的当前 函数的返回地址和帧指针备份至内存的另一区域。
[0036] 本发明的特征之二是:提出了用动态库的方法实现该备份工作。所有进程都有共 享库中代码。基础库链接过程中并不把共享库拷贝到输出文件,而是所有进程共享一份它 们用到的共享库例程的拷贝,从而可以节省大量的存储空间。
[0037]在本发明中,通过备份控制流信息,尽可能的避免了恶意程序对控制流信息的篡 改。同时,相比于双栈与单栈结构,避免了对体系结构的改动,对兼容性和程序实现的复杂 度做了综合权衡。在安全性方面,其对栈缓冲区的溢出的问题其可以对返回地址的直接攻 击、帧指针的间接攻击、指针篡改控制流等均能正确防护。在性能方面,动态库方式的实现 在保证了性能损耗在5%以下。在兼容性方面,采用数组来保存备份信息,故不会导致兼容 性问题。
[0038]此外,需要说明的是,除非特别指出,否则说明书中的术语"第一"、"第二"、"第三" 等描述仅仅用于区分说明书中的各个组件、元素、步骤等,而不是用于表示各个组件、元素、 步骤之间的逻辑关系或者顺序关系等。
[0039]可以理解的是,虽然本发明已以较佳实施例披露如上,然而上述实施例并非用以 限定本发明。对于任何熟悉本领域的技术人员而言,在不脱离本发明技术方案范围情况下, 都可利用上述揭示的技术内容对本发明技术方案作出许多可能的变动和修饰,或修改为等 同变化的等效实施例。因此,凡是未脱离本发明技术方案的内容,依据本发明的技术实质对 以上实施例所做的任何简单修改、等同变化及修饰,均仍属于本发明技术方案保护的范围 内。
【主权项】
1. 一种缓冲区溢出保护方法,其特征在于包括: 根据原始栈形成一个备份栈,其中备份栈备份了函数返回地址和堆栈帧指针,而且备 份栈在调用函数入口处备份控制流信息; 在函数调用返回时通过比较原始栈与备份栈信息来判断是否有溢出发生。2. 根据权利要求1所述的缓冲区溢出保护方法,其特征在于,所有进程都有共享库中代 码;在基础库链接过程中,不把所述共享库拷贝到输出文件,而是使得所有进程共享一份它 们用到的共享库中的例程的拷贝。3. 根据权利要求1或2所述的缓冲区溢出保护方法,其特征在于,通过设计一个库来实 现在调用函数入口处备份控制流信息。4. 根据权利要求3所述的缓冲区溢出保护方法,其特征在于,所述库中定义了一个静态 数组用于保存控制流信息。5. 根据权利要求3所述的缓冲区溢出保护方法,其特征在于,所述库中的函数实现栈的 压入和弹出操作,以及监测到控制流信息被修改时的处理机制。6. 根据权利要求3所述的缓冲区溢出保护方法,其特征在于,所述库包括第一函数和第 二函数;其中第一函数在被编译程序的每个函数的入口处被调用,第一函数的输入为当前 函数的帧指针指向的内存位置的内容和返回地址;第二函数在被编译程序的每个函数的出 口处被调用,其中第二函数的输入为当前函数的帧指针指向的内存位置的内容和返回地 址。7. 根据权利要求6所述的缓冲区溢出保护方法,其特征在于,第一函数和第二函数被插 入在目标函数的头部和尾部的第一条指令前和最后一条指令后。
【专利摘要】本发明提供了一种缓冲区溢出保护方法,包括:根据原始栈形成一个备份栈,其中备份栈备份了函数返回地址和堆栈帧指针,而且备份栈在调用函数入口处备份控制流信息;在函数调用返回时通过比较原始栈与备份栈信息来判断是否有溢出发生。
【IPC分类】G06F21/56, G06F21/52
【公开号】CN105426752
【申请号】CN201510828343
【发明人】马晓东, 谢汶兵, 漆锋滨, 尉红梅, 翟彦河, 陈茜
【申请人】无锡江南计算技术研究所
【公开日】2016年3月23日
【申请日】2015年11月24日
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1