Search in sources :

Example 1 with StmtTraveler

use of com.googlecode.dex2jar.ir.StmtTraveler in project dex2jar by pxb1988.

the class MultiArrayTransformer method transformReportChanged.

@Override
public boolean transformReportChanged(IrMethod method) {
    final boolean[] changed = { false };
    new StmtTraveler() {

        @Override
        public Value travel(Value op) {
            if (op.vt == Value.VT.CHECK_CAST) {
                TypeExpr te = (TypeExpr) op;
                if (te.op.vt == Value.VT.CHECK_CAST) {
                    TypeExpr te2 = (TypeExpr) te.op;
                    if (te.type.equals(te2.type)) {
                        op = te2;
                    }
                }
            }
            op = super.travel(op);
            if (op.vt == Value.VT.CHECK_CAST) {
                TypeExpr te = (TypeExpr) op;
                if (te.type.charAt(0) == '[') {
                    Value from = te.getOp();
                    if (from.vt == Value.VT.INVOKE_STATIC) {
                        InvokeExpr invokeExpr = (InvokeExpr) from;
                        if (invokeExpr.name.equals("newInstance") && invokeExpr.owner.equals("Ljava/lang/reflect/Array;") && invokeExpr.args.length == 2 && invokeExpr.args[0].equals("Ljava/lang/Class;")) {
                            Value arg0 = invokeExpr.getOps()[0];
                            String elementType = null;
                            if (arg0.vt == Value.VT.CONSTANT) {
                                elementType = ((Constant.Type) ((Constant) invokeExpr.getOps()[0]).value).desc;
                            } else {
                                if (arg0.vt == Value.VT.STATIC_FIELD) {
                                    StaticFieldExpr sfe = (StaticFieldExpr) arg0;
                                    if (sfe.owner.startsWith("Ljava/lang/") && sfe.name.equals("TYPE")) {
                                        switch(sfe.owner) {
                                            case "Ljava/lang/Boolean;":
                                                elementType = "Z";
                                                break;
                                            case "Ljava/lang/Byte;":
                                                elementType = "B";
                                                break;
                                            case "Ljava/lang/Short;":
                                                elementType = "S";
                                                break;
                                            case "Ljava/lang/Character;":
                                                elementType = "C";
                                                break;
                                            case "Ljava/lang/Integer;":
                                                elementType = "I";
                                                break;
                                            case "Ljava/lang/Long;":
                                                elementType = "J";
                                                break;
                                            case "Ljava/lang/Float;":
                                                elementType = "F";
                                                break;
                                            case "Ljava/lang/Double;":
                                                elementType = "D";
                                                break;
                                            case "Ljava/lang/Void;":
                                                elementType = "V";
                                                break;
                                            default:
                                        }
                                    }
                                }
                            }
                            if (elementType != null) {
                                Value dt = invokeExpr.getOps()[1];
                                if (invokeExpr.args[1].equals("I")) {
                                    if (te.type.equals("[" + elementType)) {
                                        int d = 0;
                                        while (elementType.charAt(d) == '[') {
                                            d++;
                                        }
                                        changed[0] = true;
                                        if (d > 0) {
                                            return Exprs.nNewMutiArray(elementType.substring(d), d + 1, new Value[] { dt });
                                        } else {
                                            return Exprs.nNewArray(elementType, dt);
                                        }
                                    }
                                } else {
                                    // [I
                                    if (dt.vt == Value.VT.FILLED_ARRAY) {
                                        FilledArrayExpr filledArrayExpr = (FilledArrayExpr) dt;
                                        int d = filledArrayExpr.getOps().length;
                                        if (te.type.length() > d && te.type.substring(d).equals(elementType)) {
                                            int d1 = 0;
                                            while (elementType.charAt(d1) == '[') {
                                                d1++;
                                            }
                                            changed[0] = true;
                                            return Exprs.nNewMutiArray(elementType.substring(d1), d1 + d, filledArrayExpr.getOps());
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return op;
        }
    }.travel(method);
    return changed[0];
}
Also used : StmtTraveler(com.googlecode.dex2jar.ir.StmtTraveler)

Example 2 with StmtTraveler

use of com.googlecode.dex2jar.ir.StmtTraveler in project dex2jar by pxb1988.

the class NewTransformer method makeSureUsedBeforeConstructor.

void makeSureUsedBeforeConstructor(IrMethod method, final Map<Local, TObject> init, final int size) {
    Cfg.createCFG(method);
    Cfg.dfs(method.stmts, new Cfg.FrameVisitor<Vx[]>() {

        boolean keepFrame = false;

        Vx[] tmp = new Vx[size];

        StmtTraveler stmtTraveler = new StmtTraveler() {

            Stmt current;

            @Override
            public Stmt travel(Stmt stmt) {
                this.current = stmt;
                if (stmt.et == ET.E2) {
                    if (stmt.getOp1().vt == LOCAL) {
                        Local op1 = (Local) stmt.getOp1();
                        if (stmt.getOp2().vt == LOCAL) {
                            Local op2 = (Local) stmt.getOp2();
                            tmp[op1._ls_index] = tmp[op2._ls_index];
                            return stmt;
                        } else if (stmt.getOp2().vt == NEW) {
                            tmp[op1._ls_index] = new Vx(init.get(op1), false);
                            return stmt;
                        } else {
                            travel(stmt.getOp2());
                            tmp[op1._ls_index] = IGNORED;
                            return stmt;
                        }
                    }
                }
                if (stmt.st == LABEL) {
                    LabelStmt labelStmt = (LabelStmt) stmt;
                    if (labelStmt.phis != null) {
                        for (AssignStmt phi : labelStmt.phis) {
                            Local local = (Local) phi.getOp1();
                            tmp[local._ls_index] = IGNORED;
                        }
                    }
                    return stmt;
                }
                return super.travel(stmt);
            }

            @Override
            public Value travel(Value op) {
                if (op.vt == INVOKE_SPECIAL) {
                    if (op.getOps().length >= 1) {
                        InvokeExpr ie = (InvokeExpr) op;
                        if ("<init>".equals(ie.name)) {
                            Value thiz = op.getOps()[0];
                            if (thiz.vt == LOCAL) {
                                Local local = (Local) thiz;
                                Vx vx = tmp[local._ls_index];
                                TObject object = vx.obj;
                                if (object != null) {
                                    if (object.invokeStmt != null) {
                                        object.useBeforeInit = true;
                                    } else {
                                        vx.init = true;
                                        object.invokeStmt = current;
                                        for (int i = 0; i < tmp.length; i++) {
                                            Vx s = tmp[i];
                                            if (s != null && s.obj == object) {
                                                tmp[i] = IGNORED;
                                            }
                                        }
                                        keepFrame = true;
                                    }
                                }
                            }
                        }
                    }
                }
                op = super.travel(op);
                if (op.vt == LOCAL) {
                    use((Local) op);
                }
                return op;
            }
        };

        @Override
        public Vx[] merge(Vx[] srcFrame, Vx[] distFrame, Stmt src, Stmt dist) {
            if (distFrame == null) {
                distFrame = new Vx[size];
                System.arraycopy(srcFrame, 0, distFrame, 0, size);
            } else {
                for (int i = 0; i < size; i++) {
                    Vx s = srcFrame[i];
                    Vx d = distFrame[i];
                    if (s != null) {
                        if (d == null) {
                            distFrame[i] = s;
                        } else {
                            if (s != d) {
                                TObject obj = s.obj;
                                if (obj != null) {
                                    obj.useBeforeInit = true;
                                }
                                obj = d.obj;
                                if (obj != null) {
                                    obj.useBeforeInit = true;
                                }
                            }
                        }
                    }
                }
            }
            if (dist.st == LABEL) {
                List<AssignStmt> phis = ((LabelStmt) dist).phis;
                if (phis != null && phis.size() > 0) {
                    for (AssignStmt phi : phis) {
                        for (Value value : phi.getOp2().getOps()) {
                            Local local = (Local) value;
                            int i = local._ls_index;
                            Vx s = srcFrame[i];
                            Vx d = distFrame[i];
                            if (d != null) {
                                if (!d.init) {
                                    TObject obj = d.obj;
                                    if (obj != null) {
                                        obj.useBeforeInit = true;
                                    }
                                }
                            } else if (s != null) {
                                if (!s.init) {
                                    TObject obj = s.obj;
                                    if (obj != null) {
                                        obj.useBeforeInit = true;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return distFrame;
        }

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

        @Override
        public Vx[] exec(Vx[] frame, Stmt stmt) {
            keepFrame = false;
            System.arraycopy(frame, 0, tmp, 0, size);
            stmtTraveler.travel(stmt);
            if (stmt._cfg_froms.size() > 1) {
                keepFrame = true;
            }
            if (!keepFrame) {
                stmt.frame = null;
            }
            return tmp;
        }

        void use(Local local) {
            Vx vx = tmp[local._ls_index];
            if (!vx.init) {
                TObject object = vx.obj;
                if (object != null) {
                    object.useBeforeInit = true;
                }
                tmp[local._ls_index] = IGNORED;
            }
        }
    });
    for (Iterator<Map.Entry<Local, TObject>> iterator = init.entrySet().iterator(); iterator.hasNext(); ) {
        Map.Entry<Local, TObject> e = iterator.next();
        boolean keep = true;
        TObject obj = e.getValue();
        if (obj.useBeforeInit) {
            keep = false;
        }
        if (obj.invokeStmt == null) {
            keep = false;
        }
        if (!keep) {
            iterator.remove();
        }
    }
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) 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 3 with StmtTraveler

use of com.googlecode.dex2jar.ir.StmtTraveler 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 4 with StmtTraveler

use of com.googlecode.dex2jar.ir.StmtTraveler in project dex2jar by pxb1988.

the class DecryptStringCmd method optAndDecrypt.

public void optAndDecrypt(IrMethod irMethod, final Map<MethodConfig, MethodConfig> map) {
    T_deadCode.transform(irMethod);
    T_cleanLabel.transform(irMethod);
    T_removeLocal.transform(irMethod);
    T_removeConst.transform(irMethod);
    T_zero.transform(irMethod);
    if (T_npe.transformReportChanged(irMethod)) {
        T_deadCode.transform(irMethod);
        T_removeLocal.transform(irMethod);
        T_removeConst.transform(irMethod);
    }
    T_new.transform(irMethod);
    T_fillArray.transform(irMethod);
    T_agg.transform(irMethod);
    T_voidInvoke.transform(irMethod);
    new StmtTraveler() {

        @Override
        public Value travel(Value op) {
            op = super.travel(op);
            if (op.vt == Value.VT.INVOKE_STATIC) {
                InvokeExpr ie = (InvokeExpr) op;
                MethodConfig key = DecryptStringCmd.this.key;
                key.owner = ie.owner.substring(1, ie.owner.length() - 1);
                key.name = ie.name;
                key.desc = buildMethodDesc(ie.args, ie.ret);
                MethodConfig c = map.get(key);
                if (c != null) {
                    try {
                        Method jmethod = c.jmethod;
                        if (ie.args.length != jmethod.getParameterTypes().length) {
                            throw new RuntimeException();
                        }
                        Object[] args = new Object[ie.args.length];
                        for (int i = 0; i < args.length; i++) {
                            args[i] = convertIr2Jobj(ie.getOps()[i], ie.args[i]);
                        }
                        if (verbose) {
                            System.out.println(" > calling " + jmethod + " with arguments " + v(args));
                        }
                        String str = (String) jmethod.invoke(null, args);
                        if (verbose) {
                            System.out.println("  -> " + Escape.v(str));
                        }
                        return Exprs.nString(str);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            return op;
        }
    }.travel(irMethod.stmts);
    T_type.transform(irMethod);
    T_unssa.transform(irMethod);
    T_trimEx.transform(irMethod);
    T_ir2jRegAssign.transform(irMethod);
}
Also used : StmtTraveler(com.googlecode.dex2jar.ir.StmtTraveler) Method(java.lang.reflect.Method) IrMethod(com.googlecode.dex2jar.ir.IrMethod) IOException(java.io.IOException) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Example 5 with StmtTraveler

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

Aggregations

StmtTraveler (com.googlecode.dex2jar.ir.StmtTraveler)5 AssignStmt (com.googlecode.dex2jar.ir.stmt.AssignStmt)2 LabelStmt (com.googlecode.dex2jar.ir.stmt.LabelStmt)2 Stmt (com.googlecode.dex2jar.ir.stmt.Stmt)2 IrMethod (com.googlecode.dex2jar.ir.IrMethod)1 Constant (com.googlecode.dex2jar.ir.expr.Constant)1 Local (com.googlecode.dex2jar.ir.expr.Local)1 Value (com.googlecode.dex2jar.ir.expr.Value)1 Cfg (com.googlecode.dex2jar.ir.ts.Cfg)1 IOException (java.io.IOException)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 Method (java.lang.reflect.Method)1