Search in sources :

Example 46 with Local

use of com.googlecode.dex2jar.ir.expr.Local in project dex2jar by pxb1988.

the class Dex2IrAdapter method visitRegister.

@Override
public void visitRegister(int total) {
    Local[] locals = new Local[total];
    this.locals = locals;
    this.tmpLocal = new Local(total);
    for (int i = 0; i < locals.length; i++) {
        locals[i] = new Local(i);
    }
    int nextReg = total - countParameterRegisters(method, isStatic);
    int nextReg0 = nextReg;
    if (!isStatic) {
        // is not static
        x(Stmts.nIdentity(locals[nextReg], Exprs.nThisRef(method.getOwner())));
        nextReg++;
    }
    String[] args = method.getParameterTypes();
    for (int i = 0; i < args.length; i++) {
        String t = args[i];
        x(Stmts.nIdentity(locals[nextReg], Exprs.nParameterRef(t, i)));
        nextReg++;
        if (t.equals("J") || t.equals("D")) {
            nextReg++;
        }
    }
    // simple fix for issue 219, init all tmp register to 0 at the start of insn.
    for (int i = 0; i < nextReg0; i++) {
        x(Stmts.nAssign(locals[i], nInt(0)));
    }
    x(Stmts.nAssign(tmpLocal, nInt(0)));
}
Also used : Local(com.googlecode.dex2jar.ir.expr.Local) Exprs.nString(com.googlecode.dex2jar.ir.expr.Exprs.nString)

Example 47 with Local

use of com.googlecode.dex2jar.ir.expr.Local in project dex2jar by pxb1988.

the class NpeTransformer method replace.

private void replace(final IrMethod m, final Stmt p) {
    StmtTraveler traveler = new StmtTraveler() {

        @Override
        public Value travel(Value op) {
            switch(op.vt) {
                case INVOKE_VIRTUAL:
                case INVOKE_SPECIAL:
                case INVOKE_INTERFACE:
                    {
                        Value[] ops = op.getOps();
                        if (isNull(ops[0])) {
                            for (int i = 1; i < ops.length; i++) {
                                travel(ops[i]);
                            }
                            throw NPE;
                        }
                    }
                    break;
                case ARRAY:
                    {
                        if (isNull(op.getOp1())) {
                            travel(op.getOp2());
                            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) {
                            travel(op.getOp1());
                            throw DIVE;
                        }
                    }
                    break;
                case LDIV:
                    if (op.getOp2().vt == Value.VT.CONSTANT) {
                        Constant constant = (Constant) op.getOp2();
                        if (((Number) constant.value).longValue() == 0) {
                            travel(op.getOp1());
                            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;
                            } else {
                                travel(size);
                            }
                        }
                    }
                    break;
                default:
            }
            Value sop = super.travel(op);
            if (sop.vt == Value.VT.LOCAL || sop.vt == Value.VT.CONSTANT) {
                return sop;
            } else {
                Local local = new Local();
                m.locals.add(local);
                m.stmts.insertBefore(p, Stmts.nAssign(local, sop));
                return local;
            }
        }
    };
    try {
        switch(p.et) {
            case E0:
                // impossible
                break;
            case E1:
                traveler.travel(p.getOp());
                break;
            case E2:
                if (p.st == Stmt.ST.ASSIGN) {
                    switch(p.getOp1().vt) {
                        case ARRAY:
                            traveler.travel(p.getOp1().getOp1());
                            traveler.travel(p.getOp1().getOp2());
                            traveler.travel(p.getOp2());
                            break;
                        case FIELD:
                            traveler.travel(p.getOp1().getOp());
                            traveler.travel(p.getOp2());
                            break;
                        case STATIC_FIELD:
                        case LOCAL:
                            traveler.travel(p.getOp2());
                            break;
                        default:
                    }
                } else if (p.st == Stmt.ST.FILL_ARRAY_DATA) {
                    if (isNull(p.getOp1())) {
                        throw NPE;
                    } else {
                        traveler.travel(p.getOp1());
                    }
                }
                break;
            case En:
        }
    } catch (MustThrowException e) {
        if (e == NPE) {
            m.stmts.insertBefore(p, Stmts.nThrow(Exprs.nInvokeNew(new Value[0], new String[0], "Ljava/lang/NullPointerException;")));
        } else if (e == DIVE) {
            m.stmts.insertBefore(p, Stmts.nThrow(Exprs.nInvokeNew(new Value[] { Exprs.nString("divide by zero") }, new String[] { "Ljava/lang/String;" }, "Ljava/lang/ArithmeticException;")));
        } else if (e == NEGATIVE_ARRAY_SIZE) {
            m.stmts.insertBefore(p, Stmts.nThrow(Exprs.nInvokeNew(new Value[0], new String[0], "Ljava/lang/NegativeArraySizeException;")));
        }
    }
}
Also used : StmtTraveler(com.googlecode.dex2jar.ir.StmtTraveler) Constant(com.googlecode.dex2jar.ir.expr.Constant) Value(com.googlecode.dex2jar.ir.expr.Value) Local(com.googlecode.dex2jar.ir.expr.Local)

Example 48 with Local

use of com.googlecode.dex2jar.ir.expr.Local 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 49 with Local

use of com.googlecode.dex2jar.ir.expr.Local in project dex2jar by pxb1988.

the class RemoveLocalFromSSA method collectPhiObjects.

private Map<Local, PhiObject> collectPhiObjects(List<LabelStmt> phiLabels) {
    Map<Local, PhiObject> phis;
    phis = new HashMap<>();
    for (LabelStmt labelStmt : phiLabels) {
        for (AssignStmt as : labelStmt.phis) {
            Local local = (Local) as.getOp1();
            PhiObject child = getOrCreate(phis, local);
            child.isInitByPhi = true;
            for (Value op : as.getOp2().getOps()) {
                if (op == local) {
                    continue;
                }
                PhiObject parent = getOrCreate(phis, (Local) op);
                linkPhiObject(parent, child);
            }
        }
    }
    return phis;
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Value(com.googlecode.dex2jar.ir.expr.Value) Local(com.googlecode.dex2jar.ir.expr.Local)

Example 50 with Local

use of com.googlecode.dex2jar.ir.expr.Local 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)

Aggregations

Local (com.googlecode.dex2jar.ir.expr.Local)86 Test (org.junit.Test)44 LabelStmt (com.googlecode.dex2jar.ir.stmt.LabelStmt)28 Stmt (com.googlecode.dex2jar.ir.stmt.Stmt)23 Value (com.googlecode.dex2jar.ir.expr.Value)19 AssignStmt (com.googlecode.dex2jar.ir.stmt.AssignStmt)15 ArrayList (java.util.ArrayList)8 IrMethod (com.googlecode.dex2jar.ir.IrMethod)6 Exprs.nLocal (com.googlecode.dex2jar.ir.expr.Exprs.nLocal)6 UnopStmt (com.googlecode.dex2jar.ir.stmt.UnopStmt)6 JumpStmt (com.googlecode.dex2jar.ir.stmt.JumpStmt)5 ConstTransformer (com.googlecode.dex2jar.ir.ts.ConstTransformer)5 Exprs.nString (com.googlecode.dex2jar.ir.expr.Exprs.nString)4 StmtList (com.googlecode.dex2jar.ir.stmt.StmtList)4 Trap (com.googlecode.dex2jar.ir.Trap)3 Exprs.nArrayValue (com.googlecode.dex2jar.ir.expr.Exprs.nArrayValue)3 AnalyzeValue (com.googlecode.dex2jar.ir.ts.an.AnalyzeValue)3 List (java.util.List)3 DexLabel (com.googlecode.d2j.DexLabel)2 Op (com.googlecode.d2j.reader.Op)2