CodeQL

CodeQL是一个代码检查工具,会根据开发者编写的代码生成数据库,之后开发者通过编写ql脚本查找代码中的问题。原本似乎是semmle(?)的产品,后来被github收购了,所以现在实际上应该算是github官方的东西(但是github现在又是微软的了...)。

以C++为例,虽然gcc编译器本身就会对代码做语法检查,保证代码没有错误,但是在每个项目中可能会有一些约定俗成的规则,比如在某个函数中不能调用某个函数这样的规则,此时就可以通过ql脚本制定一个自定义规则,codeql会筛查出来符合规则的代码。并且可以输出为csv文件。

CodeQL支持vscode编辑器,网上几乎所有的使用教程都是使用VSCode编辑器运行CodeQL的,但是我的使用环境是服务器,使用vim开发,并不能使用VSCode,所以研究了一下怎么直接在命令行中使用CodeQL对代码进行检查。

相关参考:

建议先通过vscode配置好一个codeql方便学习语法,然后再命令行中使用。

概述

codeql分成两部分,一部分是CodeQL CLI,另一部分就是它自带的qll库了 可以理解为,前者是解释器控制台(编译器),后者是库文件,相当于C语言中stdio.h的存在,提供一些常用的类和方法

Getting started with the CodeQL CLI — CodeQL (github.com)

大体使用过程分为两步,首先生成数据库,之后编写ql脚本对数据库进行查询。

在生成数据库这一步分为需要区别解释型语言和编译型语言,解释型语言可以解析直接生成数据库,而编译型语言codeql需要监控编译过程。

安装

直接使用在线查询(lgtm)

lgtm.com

不过这个网站访问比较玄学,科学或者魔法你总得会一个。国内直连访问不太稳定,经常打不开,所以建议学习的时候使用vscode

vscode使用codeql

这也是网络上最常用的使用方式,不过根据网上的操作方式给我弄得很懵逼,如果会英文的话,直接看官方文档比较好。

Setting up CodeQL in Visual Studio Code — CodeQL (github.com)

下载

在vscode里面安装插件

然后点击这个测试,新版会问你要不要安装CLI,点击YES之后就会自动开始下载 (我第一次使用的时候是没有提示下载的,如果没有提示需要自己下载,参考网上别的教程,唯一需要注意的就是需要把库文件给放到CLI目录(codeql命令所在目录)里,改名。否则运行脚本的时候会提示找不到库文件)

到此CLI就安装好了 它自己安装的路径C:\Users\用户名\AppData\Roaming\Code\User\globalStorage\github.vscode-codeql\distribution1\codeql

库文件

(通过vscode自动安装就不需要手动下载库文件了)

然后下载库文件,github/codeql: CodeQL: the libraries and queries that power security researchers around the world, as well as code scanning in GitHub Advanced Security (code scanning), LGTM.com, and LGTM Enterprise

或者把这个仓库克隆下来也行 (我给放到了 D:/codeql/codeql_repo)

测试

下载现成的数据库,用来测试环境是不是正常的,数据库位置无所谓,解压出来

uboot数据库:https://downloads.lgtm.com/snapshots/cpp/uboot/u-boot_u-boot_cpp-srcVersion_d0d07ba86afc8074d79e436b1ba4478fa0f0c1b5-dist_odasa-2019-07-25-linux64.zip

vscode打开文件夹 D:/codeql/codeql_repo

然后选择 From a folder选择到刚才解压的数据库

然后在vscode的资源管理器里面打开路径 cpp/ql/src/ 这里面都是一些例子代码,比如下面我运行了 Likely Bugs/ReturnConstType.ql 只需要在ql文件里面右键选择 CodeQL: Run Query

linux控制台运行

这里使用的版本是 2.6.3版本,经过测试centos6.8及以下是不能直接运行的 (但是你可以安装docker然后在centos7.9的容器中运行)

下载

通过Releases · github/codeql-cli-binaries下载,linux下载codeql-linux64.zip

解压到~/codeql/codeql

下载或者克隆库文件 github/codeql: CodeQL: the libraries and queries that power security researchers around the world, as well as code scanning in GitHub Advanced Security (code scanning), LGTM.com, and LGTM Enterprise

放到 ~/codeql/codeqlrepo

这里需要注意的是,库文件必须在cli的同级目录或者子目录 否则会找不到包

安装

可以建立一个软链到/usr/bin/

然后执行 codeql --version 没有问题就好了

创建数据库

相关的官方说明:Creating CodeQL databases — CodeQL (github.com)

对于C++来说,命令如下

codeql database create testdb/ --language=cpp --command="g++ c.cpp"

--command参数指定了正常编译的时候需要执行的命令,可以是make -j20这样的命令

--language 参数指定了需要生成数据库的语言,具体可以是什么参看上面相关官方说明的连接里面

如果修改了代码想要重复生成数据库,可以添加--overwrite参数覆盖数据库

所以,生成C++数据的命令可以是codeql database create testdb/ --overwrite --language=cpp --command="make -j20"

[st@local ~]$ codeql database create testdb/ --language=cpp --command="g++ c.cpp"
Initializing database at /home/st/testdb.
Running build command: [g++, c.cpp]
Finalizing database at /home/st/testdb.
Successfully created database at /home/st/testdb.

命令执行完成之后可以看到当前目录下面有一个testdb文件夹,这个就是codeql的数据库

编写QL查询数据库

相关官方说明:database analyze — CLI manual (github.com)

建议在~/codeql/codeqlrepo/cpp/ql/src/创建一个文件夹比如work,在这个文件夹中编写自己的ql代码

一个简单的例子

/**
* @name AllFunction
* @kind problem
* @id cpp-test
*/ import cpp
from Function f
select f, "name: " + f.getName()

这个ql脚本会把所有的函数列举出来,

运行这个脚本使用命令如下

codeql database analyze testdb --rerun --format=csv --output=c.csv ./codeql_repo/cpp/ql/src/work/allfun.ql

--rerun 表示重复查询,默认情况下codeql会直接使用数据库中缓存的结果,会导致修改ql脚本之后再运行的结果不正确,所以强烈建议加上这个参数

--format=csv表示指定输出结果文件的格式,一般控制台的话输出csv格式就好了,还有其他格式参考上面给出的相关官方说明

--output=c.csv把结果输出到c.csv文件里面

完整参数解释database analyze — CLI manual (github.com)

运行结果

简单解释

首先贴出来对于ql文件的官方说明: About CodeQL queries — CodeQL (github.com)

注释风格是C/C++的风格,上面代码中注释的部分被称之为query metadata,相关说明: Metadata for CodeQL queries — CodeQL (github.com)

不过需要注意的是,文档比较老旧,所以只能作为参考,比如文档说@kind是可选项,但是经过测试,脚本在控制台下执行的时候,是必须的,否则运行不起来(vscode里面跑的时候确实是可选的)。此外,虽然说文档里说@kind类型只有problempath-problem两个,但是我看例子代码里面还有table,所以说,最好是文档配合位于codeql库文件/cpp/ql/src/里面的例子代码一起看比较好。

import cpp表示导入C++相关的库文件

from Function f 按照C++的思想来说就是声明一个变量,如果类比sql语句,就相当于选定了一张表,可以理解为f是一个集合,里面是数据库中所有的函数。

select 输出结果,如果上面是@kind problem,那么select就必须是两个参数。否则会报错

linux 命令行使用codeql的更多相关文章

  1. 像黑客一样使用 Linux 命令行

    前言 之前在博客园看到一篇介绍 IntelliJ IDEA 配置的文章,它里面用的是 gif 动态图片进行展示,我觉得很不错.所以在我今天以及以后的博文中,我也会尽量使用 gif 动图进行展示.制作 ...

  2. 详解Linux命令行下常用svn命令

    1.Linux命令行下将文件checkout到本地目录 svn checkout path(path是服务器上的目录) 例如:svn checkout svn://192.168.1.1/pro/do ...

  3. linux 命令行 光标移动技巧

    linux 命令行 光标移动技巧 看一个真正的专家操作命令行绝对是一种很好的体验-光标在单词之间来回穿梭,命令行不同的滚动.在这里强烈建立适应GUI节目的开发者尝试一下在提示符下面工作.但是事情也不是 ...

  4. 在linux命令行下执行php 程序

    如何在linux命令行下,执行php程序. 例子 打印当前时间 php -r "echo time()" 随机输出一个数字 php -r "echo rand(1,20) ...

  5. git代理,windows命令行代理,linux命令行代理

    下载不动设置代理:git config --global http.proxy http://127.0.0.1:1080git config --global https.proxy https:/ ...

  6. [转]12款最佳Linux命令行终端工具

    摘要 “工欲善其事必先利其器”,作为菜鸟,也是从别人那里偷学来的一些东东.今天看到同事用到一个终端命令行工具,觉得自己弱爆了.然后在网上搜了下该工具.发现类似的工具还是挺多的,只是自己不知道罢了. 原 ...

  7. Linux命令行修改IP、网关、DNS、主机名 的方法

    修改主机名:[改里面的 HOSTNAME 即可] vim /etc/sysconfig/network 网卡eth0    IP修改为 102.168.0.1 ifconfig eth0 102.16 ...

  8. Linux命令行与命令

    Linux命令行与命令   作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! Linux的命令是很重要的工具,也往往是初学者最大的瓶 ...

  9. 12款最佳Linux命令行终端工具, 20款优秀的 Linux 终端仿真器

    12款最佳Linux命令行终端工具     如果你跟我一样,整天要花大量的时间使用Linux命令行,而且正在寻找一些可替代系统自带的老旧且乏味的终端软件,那你真是找对了文章.我这里搜集了一些非常有趣的 ...

  10. Linux命令行–初识Linux shell

    shell及脚本简介  GNU/Linux shell 是个交互工具,它为用户提供了启动程序.管理文件系统上的文件以及管理运行在Linux系统上的进程的途径 . shell的核心是命令行提示符 它是s ...

随机推荐

  1. 范德蒙德矩阵行列式 & 循环矩阵行列式的证明

    范德蒙德矩阵的行列式 \[\begin{vmatrix} 1 & 1 & 1 & \dots & 1 \\ x_1 & x_2 & x_3 & ...

  2. 【k哥爬虫普法】爬取数据是否一定构成不正当竞争?

    我国目前并未出台专门针对网络爬虫技术的法律规范,但在司法实践中,相关判决已屡见不鲜,K 哥特设了"K哥爬虫普法"专栏,本栏目通过对真实案例的分析,旨在提高广大爬虫工程师的法律意识, ...

  3. 如何在IntelliJ IDEA中运行Java/Scala/Spark程序

    本文将分两部分来介绍如何在IntelliJ IDEA中运行Java/Scala/Spark程序: 基本概念介绍 在IntelliJ IDEA中创建和运行java/scala/spark程序 基本概念介 ...

  4. SqlSugar分组查询

    一.分组查询和使用 1.1 语法 只有在聚合对象需要筛选的时候才会用到Having,一般分组查询用不到可以去掉   var list = db.Queryable<Student>()   ...

  5. 5.1 C/C++ 使用文件与指针

    C/C++语言是一种通用的编程语言,具有高效.灵活和可移植等特点.C语言主要用于系统编程,如操作系统.编译器.数据库等:C语言是C语言的扩展,增加了面向对象编程的特性,适用于大型软件系统.图形用户界面 ...

  6. 从浏览器原理出发聊聊 Chrome 插件

    浏览器架构演进 单进程浏览器时代 单进程浏览器是指浏览器的所有功能模块都是运行在同一个进程里,这些模块包含了网络.插件.JavaScript 运行环境.渲染引擎和页面等.在 2007 年之前,市面上浏 ...

  7. TortoiseSVN 官网打不开,去哪下最新的软件和中文包?

    官网:https://tortoisesvn.net 能打开最好,但通常打不开,打不开时候去这个网站下: https://sourceforge.net/projects/tortoisesvn/ 这 ...

  8. 《ASP.NET Core 微服务实战》-- 读书笔记(第4章)

    第 4 章 后端服务 现实中的服务不可能处于真空之中,大多数服务都需要与其他服务通信才能完成功能. 我们将这些支持性服务称为后端服务,接下来我们将通过创建一个新的服务并修改之前的团队服务与这个服务通信 ...

  9. CF1916

    重点在 E B 如果 \(lcm(a,b)\neq b\),则是一个答案. 否则答案是 \(b\times\frac{b}{a}\). C 先前缀和.设前缀和 \(s_i\).考虑 \(s_i\) 减 ...

  10. java实现幂等性校验

    我们在做web应用的时候通常会遇到前端提交按钮重复点击的场景,在某些新增操作上就需要做幂等性限制来保证数据的可靠性.下面来用java aop实现幂等性校验. 一:首先我们需要一个自定义注解 packa ...