Search in sources :

Example 21 with AssignStmt

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

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

the class TypeTransformerTest method test1Const.

@Test
public void test1Const() {
    initMethod(true, "F");
    Local b = addLocal("b");
    AssignStmt st1 = addStmt(nAssign(b, nInt(0)));
    UnopStmt st3 = addStmt(nReturn(b));
    transform();
    Assert.assertEquals("", b.valueType, "F");
}
Also used : AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Local(com.googlecode.dex2jar.ir.expr.Local) UnopStmt(com.googlecode.dex2jar.ir.stmt.UnopStmt) Test(org.junit.Test)

Aggregations

AssignStmt (com.googlecode.dex2jar.ir.stmt.AssignStmt)22 LabelStmt (com.googlecode.dex2jar.ir.stmt.LabelStmt)18 Stmt (com.googlecode.dex2jar.ir.stmt.Stmt)13 Local (com.googlecode.dex2jar.ir.expr.Local)12 Value (com.googlecode.dex2jar.ir.expr.Value)11 ArrayList (java.util.ArrayList)6 JumpStmt (com.googlecode.dex2jar.ir.stmt.JumpStmt)4 StmtList (com.googlecode.dex2jar.ir.stmt.StmtList)3 Cfg (com.googlecode.dex2jar.ir.ts.Cfg)3 List (java.util.List)3 StmtTraveler (com.googlecode.dex2jar.ir.StmtTraveler)2 PhiExpr (com.googlecode.dex2jar.ir.expr.PhiExpr)2 HashSet (java.util.HashSet)2 Trap (com.googlecode.dex2jar.ir.Trap)1 Constant (com.googlecode.dex2jar.ir.expr.Constant)1 UnopStmt (com.googlecode.dex2jar.ir.stmt.UnopStmt)1 AnalyzeValue (com.googlecode.dex2jar.ir.ts.an.AnalyzeValue)1 HashMap (java.util.HashMap)1 Test (org.junit.Test)1