基于二进制代码植入技术的软件运行时监控方法与流程

文档序号:12120557阅读:415来源:国知局
基于二进制代码植入技术的软件运行时监控方法与流程

本发明属于计算机技术领域,更进一步涉及软件安全技术领域中的一种基于二进制代码植入的软件运行时监控方法。本发明用于windows环境下的PE格式文件或linux环境下的ELF格式文件,使用静态二进制代码植入技术,对软件的运行轨迹进行有效的监控。



背景技术:

随着计算机技术的发展,计算机软件已经渗透到国民经济的各个领域,一些关键软件一旦遭到破坏,会对用户造成经济和安全上的威胁,因此软件的安全性问题越来越凸显其重要性。针对特定软件的安全漏洞,运行恶意代码能够获得访问非法数据的权限。典型的安全漏洞包括缓冲区溢出漏洞。

软件运行时监控方法是一种在软件实际运行阶段,通过获得软件的运行状态信息和轨迹,并与事先分析出的预期运行轨迹进行比较,判断软件运行时安全性的一种技术。

通常可利用静态分析工具提取软件的控制流信息,比如函数调用图、控制流图等。根据拟分析目标代码的类型,软件静态分析可分为基于源代码的分析和基于二进制码的分析。针对源代码分析直接对源代码程序表达式及数据结构进行分析;二进制分析在机器代码级上进行,分析可执行代码的中间表达式。基于源代码的分析只能分析出源代码文件所包含的控制流信息,无法分析出该软件所依赖的静态库和动态库文件包含的控制流信息。基于二进制码的分析,不仅可以分析出软件可执行文件内的控制流信息,还可以分析出该软件所依赖的动态库文件包含的一些控制流信息。

软件运行时的轨迹可通过代码植入技术获取。代码植入技术分为基于源代码的代码植入和基于二进制的植入。其中,基于二进制的植入技术又分为动态植入和静态植入。与动态植入相比,静态植入在程序执行前完成,因而静态植入产生的运行时开销较小,同时静态植入实现较为简单。

北京航空航天大学在其申请的专利“基于函数调用图的并行化安全漏洞检测方法”(专利申请号:201110417105.3,申请公布号:102567200A)中公开了一种漏洞检测方法。该方法使用了基于源代码的分析方法,生成了源代码文件对应模块内的函数调用图,只对源代码文件存在的安全漏洞进行检测。该方法的不足之处是,无法分析源代码所依赖的静态库和动态库文件对应模块内的函数调用关系和函数内的控制流信息,无法对源代码文件依赖的静态库和动态库存在的安全漏洞进行检测。

常州云博软件工程技术有限公司在其申请的专利“一种软件探测器的软件探测方法”(专利申请号:201210054220.3,申请公布号:102646068A)中公开了一种对应用软件运行时程序流程信息进行实时探测的方法。该方法利用了基于源代码的代码植入技术,可以对计算机系统内的运行时软件进行实时监控。该方法的不足之处是,新植入的代码要编译后才能执行,无法避免较大运行时开销。



技术实现要素:

本发明的目的在于克服上述已有技术的不足,提出一种基于二进制代码植入的软件运行时监控方法。

为实现上述目的,本发明的思路是,利用静态二进制分析工具分析出被监控软件内函数之间的调用关系和函数内部的控制流信息,并生成函数调用图G(E,F)和控制流图G(B,E),然后利用函数调用图G(E,F)构造一个有限状态机FSM(Z,S,T,S0,A),用控制流图G(B,E)初始化表格TABbb。状态机中每一个状态分别对应函数调用图G(E,F)中的每个函数,同时状态机中加入一个无效状态。状态机中任意两个有效状态之间的迁移关系代表对应函数之间的有效函数调用或函数返回关系,任何非法的函数调用或返回均导致有限状态机迁移到无效状态。表格TABbb包含的行数与对应函数内基本块数量相同,每行包含三个字段:(1)分别代表一个基本块的索引,(2)基本块入口地址相对基本块所在函数的入口地址的相对偏移量,(3)基本块后继块的索引。利用静态二进制代码植入工具将包含监控代码的依赖库加载到被监控软件的进程地址空间中,并在被监控软件的特定位置植入对监控函数的调用语句。当被监控软件运行过程中发生函数调用、函数返回或函数内控制流变化时,会调用依赖库中的监控函数,监控函数通过查有限状态机和TABbb来判断被监控软件运行是否与事先分析预测的运行轨迹一致。

实现本发明目的的具体步骤如下:

(1)提取函数调用关系:

利用静态二进制分析工具,提取被监控软件可执行文件及其依赖库文件中的函数调用关系,并将函数调用关系存储到函数调用图G(E,F)数据结构中,其中,E表示有向边的集合,F表示函数调用图G(E,F)内所有函数的集合;

(2)提取函数内部控制流信息:

利用静态二进制分析工具,提取函数调用图G(E,F)中每个函数的基本块及控制流信息,并将基于基本块的控制流信息存储到控制流图G(B,E)数据结构中,其中,E表示有向边的集合,B表示控制流图G(B,E)中基本块的集合;

(3)构造一个有限状态机:

(3a)将状态0添加到有限状态机的状态的非空有限集合S中;

(3b)对函数调用图G(E,F)中的每个函数进行编号,其中,第i个函数编号为i;

(3c)将函数调用图G(E,F)中的main(·)函数对应的状态1赋给有限状态机的初始状态S0;

(3d)对满足fi∈F的函数fi,将状态i-分别添加到有限状态机的状态集合S和有限状态机的最终状态集合A中;

(3e)对fi∈F、fj∈F的fi和fj,如果存在从函数fi指向函数fj的一条有向边,则将以下状态迁移添加到状态迁移函数T中:

Z0=0,Z1=j→Nextstate[i]=状态j

Z0=1,Z1=i→Nextstate[j]=状态i

其中,Z0和Z1表示有限状态机的输入字母,Nextstate[i]表示状态i的下一个状态,Nextstate[j]表示状态j的下一个状态,i和j分别是函数fi和函数fj的编号;

(3f)对于所有的下一状态为空的状态,将其下一状态设置为状态0;

(4)初始化表格TABbb:

将函数调用图G(E,F)中的每个函数对应一个控制流图G(B,E),将函数调用图G(E,F)中的每个函数对应一个初始化的表格TABbb,其中,初始化表格TABbb中的第i行对应控制流图G(B,E)中第i个基本块;每行包含三个字段index、offset、sucs,字段index表示第i个基本块的索引,字段offset表示第i个基本块的入口地址相对于第i个基本块所在函数入口地址的相对偏移量,字段sucs表示第i个基本块的后继基本块的索引;

(5)初始化表格TABstart和TABret:

(5a)当被监控软件加载后,获取函数调用图G(E,F)中所有函数的入口地址;

(5b)将第i个函数的相关信息添加到表格TABstart的第i行中;其中,表格TABstart中的第i行对应函数调用图G(E,F)中的第i个函数,每行包含三个字段addr、index、ptr,字段addr表示第i个函数的入口地址,字段index表示第i个函数的函数编号,字段ptr表示第i个函数对应表格TABbb的指针;

(5c)将值0、-1、-1添加到表格TABret的第一行中,表格TABret中的每行对应被监控软件执行过程中,数调用图G(E,F)中被调用的的函数;

(6)初始化整型变量Cur_F和Cur_B:

将函数调用图G(E,F)中main(·)函数的编号1赋给整型变量Cur_F,将该main(·)函数中第一个基本块的编号1赋给整型变量Cur_B;

(7)植入代码:

(7a)利用二进制代码的静态植入工具,将包含监控代码的动态库加载到被监控软件的进程地址空间中;

(7b)根据函数名查找动态库中的监控函数,并构造对监控函数的调用语句;

(7c)利用代码植入工具,根据函数调用图G(E,F)和控制流图G(B,E)中的信息,分析被监控软件中的代码植入点;

(7d)将构造的调用语句植入到对应的代码植入点;

(8)监控软件运行状态:

(8a)判断被监控软件是否执行到函数调用图G(E,F)中某个函数的入口位置,若是,则执行步骤(8b),否则,执行步骤(8f);

(8b)根据函数入口地址查表格TABstart,判断函数入口地址是否在表格TABstart中,若是,则将对应的函数编号和正整数0传给有限状态机,执行步骤(8c),否则,执行步骤(9);

(8c)判断有限状态机接收的函数编号是否为1,若是,则执行步骤(8d),否则,执行步骤(8e);

(8d)将有限状态机的当前状态设置为初始状态S0,执行步骤(8a);

(8e)判断有限状态机能否从当前状态迁移到接收编号对应的状态,若是,则有限状态机迁移到接收编号对应的状态,并将步骤(8b)中所获得的函数编号值赋给Cur_F,执行步骤(8a),否则,有限状态机迁移到无效状态0,执行步骤(9);

(8f)判断被监控软件是否执行到函数调用图G(E,F)中函数内call指令位置,若是,则执行步骤(8g),否则,执行步骤(8h);

(8g)将函数调用call指令后的下一条指令的地址添加到TABret中;将函数调用call指令所在函数的编号、所在基本块的索引添加到TABret中,执行步骤(8a);

(8h)判断被监控软件是否执行到函数调用图G(E,F)中函数的出口点,若是,则执行步骤(8i),否则,执行步骤(8l);

(8i)判断表格TABret中最后一行中存储的地址值是否为0,如是,则执行步骤(9),否则,执行步骤(8j);

(8j)判断函数返回指令ret中返回地址值是否与表格TABret中最后一行中存储的地址值一致,若是,则执行步骤(8k),否则,执行步骤(9);

(8k)将表格TABret最后一行对应函数的编号和正整数1传给有限状态机,判断有限状态机能否从当前状态迁移到接收编号对应的状态,若是,则有限状态机迁移到接收编号对应的状态,并将表格TABret最后一行对应函数的编号赋给整型变量Cur_F,表格TABret中最后一行中存储的基本块索引值赋给整型变量Cur_B,删除表格TABret中的最后一条记录,执行步骤(8a),否则,有限状态机迁移到无效状态0,执行步骤(9);

(8l)当被监控软件执行到控制流图G(B,E)中基本块的入口位置,计算该基本块入口点相对于包含该基本块的函数的入口点的相对偏移量;

(8m)判断计算出来的偏移量是否为0,若是,则执行步骤(8n),否则,执行步骤(8o);

(8n)将正整数1赋给变量Cur_B,执行步骤(8a);

(8o)判断该偏量是否是Cur_B对应基本块的后继块中一个的偏移量,若是,则将该后继块的编号赋给整型变量Cur_B,执行步骤(8a),否则执行步骤(9);

(9)结束监控。

本发明与现有技术相比具有以下优点:

第一,由于本发明采用了静态二进制分析工具,提取被监控软件文件及其依赖库文件中的函数调用关系,并将函数调用关系存储到函数调用图G(E,F)数据结构中,提取函数调用图G(E,F)中每个函数的基于基本块的控制流信息,不仅可以监控软件可执行文件对应的控制流,还可以监控软件所依赖动态库文件对应的控制流。从而克服了现有技术只能对软件源代码文件对应控制流进行监控的不足,使得本发明的监控方法具有更全面的优点。

第二,由于本发明利用二进制的静态代码植入工具,将包含监控代码的动态库加载到被监控软件的进程地址空间里,只对软件代码进行静态分析,找出代码植入点,而且静态植入过程在软件执行之前就已完成,从而克服了现有技术产生较高运行时开销的不足,使得本发明具有运行时开销低,实现较为简单的特点。

具体实施方式

附图说明

图1为本发明的整体流程图;

图2为本发明监控软件运行状态步骤的流程图。

具体实施方式

下面结合附图对本发明做进一步的描述。

参照附图1,对本发明的具体步骤做进一步的描述。

步骤1,提取函数调用关系。

利用静态二进制分析工具,提取被监控软件可执行文件及其依赖库文件中的函数调用关系,并将函数调用关系存储到函数调用图G(E,F)数据结构中,其中,E表示有向边的集合,F表示函数调用图G(E,F)内所有函数的集合。

步骤2,提取函数内部控制流信息。

利用静态二进制分析工具,提取函数调用图G(E,F)中每个函数的基本块及控制流信息,并将基于基本块的控制流信息存储到控制流图G(B,E)数据结构中,其中,E表示有向边的集合,B表示控制流图G(B,E)中基本块的集合。

步骤3,构造一个有限状态机。

将状态0添加到有限状态机的状态的非空有限集合S中。

对函数调用图G(E,F)中的每个函数进行编号,其中,第i个函数编号为i。

将函数调用图G(E,F)中的main(·)函数对应的状态1赋给有限状态机的初始状态S0。

对满足fi∈F的函数fi,将状态i-分别添加到有限状态机的状态集合S和有限状态机的最终状态集合A中。

对fi∈F、fj∈F的fi和fj,如果存在从函数fi指向函数fj的一条有向边,则将以下状态迁移添加到状态迁移函数T中:

Z0=0,Z1=j→Nextstate[i]=状态j

Z0=1,Z1=i→Nextstate[j]=状态i

其中,Z0和Z1表示有限状态机的输入字母,Nextstate[i]表示状态i的下一个状态,Nextstate[j]表示状态j的下一个状态,i和j分别是函数fi和函数fj的编号。

对于所有的下一状态为空的状态,将其下一状态设置为状态0。

对于包含N个函数的函数调用图G(E,F),本算法将会构造包含N+1个状态的有限状态机FSM(Z,S,T,S0,A),状态0代表无效状态,其余N个状态分别对应函数调用图G(E,F)中的N个函数,任何两个函数之间的有效函数调用或返回关系会映射到状态机中对应状态之间的迁移关系,任何非法的函数调用或返回会导致有限状态机迁移到无效状态;其中,Z表示状态机的输入字母表,S表示状态机的状态的非空有限集合,S0表示状态机的初始状态,A表示状态机的最终状态的集合,T表示状态机的状态迁移关函数:S×Z→S,状态机的输入字母表Z包含两个字母Z0和Z1,Z0取0或1,Z1取1到N中的一个正整数。

步骤4,初始化表格TABbb。

将函数调用图G(E,F)中的每个函数对应一个控制流图G(B,E),将函数调用图G(E,F)中的每个函数对应一个初始化的表格TABbb,其中,初始化表格TABbb中的第i行对应控制流图G(B,E)中第i个基本块;每行包含三个字段index、offset、sucs,字段index表示第i个基本块的索引,字段offset表示第i个基本块的入口地址相对于第i个基本块所在函数入口地址的相对偏移量,字段sucs表示第i个基本块的后继基本块的索引。

步骤5,初始化表格TABstart和TABret。

当被监控软件加载后,获取函数调用图G(E,F)中所有函数的入口地址。

将第i个函数的相关信息添加到表格TABstart的第i行中;其中,表格TABstart中的第i行对应函数调用图G(E,F)中的第i个函数,每行包含三个字段addr、index、ptr,字段addr表示第i个函数的入口地址,字段index表示第i个函数的函数编号,字段ptr表示第i个函数对应表格TABbb的指针。

将值0、-1、-1添加到表格TABret的第一行中,表格TABret中的每行对应被监控软件执行过程中,数调用图G(E,F)中被调用的的函数。

步骤6,初始化整型变量Cur_F和Cur_B。

将函数调用图G(E,F)中main(·)函数的编号1赋给整型变量Cur_F,将该main(·)函数中第一个基本块的编号1赋给整型变量Cur_B。

步骤7,植入代码。

利用二进制代码的静态植入工具,将包含监控代码的动态库加载到被监控软件的进程地址空间中。

根据函数名查找动态库中的监控函数,并构造对监控函数的调用语句。

利用代码植入工具,根据函数调用图G(E,F)和控制流图G(B,E)中的信息,分析被监控软件中的代码植入点。

代码植入点包括:函数调用图G(E,F)中函数的入口点BPatch_entry,函数出口点BPatch_exit,函数中包含静态call指令点BPatch_subroutine以及控制流图G(B,E)中基本块的入口点BPatch_locBasicBlockEntry。

将构造的调用语句植入到对应的代码植入点。

在函数调用图G(E,F)中函数的入口点BPatch_entry植入对函数调用关系合法性检验函数的调用语句,该函数的功能是:根据函数入口地址查表格TABstart,若该地址在TABstart中则将对应的函数编号传给有限状态机FSM,FSM来查是否存在从当前状态到接受编号对应状态的迁移关系,若有说明函数调用是合法。在函数调用图G(E,F)中函数的入口点BPatch_exit点植入对函数返回关系合法性检验函数的调用语句,该函数的功能是:根据ret指令中的函数返回地址查表格TABret,若表格TABret最后一行中所记录的返回地址是0,说明被监控软件执行到函数调用图G(E,F)中main(·)函数的出口点,结束执行,否则,判断表格TABret最后一行中所记录的返回地址是否与ret指令中的返回地址相同,若是,则将最后一行对应函数的编号传给有限状态机FSM,FSM来查是否存在从当前状态到接受编号对应状态的迁移关系,若存在说明函数返回是合法的,否则结束监控。在函数调用图G(E,F)中函数的call指令点BPatch_subroutine植入对返回信息存储函数的调用语句,当执行完call指令后,该函数会将call指令下一条指令的地址、包含此call指令的函数编号、变量Cur_F和Cur_B存储到表格TABret的最后一行中。在控制流图G(B,E)中基本块的入口点BPatch_locBasicBlockEntry植入对函数内部控制流合法性检验函数的调用语句,该函数的功能是根据基本块的入口地址和基本块所在函数的入口地址计算基本块入口点对于函数入口点的相对偏移量,再根据变量Cur_F和Cur_B来查基本块所在函数对应的表格TABbb,若该偏移量是Cur_B对应基本块的后继块中某一个的相对偏移量,则说明控制流改变是合法的,更新Cur_B的值,否则,监控结束。

参照附图2,对本发明监控软件运行状态步骤的流程做进一步的描述。

步骤8,监控软件运行状态。

(8a)判断被监控软件是否执行到函数调用图G(E,F)中某个函数的入口位置,若是,则执行步骤(8b),否则,执行步骤(8f)。

(8b)根据函数入口地址查表格TABstart,判断函数入口地址是否在表格TABstart中,若是,则将对应的函数编号和正整数0传给有限状态机,执行步骤(8c),否则,执行步骤9。

(8c)判断有限状态机接收的函数编号是否为1,若是,则执行步骤(8d),否则,执行步骤(8e)。

(8d)将有限状态机的当前状态设置为初始状态S0,执行步骤(8a)。

(8e)判断有限状态机能否从当前状态迁移到接收编号对应的状态,若是,则有限状态机迁移到接收编号对应的状态,并将步骤(8b)中所获得的函数编号值赋给Cur_F,执行步骤(8a),否则,有限状态机迁移到无效状态0,执行步骤9;

(8f)判断被监控软件是否执行到函数调用图G(E,F)中函数内call指令位置,若是,则执行步骤(8g),否则,执行步骤(8h)。

(8g)将函数调用call指令后的下一条指令的地址添加到TABret中;将函数调用call指令所在函数的编号、所在基本块的索引添加到TABret中,执行步骤(8a)。

(8h)判断被监控软件是否执行到函数调用图G(E,F)中函数的出口点,若是,则执行步骤(8i),否则,执行步骤(8l)。

(8i)判断表格TABret中最后一行中存储的地址值是否为0,如是,则执行步骤9,否则,执行步骤(8j)。

(8j)判断函数返回指令ret中返回地址值是否与表格TABret中最后一行中存储的地址值一致,若是,则执行步骤(8k),否则,执行步骤9。

(8k)将表格TABret最后一行对应函数的编号和正整数1传给有限状态机,判断有限状态机能否从当前状态迁移到接收编号对应的状态,若是,则有限状态机迁移到接收编号对应的状态,并将表格TABret最后一行对应函数的编号赋给整型变量Cur_F,表格TABret中最后一行中存储的基本块索引值赋给整型变量Cur_B,删除表格TABret中的最后一条记录,执行步骤(8a),否则,有限状态机迁移到无效状态0,执行步骤9。

(8l)当被监控软件执行到控制流图G(B,E)中基本块的入口位置,计算该基本块入口点相对于包含该基本块的函数的入口点的相对偏移量。

(8m)判断计算出来的偏移量是否为0,若是,则执行步骤(8n),否则,执行步骤(8o)。

(8n)将正整数1赋给变量Cur_B,执行步骤(8a)。

(8o)判断该偏量是否是Cur_B对应基本块的后继块中一个的偏移量,若是,则将该后继块的编号赋给整型变量Cur_B,执行步骤(8a),否则执行步骤9。

步骤9,结束监控。

当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1