Search in sources :

Example 26 with FieldRef

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");
            }
        }
    }
}
Also used : FieldRef(soot.jimple.FieldRef) Value(soot.Value) Local(soot.Local) SootField(soot.SootField) CPFlowSet(soot.dava.toolkits.base.AST.structuredAnalysis.CPFlowSet)

Example 27 with FieldRef

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");
    }
}
Also used : ASTBinaryCondition(soot.dava.internal.AST.ASTBinaryCondition) FieldRef(soot.jimple.FieldRef) Value(soot.Value) Local(soot.Local) SootField(soot.SootField) ASTAggregatedCondition(soot.dava.internal.AST.ASTAggregatedCondition) ASTUnaryCondition(soot.dava.internal.AST.ASTUnaryCondition) ASTCondition(soot.dava.internal.AST.ASTCondition)

Example 28 with FieldRef

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
}
Also used : ExitMonitorStmt(soot.jimple.ExitMonitorStmt) InvokeStmt(soot.jimple.InvokeStmt) AssignStmt(soot.jimple.AssignStmt) Unit(soot.Unit) InvokeStmt(soot.jimple.InvokeStmt) ThrowStmt(soot.jimple.ThrowStmt) IfStmt(soot.jimple.IfStmt) IdentityStmt(soot.jimple.IdentityStmt) EnterMonitorStmt(soot.jimple.EnterMonitorStmt) ReturnStmt(soot.jimple.ReturnStmt) ExitMonitorStmt(soot.jimple.ExitMonitorStmt) Stmt(soot.jimple.Stmt) AssignStmt(soot.jimple.AssignStmt) DefinitionStmt(soot.jimple.DefinitionStmt) ArrayRef(soot.jimple.ArrayRef) AbstractInvokeExpr(soot.jimple.internal.AbstractInvokeExpr) AbstractInstanceInvokeExpr(soot.jimple.internal.AbstractInstanceInvokeExpr) AbstractInvokeExpr(soot.jimple.internal.AbstractInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) AbstractInstanceInvokeExpr(soot.jimple.internal.AbstractInstanceInvokeExpr) CastExpr(soot.jimple.CastExpr) AbstractStmtSwitch(soot.jimple.AbstractStmtSwitch) InstanceFieldRef(soot.jimple.InstanceFieldRef) List(java.util.List) IdentityStmt(soot.jimple.IdentityStmt) EnterMonitorStmt(soot.jimple.EnterMonitorStmt) FieldRef(soot.jimple.FieldRef) InstanceFieldRef(soot.jimple.InstanceFieldRef) StaticFieldRef(soot.jimple.StaticFieldRef) SootMethodRef(soot.SootMethodRef) LengthExpr(soot.jimple.LengthExpr) Local(soot.Local) StaticFieldRef(soot.jimple.StaticFieldRef) UnknownType(soot.UnknownType) UnknownType(soot.UnknownType) Type(soot.Type) IfStmt(soot.jimple.IfStmt) NewArrayExpr(soot.jimple.NewArrayExpr) ConditionExpr(soot.jimple.ConditionExpr) Value(soot.Value) NewExpr(soot.jimple.NewExpr) StringConstant(soot.jimple.StringConstant) DefinitionStmt(soot.jimple.DefinitionStmt) ReturnStmt(soot.jimple.ReturnStmt) ThrowStmt(soot.jimple.ThrowStmt) BinopExpr(soot.jimple.BinopExpr)

Example 29 with FieldRef

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
}
Also used : Type(soot.Type) FieldRef(soot.jimple.FieldRef) SootField(soot.SootField) Unit(soot.Unit) SootClass(soot.SootClass) Stmt(soot.jimple.Stmt)

Example 30 with FieldRef

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);
                    }
                }
            }
        }
    }
}
Also used : ExceptionalUnitGraph(soot.toolkits.graph.ExceptionalUnitGraph) FieldRef(soot.jimple.FieldRef) LocalCreation(soot.jimple.toolkits.scalar.LocalCreation) AssignStmt(soot.jimple.AssignStmt) Constant(soot.jimple.Constant) Value(soot.Value) Local(soot.Local) ArrayList(java.util.ArrayList) List(java.util.List) LocalUses(soot.toolkits.scalar.LocalUses) Unit(soot.Unit) LocalDefs(soot.toolkits.scalar.LocalDefs) ReturnStmt(soot.jimple.ReturnStmt)

Aggregations

FieldRef (soot.jimple.FieldRef)31 Value (soot.Value)25 Local (soot.Local)21 Unit (soot.Unit)20 Stmt (soot.jimple.Stmt)17 ArrayRef (soot.jimple.ArrayRef)14 InvokeExpr (soot.jimple.InvokeExpr)14 AssignStmt (soot.jimple.AssignStmt)13 SootField (soot.SootField)12 Type (soot.Type)12 DefinitionStmt (soot.jimple.DefinitionStmt)12 InstanceFieldRef (soot.jimple.InstanceFieldRef)12 SootMethod (soot.SootMethod)10 ValueBox (soot.ValueBox)10 ArrayList (java.util.ArrayList)9 NewArrayExpr (soot.jimple.NewArrayExpr)9 CastExpr (soot.jimple.CastExpr)8 StaticFieldRef (soot.jimple.StaticFieldRef)8 HashSet (java.util.HashSet)7 Iterator (java.util.Iterator)7