一文入门 soot
字数 1690 2025-08-26 22:11:22

Soot 静态分析工具入门指南

1. Soot 简介

Soot 是一个 Java 静态分析框架,主要用于程序分析和优化。它提供了多种中间表示(IR),其中最常用的是 Jimple,一种有类型的三地址码表示形式。

2. 安装与配置

下载地址

Soot 可以从以下地址下载:
https://soot-build.cs.uni-paderborn.de/public/origin/master/soot/soot-master/

验证安装

运行以下命令验证 Soot 是否安装成功:

java -cp sootclasses-trunk-jar-with-dependencies.jar soot.Main Jimple

Maven 依赖

<dependency>
    <groupId>org.soot-oss</groupId>
    <artifactId>soot</artifactId>
    <version>4.2.1</version>
</dependency>

3. 基本使用

示例代码

public class ForLoop {
    public static void main(String[] args) {
        int x = 0;
        for (int i = 0; i < 10; i++){
            x = x + 1;
        }
    }
}

生成 Jimple 代码

java -cp sootclasses-trunk-jar-with-dependencies.jar soot.Main -cp . -pp -process-dir examples/ForLoop/ -f J

参数说明:

  • -cp .:添加当前路径到 Soot 的 classpath
  • -pp:自动包含所需的 jar 文件(包括 java.lang.Object)
  • -process-dir:指定处理的目录
  • -f J:生成 Jimple 类型的文件(默认输出到 sootOutput 目录)

其他输出格式选项:

  • S:Shimple
  • G:Grimple

生成的 Jimple 示例

public class ForLoop extends java.lang.Object {
    public void <init>() {
        ForLoop r0;
        r0 := @this: ForLoop;
        specialinvoke r0.<java.lang.Object: void <init>()>();
        return;
    }
    
    public static void main(java.lang.String[]) {
        java.lang.String[] r0;
        int i1;
        r0 := @parameter0: java.lang.String[];
        i1 = 0;
    label1:
        if i1 >= 10 goto label2;
        i1 = i1 + 1;
        goto label1;
    label2:
        return;
    }
}

4. Jimple 中间表示

Jimple 特点

  • 有类型的三地址码(typed 3-address code)
  • 每个语句最多包含一个操作
  • 变量以 r 开头(如 r0
  • 临时变量以 $ 开头(如 $r0

方法调用类型

  • specialinvoke:调用构造函数、私有方法或父类方法
  • virtualinvoke:调用虚方法(常规实例方法)
  • interfaceinvoke:调用接口方法
  • staticinvoke:调用静态方法

5. 控制流图(CFG)生成

生成 CFG

java -cp sootclasses-trunk-jar-with-dependencies.jar soot.tools.CFGViewer -cp . -pp -process-dir examples/ForLoop/

安装 Graphviz

apt-get install graphviz
sudo apt-get install graphviz graphviz-doc

生成 PNG

dot -Tpng ForLoopMain.dot -o ForLoop.png

6. Soot 处理流程

Soot 的处理流程分为多个阶段(packs),每个阶段由三个字母标识:

  1. 第一个字母表示输入类型:

    • s:Shimple
    • j:Jimple
    • b:Baf
    • g:Grimp
  2. 第二个字母表示处理类型:

    • t:用户定义的转换(transformation)
    • o:优化(optimizations)
    • a:属性生成(attribute generation)
    • b:方法体创建(body creation)
  3. 第三个字母 p 表示 pack(处理阶段)

7. 在 Java 项目中使用 Soot

初始化配置

@Before
public void init() {
    soot.G.reset();  // 重置 Soot 环境
    Options.v().set_src_prec(Options.src_prec_class);  // 设置处理文件类型(默认 class)
    Options.v().set_process_dir(Arrays.asList("target/classes/com/examples"));  // 处理路径
    Options.v().set_whole_program(true);  // 开启全局模式
    Options.v().set_prepend_classpath(true);  // 对应命令行的 -pp
    Options.v().set_output_format(Options.output_format_jimple);  // 输出 Jimple 文件
    Scene.v().loadNecessaryClasses();  // 加载所有需要的类
}

运行分析

@Test
public void test() {
    PackManager.v().runPacks();  // 运行所有 packs
    PackManager.v().writeOutput();  // 输出结果到 sootOutput 目录
}

8. 自定义转换器(Transformer)

实现 BodyTransformer

public class TransformerTest extends BodyTransformer {
    @Override
    protected void internalTransform(Body body, String s, Map<String, String> map) {
        System.out.println(body.getMethod().getName());  // 输出方法名
    }
}

使用自定义 Transformer

@Test
public void test() {
    PackManager.v().getPack("jtp").add(new Transform("jtp.TT", new TransformerTest()));
    for (SootClass appClazz : Scene.v().getApplicationClasses()) {
        for (SootMethod method : appClazz.getMethods()) {
            Body body = method.retrieveActiveBody();
            PackManager.v().getPack("jtp").apply(body);
        }
    }
}

9. 流分析框架

Soot 提供了流分析框架,可用于实现数据流分析。

实现步骤

  1. 继承 FlowAnalysis

    • 前向分析:ForwardFlowAnalysis<Unit, FlowSet>
    • 后向分析:BackwardFlowAnalysis<Unit, FlowSet>
  2. 实现关键方法:

    • copy():复制流值(IN 到 OUT 或 OUT 到 IN)
    • merge():合并流值(实现转换函数)
    • flowThrough():流分析的核心逻辑
  3. 初始化流值:

    • newInitialFlow():初始化每个基本块的流值
    • entryInitialFlow():初始化入口流值
  4. 构造函数必须调用 doAnalysis

super(graph);
super.doAnalysis();

使用分析结果

OurAnalysis analysis = new OurAnalysis(graph);
analysis.getFlowBefore(s);  // 获取 Unit s 之前的流值
analysis.getFlowAfter(s);   // 获取 Unit s 之后的流值

10. 关键概念

Box 概念

  • Unit:表示 Jimple 中的语句
  • Local:表示 Jimple 中的本地变量
  • getUseBoxes():获取语句使用的变量
  • getDefBoxes():获取语句定义的变量

应用类获取

Scene.v().getApplicationClasses()  // 获取所有应用类

11. 总结

Soot 是一个功能强大的 Java 静态分析框架,通过本指南,您已经学习了:

  1. Soot 的安装和基本配置
  2. Jimple 中间表示的生成和理解
  3. 控制流图的生成和可视化
  4. Soot 的处理流程和阶段
  5. 如何在 Java 项目中使用 Soot
  6. 如何实现自定义转换器
  7. 如何使用 Soot 的流分析框架

这些基础知识将帮助您开始使用 Soot 进行更复杂的静态分析任务。

Soot 静态分析工具入门指南 1. Soot 简介 Soot 是一个 Java 静态分析框架,主要用于程序分析和优化。它提供了多种中间表示(IR),其中最常用的是 Jimple,一种有类型的三地址码表示形式。 2. 安装与配置 下载地址 Soot 可以从以下地址下载: https://soot-build.cs.uni-paderborn.de/public/origin/master/soot/soot-master/ 验证安装 运行以下命令验证 Soot 是否安装成功: Maven 依赖 3. 基本使用 示例代码 生成 Jimple 代码 参数说明: -cp . :添加当前路径到 Soot 的 classpath -pp :自动包含所需的 jar 文件(包括 java.lang.Object) -process-dir :指定处理的目录 -f J :生成 Jimple 类型的文件(默认输出到 sootOutput 目录) 其他输出格式选项: S :Shimple G :Grimple 生成的 Jimple 示例 4. Jimple 中间表示 Jimple 特点 有类型的三地址码(typed 3-address code) 每个语句最多包含一个操作 变量以 r 开头(如 r0 ) 临时变量以 $ 开头(如 $r0 ) 方法调用类型 specialinvoke :调用构造函数、私有方法或父类方法 virtualinvoke :调用虚方法(常规实例方法) interfaceinvoke :调用接口方法 staticinvoke :调用静态方法 5. 控制流图(CFG)生成 生成 CFG 安装 Graphviz 生成 PNG 6. Soot 处理流程 Soot 的处理流程分为多个阶段(packs),每个阶段由三个字母标识: 第一个字母表示输入类型: s :Shimple j :Jimple b :Baf g :Grimp 第二个字母表示处理类型: t :用户定义的转换(transformation) o :优化(optimizations) a :属性生成(attribute generation) b :方法体创建(body creation) 第三个字母 p 表示 pack(处理阶段) 7. 在 Java 项目中使用 Soot 初始化配置 运行分析 8. 自定义转换器(Transformer) 实现 BodyTransformer 使用自定义 Transformer 9. 流分析框架 Soot 提供了流分析框架,可用于实现数据流分析。 实现步骤 继承 FlowAnalysis : 前向分析: ForwardFlowAnalysis<Unit, FlowSet> 后向分析: BackwardFlowAnalysis<Unit, FlowSet> 实现关键方法: copy() :复制流值(IN 到 OUT 或 OUT 到 IN) merge() :合并流值(实现转换函数) flowThrough() :流分析的核心逻辑 初始化流值: newInitialFlow() :初始化每个基本块的流值 entryInitialFlow() :初始化入口流值 构造函数必须调用 doAnalysis : 使用分析结果 10. 关键概念 Box 概念 Unit :表示 Jimple 中的语句 Local :表示 Jimple 中的本地变量 getUseBoxes() :获取语句使用的变量 getDefBoxes() :获取语句定义的变量 应用类获取 11. 总结 Soot 是一个功能强大的 Java 静态分析框架,通过本指南,您已经学习了: Soot 的安装和基本配置 Jimple 中间表示的生成和理解 控制流图的生成和可视化 Soot 的处理流程和阶段 如何在 Java 项目中使用 Soot 如何实现自定义转换器 如何使用 Soot 的流分析框架 这些基础知识将帮助您开始使用 Soot 进行更复杂的静态分析任务。