序言
江山留胜迹,我辈复登临。
今天继续跟Soot,来看如何反汇编class文件。
Soot基本用途
Soot有两个基本用途:它可以用作独立的命令行工具或Java编译器框架。
作为命令行工具,Soot可以:
- 反汇编类文件
- 汇编类文件
- 优化类文件
作为Java编译器框架,Soot可用作开发新优化的测试平台。然后,可以将这些新的优化添加到Soot命令行工具调用的优化基础集。添加的优化部分可以应用于单个类文件,也可以应用于整个应用程序。
Soot通过能够以各种不同形式处理类文件来完成这些无数的任务。目前,Soot接受来自以下来源的代码,并输出其任何中间表示:
- Java(字节码和Java 7之前的源代码),包括编译成Java字节码的其他语言,例如Scala
- Android字节码
- 简单的中间表示
- Jasmin,低级别的中间表示。
通过使用-help选项调用Soot,可以看到输出格式:
Soot中目前使用六个中间表示形式:baf,jimple,shimple,grimp,jasmin和classfile。每种形式的简要说明如下:
baf
字节码的简化表示形式。用于检查Java字节码作为堆栈代码,但格式更好。有两种文本表示形式(一种缩写(.b文件),一种完整(.baf文件)。)jimple
键入3地址代码。用于执行优化和检查字节码的非常方便的表示形式。有两个文本表示形式(.jimp文件和.jimple文件。)shimple
Jimple的SSA变体。有两个文本表示形式(.shimp文件和.shimple文件。)grimp
聚集的(相对于表达式树)jimple。检查反汇编代码的最佳中间表示。有两个文本表示形式(.grimp文件和.grimple文件。)jasmin
凌乱的汇编器格式。主要用于调试Soot。Jasmin文件以“ .jasmin”结尾。classfiles
原始Java字节码格式。二进制(非文本)表示形式。通常的.class文件。
生成一个Jimple文件
先实现一个简单的Jimple类:
1 | public class Hello |
只需编译该类(使用javac或其他编译器),然后在Hello.class所在的目录中尝试以下命令。
1 | java soot.Main -cp CLASSPATH -f jimple Hello |
1 | java -cp soot-4.2.1.jar soot.Main -cp . -f J -pp Hello |
名为Hello.jimple的文件应包含:
1 | public class Hello extends java.lang.Object |
例子:为Java基础类库生成baf文件
接下来尝试为任何类文件生成.b,.baf,.jimp,.jimple,.grimp和.grimple文件。一个特别好的测试是JDK库中的类文件。所以像这样的命令:
1 | java -cp soot-4.2.1.jar soot.Main -cp . -f baf -pp java.lang.String |
应该会产生一个文件java.lang.String.baf,其中包含以下格式的文本:
输出java文件
Soot不仅可以产生.jimple
文件还可以产生.java
文件。如果–f dava
用于反编译为Java,请确保该文件/lib/jce.jar
位于Soot的类路径中。
举例:
1 | java -cp soot-4.2.1.jar soot.Main -cp . -f d -pp lll |
该文件下有一个lll.class文件,直接选择-f d
,将其变为java文件:
lll.java代码如下: