use of soot.Body in project soot by Sable.
the class AbstractJimpleBasedICFG method getStartPointsOf.
@Override
public Collection<Unit> getStartPointsOf(SootMethod m) {
if (m.hasActiveBody()) {
Body body = m.getActiveBody();
DirectedGraph<Unit> unitGraph = getOrCreateUnitGraph(body);
return unitGraph.getHeads();
}
return Collections.emptySet();
}
use of soot.Body in project soot by Sable.
the class AbstractJimpleBasedICFG method isStartPoint.
@Override
public boolean isStartPoint(Unit u) {
Body body = unitToOwner.get(u);
DirectedGraph<Unit> unitGraph = getOrCreateUnitGraph(body);
return unitGraph.getHeads().contains(u);
}
use of soot.Body in project soot by Sable.
the class ReflectiveCallsInliner method initializeReflectiveCallsTable.
private void initializeReflectiveCallsTable() {
int callSiteId = 0;
SootClass reflCallsClass = Scene.v().getSootClass("soot.rtlib.tamiflex.ReflectiveCalls");
SootMethod clinit = reflCallsClass.getMethodByName(SootMethod.staticInitializerName);
Body body = clinit.retrieveActiveBody();
PatchingChain<Unit> units = body.getUnits();
LocalGenerator localGen = new LocalGenerator(body);
Chain<Unit> newUnits = new HashChain<Unit>();
SootClass setClass = Scene.v().getSootClass("java.util.Set");
SootMethodRef addMethodRef = setClass.getMethodByName("add").makeRef();
for (SootMethod m : RTI.methodsContainingReflectiveCalls()) {
{
if (!RTI.classForNameClassNames(m).isEmpty()) {
SootFieldRef fieldRef = Scene.v().makeFieldRef(reflCallsClass, "classForName", RefType.v("java.util.Set"), true);
Local setLocal = localGen.generateLocal(RefType.v("java.util.Set"));
newUnits.add(Jimple.v().newAssignStmt(setLocal, Jimple.v().newStaticFieldRef(fieldRef)));
for (String className : RTI.classForNameClassNames(m)) {
InterfaceInvokeExpr invokeExpr = Jimple.v().newInterfaceInvokeExpr(setLocal, addMethodRef, StringConstant.v(callSiteId + className));
newUnits.add(Jimple.v().newInvokeStmt(invokeExpr));
}
callSiteId++;
}
}
{
if (!RTI.classNewInstanceClassNames(m).isEmpty()) {
SootFieldRef fieldRef = Scene.v().makeFieldRef(reflCallsClass, "classNewInstance", RefType.v("java.util.Set"), true);
Local setLocal = localGen.generateLocal(RefType.v("java.util.Set"));
newUnits.add(Jimple.v().newAssignStmt(setLocal, Jimple.v().newStaticFieldRef(fieldRef)));
for (String className : RTI.classNewInstanceClassNames(m)) {
InterfaceInvokeExpr invokeExpr = Jimple.v().newInterfaceInvokeExpr(setLocal, addMethodRef, StringConstant.v(callSiteId + className));
newUnits.add(Jimple.v().newInvokeStmt(invokeExpr));
}
callSiteId++;
}
}
{
if (!RTI.constructorNewInstanceSignatures(m).isEmpty()) {
SootFieldRef fieldRef = Scene.v().makeFieldRef(reflCallsClass, "constructorNewInstance", RefType.v("java.util.Set"), true);
Local setLocal = localGen.generateLocal(RefType.v("java.util.Set"));
newUnits.add(Jimple.v().newAssignStmt(setLocal, Jimple.v().newStaticFieldRef(fieldRef)));
for (String constrSig : RTI.constructorNewInstanceSignatures(m)) {
InterfaceInvokeExpr invokeExpr = Jimple.v().newInterfaceInvokeExpr(setLocal, addMethodRef, StringConstant.v(callSiteId + constrSig));
newUnits.add(Jimple.v().newInvokeStmt(invokeExpr));
}
callSiteId++;
}
}
{
if (!RTI.methodInvokeSignatures(m).isEmpty()) {
SootFieldRef fieldRef = Scene.v().makeFieldRef(reflCallsClass, "methodInvoke", RefType.v("java.util.Set"), true);
Local setLocal = localGen.generateLocal(RefType.v("java.util.Set"));
newUnits.add(Jimple.v().newAssignStmt(setLocal, Jimple.v().newStaticFieldRef(fieldRef)));
for (String methodSig : RTI.methodInvokeSignatures(m)) {
InterfaceInvokeExpr invokeExpr = Jimple.v().newInterfaceInvokeExpr(setLocal, addMethodRef, StringConstant.v(callSiteId + methodSig));
newUnits.add(Jimple.v().newInvokeStmt(invokeExpr));
}
callSiteId++;
}
}
}
Unit secondLastStmt = units.getPredOf(units.getLast());
units.insertAfter(newUnits, secondLastStmt);
if (Options.v().validate())
body.validate();
}
use of soot.Body in project soot by Sable.
the class ReflectiveCallsInliner method inlineRelectiveCalls.
private void inlineRelectiveCalls(SootMethod m, Set<String> targets, Kind callKind) {
if (!m.hasActiveBody())
m.retrieveActiveBody();
Body b = m.getActiveBody();
PatchingChain<Unit> units = b.getUnits();
Iterator<Unit> iter = units.snapshotIterator();
LocalGenerator localGen = new LocalGenerator(b);
// for all units
while (iter.hasNext()) {
Chain<Unit> newUnits = new HashChain<Unit>();
Stmt s = (Stmt) iter.next();
// reflective invoke expression
if (s.containsInvokeExpr()) {
InvokeExpr ie = s.getInvokeExpr();
boolean found = false;
Type fieldSetGetType = null;
if (callKind == Kind.ClassForName && (ie.getMethodRef().getSignature().equals("<java.lang.Class: java.lang.Class forName(java.lang.String)>") || ie.getMethodRef().getSignature().equals("<java.lang.Class: java.lang.Class forName(java.lang.String,boolean,java.lang.ClassLoader)>"))) {
found = true;
Value classNameValue = ie.getArg(0);
newUnits.add(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(Scene.v().getMethod("<soot.rtlib.tamiflex.ReflectiveCalls: void knownClassForName(int,java.lang.String)>").makeRef(), IntConstant.v(callSiteId), classNameValue)));
} else if (callKind == Kind.ClassNewInstance && ie.getMethodRef().getSignature().equals("<java.lang.Class: java.lang.Object newInstance()>")) {
found = true;
Local classLocal = (Local) ((InstanceInvokeExpr) ie).getBase();
newUnits.add(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(Scene.v().getMethod("<soot.rtlib.tamiflex.ReflectiveCalls: void knownClassNewInstance(int,java.lang.Class)>").makeRef(), IntConstant.v(callSiteId), classLocal)));
} else if (callKind == Kind.ConstructorNewInstance && ie.getMethodRef().getSignature().equals("<java.lang.reflect.Constructor: java.lang.Object newInstance(java.lang.Object[])>")) {
found = true;
Local constrLocal = (Local) ((InstanceInvokeExpr) ie).getBase();
newUnits.add(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(Scene.v().getMethod("<soot.rtlib.tamiflex.ReflectiveCalls: void knownConstructorNewInstance(int,java.lang.reflect.Constructor)>").makeRef(), IntConstant.v(callSiteId), constrLocal)));
} else if (callKind == Kind.MethodInvoke && ie.getMethodRef().getSignature().equals("<java.lang.reflect.Method: java.lang.Object invoke(java.lang.Object,java.lang.Object[])>")) {
found = true;
Local methodLocal = (Local) ((InstanceInvokeExpr) ie).getBase();
Value recv = ie.getArg(0);
newUnits.add(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(Scene.v().getMethod("<soot.rtlib.tamiflex.ReflectiveCalls: void knownMethodInvoke(int,java.lang.Object,java.lang.reflect.Method)>").makeRef(), IntConstant.v(callSiteId), recv, methodLocal)));
} else if (callKind == Kind.FieldSet) {
SootMethod sootMethod = ie.getMethodRef().resolve();
if (sootMethod.getDeclaringClass().getName().equals("java.lang.reflect.Field") && fieldSets.contains(sootMethod.getName())) {
found = true;
// assign
fieldSetGetType = sootMethod.getParameterType(1);
// type
// of
// 2nd
// parameter
// (1st
// is
// receiver
// object)
Value recv = ie.getArg(0);
Value field = ((InstanceInvokeExpr) ie).getBase();
newUnits.add(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(Scene.v().getMethod("<soot.rtlib.tamiflex.ReflectiveCalls: void knownFieldSet(int,java.lang.Object,java.lang.reflect.Field)>").makeRef(), IntConstant.v(callSiteId), recv, field)));
}
} else if (callKind == Kind.FieldGet) {
SootMethod sootMethod = ie.getMethodRef().resolve();
if (sootMethod.getDeclaringClass().getName().equals("java.lang.reflect.Field") && fieldGets.contains(sootMethod.getName())) {
found = true;
// assign
fieldSetGetType = sootMethod.getReturnType();
// return
// type
// of
// get
Value recv = ie.getArg(0);
Value field = ((InstanceInvokeExpr) ie).getBase();
newUnits.add(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(Scene.v().getMethod("<soot.rtlib.tamiflex.ReflectiveCalls: void knownFieldSet(int,java.lang.Object,java.lang.reflect.Field)>").makeRef(), IntConstant.v(callSiteId), recv, field)));
}
}
if (!found)
continue;
NopStmt endLabel = Jimple.v().newNopStmt();
// for all recorded targets
for (String target : targets) {
NopStmt jumpTarget = Jimple.v().newNopStmt();
// boolean predLocal = Opaque.getFalse();
Local predLocal = localGen.generateLocal(BooleanType.v());
StaticInvokeExpr staticInvokeExpr = Jimple.v().newStaticInvokeExpr(UNINTERPRETED_METHOD);
newUnits.add(Jimple.v().newAssignStmt(predLocal, staticInvokeExpr));
// if predLocal == 0 goto <original reflective call>
newUnits.add(Jimple.v().newIfStmt(Jimple.v().newEqExpr(IntConstant.v(0), predLocal), jumpTarget));
SootMethod newMethod = createNewMethod(callKind, target, fieldSetGetType);
List<Value> args = new LinkedList<Value>();
switch(callKind) {
case ClassForName:
case ClassNewInstance:
// no arguments
break;
case ConstructorNewInstance:
// add Object[] argument
args.add((Value) ie.getArgs().get(0));
break;
case MethodInvoke:
// add Object argument
args.add((Value) ie.getArgs().get(0));
// add Object[] argument
args.add((Value) ie.getArgs().get(1));
break;
case FieldSet:
// add Object argument
args.add((Value) ie.getArgs().get(0));
// add value argument
args.add((Value) ie.getArgs().get(1));
break;
case FieldGet:
// add Object argument
args.add((Value) ie.getArgs().get(0));
break;
default:
throw new IllegalStateException();
}
StaticInvokeExpr methodInvokeExpr = Jimple.v().newStaticInvokeExpr(newMethod.makeRef(), args);
Local retLocal = localGen.generateLocal(newMethod.getReturnType());
newUnits.add(Jimple.v().newAssignStmt(retLocal, methodInvokeExpr));
if (s instanceof AssignStmt) {
AssignStmt assignStmt = (AssignStmt) s;
Value leftOp = assignStmt.getLeftOp();
AssignStmt newAssignStmt = Jimple.v().newAssignStmt(leftOp, retLocal);
newUnits.add(newAssignStmt);
}
GotoStmt gotoStmt = Jimple.v().newGotoStmt(endLabel);
newUnits.add(gotoStmt);
newUnits.add(jumpTarget);
}
Unit end = newUnits.getLast();
units.insertAfter(newUnits, s);
units.remove(s);
units.insertAfter(s, end);
units.insertAfter(endLabel, s);
}
}
callSiteId++;
}
use of soot.Body in project soot by Sable.
the class ReflectiveCallsInliner method internalTransform.
@Override
protected void internalTransform(String phaseName, @SuppressWarnings("rawtypes") Map options) {
if (!initialized) {
CGOptions cgOptions = new CGOptions(PhaseOptions.v().getPhaseOptions("cg"));
String logFilePath = cgOptions.reflection_log();
RTI = new ReflectionTraceInfo(logFilePath);
Scene.v().getSootClass(SootSig.class.getName()).setApplicationClass();
Scene.v().getSootClass(UnexpectedReflectiveCall.class.getName()).setApplicationClass();
Scene.v().getSootClass(IUnexpectedReflectiveCallHandler.class.getName()).setApplicationClass();
Scene.v().getSootClass(DefaultHandler.class.getName()).setApplicationClass();
Scene.v().getSootClass(OpaquePredicate.class.getName()).setApplicationClass();
Scene.v().getSootClass(ReflectiveCalls.class.getName()).setApplicationClass();
reflectiveCallsClass = new SootClass("soot.rtlib.tamiflex.ReflectiveCallsWrapper", Modifier.PUBLIC);
Scene.v().addClass(reflectiveCallsClass);
reflectiveCallsClass.setApplicationClass();
UNINTERPRETED_METHOD = Scene.v().makeMethodRef(Scene.v().getSootClass("soot.rtlib.tamiflex.OpaquePredicate"), "getFalse", Collections.<Type>emptyList(), BooleanType.v(), true);
if (useCaching)
addCaching();
initializeReflectiveCallsTable();
callSiteId = 0;
callNum = 0;
initialized = true;
}
for (SootMethod m : RTI.methodsContainingReflectiveCalls()) {
m.retrieveActiveBody();
Body b = m.getActiveBody();
{
Set<String> classForNameClassNames = RTI.classForNameClassNames(m);
if (!classForNameClassNames.isEmpty()) {
inlineRelectiveCalls(m, classForNameClassNames, ReflectionTraceInfo.Kind.ClassForName);
if (Options.v().validate())
b.validate();
}
}
{
Set<String> classNewInstanceClassNames = RTI.classNewInstanceClassNames(m);
if (!classNewInstanceClassNames.isEmpty()) {
inlineRelectiveCalls(m, classNewInstanceClassNames, ReflectionTraceInfo.Kind.ClassNewInstance);
if (Options.v().validate())
b.validate();
}
}
{
Set<String> constructorNewInstanceSignatures = RTI.constructorNewInstanceSignatures(m);
if (!constructorNewInstanceSignatures.isEmpty()) {
inlineRelectiveCalls(m, constructorNewInstanceSignatures, ReflectionTraceInfo.Kind.ConstructorNewInstance);
if (Options.v().validate())
b.validate();
}
}
{
Set<String> methodInvokeSignatures = RTI.methodInvokeSignatures(m);
if (!methodInvokeSignatures.isEmpty()) {
inlineRelectiveCalls(m, methodInvokeSignatures, ReflectionTraceInfo.Kind.MethodInvoke);
if (Options.v().validate())
b.validate();
}
}
{
Set<String> fieldSetSignatures = RTI.fieldSetSignatures(m);
if (!fieldSetSignatures.isEmpty()) {
inlineRelectiveCalls(m, fieldSetSignatures, ReflectionTraceInfo.Kind.FieldSet);
if (Options.v().validate())
b.validate();
}
}
{
Set<String> fieldGetSignatures = RTI.fieldGetSignatures(m);
if (!fieldGetSignatures.isEmpty()) {
inlineRelectiveCalls(m, fieldGetSignatures, ReflectionTraceInfo.Kind.FieldGet);
if (Options.v().validate())
b.validate();
}
}
// clean up after us
cleanup(b);
}
}
Aggregations