Search in sources :

Example 36 with Stmt

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

the class VoidInvokeTransformer method transformReportChanged.

@Override
public boolean transformReportChanged(IrMethod method) {
    if (method.locals.size() == 0) {
        return false;
    }
    int[] reads = Cfg.countLocalReads(method);
    boolean changed = false;
    for (Stmt p = method.stmts.getFirst(); p != null; p = p.getNext()) {
        if (p.st == Stmt.ST.ASSIGN && p.getOp1().vt == Value.VT.LOCAL) {
            Local left = (Local) p.getOp1();
            if (reads[left._ls_index] == 0) {
                switch(p.getOp2().vt) {
                    case INVOKE_INTERFACE:
                    case INVOKE_NEW:
                    case INVOKE_SPECIAL:
                    case INVOKE_STATIC:
                    case INVOKE_VIRTUAL:
                        method.locals.remove(left);
                        Stmt nVoidInvoke = Stmts.nVoidInvoke(p.getOp2());
                        method.stmts.replace(p, nVoidInvoke);
                        p = nVoidInvoke;
                        changed = true;
                        break;
                    default:
                        break;
                }
            }
        }
    }
    return changed;
}
Also used : Local(com.googlecode.dex2jar.ir.expr.Local) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt)

Example 37 with Stmt

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

the class BaseAnalyze method init.

protected void init() {
    if (reindexLocal) {
        int index = 0;
        for (Local local : method.locals) {
            local._ls_index = index;
            index++;
        }
    }
    if (DEBUG) {
        int idx = 0;
        for (Stmt s : method.stmts) {
            if (s.st == Stmt.ST.LABEL) {
                LabelStmt label = (LabelStmt) s;
                label.displayName = "L" + idx++;
            }
        }
    }
    initCFG();
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) 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 38 with Stmt

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

the class ArrayElementTransformer method transformReportChanged.

@Override
public boolean transformReportChanged(IrMethod method) {
    Set<Local> arrays = searchForArrayObject(method);
    if (arrays.size() == 0) {
        return false;
    }
    for (Local local : method.locals) {
        local._ls_index = -1;
    }
    int i = 0;
    for (Local local : arrays) {
        local._ls_index = i++;
    }
    final int size = i;
    Cfg.createCFG(method);
    final List<ArrayValue> values = new ArrayList<>();
    final List<Stmt> used = new ArrayList<>();
    Cfg.dfs(method.stmts, new Cfg.FrameVisitor<ArrayValue[]>() {

        Set<Integer> phis = new HashSet<>();

        @Override
        public ArrayValue[] merge(ArrayValue[] srcFrame, ArrayValue[] distFrame, Stmt src, Stmt dist) {
            if (dist.st == Stmt.ST.LABEL) {
                LabelStmt labelStmt = (LabelStmt) dist;
                if (labelStmt.phis != null) {
                    for (AssignStmt phi : labelStmt.phis) {
                        int idx = ((Local) phi.getOp1())._ls_index;
                        if (idx >= 0) {
                            phis.add(idx);
                        }
                    }
                }
            }
            if (distFrame == null) {
                distFrame = new ArrayValue[size];
                for (int i = 0; i < size; i++) {
                    if (phis.contains(i)) {
                        ArrayValue aov = new ArrayValue();
                        values.add(aov);
                        aov.s = ArrayValue.S.UNKNOWN;
                        aov.indexType = ArrayValue.IndexType.NONE;
                        aov.stmt = dist;
                        distFrame[i] = aov;
                    } else {
                        ArrayValue arc = srcFrame[i];
                        if (arc != null) {
                            ArrayValue aov = new ArrayValue();
                            values.add(aov);
                            aov.s = ArrayValue.S.INHERIT;
                            aov.indexType = ArrayValue.IndexType.NONE;
                            aov.stmt = dist;
                            aov.parent = arc;
                            distFrame[i] = aov;
                        }
                    }
                }
            } else {
                for (int i = 0; i < size; i++) {
                    if (phis.contains(i)) {
                        continue;
                    }
                    ArrayValue arc = srcFrame[i];
                    ArrayValue aov = distFrame[i];
                    if (arc != null && aov != null) {
                        if (aov.parent == null) {
                            aov.parent = arc;
                        } else if (!aov.parent.equals(arc)) {
                            if (aov.otherParents == null) {
                                aov.otherParents = new HashSet<>();
                            }
                            aov.otherParents.add(arc);
                        }
                    }
                }
            }
            phis.clear();
            return distFrame;
        }

        @Override
        public ArrayValue[] initFirstFrame(Stmt first) {
            return new ArrayValue[size];
        }

        ArrayValue[] tmp = new ArrayValue[size];

        Stmt currentStmt;

        @Override
        public ArrayValue[] exec(ArrayValue[] frame, Stmt stmt) {
            currentStmt = stmt;
            System.arraycopy(frame, 0, tmp, 0, size);
            if (stmt.st == Stmt.ST.ASSIGN) {
                // create an array
                if (stmt.getOp1().vt == Value.VT.LOCAL) {
                    Local local = (Local) stmt.getOp1();
                    use(stmt.getOp2());
                    if (local._ls_index >= 0) {
                        Value op2 = stmt.getOp2();
                        if (op2.vt == Value.VT.NEW_ARRAY) {
                            ArrayValue av = new ArrayValue();
                            av.s = ArrayValue.S.DEFAULT;
                            av.size = op2.getOp();
                            values.add(av);
                            tmp[local._ls_index] = av;
                        } else if (op2.vt == Value.VT.FILLED_ARRAY) {
                            ArrayValue av = new ArrayValue();
                            av.s = ArrayValue.S.DEFAULT;
                            av.indexType = ArrayValue.IndexType.CONST;
                            av.stmt = stmt;
                            FilledArrayExpr fae = (FilledArrayExpr) stmt.getOp2();
                            av.size = Exprs.nInt(fae.getOps().length);
                            Value[] ops = fae.getOps();
                            for (int i = 0; i < ops.length; i++) {
                                av.elements1.put(i, ops[i]);
                            }
                            values.add(av);
                            tmp[local._ls_index] = av;
                        } else if (op2.vt == Value.VT.CONSTANT) {
                            Object cst = ((Constant) op2).value;
                            if (cst != null && !cst.equals(Constant.Null) && cst.getClass().isArray()) {
                                ArrayValue av = new ArrayValue();
                                av.s = ArrayValue.S.DEFAULT;
                                av.indexType = ArrayValue.IndexType.CONST;
                                av.stmt = stmt;
                                int size = Array.getLength(cst);
                                av.size = Exprs.nInt(size);
                                for (int i = 0; i < size; i++) {
                                    av.elements1.put(i, Exprs.nConstant(Array.get(cst, size)));
                                }
                                values.add(av);
                                tmp[local._ls_index] = av;
                            } else {
                                ArrayValue av = new ArrayValue();
                                values.add(av);
                                av.s = ArrayValue.S.UNKNOWN;
                                av.indexType = ArrayValue.IndexType.NONE;
                                av.stmt = stmt;
                                tmp[local._ls_index] = av;
                            }
                        } else {
                            ArrayValue av = new ArrayValue();
                            values.add(av);
                            av.s = ArrayValue.S.UNKNOWN;
                            av.indexType = ArrayValue.IndexType.NONE;
                            av.stmt = stmt;
                            tmp[local._ls_index] = av;
                        }
                    }
                // assign index1
                } else if (stmt.getOp1().vt == Value.VT.ARRAY) {
                    use(stmt.getOp2());
                    ArrayExpr ae = (ArrayExpr) stmt.getOp1();
                    if (ae.getOp1().vt == Value.VT.LOCAL) {
                        Local local = (Local) ae.getOp1();
                        Value index = ae.getOp2();
                        if (local._ls_index >= 0) {
                            if (index.vt == Value.VT.CONSTANT) {
                                ArrayValue parent = tmp[local._ls_index];
                                ArrayValue av = new ArrayValue();
                                values.add(av);
                                av.parent = parent;
                                av.elements1.put(((Number) (((Constant) index).value)).intValue(), stmt.getOp2());
                                av.indexType = ArrayValue.IndexType.CONST;
                                av.s = ArrayValue.S.INHERIT;
                                av.stmt = stmt;
                                tmp[local._ls_index] = av;
                            } else if (index.vt == Value.VT.LOCAL) {
                                ArrayValue parent = tmp[local._ls_index];
                                ArrayValue av = new ArrayValue();
                                values.add(av);
                                av.parent = parent;
                                av.elements1.put(index, stmt.getOp2());
                                av.indexType = ArrayValue.IndexType.LOCAL;
                                av.s = ArrayValue.S.INHERIT;
                                av.stmt = stmt;
                                tmp[local._ls_index] = av;
                            } else {
                                ArrayValue av = new ArrayValue();
                                values.add(av);
                                av.s = ArrayValue.S.UNKNOWN;
                                av.indexType = ArrayValue.IndexType.NONE;
                                av.stmt = stmt;
                                tmp[local._ls_index] = av;
                            }
                        } else {
                            use(stmt.getOp1());
                        }
                    } else {
                        use(stmt.getOp1());
                    }
                } else {
                    use(stmt.getOp1());
                    use(stmt.getOp2());
                }
            // assign index2
            } else if (stmt.st == Stmt.ST.FILL_ARRAY_DATA) {
                if (stmt.getOp1().vt == Value.VT.LOCAL) {
                    Local local = (Local) stmt.getOp1();
                    if (local._ls_index >= 0) {
                        Object array = ((Constant) stmt.getOp2()).value;
                        ArrayValue parent = tmp[local._ls_index];
                        ArrayValue av = new ArrayValue();
                        values.add(av);
                        av.parent = parent;
                        int size = Array.getLength(array);
                        av.size = Exprs.nInt(size);
                        for (int i = 0; i < size; i++) {
                            av.elements1.put(i, Exprs.nConstant(Array.get(array, i)));
                        }
                        av.indexType = ArrayValue.IndexType.CONST;
                        av.s = ArrayValue.S.INHERIT;
                        av.stmt = stmt;
                        tmp[local._ls_index] = av;
                    }
                } else {
                    use(stmt.getOp1());
                }
            } else {
                switch(stmt.et) {
                    case E0:
                        break;
                    case E1:
                        use(stmt.getOp());
                        break;
                    case E2:
                        use(stmt.getOp1());
                        use(stmt.getOp2());
                        break;
                    case En:
                        throw new RuntimeException();
                }
            }
            return tmp;
        }

        private void use(Value v) {
            switch(v.et) {
                case E0:
                    break;
                case E1:
                    use(v.getOp());
                    break;
                case E2:
                    Value op1 = v.getOp1();
                    Value op2 = v.getOp2();
                    use(op1);
                    use(op2);
                    if (v.vt == Value.VT.ARRAY) {
                        if (op1.vt == Value.VT.LOCAL && (op2.vt == Value.VT.LOCAL || op2.vt == Value.VT.CONSTANT)) {
                            Local local = (Local) op1;
                            if (local._ls_index > 0) {
                                used.add(currentStmt);
                            }
                        }
                    }
                    break;
                case En:
                    for (Value op : v.getOps()) {
                        use(op);
                    }
                    break;
            }
        }
    });
    for (Stmt p : method.stmts) {
    }
    new StmtTraveler() {

        @Override
        public Value travel(Value op) {
            op = super.travel(op);
            if (op.vt == Value.VT.ARRAY) {
            }
            return op;
        }
    }.travel(method.stmts);
    return false;
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) Cfg(com.googlecode.dex2jar.ir.ts.Cfg) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt) StmtTraveler(com.googlecode.dex2jar.ir.StmtTraveler)

Example 39 with Stmt

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

the class UnSSATransformerTransformerTest method test01SSAProblem.

@Test
public void test01SSAProblem() {
    initMethod(true, "I");
    Local a = addLocal("a");
    Local b = addLocal("b");
    Local phi = addLocal("p");
    LabelStmt L0 = newLabel();
    addStmt(nAssign(a, nInt(2)));
    addStmt(L0);
    attachPhi(L0, nAssign(phi, nPhi(a, b)));
    Stmt stmt = addStmt(nAssign(b, niAdd(phi, nInt(0))));
    addStmt(nIf(niGt(nInt(100), nInt(0)), L0));
    addStmt(nReturn(phi));
    transform();
    Assert.assertTrue("a new local should introduced to solve the problem", stmt.getPre() != L0);
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) Local(com.googlecode.dex2jar.ir.expr.Local) LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt) Test(org.junit.Test)

Example 40 with Stmt

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

the class UnSSATransformerTransformerTest method test05OneInPhiLoop.

@Test
public void test05OneInPhiLoop() {
    initMethod(true, "V");
    Local a = addLocal("a");
    Local b = addLocal("b");
    Local phi = addLocal("p");
    Stmt s1 = addStmt(nAssign(a, nString("123")));
    LabelStmt L1 = newLabel();
    addStmt(L1);
    attachPhi(L1, nAssign(phi, nPhi(a)));
    addStmt(nVoidInvoke(nInvokeStatic(new Value[] { phi }, "LAAA;", "bMethod", new String[] { "Ljava/lang/String;" }, "V")));
    addStmt(nAssign(b, nString("456")));
    // phi is still live here
    Stmt s2 = addStmt(nVoidInvoke(nInvokeStatic(new Value[] { b }, "LBBB;", "cMethod", new String[] { "Ljava/lang/String;" }, "V")));
    addStmt(nIf(niGt(nInt(100), nInt(0)), L1));
    addStmt(nReturnVoid());
    transform();
    Assert.assertTrue("p=a should inserted", s1.getPre() != L1);
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) Local(com.googlecode.dex2jar.ir.expr.Local) LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt) Test(org.junit.Test)

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