首页 > 其他分享 >CodeQL与AST之间联系

CodeQL与AST之间联系

时间:2023-07-11 15:48:03浏览次数:41  
标签:github java 联系 CodeQL javaparser AST import com

为什么要学习Java抽象语法树呢?

在计算机科学中,抽象语法树(abstract syntax tree 或者缩写为 AST),或者语法树(syntax tree),是源代码的抽象语法结构的树状表现形式,这里特指编程语言的源代码。树上的每个节点都表示源代码中的一种结构。

先用一个示例来看看AST作用

`java
package com.github.javaparser;

import java.time.LocalTime;

public class TimePrinter {
public static void main(String[] args) {
System.out.println(LocalTime.now());
}
}


![image-20211227104045005](/img/sin/M00/00/EC/wKg0C2IphI2AEvhWAABrjtMgDNo893.png)

可以看到导入包

![image-20211227105053110](/img/sin/M00/00/EC/wKg0C2IphIyAfxJqAAA3MlyLJmk326.png)

方法声明主体

![time](/img/sin/M00/00/EC/wKg0C2IphJ-AESlqAACL5B3EXco433.png)

整个类全部信息

可以看出来用树状结构表示一个类的结构是方便的,但即使是这样子,学习AST对安全来说貌似也没啥关系。那我们再来看一个示例

```java
    class Comparator implements java.util.Comparator<PropertySource>, Serializable {
        private static final long serialVersionUID = 1L;
        @Override
        public int compare(final PropertySource o1, final PropertySource o2) {
            return Integer.compare(Objects.requireNonNull(o1).getPriority(), Objects.requireNonNull(o2).getPriority());
        }
    }

如果用ql形式去找上面这个类Comparator,那我们需要的用到ClassOrInterface。首先可以判断实现了Comparator和Serializable接口,那么可以用ClassOrInterface简单判断一下名字是否一致即可。

`ql
import java

class MySerializableImpl extends ClassOrInterface{
MySerializableImpl(){
this.getName() = "Comparator"
}
}
predicate isMyClass(Class m){
m.getASourceSupertype() instanceof MySerializableImpl
and m.getASourceSupertype() instanceof TypeSerializable

}

from Class c
where isMyClass(c)
select c


如果ql大部分查询是基于AST语法之上的,通过查看AST语法树的图不难发现所有的实现类都是一个类型**ClassOrInterfaceType**。

![image-20211228101944016](/img/sin/M00/00/EC/wKg0C2IphIyAR6NzAADXEdcKNe8803.png)

学习AST可以更好的知道ql的规则,不至于不知道调用啥类型的去查询。并且学习AST可以大大将复杂冗杂且抽象的代码使用树状形式表现更加直观易懂的形式。学习AST适合做代码审计、代码分析、漏洞分析、安全研究等之类人群。

---

### AST--Java导出的几种格式的方法

直接新建一个maven项目,将下面三个依赖导入。

```xml
<dependencies>
    <dependency>
        <groupId>com.github.javaparser</groupId>
        <artifactId>javaparser-core</artifactId>
        <version>3.23.1</version>
    </dependency>
    <dependency>
        <groupId>com.github.javaparser</groupId>
        <artifactId>javaparser-core-serialization</artifactId>
        <version>3.23.1</version>
    </dependency>
    <dependency>
        <groupId>com.github.javaparser</groupId>
        <artifactId>javaparser-symbol-solver-core</artifactId>
        <version>3.23.1</version>
    </dependency>
</dependencies>

`java
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.serialization.JavaParserJsonSerializer;

import javax.json.Json;
import javax.json.stream.JsonGenerator;
import javax.json.stream.JsonGeneratorFactory;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

import static com.github.javaparser.StaticJavaParser.parse;

public class JSONSERDEMO {
public static void main(String[] args) {

    CompilationUnit cu = parse("class X{java.util.Y y;}");
    JavaParserJsonSerializer jsonSerializer = new JavaParserJsonSerializer();
    Map\<String, ?> config = new HashMap\<>();
    config.put(JsonGenerator.PRETTY_PRINTING, null);
    StringWriter  writer = new StringWriter();
    JsonGeneratorFactory generatorFactory = Json.createGeneratorFactory(config);
    JsonGenerator jsonGenerator = generatorFactory.createGenerator(writer);
    jsonSerializer.serialize(cu,jsonGenerator);
    System.out.println(writer);

}

}


![image-20211228110649571](/img/sin/M00/00/EC/wKg0C2IphJOAHcQMAACPRMMgiww637.png)

#### DOT

dot可以使用转化工具转化成png图片,首先运行下面代码会生成X.dot文件。然后我们需要下载[Graphviz](http://graphviz.org/download/),配置环境变量后到生成的X.dot文件夹下执行命令**dot X.dot -Tpng >X.png**。

```java
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.printer.DotPrinter;

import java.io.FileWriter;
import java.io.PrintWriter;

import static com.github.javaparser.StaticJavaParser.parse;


public class DotSerDemo {
    public static void main(String[] args) {
        CompilationUnit cu = parse("class X{java.util.Y y;}");
        DotPrinter dotPrinter =  new DotPrinter(true);
        dotPrinter.output(cu);
        try {
            FileWriter fileWriter = new FileWriter("X.dot");
            PrintWriter printWriter = new PrintWriter(fileWriter, true);
            printWriter.println(dotPrinter.output(cu));

        }catch (Exception e){

        }
    }
}

image-20211228111241967

`java
import com.github.javaparser.JavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.printer.YamlPrinter;
import static com.github.javaparser.StaticJavaParser.parse;

public class YamlSerDEMO {
public static void main(String[] args) {
CompilationUnit cu = parse("class X{java.util.Y y;}");
YamlPrinter yamlPrinter = new YamlPrinter(true);
System.out.println(yamlPrinter.output(cu));
}
}


![image-20211228111647854](/img/sin/M00/00/EC/wKg0C2IphKGARgtUAADE829Ou7Q378.png)

#### XML

```java
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.printer.XmlPrinter;
import static com.github.javaparser.StaticJavaParser.parse;

public class XmlSerDemo {
    public static void main(String[] args) {
        CompilationUnit cu = parse("class X{java.util.Y y;}");
        XmlPrinter printer = new XmlPrinter(true);
        System.out.println(printer.output(cu));
    }
}

image-20211228111817441


前面我们对下面一段源码生成AST语法树图,下面分析一下AST语法树有那些内容。

package com.sumsec.sources.UserDemo;

import java.time.LocalTime;

public class TimePrinter {
public static void main(String[] args) {
System.out.println(LocalTime.now());
}
}
首先是有一个根节点,根节点下面有三个叶子节点,分别是packageDeclarationimportstypes

image-20211228143811027

packageDeclaration是对应着TimePrinter的包名称,对应ql规则中谓词的hasQualifiedName或者是getQualifiedName

image-20211228144236650

举例说明

`ql
import java

from Class c
select c.getQualifiedName()


![image-20211228145616981](/img/sin/M00/00/EC/wKg0C2IphJmABrglAACmsIbjjpQ768.png)

---

#### imports

**imports**是对应着导入的包名,示例中导入的包名java.time.LocalTime。对应ql文件中的ImportType模块。

![image-20211228145720020](/img/sin/M00/00/EC/wKg0C2IphJ-ASddHAADgFSJ8VNM536.png)

举例查看哪里导入**org.apache.commons.lang3.compare**下的任意类,编写ql规则就能很快找到。

```ql
import java

from ImportType i, Class c
where c.getPackage().getName() = "org.apache.commons.lang3.compare"
and i.getImportedType() = c
select i

image-20211228152327119

image-20211228152318395


image-20211228152811903

Type是一个大的模块,除了packageDeclaration和import模块其他所有的内容都属于Types。换一句话说,除了包名和导入的包其他所有的都是属于Type,像Javadoc、method、类名、字段等等。。。

Type模块也是ql重点模块,首先可以type下面的节点是类型是ClassOrInterface,对应是类或者接口主体class f{}

AST的ClassOrInterface是有判断是否是接口,但在ql模块里是没有这个谓词的,将接口和类统一归为Class模块。


学习AST语法树可以更好程度上了解ql的规则编写与ql开发者对应的编写规则的依据来源,不然有时候确实是有些地方可以无从下手。

虽然ql的语法远不止这些,但学习AST语法树能够让我们从根本上理解为什么ql的规则是这么编写。之前笔者在这块就走了不少弯路,大多数代码审计工具其实多多少少会涉及到AST的知识,另外程序分析里面也有涉及了AST知识。总的来说AST对于有代码分析的需求的研究人员应该是必须的学习之路。

DOT格式导出之后转化成图片,比较直观更加方便、容易获取关键信息。


为了更好的分析AST和CFG,本人写了一款工具。工具官方网站静态程序分析工具 主要生成方法的CFG和.java文件的AST,使用教程也在网站的。是一款开源工具,欢迎大家使用,提交issue和pr。


https://houbb.github.io/2020/05/29/java-ast-04-javaparser-ast

https://javaparser.org/inspecting-an-ast/

https://github.com/javaparser/javaparser/blob/master/javaparser-core-serialization/src/test/java/com/github/javaparser/serialization/JavaParserJsonSerializerTest.java

标签:github,java,联系,CodeQL,javaparser,AST,import,com
From: https://www.cnblogs.com/SecIN/p/17544871.html

相关文章

  • 十二、ElasticSearch和Kibana安装及入门--谷粒商城
    ElasticSearch官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html官方中文:https://www.elastic.co/guide/cn/elasticsearch/guide/current/foreword_id.html社区中文:https://es.xiaoleilu.com/index.htmlhttp://doc.codingdict.com/elasti......
  • logstash+Elasticseach单节点 让logstash生成单副本索引
    要让Logstash和Elasticsearch生成单副本索引,请按照以下步骤更改Logstash的输出配置文件:打开Logstash配置文件,该文件默认位于 logstash/config 目录下。找到输出部分配置,并添加以下行:output{elasticsearch{hosts=>["localhost"]index=>"your......
  • CF603E Pastoral Oddities
    题目条件的充要条件是原图每个连通块点数都是偶数。必要性:若为奇数,则总度数为奇数*奇数,还是奇数,但是每条边贡献两个度,总度数一定是偶数。矛盾。充分性:对于一个偶数个点的连通块,我们一定能找到合法的边集,构造方式如下:随便抠出一颗生成树,随便定个根,从叶子开始向上重复这个......
  • SAM-FastSAM-MobileSAM
    SAM-FastSAM-MobileSAM目录SAM-FastSAM-MobileSAMSAM:FastSAM:MobileSAM参考资料SAM:构建了一个大型分割数据集,包含1100w图像10亿masks模型结构上,包含三个部分图像编码器,灵活的提示编码器和快速的掩码解码器。建立在Transformer视觉模型之上。imageencoder采用VITDet中......
  • Contrast Value(数学规律)
    #ContrastValue##题面翻译定义序列$a_1,a_2,\dots,a_n$的权值是$|a_1-a_2|+|a_2-a_3|+\dots+|a_{n-1}-a_n|$。$T$次询问,每次给一个序列$a$,一个$a$的子序列$b$合法当且仅当$b$权值和$a$相等,求$b$的最小长度。##题目描述Foranarrayofintegers$[a_1,a......
  • mapbox_master
    1.项目描述根据奔跑吧面条的**vue-big-screen**开源框架基础上进行修改。项目需要全屏展示(按F11)。项目部分区域使用了全局注册方式,增加了打包体积,在实际运用中请使用按需引入。项目环境:Vue-cli、DataV、Echarts、Webpack、Npm、Node,axios,mock。请拉取master分支的代码,其......
  • 使用 INFINI Console 实现 Elasticsearch 的增量数据迁移
    功能介绍#在INFINIConsole1.3.0版本里,数据迁移功能增加了对增量迁移的支持。这篇文章将会介绍增量迁移的具体使用方法和实现原理。场景介绍#以常见的日志场景为例,假设A集群有一个用来记录线上HTTP请求记录的索引request-logs,数据结构如下:{"request_body":{...},......
  • apollo+carsim自动驾驶控制模块仿真 windows联系独编译,
    apollo+carsim自动驾驶控制模块仿真windows联系独编译,和carsim联合仿真仿真调试有编译和调试过程文档基于windows平台,所有依赖的库有预编译好的包apollo6.0版本。ID:6699625478961058......
  • 升级Elasticsearch到8.7.1版本,我给自己挖了很多坑......
    转载说明:如果您喜欢这篇文章并打算转载它,请私信作者取得授权。感谢您喜爱本文,请文明转载,谢谢。最近因为某些原因,需要将ES升级到8.7.1版本。之前用的ES版本比较老了,这次部署新版本ES,发现变化蛮大的,一小心又踩了一些坑,还给自己挖了一些坑......1.java版本不符合需求,es启动失败报错内......
  • web中间件漏洞之(3)fastjson反序列化漏洞
    引言fastjson可以将Java对象序列化为json格式,也可将json反序列化为Java对象。在请求包里面中发送恶意的json格式payload,fastjson在处理json对象时使用了autotype机制,允许在反序列化时通过@type指定反序列化的类,调用指定类的set和get方法。攻击者可以通过rmi或ldap服务,将ldap......