Search in sources :

Example 1 with ASTStatementSequenceNode

use of soot.dava.internal.AST.ASTStatementSequenceNode in project soot by Sable.

the class MethodCallFinder method inInvokeStmt.

/*
	 * some ASTConstuct{ ASTConstruct{ Some bodies Some Bodies Statement
	 * SequenceNode New Stmt seq node with some stmts some stmts ---------->
	 * Body of method to inline the invoke stmt New Stmt seq node with other
	 * stmts some other stmts Some other bodies Some other bodies End
	 * ASTConstruct End ASTConstruct
	 */
/*
	 * Notice that since this class is only invoked for clinit methods this
	 * invoke statement is some invocation that occured within the clinit method
	 */
public void inInvokeStmt(InvokeStmt s) {
    InvokeExpr invokeExpr = s.getInvokeExpr();
    SootMethod maybeInline = invokeExpr.getMethod();
    // check whether we want to inline
    ASTMethodNode toInlineASTMethod = cleaner.inline(maybeInline);
    if (toInlineASTMethod == null) {
        // not to inline
        return;
    } else {
        // yes we want to inline
        // we know that the method to be inlined has no declarations.
        List<Object> subBodies = toInlineASTMethod.get_SubBodies();
        if (subBodies.size() != 1) {
            throw new RuntimeException("Found ASTMEthod node with more than one subBodies");
        }
        List body = (List) subBodies.get(0);
        ASTParentNodeFinder finder = new ASTParentNodeFinder();
        underAnalysis.apply(finder);
        List<ASTStatementSequenceNode> newChangedBodyPart = createChangedBodyPart(s, body, finder);
        boolean replaced = replaceSubBody(s, newChangedBodyPart, finder);
        if (replaced) {
            // so the invoke stmt has been replaced with the body of the
            // method invoked
            /*
				 * if the inlined method contained an assignment to a static
				 * field we want to replace that with a throw stmt
				 */
            StaticDefinitionFinder defFinder = new StaticDefinitionFinder(maybeInline);
            toInlineASTMethod.apply(defFinder);
            if (defFinder.anyFinalFieldDefined()) {
                // create throw stmt to be added to inlined method
                // create a SootMethodRef
                SootClass runtime = Scene.v().loadClassAndSupport("java.lang.RuntimeException");
                if (runtime.declaresMethod("void <init>(java.lang.String)")) {
                    SootMethod sootMethod = runtime.getMethod("void <init>(java.lang.String)");
                    SootMethodRef methodRef = sootMethod.makeRef();
                    RefType myRefType = RefType.v(runtime);
                    StringConstant tempString = StringConstant.v("This method used to have a definition of a final variable. " + "Dava inlined the definition into the static initializer");
                    List list = new ArrayList();
                    list.add(tempString);
                    GNewInvokeExpr newInvokeExpr = new GNewInvokeExpr(myRefType, methodRef, list);
                    GThrowStmt throwStmt = new GThrowStmt(newInvokeExpr);
                    AugmentedStmt augStmt = new AugmentedStmt(throwStmt);
                    List<AugmentedStmt> sequence = new ArrayList<AugmentedStmt>();
                    sequence.add(augStmt);
                    ASTStatementSequenceNode seqNode = new ASTStatementSequenceNode(sequence);
                    List<Object> subBody = new ArrayList<Object>();
                    subBody.add(seqNode);
                    toInlineASTMethod.replaceBody(subBody);
                }
            }
        }
    }
}
Also used : ASTParentNodeFinder(soot.dava.toolkits.base.AST.traversals.ASTParentNodeFinder) SootMethodRef(soot.SootMethodRef) ArrayList(java.util.ArrayList) ASTStatementSequenceNode(soot.dava.internal.AST.ASTStatementSequenceNode) SootClass(soot.SootClass) AugmentedStmt(soot.dava.internal.asg.AugmentedStmt) RefType(soot.RefType) GNewInvokeExpr(soot.grimp.internal.GNewInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) GNewInvokeExpr(soot.grimp.internal.GNewInvokeExpr) GThrowStmt(soot.grimp.internal.GThrowStmt) SootMethod(soot.SootMethod) ASTMethodNode(soot.dava.internal.AST.ASTMethodNode) ArrayList(java.util.ArrayList) List(java.util.List) StringConstant(soot.jimple.StringConstant)

Example 2 with ASTStatementSequenceNode

use of soot.dava.internal.AST.ASTStatementSequenceNode in project soot by Sable.

the class MethodCallFinder method createChangedBodyPart.

/*
	 * Given an invoke stmt this method finds the parent of this stmt which
	 * should always be a StatementSequenceNode Then the sequence is broken into
	 * three parts. The first part contains stmts till above the invoke stmt.
	 * The second part contains the body argument which is the body of the
	 * inlined method and the third part are the stmts below the invoke stmt
	 */
public List<ASTStatementSequenceNode> createChangedBodyPart(InvokeStmt s, List body, ASTParentNodeFinder finder) {
    // get parent node of invoke stmt
    Object parent = finder.getParentOf(s);
    if (parent == null) {
        throw new RuntimeException("MethodCall FInder: parent of invoke stmt not found");
    }
    ASTNode parentNode = (ASTNode) parent;
    if (!(parentNode instanceof ASTStatementSequenceNode)) {
        throw new RuntimeException("MethodCall FInder: parent node not a stmt seq node");
    }
    ASTStatementSequenceNode orignal = (ASTStatementSequenceNode) parentNode;
    // copying the stmts till above the inoke stmt into one stmt sequence
    // node
    List<AugmentedStmt> newInitialNode = new ArrayList<AugmentedStmt>();
    Iterator<AugmentedStmt> it = orignal.getStatements().iterator();
    while (it.hasNext()) {
        AugmentedStmt as = it.next();
        Stmt tempStmt = as.get_Stmt();
        if (tempStmt != s) {
            newInitialNode.add(as);
        } else {
            // stmt we break
            break;
        }
    }
    // copy remaining stmts into the AFTER stmt sequence node
    List<AugmentedStmt> newSecondNode = new ArrayList<AugmentedStmt>();
    while (it.hasNext()) {
        newSecondNode.add(it.next());
    }
    List<ASTStatementSequenceNode> toReturn = new ArrayList<ASTStatementSequenceNode>();
    if (newInitialNode.size() != 0)
        toReturn.add(new ASTStatementSequenceNode(newInitialNode));
    // add inline methods body
    toReturn.addAll(body);
    if (newSecondNode.size() != 0)
        toReturn.add(new ASTStatementSequenceNode(newSecondNode));
    return toReturn;
}
Also used : ASTNode(soot.dava.internal.AST.ASTNode) ArrayList(java.util.ArrayList) ASTStatementSequenceNode(soot.dava.internal.AST.ASTStatementSequenceNode) AugmentedStmt(soot.dava.internal.asg.AugmentedStmt) InvokeStmt(soot.jimple.InvokeStmt) AugmentedStmt(soot.dava.internal.asg.AugmentedStmt) Stmt(soot.jimple.Stmt) GThrowStmt(soot.grimp.internal.GThrowStmt)

Example 3 with ASTStatementSequenceNode

use of soot.dava.internal.AST.ASTStatementSequenceNode in project soot by Sable.

the class EliminateConditions method change.

public boolean change(Boolean returned, ASTNode temp) {
    if (bodyContainingNode != null && returned != null && temp != null) {
        int index = bodyContainingNode.indexOf(temp);
        if (DEBUG)
            System.out.println("in change");
        if (temp instanceof ASTIfNode) {
            bodyContainingNode.remove(temp);
            if (returned.booleanValue()) {
                // if statement and value was true put the body of if into
                // the code
                // if its a labeled stmt we need a labeled block instead
                // notice that its okkay to put a labeled block since other
                // transformations might remove it
                String label = ((ASTLabeledNode) temp).get_Label().toString();
                if (label != null) {
                    ASTLabeledBlockNode labeledNode = new ASTLabeledBlockNode(((ASTLabeledNode) temp).get_Label(), (List<Object>) temp.get_SubBodies().get(0));
                    bodyContainingNode.add(index, labeledNode);
                } else {
                    bodyContainingNode.addAll(index, (List) temp.get_SubBodies().get(0));
                }
            }
            if (DEBUG)
                System.out.println("Removed if" + temp);
            return true;
        } else if (temp instanceof ASTIfElseNode) {
            bodyContainingNode.remove(temp);
            if (returned.booleanValue()) {
                // true so the if branch's body has to be added
                // if its a labeled stmt we need a labeled block instead
                // notice that its okkay to put a labeled block since other
                // transformations might remove it
                String label = ((ASTLabeledNode) temp).get_Label().toString();
                if (label != null) {
                    ASTLabeledBlockNode labeledNode = new ASTLabeledBlockNode(((ASTLabeledNode) temp).get_Label(), (List<Object>) temp.get_SubBodies().get(0));
                    bodyContainingNode.add(index, labeledNode);
                } else {
                    bodyContainingNode.addAll(index, (List) temp.get_SubBodies().get(0));
                }
            } else {
                // if its a labeled stmt we need a labeled block instead
                // notice that its okkay to put a labeled block since other
                // transformations might remove it
                String label = ((ASTLabeledNode) temp).get_Label().toString();
                if (label != null) {
                    ASTLabeledBlockNode labeledNode = new ASTLabeledBlockNode(((ASTLabeledNode) temp).get_Label(), (List<Object>) temp.get_SubBodies().get(1));
                    bodyContainingNode.add(index, labeledNode);
                } else {
                    bodyContainingNode.addAll(index, (List) temp.get_SubBodies().get(1));
                }
            }
            return true;
        } else if (temp instanceof ASTWhileNode && returned.booleanValue() == false) {
            // notice we only remove if ASTWhileNode has false condition
            bodyContainingNode.remove(temp);
            return true;
        } else if (temp instanceof ASTDoWhileNode && returned.booleanValue() == false) {
            // System.out.println("in try dowhile false");
            // remove the loop copy the body out since it gets executed once
            bodyContainingNode.remove(temp);
            bodyContainingNode.addAll(index, (List) temp.get_SubBodies().get(0));
            return true;
        } else if (temp instanceof ASTForLoopNode && returned.booleanValue() == false) {
            bodyContainingNode.remove(temp);
            ASTStatementSequenceNode newNode = new ASTStatementSequenceNode(((ASTForLoopNode) temp).getInit());
            bodyContainingNode.add(index, newNode);
            return true;
        }
    }
    return false;
}
Also used : ASTIfNode(soot.dava.internal.AST.ASTIfNode) ASTDoWhileNode(soot.dava.internal.AST.ASTDoWhileNode) ASTWhileNode(soot.dava.internal.AST.ASTWhileNode) List(java.util.List) ASTIfElseNode(soot.dava.internal.AST.ASTIfElseNode) ASTLabeledNode(soot.dava.internal.AST.ASTLabeledNode) ASTForLoopNode(soot.dava.internal.AST.ASTForLoopNode) ASTStatementSequenceNode(soot.dava.internal.AST.ASTStatementSequenceNode) ASTLabeledBlockNode(soot.dava.internal.AST.ASTLabeledBlockNode)

Example 4 with ASTStatementSequenceNode

use of soot.dava.internal.AST.ASTStatementSequenceNode in project soot by Sable.

the class SuperFirstStmtHandler method addDefsToLiveVariables.

/*
	 * newASTPreInitMethod at time of invocation just contains body X find all
	 * defs for this body
	 */
private List<Local> addDefsToLiveVariables() {
    // get all defs within x
    AllDefinitionsFinder finder = new AllDefinitionsFinder();
    newASTPreInitMethod.apply(finder);
    List<DefinitionStmt> allDefs = finder.getAllDefs();
    List<Local> uniqueLocals = new ArrayList<Local>();
    List<DefinitionStmt> uniqueLocalDefs = new ArrayList<DefinitionStmt>();
    // remove any defs for fields, and any which are done multiple times
    Iterator<DefinitionStmt> it = allDefs.iterator();
    while (it.hasNext()) {
        DefinitionStmt s = it.next();
        Value left = s.getLeftOp();
        if (left instanceof Local) {
            if (uniqueLocals.contains(left)) {
                // a def for this local already encountered
                int index = uniqueLocals.indexOf(left);
                uniqueLocals.remove(index);
                uniqueLocalDefs.remove(index);
            } else {
                // no def for this local yet
                uniqueLocals.add((Local) left);
                uniqueLocalDefs.add(s);
            }
        }
    }
    // at this point unique locals contains all locals defined and
    // uniqueLocaldef list has a list of the corresponding definitions
    // Now remove those unique locals and localdefs whose stmtseq node does
    // not have the ASTMEthodNode as a parent
    // This is a conservative step!!
    ASTParentNodeFinder parentFinder = new ASTParentNodeFinder();
    newASTPreInitMethod.apply(parentFinder);
    List<DefinitionStmt> toRemoveDefs = new ArrayList<DefinitionStmt>();
    it = uniqueLocalDefs.iterator();
    while (it.hasNext()) {
        DefinitionStmt s = it.next();
        Object parent = parentFinder.getParentOf(s);
        if (parent == null || (!(parent instanceof ASTStatementSequenceNode))) {
            // shouldnt happen but if it does add this s to toRemove list
            toRemoveDefs.add(s);
        }
        // parent is an ASTStatementsequence node. check that its parent is
        // the ASTMethodNode
        Object grandParent = parentFinder.getParentOf(parent);
        if (grandParent == null || (!(grandParent instanceof ASTMethodNode))) {
            // can happen if obfuscators are really smart. add s to toRemove
            // list
            toRemoveDefs.add(s);
        }
    }
    // remove any defs and corresponding locals if present in the
    // toRemoveDefs list
    it = toRemoveDefs.iterator();
    while (it.hasNext()) {
        DefinitionStmt s = it.next();
        int index = uniqueLocalDefs.indexOf(s);
        uniqueLocals.remove(index);
        uniqueLocalDefs.remove(index);
    }
    // the uniqueLocalDefs contains all those definitions to unique locals
    // which are not deeply nested in the X body
    // find all the uses of these definitions in the original method body
    toRemoveDefs = new ArrayList<DefinitionStmt>();
    ASTUsesAndDefs uDdU = new ASTUsesAndDefs(originalASTMethod);
    originalASTMethod.apply(uDdU);
    it = uniqueLocalDefs.iterator();
    while (it.hasNext()) {
        DefinitionStmt s = it.next();
        Object temp = uDdU.getDUChain(s);
        if (temp == null) {
            // couldnt find uses
            toRemoveDefs.add(s);
            continue;
        }
        ArrayList uses = (ArrayList) temp;
        // check if uses is non-empty
        if (uses.size() == 0) {
            toRemoveDefs.add(s);
        }
        // check for all the non zero uses
        Iterator useIt = uses.iterator();
        boolean onlyInConstructorUnit = true;
        while (useIt.hasNext()) {
            // a use is either a statement or a node(condition, synch,
            // switch , for etc)
            Object tempUse = useIt.next();
            if (tempUse != originalConstructorUnit) {
                onlyInConstructorUnit = false;
            }
        }
        if (onlyInConstructorUnit) {
            // mark it to be removed
            toRemoveDefs.add(s);
        }
    }
    // remove any defs and corresponding locals if present in the
    // toRemoveDefs list
    it = toRemoveDefs.iterator();
    while (it.hasNext()) {
        DefinitionStmt s = it.next();
        int index = uniqueLocalDefs.indexOf(s);
        uniqueLocals.remove(index);
        uniqueLocalDefs.remove(index);
    }
    // the remaining uniquelocals are the ones which are needed for body Y
    return uniqueLocals;
}
Also used : ASTParentNodeFinder(soot.dava.toolkits.base.AST.traversals.ASTParentNodeFinder) ASTUsesAndDefs(soot.dava.toolkits.base.AST.traversals.ASTUsesAndDefs) AllDefinitionsFinder(soot.dava.toolkits.base.AST.traversals.AllDefinitionsFinder) ArrayList(java.util.ArrayList) JimpleLocal(soot.jimple.internal.JimpleLocal) Local(soot.Local) ASTStatementSequenceNode(soot.dava.internal.AST.ASTStatementSequenceNode) Value(soot.Value) Iterator(java.util.Iterator) ASTMethodNode(soot.dava.internal.AST.ASTMethodNode) DefinitionStmt(soot.jimple.DefinitionStmt)

Example 5 with ASTStatementSequenceNode

use of soot.dava.internal.AST.ASTStatementSequenceNode in project soot by Sable.

the class SuperFirstStmtHandler method finalizePreInitMethod.

// method should return false if the PreInit body(ASTBody that is) is empty
// meaning there is no need to create it all
private boolean finalizePreInitMethod() {
    // set davaBody...totally redundant but have to do as this is checked by
    // toString of ASTMethodNode
    newASTPreInitMethod.setDavaBody(newPreInitDavaBody);
    // newPreInitDavaBody is the active body
    newPreInitDavaBody.getUnits().clear();
    newPreInitDavaBody.getUnits().addLast(newASTPreInitMethod);
    // check whether there is something in side the ASTBody
    // if its empty (maybe there were only declarations and that got removed
    // then no point in creating the preInit method
    List<Object> subBodies = newASTPreInitMethod.get_SubBodies();
    if (subBodies.size() != 1)
        return false;
    List body = (List) subBodies.get(0);
    // body is NOT allowed to contain one declaration node with whatever in
    // it
    // after that it is NOT allowed all ASTStatement nodes with empty bodies
    Iterator it = body.iterator();
    // indicating that method is empty
    boolean empty = true;
    while (it.hasNext()) {
        ASTNode tempNode = (ASTNode) it.next();
        if (!(tempNode instanceof ASTStatementSequenceNode)) {
            // found some node other than stmtseq...body not empty return
            // true
            empty = false;
            break;
        }
        List<AugmentedStmt> stmts = ((ASTStatementSequenceNode) tempNode).getStatements();
        // all declaration stmts are allowed
        for (AugmentedStmt as : stmts) {
            Stmt s = as.get_Stmt();
            if (!(s instanceof DVariableDeclarationStmt)) {
                empty = false;
                break;
            }
        }
        if (!empty)
            break;
    }
    if (empty) {
        // should not be creating the method
        return false;
    }
    // about to return true enter all DavaSuperHandler stmts to make it part
    // of the preinit method
    createDavaStoreStmts();
    return true;
}
Also used : DVariableDeclarationStmt(soot.dava.internal.javaRep.DVariableDeclarationStmt) Iterator(java.util.Iterator) ASTNode(soot.dava.internal.AST.ASTNode) List(java.util.List) ArrayList(java.util.ArrayList) ASTStatementSequenceNode(soot.dava.internal.AST.ASTStatementSequenceNode) AugmentedStmt(soot.dava.internal.asg.AugmentedStmt) GReturnStmt(soot.grimp.internal.GReturnStmt) AugmentedStmt(soot.dava.internal.asg.AugmentedStmt) DVariableDeclarationStmt(soot.dava.internal.javaRep.DVariableDeclarationStmt) GInvokeStmt(soot.grimp.internal.GInvokeStmt) Stmt(soot.jimple.Stmt) GAssignStmt(soot.grimp.internal.GAssignStmt) DefinitionStmt(soot.jimple.DefinitionStmt)

Aggregations

ASTStatementSequenceNode (soot.dava.internal.AST.ASTStatementSequenceNode)12 ArrayList (java.util.ArrayList)9 List (java.util.List)8 AugmentedStmt (soot.dava.internal.asg.AugmentedStmt)8 ASTNode (soot.dava.internal.AST.ASTNode)7 ASTMethodNode (soot.dava.internal.AST.ASTMethodNode)5 DVariableDeclarationStmt (soot.dava.internal.javaRep.DVariableDeclarationStmt)5 GAssignStmt (soot.grimp.internal.GAssignStmt)5 GInvokeStmt (soot.grimp.internal.GInvokeStmt)5 GReturnStmt (soot.grimp.internal.GReturnStmt)5 DefinitionStmt (soot.jimple.DefinitionStmt)5 Stmt (soot.jimple.Stmt)5 Iterator (java.util.Iterator)4 Local (soot.Local)3 RefType (soot.RefType)3 SootClass (soot.SootClass)3 SootMethodRef (soot.SootMethodRef)3 Value (soot.Value)3 CorruptASTException (soot.dava.CorruptASTException)3 DecompilationException (soot.dava.DecompilationException)3