基于智能电网内部数据流分析的内存泄露检测方法研究

2022-01-12 04:45刘福来
信息安全研究 2022年1期
关键词:数据流内存电网

陈 畅 刘福来

(广东电网有限责任公司广州供电局 广州 510620)

(change.c@163.com)

随着社会与网络技术的飞速发展,智能电网正在深度影响着每个人的生活,其发展正从发电、输电、变电、配电、用电和调度各个环节改变着传统的电网模式[1].建设高效、环保、安全的智能电网成为我国能源安全新战略.然而想要实现这一目标,在我国现有条件背景的支持下,还需要提高针对性的安全加固手段,包括从芯片、操作系统、功能运用各层级系统化的安全评估体系.同时,利用芯片设计改变芯片运算逻辑的硬件木马应运而生,它对电网系统的攻击性是巨大的,因此要保证智能电网系统的稳定运行,意味着对二次系统所管理资源的安全性、保密性、完整性提出了新的挑战.

1) 研究背景

经历了长时间的发展和市场的检验,二次系统的特点逐渐凸显,首先要保证系统信息的机密性,只有授权人员才能通过计算机访问系统资源,其次要保证数据信息是完整的,未经授权不得更改.

控制指令被窃取,顾名思义就是主站命令参数设置无法安全鉴别和保持数据完整性,对变电站失去了控制,即使人员操作失误也无法识别,易引发变电站事故,如果自动化装置中的软件配置未使用统一规范,或者设备厂家携带的U盘不安全,就会给变电站自动化装置带来很大隐患.控制指令被窃取的配置管理正确性依赖于厂家,即工程备份不可控.

内存泄露的本质是某些位置的内存无法控制或利用,对于软件系统来说,偶尔发生1次内存泄露并不会产生特别大的危害,用户可能都不会察觉到,或者对于整个系统并没有产生大的影响.真正的危害是内存泄露的累积,因为内存泄露会导致某些内存单元里存放着无用的或者无意义的数据,从而变得不可利用.随着内存泄露的堆积,不可利用的内存单元越来越多,相对地系统可利用的内存资源就越来越少,最终导致系统卡顿,甚至直接导致系统崩溃.

2) 相关工作

目前,变电站是专业密集、设备密集的重资产主体.国内智能站通过10多年的试点建设,已经研究出集采集信息、测量、计量等基本功能于一体的实时自动控制电网.因此,智能电网具有空间维度上复杂的动态性、不确定性、非线性等特点[2].例如南方电网,运用组网跳闸模式,使信息共享更为高效,已初具智能站技术规范体系.然而自动化安全装置也存在着多种多样的安全问题,主要有:不能完全保障安全性的计算机平台安全机制、过于简单的自动化装置安全架构等.原因则更多样化,主要有:系统本身存在漏洞、使用人员安全意识薄弱无法抵挡黑客入侵及硬件架构不完善等.目前,嵌入式系统的安全机制应用广泛,国内外采用的方法也不尽相同,国内主要方法是使用防护、检测、恢复机制对系统进行安全保护,分析硬件行为从而达到保证信息系统安全可靠的目的.

要想有效地减少内存泄露,必须在充分了解内存泄露发生原理的基础上,对内存泄露进行准确地检测,从而排除内存泄露的隐患.目前相关领域研究主要集中在静态检测、动态检测以及静态和动态检测结合这3大方向.静态检测的关键是程序的控制流图,并以内存泄露的原理为基础设计算法,对程序控制流图进行检测[3].动态检测则是在程序运行的同时进行内存泄露的检测,相较于静态检测方法,动态检测程序运行过程中实时检测,准确率较高;缺点是需要执行目标代码,这就导致了对测试用例的依赖,还会导致部分代码未被执行到,运行开销可能会很大[4].

3) 本文主要成果

基于研究背景,本文结合C++的语言特点论述了电网特点以及内存泄露发生的原因,将研究过程分为预处理、中间模型构建以及检测分析3个部分,结合示例代码分别对各个部分进行详细的方法设计说明,展示了基于数据流分析的安全漏洞检测方法的基本思路.最后基于研究的内存检测方法,进行多组实验,覆盖全部漏洞的实际情况,对研究方法进行测试,并分析实验结果.

1 内存泄露与数据流

在理解、分析内存泄露之前,首先应该了解C++对于内存如何进行管理.C++之所以具有灵活、高性能的特点,这与其灵活的内存管理机制是分不开的.且C++将系统分配的内存分为5个区:栈、堆、自由存储区、全局静态存储区、常量存储区[5].

1.1 内存泄露

内存泄露作为一种常见的程序缺陷,因其特性经常不被设计人员重视,如果不加以重视,内存泄露会造成严重的后果,轻则造成电网程序卡顿,重则导致整个二次系统的崩溃.

内存泄露的具体概念是:在程序运行过程中,已经动态分配的内存单元,由于错误释放或未释放等原因,导致这部分内存不能再次使用,从而影响了电网程序的运行,严重的可能会导致系统崩溃.内存泄露具有隐蔽性、累积性,且在某些情况下具有偶发性.

1.1.1 产生原因

C/C++作为允许显式动态内存分配的语言,程序设计人员可以手动分配智能电网系统内存,因此具备了高效性、灵活性,但是随之而来的隐患就是内存泄露.

根据发生内存泄露的场景进行分类,内存泄露归纳为以下几种情况[6]:

1) 使用new和delete语句分别对类的对象构造函数和析构函数进行调用,实现对象的创建和销毁,但是由于开发人员的失误,new和delete语句没有相应进行匹配;

2) 对于嵌套的对象指针的不正确操作,导致指针混乱;

3) 通过delete语句释放对象数组时错误地使用,或者没有使用方括号[];

4) 混淆对象数组与指向对象的指针数组;

5) 复制构造函数的缺失.

1.1.2 分类

如果根据发生的形式和频率分类,内存泄露可以分为常发性内存泄露、偶发性内存泄露、一次性内存泄露、隐式内存泄露4类.

1.2 数据流分析

数据流分析通常用于程序没有运行时静态分析源代码,以预测程序动态运行时的过程.数据流分析并不是真正的运行程序,而是在运行之前进行静态地分析,预测程序真正执行时的相关信息.数据流分析的基础是程序控制流图,它将程序所有可能的执行路径记录下来,程序实际运行时执行的路径会根据赋值变化.

2 基于数据流分析的内存泄露检测

本文提出一种基于数据流分析的内存泄露检测,该方法包括3部分:预处理部分、数据存储部分以及检测部分,如图1所示:

图1 方法总体设计

2.1 预处理

预处理,就是需要对内存泄露检测的目标代码进行预处理,以达到为后续数据存储部分作铺垫的目的.为了能够通过数据流分析检测目标代码的内存泄露,对目标代码进行合适的预处理是必不可少的环节.如图2所示,在本文研究中,对目标代码的预处理主要包括词法、语法分析,提取抽象语法树以及生成程序控制流图几个部分.

图2 预处理阶段

2.1.1 提取抽象语法树

抽象语法树将源代码语法结构通过抽象树的形式表示出来,常作为中间表示进行分析.其中,树中的每一个节点代表源代码的一个语法结构.同时它也是程序源代码的一种中间结构,需要进行语法分析,且作为连接语法分析和后端的接口,能够表示语法本身的自然结构,对后端的操作不产生影响[7].

2.1.2 生成控制流图

控制流图是一种重要的数据结构,主要进行程序分析和源代码结构分析,可以由源代码的抽象语法树得到.数据在程序中流动需要有依附,数据流依附程序的控制流,即数据的流动沿着控制流图中程序的执行路径流动[8].

将代码语句抽象为树结构,得到程序流程图,如图3(a)所示.流程图清晰反映程序运行的具体步骤,然后经过对流程图简化得到更加突出控制流结构的控制流图,如图3(b)所示.

图3 程序流程图和控制流图

2.2 XML中间模型

目标代码经过语法分析得到抽象语法树,画出程序控制流图,通过自定义的程序控制流图,可以实现对需要的信息(关于内存操作的语句信息)的提取.但是想要进一步地设计算法对这些进行处理,达到电网内存泄露检测的目的,控制流图的信息并不能被直接利用.本文研究中,在能够完整地存储每个节点提取出来的信息的前提下,还要体现节点之间的关系,并且方便解析、读取,因此选择XML(extensible markup language)作为中间模型的构建基础.

XML是一种可拓展的标志性语言,关键在于能对每一个数据打上标签,以描述、标记不同的数据.同一种标签包括开始标签和结束标签,中间是该标签定义的数据,同时在标签中又可以嵌套1个或多个标签,这样就可以体现出数据之间的关系.

本文选择利用TinyXML开源库进行XML中间模型的解析,其主要原因是TinyXML的基础是文档对象模型,这种树结构在易于理解的同时,也为用户提供了用于访问的面向对象接口[9].XML中间模型解析(写入和读取)的基础是多个面向对象的访问接口,访问XML文档信息时使用分层对象模型,这些分层对象模型根据XML的文档结构形成1棵节点树,如图4所示.其中,各节点表示的访问接口可归纳如下:

图4 TinyXML

1) TiXmlDocument.文档类,代表了整个XML文件.

2) TiXmlDeclaration.声明类,表示文件的声明部分.

3) TiXmlComment.注释类,表示文件的注释部分.

4) TiXmlElement.元素类,是文件的主要部分,支持嵌套结构,一般使用这种结构对存储信息进行分类,可以包含属性类和文本类.

5) TiXmlAttribute/TiXmlAttributeSet.元素属性,一般嵌套在元素中,记录该元素的一些属性.

6) TiXmlText.文本对象,嵌套在某个元素内部.

2.3 分析与检测

智能电网系统程序中比较常见的问题是堆内存泄露,malloc,new等操作符用于程序分配堆内存,使用之后必须调用free或delete显式释放分配的堆内存.如果由于程序设计的疏忽导致这部分堆内存没有释放或者错误释放,使这部分内存无法再次使用,就会造成内存泄露[10].

在本文研究中,基于数据流分析的内存泄露故障检测思路如下:

1) 根据目标代码中与内存操作相关语句的控制流图,生成形式化定义的控制流图节点组成的所有可达路径.

2) 根据已经生成的可达路径,构建每一条路径对应的XML中间模型,存储路径上关于内存操作的可用信息,方便后续模拟内存操作.

3) 通过哈希表模拟路径中每一个节点对内存的操作,例如分配、释放堆内存.

4) 在一条路径上所有的节点对内存操作全部进行之后,通过判断哈希表的状态,推断目标代码是否存在内存泄露.

操作过程如表1所示:

表1 内存操作过程

C++中常见的内存操作有增(add)、删(delete)、查(get)、改(modify),这也可以对应于哈希表中的操作,可以使用哈希表的操作模拟C++程序中内存的操作,处理过程如表2所示:

表2 哈希表处理过程

3 实验验证

3.1 实验环境

本文开展的实验所用设备是个人电脑,如表3所示.其配置如下:操作系统使用Windows10家庭中文版,处理器由12个Intel®CoreTMCPU 组成,型号为i7-9750H,内存大小为8 GB,显卡型号为NVIDIA GeForce GTX 1650,显卡内存为4 GB.

表3 实验设备

本实验采用的开发平台是Visual Studio 2019,使用的编程语言是C++.通过在Visual Studio上安装C++的桌面开发工作负载,构建本次实验的基本开发环境.除此之外,本实验使用了大量的C++第三方库以及开源工具,主要有TinyXML和cppcheck.

3.2 实验内容

本文研究的内容是基于数据流分析的内存泄露检测方法,这种方法可以直接得到检测结果,无需程序运行,但该方法的缺点是存在误报的风险.本文研究的实验验证分为3个阶段:

1) 词法分析、语法分析简单实现;

2) 实现对XML中间模型的解析,验证其可用性;

3) 测试该方法对内存泄露检测的可靠性.

3.3 实验结果与分析

3.3.1 词法分析及语法分析简单实现

抽象语法树的生成主要分为3个部分:词法分析、语法分析以及树的生成.本文基于C++程序的特点,分别实现了简易的词法分析器和语法分析器.

首先编制一个读单词过程[11],从输入的源程序中,识别出各个具有独立意义的单词,如算法1所示.即基本保留字、标识符、常数、运算符、分隔符5大类,并依次输出各个单词的内部编码及单词符号自身值,如表4所示:

表4 词法分析结果

算法1.词法分析.

输入:inti,ans; charc; scanc; doubleb=1.5; floatf.

for (i=0;i<5;i=i+1)

ans=ans+1;

end for

输出:printans; return 0.

语法分析时,使用递归下降分析法对算术表达式(包括+,-,*,/,())进行分析,一次性来判断该表达式正确与否,得到简单语法分析结果[12].如表5所示:

表5 语法分析结果

3.3.2 XML中间模型解析

XML中间模型解析原理基于开源的TinyXML库,利用文档对象一次性将XML文件导入到内存中,根据文档内容建立树结构,实现存储的功能.同时通过分析利用TinyXML库,按照本文预先定义的节点形式实现XML中间模型的解析,生成控制流图节点XML模型表示结果,如图5所示:

图5 XML模型解析结果

3.3.3 内存泄露检测方法验证

本文实验借助开源工具cppcheck部分模块,实现了基于数据流分析的内存泄露检测方法,测试用例程序如图6所示:

图6 待测目标代码

除此之外,结合实际程序开发过程的需求,将内存泄露工具与visual studio的使用结合起来,通过外部工具的方式实现在visual studio中直接调用该工具进行内存泄露的检测[10].

该程序第15行处存在内存泄露.实验证明在不运行程序的情况下,该工具能够准确地检测出内存泄露的风险,并且显示出存在内存泄露的代码行数,如图7所示:

图7 内存泄露检测结果

4 结 论

本文提出一种基于电网操作系统中数据流分析的内存泄露检测方法,在广泛查阅资料和借助开源工具的基础上自主实现了目标代码的词法分析、语法分析.设计了一种规范的自定义XML中间模型用于存储相关信息.同时基于特定算法实现内存泄露静态检测.实验表明,该方法能有效检测内存泄露问题,在自动化测试、程序静态检测等方面具有实际意义[13].

如今电网程序的并行化程度和复杂性逐渐提高,基于电网系统中数据流分析的内存泄露检测方法在准确性方面还存在一定的限制.因此,如何进一步提高检测效率和可靠性是后续研究的目标.另外,对于内存泄露的检测,使用静态检测和动态检测结合的思想[14]是通过运行之前的静态检测找出内存泄露风险点,然后在运行的同时对风险点进行进一步检查.动态与静态结合检测既可以减少检测对于程序运行的影响,又对检测的可靠性和准确率提供保证,这也是未来对于内存泄露检测的研究趋势.

猜你喜欢
数据流内存电网
优先级驱动的泛化航电网络实时性能分析
数字化电网技术在电网规划设计中的应用
穿越电网
汽车维修数据流基础(上)
汽车维修数据流基础(下)
笔记本内存已经在涨价了,但幅度不大,升级扩容无须等待
“春夏秋冬”的内存
数据流安全查询技术综述
内存搭配DDR4、DDR3L还是DDR3?
上网本为什么只有1GB?