Search in sources :

Example 6 with ASTMethodNode

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

the class MethodCallFinder method replaceSubBody.

public boolean replaceSubBody(InvokeStmt s, List<ASTStatementSequenceNode> newChangedBodyPart, ASTParentNodeFinder finder) {
    // get the stmt seq node of invoke stmt
    Object stmtSeqNode = finder.getParentOf(s);
    // find the parent node of the stmt seq node
    Object ParentOfStmtSeq = finder.getParentOf(stmtSeqNode);
    if (ParentOfStmtSeq == null) {
        throw new RuntimeException("MethodCall FInder: parent of stmt seq node not found");
    }
    ASTNode node = (ASTNode) ParentOfStmtSeq;
    if (node instanceof ASTMethodNode) {
        // get the subBody to replace
        List<Object> subBodyToReplace = getSubBodyFromSingleSubBodyNode(node);
        List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
        ((ASTMethodNode) node).replaceBody(newBody);
        return true;
    } else if (node instanceof ASTSynchronizedBlockNode) {
        // get the subBody to replace
        List<Object> subBodyToReplace = getSubBodyFromSingleSubBodyNode(node);
        List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
        ((ASTSynchronizedBlockNode) node).replaceBody(newBody);
        return true;
    } else if (node instanceof ASTLabeledBlockNode) {
        // get the subBody to replace
        List<Object> subBodyToReplace = getSubBodyFromSingleSubBodyNode(node);
        List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
        ((ASTLabeledBlockNode) node).replaceBody(newBody);
        return true;
    } else if (node instanceof ASTUnconditionalLoopNode) {
        // get the subBody to replace
        List<Object> subBodyToReplace = getSubBodyFromSingleSubBodyNode(node);
        List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
        ((ASTUnconditionalLoopNode) node).replaceBody(newBody);
        return true;
    } else if (node instanceof ASTIfNode) {
        // get the subBody to replace
        List<Object> subBodyToReplace = getSubBodyFromSingleSubBodyNode(node);
        List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
        ((ASTIfNode) node).replaceBody(newBody);
        return true;
    } else if (node instanceof ASTWhileNode) {
        // get the subBody to replace
        List<Object> subBodyToReplace = getSubBodyFromSingleSubBodyNode(node);
        List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
        ((ASTWhileNode) node).replaceBody(newBody);
        return true;
    } else if (node instanceof ASTDoWhileNode) {
        // get the subBody to replace
        List<Object> subBodyToReplace = getSubBodyFromSingleSubBodyNode(node);
        List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
        ((ASTDoWhileNode) node).replaceBody(newBody);
        return true;
    } else if (node instanceof ASTForLoopNode) {
        // get the subBody to replace
        List<Object> subBodyToReplace = getSubBodyFromSingleSubBodyNode(node);
        List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
        ((ASTForLoopNode) node).replaceBody(newBody);
        return true;
    } else if (node instanceof ASTIfElseNode) {
        List<Object> subBodies = node.get_SubBodies();
        if (subBodies.size() != 2)
            throw new RuntimeException("Found an ifelse ASTNode which does not have two bodies");
        List<Object> ifBody = (List<Object>) subBodies.get(0);
        List<Object> elseBody = (List<Object>) subBodies.get(1);
        // find out which of these bodies has the stmt seq node with the
        // invoke stmt
        int subBodyNumber = -1;
        Iterator<Object> it = ifBody.iterator();
        while (it.hasNext()) {
            Object temp = it.next();
            if (temp == stmtSeqNode) {
                subBodyNumber = 0;
                break;
            }
        }
        if (subBodyNumber != 0) {
            it = elseBody.iterator();
            while (it.hasNext()) {
                Object temp = it.next();
                if (temp == stmtSeqNode) {
                    subBodyNumber = 1;
                    break;
                }
            }
        }
        List<Object> subBodyToReplace = null;
        if (subBodyNumber == 0)
            subBodyToReplace = ifBody;
        else if (subBodyNumber == 1)
            subBodyToReplace = elseBody;
        else
            throw new RuntimeException("Could not find the related ASTNode in the method");
        List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
        if (subBodyNumber == 0) {
            ((ASTIfElseNode) node).replaceBody(newBody, elseBody);
            return true;
        } else if (subBodyNumber == 1) {
            ((ASTIfElseNode) node).replaceBody(ifBody, newBody);
            return true;
        }
    } else if (node instanceof ASTTryNode) {
        // NOTE THAT method INLINING Is currently only done in the tryBody
        // and not the catchBody
        // THe only reason for this being that mostly method calls are made
        // in the try and not the catch
        // get try body
        List<Object> tryBody = ((ASTTryNode) node).get_TryBody();
        Iterator<Object> it = tryBody.iterator();
        // find whether stmtSeqNode is in the tryBody
        boolean inTryBody = false;
        while (it.hasNext()) {
            ASTNode temp = (ASTNode) it.next();
            if (temp == stmtSeqNode) {
                inTryBody = true;
                break;
            }
        }
        if (!inTryBody) {
            // return without making any changes
            return false;
        }
        List<Object> newBody = createNewSubBody(tryBody, newChangedBodyPart, stmtSeqNode);
        ((ASTTryNode) node).replaceTryBody(newBody);
        return true;
    } else if (node instanceof ASTSwitchNode) {
        List<Object> indexList = ((ASTSwitchNode) node).getIndexList();
        Map<Object, List<Object>> index2BodyList = ((ASTSwitchNode) node).getIndex2BodyList();
        Iterator<Object> it = indexList.iterator();
        while (it.hasNext()) {
            // going through all the cases of the switch
            // statement
            Object currentIndex = it.next();
            List<Object> body = index2BodyList.get(currentIndex);
            if (body != null) {
                // this body is a list of ASTNodes
                // see if it contains stmtSeqNode
                boolean found = false;
                Iterator<Object> itBody = body.iterator();
                while (itBody.hasNext()) {
                    ASTNode temp = (ASTNode) itBody.next();
                    if (temp == stmtSeqNode) {
                        found = true;
                        break;
                    }
                }
                if (found) {
                    // this is the body which has the stmt seq node
                    List<Object> newBody = createNewSubBody(body, newChangedBodyPart, stmtSeqNode);
                    // put this body in the Map
                    index2BodyList.put(currentIndex, newBody);
                    // replace in actual switchNode
                    ((ASTSwitchNode) node).replaceIndex2BodyList(index2BodyList);
                    return true;
                }
            }
        // if body not null
        }
    // going through all cases
    }
    return false;
}
Also used : ASTSynchronizedBlockNode(soot.dava.internal.AST.ASTSynchronizedBlockNode) ASTIfNode(soot.dava.internal.AST.ASTIfNode) ASTTryNode(soot.dava.internal.AST.ASTTryNode) ASTDoWhileNode(soot.dava.internal.AST.ASTDoWhileNode) ASTWhileNode(soot.dava.internal.AST.ASTWhileNode) ASTNode(soot.dava.internal.AST.ASTNode) Iterator(java.util.Iterator) ASTMethodNode(soot.dava.internal.AST.ASTMethodNode) ArrayList(java.util.ArrayList) List(java.util.List) ASTUnconditionalLoopNode(soot.dava.internal.AST.ASTUnconditionalLoopNode) ASTForLoopNode(soot.dava.internal.AST.ASTForLoopNode) ASTIfElseNode(soot.dava.internal.AST.ASTIfElseNode) ASTSwitchNode(soot.dava.internal.AST.ASTSwitchNode) ASTLabeledBlockNode(soot.dava.internal.AST.ASTLabeledBlockNode)

Example 7 with ASTMethodNode

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

the class DavaStaticBlockCleaner method staticBlockInlining.

// invoked by the PackManager
public void staticBlockInlining(SootClass sootClass) {
    this.sootClass = sootClass;
    // the clinit method gets converted into the static block which could initialize the final variable
    if (!sootClass.declaresMethod("void <clinit>()")) {
        // System.out.println("no clinit");
        return;
    }
    SootMethod clinit = sootClass.getMethod("void <clinit>()");
    // retireve the active body
    if (!clinit.hasActiveBody())
        throw new RuntimeException("method " + clinit.getName() + " has no active body!");
    Body clinitBody = clinit.getActiveBody();
    Chain units = ((DavaBody) clinitBody).getUnits();
    if (units.size() != 1) {
        throw new RuntimeException("DavaBody AST doesn't have single root.");
    }
    ASTNode AST = (ASTNode) units.getFirst();
    if (!(AST instanceof ASTMethodNode))
        throw new RuntimeException("Starting node of DavaBody AST is not an ASTMethodNode");
    // running methodCallFinder on the Clinit method
    AST.apply(new MethodCallFinder(this));
}
Also used : Chain(soot.util.Chain) ASTNode(soot.dava.internal.AST.ASTNode) SootMethod(soot.SootMethod) ASTMethodNode(soot.dava.internal.AST.ASTMethodNode) Body(soot.Body)

Example 8 with ASTMethodNode

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

the class SuperFirstStmtHandler method createNewASTConstructor.

public void createNewASTConstructor(ASTStatementSequenceNode initNode) {
    List<Object> newConstructorBody = new ArrayList<Object>();
    List<AugmentedStmt> newStmts = new ArrayList<AugmentedStmt>();
    /*
		 * add any definitions to live variables that might be in body X
		 */
    // we have gotten argsTwoType size() out of the handler so thats the
    // index count
    // mustInitialize has the live variables that need to be initialized
    // create new ReftType for DavaSuperHandler
    RefType type = (new SootClass("DavaSuperHandler")).getType();
    // make JimpleLocal to be used in each arg
    // takes care of
    Local jimpleLocal = new JimpleLocal("handler", type);
    // handler
    // make reference to a method of name get takes one int arg belongs to
    // DavaSuperHandler
    ArrayList tempList = new ArrayList();
    tempList.add(IntType.v());
    SootMethodRef getMethodRef = makeMethodRef("get", tempList);
    // Iterator typeIt = argsTwoTypes.iterator();
    if (mustInitialize != null) {
        Iterator<Local> initIt = mustInitialize.iterator();
        while (initIt.hasNext()) {
            Local initLocal = initIt.next();
            Type tempType = initLocal.getType();
            // takes
            DIntConstant arg = DIntConstant.v(mustInitializeIndex, IntType.v());
            // care
            // of
            // the
            // index
            mustInitializeIndex++;
            ArrayList tempArgList = new ArrayList();
            tempArgList.add(arg);
            DVirtualInvokeExpr tempInvokeExpr = new DVirtualInvokeExpr(jimpleLocal, getMethodRef, tempArgList, new HashSet<Object>());
            // NECESASARY CASTING OR RETRIEVAL OF PRIM TYPES TO BE DONE HERE
            Value toAddExpr = getProperCasting(tempType, tempInvokeExpr);
            if (toAddExpr == null)
                throw new DecompilationException("UNABLE TO CREATE TOADDEXPR:" + tempType);
            // need to create a def stmt with the local on the left and
            // toAddExpr on the right
            GAssignStmt assign = new GAssignStmt(initLocal, toAddExpr);
            newStmts.add(new AugmentedStmt(assign));
        }
    }
    // add any statements following the this.<init> statement
    Iterator<AugmentedStmt> it = initNode.getStatements().iterator();
    while (it.hasNext()) {
        AugmentedStmt augStmt = (AugmentedStmt) it.next();
        Stmt stmtTemp = augStmt.get_Stmt();
        if (stmtTemp == originalConstructorUnit) {
            break;
        }
    }
    while (it.hasNext()) {
        /*
			 * notice we dont need to clone these because these will be removed
			 * from the other method from which we are copying these
			 */
        newStmts.add(it.next());
    }
    if (newStmts.size() > 0) {
        newConstructorBody.add(new ASTStatementSequenceNode(newStmts));
    }
    // adding body Y now
    List<Object> originalASTMethodSubBodies = originalASTMethod.get_SubBodies();
    if (originalASTMethodSubBodies.size() != 1)
        throw new CorruptASTException("size of ASTMethodNode subBody not 1");
    List<Object> oldASTBody = (List<Object>) originalASTMethodSubBodies.get(0);
    Iterator<Object> itOld = oldASTBody.iterator();
    boolean sanity = false;
    while (itOld.hasNext()) {
        // going through originalASTMethodNode's ASTNodes
        ASTNode tempNode = (ASTNode) itOld.next();
        // enter only if its not the initNode
        if (tempNode instanceof ASTStatementSequenceNode) {
            if ((((ASTStatementSequenceNode) tempNode).getStatements()).equals(initNode.getStatements())) {
                sanity = true;
                break;
            }
        }
    }
    if (!sanity) {
        // means we never found the initNode which shouldnt happen
        throw new DecompilationException("never found the init node");
    }
    // Y are all the nodes following the initNode
    while (itOld.hasNext()) {
        newConstructorBody.add(itOld.next());
    }
    // setDeclarations in newNode
    // The LocalVariableCleaner which is called in the end of DavaBody will
    // clear up any declarations that are not required
    List<AugmentedStmt> newConstructorDeclarations = new ArrayList<AugmentedStmt>();
    for (AugmentedStmt as : originalASTMethod.getDeclarations().getStatements()) {
        DVariableDeclarationStmt varDecStmt = (DVariableDeclarationStmt) as.get_Stmt();
        newConstructorDeclarations.add(new AugmentedStmt((DVariableDeclarationStmt) varDecStmt.clone()));
    }
    ASTStatementSequenceNode newDecs = new ASTStatementSequenceNode(new ArrayList<AugmentedStmt>());
    if (newConstructorDeclarations.size() > 0) {
        newDecs = new ASTStatementSequenceNode(newConstructorDeclarations);
        // DONT FORGET TO SET THE DECLARATIONS IN THE METHOD ONCE IT IS
        // CREATED
        // newASTConstructorMethod.setDeclarations(newDecs);
        // declarations are always the first element
        newConstructorBody.add(0, newDecs);
    }
    // so we have any declarations followed by body Y
    // have to put the newConstructorBody into an list of subBodies which
    // goes into the newASTConstructorMethod
    newASTConstructorMethod = new ASTMethodNode(newConstructorBody);
    // dont forget to set the declarations
    newASTConstructorMethod.setDeclarations(newDecs);
}
Also used : DVariableDeclarationStmt(soot.dava.internal.javaRep.DVariableDeclarationStmt) CorruptASTException(soot.dava.CorruptASTException) ArrayList(java.util.ArrayList) DecompilationException(soot.dava.DecompilationException) ASTStatementSequenceNode(soot.dava.internal.AST.ASTStatementSequenceNode) JimpleLocal(soot.jimple.internal.JimpleLocal) 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) RefType(soot.RefType) DVirtualInvokeExpr(soot.dava.internal.javaRep.DVirtualInvokeExpr) ASTNode(soot.dava.internal.AST.ASTNode) List(java.util.List) ArrayList(java.util.ArrayList) ASTMethodNode(soot.dava.internal.AST.ASTMethodNode) GAssignStmt(soot.grimp.internal.GAssignStmt) SootMethodRef(soot.SootMethodRef) JimpleLocal(soot.jimple.internal.JimpleLocal) Local(soot.Local) AugmentedStmt(soot.dava.internal.asg.AugmentedStmt) SootClass(soot.SootClass) RefType(soot.RefType) ShortType(soot.ShortType) BooleanType(soot.BooleanType) ByteType(soot.ByteType) Type(soot.Type) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) CharType(soot.CharType) LongType(soot.LongType) PrimType(soot.PrimType) VoidType(soot.VoidType) DIntConstant(soot.dava.internal.javaRep.DIntConstant) Value(soot.Value)

Example 9 with ASTMethodNode

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

the class SuperFirstStmtHandler method createNewASTPreInitMethod.

/*
	 * January 23rd New Algorithm Leave originalASTMethod unchanged Clone
	 * everything and copy only those which are needed in the
	 * newASTPreInitMethod
	 */
private void createNewASTPreInitMethod(ASTStatementSequenceNode initNode) {
    List<Object> newPreinitBody = new ArrayList<Object>();
    // start adding ASTNodes into newPreinitBody from the
    // originalASTMethod's body until we reach initNode
    List<Object> originalASTMethodSubBodies = originalASTMethod.get_SubBodies();
    if (originalASTMethodSubBodies.size() != 1)
        throw new CorruptASTException("size of ASTMethodNode subBody not 1");
    List<Object> oldASTBody = (List<Object>) originalASTMethodSubBodies.get(0);
    Iterator<Object> it = oldASTBody.iterator();
    boolean sanity = false;
    while (it.hasNext()) {
        // going through originalASTMethodNode's ASTNodes
        ASTNode tempNode = (ASTNode) it.next();
        // enter only if its not the initNode
        if (tempNode instanceof ASTStatementSequenceNode) {
            if ((((ASTStatementSequenceNode) tempNode).getStatements()).equals(initNode.getStatements())) {
                sanity = true;
                break;
            } else {
                // this was not the initNode so we add
                newPreinitBody.add(tempNode);
            }
        } else {
            // not a stmtseq so simply add it
            newPreinitBody.add(tempNode);
        }
    }
    if (!sanity) {
        // means we never found the initNode which shouldnt happen
        throw new DecompilationException("never found the init node");
    }
    // at this moment newPreinitBody contains all of X except for any stmts
    // above the this.init call in the stmtseq node
    // copy those
    List<AugmentedStmt> newStmts = new ArrayList<AugmentedStmt>();
    for (AugmentedStmt augStmt : initNode.getStatements()) {
        Stmt stmtTemp = augStmt.get_Stmt();
        if (stmtTemp == originalConstructorUnit) {
            break;
        }
        // adding any stmt until constructorUnit into topList for
        // newMethodNode
        /*
			 * notice we dont need to clone these because these will be removed
			 * from the other method from which we are copying these
			 */
        newStmts.add(augStmt);
    }
    if (newStmts.size() > 0) {
        newPreinitBody.add(new ASTStatementSequenceNode(newStmts));
    }
    // setDeclarations in newNode
    // The LocalVariableCleaner which is called in the end of DavaBody will
    // clear up any declarations that are not required
    List<AugmentedStmt> newPreinitDeclarations = new ArrayList<AugmentedStmt>();
    for (AugmentedStmt as : originalASTMethod.getDeclarations().getStatements()) {
        DVariableDeclarationStmt varDecStmt = (DVariableDeclarationStmt) as.get_Stmt();
        newPreinitDeclarations.add(new AugmentedStmt((DVariableDeclarationStmt) varDecStmt.clone()));
    }
    ASTStatementSequenceNode newDecs = new ASTStatementSequenceNode(new ArrayList<AugmentedStmt>());
    if (newPreinitDeclarations.size() > 0) {
        newDecs = new ASTStatementSequenceNode(newPreinitDeclarations);
        // DONT FORGET TO SET THE DECLARATIONS IN THE METHOD ONCE IT IS
        // CREATED
        // newASTPreInitMethod.setDeclarations(newDecs);
        // when we copied the body X the first Node copied was the
        // Declarations from the originalASTMethod
        // replace that with this new one
        newPreinitBody.remove(0);
        newPreinitBody.add(0, newDecs);
    }
    // otherwise super is infact the first stmt
    if (newPreinitBody.size() < 1) {
        // System.out.println("Method node empty doing nothing returning");
        // meaning ASTMethodNode for this method
        newASTPreInitMethod = null;
        // not created
        return;
    }
    // so we have any declarations followed by body X
    // NEXT THING SHOULD BE CODE TO CREATE A DAVAHANDLER AND STORE THE ARGS
    // TO SUPER IN IT
    // HOWEVER WE WILL DELAY THIS TILL UNTIL WE ARE READY TO FINALIZE the
    // PREINIT
    // reason for delaying is that even though we know that the body is not
    // empty the body
    // could be made empty by the transformations which act in the finalize
    // method
    // have to put the newPreinitBody into an list of subBodies which goes
    // into the newASTPreInitMethod
    newASTPreInitMethod = new ASTMethodNode(newPreinitBody);
    // dont forget to set the declarations
    newASTPreInitMethod.setDeclarations(newDecs);
}
Also used : DVariableDeclarationStmt(soot.dava.internal.javaRep.DVariableDeclarationStmt) CorruptASTException(soot.dava.CorruptASTException) ArrayList(java.util.ArrayList) DecompilationException(soot.dava.DecompilationException) 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) ASTNode(soot.dava.internal.AST.ASTNode) List(java.util.List) ArrayList(java.util.ArrayList) ASTMethodNode(soot.dava.internal.AST.ASTMethodNode)

Aggregations

ASTMethodNode (soot.dava.internal.AST.ASTMethodNode)9 ASTNode (soot.dava.internal.AST.ASTNode)7 ArrayList (java.util.ArrayList)6 List (java.util.List)5 ASTStatementSequenceNode (soot.dava.internal.AST.ASTStatementSequenceNode)5 Iterator (java.util.Iterator)4 SootMethod (soot.SootMethod)4 Body (soot.Body)3 SootClass (soot.SootClass)3 AugmentedStmt (soot.dava.internal.asg.AugmentedStmt)3 DefinitionStmt (soot.jimple.DefinitionStmt)3 Chain (soot.util.Chain)3 Local (soot.Local)2 RefType (soot.RefType)2 SootMethodRef (soot.SootMethodRef)2 Value (soot.Value)2 CorruptASTException (soot.dava.CorruptASTException)2 DavaBody (soot.dava.DavaBody)2 DecompilationException (soot.dava.DecompilationException)2 DVariableDeclarationStmt (soot.dava.internal.javaRep.DVariableDeclarationStmt)2