内容简介:CppCheck是一个静态语法扫描器,官方介绍:Static analysis of C/C++ code. Checks for: memory leaks, mismatching allocation-deallocation, buffer overrun, and many more. The goal is 0% false positives. SeeCppCheck是一个开源工程,要对其进行修改,最好还是理清楚它的工作流程。首先,让我们对一个常见的问题进行检查,代码如下:
CppCheck是一个静态语法扫描器,官方介绍:
Static analysis of C/C++ code. Checks for: memory leaks, mismatching allocation-deallocation, buffer overrun, and many more. The goal is 0% false positives. See http://cppcheck.sourceforge.net for more information.
CppCheck是一个开源工程,要对其进行修改,最好还是理清楚它的工作流程。首先,让我们对一个常见的问题进行检查,代码如下:
int a[10];
a[10] = 0;
对这个越界代码进行扫描,可以发现如下调用栈处报警:
> cppcheck-core.dll!CheckBufferOverrun::arrayIndexOutOfBoundsError(const Token * tok, const CheckBufferOverrun::ArrayInfo & arrayInfo, const std::vector<ValueFlow::Value,std::allocator<ValueFlow::Value> > & index) 行 142 C++ cppcheck-core.dll!CheckBufferOverrun::valueFlowCheckArrayIndex(const Token * const tok, const CheckBufferOverrun::ArrayInfo & arrayInfo) 行 878 C++ cppcheck-core.dll!CheckBufferOverrun::bufferOverrun() 行 1593 C++ cppcheck-core.dll!CheckBufferOverrun::runChecks(const Tokenizer * tokenizer, const Settings * settings, ErrorLogger * errorLogger) 行 91 C++ cppcheck-core.dll!CppCheck::checkNormalTokens(const Tokenizer & tokenizer) 行 563 C++ cppcheck-core.dll!CppCheck::checkFile(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & filename, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & cfgname, std::basic_istream<char,std::char_traits<char> > & fileStream) 行 416 C++ cppcheck-core.dll!CppCheck::check(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & path) 行 83 C++ cppcheck.exe!CppCheckExecutor::check_internal(CppCheck & cppcheck, int __formal, const char * const * argv) 行 871 C++ cppcheck.exe!CppCheckExecutor::check(int argc, const char * const * argv) 行 198 C++ cppcheck.exe!main(int argc, char * * argv) 行 95 C++
简单分析一下,基本是这几行起了作用:
cppcheck-core.dll!CheckBufferOverrun::runChecks(const Tokenizer * tokenizer, const Settings * settings, ErrorLogger * errorLogger) 行 91 C++ cppcheck-core.dll!CppCheck::checkNormalTokens(const Tokenizer & tokenizer) 行 563 C++ > cppcheck-core.dll!CppCheck::checkFile(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & filename, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & cfgname, std::basic_istream<char,std::char_traits<char> > & fileStream) 行 416 C++
注意第一行:
void CppCheck::checkNormalTokens(const Tokenizer &tokenizer) { // call all "runChecks" in all registered Check classes for (std::list<Check *>::const_iterator it = Check::instances().begin(); it != Check::instances().end(); ++it) { if (mSettings.terminated()) return; if (tokenizer.isMaxTime()) return; Timer timerRunChecks((*it)->name() + "::runChecks", mSettings.showtime, &S_timerResults); (*it)->runChecks(&tokenizer, &mSettings, this); }
也就是说,it从Check::instances()中遍历所有项目。
Check::instances中有:
名称 值 类型 ▶ [0] 0x01557438 {cppcheck-core.dll!Check64BitPortability instance} {...} Check * {Check64BitPortability} ▶ [1] 0x01557494 {cppcheck-core.dll!CheckAssert instance} {...} Check * {CheckAssert} ▶ [2] 0x015574ec {cppcheck-core.dll!CheckAutoVariables instance} {...} Check * {CheckAutoVariables} ▶ [3] 0x01557550 {cppcheck-core.dll!CheckBool instance} {...} Check * {CheckBool} ▶ [4] 0x015575b8 {cppcheck-core.dll!CheckBoost instance} {...} Check * {CheckBoost} ▶ [5] 0x01557614 {cppcheck-core.dll!CheckBufferOverrun instance} {...} Check * {CheckBufferOverrun} ▶ [6] 0x01557774 {cppcheck-core.dll!CheckFunctions instance} {...} Check * {CheckFunctions} ▶ [7] 0x0155768c {cppcheck-core.dll!CheckClass instance} {mSymbolDatabase=0x00000000 <NULL> } Check * {CheckClass} ▶ [8] 0x0155771c {cppcheck-core.dll!CheckCondition instance} {...} Check * {CheckCondition} ▶ [9] 0x01557864 {cppcheck-core.dll!CheckExceptionSafety instance} {...} Check * {CheckExceptionSafety} ▶ [10] 0x015578bc {cppcheck-core.dll!CheckIO instance} {...} Check * {CheckIO} ▶ [11] 0x01557974 {cppcheck-core.dll!CheckLeakAutoVar instance} {...} Check * {CheckLeakAutoVar} ▶ [12] 0x01557a7c {cppcheck-core.dll!CheckMemoryLeakNoVar instance4} {...} Check * {CheckMemoryLeakNoVar} ▶ [13] 0x01557a0c {cppcheck-core.dll!CheckMemoryLeakInClass instance2} {...} Check * {CheckMemoryLeakInClass} ▶ [14] 0x015579d4 {cppcheck-core.dll!CheckMemoryLeakInFunction instance1} {...} Check * {CheckMemoryLeakInFunction} ▶ [15] 0x01557a44 {cppcheck-core.dll!CheckMemoryLeakStructMember instance3} {...} Check * {CheckMemoryLeakStructMember} ▶ [16] 0x01557b34 {cppcheck-core.dll!CheckNullPointer instance} {...} Check * {CheckNullPointer} ▶ [17] 0x01557bb0 {cppcheck-core.dll!CheckOther instance} {...} Check * {CheckOther} ▶ [18] 0x01557d20 {cppcheck-core.dll!CheckStl instance} {...} Check * {CheckStl} ▶ [19] 0x01557cbc {cppcheck-core.dll!CheckSizeof instance} {...} Check * {CheckSizeof} ▶ [20] 0x015577ec {cppcheck-core.dll!CheckString instance} {...} Check * {CheckString} ▶ [21] 0x01557e98 {cppcheck-core.dll!CheckType instance} {...} Check * {CheckType} ▶ [22] 0x01557f00 {cppcheck-core.dll!CheckUninitVar instance} {...} Check * {CheckUninitVar} ▶ [23] 0x01557f70 {cppcheck-core.dll!CheckUnusedFunctions CheckUnusedFunctions::instance} {mFunctions={ size=0 } ...} Check * {CheckUnusedFunctions} ▶ [24] 0x01557ff8 {cppcheck-core.dll!CheckUnusedVar instance} {mIsRecordTypeWithoutSideEffectsMap={ size=0 } ...} Check * {CheckUnusedVar} ▶ [25] 0x01557c64 {cppcheck-core.dll!CheckPostfixOperator instance} {...} Check * {CheckPostfixOperator} ▶ [26] 0x01558070 {cppcheck-core.dll!CheckVaarg instance} {...} Check * {CheckVaarg}
鉴于代码表明_instalces这是一个static变量,所以必然有代码调用了Check::instances().XXXX向它推送代码。
std::list<Check *> &Check::instances() { #ifdef __SVR4 // Under Solaris, destructors are called in wrong order which causes a segmentation fault. // This fix ensures pointer remains valid and reachable until program terminates. static std::list<Check *> *_instances= new std::list<Check *>; return *_instances; #else static std::list<Check *> _instances; return _instances; #endif }
查找所有的代码以后,只有构造函数有相关代码:
Check::Check(const std::string &aname) : mTokenizer(nullptr), mSettings(nullptr), mErrorLogger(nullptr), mName(aname) { for (std::list<Check*>::iterator i = instances().begin(); i != instances().end(); ++i) { if ((*i)->name() > aname) { instances().insert(i, this); return; } } instances().push_back(this); }
下断点,重新执行。
cppcheck-core.dll!Check::Check(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & aname) 行 30 C++ cppcheck-core.dll!Check64BitPortability::Check64BitPortability() 行 46 C++ > cppcheck-core.dll!`anonymous namespace'::`dynamic initializer for 'instance''() 行 41 C++
可以看到这样的调用栈,再往下就是程序的初始化代码了,一层层看。
1:最上层可以看到一个类似全局变量的代码
// Register this check class (by creating a static instance of it) namespace { Check64BitPortability instance; }
2:可以看到检测的类都是公开继承Check的
class CPPCHECKLIB Check64BitPortability : public Check { public: /** This constructor is used when registering the Check64BitPortability */ Check64BitPortability() : Check(myName()) { }
3:随后代码走到Check中,该类被加入。
再保留断点继续执行,可以发现所有的Check都是这样加入的,因为这些Check类都是全局变量,所以程序一启动就会自动添加进去。等他们执行完了才会进入main。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 开源扫描仪的工具箱:安全行业从业人员自研开源扫描器合集
- XSS 扫描器成长记
- 手动编译高速扫描器MasScan
- 漏洞扫描器 hang 住 case 复盘
- 修改CppCheck,做自己的扫描器 - 02
- Python实现FTP弱口令扫描器
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
无懈可击的Web设计
西德霍姆 / 刘建宁 / 清华大学出版社 / 2009-4 / 59.90元
一个网站,无论视觉上多么美观,内容多么丰富,如果不能面向最广泛的用户群,那它就不算是真正成功的网站。《无懈可击的Web设计:利用XHTML和CSS提高网站的灵活性与适应性》是Web标准设计领域的公认专家Dan Cederholm的倾力之作,向您描述了基于Web标准的设计策略,以适应各种各样的用户浏览方式。书中每一章的开头都给出了一个基于传统HTML技术的实例,然后对它进行重构,指出它的局限性,并利......一起来看看 《无懈可击的Web设计》 这本书的介绍吧!