1.下载soot的相关jar包,并将其导入eclipse中:
在Eclipse中导入jar包的方法:右键项目->Build Path->Add External Achieves
然后选择单个或多个的,对应的库;
2.下载不同版本的Android标准库https://github.com/Sable/android-platforms,
Soot利用这些标准库来解析所插装的应用程序的类型。
3.官方给的一个测试例:
import java.util.Iterator;
import java.util.Map;
import soot.Body;
import soot.BodyTransformer;
import soot.Local;
import soot.PackManager;
import soot.PatchingChain;
import soot.RefType;
import soot.Scene;
import soot.SootClass;
import soot.SootMethod;
import soot.Transform;
import soot.Unit;
import soot.jimple.AbstractStmtSwitch;
import soot.jimple.InvokeExpr;
import soot.jimple.InvokeStmt;
import soot.jimple.Jimple;
import soot.jimple.StringConstant;
import soot.options.Options;
public class AndroidInstrument {
public static void main(String[] args) {
//告知Soot装载Android apk文件
Options.v().set_src_prec(Options.src_prec_apk);
//告知Soot输出一个Dex/APK 文件
Options.v().set_output_format(Options.output_format_dex);
// 告诉Soot装着两个类,我们在插装的时候需要这两个类,但可能被插装的APK不需要这两个类
Scene.v().addBasicClass("java.io.PrintStream",SootClass.SIGNATURES);
Scene.v().addBasicClass("java.lang.System",SootClass.SIGNATURES);
PackManager.v().getPack("jtp").add(new Transform("jtp.myInstrumenter", new BodyTransformer() {
@Override
protected void internalTransform(final Body b, String phaseName, @SuppressWarnings("rawtypes") Map options) {
final PatchingChain<Unit> units = b.getUnits();
//important to use snapshotIterator here
for(Iterator<Unit> iter = units.snapshotIterator(); iter.hasNext();) {
final Unit u = iter.next();
u.apply(new AbstractStmtSwitch() {
public void caseInvokeStmt(InvokeStmt stmt) {
InvokeExpr invokeExpr = stmt.getInvokeExpr();
if(invokeExpr.getMethod().getName().equals("onDraw")) {
Local tmpRef = addTmpRef(b);
Local tmpString = addTmpString(b);
// insert "tmpRef = java.lang.System.out;"
units.insertBefore(Jimple.v().newAssignStmt(
tmpRef, Jimple.v().newStaticFieldRef(
Scene.v().getField("<java.lang.System: java.io.PrintStream out>").makeRef())), u);
// insert "tmpLong = 'HELLO';"
units.insertBefore(Jimple.v().newAssignStmt(tmpString,
StringConstant.v("HELLO")), u);
// insert "tmpRef.println(tmpString);"
SootMethod toCall = Scene.v().getSootClass("java.io.PrintStream").getMethod("void println(java.lang.String)");
units.insertBefore(Jimple.v().newInvokeStmt(
Jimple.v().newVirtualInvokeExpr(tmpRef, toCall.makeRef(), tmpString)), u);
//check that we did not mess up the Jimple
b.validate();
}
}
});
}
}
}));
soot.Main.main(args);
}
private static Local addTmpRef(Body body)
{
Local tmpRef = Jimple.v().newLocal("tmpRef", RefType.v("java.io.PrintStream"));
body.getLocals().add(tmpRef);
return tmpRef;
}
private static Local addTmpString(Body body)
{
Local tmpString = Jimple.v().newLocal("tmpString", RefType.v("java.lang.String"));
body.getLocals().add(tmpString);
return tmpString;
}
}
4.带参数运行程序
-android-jars E:\\Soot\\Android_Flatforms
-process-dir E:\\Soot\\DeskClock\\bin\\DeskClock.apk
第一个路径为android标准库的路径,第二个路径为APK的路径