适用于虚函数和函数指针的静态函数调用图构建方法技术

技术编号:21999809 阅读:26 留言:0更新日期:2019-08-31 05:17
本发明专利技术公开了一种适用于虚函数和函数指针的静态函数调用图构建方法,其步骤包括:1获取源程序的中间代码;2获取中间代码中的关键信息,所述关键信息包括基本块顺序队列以及虚函数相关信息;3基于所述关键信息,对所述中间代码进行模拟执行,分析出所述中间代码中的函数调用指令调用的实际函数,同时记录下函数调用关系;4根据所述函数调用关系,构建出静态函数调用图。本发明专利技术能够全面的分析出虚函数、函数指针调用以及线程创建关系,而且能准确的分析出复杂的函数指针调用,从而能更好的帮助程序开发人员理解程序,同时提升依赖于函数调用图的静态分析方法的准确性。

A Method of Constructing Static Function Call Graph for Virtual Functions and Function Pointer

【技术实现步骤摘要】
适用于虚函数和函数指针的静态函数调用图构建方法
本专利技术涉及计算机软件
,尤其涉及一种适用于虚函数和函数指针的静态函数调用图构建方法。
技术介绍
现代软件系统的规模和复杂度不断提高,函数调用图也因此越来越受到重视。一方面,函数调用图可以帮助软件开发人员分析代码结构,理清代码逻辑。另一方面,函数调用图被广泛应用在程序静态分析领域。例如,函数调用图可以用来检测和消除程序中的死代码。函数调用图还可以与控制流图结合,形成过程间控制流图,这是程序静态分析中关于漏洞检测、安全分析等流敏感算法的基础。完备且准确的函数调用图可以更好的帮助程序开发人员理解程序,同时可以提升依赖于函数调用图的静态分析方法的准确性。在目前构建函数调用图的方法中,主要分为动态分析和静态分析两种。动态分析方法查准率高,但构建完整的函数调用图较为困难,查全率不高。静态分析方法查全率高,同时能保持较高的查准率,因此更受欢迎。目前已涌现许多用来构建静态函数调用图的方法,但现有的静态分析方法还存在较多问题,主要包括:1.目前还没有静态分析方法能全面的提取出虚函数、函数指针等函数调用关系。2.已有方法不能准确的分析出函数指针调用关系。3.对于使用多线程编程的程序,目前还没有方法可以静态提取线程间父子关系,线程函数的上下文信息在静态分析中全部丢失,这导致对多线程编程中死锁、数据竞争、伪共享等问题的静态检测准确性不高。
技术实现思路
本专利技术是为避免上述现有技术所存在的不足之处,提供一种适用于虚函数和函数指针的静态函数调用图构建方法,以期不仅能够全面的分析出虚函数、函数指针调用以及线程间父子关系,而且能准确的分析出复杂的函数指针调用,从而能更好的帮助程序开发人员理解代码并提升依赖于函数调用图的静态分析方法的准确性,具有较好的研究意义和实用价值。为达到上述目的,本专利技术采用如下技术方案:本专利技术一种适用于虚函数和函数指针的静态函数调用图构建方法的特点是按如下步骤进行:步骤1、获取源程序的中间代码;步骤2、获取中间代码中的关键信息,所述关键信息包括基本块顺序队列以及虚函数相关信息;步骤3、指定静态分析入口函数,并基于所述关键信息,对所述中间代码进行模拟执行,分析出所述中间代码中的函数调用指令调用的实际函数,同时记录下函数调用关系;步骤4、根据所述函数调用关系,构建出静态函数调用图。本专利技术所述的适用于虚函数和函数指针的静态函数调用图构建方法的特点也在于,所述步骤2中是按如下过程获取基本块顺序队列:步骤2A_1、获取所述中间代码中第i个函数Fi所对应的控制流图CFGi,并根据所述控制流图CFGi得到CFGi所对应的入口基本块EntryBBi;i=1,2,…,FN,FN为中间代码中函数的总个数;设置所述入口基本块EntryBBi为当前基本块,并将所述控制流图CFGi中所有循环的标识符记为“False”,表示未遍历到相应循环;步骤2A_2、如果当前基本块为循环L的头基本块,则执行步骤2A_3,否则执行步骤2A_6;步骤2A_3、如果所述当前基本块所在的循环L的标识符为“False”,则执行步骤2A_4,否则执行步骤2A_5;步骤2A_4、将当前基本块加入第i个基本块顺序队列BBOrderQi,并将当前基本块的后继基本块中处于循环L中的后继基本块设为当前基本块,将未处于循环L中的后继基本块压入第i个未处理栈UnProcessSi中,再将所述循环L的标识符置为“True”后,返回执行步骤2A_2;步骤2A_5、如果所述第i个未处理栈UnProcessSi为非空栈,则弹出所述第i个未处理栈UnProcessSi中栈顶的基本块,并将栈顶的基本块设置当前基本块后,执行步骤2A_2;步骤2A_6、将当前基本块加入所述第i个基本块顺序队列BBOrderQi中,如果当前基本块存在后继基本块,且后续基本块满足先序条件,则将满足先序条件的任意一个后继基本块为当前基本块,将其余后继基本块依次压入所述第i个未处理栈UnProcessSi中,再返回步骤2A_2执行,否则,执行步骤2A_5;所述先序条件为:后继基本块的前驱基本块均在所述第i个基本块顺序队列BBOrderQi中。所述步骤2中是按如下过程获取所述虚函数相关信息:步骤2B_1、定义中间代码中第j个虚表结构体变量为Vj,Vj[k]表示第j个虚表结构体变量Vj中第k个成员数组,且每个成员数组均对应一个类,Vj[k][t]表示第j个虚表结构体变量Vj中第k个成员数组的第t个元素,其中j=1,2,…,N;N为虚表结构体变量的总个数,k=1,2,…,Mj,Mj为第j个虚表结构体变量Vj中成员数组的总个数,t=1,2,…,Mjk,Mjk为第j个虚表结构体变量Vj中第k个成员数组的元素总个数;步骤2B_2、将第j个虚表结构体变量Vj中第k个成员数组的第1个元素Vj[k][1]转换成整型变量VPtrOffsetjk,以第j个虚表结构体变量Vj对应的类为键,以所述整型变量VPtrOffsetjk为值,构建键值对Pair1,并将键值对Pair1加入第j个虚表结构体变量Vj对应的虚表指针偏移表VirtualPtrj中,其中所述整型变量VPtrOffsetjk表示第k个虚表指针在所述第j个虚表结构体变量Vj所对应的类创建出的对象的内存布局中的偏移字节数;步骤2B_3、将第j个虚表结构体变量Vj中第k个成员数组的第t个元素Vj[k][t]转换成函数指针类型变量Vfunjkt,以偏移字节数Vj[k][1]为键,以所述指针类型变量Vfunjkt为值,构建键值对Pair2,并将键值对Pair2加入第j个虚表结构体变量Vj中第k个成员数组对应类的虚函数相关信息表VirtualTabjk中,其中,所述指针类型变量Vfunjkt表示第j个虚表结构体变量Vj中第k个成员数组对应类的虚表中的第t-1个虚函数,t=2,…,Mjk。所述步骤3中所述模拟执行具体包括步骤:步骤3_1、根据所述静态分析入口函数的基本块顺序队列,将队头基本块设置为当前基本块;步骤3_2、设置当前基本块中的第一条指令为当前指令;步骤3_3、对所述当前指令进行仿真地址分析,获得中间代码模拟执行至所述当前指令过程中,仿真地址上存放的变量指针、函数指针、虚函数信息,并依次存放至变量指针关系表R1、函数指针关系表R2、虚函数关系表R3中;步骤3_4、如果所述当前指令为函数调用指令,则根据所述变量指针关系表R1、函数指针关系表R2、虚函数关系表R3,分析出所述函数调用指令实际调用的函数,并记录下函数的调用关系,再将所述静态分析入口函数设置为所述实际调用的函数后,递归执行步骤3_1至步骤3_4模拟执行过程;否则,执行步骤3_5;步骤3_5、如果所述当前基本块中仍存在未处理的指令,将当前指令的下一条指令置为当前指令,再执行步骤3_3;否则,执行步骤3_6;步骤3_6、如果所述静态分析入口函数的基本块顺序队列中仍存在未处理的基本块,则将当前基本块的下一个基本块置为当前基本块,再执行步骤3_1。所述步骤3_3是在模拟执行过程开始时,给未处理过的指令分配仿真内存后,按如下方式进行仿真地址分析:如果当前指令为取元素地址指令,则针对取元素地址指令的每个维度,获取每个维度上的操作数数值,并分别与相应操作数的内存对齐后所得到本文档来自技高网...

【技术保护点】
1.一种适用于虚函数和函数指针的静态函数调用图构建方法,其特征是按如下步骤进行:步骤1、获取源程序的中间代码;步骤2、获取中间代码中的关键信息,所述关键信息包括基本块顺序队列以及虚函数相关信息;步骤3、指定静态分析入口函数,并基于所述关键信息,对所述中间代码进行模拟执行,分析出所述中间代码中的函数调用指令调用的实际函数,同时记录下函数调用关系;步骤4、根据所述函数调用关系,构建出静态函数调用图。

【技术特征摘要】
1.一种适用于虚函数和函数指针的静态函数调用图构建方法,其特征是按如下步骤进行:步骤1、获取源程序的中间代码;步骤2、获取中间代码中的关键信息,所述关键信息包括基本块顺序队列以及虚函数相关信息;步骤3、指定静态分析入口函数,并基于所述关键信息,对所述中间代码进行模拟执行,分析出所述中间代码中的函数调用指令调用的实际函数,同时记录下函数调用关系;步骤4、根据所述函数调用关系,构建出静态函数调用图。2.根据权利要求1所述的适用于虚函数和函数指针的静态函数调用图构建方法,其特征在于,所述步骤2中是按如下过程获取基本块顺序队列:步骤2A_1、获取所述中间代码中第i个函数Fi所对应的控制流图CFGi,并根据所述控制流图CFGi得到CFGi所对应的入口基本块EntryBBi;i=1,2,…,FN,FN为中间代码中函数的总个数;设置所述入口基本块EntryBBi为当前基本块,并将所述控制流图CFGi中所有循环的标识符记为“False”,表示未遍历到相应循环;步骤2A_2、如果当前基本块为循环L的头基本块,则执行步骤2A_3,否则执行步骤2A_6;步骤2A_3、如果所述当前基本块所在的循环L的标识符为“False”,则执行步骤2A_4,否则执行步骤2A_5;步骤2A_4、将当前基本块加入第i个基本块顺序队列BBOrderQi,并将当前基本块的后继基本块中处于循环L中的后继基本块设为当前基本块,将未处于循环L中的后继基本块压入第i个未处理栈UnProcessSi中,再将所述循环L的标识符置为“True”后,返回执行步骤2A_2;步骤2A_5、如果所述第i个未处理栈UnProcessSi为非空栈,则弹出所述第i个未处理栈UnProcessSi中栈顶的基本块,并将栈顶的基本块设置当前基本块后,执行步骤2A_2;步骤2A_6、将当前基本块加入所述第i个基本块顺序队列BBOrderQi中,如果当前基本块存在后继基本块,且后续基本块满足先序条件,则将满足先序条件的任意一个后继基本块为当前基本块,将其余后继基本块依次压入所述第i个未处理栈UnProcessSi中,再返回步骤2A_2执行,否则,执行步骤2A_5;所述先序条件为:后继基本块的前驱基本块均在所述第i个基本块顺序队列BBOrderQi中。3.根据权利要求1所述的适用于虚函数和函数指针的静态函数调用图构建方法,其特征在于,所述步骤2中是按如下过程获取所述虚函数相关信息:步骤2B_1、定义中间代码中第j个虚表结构体变量为Vj,Vj[k]表示第j个虚表结构体变量Vj中第k个成员数组,且每个成员数组均对应一个类,Vj[k][t]表示第j个虚表结构体变量Vj中第k个成员数组的第t个元素,其中j=1,2,…,N;N为虚表结构体变量的总个数,k=1,2,…,Mj,Mj为第j个虚表结构体变量Vj中成员数组的总个数,t=1,2,…,Mjk,Mjk为第j个虚表结构体变量Vj中第k个成员数组的元素总个数;步骤2B_2、将第j个虚表结构体变量Vj中第k个成员数组的第1个元素Vj[k][1]转换成整型变量VPtrOffsetjk,以第j个虚表结构体变量Vj对应的类为键,以所述整型变量VPtrOffsetjk为值,构建键值对Pair1,并将键值对Pair1加入第j个虚表结构体变量Vj对应的虚表指针偏移表VirtualPtrj中,其中所述整型变量VPtrOffsetjk表示第k个虚表指针在所述第j个虚表结构体变量Vj所对应的类创建出的对象的内存布局中的偏移字节数;步骤2B_3、将第j个虚表结构体变量Vj中第k个成员数组的第t个元素Vj[k][t]转换成函数指针类型变量Vfunjkt,以偏移字节数Vj[k][1]为键,以所述指针类型变量Vfunjkt为值...

【专利技术属性】
技术研发人员:顾乃杰张帆苏俊杰
申请(专利权)人:中国科学技术大学
类型:发明
国别省市:安徽,34

网友询问留言 已有0条评论
  • 还没有人留言评论。发表了对其他浏览者有用的留言会获得科技券。

1