Loading

Soot使用笔记

一、Soot的安装与使用

1、soot简介

Soot是McGill大学的Sable研究小组自1996年开始开发的Java字节码分析工具,它提供了多种字节码分析和变换功能,通过它可以进行过程内和过程间的分析优化,以及程序流图的生成,还能通过图形化的方式输出,让用户对程序有个直观的了解。尤其是做单元测试的时候,可以很方便的通过这个生成控制流图然后进行测试用例的覆盖,显著提高效率。

soot项目在github上的地址为:https://github.com/Sable/soot

soot是java优化框架,提供4种中间代码来分析和转换字节码。

  • Baf:精简的字节码表示,操作简单
  • Jimple:适用于优化的3-address中间表示
  • Shimple:Jimple的SSA变体
  • Grimple:适用于反编译和代码检查的Jimple汇总版本。

soot提供的输入和输出格式

输入格式

  • java
  • android 字节码
  • Jasmin,低级中间表示
  • soot提供的分析功能
  • class(Java8以后)

输出格式

  • Java字节码
  • android字节码
  • Jimple
  • Jasmin
  • shimple
  • baf
  • grimple
  • xml
  • class
  • dava
  • template
  • jar文件

soot提供的分析功能

  • 调用图构造
  • 指针分析
  • Def/use chains
  • 模块驱动的程序内数据流分析
  • 结合FlowDroid的污染分析

2.soot的安装

目前来说,要使用soot有三种途径,分别是命令行、程序内以及Eclipse插件(不推荐)

2.1、命令行

可以在这里下载最新的soot jar包,我下载的是4.1.0版本中的sootclasses-trunk-jar-with-dependencies.jar 包,这个包应该自带了soot所需要的所有依赖。下载完成后使用powershell进入jar文件所在的文件夹(我的是D:\programing\sootTest),输入以下命令:

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

可以看到:

image-20210310150138324

再输入

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

可以看到有关soot的各种帮助信息。

2.2、程序内使用soot

从github上soot项目的简介可知,soot一般配合maven来进行部署,相关的依赖添加语句如下:

<dependencies>
  <dependency>
    <groupId>ca.mcgill.sable</groupId>
    <artifactId>soot</artifactId>
    <version>4.1.0</version>
  </dependency>
</dependencies>

因为目前我的目的只是简单的使用soot,所以对于程序中soot的使用在后面学习了相关api再来更新。

3.命令行中soot的使用

我的目标是将java转化为Jimple以发现程序编译中的问题和规律。因此本文的重点就在这里,我先在soot.jar所在的文件夹下新建了一个java文件HelloWorld.java如下图所示:

//HelloWorld.java
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("hello");
    }
}

因为我使用的Java版本是JDK1.8,根据soot提示,默认输入是class文件,所以我先用javac命令将HelloWorld.java编译为HelloWorld.class。

javac HelloWorld.java

下面我们尝试将上面得到的class文件作为输入传给soot.

java -cp sootclasses-trunk-jar-with-dependencies.jar soot.Main -pp -cp .  HelloWorld

得到的结果没有报错,但是也无事发生,这是因为soot需要通过-f属性指定输出的类型,这里我们将输出类型指定为Jimple,查询文档之后得知要添加-f J以确定输出格式,最终的语句如下:

java -cp sootclasses-trunk-jar-with-dependencies.jar soot.Main -f J -pp -cp .  HelloWorld

该命令在jar文件所在目录下生成了一个sootOutput文件夹,里面有一个HelloWorld.jimple文件,使用Idea编辑器打开这个文件,得到的内容如下,这就是一个最基本的HelloWorld.java文件所形成的jimple码。

public class HelloWorld extends java.lang.Object
{

    public void <init>()
    {
        HelloWorld r0;

        r0 := @this;

        specialinvoke r0.<init>();

        return;
    }

    public static void main(java.lang.String[])
    {
        java.io.PrintStream $r0;
        java.lang.String[] r1;

        r1 := @parameter0;

        $r0 = java.lang.System.out;

        $r0.println("hello");

        return;
    }
}

3.soot命令行相关参数设置

soot/wiki里的命令表格写的十分清楚和明确,这里我就直接搬运过来,方便以后查阅。

二、Soot生成控制流图

如果是将Soot当作简单工具来分析的人,可以直接使用Soot自带的工具soot.tools.CFGViewer分析类中的每个方法的控制流并生成DOT语言描述的控制流图,然后用graphviz中的dot命令来转换成可视化图形格式如.PNG

1、使用soot.tools.CFGViewer来生成Triangle.class的控制流图

//Triangle.class
package Soot;

public class Test {
    private double num = 5.0;
    public double cal(int num, String type){
        double temp=0;
        if(type == "sum"){
            for(int i = 0; i <= num; i++){
                temp =temp + i;
            }
        }
        else if(type == "average"){
            for(int i = 0; i <= num; i++){
                temp = temp + i;
            }
            temp = temp / (num -1);
        }else{
            System.out.println("Please enter the right type(sum or average)");
        }
        return temp;
    }
}

java -cp sootclasses-trunk-jar-with-dependencies.jar soot.tools.CFGViewer -pp -cp . Triangle

生成了Triangle.dot 文件

dot -Tpng -o Triangle.png Triangle.dot 

生成了png文件。

pic2

三、mac下的Graphviz安装及使用

1、安装Graphviz

homebrew安装完毕后运行 brew install graphviz即可

2、例子

  • 使用文本编辑器(这里用的是sublime )输入以下内容:

    digraph pic { 
    	Hello -> World
    }
    
  • 保存为pic.dot文件

  • 打开终端,切换到dot文件所在目录,输入dot pic.dot -T png -o pic.png

  • 可以看到在dot文件目录下生成了一个pic.png文件

pic2

posted @ 2021-03-10 15:11  xine  阅读(6776)  评论(0编辑  收藏  举报