1、C 语言源代码静态检测工具设计与实现学 院 计算机学院专 业 计算机科学与技术班 级 04010101学 号 2010040101015姓 名 指导教师 负责教师沈阳航空航天大学2014 年 6 月沈阳航空航天大学毕业设计(论文)0摘 要随着信息社会的发展,网络的不安全问题越来越严重,其中许多安全问题都是由于软件本身存在安全漏洞所引起的,并且造成了巨大的经济损失。一方面是程序员编程上的疏忽,一方面也是相关语言没有提供完整的安全机制。在众多的语言中,C 语言也被认为是最容易遭到攻击的语言。所以代码的安全检查就变得极其重要。但是由于现代软件工程越来越复杂,致使传统的检查方法在准确度和效率上都不能满
2、足要求,所以代码的静态安全检测应运而生。本文将首先调研并介绍国内外的关于静态安全检测的研究现状以及代码安全检测技术的主要趋势,然后提出我们的构想与设计目标,详细论述了系统的需求分析、概要设计、详细设计与实现、系统测试等相关过程,通过使用 Python 语言整合开源的静态检测工具 Splint 和 Flawfinder,实现代码的静态安全检查以及生成分析图表等功能。关键词:安全检测;C 源代码;静态代码分析沈阳航空航天大学毕业设计(论文)1Development of C language source code static analysis toolAbstractWith the deve
3、lopment of the information society, the problem of Internet insecurity is becoming more and more serious. Many of these problems are due to the flaw of the software itself and therefore cause huge economic losses. On one hand, it is because of the programmers negligence on software producing, and on
4、 the other hand, it is also because the relative languages dose not provide a complete security mechanism. Among many languages, C language is believed as the most vulnerable one to be attacked. As a result, the code safety check seems very important. However, because the modern software engineering
5、 is becoming more and more complicated, the traditional check methods can not meet the requirement in accuracy and efficiency, so the static code analysis emerge as the times require.This paper will first investigate the current situation and main trend of the static code analysis at home and abroad
6、. And then put forward our ideas and design objectives. Discusses in detail about the system requirements analysis, preliminary design, detailed design and implementation, system testing and other related processes, integrating open source static detection tools Splint and Flawfinder through the use
7、 of the Python language, implement static security check code and generate analytic charts and other functions. Keywords: Safety testing; C source code; static code analysis沈阳航空航天大学毕业设计(论文)2目 录1 绪论 .61.1 研究背景 .61.2 设计目标 .71.2.1 主要内容 .71.2.2 设计要求 .71.3 国内外现状 .71.3.1 模型检验 .81.3.2 携带源代码 .81.3.3 词法扫描 .8
8、1.3.4 简单语义分析 .81.4 软件代码风险介绍与原理 .91.4.1 内存访问错 .91.4.2 缓冲区溢出 .101.4.3 竞争条件 .111.4.4 随机数滥用 .121.4.5 异常处理 .121.4.6 空指针引用 .121.5 技术简介 .131.5.1 Python 语言简介 .131.5.2 PyQt 图形类库简介 .131.5.3 SQLite 数据库简介 .132 需求分析 .152.1 用户需求 .152.2 系统需求 .152.2.1 实现代码静态安全分析需求 .152.2.2 代码检查工具基本控制需求 .152.2.3 待检测代码列表管理需求 .162.2.4
9、 检测代码工具参数设置需求 .16沈阳航空航天大学毕业设计(论文)32.2.5 图表化显示安全漏洞需求 .162.3 技术需求 .162.3.1 Eric5 集成开发环境 .162.3.2 Qt designer 图形开发环境 .162.3.3 Python 面向对象开发语言 .162.3.4 静态检测工具调研 .173 概要设计 .183.1 总体设计目标 .183.1.1 功能完备 .183.1.2 用户界面友好 .183.2 总体功能设计 .183.3 代码安全检测界面功能设计 .193.4 数据库存储设计 .193.4.1 SQLiteDatabase 数据库 .193.4.2 Spl
10、int 表设计 .203.4.3 Flawfinder 表设计 .204 详细设计 .224.1 代码检测功能模块设计 .224.1.1 代码的静态检查功能设计与实现 .224.1.2 待检测代码目录列表设计与实现 .244.1.3 结果显示界面设计与实现 .274.2 模式选择与参数的添加功能设计 .284.3 生成分析图表功能设计 .304.3.1 生成安全漏洞统计表格 .304.3.2 生成安全漏洞分析图表 .315 系统测试 .325.1 代码检测功能模块测试 .325.1.1 代码检查功能主界面测试 .325.1.2 待检测本地目录列表测试 .335.1.3 代码安全检测功能测试 .
11、335.2 模式选择与参数的设定功能测试 .34沈阳航空航天大学毕业设计(论文)45.2.1 命令行模式测试 .345.2.2 自定义模式测试 .355.3 生成分析图表功能测试 .36参考文献 .38致 谢 .39沈阳航空航天大学毕业设计(论文)51 绪论随着信息社会的发展,我们在享受计算机带来的方便快捷的同时,计算机软件的安全问题也愈演愈烈。这其中大部分的安全问题是软件本身存在安全漏洞所致,这些安全漏洞不仅造成了信息的泄露,也造成了巨大的经济损失。软件安全漏洞的频繁出现,一方面是一些程序员缺乏编写高质量代码的意识,另一方面,编程语言本身在设计上的不安全性也增加了程序员在无意中编写出存在安全
12、漏洞的代码的几率。在众多编程语言中,C/C+ 语言是目前公认的最容易引起安全问题的语言,黑客往往就利用这些安全问题产生的漏洞来绕过安全防范策略,以达到网络攻击的目的。针对这种现状,我们在程序测试的过程中,使用代码的静态安全检查工具对程序源代码进行安全检查成为了一种有效并且必要的方法。1.1 研究背景在信息社会中,互联网规模越来越大,在享受着网络带来的方便的同时,人们也不得不面临网络安全问题。据权威机构统计,目前因特网上 20%的企业的防火墙、80%的计算机网络包含严重的安全缺陷。研究表明,所有的入侵都是因为软件本身存在漏洞。当前的计算机软件系统越来越复杂,程序员难免会在设计时产生一些没有意识到
13、的安全漏洞,这些漏洞就经常被黑客利用来绕过安全防护策略,以达到自身的不正当目的。对程序源代码进行静态安全检查的目的就是在程序设计阶段之后,在系统正式运行之前通过分析源代码尽可能多的发现潜在的安全漏洞与安全缺陷。本节讨论 C 语言源代码的静态安全检查原理,首先对时下流行的安全漏洞做一个简介,并调研一些成熟的静态安全漏洞检查方法。C 语言是一个语法形式自由的语言,程序效率更高,更加贴近于计算机的底层。使用 C 语言能编写高性能程序,包括系统程序和应用程序,尤其是在航空领域,控制领域等对代码性能要求很高的领域,更是占有很高的地位。可是,C 语言与它支持的库本身就存在许多不安全的隐患,编程人员无意间的
14、设计失误就可能导致十分严重的结果,尤其是大型控制程序,网络系统程序,通讯设备程序等。但是传统的代码安全检查具有很大的不易操作性,很大的难度性。并且在软件系统工程日益庞沈阳航空航天大学毕业设计(论文)6大的今天,软件代码量不断的增多,原有的代码走查方式几乎成为不可能,效率低下的弱点逐渐暴露。静态源代码理论则应运而生,也是近些年来被研究与应用较多的的软件安全解决方案之一。它是指在软件开发的流程中,编程人员在写好源代码后,无需生成目标代码经编译器编译,而是使用一些静态安全扫描工具检测,找出代码中的安全漏洞,并且提出相应的解决方案。所以使用代码的静态安全检查具有很大的现实意义。另一方面,由于它面对的是
15、问题本身而非征兆,所以有时它比动态检测更加有效。1.2 设计目标1.2.1 主要内容静态源代码扫描是近年被人提及较多的软件应用安全解决方案之一,它是指在软件工程中,程序员在写好源代码后,无需经过编译器编译,而直接使用一些扫描工具对其进行扫描,找出代码当中存在的一些安全漏洞的解决方案。本项目研究任务如下:1静态代码分析工具调研,研究目前主流的静态代码分析工具和安全漏洞原理,调研目前最新的研究成果并形成研究报告。2静态代码分析工具研制:检查 C、C+程序潜在的安全隐患,并发现编译器不能发现的事情。编译环境为 GCC,测试用例为开源的 IpsecSSLSSHVPN,针对的操作系统为 Linux 内核
16、 2.6 和 3.0 版本。1.2.2 设计要求1.对 C 语言程序进行检查;可以检查出跨越函数的错误;可以对程序内的循环和分支进行处理2检查的错误为缓冲区溢出错误,包括非用户输入造成的缓冲区溢出错误和用户输入造成的缓冲区溢出错误。1.3 国内外现状在软件的安全性分析方面国内外的许多研究机构做了许多的研究,并取得了一些可观的研究成果,他们提出了许多切实可行的代码静态安全性检测方法,也开发沈阳航空航天大学毕业设计(论文)7了许多相关的代码静态分析工具,如 Flawfinder, Splint,ITS4 等。当前相关领域学者们提出的较为成熟的代码静态分析方法主要分为:模型检验,携带代码验证,词法分
17、析,简单语义分析,基于信息流的安全性分析等。1.3.1 模型检验模型检验是以有限状态自动机原理为基础的,它尽可能 多的将系统能够处于的可能状态列出,它将将要检验的代码转换成时序逻辑公式,在运行有限状态自动机的过程中,检查自动机所有状态是否满足安全条件,检查状态是否违反用户制定的规则和条件,并根据分析结果报告导致不合法的状态。根据检测工具中的检测模型的复杂程度,可以分析复杂的语法语义逻辑,从而精确的检测出系统中潜在的安全性漏洞。 1.3.2 携带源代码Pcc(Proof-caringcode,简称 PCC)检测方法是一种类似于密码匹配的方法。首先,我们为代码定义一组预先设定的安全策略。然后,代码
18、的编写者在编写代码时必须遵守这些安全策略,并在程序源代码中加入验证的代码以证明源程序的代码遵守了这些安全策略。最后由代码使用者确认这些代码的安全性。1.3.3 词法扫描词法扫描是一种以词法分析为基础的静态代码安全检测方法。在通过对源代码的静态的扫描过程中,找出可能存在的安全漏洞。它的基本原理是,首先,将一个或多个源代码文件作为输入,并将文件中的源代码转换为相应的词法符号流。然后使词法符号流与预先设定好的安全漏洞字典相比对。如果发现比对命中,则报告漏洞。例如:一旦发现 c 源程序中存在 strcpy, strcat 等函数即认为可能存在缓冲区溢出这种安全性漏洞。这种方法易于操作,但是采用词法分析
19、的扫描工具容易出现误报。1.3.4 简单语义分析基于简单语义分析的的检查工具采用了类似于编译器的设计原理。结合了语法分析和语义分析技术。同时也加入了数据流分析和控制流分析。因此,这种方法具有较高的准确性,较低的错报率和误报率。同时具有较强的可扩展性且可适用于对沈阳航空航天大学毕业设计(论文)8大规模程序的分析。1.4 软件代码风险介绍与原理我们调研了现今最常出现的代码安全漏洞风险。他们是网络安全问题的罪魁祸首,我们应采取各种方法尽量避免他们的出现。以下我们来做详细介绍。他们分别是内存访问错,缓冲区溢出,竞争条件,随机数的滥用,异常控制,空指针的使用。1.4.1 内存访问错C 语言程序中引发安全
20、漏洞的问题,绝大多数属于内存访问错误,因为 C 语言并没有提供完善的内存保护策略。内存访问错误可能由数组、指针或内存管理造成。对指针和数组缺乏边界检查是造成内存访问错误的根源。据统计,超过 50%的软件安全漏洞都是由指针和数组访问造成的。被列为攻击手段之首的“缓冲区溢出攻击”就是利用此类安全漏洞。首先,我们要仔细分析一下 C 语言程序能够使用的内存是怎样分配的:(1) 从静态存储区域分配,这块内存在程序的整个运行期间都存在,例如全局变量、static 变量。(2) 在栈上创建,函数内的局部变量的存储单元都可以在栈上创建。(3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或ne
21、w申请任意多少的内存,程序员自己负责在何时用free或delete 释放内存。动态内存的生存期由程序决定,使用非常灵活,但问题也最多。针对内存从分配、使用到释放的整个过程,可能发生如:(1) 内存未成功分配,却在后续代码中使用。典型的情况就是在堆中动态的申请一部分内存空间,许多有安全漏洞的代码总是假设内存是分配成功的,继续其他操作。但是,在实际程序运行的过程中,内存的空间可能被占满,造成内存分配不成功,所以程序必须在使用内存空间之前检查内存是否成功分配,以预防出错。(2) 内存空间虽然分配成功,但是使用前没用进行初始化。在C语言中,内存的缺省初值没有统一的标准,尽管有些时候为零值。如果变量的引用处和其定义处相隔比较远,变量的初始化很容易被忘记。如果引用了未被初始化的变量,可能会导致程序错误。(3) 内存分配成功并且已经初始化,但操作越过了内存的边界。这类错误在C