Search in sources :

Example 1 with Constant

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

the class ZeroTransformer method transformReportChanged.

@Override
public boolean transformReportChanged(IrMethod method) {
    boolean changed = false;
    List<AssignStmt> assignStmtList = new ArrayList<>();
    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.CONSTANT) {
                Constant cst = (Constant) as.getOp2();
                Object value = cst.value;
                if (value instanceof Number && !((value instanceof Long) || (value instanceof Double))) {
                    int v = ((Number) value).intValue();
                    if (v == 0 || v == 1) {
                        assignStmtList.add(as);
                    }
                }
            }
        }
    }
    if (assignStmtList.size() == 0) {
        return false;
    }
    List<LabelStmt> phiLabels = method.phiLabels;
    if (phiLabels != null) {
        for (AssignStmt as : assignStmtList) {
            Local local = (Local) as.getOp1();
            boolean first = true;
            for (LabelStmt labelStmt : phiLabels) {
                for (AssignStmt phi : labelStmt.phis) {
                    Value[] vs = phi.getOp2().getOps();
                    for (int i = 0; i < vs.length; i++) {
                        Value v = vs[i];
                        if (v == local) {
                            if (first) {
                                first = false;
                            } else {
                                Local nLocal = Exprs.nLocal(-1);
                                method.locals.add(nLocal);
                                changed = true;
                                method.stmts.insertBefore(as, Stmts.nAssign(nLocal, as.getOp2().clone()));
                                vs[i] = nLocal;
                            }
                        }
                    }
                }
            }
        }
    }
    return changed;
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Constant(com.googlecode.dex2jar.ir.expr.Constant) 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)

Example 2 with Constant

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

the class ArrayNullPointerTransformer method tryAdd.

private boolean tryAdd(Value value, List<Value> values) {
    if (!arrayNPE(value)) {
        values.add(value);
        return true;
    } else {
        switch(value.et) {
            case E0:
                values.add(value);
                break;
            case E1:
                E1Expr e1 = (E1Expr) value;
                if (e1.op == null || e1.op.trim() == null) {
                    return false;
                }
                tryAdd(e1.op.trim(), values);
                break;
            case E2:
                E2Expr e2 = (E2Expr) value;
                if (e2.vt == VT.ARRAY && e2.op1.trim().vt == VT.CONSTANT) {
                    Constant cst = (Constant) e2.op1.trim();
                    if (cst.value.equals(Integer.valueOf(0))) {
                        tryAdd(e2.op2.trim(), values);
                        return false;
                    }
                }
                if (tryAdd(e2.op1.trim(), values)) {
                    tryAdd(e2.op2.trim(), values);
                }
            case En:
                for (Value vb : ((EnExpr) value).ops) {
                    if (!tryAdd(vb.trim(), values)) {
                        break;
                    }
                }
        }
    }
    return false;
}
Also used : E2Expr(com.googlecode.dex2jar.ir.expr.Value.E2Expr) E1Expr(com.googlecode.dex2jar.ir.expr.Value.E1Expr) EnExpr(com.googlecode.dex2jar.ir.expr.Value.EnExpr) Constant(com.googlecode.dex2jar.ir.expr.Constant) Value(com.googlecode.dex2jar.ir.expr.Value)

Example 3 with Constant

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

the class JimpleTransformer method convertExpr.

private Value convertExpr(Value x, boolean keep, N tmp) {
    switch(x.et) {
        case E0:
            if (!keep) {
                switch(x.vt) {
                    case CONSTANT:
                        Constant cst = (Constant) x;
                        if (cst.value instanceof String || cst.value instanceof Constant.Type || cst.value.getClass().isArray()) {
                            return tmp.newAssign(x);
                        }
                        break;
                    case NEW:
                    case STATIC_FIELD:
                        return tmp.newAssign(x);
                    default:
                }
            }
            break;
        case E1:
            x.setOp(convertExpr(x.getOp(), false, tmp));
            if (!keep) {
                return tmp.newAssign(x);
            }
            break;
        case E2:
            x.setOp1(convertExpr(x.getOp1(), false, tmp));
            x.setOp2(convertExpr(x.getOp2(), false, tmp));
            if (!keep) {
                return tmp.newAssign(x);
            }
            break;
        case En:
            Value[] ops = x.getOps();
            for (int i = 0; i < ops.length; i++) {
                ops[i] = convertExpr(ops[i], false, tmp);
            }
            if (!keep) {
                return tmp.newAssign(x);
            }
            break;
    }
    return x;
}
Also used : Constant(com.googlecode.dex2jar.ir.expr.Constant) Value(com.googlecode.dex2jar.ir.expr.Value)

Example 4 with Constant

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

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

Aggregations

Constant (com.googlecode.dex2jar.ir.expr.Constant)5 Value (com.googlecode.dex2jar.ir.expr.Value)5 Local (com.googlecode.dex2jar.ir.expr.Local)2 Stmt (com.googlecode.dex2jar.ir.stmt.Stmt)2 StmtSearcher (com.googlecode.dex2jar.ir.StmtSearcher)1 StmtTraveler (com.googlecode.dex2jar.ir.StmtTraveler)1 E1Expr (com.googlecode.dex2jar.ir.expr.Value.E1Expr)1 E2Expr (com.googlecode.dex2jar.ir.expr.Value.E2Expr)1 EnExpr (com.googlecode.dex2jar.ir.expr.Value.EnExpr)1 AssignStmt (com.googlecode.dex2jar.ir.stmt.AssignStmt)1 LabelStmt (com.googlecode.dex2jar.ir.stmt.LabelStmt)1 ArrayList (java.util.ArrayList)1