CN104636256B - 一种内存访问异常的检测方法及装置 - Google Patents
一种内存访问异常的检测方法及装置 Download PDFInfo
- Publication number
- CN104636256B CN104636256B CN201510086609.XA CN201510086609A CN104636256B CN 104636256 B CN104636256 B CN 104636256B CN 201510086609 A CN201510086609 A CN 201510086609A CN 104636256 B CN104636256 B CN 104636256B
- Authority
- CN
- China
- Prior art keywords
- function
- memory
- node
- source code
- graph
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Active
Links
Landscapes
- Debugging And Monitoring (AREA)
Abstract
本申请公开了一种内存访问异常的检测方法及装置,对源代码进行排查和词法分析、语法分析以及语义分析,生成控制流图、数据依赖图、第一列表文件和第二列表文件;根据控制流图构建源代码的全局函数调用图,根据全局函数调用图、第二列表文件和数据依赖图,对源代码进行动态内存分配的匹配性检测;构建虚拟执行平台,根据第一列表文件、控制流图和数据依赖图提取执行路径,实现对动态内存分配造成的内存泄露以及程序运行时的内存访问越界的检测操作。通过分析第一列表文件、第二列表文件、控制流图、数据依赖图和全局函数调用图,并构建虚拟执行平台抽取执行路径,可以充分挖掘源代码中存在的内存访问异常,高效地实现对于内存访问异常的检测操作。
Description
技术领域
本申请涉及编译技术领域,特别是涉及一种内存访问异常的检测方法及装置。
背景技术
内存访问异常通常表现为动态内存分配造成的内存泄露,以及程序运行时的内存访问越界。具体的,内存泄漏是指程序利用malloc等函数在运行时向操作系统动态的申请内存空间,由于程序临时退出或程序员并未在源代码内调用free函数进行释放,导致所在进程长期占用内存资源的问题;内存访问越界则是由于程序计算异常、代码书写不规范等导致的越界访问、或对内存的非法篡改的问题。这些问题可能导致程序在运行期出现很难预测的结果,因此,如何尽可能的检测、判断可能存在漏洞,并尽可能的减少误判率是目前的研究热点。
在现有技术中,针对内存访问异常中的动态内存分配造成的内存泄漏问题的检测,通常是在程序运行时,统计全部被分配的内存地址,然后在程序结束时,再次统计其中未被释放的内存块来进行的。然而,由于只能在程序结束时才进行统计与判断,一方面,由于程序中分支结构的存在,程序的一次运行不能覆盖所有的程序分支,有些错误不能通过程序的运行暴露出来,从而在一定程度上降低了检错效率;另一方面,由于它只能反馈未被释放的内存块的首地址,且由于这些首地址一般是指虚拟地址,而程序每次运行时的虚拟地址均是动态处理,也就说这些虚地址除了虚拟页号是相同的,其余的地址是变化的,这不便于程序员查找到内存泄漏的具体位置。
在现有技术中,针对内存访问异常中的程序运行时的内存访问越界问题的检测,通常是对每块独立内存区域进行首尾标记,且在程序运行时反复的进行首尾标记查找以及比较,来实现对于内存访问越界的判断。然而,由于程序在运行时,每次进行内存访问时均需要进行首尾标志符号查找,并判断是否越界,将严重影响程序的执行性能,除此之外,现有技术也无法处理栈溢出的场景。
可见,现有技术无法对内存访问异常的问题进行准确、高效地检测。
发明内容
有鉴于此,本申请实施例提供一种内存访问异常的检测方法及装置,以实现对内存访问异常问题的准确、高效检测。
为了实现上述目的,本申请实施例提供的技术方案如下:
一种内存访问异常的检测方法,包括:
对源代码进行排查和词法分析、语法分析以及语义分析,生成控制流图、数据依赖图、第一列表文件和第二列表文件;所述第一列表文件中包括所述源代码内的静态数组占用的内存的静态内存信息,或所述源代码内的动态分配的内存的动态内存信息;所述第二列表文件中包括所述源代码内的动态内存分配库函数的函数信息;
根据所述控制流图构建所述源代码的全局函数调用图,根据所述全局函数调用图、所述第二列表文件和所述数据依赖图,对所述源代码进行动态内存分配的匹配性检测;
构建虚拟执行平台,根据所述第一列表文件、所述控制流图和所述数据依赖图提取虚拟执行路径,实现对动态内存分配造成的内存泄露以及程序运行时的内存访问越界的检测操作。
优选地,所述对源代码进行排查和词法分析、语法分析以及语义分析,生成控制流图、数据依赖图、第一列表文件和第二列表文件,包括:
调用轻量级静态检测工具对源代码进行初步排查;
对所述源代码进行词法、语法分析,对所述源代码内的静态数组占用、动态申请的内存所占用的字节数、名称进行标记,生成第一列表文件,并对动态内存分配库函数所在的源文件及函数名称、调用参数进行标记,生成第二列表文件;
根据所述源代码的分支跳转和函数调用关系,将所述源代码切分为多个基本块,并分析每个基本块之间的跳转关系,根据所述跳转关系生成控制流图,并根据所述源代码的变量之间的数据依赖关系,生成数据依赖图。
优选地,所述根据所述控制流图构建所述源代码的全局函数调用图,包括:
提取所述控制流图内的函数的内入口基本块、出口基本块,统计所述入口基本块的入度和所述出口基本块的出度,并合并所述入口基本块和所述出口基本块对应的节点,构建节点之间的连接关系,为每一个独立源程序生成一个函数调用图;
遍历第一函数调用图内存在出度且在所述第一函数调用图无后继节点的节点,判断与第二函数调用图内的全局函数节点是否存在调用关系,如果存在,则添加从第一函数调用图到第二函数调用图的有向边;遍历第二函数调用图内存在出度且在所述第二函数调用图无后继节点的节点,判断与第一函数调用图内的全局函数节点是否存在调用关系,如果存在,则添加从第二函数调用图到第一函数调用图的有向边;依次处理每个函数调用图,查找到所有节点的后续节点,并删除标准库函数的后续节点,生成全局函数调用图。
优选地,所述根据所述全局函数调用图、所述第二列表文件和所述数据依赖图,对所述源代码进行动态内存分配的匹配性检测,包括:
根据所述第二列表文件,对所述全局函数调用图内的节点进行区分标记;
提取所述全局函数调用图内的入口函数节点,通过分析所述数据依赖图,向前追溯并提取与所述动态内存分配库函数存在数据依赖的前驱节点,删除其它节点;
将每个提取的节点在所述全局函数调用图中的前驱节点与后继节点重新建立连接关系,且保持逻辑序关系不变,生成精简函数调用图;
如果任意一个节点内存在针对同一变量的动态内存分配库函数,则向该节点添加自旋弧,并删除所述精简函数调用图内由于所述自旋弧出现自闭环的边,对所述源代码进行动态内存分配的匹配性检测。
优选地,所述构建虚拟机平台,包括:
选择目标处理器平台,基于指令集功能特征,建立指令行为级模拟器;
建立所述指令行为级模拟器的过程中,针对条件判断类及分支跳转类指令进行行为级建模时,添加先进后出的堆栈结构;所述堆栈结构用于保存所述条件判断类及分支跳转类指令的内存地址、寄存器内的数据的逆状态。
优选地,所述根据所述第一列表文件、所述控制流图和所述数据依赖图提取虚拟执行路径,实现对动态内存分配造成的内存泄露以及程序运行时的内存访问越界的检测操作,包括:
对程序进行虚拟执行,判断是否出现条件判断类及分支跳转类指令,如果出现,保存所述条件判断类及分支跳转类指令的内存地址、寄存器内的数据的逆状态,并进行入栈;统计当前执行路径下申请和释放的动态内存的字节数,统计对内存的写操作,并把对内存的修改写入栈顶记录所对应的内存状态修改链表内;当程序执行到出口函数时,检查申请和释放的动态内存的字节数是否相同,并根据内存地址,查找导致内存泄露的动态内存分配库函数;检测完成后,从所述堆栈结构内读取一条记录,并对虚拟机的程序指针、内存、寄存器进行恢复;程序运行到栈空为止,实现对动态内存分配造成的内存泄露的检测操作;
获得所述第一列表文件内的静态数组占用以及动态申请的内存的内存记录,在链接期对静态分配的全局数据、局部静态数组分配内存地址,在运行期通过压栈操作计算存储于程序栈内的局部未初始化数组的栈地址的偏移量,并通过动态内存分配库函数的返回值获取动态内存分配的内存块;每一条独立的加载、保存指令在函数内的基本块中首次被执行时,记录访问的内存地址以及所在的内存块,当下一次访问中的目标内存地址不在所述内存块内时,判定为内存访问越界,实现对程序运行时的内存访问越界的检测操作。
一种内存访问异常的检测装置,包括:
分析模块,用于对源代码进行排查和词法分析、语法分析以及语义分析,生成控制流图、数据依赖图、第一列表文件和第二列表文件;所述第一列表文件中包括所述源代码内的静态数组占用的内存的静态内存信息,或所述源代码内的动态分配的内存的动态内存信息;所述第二列表文件中包括所述源代码内的动态内存分配库函数的函数信息;
检测模块,用于根据所述控制流图构建所述源代码的全局函数调用图,根据所述全局函数调用图、所述第二列表文件和所述数据依赖图,对所述源代码进行动态内存分配的匹配性检测;
构建模块,用于构建虚拟执行平台,根据所述第一列表文件、所述控制流图和所述数据依赖图提取虚拟执行路径,实现对动态内存分配造成的内存泄露以及程序运行时的内存访问越界的检测操作。
优选地,所述分析模块,包括:
排查单元,用于调用轻量级静态检测工具对源代码进行初步排查;
分析单元,用于对所述源代码进行词法、语法分析,对所述源代码内的静态数组占用、动态申请的内存所占用的字节数、名称进行标记,生成第一列表文件,并对动态内存分配库函数所在的源文件及函数名称、调用参数进行标记,生成第二列表文件;
生成单元,用于根据所述源代码的分支跳转和函数调用关系,将所述源代码切分为多个基本块,并分析每个基本块之间的跳转关系,根据所述跳转关系生成控制流图,并根据所述源代码的变量之间的数据依赖关系,生成数据依赖图。
优选地,所述检测模块,包括:
提取单元,用于提取所述控制流图内的函数的内入口基本块、出口基本块,统计所述入口基本块的入度和所述出口基本块的出度,并合并所述入口基本块和所述出口基本块对应的节点,构建节点之间的连接关系,为每一个独立源程序生成一个函数调用图;
遍历单元,用于遍历第一函数调用图内存在出度且在所述第一函数调用图无后继节点的节点,判断与第二函数调用图内的全局函数节点是否存在调用关系,如果存在,则添加从第一函数调用图到第二函数调用图的有向边;遍历第二函数调用图内存在出度且在所述第二函数调用图无后继节点的节点,判断与第一函数调用图内的全局函数节点是否存在调用关系,如果存在,则添加从第二函数调用图到第一函数调用图的有向边;依次处理每个函数调用图,查找到所有节点的后续节点,并删除标准库函数的后续节点,生成全局函数调用图。
优选地,所述检测模块,包括:
标记单元,用于根据所述第二列表文件,对所述全局函数调用图内的节点进行区分标记;
分析单元,用于提取所述全局函数调用图内的入口函数节点,通过分析所述数据依赖图,向前追溯并提取与所述动态内存分配库函数存在数据依赖的前驱节点,删除其它节点;
生成单元,用于将每个提取的节点在所述全局函数调用图中的前驱节点与后继节点重新建立连接关系,且保持逻辑序关系不变,生成精简函数调用图;
如果任意一个节点内存在针对同一变量的动态内存分配库函数,则向该节点添加自旋弧,并删除所述精简函数调用图内由于所述自旋弧出现自闭环的边,对所述源代码进行动态内存分配的匹配性检测。
优选地,所述构建模块,包括:
选择单元,用于选择目标处理器平台,基于指令集功能特征,建立指令行为级模拟器;
建立单元,用于建立所述指令行为级模拟器的过程中,针对条件判断类及分支跳转类指令进行行为级建模时,添加先进后出的堆栈结构;所述堆栈结构用于保存所述条件判断类及分支跳转类指令的内存地址、寄存器内的数据的逆状态。
优选地,所述构建模块,包括:
内存泄露检测单元,用于对程序进行虚拟执行,判断是否出现条件判断类及分支跳转类指令,如果出现,保存所述条件判断类及分支跳转类指令的内存地址、寄存器内的数据的逆状态,并进行入栈;统计当前执行路径下申请和释放的动态内存的字节数,统计对内存的写操作,并把对内存的修改写入栈顶记录所对应的内存状态修改链表内;当程序执行到出口函数时,检查申请和释放的动态内存的字节数是否相同,并根据内存地址,查找导致内存泄露的动态内存分配库函数;检测完成后,从所述堆栈结构内读取一条记录,并对虚拟机的程序指针、内存、寄存器进行恢复;程序运行到栈空为止,实现对动态内存分配造成的内存泄露的检测操作;
内存越界检测单元,用于获得所述第一列表文件内的静态数组占用以及动态申请的内存的内存记录,在链接期对静态分配的全局数据、局部静态数组分配内存地址,在运行期通过压栈操作计算存储于程序栈内的局部未初始化数组的栈地址的偏移量,并通过动态内存分配库函数的返回值获取动态内存分配的内存块;每一条独立的加载、保存指令在函数内的基本块中首次被执行时,记录访问的内存地址以及所在的内存块,当下一次访问中的目标内存地址不在所述内存块内时,判定为内存访问越界,实现对程序运行时的内存访问越界的检测操作。
应用本申请的技术方案,对源代码进行排查和词法分析、语法分析以及语义分析,生成控制流图、数据依赖图、第一列表文件和第二列表文件;所述第一列表文件中包括所述源代码内的静态数组占用的内存的静态内存信息,或所述源代码内的动态分配的内存的动态内存信息;所述第二列表文件中包括所述源代码内的动态内存分配库函数的函数信息;根据所述控制流图构建所述源代码的全局函数调用图,根据所述全局函数调用图、所述第二列表文件和所述数据依赖图,对所述源代码进行动态内存分配的匹配性检测;构建虚拟执行平台,根据所述第一列表文件、所述控制流图和所述数据依赖图提取执行路径,实现对动态内存分配造成的内存泄露以及程序运行时的内存访问越界的检测操作。这样,通过分析和构建源代码的第一列表文件、第二列表文件、控制流图、数据依赖图和全局函数调用图,进行动态内存申请、释放的匹配,并构建虚拟执行平台抽取执行路径,可以充分挖掘源代码中存在的内存访问异常,通过建模和虚拟执行可以高效地实现对于内存访问异常的检测操作。
附图说明
为了更清楚地说明本申请实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本申请中记载的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。
图1为本申请实施例提供的一种内存访问异常的检测方法的流程图;
图2为本申请实施例提供的另一种内存访问异常的检测方法的流程图;
图3为本申请实施例提供的又一种内存访问异常的检测方法的流程图;
图4为本申请实施例提供的再一种内存访问异常的检测方法的流程图;
图5为本申请实施例提供的再一种内存访问异常的检测方法的流程图;
图6为本申请实施例提供的一种内存访问异常的检测装置的结构示意图。
具体实施方式
相关术语解释:
动态检测:对于内存访问异常的动态检测方法,需要在程序中插入动态检测代码或断言,在程序的执行过程中及时发现缓冲区溢出漏洞;
控制流图(Control flow graph,CFG)是用在编译器中的一个抽象数据结构。它是一个过程或程序的抽象表现,由编译器在内部维护。每个在控制流图中的节点代表一个基本块,例如,没有任何跳转或跳转目标的基本块;跳转目标以一个块开始,和以一个块结束。每条在控制流图中的有向边,用于代表控制流中的跳转方向,或基本块之间的跳转关系。函数调用图(Func Call Graph,FCG):上述CFG内的节点通常是指发生分支的基本块,而FCG内的节点即是独立的函数;
数据依赖图(data dependence)是指语句之间存在的数据约束关系,如果两个运算操作之间不占用同一变量,又或者它们只读同一变量进行连续的读写,那么执行结果与它们的执行顺序无关,数据依赖图(Data Dependence Graph,DDG)就是描述了不同语句间,同一变量或数据之间的数据依赖关系;
虚拟执行:通常是指在模拟环境下,对目标机器平台的执行,常见的工具包括模拟器、虚拟机等,其中,虚拟机通常还涉及硬件资源的调度与分配,而模拟器通常是纯软件实施。
为了使本技术领域的人员更好地理解本申请中的技术方案,下面将结合本申请实施例中的附图,对本申请实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都应当属于本申请保护的范围。
为了使本技术领域的人员更好地理解本申请方案,使本申请的上述目的、特征和优点能够更加明显易懂,下面结合附图和具体实施方式对本申请作进一步详细的说明。
图1为本申请实施例提供的一种内存访问异常的检测方法的流程图。
参照图1所示,本申请实施例提供的内存访问异常的检测方法,包括:
步骤S11:对源代码进行排查和词法分析、语法分析以及语义分析,生成控制流图、数据依赖图、第一列表文件和第二列表文件;所述第一列表文件中包括所述源代码内的静态数组占用的内存的静态内存信息,或所述源代码内的动态分配的内存的动态内存信息;所述第二列表文件中包括所述源代码内的动态内存分配库函数的函数信息;
在本申请实施例中,本申请提供的内存访问异常的检测方法,参照图2,所述对源代码进行排查和词法分析、语法分析以及语义分析,生成控制流图、数据依赖图、第一列表文件和第二列表文件,包括:
S111:调用轻量级静态检测工具对源代码进行初步排查;
S112:对所述源代码进行词法、语法分析,对所述源代码内的静态数组占用、动态申请的内存所占用的字节数、名称进行标记,生成第一列表文件,并对动态内存分配库函数所在的源文件及函数名称、调用参数进行标记,生成第二列表文件;
S113:根据所述源代码的分支跳转和函数调用关系,将所述源代码切分为多个基本块,并分析每个基本块之间的跳转关系,根据所述跳转关系生成控制流图,并根据所述源代码的变量之间的数据依赖关系,生成数据依赖图。
在本发明提出的技术方案中,对源代码进行预处理和词法分析、语法分析以及语义分析,生成控制流图、数据依赖图,是结合传统编译技术上前端分析实现。在本发明的一个应用实例中,是在开源编译编译框架GCC(GNU C Compiler)的基础上实施,但并不局限于此,诸如开源分析工具Splint等均可实现替代功能。
具体的,调用Splint等轻量级静态检测工具对代码进行初步排查;在对源代码进行词法、语法等分析的过程中,对源程序内静态数组占用、动态申请的内存所占用的字节数、名称等进行标记,并以列表的形式进行输出,第一列表文件;在对源代码进行词法、语法等分析的过程中,还对malloc、free等动态内存分配相关的库函数所在源文件及函数名称、调用参数等进行标记,并同样以列表的形式进行输出,形成第二列表文件;GCC编译框架内在前端分析结束后,生成目标源文件的控制流图CFG,CFG上的各节点对应于程序内唯一的基本块,因此,CFG不仅反映了函数之间的调用关系,还刻画了文件内函数之间的调用关系。
步骤S12:根据所述控制流图构建所述源代码的全局函数调用图,根据所述全局函数调用图、所述第二列表文件和所述数据依赖图,对所述源代码进行动态内存分配的匹配性检测;
本申请实施例提供的一种内存访问异常的检测方法,如图3所示,所述根据所述控制流图构建所述源代码的全局函数调用图,包括:
S121:提取所述控制流图内的函数的内入口基本块、出口基本块,统计所述入口基本块的入度和所述出口基本块的出度,并合并所述入口基本块和所述出口基本块对应的节点,构建节点之间的连接关系,为每一个独立源程序生成一个函数调用图;
根据特定的应用场景,本发明还需在CFG的基础上构建用于直观刻画函数之间调用关系的全局函数调用图;删除CFG内除具体函数内入口基本块、出口基本块的其它节点,统计入口基本的入度,以及出口基本块的出度,合并入口、出口基本块对应的节点,并出现构建节点之间的连接关系,即构成了一个独立源程序的单个源文件的函数调用图。
S122:遍历第一函数调用图内存在出度且在所述第一函数调用图内无后继节点的节点,判断与第二函数调用图内的全局函数节点是否存在调用关系,如果存在,则添加从第一函数调用图到第二函数调用图的有向边;遍历第二函数调用图内存在出度且在所述第二函数调用图内无后继节点的节点,判断与第一函数调用图内的全局函数节点是否存在调用关系,如果存在,则添加从第二函数调用图到第一函数调用图的有向边;依次处理每个函数调用图,查找到所有节点的后续节点,并删除标准库函数的后续节点,生成全局函数调用图。
一个完整的应用程序可以是由多个源文件组成,比如{Prj:Src1,Src2,...Srcn},其中Srci,i=1,2...,n代表一个独立的源程序,那么,经编译后可生成的单个源文件的函数调用图的集合为Cgset{Cg1,Cg2,...,Cgn}。
为了生成全局函数调用图,本发明还对单个源文件的函数调用图集合Cgset内的元素进行迭代操作。以元素Cgi、Cgj为例,其中i≠j,i,j=1,2...,n。首先,遍历Cgi内存在出度,但在Cgi内未找到后继节点的节点,判断它们与Cgj内全局函数节点是否存在调用关系,如果有,则添加i→j的有向边。然后,遍历Cgj内存在出度,但在Cgj内未找到后继节点的节点,判断它们与Cgi内全局函数节点是否存在调用关系,如果有,则添加j→i的有向边,最后,依次处理各个元素,直到所有节点的后续节点,除标准库函数外的后续节点全部找到为止,并生成全局函数调用图CallGraph。
它具备以下属性:其中,节点集合V(G)={v1,v2,v3…vn},vi与源程序内的独立的函数一一映射并被其属性刻画。vi的属性集合为{region,func,...,file},region用于标记程序是本文件内使用,还是全局使用,func、file分别代表函数名和所在文件名。vi的出度和入度取决于函数的调用关系,且出度和入度均为0的节点为死代码可被直接删除。边集合E(G)={e1,e2,e3…en},若ei={<vj,vk>|vj,vk∈V(G)},则ei是一条以vj为初节点,以vk为终节点的有向边,它描述了vj,vk之间存在的调用关系,ei的属性集合为{cond,...,seq},其中,cond代表vj调用vk的谓词条件,seq为ei位于同一个节点vj上全部的出弧上的序值,即函数调用的逻辑序关系。关联函数描述了边与节点之间的关联关系E→V×V,CallGraph中V(G)内各节点元素之间存在不定数量的边。因此,即不是单映射也不是满映射。
本申请实施例提供的一种内存访问异常的检测方法,如图4所示,所述根据所述全局函数调用图、所述第二列表文件和所述数据依赖图,对所述源代码进行动态内存分配的匹配性检测,包括:
S123:根据所述第二列表文件,对所述全局函数调用图内的节点进行区分标记;
S124:提取所述全局函数调用图内的入口函数节点,通过分析所述数据依赖图,向前追溯并提取与所述动态内存分配库函数存在数据依赖的前驱节点,删除其它节点;
S125:将每个提取的节点在所述全局函数调用图中的前驱节点与后继节点重新建立连接关系,且保持逻辑序关系不变,生成精简函数调用图;
S126:如果任意一个节点内存在针对同一变量的动态内存分配库函数,则向该节点添加自旋弧,并删除所述精简函数调用图内由于所述自旋弧出现自闭环的边,对所述源代码进行动态内存分配的匹配性检测。
程序员一般是调用标准库函数malloc和free实现对内存空间的动态申请和释放,其中,malloc函数的实现机制是通过建立链表结构,管理和组织内存中离散的内存片段,并以内存片段的首地址以及长度作为节点属性。free函数则是根据用户输入的内存地址,查找链表内的节点,并对目标内存片段进行删除。工程领域中,进行动态内存分配时,较常见的错误有下述几种:
1、程序运行期动态申请内存后,由于程序执行异常导致中断,而出现的对已申请的内存空间不释放;2、程序员的疏忽致使的未使用free函数对动态申请的内存进行显式释放,而出现的内存泄漏;3、由于程序控制流的影响,对同一内存片段进行多次显式释放;4、程序员释放非法内存地址。
基于上述现状,本发明提出的技术方案,在进行的动态检测之前,还从宏观上对malloc、free函数进行匹配性检测,这主要是为了降低后续操作计算量。为了实现这一目标,本发明分多步操作实施,工作流程如图4所示。
具体的,在进行匹配性检测前,根据代码分析模块输出的第二列表文件,对CallGraph内的节点进行区分标记;保留CallGraph结构内的入口函数节点,一般为main函数,否则将形成森林结构;保留CallGraph内被标记的节点,通过分析数据依赖图,向前追溯与malloc、free函数存在数据依赖的前驱节点,并保留;
删除上述被保留以外的全部节点,并将当前节点在图中的前驱节点与后继节点重新建立连接关系,且其中的逻辑序关系保持不变,并生成精简函数调用图ReducedCallGraph。假设存在以下关系{vm,vk},{vk,vn},但不存在{vm,vn},其中,v代表CallGraph内的一个节点,vm为vk的一个前驱节点,vk为vn的一个前驱节点,假设vk被删除,那么,在本发明提出的技术方案中将建立vm与vn之间的连接关系,而vm则成为vn的一个前驱节点;
如果任一个节点内,存在针对同一变量的malloc与free函数,则向该节点添加自旋弧;
由于函数间可能存在递归调用,这就导致函数调用图内存在由多个节点组成的环路,然而,程序的执行行为与数据激励密不可分,程序的循环次数却有可能是由运行时参数决定。为了更加深入的对导致内存泄露的症结进行排查,本发明还删除了ReducedCallGraph结构内导致出现自闭环的边,因此,ReducedCallGraph在不考额外添加的自旋弧的条件下是一个有向无环图。
ReducedCallGraph生成结束后,开始进行匹配性检测。首先,从main函数开始,进行深度优先遍历,即获取从入口节点到出口节点的各条路径{Pathi,Path2,...,Pathn};其次,基于数据依赖关系,分析全局文件内的malloc、free函数之间多对多的映射关系;然后,根据程序的谓词关系,分析路径Pathi是否有效;最后,查询Pathi下的malloc、free是否匹配,如果不匹配,则进行报告,否则继续下一条路径的匹配性检测。
步骤S13:构建虚拟执行平台,根据所述第一列表文件、所述控制流图和所述数据依赖图提取执行路径,实现对动态内存分配造成的内存泄露以及程序运行时的内存访问越界的检测操作。
常见的与平台相关的集成开发环境,如Visual Stdio等在处理内存访问异常时,是配合硬件中断而实现,如未分配的内存区的初始化数据为0xcdcdcdcd,它代表中断1。然而,针对一些特殊场景,如银行业的代码投产之后,如果内存访问出现异常,将导致生产故障,后果难以估量。
本申请实施例提供的一种内存访问异常的检测方法中,所述构建虚拟机平台,包括:选择目标处理器平台,基于指令集功能特征,建立指令行为级模拟器;建立所述指令行为级模拟器的过程中,针对条件判断类及分支跳转类指令进行行为级建模时,添加先进后出的堆栈结构;所述堆栈结构用于保存所述条件判断类及分支跳转类指令的内存地址、寄存器内的数据的逆状态。
为了构建一个能对代码中内存访问异常进行充分检测的环境与平台,本发明还建立一套虚拟机平台。公知技术可知,编译器、汇编器、链接器只是用于将高级程序源代码,分多步骤翻译为目标平台可读的二进制机器码,但不改变程序的正常执行逻辑。为了降低虚拟执行时的时间开销,本发明ARM10处理器的RISC指令集做为目标平台,并配备了相应的模拟器。这主要源于,ARM系列处理器有很好的平台支持,且指令集设计十分规范,有利于加速虚拟执行的效率,但本发明并不受限于此,用户可根据实际情况选用相应的平台。
本申请实施例提供的一种内存访问异常的检测方法,如图5所示,所述根据所述第一列表文件、所述控制流图和所述数据依赖图提取虚拟执行路径,实现对动态内存分配造成的内存泄露以及程序运行时的内存访问越界的检测操作,包括:
S131:对程序进行虚拟执行,判断是否出现条件判断类及分支跳转类指令,如果出现,保存所述条件判断类及分支跳转类指令的内存地址、寄存器内的数据的逆状态,并进行入栈;统计当前执行路径下申请和释放的动态内存的字节数,统计对内存的写操作,并把对内存的修改写入栈顶记录所对应的内存状态修改链表内;当程序执行到出口函数时,检查申请和释放的动态内存的字节数是否相同,并根据内存地址,查找导致内存泄露的动态内存分配库函数;检测完成后,从所述堆栈结构内读取一条记录,并对虚拟机的程序指针、内存、寄存器进行恢复;程序运行到栈空为止,实现对动态内存分配造成的内存泄露的检测操作;
S132:获得所述第一列表文件内的静态数组占用以及动态申请的内存的内存记录,在链接期对静态分配的全局数据、局部静态数组分配内存地址,在运行期通过压栈操作计算存储于程序栈内的局部未初始化数组的栈地址的偏移量,并通过动态内存分配库函数的返回值获取动态内存分配的内存块;每一条独立的加载、保存指令在函数内的基本块中首次被执行时,记录访问的内存地址以及所在的内存块,当下一次访问中的目标内存地址不在所述内存块内时,判定为内存访问越界,实现对程序运行时的内存访问越界的检测操作。
虚拟执行平台在本发明中完成内存泄露、内存访问越界两方面检测工作。由于程序的执行行为与数据激励密不可分,不同数据输入模式下,程序流也千差万别,这就是说内存访问异常在不同数据激励下可能是不可重现的。在虚拟平台上,所有的对程序运行逻辑的修改都是可控的,为此,本发明还提出了一种全路径的执行方法,该方法是通过在指令级行为进行修改实现的。
以RISC体系结构为例,分支判断通常是配合条件判断指令以及推断寄存器实现,这也就是说,如果通过修改条件判断指令的结果,将可以直接修改程序的控制流,以下述两条指令为例,
pr0 lt pr1,pr2,d1,12. 1)
pr1 call func. 2)
当数据寄存器d1>12时,分支指令2将被执行,否则,分支不被发生。因此,本文在虚拟机中对条件判断类及分支跳转类指令还添加了先进后出的堆栈结构,其中,栈内存储的记录包括{指令内存地址,内存数据,寄存器数据}。
虚拟执行时检测内存泄露的执行流程具体如下所示:
(1)虚拟机执行时,一但出现条件判断类及分支跳转类指令,将该指令的内存地址、当前指令相关的寄存器内的数据的逆状态(如指令1中,假设d1的值为14,指令1执行成功,那么d1被保存的数据为12),其余无关寄存器的数据、而内存数据则当下一次出现内存修改时才进行保存,并将上述数据进行入栈;
(2)程序继续运行,直到出口函数为止;
(3)程序运行过程中,统计当前执行路径下申请和释放的动态内存的字节数;
(4)程序运行过程中,还需统计对内存的写操作,并把对内存的修改写入栈顶记录所对应的内存状态修改链表内;
(5)当程序执行到出口函数时,检查申请和释放的动态内存的字节数是否相同,并根据内存地址,找出具体导致内存泄露的malloc、free函数的为止;
(6)检测完成后,从所述堆栈结构内读取一条记录,并对虚拟机的程序指针、内存、寄存器进行恢复;
(7)程序运行到栈空为止。
内存访问越界分读、写越界两种,而所有的内存操作都对应于两类机器指令load和store。因此,本文在虚拟机中对目标指令集进行行为级建模、以及链接期新增了功能,而这些添加部分遵循如下两条约束实施,一方面,不能影响程序的执行逻辑,另一方面,需要在程序的运行期判断是否出现访问越界。
本发明进行内存访问越界检测的具体步骤如下所示:
(1)读取代码分析模块所获得的第一列表文件所存取的静态数组占用以及动态申请的内存的内存记录,而链接期只能对其中静态分配的全局数据、局部静态数组分配内存地址,而局部未初始化的数组则存放于程序栈内,而这些栈地址是程序运行期决定的,因此,对其余数组需在运行期决定;
(2)运行期方可决定内存地址的数组等,它们这些操作均有一条或多条汇编指令支持。存储于程序栈内的局部未初始化数组,可通过压栈操作计算栈地址的偏移量。动态内存分配的内存块则可通过malloc等函数的返回值来获取;
(3)虚拟机内维护一张动态表,该动态表内存储了全部第一列表文件内记录对应的内存的地址,其中,上述步骤(2)中程序运行期获得内存地址,需动态的插入该动态表内;
(4)每一条独立的Load、Store指令在函数内的基本块中首次被执行时,记录了访问的内存地址,并通过查询步骤(3)所述的动态表,可获知所在的内存块,一旦下次访问中的目标内存地址不在所述内存块内,那么将被判定为内存访问越界;
需要说明的是,步骤(4)中所述的判断仅在每一次函数调用内,如果出现新的函数调用,无法判断是否存在函数返回了新的内存地址。
此处内存访问越界检测的步骤(1)~(5)与上述内存访问泄露的步骤(1)~(5)可以同时进行。
本发明生成并迭代各单文件内的函数调用图,并进行动态内存申请、释放的匹配;构建虚拟执行环境,从控制流图、数据依赖图等的基础上抽取执行路径,通过行为级建模、虚拟执行等高效地实现一系列的内存访问检测操作,且本文提出的技术方案与执行平台无关。
对于前述的各方法实施例,为了简单描述,故将其都表述为一系列的动作组合,但是本领域技术人员应该知悉,本发明并不受所描述的动作顺序的限制,因为依据本发明,某些步骤可以采用其他顺序或者同时进行。
图6为本申请实施例提供的一种内存访问异常的检测装置的结构示意图。
参照图6所示,本申请实施例提供的内存访问异常的检测装置,包括:
分析模块1,用于对源代码进行排查和词法分析、语法分析以及语义分析,生成控制流图、数据依赖图、第一列表文件和第二列表文件;所述第一列表文件中包括所述源代码内的静态数组占用的内存的静态内存信息,或所述源代码内的动态分配的内存的动态内存信息;所述第二列表文件中包括所述源代码内的动态内存分配库函数的函数信息;
检测模块2,用于根据所述控制流图构建所述源代码的全局函数调用图,根据所述全局函数调用图、所述第二列表文件和所述数据依赖图,对所述源代码进行动态内存分配的匹配性检测;
构建模块3,用于构建虚拟执行平台,根据所述第一列表文件、所述控制流图和所述数据依赖图提取虚拟执行路径,实现对动态内存分配造成的内存泄露以及程序运行时的内存访问越界的检测操作。
所述分析模块1,包括:
排查单元,用于调用轻量级静态检测工具对源代码进行初步排查;
分析单元,用于对所述源代码进行词法、语法分析,对所述源代码内的静态数组占用、动态申请的内存所占用的字节数、名称进行标记,生成第一列表文件,并对动态内存分配库函数所在的源文件及函数名称、调用参数进行标记,生成第二列表文件;
生成单元,用于根据所述源代码的分支跳转和函数调用关系,将所述源代码切分为多个基本块,并分析每个基本块之间的跳转关系,根据所述跳转关系生成控制流图,并根据所述源代码的变量之间的数据依赖关系,生成数据依赖图。
所述检测模块2,包括:
提取单元,用于提取所述控制流图内的函数的内入口基本块、出口基本块,统计所述入口基本块的入度和所述出口基本块的出度,并合并所述入口基本块和所述出口基本块对应的节点,构建节点之间的连接关系,为每一个独立源程序生成一个函数调用图;
遍历单元,用于遍历第一函数调用图内存在出度且在所述第一函数调用图内无后继节点的节点,判断与第二函数调用图内的全局函数节点是否存在调用关系,如果存在,则添加从第一函数调用图到第二函数调用图的有向边;遍历第二函数调用图内存在出度且在所述第二函数调用图内无后继节点的节点,判断与第一函数调用图内的全局函数节点是否存在调用关系,如果存在,则添加从第二函数调用图到第一函数调用图的有向边;依次处理每个函数调用图,查找到所有节点的后续节点,并删除标准库函数的后续节点,生成全局函数调用图;
标记单元,用于根据所述第二列表文件,对所述全局函数调用图内的节点进行区分标记;
分析单元,用于提取所述全局函数调用图内的入口函数节点,通过分析所述数据依赖图,向前追溯并提取与所述动态内存分配库函数存在数据依赖的前驱节点,删除其它节点;
生成单元,用于将每个提取的节点在所述全局函数调用图中的前驱节点与后继节点重新建立连接关系,且保持逻辑序关系不变,生成精简函数调用图;
如果任意一个节点内存在针对同一变量的动态内存分配库函数,则向该节点添加自旋弧,并删除所述精简函数调用图内由于所述自旋弧出现自闭环的边,对所述源代码进行动态内存分配的匹配性检测。
所述构建模块3,包括:
选择单元,用于选择目标处理器平台,基于指令集功能特征,建立指令行为级模拟器;
建立单元,用于建立所述指令行为级模拟器的过程中,针对条件判断类及分支跳转类指令进行行为级建模时,添加先进后出的堆栈结构;所述堆栈结构用于保存所述条件判断类及分支跳转类指令的内存地址、寄存器内的数据的逆状态;
内存泄露检测单元,用于对程序进行虚拟执行,判断是否出现条件判断类及分支跳转类指令,如果出现,保存所述条件判断类及分支跳转类指令的内存地址、寄存器内的数据的逆状态,并进行入栈;统计当前执行路径下申请和释放的动态内存的字节数,统计对内存的写操作,并把对内存的修改写入栈顶记录所对应的内存状态修改链表内;当程序执行到出口函数时,检查申请和释放的动态内存的字节数是否相同,并根据内存地址,查找导致内存泄露的动态内存分配库函数;检测完成后,从所述堆栈结构内读取一条记录,并对虚拟机的程序指针、内存、寄存器进行恢复;程序运行到栈空为止,实现对动态内存分配造成的内存泄露的检测操作;
内存越界检测单元,用于获得所述第一列表文件内的静态数组占用以及动态申请的内存的内存记录,在链接期对静态分配的全局数据、局部静态数组分配内存地址,在运行期通过压栈操作计算存储于程序栈内的局部未初始化数组的栈地址的偏移量,并通过动态内存分配库函数的返回值获取动态内存分配的内存块;每一条独立的加载、保存指令在函数内的基本块中首次被执行时,记录访问的内存地址以及所在的内存块,当下一次访问中的目标内存地址不在所述内存块内时,判定为内存访问越界,实现对程序运行时的内存访问越界的检测操作。
本申请实施例提供的内存访问异常的检测装置,可以采用上述方法实施例中的内存访问异常的检测方法,此处不再赘述。
本申请实施例提供的内存访问异常的检测装置,由分析模块、检测模块、构建模块三个功能模块组成。分析模块,用于对常量字符串等静态定义的数组或缓冲进行生命周期分析、占内存字节数等操作,并输出至第一和第二列表文件;然后,用于生成全局程序的函数调用图;最后,用于分析malloc、free等动态内存申请、分配库函数所在的函数名以及文件名。检测模块,一方面,基于代码分析模块生成的第一和第二列表文件,对函数调用图进行裁剪并重建;另一方面,用于分析程序中malloc、free函数在针对同一个变量时,在独立的执行路径下是否成对出现。构建模块,一方面,选定虚拟平台,并针对目标平台的指令集构建模拟器;另一方面,分析获取函数调用图的全部的执行路径,并通过外接控制逻辑的条件下进行强制执行,并判断是否存内存泄漏以及访问越界;还可以于强化机器指令功能,在程序运行时制造陷阱,来判断是否存在内存访问越界。
应用本发明提出的技术方案,首先,调用Splint等轻量级静态检测工具对代码进行初步排查;其次,在对源代码进行词法、语法等分析的过程中,对源程序内的静态数组占用或动态申请的内存的生命周期、长度等进行标记,并以列表的形式进行输出,形成第一列表文件;再次,在对源代码进行词法、语法等分析的过程中,还对malloc、free等动态内存分配相关的库函数所在区间、调用参数等进行标记,并同样以列表的形式进行输出,形成第二列表文件;然后,根据第二列表文件的输出结果,在程序的控制流图的基础上,生成并迭代各单文件内的函数调用图,并进行动态内存申请、释放的匹配;然后,构建虚拟执行环境,从控制流图、数据依赖图等的基础上抽取执行路径。最后,通过行为级建模、虚拟执行实现一系列的内存访问检测操作。可以充分挖掘源代码中存在的内存访问异常,通过建模和虚拟执行可以高效地实现对于内存访问异常的检测操作。
为了描述的方便,描述以上装置时以功能分为各种单元分别描述。当然,在实施本申请时可以把各单元的功能在同一个或多个软件和/或硬件中实现。
本说明书中的各个实施例均采用递进的方式描述,各个实施例之间相同相似的部分互相参见即可,每个实施例重点说明的都是与其他实施例的不同之处。尤其,对于装置或系统实施例而言,由于其基本相似于方法实施例,所以描述得比较简单,相关之处参见方法实施例的部分说明即可。以上所描述的装置及系统实施例仅仅是示意性的,其中所述作为分离部件说明的单元可以是或者也可以不是物理上分开的,作为单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,或者也可以分布到多个网络单元上。可以根据实际的需要选择其中的部分或者全部模块来实现本实施例方案的目的。本领域普通技术人员在不付出创造性劳动的情况下,即可以理解并实施。
专业人员还可以进一步意识到,结合本文中所公开的实施例描述的各示例的单元及算法步骤,能够以电子硬件、计算机软件或者二者的结合来实现,为了清楚地说明硬件和软件的可互换性,在上述说明中已经按照功能一般性地描述了各示例的组成及步骤。这些功能究竟以硬件还是软件方式来执行,取决于技术方案的特定应用和设计约束条件。专业技术人员可以对每个特定的应用来使用不同方法来实现所描述的功能,但是这种实现不应认为超出本发明的范围。
结合本文中所公开的实施例描述的方法或算法的步骤可以直接用硬件、处理器执行的软件模块,或者二者的结合来实施。软件模块可以置于随机存储器(RAM)、内存、只读存储器(ROM)、电可编程ROM、电可擦除可编程ROM、寄存器、硬盘、可移动磁盘、CD-ROM、或技术领域内所公知的任意其它形式的存储介质中。
对所公开的实施例的上述说明,使本领域专业技术人员能够实现或使用本发明。对这些实施例的多种修改对本领域的专业技术人员来说将是显而易见的,本文中所定义的一般原理可以在不脱离本发明的精神或范围的情况下,在其它实施例中实现。因此,本发明将不会被限制于本文所示的这些实施例,而是要符合与本文所公开的原理和新颖特点相一致的最宽的范围。
Claims (12)
1.一种内存访问异常的检测方法,其特征在于,包括:
对源代码进行排查和词法分析、语法分析以及语义分析,生成控制流图、数据依赖图、第一列表文件和第二列表文件;所述第一列表文件中包括所述源代码内的静态数组占用的内存的静态内存信息,或所述源代码内的动态分配的内存的动态内存信息;所述第二列表文件中包括所述源代码内的进行动态内存分配库函数的函数信息;
根据所述控制流图构建所述源代码的全局函数调用图,根据所述全局函数调用图、所述第二列表文件和所述数据依赖图,对所述源代码进行动态内存分配的匹配性检测;
构建虚拟执行平台,根据所述第一列表文件、所述控制流图和所述数据依赖图提取虚拟执行路径,实现对动态内存分配造成的内存泄露以及程序运行时的内存访问越界的检测操作。
2.根据权利要求1所述的方法,其特征在于,所述对源代码进行排查和词法分析、语法分析以及语义分析,生成控制流图、数据依赖图、第一列表文件和第二列表文件,包括:
调用轻量级静态检测工具对源代码进行初步排查;
对所述源代码进行词法、语法分析,对所述源代码内的静态数组占用、动态申请的内存所占用的字节数、名称进行标记,生成第一列表文件,并对动态内存分配库函数所在的源文件及函数名称、调用参数进行标记,生成第二列表文件;
根据所述源代码的分支跳转和函数调用关系,将所述源代码切分为多个基本块,并分析每个基本块之间的跳转关系,根据所述跳转关系生成控制流图,并根据所述源代码的变量之间的数据依赖关系,生成数据依赖图。
3.根据权利要求1所述的方法,其特征在于,所述根据所述控制流图构建所述源代码的全局函数调用图,包括:
提取所述控制流图内的函数的内入口基本块、出口基本块,统计所述入口基本块的入度和所述出口基本块的出度,并合并所述入口基本块和所述出口基本块对应的节点,构建节点之间的连接关系,为每一个独立源程序生成一个函数调用图;
遍历第一函数调用图内存在出度且在所述第一函数调用图内无后继节点的节点,判断与第二函数调用图内的全局函数节点是否存在调用关系,如果存在,则添加从第一函数调用图到第二函数调用图的有向边;遍历第二函数调用图内存在出度且在所述第二函数调用图内无后继节点的节点,判断与第一函数调用图内的全局函数节点是否存在调用关系,如果存在,则添加从第二函数调用图到第一函数调用图的有向边;依次处理每个函数调用图,查找到所有节点的后续节点,并删除标准库函数的后续节点,生成全局函数调用图。
4.根据权利要求1所述的方法,其特征在于,所述根据所述全局函数调用图、所述第二列表文件和所述数据依赖图,对所述源代码进行动态内存分配的匹配性检测,包括:
根据所述第二列表文件,对所述全局函数调用图内的节点进行区分标记;
提取所述全局函数调用图内的入口函数节点,通过分析所述数据依赖图,向前追溯并提取与所述动态内存分配库函数存在数据依赖的前驱节点,删除其它节点;
将每个提取的节点在所述全局函数调用图中的前驱节点与后继节点重新建立连接关系,且保持逻辑序关系不变,生成精简函数调用图;
如果任意一个节点内存在针对同一变量的动态内存分配库函数,则向该节点添加自旋弧,并删除所述精简函数调用图内由于所述自旋弧出现自闭环的边,对所述源代码进行动态内存分配的匹配性检测。
5.根据权利要求1所述的方法,其特征在于,所述构建虚拟机平台,包括:
选择目标处理器平台,基于指令集功能特征,建立指令行为级模拟器;
建立所述指令行为级模拟器的过程中,针对条件判断类及分支跳转类指令进行行为级建模时,添加先进后出的堆栈结构;所述堆栈结构用于保存所述条件判断类及分支跳转类指令的内存地址、寄存器内的数据的逆状态。
6.根据权利要求5所述的方法,其特征在于,所述根据所述第一列表文件、所述控制流图和所述数据依赖图提取虚拟执行路径,实现对动态内存分配造成的内存泄露以及程序运行时的内存访问越界的检测操作,包括:
对程序进行虚拟执行,判断是否出现条件判断类及分支跳转类指令,如果出现,保存所述条件判断类及分支跳转类指令的内存地址、寄存器内的数据的逆状态,并进行入栈;统计当前执行路径下申请和释放的动态内存的字节数,统计对内存的写操作,并把对内存的修改写入栈顶记录所对应的内存状态修改链表内;当程序执行到出口函数时,检查申请和释放的动态内存的字节数是否相同,并根据内存地址,查找导致内存泄露的动态内存分配库函数;检测完成后,从所述堆栈结构内读取一条记录,并对虚拟机的程序指针、内存、寄存器进行恢复;程序运行到栈空为止,实现对动态内存分配造成的内存泄露的检测操作;
获得所述第一列表文件内的静态数组占用以及动态申请的内存的内存记录,在链接期对静态分配的全局数据、局部静态数组分配内存地址,在运行期通过压栈操作计算存储于程序栈内的局部未初始化数组的栈地址的偏移量,并通过动态内存分配库函数的返回值获取动态内存分配的内存块;每一条独立的加载、保存指令在函数内的基本块中首次被执行时,记录访问的内存地址以及所在的内存块,当下一次访问中的目标内存地址不在所述内存块内时,判定为内存访问越界,实现对程序运行时的内存访问越界的检测操作。
7.一种内存访问异常的检测装置,其特征在于,包括:
分析模块,用于对源代码进行排查和词法分析、语法分析以及语义分析,生成控制流图、数据依赖图、第一列表文件和第二列表文件;所述第一列表文件中包括所述源代码内的静态数组占用的内存的静态内存信息,或所述源代码内的动态分配的内存的动态内存信息;所述第二列表文件中包括所述源代码内的动态内存分配库函数的函数信息;
检测模块,用于根据所述控制流图构建所述源代码的全局函数调用图,根据所述全局函数调用图、所述第二列表文件和所述数据依赖图,对所述源代码进行动态内存分配的匹配性检测;
构建模块,用于构建虚拟执行平台,根据所述第一列表文件、所述控制流图和所述数据依赖图提取虚拟执行路径,实现对动态内存分配造成的内存泄露以及程序运行时的内存访问越界的检测操作。
8.根据权利要求7所述的装置,其特征在于,所述分析模块,包括:
排查单元,用于调用轻量级静态检测工具对源代码进行初步排查;
分析单元,用于对所述源代码进行词法、语法分析,对所述源代码内的静态数组占用、动态申请的内存所占用的字节数、名称进行标记,生成第一列表文件,并对动态内存分配库函数所在的源文件及函数名称、调用参数进行标记,生成第二列表文件;
生成单元,用于根据所述源代码的分支跳转和函数调用关系,将所述源代码切分为多个基本块,并分析每个基本块之间的跳转关系,根据所述跳转关系生成控制流图,并根据所述源代码的变量之间的数据依赖关系,生成数据依赖图。
9.根据权利要求7所述的装置,其特征在于,所述检测模块,包括:
提取单元,用于提取所述控制流图内的函数的内入口基本块、出口基本块,统计所述入口基本块的入度和所述出口基本块的出度,并合并所述入口基本块和所述出口基本块对应的节点,构建节点之间的连接关系,为每一个独立源程序生成一个函数调用图;
遍历单元,用于遍历第一函数调用图内存在出度且在所述第一函数调用图无后继节点的节点,判断与第二函数调用图内的全局函数节点是否存在调用关系,如果存在,则添加从第一函数调用图到第二函数调用图的有向边;遍历第二函数调用图内存在出度且在所述第二函数调用图无后继节点的节点,判断与第一函数调用图内的全局函数节点是否存在调用关系,如果存在,则添加从第二函数调用图到第一函数调用图的有向边;依次处理每个函数调用图,查找到所有节点的后续节点,并删除标准库函数的后续节点,生成全局函数调用图。
10.根据权利要求7所述的装置,其特征在于,所述检测模块,包括:
标记单元,用于根据所述第二列表文件,对所述全局函数调用图内的节点进行区分标记;
分析单元,用于提取所述全局函数调用图内的入口函数节点,通过分析所述数据依赖图,向前追溯并提取与所述动态内存分配库函数存在数据依赖的前驱节点,删除其它节点;
生成单元,用于将每个提取的节点在所述全局函数调用图中的前驱节点与后继节点重新建立连接关系,且保持逻辑序关系不变,生成精简函数调用图;
如果任意一个节点内存在针对同一变量的动态内存分配库函数,则向该节点添加自旋弧,并删除所述精简函数调用图内由于所述自旋弧出现自闭环的边,对所述源代码进行动态内存分配的匹配性检测。
11.根据权利要求7所述的装置,其特征在于,所述构建模块,包括:
选择单元,用于选择目标处理器平台,基于指令集功能特征,建立指令行为级模拟器;
建立单元,用于建立所述指令行为级模拟器的过程中,针对条件判断类及分支跳转类指令进行行为级建模时,添加先进后出的堆栈结构;所述堆栈结构用于保存所述条件判断类及分支跳转类指令的内存地址、寄存器内的数据的逆状态。
12.根据权利要求11所述的装置,其特征在于,所述构建模块,包括:
内存泄露检测单元,用于对程序进行虚拟执行,判断是否出现条件判断类及分支跳转类指令,如果出现,保存所述条件判断类及分支跳转类指令的内存地址、寄存器内的数据的逆状态,并进行入栈;统计当前执行路径下申请和释放的动态内存的字节数,统计对内存的写操作,并把对内存的修改写入栈顶记录所对应的内存状态修改链表内;当程序执行到出口函数时,检查申请和释放的动态内存的字节数是否相同,并根据内存地址,查找导致内存泄露的动态内存分配库函数;检测完成后,从所述堆栈结构内读取一条记录,并对虚拟机的程序指针、内存、寄存器进行恢复;程序运行到栈空为止,实现对动态内存分配造成的内存泄露的检测操作;
内存越界检测单元,用于获得所述第一列表文件内的静态数组占用以及动态申请的内存的内存记录,在链接期对静态分配的全局数据、局部静态数组分配内存地址,在运行期通过压栈操作计算存储于程序栈内的局部未初始化数组的栈地址的偏移量,并通过动态内存分配库函数的返回值获取动态内存分配的内存块;每一条独立的加载、保存指令在函数内的基本块中首次被执行时,记录访问的内存地址以及所在的内存块,当下一次访问中的目标内存地址不在所述内存块内时,判定为内存访问越界,实现对程序运行时的内存访问越界的检测操作。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201510086609.XA CN104636256B (zh) | 2015-02-17 | 2015-02-17 | 一种内存访问异常的检测方法及装置 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201510086609.XA CN104636256B (zh) | 2015-02-17 | 2015-02-17 | 一种内存访问异常的检测方法及装置 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN104636256A CN104636256A (zh) | 2015-05-20 |
CN104636256B true CN104636256B (zh) | 2017-10-24 |
Family
ID=53215040
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201510086609.XA Active CN104636256B (zh) | 2015-02-17 | 2015-02-17 | 一种内存访问异常的检测方法及装置 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN104636256B (zh) |
Families Citing this family (23)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN105260174B (zh) * | 2015-09-16 | 2018-09-28 | 北京航空航天大学 | 实时Java虚拟机中基于等价类的对象内存状态的记录跟踪方法 |
CN106610892B (zh) * | 2015-10-23 | 2020-12-22 | 腾讯科技(深圳)有限公司 | 内存泄漏检测方法和装置 |
CN107479866B (zh) * | 2016-08-12 | 2020-11-06 | 北京大学 | 基于重构技术实现开放终端应用数据与功能的方法 |
CN106528403B (zh) * | 2016-10-08 | 2018-11-20 | 西安电子科技大学 | 基于二进制代码植入技术的软件运行时监控方法 |
CN107133085B (zh) * | 2017-06-26 | 2020-10-27 | 珠海大横琴科技发展有限公司 | 优化oat中冗余指令的方法及移动终端 |
CN109426504B (zh) * | 2017-08-29 | 2021-11-19 | 龙芯中科技术股份有限公司 | 程序的处理方法、装置、电子设备及存储介质 |
US10757087B2 (en) * | 2018-01-02 | 2020-08-25 | Winbond Electronics Corporation | Secure client authentication based on conditional provisioning of code signature |
CN108256337B (zh) * | 2018-02-26 | 2020-07-17 | 北京阿尔山区块链联盟科技有限公司 | 智能合约漏洞检测方法、装置及电子设备 |
CN108830049B (zh) * | 2018-05-09 | 2021-07-20 | 四川大学 | 一种基于动态控制流图权重序列胎记的软件相似性检测方法 |
CN109343855B (zh) * | 2018-09-29 | 2020-12-29 | 清华大学 | 基于指令伪装的程序编译抓取系统及方法 |
CN109799992B (zh) * | 2018-12-05 | 2022-07-19 | 交控科技股份有限公司 | 一种城市轨道交通信号系统软件缓冲区范围检查方法 |
CN110008703B (zh) * | 2019-04-08 | 2020-01-24 | 四川大学 | 一种容器内恶意软件静态检测系统及方法 |
CN110347448B (zh) * | 2019-06-10 | 2021-02-12 | 北京大学 | 一种构造终端应用行为的运行时模型的方法 |
CN110502891B (zh) * | 2019-08-08 | 2021-06-15 | 北京字节跳动网络技术有限公司 | 一种获取进程内存泄露的方法、装置、介质和电子设备 |
CN112182580B (zh) * | 2019-09-19 | 2024-04-09 | 中国科学院信息工程研究所 | 一种基于处理器芯片的内存漏洞检测方法及电子装置 |
CN112631893B (zh) * | 2019-09-24 | 2022-11-15 | 无锡江南计算技术研究所 | 面向异构平台的多层次存储结构内存检测方法 |
CN110764760B (zh) * | 2019-10-29 | 2023-09-05 | 中国工商银行股份有限公司 | 用于绘制程序流程图的方法、装置、计算机系统和介质 |
CN112783755B (zh) * | 2019-11-07 | 2024-03-22 | 上海蜚语信息科技有限公司 | 一种基于自然语言理解函数原型发现内存破坏漏洞的方法 |
CN111858307B (zh) * | 2020-06-18 | 2024-04-19 | 三星(中国)半导体有限公司 | 模糊测试方法和设备 |
CN112131132A (zh) * | 2020-10-12 | 2020-12-25 | 苏州浪潮智能科技有限公司 | 基于图与概率的问题代码协助定位方法、装置和存储介质 |
CN112380529B (zh) * | 2020-10-26 | 2022-03-11 | 浙江大学 | 一种基于操作的嵌入式裸机系统安全隔离系统 |
CN112733150B (zh) * | 2021-01-12 | 2021-11-16 | 哈尔滨工业大学 | 一种基于脆弱性分析的固件未知漏洞检测方法 |
CN114817061A (zh) * | 2022-05-16 | 2022-07-29 | 厦门大学 | 虚拟构建脚本的依赖性错误检测方法 |
Citations (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
WO1993003435A1 (en) * | 1991-08-08 | 1993-02-18 | Pure Software, Inc. | Method and apparatus for identifying memory leaks and tracking pointers in a computer program |
CN101710303A (zh) * | 2009-12-01 | 2010-05-19 | 中国人民解放军国防科学技术大学 | 基于流敏感上下文敏感指向图的内存泄漏检测方法 |
CN102662825A (zh) * | 2012-02-22 | 2012-09-12 | 中国人民解放军国防科学技术大学 | 一种面向堆操作程序的内存泄漏检测方法 |
CN103793653A (zh) * | 2014-02-19 | 2014-05-14 | 中国科学院信息工程研究所 | 一种基于树优化的程序依赖关系分析方法及系统 |
CN104133733A (zh) * | 2014-07-29 | 2014-11-05 | 北京航空航天大学 | 一种内存错误检测方法 |
-
2015
- 2015-02-17 CN CN201510086609.XA patent/CN104636256B/zh active Active
Patent Citations (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
WO1993003435A1 (en) * | 1991-08-08 | 1993-02-18 | Pure Software, Inc. | Method and apparatus for identifying memory leaks and tracking pointers in a computer program |
CN101710303A (zh) * | 2009-12-01 | 2010-05-19 | 中国人民解放军国防科学技术大学 | 基于流敏感上下文敏感指向图的内存泄漏检测方法 |
CN102662825A (zh) * | 2012-02-22 | 2012-09-12 | 中国人民解放军国防科学技术大学 | 一种面向堆操作程序的内存泄漏检测方法 |
CN103793653A (zh) * | 2014-02-19 | 2014-05-14 | 中国科学院信息工程研究所 | 一种基于树优化的程序依赖关系分析方法及系统 |
CN104133733A (zh) * | 2014-07-29 | 2014-11-05 | 北京航空航天大学 | 一种内存错误检测方法 |
Non-Patent Citations (2)
Title |
---|
"Practical Memory Leak Detection using Guarded Value-Flow Analysis";Sigmund Cherem等;《PLDI"07 Proceedings of the 28th ACM SIGPLAN Conference on Programming Language Design and Implementation》;20070613;第42卷(第6期);第480-491页 * |
"Static and dynamic testing in the software development life cycle";M. Tim Jones;《https://www.ibm.com/developerworks/library/se-static/》;20130826;第1-10页 * |
Also Published As
Publication number | Publication date |
---|---|
CN104636256A (zh) | 2015-05-20 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN104636256B (zh) | 一种内存访问异常的检测方法及装置 | |
Momeni et al. | Machine learning model for smart contracts security analysis | |
Xing et al. | UMLDiff: an algorithm for object-oriented design differencing | |
CN104573503B (zh) | 一种内存访问溢出的检测方法及装置 | |
CN109583200A (zh) | 一种基于动态污点传播的程序异常分析方法 | |
US10599852B2 (en) | High performance software vulnerabilities detection system and methods | |
Padmanabhuni et al. | Buffer overflow vulnerability prediction from x86 executables using static analysis and machine learning | |
Alrabaee et al. | On leveraging coding habits for effective binary authorship attribution | |
Fu et al. | A critical-path-coverage-based vulnerability detection method for smart contracts | |
CN111919214A (zh) | 针对安全性违反的补丁的自动生成 | |
Butgereit | Using machine learning to prioritize automated testing in an agile environment | |
US11662998B2 (en) | Detecting duplicated code patterns in visual programming language code instances | |
Tomasco et al. | Using shared memory abstractions to design eager sequentializations for weak memory models | |
Tang et al. | Conditional dyck-cfl reachability analysis for complete and efficient library summarization | |
CN112131120A (zh) | 一种源代码缺陷检测方法及装置 | |
Brylow et al. | Deadline analysis of interrupt-driven software | |
CN112131122A (zh) | 一种源代码缺陷检测工具误报评估方法及装置 | |
Boockmann et al. | Generating inductive shape predicates for runtime checking and formal verification | |
Harmon et al. | A modular worst-case execution time analysis tool for Java processors | |
CN105988811B (zh) | 获取操作系统的内核控制流程图的方法和装置 | |
Melnik et al. | Enforcing secure coding rules for the C programming language using the eclipse development environment | |
Chattopadhyay et al. | Program performance spectrum | |
Borodin et al. | Searching for Taint Vulnerabilities with Svace Static Analysis Tool | |
De Nicola et al. | Klaim and its stochastic semantics | |
Rohatgi et al. | Approach for solving the feature location problem by measuring the component modification impact |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
C06 | Publication | ||
PB01 | Publication | ||
C10 | Entry into substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |