Search in sources :

Example 1 with Field

use of com.googlecode.d2j.Field in project dex2jar by pxb1988.

the class DexWeaver method buildInvocationClz.

public String buildInvocationClz(DexFileVisitor dfv) {
    String typeName = getCurrentInvocationName();
    String typeNameDesc = "L" + typeName + ";";
    DexClassVisitor dcv = dfv.visit(DexConstants.ACC_PUBLIC, typeNameDesc, "Ljava/lang/Object;", new String[] { invocationInterfaceDesc });
    dcv.visitField(DexConstants.ACC_PRIVATE | DexConstants.ACC_FINAL, new Field(typeNameDesc, "thiz", "Ljava/lang/Object;"), null).visitEnd();
    dcv.visitField(DexConstants.ACC_PRIVATE | DexConstants.ACC_FINAL, new Field(typeNameDesc, "args", "[Ljava/lang/Object;"), null).visitEnd();
    dcv.visitField(DexConstants.ACC_PRIVATE | DexConstants.ACC_FINAL, new Field(typeNameDesc, "idx", "I"), null).visitEnd();
    {
        DexMethodVisitor mv = dcv.visitMethod(DexConstants.ACC_PUBLIC | DexConstants.ACC_CONSTRUCTOR, new Method(typeNameDesc, "<init>", new String[] { "Ljava/lang/Object;", "[Ljava/lang/Object;", "I" }, "V"));
        DexCodeVisitor codeVisitor = mv.visitCode();
        codeVisitor.visitRegister(4);
        codeVisitor.visitFieldStmt(Op.IPUT_OBJECT, 1, 0, new Field(typeNameDesc, "thiz", "Ljava/lang/Object;"));
        codeVisitor.visitFieldStmt(Op.IPUT_OBJECT, 2, 0, new Field(typeNameDesc, "args", "[Ljava/lang/Object;"));
        codeVisitor.visitFieldStmt(Op.IPUT, 3, 0, new Field(typeNameDesc, "idx", "I"));
        codeVisitor.visitStmt0R(Op.RETURN_VOID);
        codeVisitor.visitEnd();
        mv.visitEnd();
    }
    {
        genSwitchMethod(dcv, typeNameDesc, "getMethodOwner", new CB() {

            @Override
            public String getKey(Method mtd) {
                return toInternal(mtd.getOwner());
            }
        });
        genSwitchMethod(dcv, typeNameDesc, "getMethodName", new CB() {

            @Override
            public String getKey(Method mtd) {
                return mtd.getName();
            }
        });
        genSwitchMethod(dcv, typeNameDesc, "getMethodDesc", new CB() {

            @Override
            public String getKey(Method mtd) {
                return mtd.getDesc();
            }
        });
    }
    {
        DexMethodVisitor mv = dcv.visitMethod(DexConstants.ACC_PUBLIC, new Method(typeNameDesc, "getArguments", new String[0], "[Ljava/lang/Object;"));
        DexCodeVisitor code = mv.visitCode();
        code.visitRegister(2);
        code.visitFieldStmt(Op.IGET, 0, 1, new Field(typeNameDesc, "args", "[Ljava/lang/Object;"));
        code.visitStmt1R(Op.RETURN_OBJECT, 0);
        code.visitEnd();
        mv.visitEnd();
    }
    {
        DexMethodVisitor mv = dcv.visitMethod(DexConstants.ACC_PUBLIC, new Method(typeNameDesc, "getThis", new String[0], "Ljava/lang/Object;"));
        DexCodeVisitor code = mv.visitCode();
        code.visitRegister(2);
        code.visitFieldStmt(Op.IGET, 0, 1, new Field(typeNameDesc, "thiz", "Ljava/lang/Object;"));
        code.visitStmt1R(Op.RETURN_OBJECT, 0);
        code.visitEnd();
        mv.visitEnd();
    }
    {
        DexMethodVisitor mv = dcv.visitMethod(DexConstants.ACC_PUBLIC, new Method(typeNameDesc, "proceed", new String[0], "Ljava/lang/Object;"));
        DexCodeVisitor code = mv.visitCode();
        code.visitRegister(4);
        code.visitFieldStmt(Op.IGET, 0, 3, new Field(typeNameDesc, "thiz", "Ljava/lang/Object;"));
        code.visitFieldStmt(Op.IGET, 1, 3, new Field(typeNameDesc, "args", "[Ljava/lang/Object;"));
        code.visitFieldStmt(Op.IGET, 2, 3, new Field(typeNameDesc, "idx", "I"));
        DexLabel[] labels = new DexLabel[callbacks.size()];
        for (int i = 0; i < labels.length; i++) {
            labels[i] = new DexLabel();
        }
        code.visitPackedSwitchStmt(Op.PACKED_SWITCH, 2, 0, labels);
        code.visitTypeStmt(Op.NEW_INSTANCE, 0, 0, "Ljava/lang/RuntimeException;");
        code.visitConstStmt(Op.CONST_STRING, 1, "invalid idx");
        code.visitMethodStmt(Op.INVOKE_DIRECT, new int[] { 0, 1 }, new Method("Ljava/lang/RuntimeException;", "<init>", new String[] { "Ljava/lang/String;" }, "V"));
        code.visitStmt1R(Op.THROW, 0);
        for (int i = 0; i < labels.length; i++) {
            code.visitLabel(labels[i]);
            Callback callback = callbacks.get(i);
            Method mCallback = (Method) callback.callback;
            if (callback.isStatic) {
                code.visitMethodStmt(Op.INVOKE_STATIC, new int[] { 1 }, mCallback);
            } else if (callback.isSpecial) {
                code.visitTypeStmt(Op.CHECK_CAST, 0, -1, mCallback.getOwner());
                code.visitMethodStmt(Op.INVOKE_VIRTUAL, new int[] { 0, 1 }, mCallback);
            } else {
                code.visitMethodStmt(Op.INVOKE_STATIC, new int[] { 0, 1 }, mCallback);
            }
            code.visitStmt1R(Op.MOVE_RESULT_OBJECT, 0);
            code.visitStmt1R(Op.RETURN_OBJECT, 0);
        }
        code.visitEnd();
        mv.visitEnd();
    }
    dcv.visitEnd();
    return typeName;
}
Also used : Field(com.googlecode.d2j.Field) DexCodeVisitor(com.googlecode.d2j.visitors.DexCodeVisitor) DexLabel(com.googlecode.d2j.DexLabel) Method(com.googlecode.d2j.Method) DexClassVisitor(com.googlecode.d2j.visitors.DexClassVisitor) DexMethodVisitor(com.googlecode.d2j.visitors.DexMethodVisitor)

Example 2 with Field

use of com.googlecode.d2j.Field in project dex2jar by pxb1988.

the class AsmfierTest method test.

@Test
public void test() {
    ASMifierFileV fv = new ASMifierFileV(new File("target/asmftest").toPath(), "a.b");
    DexClassVisitor cv = fv.visit(ACC_PUBLIC, "La/f;", "Ljava/lang/Object;", null);
    DexFieldVisitor f2v = cv.visitField(ACC_PUBLIC, new Field("La/f;", "abc", "I"), null);
    f2v.visitEnd();
    DexMethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, new Method("La/f;", "zz", new String[0], "I"));
    DexAnnotationAble pv = mv.visitParameterAnnotation(2);
    DexAnnotationVisitor dav = pv.visitAnnotation("Leeeff;", Visibility.BUILD);
    dav.visitEnd();
    DexCodeVisitor dcv = mv.visitCode();
    dcv.visitConstStmt(Op.FILL_ARRAY_DATA, 0, new int[] { 1, 2, 3 });
    dcv.visitStmt0R(Op.RETURN_VOID);
    dcv.visitEnd();
    mv.visitEnd();
    cv.visitEnd();
    fv.visitEnd();
}
Also used : Field(com.googlecode.d2j.Field) ASMifierFileV(com.googlecode.d2j.util.ASMifierFileV) DexAnnotationAble(com.googlecode.d2j.visitors.DexAnnotationAble) DexFieldVisitor(com.googlecode.d2j.visitors.DexFieldVisitor) DexAnnotationVisitor(com.googlecode.d2j.visitors.DexAnnotationVisitor) DexCodeVisitor(com.googlecode.d2j.visitors.DexCodeVisitor) Method(com.googlecode.d2j.Method) DexClassVisitor(com.googlecode.d2j.visitors.DexClassVisitor) File(java.io.File) DexMethodVisitor(com.googlecode.d2j.visitors.DexMethodVisitor) Test(org.junit.Test)

Example 3 with Field

use of com.googlecode.d2j.Field in project dex2jar by pxb1988.

the class DexAnnotationNode method acceptAnnotationItem.

public static void acceptAnnotationItem(DexAnnotationVisitor dav, String name, Object o) {
    if (o instanceof Object[]) {
        DexAnnotationVisitor arrayVisitor = dav.visitArray(name);
        if (arrayVisitor != null) {
            Object[] array = (Object[]) o;
            for (Object e : array) {
                acceptAnnotationItem(arrayVisitor, null, e);
            }
            arrayVisitor.visitEnd();
        }
    } else if (o instanceof DexAnnotationNode) {
        DexAnnotationNode ann = (DexAnnotationNode) o;
        DexAnnotationVisitor av = dav.visitAnnotation(name, ann.type);
        if (av != null) {
            for (DexAnnotationNode.Item item : ann.items) {
                acceptAnnotationItem(av, item.name, item.value);
            }
            av.visitEnd();
        }
    } else if (o instanceof Field) {
        Field f = (Field) o;
        dav.visitEnum(name, f.getType(), f.getName());
    } else {
        dav.visit(name, o);
    }
}
Also used : Field(com.googlecode.d2j.Field) DexAnnotationVisitor(com.googlecode.d2j.visitors.DexAnnotationVisitor)

Example 4 with Field

use of com.googlecode.d2j.Field in project dex2jar by pxb1988.

the class Dex2IRConverter method buildInterpreter.

private DvmInterpreter<DvmValue> buildInterpreter() {
    return new DvmInterpreter<DvmValue>() {

        DvmValue b(com.googlecode.dex2jar.ir.expr.Value value) {
            Local local = newLocal();
            emit(Stmts.nAssign(local, value));
            return new DvmValue(local);
        }

        @Override
        public DvmValue newOperation(DexStmtNode insn) {
            switch(insn.op) {
                case CONST:
                case CONST_16:
                case CONST_4:
                case CONST_HIGH16:
                    return b(nInt((Integer) ((ConstStmtNode) insn).value));
                case CONST_WIDE:
                case CONST_WIDE_16:
                case CONST_WIDE_32:
                case CONST_WIDE_HIGH16:
                    return b(nLong((Long) ((ConstStmtNode) insn).value));
                case CONST_CLASS:
                    return b(nType(((DexType) ((ConstStmtNode) insn).value).desc));
                case CONST_STRING:
                case CONST_STRING_JUMBO:
                    return b(nString((String) ((ConstStmtNode) insn).value));
                case SGET:
                case SGET_BOOLEAN:
                case SGET_BYTE:
                case SGET_CHAR:
                case SGET_OBJECT:
                case SGET_SHORT:
                case SGET_WIDE:
                    Field field = ((FieldStmtNode) insn).field;
                    return b(nStaticField(field.getOwner(), field.getName(), field.getType()));
                case NEW_INSTANCE:
                    return b(nNew(((TypeStmtNode) insn).type));
                default:
            }
            return null;
        }

        @Override
        public DvmValue copyOperation(DexStmtNode insn, DvmValue value) {
            if (value == null) {
                emitNotFindOperand(insn);
                return b(nInt(0));
            }
            return b(getLocal(value));
        }

        @Override
        public DvmValue unaryOperation(DexStmtNode insn, DvmValue value) {
            if (value == null) {
                emitNotFindOperand(insn);
                return b(nInt(0));
            }
            Local local = getLocal(value);
            switch(insn.op) {
                case NOT_INT:
                    return b(nNot(local, "I"));
                case NOT_LONG:
                    return b(nNot(local, "J"));
                case NEG_DOUBLE:
                    return b(nNeg(local, "D"));
                case NEG_FLOAT:
                    return b(nNeg(local, "F"));
                case NEG_INT:
                    return b(nNeg(local, "I"));
                case NEG_LONG:
                    return b(nNeg(local, "J"));
                case INT_TO_BYTE:
                    return b(nCast(local, "I", "B"));
                case INT_TO_CHAR:
                    return b(nCast(local, "I", "C"));
                case INT_TO_DOUBLE:
                    return b(nCast(local, "I", "D"));
                case INT_TO_FLOAT:
                    return b(nCast(local, "I", "F"));
                case INT_TO_LONG:
                    return b(nCast(local, "I", "J"));
                case INT_TO_SHORT:
                    return b(nCast(local, "I", "S"));
                case FLOAT_TO_DOUBLE:
                    return b(nCast(local, "F", "D"));
                case FLOAT_TO_INT:
                    return b(nCast(local, "F", "I"));
                case FLOAT_TO_LONG:
                    return b(nCast(local, "F", "J"));
                case DOUBLE_TO_FLOAT:
                    return b(nCast(local, "D", "F"));
                case DOUBLE_TO_INT:
                    return b(nCast(local, "D", "I"));
                case DOUBLE_TO_LONG:
                    return b(nCast(local, "D", "J"));
                case LONG_TO_DOUBLE:
                    return b(nCast(local, "J", "D"));
                case LONG_TO_FLOAT:
                    return b(nCast(local, "J", "F"));
                case LONG_TO_INT:
                    return b(nCast(local, "J", "I"));
                case ARRAY_LENGTH:
                    return b(nLength(local));
                case IF_EQZ:
                    emit(nIf(Exprs.nEq(local, nInt(0), TypeClass.ZIL.name), getLabel(((JumpStmtNode) insn).label)));
                    return null;
                case IF_GEZ:
                    emit(nIf(Exprs.nGe(local, nInt(0), "I"), getLabel(((JumpStmtNode) insn).label)));
                    return null;
                case IF_GTZ:
                    emit(nIf(Exprs.nGt(local, nInt(0), "I"), getLabel(((JumpStmtNode) insn).label)));
                    return null;
                case IF_LEZ:
                    emit(nIf(Exprs.nLe(local, nInt(0), "I"), getLabel(((JumpStmtNode) insn).label)));
                    return null;
                case IF_LTZ:
                    emit(nIf(Exprs.nLt(local, nInt(0), "I"), getLabel(((JumpStmtNode) insn).label)));
                    return null;
                case IF_NEZ:
                    emit(nIf(Exprs.nNe(local, nInt(0), TypeClass.ZIL.name), getLabel(((JumpStmtNode) insn).label)));
                    return null;
                case PACKED_SWITCH:
                case SPARSE_SWITCH:
                    DexLabel[] labels = ((BaseSwitchStmtNode) insn).labels;
                    LabelStmt[] lss = new LabelStmt[labels.length];
                    for (int i = 0; i < labels.length; i++) {
                        lss[i] = getLabel(labels[i]);
                    }
                    LabelStmt d = new LabelStmt();
                    if (insn.op == Op.PACKED_SWITCH) {
                        emit(nTableSwitch(local, ((PackedSwitchStmtNode) insn).first_case, lss, d));
                    } else {
                        emit(nLookupSwitch(local, ((SparseSwitchStmtNode) insn).cases, lss, d));
                    }
                    emit(d);
                    return null;
                case SPUT:
                case SPUT_BOOLEAN:
                case SPUT_BYTE:
                case SPUT_CHAR:
                case SPUT_OBJECT:
                case SPUT_SHORT:
                case SPUT_WIDE:
                    {
                        Field field = ((FieldStmtNode) insn).field;
                        emit(nAssign(nStaticField(field.getOwner(), field.getName(), field.getType()), local));
                        return null;
                    }
                case IGET:
                case IGET_BOOLEAN:
                case IGET_BYTE:
                case IGET_CHAR:
                case IGET_OBJECT:
                case IGET_SHORT:
                case IGET_WIDE:
                    {
                        Field field = ((FieldStmtNode) insn).field;
                        return b(nField(local, field.getOwner(), field.getName(), field.getType()));
                    }
                case INSTANCE_OF:
                    return b(nInstanceOf(local, ((TypeStmtNode) insn).type));
                case NEW_ARRAY:
                    return b(nNewArray(((TypeStmtNode) insn).type.substring(1), local));
                case CHECK_CAST:
                    return b(nCheckCast(local, ((TypeStmtNode) insn).type));
                case MONITOR_ENTER:
                    emit(nLock(local));
                    return null;
                case MONITOR_EXIT:
                    emit(nUnLock(local));
                    return null;
                case THROW:
                    emit(nThrow(local));
                    return null;
                case ADD_INT_LIT16:
                case ADD_INT_LIT8:
                    return b(nAdd(local, nInt(((Stmt2R1NNode) insn).content), "I"));
                case RSUB_INT_LIT8:
                case //
                RSUB_INT:
                    return b(nSub(nInt(((Stmt2R1NNode) insn).content), local, "I"));
                case MUL_INT_LIT8:
                case MUL_INT_LIT16:
                    return b(nMul(local, nInt(((Stmt2R1NNode) insn).content), "I"));
                case DIV_INT_LIT16:
                case DIV_INT_LIT8:
                    return b(nDiv(local, nInt(((Stmt2R1NNode) insn).content), "I"));
                case REM_INT_LIT16:
                case REM_INT_LIT8:
                    return b(nRem(local, nInt(((Stmt2R1NNode) insn).content), "I"));
                case AND_INT_LIT16:
                case AND_INT_LIT8:
                    return b(nAnd(local, nInt(((Stmt2R1NNode) insn).content), ((Stmt2R1NNode) insn).content < 0 || ((Stmt2R1NNode) insn).content > 1 ? "I" : TypeClass.ZI.name));
                case OR_INT_LIT16:
                case OR_INT_LIT8:
                    return b(nOr(local, nInt(((Stmt2R1NNode) insn).content), ((Stmt2R1NNode) insn).content < 0 || ((Stmt2R1NNode) insn).content > 1 ? "I" : TypeClass.ZI.name));
                case XOR_INT_LIT16:
                case XOR_INT_LIT8:
                    return b(nXor(local, nInt(((Stmt2R1NNode) insn).content), ((Stmt2R1NNode) insn).content < 0 || ((Stmt2R1NNode) insn).content > 1 ? "I" : TypeClass.ZI.name));
                case SHL_INT_LIT8:
                    return b(nShl(local, nInt(((Stmt2R1NNode) insn).content), "I"));
                case SHR_INT_LIT8:
                    return b(nShr(local, nInt(((Stmt2R1NNode) insn).content), "I"));
                case USHR_INT_LIT8:
                    return b(nUshr(local, nInt(((Stmt2R1NNode) insn).content), "I"));
                case FILL_ARRAY_DATA:
                    emit(nFillArrayData(local, nArrayValue(((FillArrayDataStmtNode) insn).array)));
                    return null;
            }
            throw new RuntimeException();
        }

        @Override
        public DvmValue binaryOperation(DexStmtNode insn, DvmValue value1, DvmValue value2) {
            if (value1 == null || value2 == null) {
                emitNotFindOperand(insn);
                return b(nInt(0));
            }
            Local local1 = getLocal(value1);
            Local local2 = getLocal(value2);
            switch(insn.op) {
                case AGET:
                    return b(nArray(local1, local2, TypeClass.IF.name));
                case AGET_BOOLEAN:
                    return b(nArray(local1, local2, "Z"));
                case AGET_BYTE:
                    return b(nArray(local1, local2, "B"));
                case AGET_CHAR:
                    return b(nArray(local1, local2, "C"));
                case AGET_OBJECT:
                    return b(nArray(local1, local2, "L"));
                case AGET_SHORT:
                    return b(nArray(local1, local2, "S"));
                case AGET_WIDE:
                    return b(nArray(local1, local2, TypeClass.JD.name));
                case CMP_LONG:
                    return b(nLCmp(local1, local2));
                case CMPG_DOUBLE:
                    return b(nDCmpg(local1, local2));
                case CMPG_FLOAT:
                    return b(nFCmpg(local1, local2));
                case CMPL_DOUBLE:
                    return b(nDCmpl(local1, local2));
                case CMPL_FLOAT:
                    return b(nFCmpl(local1, local2));
                case ADD_DOUBLE:
                    return b(nAdd(local1, local2, "D"));
                case ADD_FLOAT:
                    return b(nAdd(local1, local2, "F"));
                case ADD_INT:
                    return b(nAdd(local1, local2, "I"));
                case ADD_LONG:
                    return b(nAdd(local1, local2, "J"));
                case SUB_DOUBLE:
                    return b(nSub(local1, local2, "D"));
                case SUB_FLOAT:
                    return b(nSub(local1, local2, "F"));
                case SUB_INT:
                    return b(nSub(local1, local2, "I"));
                case SUB_LONG:
                    return b(nSub(local1, local2, "J"));
                case MUL_DOUBLE:
                    return b(nMul(local1, local2, "D"));
                case MUL_FLOAT:
                    return b(nMul(local1, local2, "F"));
                case MUL_INT:
                    return b(nMul(local1, local2, "I"));
                case MUL_LONG:
                    return b(nMul(local1, local2, "J"));
                case DIV_DOUBLE:
                    return b(nDiv(local1, local2, "D"));
                case DIV_FLOAT:
                    return b(nDiv(local1, local2, "F"));
                case DIV_INT:
                    return b(nDiv(local1, local2, "I"));
                case DIV_LONG:
                    return b(nDiv(local1, local2, "J"));
                case REM_DOUBLE:
                    return b(nRem(local1, local2, "D"));
                case REM_FLOAT:
                    return b(nRem(local1, local2, "F"));
                case REM_INT:
                    return b(nRem(local1, local2, "I"));
                case REM_LONG:
                    return b(nRem(local1, local2, "J"));
                case AND_INT:
                    return b(nAnd(local1, local2, TypeClass.ZI.name));
                case AND_LONG:
                    return b(nAnd(local1, local2, "J"));
                case OR_INT:
                    return b(nOr(local1, local2, TypeClass.ZI.name));
                case OR_LONG:
                    return b(nOr(local1, local2, "J"));
                case XOR_INT:
                    return b(nXor(local1, local2, TypeClass.ZI.name));
                case XOR_LONG:
                    return b(nXor(local1, local2, "J"));
                case SHL_INT:
                    return b(nShl(local1, local2, "I"));
                case SHL_LONG:
                    return b(nShl(local1, local2, "J"));
                case SHR_INT:
                    return b(nShr(local1, local2, "I"));
                case SHR_LONG:
                    return b(nShr(local1, local2, "J"));
                case USHR_INT:
                    return b(nUshr(local1, local2, "I"));
                case USHR_LONG:
                    return b(nUshr(local1, local2, "J"));
                case IF_EQ:
                    emit(nIf(Exprs.nEq(local1, local2, TypeClass.ZIL.name), getLabel(((JumpStmtNode) insn).label)));
                    return null;
                case IF_GE:
                    emit(nIf(Exprs.nGe(local1, local2, "I"), getLabel(((JumpStmtNode) insn).label)));
                    return null;
                case IF_GT:
                    emit(nIf(Exprs.nGt(local1, local2, "I"), getLabel(((JumpStmtNode) insn).label)));
                    return null;
                case IF_LE:
                    emit(nIf(Exprs.nLe(local1, local2, "I"), getLabel(((JumpStmtNode) insn).label)));
                    return null;
                case IF_LT:
                    emit(nIf(Exprs.nLt(local1, local2, "I"), getLabel(((JumpStmtNode) insn).label)));
                    return null;
                case IF_NE:
                    emit(nIf(Exprs.nNe(local1, local2, TypeClass.ZIL.name), getLabel(((JumpStmtNode) insn).label)));
                    return null;
                case IPUT:
                case IPUT_BOOLEAN:
                case IPUT_BYTE:
                case IPUT_CHAR:
                case IPUT_OBJECT:
                case IPUT_SHORT:
                case IPUT_WIDE:
                    Field field = ((FieldStmtNode) insn).field;
                    emit(nAssign(nField(local1, field.getOwner(), field.getName(), field.getType()), local2));
                    return null;
                case ADD_DOUBLE_2ADDR:
                    return b(nAdd(local1, local2, "D"));
                case ADD_FLOAT_2ADDR:
                    return b(nAdd(local1, local2, "F"));
                case ADD_INT_2ADDR:
                    return b(nAdd(local1, local2, "I"));
                case ADD_LONG_2ADDR:
                    return b(nAdd(local1, local2, "J"));
                case SUB_DOUBLE_2ADDR:
                    return b(nSub(local1, local2, "D"));
                case SUB_FLOAT_2ADDR:
                    return b(nSub(local1, local2, "F"));
                case SUB_INT_2ADDR:
                    return b(nSub(local1, local2, "I"));
                case SUB_LONG_2ADDR:
                    return b(nSub(local1, local2, "J"));
                case MUL_DOUBLE_2ADDR:
                    return b(nMul(local1, local2, "D"));
                case MUL_FLOAT_2ADDR:
                    return b(nMul(local1, local2, "F"));
                case MUL_INT_2ADDR:
                    return b(nMul(local1, local2, "I"));
                case MUL_LONG_2ADDR:
                    return b(nMul(local1, local2, "J"));
                case DIV_DOUBLE_2ADDR:
                    return b(nDiv(local1, local2, "D"));
                case DIV_FLOAT_2ADDR:
                    return b(nDiv(local1, local2, "F"));
                case DIV_INT_2ADDR:
                    return b(nDiv(local1, local2, "I"));
                case DIV_LONG_2ADDR:
                    return b(nDiv(local1, local2, "J"));
                case REM_DOUBLE_2ADDR:
                    return b(nRem(local1, local2, "D"));
                case REM_FLOAT_2ADDR:
                    return b(nRem(local1, local2, "F"));
                case REM_INT_2ADDR:
                    return b(nRem(local1, local2, "I"));
                case REM_LONG_2ADDR:
                    return b(nRem(local1, local2, "J"));
                case AND_INT_2ADDR:
                    return b(nAnd(local1, local2, TypeClass.ZI.name));
                case AND_LONG_2ADDR:
                    return b(nAnd(local1, local2, "J"));
                case OR_INT_2ADDR:
                    return b(nOr(local1, local2, TypeClass.ZI.name));
                case OR_LONG_2ADDR:
                    return b(nOr(local1, local2, "J"));
                case XOR_INT_2ADDR:
                    return b(nXor(local1, local2, TypeClass.ZI.name));
                case XOR_LONG_2ADDR:
                    return b(nXor(local1, local2, "J"));
                case SHL_INT_2ADDR:
                    return b(nShl(local1, local2, "I"));
                case SHL_LONG_2ADDR:
                    return b(nShl(local1, local2, "J"));
                case SHR_INT_2ADDR:
                    return b(nShr(local1, local2, "I"));
                case SHR_LONG_2ADDR:
                    return b(nShr(local1, local2, "J"));
                case USHR_INT_2ADDR:
                    return b(nUshr(local1, local2, "I"));
                case USHR_LONG_2ADDR:
                    return b(nUshr(local1, local2, "J"));
            }
            throw new RuntimeException();
        }

        @Override
        public DvmValue ternaryOperation(DexStmtNode insn, DvmValue value1, DvmValue value2, DvmValue value3) {
            if (value1 == null || value2 == null || value3 == null) {
                emitNotFindOperand(insn);
                return b(nInt(0));
            }
            Local localArray = getLocal(value1);
            Local localIndex = getLocal(value2);
            Local localValue = getLocal(value3);
            switch(insn.op) {
                case APUT:
                    emit(nAssign(nArray(localArray, localIndex, TypeClass.IF.name), localValue));
                    break;
                case APUT_BOOLEAN:
                    emit(nAssign(nArray(localArray, localIndex, "Z"), localValue));
                    break;
                case APUT_BYTE:
                    emit(nAssign(nArray(localArray, localIndex, "B"), localValue));
                    break;
                case APUT_CHAR:
                    emit(nAssign(nArray(localArray, localIndex, "C"), localValue));
                    break;
                case APUT_OBJECT:
                    emit(nAssign(nArray(localArray, localIndex, "L"), localValue));
                    break;
                case APUT_SHORT:
                    emit(nAssign(nArray(localArray, localIndex, "S"), localValue));
                    break;
                case APUT_WIDE:
                    emit(nAssign(nArray(localArray, localIndex, TypeClass.JD.name), localValue));
                    break;
            }
            return null;
        }

        @Override
        public DvmValue naryOperation(DexStmtNode insn, List<? extends DvmValue> values) {
            for (DvmValue v : values) {
                if (v == null) {
                    emitNotFindOperand(insn);
                    return b(nInt(0));
                }
            }
            switch(insn.op) {
                case FILLED_NEW_ARRAY:
                case FILLED_NEW_ARRAY_RANGE:
                    DvmValue value = new DvmValue();
                    FilledNewArrayStmtNode filledNewArrayStmtNode = (FilledNewArrayStmtNode) insn;
                    String type = filledNewArrayStmtNode.type;
                    String elem = type.substring(1);
                    emit(nAssign(getLocal(value), nNewArray(elem, nInt(values.size()))));
                    for (int i = 0; i < values.size(); i++) {
                        emit(nAssign(nArray(getLocal(value), nInt(i), elem), getLocal(values.get(i))));
                    }
                    return value;
                default:
                    Op op = insn.op;
                    Method method = ((MethodStmtNode) insn).method;
                    Value[] vs = new Value[values.size()];
                    for (int i = 0; i < vs.length; i++) {
                        vs[i] = getLocal(values.get(i));
                    }
                    Value invoke = null;
                    switch(op) {
                        case INVOKE_VIRTUAL_RANGE:
                        case INVOKE_VIRTUAL:
                            invoke = nInvokeVirtual(vs, method.getOwner(), method.getName(), method.getParameterTypes(), method.getReturnType());
                            break;
                        case INVOKE_SUPER_RANGE:
                        case INVOKE_DIRECT_RANGE:
                        case INVOKE_SUPER:
                        case INVOKE_DIRECT:
                            invoke = nInvokeSpecial(vs, method.getOwner(), method.getName(), method.getParameterTypes(), method.getReturnType());
                            break;
                        case INVOKE_STATIC_RANGE:
                        case INVOKE_STATIC:
                            invoke = nInvokeStatic(vs, method.getOwner(), method.getName(), method.getParameterTypes(), method.getReturnType());
                            break;
                        case INVOKE_INTERFACE_RANGE:
                        case INVOKE_INTERFACE:
                            invoke = nInvokeInterface(vs, method.getOwner(), method.getName(), method.getParameterTypes(), method.getReturnType());
                            break;
                        default:
                            throw new RuntimeException();
                    }
                    if ("V".equals(method.getReturnType())) {
                        emit(nVoidInvoke(invoke));
                        return null;
                    } else {
                        return b(invoke);
                    }
            }
        }

        void emitNotFindOperand(DexStmtNode insn) {
            String msg;
            switch(insn.op) {
                case MOVE_RESULT:
                case MOVE_RESULT_OBJECT:
                case MOVE_RESULT_WIDE:
                    msg = "can't get operand(s) for " + insn.op + ", wrong position ?";
                    break;
                default:
                    msg = "can't get operand(s) for " + insn.op + ", out-of-range or not initialized ?";
                    break;
            }
            System.err.println("WARN: " + msg);
            emit(nThrow(nInvokeNew(new Value[] { nString("d2j: " + msg) }, new String[] { "Ljava/lang/String;" }, "Ljava/lang/VerifyError;")));
        }

        @Override
        public void returnOperation(DexStmtNode insn, DvmValue value) {
            if (value == null) {
                emitNotFindOperand(insn);
                return;
            }
            emit(nReturn(getLocal(value)));
        }
    };
}
Also used : Op(com.googlecode.d2j.reader.Op) Field(com.googlecode.d2j.Field) DvmInterpreter(com.googlecode.d2j.node.analysis.DvmInterpreter) DexType(com.googlecode.d2j.DexType) Local(com.googlecode.dex2jar.ir.expr.Local) IrMethod(com.googlecode.dex2jar.ir.IrMethod) Method(com.googlecode.d2j.Method) Value(com.googlecode.dex2jar.ir.expr.Value) DexLabel(com.googlecode.d2j.DexLabel)

Example 5 with Field

use of com.googlecode.d2j.Field in project dex2jar by pxb1988.

the class I63Test method i63.

@Test
public static void i63(DexClassVisitor cv) {
    DexMethodVisitor mv = cv.visitMethod(ACC_STATIC, new Method("La;", "b", new String[] {}, "V"));
    if (mv != null) {
        DexCodeVisitor code = mv.visitCode();
        if (code != null) {
            code.visitRegister(1);
            DexLabel L1 = new DexLabel();
            DexLabel L2 = new DexLabel();
            code.visitLabel(L1);
            code.visitFieldStmt(Op.SGET, 0, -1, new Field("La;", "f", "J"));
            code.visitLabel(L2);
            code.visitStmt0R(Op.RETURN_VOID);
            code.visitEnd();
            code.visitTryCatch(L1, L2, new DexLabel[] { L2 }, new String[] { "La;" });
        }
        mv.visitEnd();
    }
}
Also used : Field(com.googlecode.d2j.Field) DexCodeVisitor(com.googlecode.d2j.visitors.DexCodeVisitor) DexLabel(com.googlecode.d2j.DexLabel) Method(com.googlecode.d2j.Method) DexMethodVisitor(com.googlecode.d2j.visitors.DexMethodVisitor) Test(org.junit.Test)

Aggregations

Field (com.googlecode.d2j.Field)12 Method (com.googlecode.d2j.Method)9 DexCodeVisitor (com.googlecode.d2j.visitors.DexCodeVisitor)8 DexMethodVisitor (com.googlecode.d2j.visitors.DexMethodVisitor)7 DexLabel (com.googlecode.d2j.DexLabel)6 Test (org.junit.Test)5 DexAnnotationVisitor (com.googlecode.d2j.visitors.DexAnnotationVisitor)3 Op (com.googlecode.d2j.reader.Op)2 DexClassVisitor (com.googlecode.d2j.visitors.DexClassVisitor)2 DexFieldVisitor (com.googlecode.d2j.visitors.DexFieldVisitor)2 HashMap (java.util.HashMap)2 DexType (com.googlecode.d2j.DexType)1 DexFileWriter (com.googlecode.d2j.dex.writer.DexFileWriter)1 DexFieldNode (com.googlecode.d2j.node.DexFieldNode)1 DexMethodNode (com.googlecode.d2j.node.DexMethodNode)1 DvmInterpreter (com.googlecode.d2j.node.analysis.DvmInterpreter)1 ASMifierFileV (com.googlecode.d2j.util.ASMifierFileV)1 DexAnnotationAble (com.googlecode.d2j.visitors.DexAnnotationAble)1 IrMethod (com.googlecode.dex2jar.ir.IrMethod)1 Local (com.googlecode.dex2jar.ir.expr.Local)1