CodeQL笔记之基本语法(一)


前言

      学习利用CodeQL进行Java代码审计。包含一些概念和例子。


CodeQL基本语法

     CodeQL是利用解析引擎把我们需要审计的项目解析成了数据库,注意此处的数据库是转换成CodeQL能识别的中间层数据库。因为核心的解析引擎是不开源的,所以生成一个中间数据库。然后我们可以编写相关的QL规则,然后CodeQL引擎会根据规则去数据库中找到满足条件的数据,我们再分析即可。

1.语法结构

     1)QL查询的语法结构为:

from [datatype] var  /* ... 变量声明... */
where condition(var = something)   /* ... 逻辑公式 ... */
select var    /* ... 表达式 ... */

     2)一个小例子作用就是在所有的整形数字i中,当i==1的时候,输出 i。

// 表示我们要引入CodeQL的类库,因为我们分析的项目是java的,所以在ql语句里,必不可少
import java

// 表示我们定义一个变量i,它的类型是int,表示我们获取所有的int类型的数据
from int i
// 表示当i等于1的时候,符合条件
where i = 1
// 表示输出i
select i

在这里插入图片描述
     3)也可以利用官方搭建的平台练习写一些规则。LGTM查询控制台:https://lgtm.com/query
在这里插入图片描述

2.类库

     1)CodeQL解析引擎会把我们需要审计的项目代码转换为CodeQL可识别的AST数据库,格式如下所示。可以看出来大体是两级一个是导入的包,一个是类的。类的下面是一些方法、属性等。类库实际上就是上面AST的对应关系。
在这里插入图片描述
     2)比如说想要获取所有类当中的方法,在AST中 Method 就表示获取当前项目中所有的方法。如下所示:

import java

from Method method
select method

在这里插入图片描述
在这里插入图片描述
     3)升级一下,通过Method类内置的一些方法,把结果过滤一下。比如获取名字为get的方法名称。

import java
 
from Method method
where method.hasName("get")
/**
method.getName() 获取的是当前方法的名称
method.getDeclaringType() 获取的是当前方法所属class的名称。
**/
select method.getName(), method.getDeclaringType()

在这里插入图片描述

3.谓词

     1)谓词是用于描述构成 QL 程序的逻辑关系。概念上和函数有点像。个人根据官方文档理解,谓词就是一个一元数组或二元数组,一元数组的集合谓词元数就是一,二元数组的集合谓词元数就是二。通常,谓词中的所有元组都具有相同数量的元素。谓词的数量是元素的数量,不包括可能的result变量。QL中有许多内置谓词,可以参考官方文档:https://codeql.github.com/docs/ql-language-reference/ql-language-specification/#built-ins。
     2)定义一个谓词条件:

  • 需要关键字 predicate
  • 需要一个小写字母开头的标识符,例如:isCountry
  • 定义参数,多个用逗号连接,每个参数,需要指定参数类型和参数变量的标识符。
  • 谓词本身一个大的花括号 “{ }”

     3)官方例子:

predicate isCountry(string country) {
  country = "Germany"
  or
  country = "Belgium"
  or
  country = "France"
}

predicate hasCapital(string country, string capital) {
  country = "Belgium" and capital = "Brussels"
  or
  country = "Germany" and capital = "Berlin"
  or
  country = "France" and capital = "Paris"
}

     4)上方查询get的例子还可以按照如下所示改写。

import java
 
predicate isGet(Method method) {
exists(|method.hasName("get"))
}
 
from Method method
where isGet(method)
select method.getName(), method.getDeclaringType()
语法解释:
predicate 表示当前方法没有返回值。
exists子查询,是CodeQL谓词语法里非常常见的语法结构,它根据内部的子查询返回true or false,
来决定筛选出哪些数据。

在这里插入图片描述
     5)谓词可分为带有结果的谓词和不带有结果的谓词。区别就是是否引入了特殊变量result,有result的话就可以顶替predicate了。参考官方案例:

// 无结果的谓词 
predicate isSmall(int i) {
  i in [1 .. 9]
}
// 如果i是正整数并且小于10,则isSmall(i)成立。


// 有结果的谓词 
int getSuccessor(int i) {
  result = i + 1 and
  i in [1 .. 9]
}

// 如果i是正整数并且小于10,则这个谓词的结果就是接替i

4.基本数据类型及其内建函数

     1)QL语言中的基本数据类型,包括整型、浮点型、日期型、布尔型以及字符串类型。需要注意的是,对于QL语言来说,其支持的数据类型都带有相应的内建函数——通俗来说,就是系统已经为我们写好的函数就是谓词,我们直接拿来就能用了。
     2)举例来说,如果我们想求一个整数的绝对值,直接调用内建函数abs()即可,例如1.abs()。
在这里插入图片描述
     2)就是如果我们要调用某种类型的变量的通用形式为:直接在变量后面加上一个点号,然后加上要调用的内建函数即可。同时,我们还可以通过点号将多个函数串联起来,也就是对变量连续进行多种处理,例如,对于一个整型变量s,先求绝对值,再开平方,我们可以将这个处理过程表示为:s.abs().sqrt()。
在这里插入图片描述
     3)字符串类型,和其他语言差不多。

from string s
where s = "he\"llo"
select s

在这里插入图片描述
在这里插入图片描述
     4)整型与浮点型。

from float a, int b
where a = 5.3 and b = 2
// pow的作用就是参数的几次幂  下方例子就是5.3的2次幂
select a.pow(b)

在这里插入图片描述
在这里插入图片描述
     5)日期型。编写一个查询,来计算首个武汉疫情到现在已经过去了多少天了。

from date start, date now
// toDate()作用就是将指定的字符串转换为日期值
where start = "1/12/2019".toDate() and now = "25/10/2022".toDate()
select start.daysTo(now)

在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值