use of soot.jimple.FieldRef in project soot by Sable.
the class CPApplication method inASTSwitchNode.
public void inASTSwitchNode(ASTSwitchNode node) {
Object obj = cp.getBeforeSet(node);
if (obj == null)
return;
if (!(obj instanceof CPFlowSet))
return;
// before set is a non null CPFlowSet
CPFlowSet beforeSet = (CPFlowSet) obj;
Value key = node.get_Key();
if (key instanceof Local) {
Local useLocal = (Local) key;
// System.out.println("switch key is a local: "+useLocal);
Object value = beforeSet.contains(className, useLocal.toString());
if (value != null) {
// System.out.println("switch key Local "+useLocal+"is present in before set with value"+value);
// create constant value for the value and replace this local
// use with the constant value use
Value newValue = CPHelper.createConstant(value);
if (newValue != null) {
// System.out.println("Substituted the switch key local use with the constant value"+newValue);
node.set_Key(newValue);
} else {
// System.out.println("FAILED TO Substitute the local use with the constant value");
}
}
} else if (key instanceof FieldRef) {
FieldRef useField = (FieldRef) key;
// System.out.println("switch key is a FieldRef which is: "+useField);
SootField usedSootField = useField.getField();
Object value = beforeSet.contains(usedSootField.getDeclaringClass().getName(), usedSootField.getName().toString());
if (value != null) {
// System.out.println("FieldRef "+usedSootField+"is present in before set with value"+value);
// create constant value for the value and replace this local
// use with the constant value use
Value newValue = CPHelper.createConstant(value);
if (newValue != null) {
// System.out.println("Substituted the constant field ref use with the constant value"+newValue);
node.set_Key(newValue);
} else {
// System.out.println("FAILED TO Substitute the constant field ref use with the constant value");
}
}
}
}
use of soot.jimple.FieldRef in project soot by Sable.
the class CPApplication method changedCondition.
/*
* Given a unary/binary or aggregated condition this method is used to find
* all the useBoxes or locals or fieldref in the case of unary conditions
* and then the set is checked for appropriate substitutions
*/
public ASTCondition changedCondition(ASTCondition cond, CPFlowSet set) {
if (cond instanceof ASTAggregatedCondition) {
ASTCondition left = changedCondition(((ASTAggregatedCondition) cond).getLeftOp(), set);
ASTCondition right = changedCondition(((ASTAggregatedCondition) cond).getRightOp(), set);
((ASTAggregatedCondition) cond).setLeftOp(left);
((ASTAggregatedCondition) cond).setRightOp(right);
// System.out.println("New condition is: "+cond);
return cond;
} else if (cond instanceof ASTUnaryCondition) {
Value val = ((ASTUnaryCondition) cond).getValue();
if (val instanceof Local) {
Object value = set.contains(className, ((Local) val).toString());
if (value != null) {
// System.out.println("if Condition Local "+((Local)val)+"is present in before set with value"+value);
// create constant value for the value and replace this
// local use with the constant value use
Value newValue = CPHelper.createConstant(value);
if (newValue != null) {
// System.out.println("Substituted the local use with the constant value"+newValue);
((ASTUnaryCondition) cond).setValue(newValue);
} else {
// System.out.println("FAILED TO Substitute the local use with the constant value");
}
}
} else if (val instanceof FieldRef) {
FieldRef useField = (FieldRef) val;
SootField usedSootField = useField.getField();
Object value = set.contains(usedSootField.getDeclaringClass().getName(), usedSootField.getName().toString());
if (value != null) {
// System.out.println("if condition FieldRef "+usedSootField+"is present in before set with value"+value);
// create constant value for the value and replace this
// field use with the constant value use
Value newValue = CPHelper.createConstant(value);
if (newValue != null) {
// System.out.println("Substituted the constant field ref use with the constant value"+newValue);
((ASTUnaryCondition) cond).setValue(newValue);
} else {
// System.out.println("FAILED TO Substitute the constant field ref use with the constant value");
}
}
} else {
substituteUses(val.getUseBoxes(), set);
}
// System.out.println("New condition is: "+cond);
return cond;
} else if (cond instanceof ASTBinaryCondition) {
// get uses from binaryCondition
Value val = ((ASTBinaryCondition) cond).getConditionExpr();
substituteUses(val.getUseBoxes(), set);
// System.out.println("New condition is: "+cond);
return cond;
} else {
throw new RuntimeException("Method getUseList in ASTUsesAndDefs encountered unknown condition type");
}
}
use of soot.jimple.FieldRef in project soot by Sable.
the class DexIfTransformer method internalTransform.
@Override
protected void internalTransform(final Body body, String phaseName, Map<String, String> options) {
final DexDefUseAnalysis localDefs = new DexDefUseAnalysis(body);
Set<IfStmt> ifSet = getNullIfCandidates(body);
for (IfStmt ifs : ifSet) {
ConditionExpr ifCondition = (ConditionExpr) ifs.getCondition();
Local[] twoIfLocals = new Local[] { (Local) ifCondition.getOp1(), (Local) ifCondition.getOp2() };
usedAsObject = false;
for (Local loc : twoIfLocals) {
Set<Unit> defs = localDefs.collectDefinitionsWithAliases(loc);
// process normally
doBreak = false;
for (Unit u : defs) {
// put correct local in l
if (u instanceof DefinitionStmt) {
l = (Local) ((DefinitionStmt) u).getLeftOp();
} else {
throw new RuntimeException("ERROR: def can not be something else than Assign or Identity statement! (def: " + u + " class: " + u.getClass() + "");
}
// check defs
u.apply(new // Alex: should also end
AbstractStmtSwitch() {
// as soon as detected
// as not used as an
// object
@Override
public void caseAssignStmt(AssignStmt stmt) {
Value r = stmt.getRightOp();
if (r instanceof FieldRef) {
usedAsObject = isObject(((FieldRef) r).getFieldRef().type());
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof ArrayRef) {
ArrayRef ar = (ArrayRef) r;
if (ar.getType() instanceof UnknownType) {
// isObject
usedAsObject = stmt.hasTag("ObjectOpTag");
// (findArrayType
// (g,
// localDefs,
// localUses,
// stmt));
} else {
usedAsObject = isObject(ar.getType());
}
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof StringConstant || r instanceof NewExpr || r instanceof NewArrayExpr) {
usedAsObject = true;
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof CastExpr) {
usedAsObject = isObject(((CastExpr) r).getCastType());
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof InvokeExpr) {
usedAsObject = isObject(((InvokeExpr) r).getType());
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof LengthExpr) {
usedAsObject = false;
if (usedAsObject)
doBreak = true;
return;
}
}
@Override
public void caseIdentityStmt(IdentityStmt stmt) {
if (stmt.getLeftOp() == l) {
usedAsObject = isObject(stmt.getRightOp().getType());
if (usedAsObject)
doBreak = true;
return;
}
}
});
if (doBreak)
break;
// check uses
for (Unit use : localDefs.getUsesOf(l)) {
use.apply(new AbstractStmtSwitch() {
private boolean examineInvokeExpr(InvokeExpr e) {
List<Value> args = e.getArgs();
List<Type> argTypes = e.getMethodRef().parameterTypes();
assert args.size() == argTypes.size();
for (int i = 0; i < args.size(); i++) {
if (args.get(i) == l && isObject(argTypes.get(i))) {
return true;
}
}
// check for base
SootMethodRef sm = e.getMethodRef();
if (!sm.isStatic()) {
if (e instanceof AbstractInvokeExpr) {
AbstractInstanceInvokeExpr aiiexpr = (AbstractInstanceInvokeExpr) e;
Value b = aiiexpr.getBase();
if (b == l) {
return true;
}
}
}
return false;
}
@Override
public void caseInvokeStmt(InvokeStmt stmt) {
InvokeExpr e = stmt.getInvokeExpr();
usedAsObject = examineInvokeExpr(e);
if (usedAsObject)
doBreak = true;
return;
}
@Override
public void caseAssignStmt(AssignStmt stmt) {
Value left = stmt.getLeftOp();
Value r = stmt.getRightOp();
if (left instanceof ArrayRef) {
if (((ArrayRef) left).getIndex() == l) {
// doBreak = true;
return;
}
}
// used to assign
if (stmt.getRightOp() == l) {
Value l = stmt.getLeftOp();
if (l instanceof StaticFieldRef && isObject(((StaticFieldRef) l).getFieldRef().type())) {
usedAsObject = true;
if (usedAsObject)
doBreak = true;
return;
} else if (l instanceof InstanceFieldRef && isObject(((InstanceFieldRef) l).getFieldRef().type())) {
usedAsObject = true;
if (usedAsObject)
doBreak = true;
return;
} else if (l instanceof ArrayRef) {
Type aType = ((ArrayRef) l).getType();
if (aType instanceof UnknownType) {
// isObject(
usedAsObject = stmt.hasTag("ObjectOpTag");
// findArrayType(g,
// localDefs,
// localUses,
// stmt));
} else {
usedAsObject = isObject(aType);
}
if (usedAsObject)
doBreak = true;
return;
}
}
// assignment)
if (r instanceof FieldRef) {
// isObject(((FieldRef)
usedAsObject = true;
// r).getFieldRef().type());
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof ArrayRef) {
ArrayRef ar = (ArrayRef) r;
if (ar.getBase() == l) {
usedAsObject = true;
} else {
// used as index
usedAsObject = false;
}
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof StringConstant || r instanceof NewExpr) {
throw new RuntimeException("NOT POSSIBLE StringConstant or NewExpr at " + stmt);
} else if (r instanceof NewArrayExpr) {
usedAsObject = false;
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof CastExpr) {
usedAsObject = isObject(((CastExpr) r).getCastType());
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof InvokeExpr) {
usedAsObject = examineInvokeExpr((InvokeExpr) stmt.getRightOp());
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof LengthExpr) {
usedAsObject = true;
if (usedAsObject)
doBreak = true;
return;
} else if (r instanceof BinopExpr) {
usedAsObject = false;
if (usedAsObject)
doBreak = true;
return;
}
}
@Override
public void caseIdentityStmt(IdentityStmt stmt) {
if (stmt.getLeftOp() == l)
throw new RuntimeException("IMPOSSIBLE 0");
}
@Override
public void caseEnterMonitorStmt(EnterMonitorStmt stmt) {
usedAsObject = stmt.getOp() == l;
if (usedAsObject)
doBreak = true;
return;
}
@Override
public void caseExitMonitorStmt(ExitMonitorStmt stmt) {
usedAsObject = stmt.getOp() == l;
if (usedAsObject)
doBreak = true;
return;
}
@Override
public void caseReturnStmt(ReturnStmt stmt) {
usedAsObject = stmt.getOp() == l && isObject(body.getMethod().getReturnType());
if (usedAsObject)
doBreak = true;
return;
}
@Override
public void caseThrowStmt(ThrowStmt stmt) {
usedAsObject = stmt.getOp() == l;
if (usedAsObject)
doBreak = true;
return;
}
});
if (doBreak)
break;
}
// for uses
if (doBreak)
break;
}
if (// as soon as one def or use refers to an object
doBreak)
// be updated
break;
}
// change values
if (usedAsObject) {
Set<Unit> defsOp1 = localDefs.collectDefinitionsWithAliases(twoIfLocals[0]);
Set<Unit> defsOp2 = localDefs.collectDefinitionsWithAliases(twoIfLocals[1]);
defsOp1.addAll(defsOp2);
for (Unit u : defsOp1) {
Stmt s = (Stmt) u;
// If we have a[x] = 0 and a is an object, we may not conclude 0 -> null
if (!s.containsArrayRef() || (!defsOp1.contains(s.getArrayRef().getBase()) && !defsOp2.contains(s.getArrayRef().getBase())))
replaceWithNull(u);
Local l = (Local) ((DefinitionStmt) u).getLeftOp();
for (Unit uuse : localDefs.getUsesOf(l)) {
Stmt use = (Stmt) uuse;
// If we have a[x] = 0 and a is an object, we may not conclude 0 -> null
if (!use.containsArrayRef() || (twoIfLocals[0] != use.getArrayRef().getBase()) && twoIfLocals[1] != use.getArrayRef().getBase())
replaceWithNull(use);
}
}
}
// end if
}
// for if statements
}
use of soot.jimple.FieldRef in project soot by Sable.
the class DexRefsChecker method internalTransform.
@Override
protected void internalTransform(final Body body, String phaseName, @SuppressWarnings("rawtypes") Map options) {
for (Unit u : getRefCandidates(body)) {
Stmt s = (Stmt) u;
boolean hasField = false;
FieldRef fr = null;
SootField sf = null;
if (s.containsFieldRef()) {
fr = s.getFieldRef();
sf = fr.getField();
if (sf != null) {
hasField = true;
}
} else {
throw new RuntimeException("Unit '" + u + "' does not contain array ref nor field ref.");
}
if (!hasField) {
System.out.println("Warning: add missing field '" + fr + "' to class!");
SootClass sc = null;
String frStr = fr.toString();
if (frStr.contains(".<")) {
sc = Scene.v().getSootClass(frStr.split(".<")[1].split(" ")[0].split(":")[0]);
} else {
sc = Scene.v().getSootClass(frStr.split(":")[0].replaceAll("^<", ""));
}
String fname = fr.toString().split(">")[0].split(" ")[2];
int modifiers = soot.Modifier.PUBLIC;
Type ftype = fr.getType();
sc.addField(Scene.v().makeSootField(fname, ftype, modifiers));
} else {
// System.out.println("field "+ sf.getName() +" '"+ sf +"'
// phantom: "+ isPhantom +" declared: "+ isDeclared);
}
}
// for if statements
}
use of soot.jimple.FieldRef in project soot by Sable.
the class DexReturnValuePropagator method internalTransform.
@Override
protected void internalTransform(Body body, String phaseName, Map<String, String> options) {
ExceptionalUnitGraph graph = new ExceptionalUnitGraph(body, DalvikThrowAnalysis.v(), true);
LocalDefs localDefs = LocalDefs.Factory.newLocalDefs(graph);
LocalUses localUses = null;
LocalCreation localCreation = null;
// a copy statement, we take the original operand
for (Unit u : body.getUnits()) if (u instanceof ReturnStmt) {
ReturnStmt retStmt = (ReturnStmt) u;
if (retStmt.getOp() instanceof Local) {
List<Unit> defs = localDefs.getDefsOfAt((Local) retStmt.getOp(), retStmt);
if (defs.size() == 1 && defs.get(0) instanceof AssignStmt) {
AssignStmt assign = (AssignStmt) defs.get(0);
final Value rightOp = assign.getRightOp();
final Value leftOp = assign.getLeftOp();
// Copy over the left side if it is a local
if (rightOp instanceof Local) {
// to return a;
if (!isRedefined((Local) rightOp, u, assign, graph))
retStmt.setOp(rightOp);
} else if (rightOp instanceof Constant) {
retStmt.setOp(rightOp);
} else // we rename the local to help splitting
if (rightOp instanceof FieldRef) {
if (localUses == null)
localUses = LocalUses.Factory.newLocalUses(body, localDefs);
if (localUses.getUsesOf(assign).size() == 1) {
if (localCreation == null)
localCreation = new LocalCreation(body.getLocals(), "ret");
Local newLocal = localCreation.newLocal(leftOp.getType());
assign.setLeftOp(newLocal);
retStmt.setOp(newLocal);
}
}
}
}
}
}
Aggregations