zoukankan      html  css  js  c++  java
  • cppcheck,代码简单分析,以及实现一个简单的模块

    经过半天的分析和了解,大致明白了这个工具的使用方法和原理。

    这个工具,会将一个源文件(目前我是用单一源文件测试的,没有使用目录测试),

    每一个有效符号或者元素都解析出来,之后储存在一个大list里面,供后续模块检测时使用,

    但是一些特殊的元素,不会被列入list,如调用约定(__stdcall 此类等等),其他应该还有,但是还没使用到,

    目前看到的情况是,整个文件所有内容全部都被放到了一个list 里面,挺痛苦的。

    内置模块部分,其实它内置了很多功能

    一堆check,很方便我来学习,据此我也写出了一个简单的check模块,代码如下

     1 #pragma once
     2 
     3 #include "check.h"
     4 #include "ctu.h"
     5 
     6 #include <cstddef>
     7 #include <list>
     8 #include <map>
     9 #include <string>
    10 #include <vector>
    11 
    12 class CPPCHECKLIB CheckZooFrame : public Check {
    13 public:
    14 
    15     /** This constructor is used when registering the CheckClass */
    16     CheckZooFrame() : Check(myName()) {
    17     }
    18 
    19     /** This constructor is used when running checks. */
    20     CheckZooFrame(const Tokenizer* tokenizer, const Settings* settings, ErrorLogger* errorLogger)
    21         : Check(myName(), tokenizer, settings, errorLogger) {
    22     }
    23 
    24     void runChecks(const Tokenizer* tokenizer, const Settings* settings, ErrorLogger* errorLogger) OVERRIDE;
    25 
    26     void getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const OVERRIDE;
    27 
    28     /** @brief Parse current TU and extract file info */
    29     Check::FileInfo* getFileInfo(const Tokenizer* tokenizer, const Settings* settings) const OVERRIDE;
    30 
    31     /** @brief Analyse all file infos for all TU */
    32     bool analyseWholeProgram(const CTU::FileInfo* ctu, const std::list<Check::FileInfo*>& fileInfo, const Settings& settings, ErrorLogger& errorLogger) OVERRIDE;
    33 
    34 private:
    35 
    36     /** data for multifile checking */
    37     class MyFileInfo : public Check::FileInfo {
    38     public:
    39         /** unsafe array index usage */
    40         std::list<CTU::FileInfo::UnsafeUsage> unsafeArrayIndex;
    41 
    42         /** unsafe pointer arithmetics */
    43         std::list<CTU::FileInfo::UnsafeUsage> unsafePointerArith;
    44 
    45         /** Convert MyFileInfo data into xml string */
    46         std::string toString() const OVERRIDE {
    47             return "Zoos";
    48         }
    49     };
    50 
    51     Check::FileInfo* loadFileInfoFromXml(const tinyxml2::XMLElement* xmlElement) const OVERRIDE;
    52 
    53 
    54     static std::string myName() {
    55         return "Zoo checking";
    56     }
    57 
    58     std::string classInfo() const OVERRIDE {
    59         return "Zoo Check Frame
    ";
    60     }
    61 };
     1 #include "check_zoo.h"
     2 #include "check.h"
     3 
     4 namespace {
     5     CheckZooFrame instance;
     6 }
     7 
     8 
     9 
    10 static const CWE CWE_POINTER_ARITHMETIC_OVERFLOW(758U);
    11 
    12 
    13 void CheckZooFrame::runChecks(const Tokenizer* tokenizer, const Settings* settings, ErrorLogger* errorLogger) {
    14     printf("FILE [%s] LINE [%d] Function [%s] 
    ", __FILE__, __LINE__, tokenizer->tokens()->next()->str().c_str());
    15     CheckZooFrame c(tokenizer, settings, errorLogger);
    16     c.reportError(tokenizer->tokens(), Severity::portability, "Zoo检测点", "Zoo框架", CWE_POINTER_ARITHMETIC_OVERFLOW, false);
    17 
    18     for (const Token* tok = tokenizer->tokens(); tok; tok = tok->next())
    19     {
    20         printf("%s ", tok->str().c_str());
    21         if (tok->str() == "{" || tok->str() == "}" || tok->str() == ";")
    22         {
    23             printf("
    ");
    24         }
    25     }
    26 }
    27 
    28 void CheckZooFrame::getErrorMessages(ErrorLogger* errorLogger, const Settings* settings) const {
    29     printf("FILE [%s] LINE [%d] 
    ", __FILE__, __LINE__);
    30 }
    31 
    32 /** @brief Parse current TU and extract file info */
    33 Check::FileInfo* CheckZooFrame::getFileInfo(const Tokenizer* tokenizer, const Settings* settings) const {
    34     printf("FILE [%s] LINE [%d] 
    ", __FILE__, __LINE__);
    35     return NULL;
    36 }
    37 
    38 /** @brief Analyse all file infos for all TU */
    39 bool CheckZooFrame::analyseWholeProgram(const CTU::FileInfo* ctu, const std::list<Check::FileInfo*>& fileInfo, const Settings& settings, ErrorLogger& errorLogger) {
    40     printf("FILE [%s] LINE [%d] 
    ", __FILE__, __LINE__);
    41     return true;
    42 }
    43 
    44 
    45 Check::FileInfo* CheckZooFrame::loadFileInfoFromXml(const tinyxml2::XMLElement* xmlElement) const {
    46     printf("FILE [%s] LINE [%d] 
    ", __FILE__, __LINE__);
    47     return NULL;
    48 }

    扩展性还是非常强的,我的代码,几乎全部都是对照其他模块来写的,

    而且接口也非常简单,很友好。

    这里简单地解释一下吧。

    cppcheck的模块系统属于构造时直接靠全局变量串起来的这种模式(相似的可以看llvm,clang的命令行系统,也是这么串起来的),

    优点是简单方便,只要继承了父类,然后实例化一个自己,就解决了问题,

    缺点是,很多关键信息无法在初次构造时就获取到,所以使用时有点麻烦。

    本人在编写这个简单模块的时候,就遇到了这个小麻烦,不过还是解决了。

    主要体现在,错误上报的部分。

    整个cppcheck框架,其实比较强大,它实际上真的仅仅是作为一个普通框架来执行的,

    内部功能通过一个个模块,一次次传递参数,一个个reportError来列出。

    以 CheckZooFrame 为例,

    首先需要实现若干虚函数,继承于 check 父类,

    然后定义一个全局变量,供初始化的时候,挂接自己,

    但是这时候,由于自己无法获取到任何关键信息,所以内部变量初始化全部都是空,

    即CPP代码中第五行。

    挂接了自己之后,最重要的函数,其实只有一个,是runcheck,

    这个函数会被外面check管理器直接调用,会传入一系列的参数,

    让当前模块来检测是否有需要检测的异常,

    如果有的话,则通过reportError上报。

    这时候就有问题了,reportError上报需要知道当前的代码list,但是初始化的时候已经全都是空了,没有list,

    怎么办,那就只能在自己内部重新创建个局部变量,构造时让它有list,

    即CPP代码中15行的作用。

    然后就可以尽情地玩耍了。

    还有个问题,就是CWE是什么,其实CWE是一个索引ID,这个ID遵守一套XXXX的规则,

    这个规则里面定义了若干种代码可能出现的问题,通过这个ID,大家就可以统一使用并查询出代码出现了什么问题。

    具体这个ID去哪查,就去下面的网站。

    https://cwe.mitre.org/data/downloads.html

    例子中的CWE是我随便写的,并不影响。

    其实挺容易的,没有那么难,只不过,任重而道远啊。比如

    下图,指定位置有一个非常明显的内存越界写操作,可能会导致出现 0xC0000005,但是呢,cppcheck内置的模块没有发现这个问题,

    这说明了一个事情,就是它内置模块的检测范围可能还是以函数为单位的,只能检测到当前函数内的事情,无法朔源检测前面或者后面函数内的事情。

    这只是一个点吧,我希望基于对它的学习,能多少再了解一些代码审计相关的知识。

    就到这吧

    其实,由于它的模块化是如此地出色,甚至可以插入一个python或者lua脚本解释器之类的,让它支持通过脚本来加模块,那么应该会更完美。

  • 相关阅读:
    如何在delphi里面控制Edit只能输入数字
    ShellExecute函数
    GetSystemMenu 获取系统菜单
    StringReplace 函数
    delphi 字符串查找
    Pos 函数
    Copy 函数
    css笔记
    HTML5笔记
    node.js nodejs supvisor模块
  • 原文地址:https://www.cnblogs.com/suanguade/p/12773155.html
Copyright © 2011-2022 走看看