Search in sources :

Example 26 with Stmt

use of com.googlecode.dex2jar.ir.stmt.Stmt in project dex2jar by pxb1988.

the class NpeTransformer method transformReportChanged.

@Override
public boolean transformReportChanged(IrMethod method) {
    boolean changed = false;
    if (method.locals.size() == 0) {
        return false;
    }
    StmtSearcher st = new StmtSearcher() {

        @Override
        public void travel(Stmt stmt) {
            if (stmt.st == Stmt.ST.FILL_ARRAY_DATA) {
                if (isNull(stmt.getOp1())) {
                    throw NPE;
                }
            }
            super.travel(stmt);
        }

        @Override
        public void travel(Value op) {
            switch(op.vt) {
                case INVOKE_VIRTUAL:
                case INVOKE_SPECIAL:
                case INVOKE_INTERFACE:
                    {
                        if (isNull(op.getOps()[0])) {
                            throw NPE;
                        }
                    }
                    break;
                case ARRAY:
                    {
                        if (isNull(op.getOp1())) {
                            throw NPE;
                        }
                    }
                    break;
                case FIELD:
                    {
                        if (isNull(op.getOp())) {
                            throw NPE;
                        }
                    }
                    break;
                case IDIV:
                    if (op.getOp2().vt == Value.VT.CONSTANT) {
                        Constant constant = (Constant) op.getOp2();
                        if (((Number) constant.value).intValue() == 0) {
                            throw DIVE;
                        }
                    }
                    break;
                case LDIV:
                    if (op.getOp2().vt == Value.VT.CONSTANT) {
                        Constant constant = (Constant) op.getOp2();
                        if (((Number) constant.value).longValue() == 0) {
                            throw DIVE;
                        }
                    }
                    break;
                case NEW_ARRAY:
                    if (op.getOp().vt == Value.VT.CONSTANT) {
                        Constant constant = (Constant) op.getOp();
                        if (((Number) constant.value).intValue() < 0) {
                            throw NEGATIVE_ARRAY_SIZE;
                        }
                    }
                    break;
                case NEW_MUTI_ARRAY:
                    for (Value size : op.getOps()) {
                        if (size.vt == Value.VT.CONSTANT) {
                            Constant constant = (Constant) size;
                            if (((Number) constant.value).intValue() < 0) {
                                throw NEGATIVE_ARRAY_SIZE;
                            }
                        }
                    }
                    break;
                default:
            }
        }
    };
    for (Stmt p = method.stmts.getFirst(); p != null; ) {
        try {
            st.travel(p);
            p = p.getNext();
        } catch (MustThrowException e) {
            replace(method, p);
            Stmt q = p.getNext();
            method.stmts.remove(p);
            changed = true;
            p = q;
        }
    }
    return changed;
}
Also used : Constant(com.googlecode.dex2jar.ir.expr.Constant) Value(com.googlecode.dex2jar.ir.expr.Value) StmtSearcher(com.googlecode.dex2jar.ir.StmtSearcher) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt)

Example 27 with Stmt

use of com.googlecode.dex2jar.ir.stmt.Stmt in project dex2jar by pxb1988.

the class RemoveConstantFromSSA method transformReportChanged.

@Override
public boolean transformReportChanged(IrMethod method) {
    boolean changed = false;
    List<AssignStmt> assignStmtList = new ArrayList<>();
    Map<Local, Object> cstMap = new HashMap<>();
    for (Stmt p = method.stmts.getFirst(); p != null; p = p.getNext()) {
        if (p.st == Stmt.ST.ASSIGN) {
            AssignStmt as = (AssignStmt) p;
            if (as.getOp1().vt == Value.VT.LOCAL) {
                if (as.getOp2().vt == Value.VT.CONSTANT) {
                    assignStmtList.add(as);
                    cstMap.put((Local) as.getOp1(), ((Constant) as.getOp2()).value);
                } else if (as.getOp2().vt == Value.VT.LOCAL) {
                    cstMap.put((Local) as.getOp1(), as.getOp2());
                }
            }
        }
    }
    if (assignStmtList.size() == 0) {
        return false;
    }
    RemoveLocalFromSSA.fixReplace(cstMap);
    final Map<Local, Value> toReplace = new HashMap<>();
    Set<Value> usedInPhi = new HashSet<>();
    List<LabelStmt> phiLabels = method.phiLabels;
    if (phiLabels != null) {
        boolean loopAgain = true;
        while (loopAgain) {
            loopAgain = false;
            usedInPhi.clear();
            for (Iterator<LabelStmt> it = phiLabels.iterator(); it.hasNext(); ) {
                LabelStmt labelStmt = it.next();
                if (labelStmt.phis != null) {
                    for (Iterator<AssignStmt> it2 = labelStmt.phis.iterator(); it2.hasNext(); ) {
                        AssignStmt phi = it2.next();
                        Value[] vs = phi.getOp2().getOps();
                        Object sameCst = null;
                        boolean allEqual = true;
                        for (Value p : vs) {
                            Object cst = cstMap.get(p);
                            if (cst == null) {
                                allEqual = false;
                                break;
                            }
                            if (sameCst == null) {
                                sameCst = cst;
                            } else if (!sameCst.equals(cst)) {
                                allEqual = false;
                                break;
                            }
                        }
                        if (allEqual) {
                            // all are same constant
                            cstMap.put((Local) phi.getOp1(), sameCst);
                            if (sameCst instanceof Local) {
                                phi.setOp2((Value) sameCst);
                            } else {
                                phi.setOp2(Exprs.nConstant(sameCst));
                                assignStmtList.add(phi);
                            }
                            it2.remove();
                            method.stmts.insertAfter(labelStmt, phi);
                            changed = true;
                            // loop again
                            loopAgain = true;
                        } else {
                            usedInPhi.addAll(Arrays.asList(phi.getOp2().getOps()));
                        }
                    }
                    if (labelStmt.phis.size() == 0) {
                        it.remove();
                    }
                }
            }
        }
    }
    for (Iterator<AssignStmt> it = assignStmtList.iterator(); it.hasNext(); ) {
        AssignStmt as = it.next();
        if (!usedInPhi.contains(as.getOp1())) {
            it.remove();
            method.stmts.remove(as);
            method.locals.remove(as.getOp1());
            changed = true;
        }
        toReplace.put((Local) as.getOp1(), as.getOp2());
    }
    Cfg.travelMod(method.stmts, new Cfg.TravelCallBack() {

        @Override
        public Value onAssign(Local v, AssignStmt as) {
            return v;
        }

        @Override
        public Value onUse(Local v) {
            Value n = toReplace.get(v);
            return n == null ? v : n.clone();
        }
    }, false);
    return changed;
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) HashMap(java.util.HashMap) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) ArrayList(java.util.ArrayList) Local(com.googlecode.dex2jar.ir.expr.Local) LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt) Value(com.googlecode.dex2jar.ir.expr.Value) HashSet(java.util.HashSet)

Example 28 with Stmt

use of com.googlecode.dex2jar.ir.stmt.Stmt in project dex2jar by pxb1988.

the class RemoveLocalFromSSA method transformReportChanged.

@Override
public boolean transformReportChanged(IrMethod method) {
    boolean irChanged = false;
    List<AssignStmt> assignStmtList = new ArrayList<>();
    List<LabelStmt> phiLabels = method.phiLabels;
    for (Stmt p = method.stmts.getFirst(); p != null; p = p.getNext()) {
        if (p.st == Stmt.ST.ASSIGN) {
            AssignStmt as = (AssignStmt) p;
            if (as.getOp1().vt == Value.VT.LOCAL && as.getOp2().vt == Value.VT.LOCAL) {
                assignStmtList.add(as);
            }
        }
    }
    final Map<Local, Local> toReplace = new HashMap<>();
    Set<Value> set = new HashSet<>();
    boolean changed = true;
    while (changed) {
        changed = false;
        if (removeLoopFromPhi(phiLabels, toReplace)) {
            fixReplace(toReplace);
            replacePhi(phiLabels, toReplace, set);
        }
        while (simplePhi(phiLabels, toReplace, set)) {
            // remove a = phi(b)
            fixReplace(toReplace);
            replacePhi(phiLabels, toReplace, set);
        }
        while (simpleAssign(phiLabels, assignStmtList, toReplace, method.stmts)) {
            // remove a=b
            fixReplace(toReplace);
            replaceAssign(assignStmtList, toReplace);
            changed = true;
            irChanged = true;
        }
        replacePhi(phiLabels, toReplace, set);
    }
    for (Local local : toReplace.keySet()) {
        method.locals.remove(local);
        irChanged = true;
    }
    if (toReplace.size() > 0) {
        Cfg.travelMod(method.stmts, new Cfg.TravelCallBack() {

            @Override
            public Value onAssign(Local v, AssignStmt as) {
                return v;
            }

            @Override
            public Value onUse(Local v) {
                Local n = toReplace.get(v);
                return n == null ? v : n;
            }
        }, true);
    }
    return irChanged;
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Local(com.googlecode.dex2jar.ir.expr.Local) LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt) Value(com.googlecode.dex2jar.ir.expr.Value)

Example 29 with Stmt

use of com.googlecode.dex2jar.ir.stmt.Stmt in project dex2jar by pxb1988.

the class AggTransformer method transformReportChanged.

@Override
public boolean transformReportChanged(IrMethod method) {
    boolean changed = false;
    Set<Stmt> locationSensitiveStmts = new HashSet<>();
    // 1. merge location Insensitive stmts
    changed = simpleMergeLocals(method, changed, locationSensitiveStmts);
    if (locationSensitiveStmts.size() == 0) {
        return changed;
    }
    ReplaceX replaceX = new ReplaceX();
    Queue<Stmt> q = new UniqueQueue<>();
    q.addAll(locationSensitiveStmts);
    // 2. merge location sensitive stmts
    while (!q.isEmpty()) {
        Stmt stmt = q.poll();
        Local local = (Local) stmt.getOp1();
        Stmt next = stmt.getNext();
        switch(next.st) {
            case LABEL:
            case GOTO:
            case IDENTITY:
            case FILL_ARRAY_DATA:
            case NOP:
            case RETURN_VOID:
                continue;
            default:
        }
        try {
            localCanExecFirst(local, next);
            // impossible here
            throw new RuntimeException();
        } catch (MergeResult e) {
            if (e == SUCCESS) {
                replaceX.local = local;
                replaceX.replaceWith = stmt.getOp2();
                method.locals.remove(local);
                method.stmts.remove(stmt);
                Cfg.travelMod(next, replaceX, false);
                Stmt pre = next.getPre();
                if (pre != null && locationSensitiveStmts.contains(pre)) {
                    q.add(pre);
                }
            }
        }
    }
    return changed;
}
Also used : Local(com.googlecode.dex2jar.ir.expr.Local) LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt)

Example 30 with Stmt

use of com.googlecode.dex2jar.ir.stmt.Stmt in project dex2jar by pxb1988.

the class ArrayNullPointerTransformer method transform.

@Override
public void transform(IrMethod irMethod) {
    for (Stmt p = irMethod.stmts.getFirst(); p != null; ) {
        if (arrayNPE(p)) {
            Stmt q = p.getNext();
            replaceNPE(irMethod.stmts, irMethod.locals, p);
            p = q;
            continue;
        }
        p = p.getNext();
    }
}
Also used : Stmt(com.googlecode.dex2jar.ir.stmt.Stmt) E1Stmt(com.googlecode.dex2jar.ir.stmt.Stmt.E1Stmt) E2Stmt(com.googlecode.dex2jar.ir.stmt.Stmt.E2Stmt)

Aggregations

Stmt (com.googlecode.dex2jar.ir.stmt.Stmt)41 LabelStmt (com.googlecode.dex2jar.ir.stmt.LabelStmt)31 Local (com.googlecode.dex2jar.ir.expr.Local)23 AssignStmt (com.googlecode.dex2jar.ir.stmt.AssignStmt)22 Test (org.junit.Test)10 Value (com.googlecode.dex2jar.ir.expr.Value)8 ArrayList (java.util.ArrayList)7 JumpStmt (com.googlecode.dex2jar.ir.stmt.JumpStmt)4 Cfg (com.googlecode.dex2jar.ir.ts.Cfg)4 Trap (com.googlecode.dex2jar.ir.Trap)3 StmtList (com.googlecode.dex2jar.ir.stmt.StmtList)3 List (java.util.List)3 StmtTraveler (com.googlecode.dex2jar.ir.StmtTraveler)2 Constant (com.googlecode.dex2jar.ir.expr.Constant)2 PhiExpr (com.googlecode.dex2jar.ir.expr.PhiExpr)2 E2Stmt (com.googlecode.dex2jar.ir.stmt.Stmt.E2Stmt)2 HashSet (java.util.HashSet)2 IR2JConverter (com.googlecode.d2j.converter.IR2JConverter)1 DexFileNode (com.googlecode.d2j.node.DexFileNode)1 DexMethodNode (com.googlecode.d2j.node.DexMethodNode)1