package soot.jimple.infoflow.android.iccta.icc; import java.util.List; import java.util.Set; import soot.Body; import soot.Scene; import soot.SootMethod; import soot.Unit; import soot.jimple.Stmt; import soot.jimple.infoflow.android.data.AndroidMethod; import soot.jimple.infoflow.android.iccta.AndroidIPCManager; import soot.util.Chain; public class ICCLink { String fromSMString; SootMethod fromSM; Unit fromU; int instruction; String exit_kind; String destinationC; List<Integer> instructions; Chain<Unit> units = null; public ICCLink(String fromSMString, int instruction, String exit_kind, String destinationC, List<Integer> instructions) { this.fromSMString = fromSMString; this.fromSM = null; this.fromU = null; this.instruction = instruction; this.exit_kind = exit_kind; this.destinationC = destinationC; this.instructions = instructions; linkWithTarget(); } public void linkWithTarget() { if (fromSM == null) { try { fromSM = Scene.v().getMethod(fromSMString); Body body = fromSM.retrieveActiveBody(); units = body.getUnits(); // index in (0, 1, 2, 3, ...) int index = instructions.indexOf(instruction); System.out.println("body: "+ body); // get correct unit for the link source method int i = 0; for (Unit u: units) { Stmt stmt = (Stmt)u; System.out.println("bs: "+ stmt); if (!stmt.containsInvokeExpr()) continue; System.out.println("s: "+ stmt); if (isICCMethod(stmt.getInvokeExpr().getMethod())) { System.out.println("u: "+ u); if (index == i++) { fromU = u; break; } } } System.out.println("fromU: "+ fromU); } catch (Exception ex) { System.out.println("Linking the target: " + fromSMString + " is ignored."); //ex.printStackTrace(); } } } public boolean isICCMethod(SootMethod sm) { Set<AndroidMethod> amSet = AndroidIPCManager.ipcAMethods; String rightSm = sm.toString().split(":")[1]; for (AndroidMethod am: amSet) { String amRight = am.getSignature().split(":")[1]; if (amRight.equals(rightSm)) { return true; } } return false; } /** * this will return a unique String for ICCLink object */ public String toString() { StringBuilder sb = new StringBuilder(); boolean first = true; if (instructions != null) { for (int num : instructions) { if (first) { sb.append(num); first = false; } else { sb.append("," + num); } } } return fromSMString + " [" + instruction + "] " + destinationC + " {" + sb.toString() + "}"; } public String getFromSMString() { return fromSMString; } public void setFromSMString(String fromSMString) { this.fromSMString = fromSMString; } public SootMethod getFromSM() { return fromSM; } public void setFromSM(SootMethod fromSM) { this.fromSM = fromSM; } public Unit getFromU() { return fromU; } public void setFromU(Unit fromU) { this.fromU = fromU; } public int getInstruction() { return instruction; } public void setInstruction(int instruction) { this.instruction = instruction; } public String getExit_kind() { return exit_kind; } public void setExit_kind(String exit_kind) { this.exit_kind = exit_kind; } public String getDestinationC() { return destinationC; } public void setDestinationC(String destinationC) { this.destinationC = destinationC; } public List<Integer> getInstructions() { return instructions; } public void setInstructions(List<Integer> instructions) { this.instructions = instructions; } public Chain<Unit> getUnits() { return units; } public void setUnits(Chain<Unit> units) { this.units = units; } }