use of soot.jimple.JimpleBody 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();
}
use of soot.jimple.JimpleBody in project soot by Sable.
the class Walker method outAFullMethodBody.
public void outAFullMethodBody(AFullMethodBody node) {
JimpleBody jBody = Jimple.v().newBody();
if (node.getCatchClause() != null) {
int size = node.getCatchClause().size();
for (int i = 0; i < size; i++) jBody.getTraps().addFirst((Trap) mProductions.removeLast());
}
if (node.getStatement() != null) {
int size = node.getStatement().size();
Unit lastStmt = null;
for (int i = 0; i < size; i++) {
Object o = mProductions.removeLast();
if (o instanceof Unit) {
jBody.getUnits().addFirst((Unit) o);
lastStmt = (Unit) o;
} else if (o instanceof String) {
if (lastStmt == null)
throw new RuntimeException("impossible");
mLabelToStmtMap.put(o, lastStmt);
} else
throw new RuntimeException("impossible");
}
}
if (node.getDeclaration() != null) {
int size = node.getDeclaration().size();
for (int i = 0; i < size; i++) {
List<Local> localList = (List<Local>) mProductions.removeLast();
jBody.getLocals().addAll(localList);
}
}
Iterator<String> it = mLabelToPatchList.keySet().iterator();
while (it.hasNext()) {
String label = it.next();
Unit target = mLabelToStmtMap.get(label);
Iterator patchIt = mLabelToPatchList.get(label).iterator();
while (patchIt.hasNext()) {
UnitBox box = (UnitBox) patchIt.next();
box.setUnit(target);
}
}
/*
* Iterator it = mLabelToStmtMap.keySet().iterator();
* while(it.hasNext()) { String label = (String) it.next(); Unit target
* = (Unit) mLabelToStmtMap.get(label);
*
* List l = (List) mLabelToPatchList.get(label); if(l != null) {
* Iterator patchIt = l.iterator(); while(patchIt.hasNext()) { UnitBox
* box = (UnitBox) patchIt.next(); box.setUnit(target); } } }
*/
mProductions.addLast(jBody);
}
use of soot.jimple.JimpleBody in project soot by Sable.
the class Walker method outAMethodMember.
public void outAMethodMember(AMethodMember node) {
int modifier = 0;
Type type;
String name;
List parameterList = null;
List<SootClass> throwsClause = null;
JimpleBody methodBody = null;
if (node.getMethodBody() instanceof AFullMethodBody)
methodBody = (JimpleBody) mProductions.removeLast();
if (node.getThrowsClause() != null)
throwsClause = (List<SootClass>) mProductions.removeLast();
if (node.getParameterList() != null) {
parameterList = (List) mProductions.removeLast();
} else {
parameterList = new ArrayList();
}
Object o = mProductions.removeLast();
name = (String) o;
type = (Type) mProductions.removeLast();
modifier = processModifiers(node.getModifier());
SootMethod method;
if (throwsClause != null)
method = Scene.v().makeSootMethod(name, parameterList, type, modifier, throwsClause);
else
method = Scene.v().makeSootMethod(name, parameterList, type, modifier);
mSootClass.addMethod(method);
if (method.isConcrete()) {
methodBody.setMethod(method);
method.setActiveBody(methodBody);
} else if (node.getMethodBody() instanceof AFullMethodBody)
throw new RuntimeException("Impossible: !concrete => ! instanceof");
}
Aggregations