内容简介: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弱口令扫描器
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Developing Large Web Applications
Kyle Loudon / Yahoo Press / 2010-3-15 / USD 34.99
As web applications grow, so do the challenges. These applications need to live up to demanding performance requirements, and be reliable around the clock every day of the year. And they need to withs......一起来看看 《Developing Large Web Applications》 这本书的介绍吧!