Search in sources :

Example 31 with LabelStmt

use of com.googlecode.dex2jar.ir.stmt.LabelStmt 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 32 with LabelStmt

use of com.googlecode.dex2jar.ir.stmt.LabelStmt 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 33 with LabelStmt

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

the class TypeTransformerTest method test3.

// @Ignore("type b to Int is ok to this context")
@Test
public void test3() {
    initMethod(true, "V");
    Local b = addLocal("b");
    addStmt(nAssign(b, nInt(456)));
    LabelStmt L0 = newLabel();
    addStmt(nIf(nEq(b, nInt(0), TypeClass.ZIFL.name), L0));
    addStmt(L0);
    addStmt(nReturnVoid());
    transform();
    Assert.assertEquals("", "I", b.valueType);
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) Local(com.googlecode.dex2jar.ir.expr.Local) Test(org.junit.Test)

Example 34 with LabelStmt

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

the class UnSSATransformerTransformerTest method test02_3branches.

@Test
public void test02_3branches() {
    initMethod(true, "I");
    Local a = addLocal("a");
    Local b = addLocal("b");
    Local c = addLocal("c");
    Local d = addLocal("d");
    Local phi = addLocal("p");
    LabelStmt L0 = newLabel();
    LabelStmt L1 = newLabel();
    addStmt(nAssign(a, nInt(2)));
    addStmt(nIf(niGt(nInt(100), nInt(0)), L1));
    addStmt(nAssign(b, nInt(3)));
    addStmt(nIf(niGt(nInt(100), nInt(0)), L0));
    addStmt(nAssign(c, nInt(4)));
    addStmt(nLock(c));
    addStmt(nGoto(L1));
    addStmt(L0);
    addStmt(nAssign(d, nInt(5)));
    addStmt(nLock(d));
    addStmt(L1);
    attachPhi(L1, nAssign(phi, nPhi(a, b)));
    addStmt(nReturn(phi));
    transform();
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) Local(com.googlecode.dex2jar.ir.expr.Local) Test(org.junit.Test)

Example 35 with LabelStmt

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

the class UnSSATransformerTransformerTest method test06TwoJump.

@Test
public void test06TwoJump() {
    initMethod(true, "V");
    Local a1 = addLocal("a1");
    Local a2 = addLocal("a2");
    Local a = addLocal("a");
    Local b1 = addLocal("b1");
    Local b2 = addLocal("b2");
    Local b = addLocal("b");
    addStmt(nAssign(a1, nString("123")));
    addStmt(nAssign(b1, nString("123")));
    LabelStmt L1 = newLabel();
    addStmt(L1);
    attachPhi(L1, nAssign(a, nPhi(a1, a2)));
    attachPhi(L1, nAssign(b, nPhi(b1, b2)));
    addStmt(nAssign(a2, nString("456")));
    addStmt(nIf(niGt(nInt(100), nInt(0)), L1));
    addStmt(nAssign(b2, nString("456")));
    addStmt(nIf(niGt(nInt(100), nInt(0)), L1));
    addStmt(nReturnVoid());
    transform();
// Assert.assertTrue("must assign different index", ls1._ls_index != ls2._ls_index);
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) Local(com.googlecode.dex2jar.ir.expr.Local) Test(org.junit.Test)

Aggregations

LabelStmt (com.googlecode.dex2jar.ir.stmt.LabelStmt)39 Local (com.googlecode.dex2jar.ir.expr.Local)26 Stmt (com.googlecode.dex2jar.ir.stmt.Stmt)22 AssignStmt (com.googlecode.dex2jar.ir.stmt.AssignStmt)17 Test (org.junit.Test)14 Value (com.googlecode.dex2jar.ir.expr.Value)8 ArrayList (java.util.ArrayList)7 Trap (com.googlecode.dex2jar.ir.Trap)4 JumpStmt (com.googlecode.dex2jar.ir.stmt.JumpStmt)4 StmtList (com.googlecode.dex2jar.ir.stmt.StmtList)4 List (java.util.List)3 StmtTraveler (com.googlecode.dex2jar.ir.StmtTraveler)2 PhiExpr (com.googlecode.dex2jar.ir.expr.PhiExpr)2 Cfg (com.googlecode.dex2jar.ir.ts.Cfg)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 IrMethod (com.googlecode.dex2jar.ir.IrMethod)1 LabelAndLocalMapper (com.googlecode.dex2jar.ir.LabelAndLocalMapper)1