use of soot.jimple.InterfaceInvokeExpr 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.jimple.InterfaceInvokeExpr in project soot by Sable.
the class ConstraintCollector method handleInvokeExpr.
private void handleInvokeExpr(InvokeExpr ie) {
if (!uses)
return;
// Handle the parameters
SootMethodRef method = ie.getMethodRef();
for (int i = 0; i < ie.getArgCount(); i++) {
if (ie.getArg(i) instanceof Local) {
Local local = (Local) ie.getArg(i);
TypeVariable localType = resolver.typeVariable(local);
localType.addParent(resolver.typeVariable(method.parameterType(i)));
}
}
if (ie instanceof InterfaceInvokeExpr) {
InterfaceInvokeExpr invoke = (InterfaceInvokeExpr) ie;
Value base = invoke.getBase();
if (base instanceof Local) {
Local local = (Local) base;
TypeVariable localType = resolver.typeVariable(local);
localType.addParent(resolver.typeVariable(method.declaringClass()));
}
} else if (ie instanceof SpecialInvokeExpr) {
SpecialInvokeExpr invoke = (SpecialInvokeExpr) ie;
Value base = invoke.getBase();
if (base instanceof Local) {
Local local = (Local) base;
TypeVariable localType = resolver.typeVariable(local);
localType.addParent(resolver.typeVariable(method.declaringClass()));
}
} else if (ie instanceof VirtualInvokeExpr) {
VirtualInvokeExpr invoke = (VirtualInvokeExpr) ie;
Value base = invoke.getBase();
if (base instanceof Local) {
Local local = (Local) base;
TypeVariable localType = resolver.typeVariable(local);
localType.addParent(resolver.typeVariable(method.declaringClass()));
}
} else if (ie instanceof StaticInvokeExpr) {
// no base to handle
} else if (ie instanceof DynamicInvokeExpr) {
DynamicInvokeExpr invoke = (DynamicInvokeExpr) ie;
SootMethodRef bootstrapMethod = invoke.getBootstrapMethodRef();
for (int i = 0; i < invoke.getBootstrapArgCount(); i++) {
if (invoke.getArg(i) instanceof Local) {
Local local = (Local) invoke.getBootstrapArg(i);
TypeVariable localType = resolver.typeVariable(local);
localType.addParent(resolver.typeVariable(bootstrapMethod.parameterType(i)));
}
}
} else {
throw new RuntimeException("Unhandled invoke expression type: " + ie.getClass());
}
}
use of soot.jimple.InterfaceInvokeExpr in project soot by Sable.
the class LibraryMethodWrappersBuilder method buildNewMethod.
private SootMethodRef buildNewMethod(SootClass fromC, SootMethod sm, InvokeExpr origIE) {
final List<SootClass> availableClasses = getVisibleApplicationClasses(sm);
final int classCount = availableClasses.size();
if (classCount == 0) {
throw new RuntimeException("There appears to be no public non-interface Application classes!");
}
SootClass randomClass;
String methodNewName;
do {
int index = Rand.getInt(classCount);
if ((randomClass = availableClasses.get(index)) == fromC && classCount > 1) {
index = Rand.getInt(classCount);
randomClass = availableClasses.get(index);
}
final List<SootMethod> methods = randomClass.getMethods();
index = Rand.getInt(methods.size());
final SootMethod randMethod = methods.get(index);
methodNewName = randMethod.getName();
} while (methodNewName.equals(SootMethod.constructorName) || methodNewName.equals(SootMethod.staticInitializerName));
final List<Type> smParamTypes = new ArrayList<>(sm.getParameterTypes());
if (!sm.isStatic()) {
smParamTypes.add(sm.getDeclaringClass().getType());
}
// add random class params until we don't match any other method
int extraParams = 0;
if (randomClass.declaresMethod(methodNewName, smParamTypes)) {
int rtmp = Rand.getInt(classCount + 7);
if (rtmp >= classCount) {
rtmp -= classCount;
smParamTypes.add(getPrimType(rtmp));
} else {
smParamTypes.add(availableClasses.get(rtmp).getType());
}
extraParams++;
}
final int mods = ((((sm.getModifiers() | Modifier.STATIC | Modifier.PUBLIC) & (Modifier.ABSTRACT ^ 0xFFFF)) & (Modifier.NATIVE ^ 0xFFFF)) & (Modifier.SYNCHRONIZED ^ 0xFFFF));
SootMethod newMethod = Scene.v().makeSootMethod(methodNewName, smParamTypes, sm.getReturnType(), mods);
randomClass.addMethod(newMethod);
JimpleBody body = Jimple.v().newBody(newMethod);
newMethod.setActiveBody(body);
Chain<Local> locals = body.getLocals();
PatchingChain<Unit> units = body.getUnits();
List<Local> args = BodyBuilder.buildParameterLocals(units, locals, smParamTypes);
while (extraParams-- > 0) {
args.remove(args.size() - 1);
}
InvokeExpr ie = null;
if (sm.isStatic()) {
ie = Jimple.v().newStaticInvokeExpr(sm.makeRef(), args);
} else {
Local libObj = args.remove(args.size() - 1);
if (origIE instanceof InterfaceInvokeExpr) {
ie = Jimple.v().newInterfaceInvokeExpr(libObj, sm.makeRef(), args);
} else if (origIE instanceof VirtualInvokeExpr) {
ie = Jimple.v().newVirtualInvokeExpr(libObj, sm.makeRef(), args);
}
}
if (sm.getReturnType() instanceof VoidType) {
units.add(Jimple.v().newInvokeStmt(ie));
units.add(Jimple.v().newReturnVoidStmt());
} else {
Local assign = Jimple.v().newLocal("returnValue", sm.getReturnType());
locals.add(assign);
units.add(Jimple.v().newAssignStmt(assign, ie));
units.add(Jimple.v().newReturnStmt(assign));
}
if (isVerbose()) {
logger.info("{} was replaced by {} which calls {}", sm.getName(), newMethod.getName(), ie);
}
if (units.size() < 2) {
logger.warn("THERE AREN'T MANY UNITS IN THIS METHOD {}", units);
}
builtByMe.add(newMethod);
return newMethod.makeRef();
}
Aggregations