编译OpenJDK8并生成CodeQL数据库

1、前言

由于个人需求,想要使用CodeQL对JDK进行代码查询。

按照笔者平时的习惯,为了避免在目标代码库编译和生成CodeQL数据库上浪费时间,笔者多数情况下都会利用 lgtm 来搞定:

  • 方式一:在lgtm上搜索现成的CodeQL数据库。
    方式一用于直接获取代码库最新commit对应的CodeQL数据库。

  • 方式二:如果想要生成代码库指定版本所对应的CodeQL数据库,则先在github上clone一份代码库,然后切换git checkout <tag>切换到指定版本,然后git push到自己的github远程仓库中。接着通过配置 让lgtm集成到你github代码库中,这样lgtm就会对你的代码库启用CodeQL扫描,lgtm扫描后便可在上面下载CodeQL数据库(当然咯,也可以直接在lgtm上面直接进行CodeQL查询,看个人习惯和需要)。如下图:
    在这里插入图片描述
    在这里插入图片描述

但是笔者在lgtm上并没有找到 https://github.com/openjdk/jdk8u 可用的CodeQL数据库,具体原因不清楚,可能是lgtm无法通过常规的Java工程编译方式去编译openjdk?暂不细究了。完成目标比较重要。

所以就只能把OpenJDK 8的代码clone下来,自个编译并生成CodeQL数据库。

2、编译OpenJDK 8

其实只要确保代码库编译是没问题的,CodeQL数据库的生成也就没问题了,一条命令的事。

笔者成功编译了OpenJDK 8u1018u322 两个版本。


2.1 编译过程

1、使用docker镜像 ubuntu:16.04 搭建环境。
2、通过apt安装一些常用的命令行程序,以及编译时需要的依赖:

apt install -y build-essential gdb  cmake openjdk-8-jdk cpio file unzip zip wget
&&
apt install -y --no-install-recommends  libfontconfig1-dev libfreetype6-dev  libcups2-dev libx11-dev  libxext-dev  libxrender-dev  libxrandr-dev  libxtst-dev  libxt-dev libasound2-dev  libffi-dev  autoconf 

注:--no-install-recommends选项:使apt不要把推荐的软件作为安装的依赖。

3、上面的依赖安装完后,make程序的版本是4.1,由于该版本在编译OpenJDK 8u101版本时会报各种错误,所以为了简单起见,就干脆都用较低的3.81版本的make。因此从make官方下载3.81版本进行编译安装:

wget http://ftp.gnu.org/gnu/make/make-3.81.tar.gz 
  && tar -zxvf make-3.81.tar.gz 
  && cd /make-3.81 
  && bash configure -prefix=/usr 
  && make 
  && make install

安装完后如图:
在这里插入图片描述

4、进入OpenJDK源码目录,运行configure进行编译配置和编译环境检查:

# bash configure --with-debug-level=fastdebug  \
   --with-jvm-variants=server  \
   --with-boot-jdk=/usr/lib/jvm/java-1.8.0-openjdk-amd64 \
   --with-target-bits=64 \
   --enable-debug-symbols  \
   --with-native-debug-symbols=internal

编译选项可参考官方文档(参考[1])。
简单说一下用到的几个:

  • --with-jvm-variants:编译特定模式的Hotspot JVM虚拟机,这里选择server模式;
  • --with-boot-jdk:这里指定一个已经编译好的JDK路径,这个JDK叫作Bootstrap JDK,且版本至少为N-1。这里我们要编译的是8,所以至少要安装7版本的JDK,不过用8也是可以的,所以上面通过apt安装了openjdk-8-jdk
  • --with-target-bits:选择编译成32位还是64位;
  • --with-native-debug-symbols:符号信息的编译方式,我们选择internal
  • --enable-debug-symbols:启用调试符号信息。

检查通过后,如图:
在这里插入图片描述
5、执行make命令开始编译OpenJDK 8。

make images JOBS=4

编译完成后如下图:
在这里插入图片描述
在这里插入图片描述

3、生成CodeQL数据库

既然OpenJDK编译没问题了,那么生成CodeQL肯定就没问题了。

下载codeql命令行工具(下载地址:https://github.com/github/codeql-cli-binaries/releases)后,在OpenJDK的源码目录下执行如下命令生成CodeQL数据库:

codeql database create openjdk8u322-db  --language=java --command='make images JOBS=4'

:其实codeql生成数据库是在代码库编译的过程中进行的。上面我只是为了确保编译没问题,才先执行的编译。

4、QL查询 - 简单测试

笔者生成了OpenJDK 8u1018u322两个版本的CodeQL数据库。
在VS Code上编写查询简单玩一下:

import java

class RegistryContext_decodeObject extends Method {
    RegistryContext_decodeObject() {
        this.getDeclaringType().hasQualifiedName("com.sun.jndi.rmi.registry", "RegistryContext") and 
        this.getName() = "decodeObject"
    }
}

from RegistryContext_decodeObject m1
select m1

右键执行CodeQL: Run Query On Multiple Databases,执行完成后,在左侧Query HISTORY窗口便能选择查看在不同数据库的查询结果:
在这里插入图片描述
可以从com.sun.jndi.rmi.registry.RegistryContext#decodeObject() 方法看8u1018u322版本代码的其中一个区别,没错,就是JDK高版本对JNDI注入的限制。
在这里插入图片描述

5、小结

版本稍低的JDK(比如这里的8u101),编译的时候,笔者一开始用的ubuntu:18.04,结果编译的时候各种报错,后来换成3.81版本的make还是不行。为了避免再继续浪费时间,索性用了更低版本的ubuntu,结果顺利进行了编译…

不禁想起不记得在哪里看到的一句话:

Never to wrestle with a pig. You get dirty, and the pig like it.


2022-01-23 更新:
编译好的数据库分享到网盘了:
链接: hxxps://pan.baidu.com/s/1fllcshUXhgHOjq1-edywlg
提取码: s4v8

参考

[1] http://hg.openjdk.java.net/jdk8/jdk8/raw-file/tip/README-builds.html
[2] https://github.com/openjdk/jdk8u
[3] https://github.com/fnmsd/OpenJDK8-BuildEnv-Docker

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值