CodeQL 学习笔记【6】各个类的常用函数

423 阅读5分钟

如果你在一个类里没有找到某个谓词,那么你就应该去父类中去找一找。

下面是 CodeQL 中的类的继承图,然后我按照层级给各个类分一下层级,方便查询

Java 库函数

继承关系图.png

第一层

Top

from Top top

  • top.getAPrimaryQlClass() 获取当前 top 的最直接的 QL 类(通常用于判断表达式、语句等的类型)。返回 string

第二层

Element

from Element element

  • element.hasName(string name) 判断 element 的名称是否为 name。无返回值。
  • element.getName() 获取 element 的名称。返回 string。
  • element.fromSource() 判断 element 是否来自于源代码文件。无返回值。

第三层

Call

from Call call

  • call.getCallee() 获取 call 过程中被调用的 callable 是谁(例如函数调用中被调用的函数是谁)。返回 Callable。
  • call.getCaller() 获取 call 表达式被哪个函数包裹(如果我们对一个函数1的函数体里的 call 表达式使用这个 getCaller() 函数,那么返回的就是这个函数1)。返回 Callable。

Expr

from Expr expr

  • expr.getType() 获取当前表达式的类型。返回 Type。
  • expr.getIndex() 获取当前表达式在其父表达式中排第几位。返回 int。
  • expr.getEnclosingCallable() 获取当前表达式被哪个 callable 所包裹。返回 Callable。

Stmt

from Stmt stmt

  • stmt.getAChild() 获取语句的子语句(比如 if 语句的 {} 里面的语句。)。返回 Stmt。

第四层

Member

from Member member

  • member.getDeclaringType() 获取定义 member 的类, 也就是那个类里有这个 member。返回 RefType

RefType

就是引用类型,这里通常是指一个类。

from RefType reftype

  • reftype.hasQualifiedName(string package, string type) 判断一个引用类型的全限定名是否为 package.type。无返回值
  • reftype.getAField() 获取 reftype 的属性。返回 Field。
  • reftype.getAMethod() 获取 reftype 的所有方法。返回 Method。
  • reftype.getPackage() 获取 reftype 所属于哪个包。返回 Package。
  • reftype.getASupertype() 获取 reftype 的直接超类型。返回 Reftype。
  • reftype.getASubtype() 获取 reftype 的直接子类型。返回 Reftype。
  • reftype.getAMember() 获取 reftype 内部定义的成员,例如函数、字段等。返回 Member。
  • reftype.inherits(Member m) 判断 reftype 内部是否定义或继承有 m。无返回值。
  • reftype.
  • reftype.
  • reftype.
  • reftype.

MethodCall

from MethodCall methodcall

  • methodcall.getEnclosingCallable() 获取该 methodcall 被哪个 callable 包裹的(就是当前的方法调用语句写在哪个函数的方法体里)。返回 Callable。
  • methodcall.getAnArgument() 获取该 methodcall 传入的所有参数。返回 Expr。
  • methodcall.getArgument(int index) 获取当前 methdocall 所传入的第 index 的参数。返回 Expr。
  • methodcall.getEnclosingStmt() 获取当前 methdocall 被哪个语句所包裹。返回 Stmt。
  • methodcall.getAChildExpr() 获取 methodcall 表达式的子表达式(获取调用者和参数)。返回 Expr。

    例如:userComments.remove(user); 会返回 userCommentsuser

ArrayCreationExpr

from ArrayCreationExpr ace

  • ace.getFirstDimensionSize() 获取当前的 数组创建表达式 的第一个维度是几维。返回 int。

BlockStmt

from BlockStmt blockstmt

  • blockstmt.getNumStmt() 获取 blockstmt 内共有多少条语句。返回 int。

第五层

Field

from Field field

  • field.getType() 获取 field 的类型。返回 Type。
  • field.getDeclaration() 获取定义 field 的类。返回 FieldDeclaration。

Callable

from Callable callable

  • callable.getAParameter() 获取该 callable 的所有参数。返回 Parameter。
  • callable.getACallee() 获取该 callable 方法体内所调用的其他所有 callable(说白了就是看一个函数里调用哪些其他函数)。返回 Callable。
  • callable.calls(Callable target) 判断 callable 是否使用了 target。无返回值。
  • callable.polyCalls(Callable target) 判断 callable 实际真正调用的最终函数会不会是 target 呢?无返回值

Super s = new Sub(42); s.getX(); 比如这句代码,我们明面上调用的是 Super.getX() 实际真正上调用的是 Sub.getX()。

IfStmt

from IfStmt ifstmt

  • ifstmt.getElse() 获取 ifstmt 的 else 语句部分。返回 Stmt。
  • ifstmt.getCondition() 获取 ifstmt 语句中的 条件表达式语句语句。返回 Expr。

第六层

Class

from Calss class

  • class.getAnAnnotation() 获取 class 的所有注解。返回 Annotation。
  • class.isAnonymous() 判断 class 是不是匿名类。无返回值。

Method

from Method method

  • method.overrides(Method m) 判断 method 是否是覆写了 方法m。无返回值。
  • method.getASourceOverriddenMethod() 获取 method 所覆写的原始函数。返回 SrcMethod。
  • method.getSignature() 获取 method 的签名。返回 string。
  • method.getAReference() 获取对该 method 的调用或者说使用。返回 MethodCall。

CodeQL 语言基础函数

string

  • string.indexof(string s) 返回 s 在 string 中的位置,从 0 开始。返回 int

特殊:假如说现在有一个代码: .param("field1", "abcd") 其中 "field1" 是一个表达式,设为 e1,然后执行 e1.toString().indexOf("f") 结果是 1, 因为 0 位置的是 "

DataFlow 数据流分析函数

image.png

  • DataFlow::localFlow(Node node1, Node node2) 判断 node1 到 node2 是否为有效本地数据流, 经过 0 个或者多个步骤均可, 0 步骤不是代表没有流经,而是代表 node1 流向 node1 自身这叫经过 0 个步骤。
  • DataFlow::localFlowStep(Node node1, Node node2) 判断 node1 到 node2 是否为有效本地数据流,并且只经过 1 个步骤。

  • TaintTracking::localTaint(Node node1, Node node2) 判断 node1 到 node2 是否为有效的污点数据流,经过 0 个或者多个步骤均可。
  • TaintTracking::localTaintStep(Node node1, Node node2) 判断 node1 到 node2 是否为有效的污点数据流并且只经过 1 个步骤。

  • DataFlow::parameterNode(Parameter p) 获取 p 对应的 参数节点。返回 ExplicitParameterNode。
  • DataFlow::exprNode(Expr e) 获取 e 对应的 表达式节点,返回 ExprNode。

第一层

第二层

DataFlow::Configuration

  • conf.hasFlow(Node source, Node sink) 判断 source 到 sink 之间是否有全局数据流。

  • conf.isSource(Node source) 自行实现方法体。判断 source 是否为 source。无返回值。
  • conf.isSink(Node sink) 自行实现方法体。判断 sink 是否为 sink。无返回值。
  • conf.isAdditionalFlowStep(Node node1, Node node2) 自行实现方法体。强制将一个 节点 传递给另一个节点。无返回值。
x = "危险数据"
y = someFunction(x)
eval(y)

暂时还没有理解这个函数。

  • conf.isSanitizer(Node node) 自行实现方法体。判断 node 是否应该被截止。无返回值。