简述

静态分析(static analysis)是指在不执行代码的情况下对其进行分析评估的过程,是软件质量和软件安全保障的重要一环。它通过词法分析、语义分析、控制流分析、数据流分析等技术对代码逐行解析暴露问题,从而协助我们将许多在运行时才会暴露的棘手麻烦扼杀于摇篮之中。

典型问题示例

代码静态分析能够识别诸多类型的漏洞或缺陷,轻至警告级的「变量未使用」,重至错误级的各类bug,这里列举几种常见的、较严重的、可静态检测的问题。

■ 缓冲区溢出

缓冲区溢出是指向缓冲区中存入超出其空间大小的数据量,导致多余的数据覆盖其他区域的合法数据,类似倒入容器中的水过多而导致溢出,流到它不该去的地方,造成不可预期的后果。从实践统计看,缓冲区溢出问题是软件中最普遍存在的漏洞问题,在C/C++这类不提供内存越界检测的语言中尤甚。通常,发生缓冲区溢出的情况有:

  • 字符串拷贝,当目标缓冲区长度小于源字串的长度时(此类的函数包括strcpy_mbscpystrcatwcscatmemcpystrncpy_mbsncpystrncatwcsncat等)。
// 字符串拷贝之前没有对s做长度判断,如果超过10,就会造成缓冲区溢出。
void func(char* s)
{char buf[10];strcpy(buf, s);
}
  • 格式化字符串处理,当参数与格式化字符串不匹配时(此类的函数包括printffprintfsprintfswprintf等)。
// %n将前面打印的字串长度信息写到相应地址
int len = 0;
printf("This is a test string.%n", &len);
// 错误的写法,此时长度信息会写到地址为0的内存空间中
int len = 0;
printf("This is a test string.%n", len);
  • 字符串读取,当缓冲区小于所要读入的字符串长度时(此类的函数包括scanffscanfsscanfgetsgetcfgetsfgetc等)。
// 用户输入的字串长度不受控制,如果超过10,就会造成缓冲区溢出。
char buf[10];
scanf("%s", &buf);

■ 内存泄漏

内存泄漏一般指堆内存的泄漏(也有系统资源的泄漏),程序申请的内存资源没有被合理地释放,导致这部分内存不能被回收利用而造成资源的浪费。严重时,过多的内存泄漏会造成系统崩溃。C/C++语言没有自动回收机制,需要程序员自行确保内存使用的闭环(new/deletealloc/freemalloc/freeGlobalAlloc/GlobalFree成对使用)。

通常,发生内存泄漏的情况有:

  • 分配内存后忘了调用相应的释放函数。
  • 过程因达到某种条件提前结束,未能执行后面的内存释放函数。
  • 程序设计不合理,不断分配内存,到最后才一起释放,虽然整体上不算内存泄漏,但在过程中已经酝酿了资源耗尽的可能性,无异于内存泄漏。

■ 野指针

当指针变量未被初始化,或指向的内存已被回收时,该指针便成了野指针。其指向的内存地址是非法的,对这块非法区域进行操作将导致不可预料的后果。

// 对指针是否为空的判断看是严谨,其实是无效的。
char *p = (char*)malloc(10);
free(p);
if (p != NULL)
{strcpy(p, "danger");
}

工具调研

根据工作需要,从可检测的语言、使用平台和授权三方面考量,调研了20余种主流的C/C++代码静态分析工具。

工具 语言 平台 授权
AdLint C Windows, Linux, Mac OS, FreeBSD 开源
Astrée C Windows, Linux 付费
Bauhaus Toolkit C, C++, Java, C#, Ada Windows, Linux, Solaris 付费
BLAST C Linux 开源
Cppcheck C, C++ Windows, Linux 开源
Coccinelle C Linux 开源
Coverity C, C++, C#, Java, JS, PHP, Python, Objective-C, Ruby, Swift, Fortran, VB Windows, Linux, Mac OS, FreeBSD, Solaris 付费
CppDepend C, C++ Windows, Linux 付费
ECLAIR C, C++ Windows, Linux, Mac OS 付费
Flawfinder C, C++ Python 开源
Fluctuat C, Ada Windows, Linux, Mac OS, FreeBSD 付费
Frama-C C Windows, Linux, Mac OS, FreeBSD 开源/付费
CodeSonar C, C++, Java, 二进制码 Windows, Linux, Mac OS, FreeBSD 付费
Klocwork C, C++, Java, C# Windows, Linux, Solaris 付费
LDRA Testbed C, C++, Java, Ada Windows, Linux, Mac OS 付费
Parasoft C/C++test C, C++ Windows, Linux, Solaris 付费
PC-Lint C, C++ Windows 付费
Polyspace C, C++, Ada Windows, Linux, Mac OS 付费
PRQA QA·Static Analyzers C, C++, Java Windows, Linux 付费
SLAM C Windows 免费
Sparse C Linux, Mac OS, BSD 开源
Splint C Linux, FreeBSD, Solaris 开源
TscanCode C, C++, C#, Lua Windows, Linux, Mac OS 开源

根据以下标准,筛选出3款适用性较高的工具——Cppcheck、Flawfinder、TscanCode——进行详细调研:

  • 语言:支持C/C++代码分析
  • 平台:支持在Windows和/或Linux平台运行
  • 授权:免费

为进行一次实践对比,从TscanCode的GitHub上抓到一组现成的C/C++编码问题示例,共94个CPP文件,考察三者的检测效果。

运行平台:Windows
被测语言:C/C++
测试集:TscanCode/samples/cpp

■ Cppcheck

Cppcheck可检测的问题包括:

  • Dead pointers
  • Division by zero
  • Integer overflows
  • Invalid bit shift operands
  • Invalid conversions
  • Invalid usage of STL
  • Memory management
  • Null pointer dereferences
  • Out of bounds checking
  • Uninitialized variables
  • Writing const data

并将问题分为以下6类:

  • 错误(error):bug。
  • 警告(warning):预防性编程方面的建议。
  • 风格警告(style):出于对代码简洁性的考虑(函数未使用、冗余代码等)。
  • 可移植性警告(portability):64/32位可移植性、编译器通用性等。
  • 性能警告(performance):使代码更高效的建议,但不保证一定有明显效果。
  • 信息消息(information):条件编译方面的警告。

安装十分简便,只需在官网下载最新的可执行安装包(本文目前为cppcheck-1.83-x86-Setup.msi)跟着向导「下一步」即可。

Cppcheck有GUI,选择菜单栏「Analyze」下的「文件」或「目录」即可对源代码进行静态分析。
运行结果对94个例子的分析十分到位,只不过底侧的代码预览对中文注释似乎不太友好。

除了GUI,Cppcheck还支持与多种IDE(如VS、Eclipse、QtCreator等)、版本管理系统(如Tortoise SVN、Git)集成使用。

可对每次分析进行配置甚至自定义规则,并作为项目文件进行保存或重载。

分析的结果报告可保存为格式化纯文本或XML,并可借助Python pygments将XML生成为HTML。

■ TscanCode

TscanCode是腾讯的开源项目,为此次调研的唯一一款本土工具,起初构建于Cppcheck的基础之上,后来进行了重新实现,并加入了对C#和Lua的支持。

TscanCode可检测的问题包括:

  • 空指针检查,包含可疑的空指针,判空后解引用比如Crash等共3类subid检查
  • 数据越界,Sprintf_S越界共1类subid检查
  • 内存泄漏,分配和释放不匹配同1类subid检查
  • 逻辑错误,重复的代码分支,bool类型和INT进行比较,表达式永远True或者false等共18类检查
  • 可疑代码检查,if判断中含有可疑的=号,自由变量返回局部变量等共计15类检查
  • 运算错误,判断无符号数小于0,对bool类型进行++自增等,共计11类检查

并将问题分为致命严重警告提示风格5类。

安装同样便捷,下载安装包(本文目前为TscanCodeV2.14.24.windows.exe)跟着向导「下一步」即可。

同样具有用户友好的GUI,且UI设计更时尚些。点击「扫描文件夹」或「扫描文件」选定路径后点击「开始扫描」即可使用。
扫描结果,对中文注释必然友好。

TscanCode的提示信息可以说直接照搬了Cppcheck,但给出的提示数量明显少于Cppcheck,以mismatchsize.cpp为例:

void Demo()
{//分配的内存空间不匹配int i = malloc(3);
}
Cppcheck对mismatchsize.cpp的检测结果有4条提示,TscanCode相应地只给出了后两条。

■ Flawfinder

Flawfinder由计算机安全专家David A. Wheeler个人开发,依托于Python,自然而然拥有了跨平台性。

安装:

pip install flawfinder

运行:

cd *python_path*/Scripts
python flawfinder *directory_with_source_code*

实践表明,Flawfinder对中文注释更不友好,直接拿TscanCode的测试集跑会报编码错误,尽管这些CPP文件本来就是Flawfinder文档所建议的UTF-8格式:

UnicodeDecodeError: 'gbk' codec can't decode byte 0xaf in position 92: illegal multibyte sequence

将测试集批量转换为ANSI格式后方可正常运行:

94个示例,仅检测出11个问题。

David A. Wheeler本人也在官网特别声明Flawfinder是款相对简单的静态分析工具,不进行数据流和控制流分析,甚至不识别函数的参数类型。

Flawfinder可将结果保存为格式化纯文本、HTML和CSV三种格式。

3款工具对比

  • 检测能力:Cppcheck > TscanCode > Flawfinder
  • 友好度:TscanCode > Cppcheck > Flawfinder
  • 易用性:TscanCode > Cppcheck > Flawfinder

参考文献

  • 向东, 刘海燕. C/C++静态代码安全检查工具研究[J]. 计算机工程与设计, 2005, 26(8):2110-2112.
  • 罗琴灵. 基于静态检测的代码审计技术研究[J]. 2016.
  • List of tools for static code analysis - Wikipedia
  • C++代码质量扫描主流工具深度比较 - CSDN博客
  • C/C++静态代码检查工具对比分析 - 网易博客
  • Cppcheck 用法(上篇) - CSDN博客
  • Cppcheck手册
  • Flawfinder文档

2018年4月10日~16日 无锡

C/C++代码静态分析工具调研相关推荐

  1. Linux平台下QtCreator集成代码静态分析工具clang-tidy和Clazy

    Linux平台下QtCreator集成代码静态分析工具clang-tidy和Clazy 原文连接: https://blog.csdn.net/wsj18808050/article/details/ ...

  2. PHP代码静态分析工具PHPStan

    最近发现自己写的PHP代码运行结果总跟自己预想的不一样,排查时发现大多是语法错误,在运行之前错误已经种下.可能是自己粗心大意,或者说php -l检测太简单,不过的确是有一些语法错误埋藏得太深(毕竟PH ...

  3. 代码静态分析工具PC-LINT安装配置

    PC-Lint是C/C++软件代码静态分析工具,你可以把它看作是一种更加严格的编译器.它不仅可以检查出一般的语法错误,还可以检查出那些虽然符合语法要求但不易发现的潜在错误.  C语言的灵活性带来了代码 ...

  4. 代码静态分析工具-splint的学习与使用[转]

    代码静态分析工具--splint的学习与使用[转] 引言 最近在项目中使用了静态程序分析工具PC-Lint,体会到它在项目实施中带给开发人员的方便.PC-Lint是一款针对C/C++语言.window ...

  5. linux pclint配置_代码静态分析工具PC-LINT安装配置

    PC-Lint是C/C++软件代码静态分析工具,你可以把它看作是一种更加严格的编译器.它不仅可以检查出一般的语法错误,还可以检查出那些虽然符合语法要求但不易发现的潜在错误. C语言的灵活性带来了代码效 ...

  6. 代码静态分析工具——splint的学习与使用

    引言 最近在项目中使用了静态程序分析工具PC-Lint,体会到它在项目实施中带给开发人员的方便.PC-Lint是一款针对C/C++语言.windows平台的静态分析工具,FlexeLint是针对其他平 ...

  7. php代码静态分析工具,Wpbullet:一款针对WordPress(PHP)的静态代码分析工具

    今天给大家介绍的是一款名叫Wpbullet的工具,广大安全研究人员可以使用这款工具来对WordPress.插件.主题以及其他PHP项目进行静态代码分析. 工具安装 大家可以直接从Wpbullet的Gi ...

  8. PhpStorm添加PHP代码规范检查CodeSniffer(phpcs)和PHP代码静态分析工具Mess Detector(phpmd)

    首先需要了解一下这些工具是用来干什么: PHPCS 是 PHP Code Sniffer,一款代码规范检查工具,可以根据你的设置来检查代码规范性问题. PHPCBF 是PHPCS 内置的代码规范修复工 ...

  9. ABAP代码静态分析工具SQF - Support Query Framework

    如果系统里没有SQF这个tcode,可以参考note 1814328: SQF: Plug-In for Source Code Scans进行安装. ABAP static analysis too ...

最新文章

  1. tableview插入刷新_iOS中tableview的几种刷新
  2. jQuery Alert Dialogs (Alert, Confirm, Prompt Replacements)(翻译)
  3. 机器学习算法小结与收割offer遇到的问题
  4. 一篇文章让你真正了解Java
  5. C++检查给定数字是否为4的幂的算法实现(附完整源码)
  6. HALCON示例程序stamp_catalogue.hdev分割图片与文字
  7. ubuntu 远程桌面及Qt安装
  8. rabbitmq 传递文件_RabbitMQ:计划邮件传递
  9. [性能测试] LoadRunner结果分析 – TPS
  10. mysql群集配置_mysql8 参考手册-NDB群集配置参数,选项和变量概述
  11. unet网络python代码详解_python网络编程详解
  12. Python菜鸟入门:day06元组与字典
  13. 瀑布流JavaScript
  14. vs 和 rider 一决高下 结合开发dotnet应用
  15. UTM(Undergraduate Texts in Mathematics)书单 |附下载链接
  16. ThinkBook 14P Win11网卡驱动掉了-解决方案
  17. 给自动化专业的大学生的终极警钟,单片机、PLC、嵌入式等方向哪个才是香饽饽?
  18. linux系统可以在移动硬盘,如何在移动硬盘上装LINUX系统?
  19. 万达商管冲刺香港上市:上半年净赚20亿元,已提前“套现”约63亿
  20. 公众号用聊天式万用查询系统多用户后台版

热门文章

  1. echarts为什么用getElementsByClassName()方法显示不了图表
  2. 基于Python AutoCAD ActiveX 二次开发,pyautocad应用技术
  3. linux day1
  4. python——常见内置函数、可迭代对象与迭代器对象
  5. Linux kernel内存管理之OOM相关参数
  6. java多人聊天室实现(可群聊私聊/添加好友/发送文件)
  7. 2020年你不应该错过的CSS新特性
  8. 输出动物的声音JAVA_Java-动物声音
  9. c语言中单引号b是啥意思,c语言中单引号和双引号的区别和应用?
  10. 稻盛和夫修的是什么心?