本文基于 VSCode 与 Maven 在 Win 10 配置 java 漏洞调试环境,并未使用 IDEA 与 Gradle
是的我用 VSCode 调 java,事实证明 IDEA 更好用,由于我懒得申请学生账号才用这么别扭的方法调 java,本文仅供参考
jdk 多版本安装与切换
对于某些漏洞,需要使用较旧版本的 jdk,例如 CC1 链在 jdk8u71 版本被修复,我们使用 8u71 之后的 jdk 版本就无法成功复现该链子
为了方便地在各种 jdk 版本之间切换,我们可以同时安装多个版本的 jdk
安装特定版本 JDK
以 jdk8u65 和 jdk8u71 为例
到 https://www.oracle.com/java/technologies/downloads/archive/ 找到 java8
点进去找到要安装的 jdk 小版本
jdk8u71:
jdk8u65:
根据自己的系统版本下载对应的 jdk 安装包,注意是 jdk,也就是 Java SE Development Kit
别误下载了 jre,也就是 Java SE Runtime Environment
在 Oracle 官网下载 JDK 是需要登录 Oracle 账号的,没有的话请先注册一个
如果你的电脑是 win10,下载完成后你应该能找到下面这样的安装包
运行程序安装即可
我们不需要独立 JRE,所以该模块我们将其设置为 “不可用”
然后修改一下 JDK 的安装路径,你喜欢默认安装路径就别改
然后点击 “下一步” 安装即可,我就都安装到 d:/Java
里了
配置环境变量
环境变量配置:
JAVA_HOME=这里填JDK的安装路径
PATH=%JAVA_HOME%/bin;%JAVA_HOME%/jre/bin
以防万一,这里提醒一下,不要把 PATH 变量中的其他内容给删掉
以我安装的 jdk8u65 为例
在终端使用 java -version
和 javac -version
验证安装
安装 VSCode 插件
直接找到微软提供的整合包安装即可
切换 JDK 版本
需要切换 jdk 版本时,修改 JAVA_HOME 即可,这里从 8u65 切换到 8u71
对于较高版本的 jdk,是不存在 %JAVA_HOME%/jre
这个文件夹的
但是没有关系,按照前面的方法配置环境变量,照样能够正常使用
来跑个 HelloWorld
新建 d:/MyCode/java
文件夹,创建 hello.java
public class hello {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
javac hello.java; java hello
编译执行
输出了 Hello World
,确认 jdk 可以正常使用
Maven 安装与配置
Maven 是 Apache 基金会维护的一个 Java 构建工具,需要研究一些第三方 java 包中的漏洞时,就可以用 Maven 下载这些包
安装 Maven
到 Maven 官网:https://maven.apache.org/ 中下载 maven 安装包
下载后解压到你喜欢的路径中
然后添加环境变量
PATH=Maven安装路径/bin
在终端使用 mvn -v
验证安装
配置 Maven
Maven 安装路径下存在一个 conf
文件夹,里面的 settings.xml
是 Maven 的配置文件
修改 Maven 仓库路径
Maven 默认将软件包存储在 用户家目录/.m2/repository/
下,通过 localRepository
标签我们可以更改本地仓库的路径
添加镜像源
默认源服务器位于国外,下载速率可能较慢,而且受网络波动的影响会比较大
这时我们可以配置一些位于国内的源服务,通过 mirrors
标签进行设置
以阿里云为例,我们向 mirrors
标签中添加如下内容即可
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
下面是对配置项的解释
配置项 | 意义 |
---|---|
id | 镜像源的唯一 id |
mirrorOf | 指定哪些软件包需要使用该镜像源进行下载,设置为 * 即所有软件包都使用该镜像源 |
name | 镜像源的名称 |
url | 镜像源的地址 |
配置 VSCode Maven 插件
在 settings.json 中添加 maven-settingsFile
和 java.configuration.maven.globalSettings
将 Maven 的配置文件所在路径填入即可
来跑个 HelloWorld
到 Maven 官网中能找到一个快速创建 Maven 项目模板的命令
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.5 -DinteractiveMode=false
-DgroupId
修改为你的组织id,一般来说使用倒置域名,例如 cn.caterpie.app
-DartifactId
修改为项目名称
其余选项保持默认即可,运行该命令,就会在当前目录创建一个符合 Maven 项目结构的文件夹
使用 vscode 打开该项目,能看到:
其中的 App.java
中已经包含了 HelloWorld 代码
使用 mvn compile package
编译并打包项目
然后使用 java -cp target/生成的jar包 组织id.App
运行
调试环境搭建
jdk 提供的部分核心类是只有字节码的(也就是 class 文件)
我们启动调试的时候要想跟进某段代码,就必须有源代码(也就是 java 文件)
为了调试某个与核心类有关的漏洞,我们要想办法拿到这些字节码的 java 源码
从 OpenJDK 中获取核心类源码
以 jdk8u 为例,到 https://hg.openjdk.org/jdk8u/jdk8u/jdk/tags 查找 openjdk 的仓库
然后找到 tag 为 jdk8u65 和 jdk8u71 的提交记录,下载源码包
解压后在 src\share\classes
目录即可找到源码
一般来说关注 sun 包中的代码即可
接下来需要让 vscode java 插件读取源码内容,这里是最恶心的地方,IDEA 在这个方面可以说完爆 vscode
首先我们要有一个 java 项目,可以是 maven 项目也可以是普通的 java 项目
无论是哪一种 java 项目,我们要引入的源码内容都无法超出项目根目录,也就是说我们的 sun 包(或其他你想引入的软件包)源码必须要在项目目录之下
当然你不需要把整个 sun 文件夹复制到你的项目里,只需要使用一个软链接即可
然后在 pox.xml 中添加源码目录,这里使用 build-helper-maven-plugin
插件实现
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>src/main/java</source> <!-- 默认源代码目录 -->
<source>source_jdk8u65</source> <!-- 自定义源代码目录 -->
</sources>
</configuration>
</execution>
<execution>
<id>add-test-source</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/test/java</source> <!-- 默认测试源代码目录 -->
</sources>
</configuration>
</execution>
</executions>
</plugin>
此时 VSCode 查找某函数或属性等引用的时候就能找到 jdk 核心类中的引用,在调试模式下也能够正常跳转到 jdk 核心类的代码段中
不过 VSCode 有一个致命的问题,那就是它会对引入的 jdk 源码进行语法检查(IDEA 使用 SDKs 添加 jdk 源码路径的时候,是不会做语法检查的,因为没有必要),导致花费大量的系统资源,还会产生大量的错误提示
所以大伙有条件的话还是用 IDEA 吧 😅
获取依赖项源码
vscode 管理的 maven 项目似乎会自动下载依赖项源码 🤔
实际调试体验
目前尝试使用这种方式调试了几条 CC 链,体验还行
不过每次启动项目的时候速度都比较慢,因为 VSCode java 插件非要分析一通我引入的 jdk 源码