用 soot 生成安卓App的控制流 Day 1

以下实验环境是在 Ubuntu 下,使用 eclipse kepler, java 1.7

多版本java管理

注意!soot不支持java 1.8版本,请在eclipse 中设置JRE是1.7的版本。

使用如下方法安装java
java的默认路径为 /usr/lib/jvm

安装命令

1
2
3
4
$ sudo add-apt-repository ppa:webupd8team/java
$ sudo apt-get update
$ sudo apt-get install oracle-java8-installer
$ sudo apt-get install oracle-java7-installer

临时切换java版本

1
2
sudo update-java-alternatives -s java-8-oracle
sudo update-java-alternatives -s java-7-oracle

eclipse soot 插件安装

注意!soot的eclipse plugin 不支持 kepler 以上的版本。
所以需要安装 eclipse kepler 的版本。
注意!soot不支持java 1.8版本,请在eclipse 中设置JRE是1.7的版本。
在 Window -> preference -> Java -> Installed JREs 修改。

进入
Help -> Install New Software -> add

http://sable.github.io/soot/eclipse/

然后一路next即可。

之后对 .class,或 .java 文件按右键即可出现soot的选项。按提示步骤操作即可。

建立soot项目

File -> New -> Example -> A simple BodyTransformer
可以修改 SOOTCLASSES 路径
Project -> Properties -> Java Build Path:Library

Android class 文件的产生

首先将 apk 文件进行 unzip ,然后对 classes.dex 文件进行dex2jar,之后再次unzip产生的jar文件后即可生成 MainActivity.class 等文件

1
2
3
unzip crackme.apk -d ~/crackme
./d2j-dex2jar.sh classes.dex
unzip classes-dex2jar.jar -d ~/crackme-jar

soot 的基本使用方法

本示例是将一个 Android 的 class 文件转换成 Jimple 的 IR 表示方式
–keep-line-number 保持行数不变
–xml-attributes 对生成的jimple文件进行着色
–f J 输出类型时 Jimple
–cp usr/lib/jvm/java-7-oracle/jre/lib/ext/zipfs.jar:…. soot的class-path
–d 输出路径

1
java -cp soot-2.5.0.jar soot.Main --keep-line-number --xml-attributes --f J --cp /usr/lib/jvm/java-7-oracle/jre/lib/ext/zipfs.jar:/usr/lib/jvm/java-7-oracle/jre/lib/rt.jar:/usr/lib/jvm/java-7-oracle/jre/lib/ext/sunpkcs11.jar:/usr/lib/jvm/java-7-oracle/jre/lib/resources.jar:/usr/lib/jvm/java-7-oracle/jre/lib/ext/sunec.jar:/usr/lib/jvm/java-7-oracle/jre/lib/ext/sunjce_provider.jar:/usr/lib/jvm/java-7-oracle/jre/lib/jfr.jar:/home/gary/workspace-kepler/Test/bin/:/usr/lib/jvm/java-7-oracle/jre/lib/jsse.jar:/usr/lib/jvm/java-7-oracle/jre/lib/ext/localedata.jar:/usr/lib/jvm/java-7-oracle/jre/lib/jce.jar:/usr/lib/jvm/java-7-oracle/jre/lib/charsets.jar:/usr/lib/jvm/java-7-oracle/jre/lib/ext/dnsns.jar:/home/gary/workspace-kepler/Test/src/:/home/gary/Android/Sdk/platforms/android-24/android.jar:/Test/src::null --d /home/gary/workspace-kepler/Test/sootOutput com.droider.crackme0201.MainActivity

利用 CFGViewer 生成程序控制流图

以下是以soot作为命令行工具的使用方法。

生成 dot 文件

首先使用 CFGViewer 生成 dot 文件
–graph=BriefUnitGraph 生成图的类型
–ir=jimple 使用jimple作为中间语言
–soot-class-path soot的classpath

1
java -cp soot-2.5.0.jar soot.tools.CFGViewer --graph=BriefUnitGraph --ir=jimple --soot-class-path /usr/lib/jvm/java-7-oracle/jre/lib/ext/zipfs.jar:/usr/lib/jvm/java-7-oracle/jre/lib/rt.jar:/usr/lib/jvm/java-7-oracle/jre/lib/ext/sunpkcs11.jar:/usr/lib/jvm/java-7-oracle/jre/lib/resources.jar:/usr/lib/jvm/java-7-oracle/jre/lib/ext/sunec.jar:/usr/lib/jvm/java-7-oracle/jre/lib/ext/sunjce_provider.jar:/usr/lib/jvm/java-7-oracle/jre/lib/jfr.jar:/home/gary/workspace-kepler/Test/bin/:/usr/lib/jvm/java-7-oracle/jre/lib/jsse.jar:/usr/lib/jvm/java-7-oracle/jre/lib/ext/localedata.jar:/usr/lib/jvm/java-7-oracle/jre/lib/jce.jar:/usr/lib/jvm/java-7-oracle/jre/lib/charsets.jar:/usr/lib/jvm/java-7-oracle/jre/lib/ext/dnsns.jar:/home/gary/workspace-kepler/Test/src/:/home/gary/dev/android-platforms/android-17/android.jar:/home/gary/dev/android-platforms/android-17/android-17-api.jar:/Test/src::null --d /home/gary/workspace-kepler/Test/sootOutput com.droider.crackme0201.MainActivity

使用 graphviz 将dot文件转化为png

1
2
sudo apt-get install graphviz
dot -Tpng android.widget.Button(com.droider.crackme0201.MainActivity\).dot > output.png

之后可以用以下脚本处理,一个是替换生成的文件名,去除一些特殊字符,另一个是批量生成png图片。
发现shell的交互模式、以及不同的shell,可能造成脚本运行失败,建议用bash执行脚本。
bash script_name.sh,如果用 ./script_name.sh 可能会执行失败。

replace_spaces.sh

1
2
3
4
5
6
7
8
9
#/bin/bash
find . -type f -name "*.dot" -print |
while read name; do
# echo $name
na=$(echo $name | tr '[' '_' | tr ']' '_' | tr ' ' '_' | tr '\<' '_' | tr '\>' '_' | tr '\$' '_')
if [[ $name != $na ]]; then
mv "$name" $na
fi
done

generate_png.sh

1
2
3
4
5
6
7
8
#/bin/bash
dotfile=` find . -name '*.dot' -type f`
for fdot in $dotfile
do
dotfname=`basename -s .dot $fdot`
# echo $dotfname.png
dot -Tpng $fdot >$dotfname.png
done

出错处理

报错记录1

解决方法 -soot-class-path 中加入 android-17-api.jar
android-17-api.jar 下载地址
https://github.com/Sable/android-platforms
直接下载 Android sdk 在里面也是能找到的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
➜ soot-runable java -cp soot-2.5.0.jar soot.tools.CFGViewer --graph=BriefUnitGraph --ir=jimple --soot-class-path /usr/lib/jvm/java-7-oracle/jre/lib/ext/zipfs.jar:/usr/lib/jvm/java-7-oracle/jre/lib/rt.jar:/usr/lib/jvm/java-7-oracle/jre/lib/ext/sunpkcs11.jar:/usr/lib/jvm/java-7-oracle/jre/lib/resources.jar:/usr/lib/jvm/java-7-oracle/jre/lib/ext/sunec.jar:/usr/lib/jvm/java-7-oracle/jre/lib/ext/sunjce_provider.jar:/usr/lib/jvm/java-7-oracle/jre/lib/jfr.jar:/home/gary/workspace-kepler/Test/bin/:/usr/lib/jvm/java-7-oracle/jre/lib/jsse.jar:/usr/lib/jvm/java-7-oracle/jre/lib/ext/localedata.jar:/usr/lib/jvm/java-7-oracle/jre/lib/jce.jar:/usr/lib/jvm/java-7-oracle/jre/lib/charsets.jar:/usr/lib/jvm/java-7-oracle/jre/lib/ext/dnsns.jar:/home/gary/workspace-kepler/Test/src/:/home/gary/Android/Sdk/platforms/android-24/android.jar:/Test/src::null --d /home/gary/workspace-kepler/Test/sootOutput com.droider.crackme0201.MainActivity
Soot started on Thu Aug 04 18:56:04 CST 2016
Transforming com.droider.crackme0201.MainActivity...
Generate dot file in /home/gary/workspace-kepler/Test/sootOutput/void <init>().dot
Generate dot file in /home/gary/workspace-kepler/Test/sootOutput/void <init>(java.lang.Object[],com.android.tools.fd.runtime.InstantReloadException).dot
Generate dot file in /home/gary/workspace-kepler/Test/sootOutput/android.widget.EditText access$000(com.droider.crackme0201.MainActivity).dot
Generate dot file in /home/gary/workspace-kepler/Test/sootOutput/android.widget.EditText access$100(com.droider.crackme0201.MainActivity).dot
Generate dot file in /home/gary/workspace-kepler/Test/sootOutput/boolean access$200(com.droider.crackme0201.MainActivity,java.lang.String,java.lang.String).dot
Generate dot file in /home/gary/workspace-kepler/Test/sootOutput/android.widget.Button access$300(com.droider.crackme0201.MainActivity).dot
Exception in thread "main" soot.SootMethodRefImpl$ClassResolutionFailedException: Class android.app.Activity doesn't have method setPersistent([boolean]) : void; failed to resolve in superclasses and interfacesLooking in android.app.Activity which has methods
[
<android.app.Activity: void <init>()>,
<android.app.Activity: android.content.Intent getIntent()>,
<android.app.Activity: void setIntent(android.content.Intent)>, <android.app.Activity: android.app.Application getApplication()>,
......
<android.app.Activity: boolean isChild()>,
<android.app.Activity: android.app.Activity getParent()>,
<android.content.ComponentCallbacks: void onLowMemory()>
]
at soot.SootMethodRefImpl.resolve(SootMethodRefImpl.java:183)
at soot.SootMethodRefImpl.resolve(SootMethodRefImpl.java:109)
at soot.BriefUnitPrinter.methodRef(BriefUnitPrinter.java:43)
at soot.jimple.internal.AbstractSpecialInvokeExpr.toString(AbstractSpecialInvokeExpr.java:99)
at soot.AbstractValueBox.toString(AbstractValueBox.java:52)
at soot.jimple.internal.JInvokeStmt.toString(JInvokeStmt.java:71)
at soot.util.cfgcmd.CFGToDotGraph.formatNodeText(CFGToDotGraph.java:502)
at soot.util.cfgcmd.CFGToDotGraph.drawCFG(CFGToDotGraph.java:316)
at soot.util.cfgcmd.CFGGraphType$1.drawGraph(CFGGraphType.java:128)
at soot.tools.CFGViewer.print_cfg(CFGViewer.java:247)
at soot.tools.CFGViewer.internalTransform(CFGViewer.java:76)
at soot.BodyTransformer.transform(BodyTransformer.java:51)
at soot.Transform.apply(Transform.java:104)
at soot.BodyPack.internalApply(BodyPack.java:49)
at soot.Pack.apply(Pack.java:124)
at soot.PackManager.runBodyPacks(PackManager.java:775)
at soot.PackManager.runBodyPacks(PackManager.java:463)
at soot.PackManager.runBodyPacks(PackManager.java:380)
at soot.PackManager.runPacks(PackManager.java:357)
at soot.Main.run(Main.java:198)
at soot.Main.main(Main.java:141)
at soot.tools.CFGViewer.main(CFGViewer.java:101)

参考资料

[1] soot之Eclipse插件
[2] soot 基本对象
[3] Creating a class from scratch(从头开始创建一个类)
[4] 利用Soot插装Android App