use of soot.jimple.InstanceInvokeExpr in project soot by Sable.
the class TypeAssigner method replaceNullType.
/**
* Replace statements using locals with null_type type and that would
* throw a NullPointerException at runtime by a set of instructions
* throwing a NullPointerException.
*
* This is done to remove locals with null_type type.
*
* @param b
*/
private void replaceNullType(Body b) {
List<Local> localsToRemove = new ArrayList<Local>();
boolean hasNullType = false;
// check if any local has null_type
for (Local l : b.getLocals()) {
if (l.getType() instanceof NullType) {
localsToRemove.add(l);
hasNullType = true;
}
}
// No local with null_type
if (!hasNullType)
return;
// force to propagate null constants
Map<String, String> opts = PhaseOptions.v().getPhaseOptions("jop.cpf");
if (!opts.containsKey("enabled") || !opts.get("enabled").equals("true")) {
logger.warn("Cannot run TypeAssigner.replaceNullType(Body). Try to enable jop.cfg.");
return;
}
ConstantPropagatorAndFolder.v().transform(b);
List<Unit> unitToReplaceByException = new ArrayList<Unit>();
for (Unit u : b.getUnits()) {
for (ValueBox vb : u.getUseBoxes()) {
if (vb.getValue() instanceof Local && ((Local) vb.getValue()).getType() instanceof NullType) {
Local l = (Local) vb.getValue();
Stmt s = (Stmt) u;
boolean replace = false;
if (s.containsArrayRef()) {
ArrayRef r = s.getArrayRef();
if (r.getBase() == l) {
replace = true;
}
} else if (s.containsFieldRef()) {
FieldRef r = s.getFieldRef();
if (r instanceof InstanceFieldRef) {
InstanceFieldRef ir = (InstanceFieldRef) r;
if (ir.getBase() == l) {
replace = true;
}
}
} else if (s.containsInvokeExpr()) {
InvokeExpr ie = s.getInvokeExpr();
if (ie instanceof InstanceInvokeExpr) {
InstanceInvokeExpr iie = (InstanceInvokeExpr) ie;
if (iie.getBase() == l) {
replace = true;
}
}
}
if (replace) {
unitToReplaceByException.add(u);
}
}
}
}
for (Unit u : unitToReplaceByException) {
soot.dexpler.Util.addExceptionAfterUnit(b, "java.lang.NullPointerException", u, "This statement would have triggered an Exception: " + u);
b.getUnits().remove(u);
}
// should be done on a separate phase
DeadAssignmentEliminator.v().transform(b);
UnusedLocalEliminator.v().transform(b);
}
use of soot.jimple.InstanceInvokeExpr in project soot by Sable.
the class MultiRunStatementsFinder method findMultiCalledMethodsIntra.
private void findMultiCalledMethodsIntra(Set<SootMethod> multiCalledMethods, CallGraph callGraph) {
Iterator<Unit> it = multiRunStatements.iterator();
while (it.hasNext()) {
Stmt stmt = (Stmt) it.next();
if (stmt.containsInvokeExpr()) {
InvokeExpr invokeExpr = stmt.getInvokeExpr();
List<SootMethod> targetList = new ArrayList<SootMethod>();
SootMethod method = invokeExpr.getMethod();
if (invokeExpr instanceof StaticInvokeExpr) {
targetList.add(method);
} else if (invokeExpr instanceof InstanceInvokeExpr) {
if (method.isConcrete() && !method.getDeclaringClass().isLibraryClass()) {
TargetMethodsFinder tmd = new TargetMethodsFinder();
targetList = tmd.find(stmt, callGraph, true, true);
}
}
if (targetList != null) {
Iterator<SootMethod> iterator = targetList.iterator();
while (iterator.hasNext()) {
SootMethod obj = iterator.next();
if (!obj.isNative()) {
multiCalledMethods.add(obj);
}
}
}
}
}
}
use of soot.jimple.InstanceInvokeExpr in project soot by Sable.
the class DavaBody method javafy_invoke_expr.
private void javafy_invoke_expr(ValueBox vb) {
InvokeExpr ie = (InvokeExpr) vb.getValue();
String className = ie.getMethodRef().declaringClass().toString();
String packageName = ie.getMethodRef().declaringClass().getJavaPackageName();
String classPackageName = packageName;
if (className.lastIndexOf('.') > 0) {
// 0 doesnt make sense
classPackageName = className.substring(0, className.lastIndexOf('.'));
}
if (!packageName.equals(classPackageName))
throw new DecompilationException("Unable to retrieve package name for identifier. Please report to developer.");
addToImportList(className);
for (int i = 0; i < ie.getArgCount(); i++) {
Value arg = ie.getArg(i);
if (arg instanceof IntConstant)
ie.getArgBox(i).setValue(DIntConstant.v(((IntConstant) arg).value, ie.getMethodRef().parameterType(i)));
else
javafy(ie.getArgBox(i));
}
if (ie instanceof InstanceInvokeExpr) {
javafy(((InstanceInvokeExpr) ie).getBaseBox());
if (ie instanceof VirtualInvokeExpr) {
VirtualInvokeExpr vie = (VirtualInvokeExpr) ie;
vb.setValue(new DVirtualInvokeExpr(vie.getBase(), vie.getMethodRef(), vie.getArgs(), thisLocals));
} else if (ie instanceof SpecialInvokeExpr) {
SpecialInvokeExpr sie = (SpecialInvokeExpr) ie;
vb.setValue(new DSpecialInvokeExpr(sie.getBase(), sie.getMethodRef(), sie.getArgs()));
} else if (ie instanceof InterfaceInvokeExpr) {
InterfaceInvokeExpr iie = (InterfaceInvokeExpr) ie;
vb.setValue(new DInterfaceInvokeExpr(iie.getBase(), iie.getMethodRef(), iie.getArgs()));
} else
throw new RuntimeException("InstanceInvokeExpr " + ie + " not javafied correctly");
} else if (ie instanceof StaticInvokeExpr) {
StaticInvokeExpr sie = (StaticInvokeExpr) ie;
if (sie instanceof NewInvokeExpr) {
NewInvokeExpr nie = (NewInvokeExpr) sie;
RefType rt = nie.getBaseType();
className = rt.getSootClass().toString();
packageName = rt.getSootClass().getJavaPackageName();
classPackageName = packageName;
if (className.lastIndexOf('.') > 0) {
// 0 doesnt make sense
classPackageName = className.substring(0, className.lastIndexOf('.'));
}
if (!packageName.equals(classPackageName))
throw new DecompilationException("Unable to retrieve package name for identifier. Please report to developer.");
addToImportList(className);
vb.setValue(new DNewInvokeExpr((RefType) nie.getType(), nie.getMethodRef(), nie.getArgs()));
} else {
SootMethodRef methodRef = sie.getMethodRef();
className = methodRef.declaringClass().toString();
packageName = methodRef.declaringClass().getJavaPackageName();
classPackageName = packageName;
if (className.lastIndexOf('.') > 0) {
// 0 doesnt make sense
classPackageName = className.substring(0, className.lastIndexOf('.'));
}
if (!packageName.equals(classPackageName))
throw new DecompilationException("Unable to retrieve package name for identifier. Please report to developer.");
addToImportList(className);
// addPackage(methodRef.declaringClass().getJavaPackageName());
vb.setValue(new DStaticInvokeExpr(methodRef, sie.getArgs()));
}
} else
throw new RuntimeException("InvokeExpr " + ie + " not javafied correctly");
}
use of soot.jimple.InstanceInvokeExpr in project soot by Sable.
the class DavaBody method copy_Body.
/*
* Copy and patch a GrimpBody so that it can be used to output Java.
*/
private void copy_Body(Body body) {
if (!(body instanceof GrimpBody))
throw new RuntimeException("You can only create a DavaBody from a GrimpBody!");
GrimpBody grimpBody = (GrimpBody) body;
/*
* Import body contents from Grimp.
*/
{
HashMap<Switchable, Switchable> bindings = new HashMap<Switchable, Switchable>();
HashMap<Unit, Unit> reverse_binding = new HashMap<Unit, Unit>();
// Clone units in body's statement list
for (Unit original : grimpBody.getUnits()) {
Unit copy = (Unit) original.clone();
// Add cloned unit to our unitChain.
getUnits().addLast(copy);
// Build old <-> new map to be able to patch up references to other units
// within the cloned units. (these are still refering to the original
// unit objects).
bindings.put(original, copy);
reverse_binding.put(copy, original);
}
// patch up the switch statments
for (Unit u : getUnits()) {
Stmt s = (Stmt) u;
if (s instanceof TableSwitchStmt) {
TableSwitchStmt ts = (TableSwitchStmt) s;
TableSwitchStmt original_switch = (TableSwitchStmt) reverse_binding.get(u);
ts.setDefaultTarget((Unit) bindings.get(original_switch.getDefaultTarget()));
LinkedList<Unit> new_target_list = new LinkedList<Unit>();
int target_count = ts.getHighIndex() - ts.getLowIndex() + 1;
for (int i = 0; i < target_count; i++) new_target_list.add((Unit) bindings.get(original_switch.getTarget(i)));
ts.setTargets(new_target_list);
}
if (s instanceof LookupSwitchStmt) {
LookupSwitchStmt ls = (LookupSwitchStmt) s;
LookupSwitchStmt original_switch = (LookupSwitchStmt) reverse_binding.get(u);
ls.setDefaultTarget((Unit) bindings.get(original_switch.getDefaultTarget()));
Unit[] new_target_list = new Unit[original_switch.getTargetCount()];
for (int i = 0; i < original_switch.getTargetCount(); i++) new_target_list[i] = (Unit) (bindings.get(original_switch.getTarget(i)));
ls.setTargets(new_target_list);
ls.setLookupValues(original_switch.getLookupValues());
}
}
// Clone locals.
for (Local original : grimpBody.getLocals()) {
Local copy = Dava.v().newLocal(original.getName(), original.getType());
getLocals().add(copy);
// Build old <-> new mapping.
bindings.put(original, copy);
}
// Patch up references within units using our (old <-> new) map.
for (UnitBox box : getAllUnitBoxes()) {
Unit newObject, oldObject = box.getUnit();
// it's clone.
if ((newObject = (Unit) bindings.get(oldObject)) != null)
box.setUnit(newObject);
}
// backpatch all local variables.
for (ValueBox vb : getUseAndDefBoxes()) {
if (vb.getValue() instanceof Local)
vb.setValue((Value) bindings.get(vb.getValue()));
}
// clone the traps
for (Trap originalTrap : grimpBody.getTraps()) {
Trap cloneTrap = (Trap) originalTrap.clone();
Unit handlerUnit = (Unit) bindings.get(originalTrap.getHandlerUnit());
cloneTrap.setHandlerUnit(handlerUnit);
cloneTrap.setBeginUnit((Unit) bindings.get(originalTrap.getBeginUnit()));
cloneTrap.setEndUnit((Unit) bindings.get(originalTrap.getEndUnit()));
getTraps().add(cloneTrap);
}
}
/*
* Add one level of indirection to "if", "switch", and exceptional control flow.
* This allows for easy handling of breaks, continues and exceptional loops.
*/
{
PatchingChain<Unit> units = getUnits();
Iterator<Unit> it = units.snapshotIterator();
while (it.hasNext()) {
Unit u = it.next();
Stmt s = (Stmt) u;
if (s instanceof IfStmt) {
IfStmt ifs = (IfStmt) s;
JGotoStmt jgs = new JGotoStmt((Unit) units.getSuccOf(u));
units.insertAfter(jgs, u);
JGotoStmt jumper = new JGotoStmt((Unit) ifs.getTarget());
units.insertAfter(jumper, jgs);
ifs.setTarget((Unit) jumper);
} else if (s instanceof TableSwitchStmt) {
TableSwitchStmt tss = (TableSwitchStmt) s;
int targetCount = tss.getHighIndex() - tss.getLowIndex() + 1;
for (int i = 0; i < targetCount; i++) {
JGotoStmt jgs = new JGotoStmt((Unit) tss.getTarget(i));
units.insertAfter(jgs, tss);
tss.setTarget(i, (Unit) jgs);
}
JGotoStmt jgs = new JGotoStmt((Unit) tss.getDefaultTarget());
units.insertAfter(jgs, tss);
tss.setDefaultTarget((Unit) jgs);
} else if (s instanceof LookupSwitchStmt) {
LookupSwitchStmt lss = (LookupSwitchStmt) s;
for (int i = 0; i < lss.getTargetCount(); i++) {
JGotoStmt jgs = new JGotoStmt((Unit) lss.getTarget(i));
units.insertAfter(jgs, lss);
lss.setTarget(i, (Unit) jgs);
}
JGotoStmt jgs = new JGotoStmt((Unit) lss.getDefaultTarget());
units.insertAfter(jgs, lss);
lss.setDefaultTarget((Unit) jgs);
}
}
for (Trap t : getTraps()) {
JGotoStmt jgs = new JGotoStmt((Unit) t.getHandlerUnit());
units.addLast(jgs);
t.setHandlerUnit((Unit) jgs);
}
}
/*
* Fix up the grimp representations of statements so they can be compiled as java.
*/
{
for (Local l : getLocals()) {
Type t = l.getType();
if (t instanceof RefType) {
RefType rt = (RefType) t;
String className = rt.getSootClass().toString();
String packageName = rt.getSootClass().getJavaPackageName();
String classPackageName = packageName;
if (className.lastIndexOf('.') > 0) {
// 0 doesnt make sense
classPackageName = className.substring(0, className.lastIndexOf('.'));
}
if (!packageName.equals(classPackageName))
throw new DecompilationException("Unable to retrieve package name for identifier. Please report to developer.");
addToImportList(className);
// addPackage(rt.getSootClass().getJavaPackageName());
}
}
for (Unit u : getUnits()) {
Stmt s = (Stmt) u;
if (s instanceof IfStmt)
javafy(((IfStmt) s).getConditionBox());
else if (s instanceof ThrowStmt)
javafy(((ThrowStmt) s).getOpBox());
else if (s instanceof TableSwitchStmt)
javafy(((TableSwitchStmt) s).getKeyBox());
else if (s instanceof LookupSwitchStmt)
javafy(((LookupSwitchStmt) s).getKeyBox());
else if (s instanceof MonitorStmt)
javafy(((MonitorStmt) s).getOpBox());
else if (s instanceof DefinitionStmt) {
DefinitionStmt ds = (DefinitionStmt) s;
javafy(ds.getRightOpBox());
javafy(ds.getLeftOpBox());
if (ds.getRightOp() instanceof IntConstant)
ds.getRightOpBox().setValue(DIntConstant.v(((IntConstant) ds.getRightOp()).value, ds.getLeftOp().getType()));
} else if (s instanceof ReturnStmt) {
ReturnStmt rs = (ReturnStmt) s;
if (rs.getOp() instanceof IntConstant)
rs.getOpBox().setValue(DIntConstant.v(((IntConstant) rs.getOp()).value, body.getMethod().getReturnType()));
else
javafy(rs.getOpBox());
} else if (s instanceof InvokeStmt)
javafy(((InvokeStmt) s).getInvokeExprBox());
}
}
/*
* Convert references to "this" and parameters.
*/
{
for (Unit u : getUnits()) {
Stmt s = (Stmt) u;
if (s instanceof IdentityStmt) {
IdentityStmt ids = (IdentityStmt) s;
Value ids_rightOp = ids.getRightOp();
Value ids_leftOp = ids.getLeftOp();
if ((ids_leftOp instanceof Local) && (ids_rightOp instanceof ThisRef)) {
Local thisLocal = (Local) ids_leftOp;
thisLocals.add(thisLocal);
thisLocal.setName("this");
}
}
if (s instanceof DefinitionStmt) {
DefinitionStmt ds = (DefinitionStmt) s;
Value rightOp = ds.getRightOp();
if (rightOp instanceof ParameterRef)
pMap.put(((ParameterRef) rightOp).getIndex(), ds.getLeftOp());
if (rightOp instanceof CaughtExceptionRef)
caughtrefs.add((CaughtExceptionRef) rightOp);
}
}
}
/*
* Fix up the calls to other constructors. Note, this is seriously underbuilt.
*/
{
for (Unit u : getUnits()) {
Stmt s = (Stmt) u;
if (s instanceof InvokeStmt) {
InvokeStmt ivs = (InvokeStmt) s;
Value ie = ivs.getInvokeExpr();
if (ie instanceof InstanceInvokeExpr) {
InstanceInvokeExpr iie = (InstanceInvokeExpr) ie;
Value base = iie.getBase();
if ((base instanceof Local) && (((Local) base).getName().equals("this"))) {
SootMethodRef m = iie.getMethodRef();
String name = m.name();
if ((name.equals(SootMethod.constructorName)) || (name.equals(SootMethod.staticInitializerName))) {
if (constructorUnit != null)
throw new RuntimeException("More than one candidate for constructor found.");
constructorExpr = iie;
constructorUnit = (Unit) s;
}
}
}
}
}
}
}
use of soot.jimple.InstanceInvokeExpr in project soot by Sable.
the class MethodInvocationInstruction method finalize.
@Override
public void finalize(DexBody body, DexlibAbstractInstruction successor) {
// defer final jimplification to move result
if (successor instanceof MoveResultInstruction) {
// MoveResultInstruction i = (MoveResultInstruction)successor;
// i.setExpr(invocation);
// if (lineNumber != -1)
// i.setTag(new SourceLineNumberTag(lineNumber));
assign = Jimple.v().newAssignStmt(body.getStoreResultLocal(), invocation);
setUnit(assign);
addTags(assign);
body.add(assign);
unit = assign;
// this is a invoke statement (the MoveResult had to be the direct successor for an expression)
} else {
InvokeStmt invoke = Jimple.v().newInvokeStmt(invocation);
setUnit(invoke);
addTags(invoke);
body.add(invoke);
unit = invoke;
}
if (IDalvikTyper.ENABLE_DVKTYPER) {
if (invocation instanceof InstanceInvokeExpr) {
Type t = invocation.getMethodRef().declaringClass().getType();
DalvikTyper.v().setType(((InstanceInvokeExpr) invocation).getBaseBox(), t, true);
// DalvikTyper.v().setObjectType(assign.getLeftOpBox());
}
int i = 0;
for (Type pt : invocation.getMethodRef().parameterTypes()) {
DalvikTyper.v().setType(invocation.getArgBox(i++), pt, true);
}
if (assign != null) {
DalvikTyper.v().setType(assign.getLeftOpBox(), invocation.getType(), false);
}
}
}
Aggregations