Skip to content

Instantly share code, notes, and snippets.

@yehjames
Created August 23, 2014 06:00
Show Gist options
  • Save yehjames/7848d72c558bd6e5f839 to your computer and use it in GitHub Desktop.
Save yehjames/7848d72c558bd6e5f839 to your computer and use it in GitHub Desktop.
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
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.IntConstant;
import soot.jimple.InvokeExpr;
import soot.jimple.InvokeStmt;
import soot.jimple.Jimple;
import soot.jimple.StringConstant;
import soot.options.Options;
import java.io.*;
public class AndroidInstrumentVer2 {
public static void main(String[] args) throws Exception {
//prefer Android APK files// -src-prec apk
Options.v().set_src_prec(Options.src_prec_apk);
//output as APK, too//-f J
Options.v().set_output_format(Options.output_format_dex);
// resolve the PrintStream and System soot-classes
Scene.v().addBasicClass("java.io.PrintStream",SootClass.SIGNATURES);
Scene.v().addBasicClass("java.lang.System",SootClass.SIGNATURES);
Scene.v().addBasicClass("java.lang.Thread",SootClass.SIGNATURES);
Scene.v().addBasicClass("java.lang.StackTraceElement",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);
units.insertBefore(Jimple.v().newAssignStmt(tmpString,
IntConstant.v(111111)), u);
// insert "tmpRef.println(tmpString);"
SootMethod toCall = Scene.v().getSootClass("java.io.PrintStream").getMethod("void println(int)");
units.insertBefore(Jimple.v().newInvokeStmt(
Jimple.v().newVirtualInvokeExpr(tmpRef, toCall.makeRef(), tmpString)), u);
units.insertBefore(Jimple.v().newAssignStmt(
tmpRef, Jimple.v().newStaticInvokeExpr(
Scene.v().getMethod("<java.lang.Thread: java.lang.Thread currentThread()>").makeRef())), u);
// insert "tmpLong = 'HELLO';"
// units.insertBefore(Jimple.v().newAssignStmt(tmpString,
// StringConstant.v("HELLO")), u);
units.insertBefore(Jimple.v().newAssignStmt(tmpString,
IntConstant.v(1)), u);
// insert "tmpRef.println(tmpString);"
SootMethod toCall2 = Scene.v().getSootClass("java.io.PrintStream").getMethod("void println(int)");
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("int"));
body.getLocals().add(tmpString);
return tmpString;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment