C/C++代码静态分析工具调研

您所在的位置:网站首页 C代码检查工具A C/C++代码静态分析工具调研

C/C++代码静态分析工具调研

2023-09-16 20:35| 来源: 网络整理| 查看: 265

C/C++代码静态分析工具调研 摘自:https://www.jianshu.com/p/92886d979401 简述

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

典型问题示例

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

■ 缓冲区溢出

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

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

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

  C/C++代码静态分析工具调研_缓冲区溢出   C/C++代码静态分析工具调研_缓冲区溢出_02

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

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

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

// 对指针是否为空的判断看是严谨,其实是无效的。 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)跟着向导「下一步」即可。

  C/C++代码静态分析工具调研_静态分析_03 Cppcheck有GUI,选择菜单栏「Analyze」下的「文件」或「目录」即可对源代码进行静态分析。   C/C++代码静态分析工具调研_c++_04 运行结果对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)跟着向导「下一步」即可。

  C/C++代码静态分析工具调研_c++_05 同样具有用户友好的GUI,且UI设计更时尚些。点击「扫描文件夹」或「扫描文件」选定路径后点击「开始扫描」即可使用。   C/C++代码静态分析工具调研_静态分析_06 扫描结果,对中文注释必然友好。

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

void Demo() { //分配的内存空间不匹配 int i = malloc(3); }   C/C++代码静态分析工具调研_缓冲区溢出_07 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格式后方可正常运行:

  C/C++代码静态分析工具调研_内存泄漏_08 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日 无锡



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3