Search in sources :

Example 11 with DexMethodVisitor

use of com.googlecode.d2j.visitors.DexMethodVisitor in project dex2jar by pxb1988.

the class ArrayTypeTest method a122.

@Test
public static void a122(DexClassVisitor cv) {
    DexMethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, new Method("La;", "b", new String[] {}, "V"));
    DexCodeVisitor code = mv.visitCode();
    code.visitRegister(3);
    code.visitConstStmt(CONST, 0, Integer.valueOf(0));
    code.visitConstStmt(CONST, 2, Integer.valueOf(1));
    code.visitStmt3R(AGET, 1, 0, 2);
    code.visitStmt0R(RETURN_VOID);
    code.visitEnd();
    mv.visitEnd();
}
Also used : DexCodeVisitor(com.googlecode.d2j.visitors.DexCodeVisitor) Method(com.googlecode.d2j.Method) DexMethodVisitor(com.googlecode.d2j.visitors.DexMethodVisitor) Test(org.junit.Test)

Example 12 with DexMethodVisitor

use of com.googlecode.d2j.visitors.DexMethodVisitor in project dex2jar by pxb1988.

the class EmptyTrapTest method m005_toJSONString.

@Test
public static void m005_toJSONString(DexClassVisitor cv) {
    DexMethodVisitor mv = cv.visitMethod(0, new Method("LJSResponseTest;", "toJSONString", new String[] {}, "Ljava/lang/String;"));
    if (mv != null) {
        DexCodeVisitor code = mv.visitCode();
        if (code != null) {
            code.visitRegister(6);
            DexLabel L8 = new DexLabel();
            DexLabel L9 = new DexLabel();
            DexLabel L10 = new DexLabel();
            DexLabel L0 = new DexLabel();
            DexLabel L1 = new DexLabel();
            DexLabel L2 = new DexLabel();
            code.visitTryCatch(L0, L1, new DexLabel[] { L2 }, new String[] { "Lorg/json/JSONException;" });
            DexLabel L3 = new DexLabel();
            DexLabel L4 = new DexLabel();
            code.visitTryCatch(L3, L4, new DexLabel[] { L2 }, new String[] { "Lorg/json/JSONException;" });
            DexLabel L5 = new DexLabel();
            DexLabel L6 = new DexLabel();
            code.visitTryCatch(L5, L6, new DexLabel[] { L2 }, new String[] { "Lorg/json/JSONException;" });
            code.visitConstStmt(CONST_STRING, 2, "response");
            code.visitConstStmt(CONST_STRING, 4, "");
            code.visitLabel(L0);
            code.visitFieldStmt(IGET, 2, 5, new Field("LJSResponseTest;", "className", "Ljava/lang/String;"));
            code.visitJumpStmt(IF_EQZ, 2, -1, L8);
            code.visitFieldStmt(IGET, 2, 5, new Field("LJSResponseTest;", "methodName", "Ljava/lang/String;"));
            code.visitJumpStmt(IF_NEZ, 2, -1, L10);
            code.visitLabel(L8);
            code.visitConstStmt(CONST_STRING, 2, "");
            code.visitStmt2R(MOVE, 2, 4);
            code.visitLabel(L9);
            code.visitStmt1R(RETURN_OBJECT, 2);
            code.visitLabel(L10);
            code.visitTypeStmt(NEW_INSTANCE, 1, -1, "Lorg/json/JSONObject;");
            code.visitMethodStmt(INVOKE_DIRECT, new int[] { 1 }, new Method("Lorg/json/JSONObject;", "<init>", new String[] {}, "V"));
            code.visitConstStmt(CONST_STRING, 2, "class");
            code.visitFieldStmt(IGET, 3, 5, new Field("LJSResponseTest;", "className", "Ljava/lang/String;"));
            code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 1, 2, 3 }, new Method("Lorg/json/JSONObject;", "put", new String[] { "Ljava/lang/String;", "Ljava/lang/Object;" }, "Lorg/json/JSONObject;"));
            code.visitConstStmt(CONST_STRING, 2, "call");
            code.visitFieldStmt(IGET, 3, 5, new Field("LJSResponseTest;", "methodName", "Ljava/lang/String;"));
            code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 1, 2, 3 }, new Method("Lorg/json/JSONObject;", "put", new String[] { "Ljava/lang/String;", "Ljava/lang/Object;" }, "Lorg/json/JSONObject;"));
            code.visitConstStmt(CONST_STRING, 2, "result");
            code.visitFieldStmt(IGET, 3, 5, new Field("LJSResponseTest;", "result", "I"));
            code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 1, 2, 3 }, new Method("Lorg/json/JSONObject;", "put", new String[] { "Ljava/lang/String;", "I" }, "Lorg/json/JSONObject;"));
            code.visitFieldStmt(IGET, 2, 5, new Field("LJSResponseTest;", "response", "Ljava/lang/Object;"));
            code.visitJumpStmt(IF_EQZ, 2, -1, L3);
            code.visitConstStmt(CONST_STRING, 2, "response");
            code.visitFieldStmt(IGET, 3, 5, new Field("LJSResponseTest;", "response", "Ljava/lang/Object;"));
            code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 1, 2, 3 }, new Method("Lorg/json/JSONObject;", "put", new String[] { "Ljava/lang/String;", "Ljava/lang/Object;" }, "Lorg/json/JSONObject;"));
            code.visitLabel(L1);
            code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 1 }, new Method("Lorg/json/JSONObject;", "toString", new String[] {}, "Ljava/lang/String;"));
            code.visitStmt1R(MOVE_RESULT_OBJECT, 2);
            code.visitJumpStmt(GOTO, -1, -1, L9);
            code.visitLabel(L3);
            code.visitFieldStmt(IGET, 2, 5, new Field("LJSResponseTest;", "dataResponse", "[B"));
            code.visitJumpStmt(IF_EQZ, 2, -1, L5);
            code.visitConstStmt(CONST_STRING, 2, "response");
            code.visitFieldStmt(IGET, 3, 5, new Field("LJSResponseTest;", "dataResponse", "[B"));
            code.visitMethodStmt(INVOKE_STATIC, new int[] { 3 }, new Method("LBase64;", "encode", new String[] { "[B" }, "Ljava/lang/String;"));
            code.visitStmt1R(MOVE_RESULT, 3);
            code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 1, 2, 3 }, new Method("Lorg/json/JSONObject;", "put", new String[] { "Ljava/lang/String;", "Ljava/lang/Object;" }, "Lorg/json/JSONObject;"));
            code.visitLabel(L4);
            code.visitJumpStmt(GOTO, -1, -1, L1);
            code.visitLabel(L2);
            code.visitStmt1R(MOVE_EXCEPTION, 2);
            code.visitStmt2R(MOVE, 0, 2);
            code.visitConstStmt(CONST_STRING, 2, "MillennialMediaSDK");
            code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 0 }, new Method("Lorg/json/JSONException;", "getMessage", new String[] {}, "Ljava/lang/String;"));
            code.visitStmt1R(MOVE_RESULT, 3);
            code.visitMethodStmt(INVOKE_STATIC, new int[] { 2, 3 }, new Method("Landroid/util/Log;", "e", new String[] { "Ljava/lang/String;", "Ljava/lang/String;" }, "I"));
            code.visitConstStmt(CONST_STRING, 2, "");
            code.visitStmt2R(MOVE, 2, 4);
            code.visitJumpStmt(GOTO, -1, -1, L9);
            code.visitLabel(L5);
            code.visitConstStmt(CONST_STRING, 2, "");
            code.visitLabel(L6);
            code.visitStmt2R(MOVE, 2, 4);
            code.visitJumpStmt(GOTO, -1, -1, L9);
            code.visitEnd();
        }
        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)

Example 13 with DexMethodVisitor

use of com.googlecode.d2j.visitors.DexMethodVisitor in project dex2jar by pxb1988.

the class I101Test method a.

public static void a(DexClassVisitor cv) {
    DexMethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, new Method("La;", "b", new String[] {}, "V"));
    DexCodeVisitor code = mv.visitCode();
    code.visitRegister(2);
    DexLabel L0 = new DexLabel();
    DexLabel L1 = new DexLabel();
    DexLabel L2 = new DexLabel();
    code.visitTryCatch(L0, L1, new DexLabel[] { L2 }, new String[] { "Lsome/Exception;" });
    code.visitLabel(L0);
    code.visitConstStmt(CONST_STRING, 0, "abc");
    code.visitLabel(L1);
    code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 0 }, new Method("Ljava/lang/String;", "toString", new String[] {}, "Ljava/lang/String;"));
    code.visitStmt0R(RETURN_VOID);
    code.visitLabel(L2);
    code.visitStmt1R(MOVE_EXCEPTION, 1);
    code.visitMethodStmt(INVOKE_VIRTUAL, new int[] { 1 }, new Method("Ljava/lang/String;", "toString", new String[] {}, "Ljava/lang/String;"));
    code.visitStmt0R(RETURN_VOID);
    code.visitEnd();
    mv.visitEnd();
}
Also used : DexCodeVisitor(com.googlecode.d2j.visitors.DexCodeVisitor) DexLabel(com.googlecode.d2j.DexLabel) Method(com.googlecode.d2j.Method) DexMethodVisitor(com.googlecode.d2j.visitors.DexMethodVisitor)

Example 14 with DexMethodVisitor

use of com.googlecode.d2j.visitors.DexMethodVisitor in project dex2jar by pxb1988.

the class DexWeaver method genSwitchMethod.

private void genSwitchMethod(DexClassVisitor dcv, String typeNameDesc, String methodName, CB callback) {
    DexMethodVisitor dmv = dcv.visitMethod(DexConstants.ACC_PUBLIC, new Method(typeNameDesc, methodName, new String[0], "Ljava/lang/String;"));
    DexCodeVisitor code = dmv.visitCode();
    code.visitRegister(3);
    code.visitFieldStmt(Op.IGET, 0, 2, new Field(typeNameDesc, "idx", "I"));
    DexLabel[] labels = new DexLabel[callbacks.size()];
    Map<String, DexLabel> strMap = new TreeMap<>();
    for (int i = 0; i < labels.length; i++) {
        Callback cb = callbacks.get(i);
        String key = callback.getKey((Method) cb.target);
        DexLabel label = strMap.get(key);
        if (label == null) {
            label = new DexLabel();
            strMap.put(key, label);
        }
        labels[i] = label;
    }
    code.visitPackedSwitchStmt(Op.PACKED_SWITCH, 0, 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 (Map.Entry<String, DexLabel> e : strMap.entrySet()) {
        code.visitLabel(e.getValue());
        code.visitConstStmt(Op.CONST_STRING, 0, e.getKey());
        code.visitStmt1R(Op.RETURN_OBJECT, 0);
    }
    code.visitEnd();
    dmv.visitEnd();
}
Also used : Method(com.googlecode.d2j.Method) TreeMap(java.util.TreeMap) Field(com.googlecode.d2j.Field) DexCodeVisitor(com.googlecode.d2j.visitors.DexCodeVisitor) DexLabel(com.googlecode.d2j.DexLabel) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap) Map(java.util.Map) DexMethodVisitor(com.googlecode.d2j.visitors.DexMethodVisitor)

Example 15 with DexMethodVisitor

use of com.googlecode.d2j.visitors.DexMethodVisitor in project dex2jar by pxb1988.

the class DexWeaver method wrap.

public DexClassVisitor wrap(final String classNameDesc, final DexClassVisitor dcv) {
    return dcv == null ? null : new DexClassVisitor(dcv) {

        Map<MtdInfo, Method> cache = new HashMap<>();

        @Override
        public DexMethodVisitor visitMethod(final int accessFlags, Method method) {
            final DexMethodVisitor dmv = superVisitDexMethod(accessFlags, method);
            final MtdInfo mapTo = findDefinedTargetMethod(method.getOwner(), method.getName(), method.getDesc());
            if (mapTo != null) {
                final Method t = new Method(method.getOwner(), buildMethodAName(method.getName()), method.getParameterTypes(), method.getReturnType());
                final Method src = method;
                return new DexMethodNode(accessFlags, method) {

                    @Override
                    public void visitEnd() {
                        super.visitEnd();
                        DexCodeNode code = this.codeNode;
                        this.codeNode = null;
                        accept(dmv);
                        Op opcode;
                        if (Modifier.isStatic(access)) {
                            opcode = Op.INVOKE_STATIC_RANGE;
                        } else {
                            opcode = Op.INVOKE_VIRTUAL_RANGE;
                        }
                        generateMtdACode(opcode, t, mapTo, dmv, src);
                        // make sure public
                        int newAccess = (access & ~(DexConstants.ACC_PRIVATE | DexConstants.ACC_PROTECTED)) | DexConstants.ACC_PUBLIC;
                        code.accept(wrap(superVisitDexMethod(newAccess, t), dcv));
                    }
                };
            } else {
                return wrap(dmv, dcv);
            }
        }

        private DexMethodVisitor wrap(DexMethodVisitor dmv, final DexClassVisitor classVisitor) {
            return dmv == null ? null : new DexMethodVisitor(dmv) {

                @Override
                public DexCodeVisitor visitCode() {
                    return wrap(super.visitCode(), classVisitor);
                }
            };
        }

        private DexCodeVisitor wrap(DexCodeVisitor dcv, final DexClassVisitor classVisitor) {
            return dcv == null ? null : new DexCodeVisitor(dcv) {

                @Override
                public void visitMethodStmt(Op op, int[] args, Method method) {
                    MtdInfo mapTo = findTargetMethod(method.getOwner(), method.getName(), method.getDesc());
                    if (mapTo != null) {
                        Method methodA = cache.get(buildKey(method.getOwner(), method.getName(), method.getDesc()));
                        if (methodA == null) {
                            if (isStatic(op)) {
                                methodA = new Method(classNameDesc, buildMethodAName(method.getName()), method.getParameterTypes(), method.getReturnType());
                            } else {
                                methodA = new Method(classNameDesc, buildMethodAName(method.getName()), join(method.getOwner(), method.getParameterTypes()), method.getReturnType());
                            }
                            DexMethodVisitor dmv = classVisitor.visitMethod(DexConstants.ACC_PRIVATE | DexConstants.ACC_STATIC, methodA);
                            generateMtdACode(op, method, mapTo, dmv, method);
                            dmv.visitEnd();
                            cache.put(buildKey(method.getOwner(), method.getName(), method.getDesc()), methodA);
                        }
                        super.visitMethodStmt(isRange(op) ? Op.INVOKE_STATIC_RANGE : Op.INVOKE_STATIC, args, methodA);
                    } else {
                        super.visitMethodStmt(op, args, method);
                    }
                }
            };
        }

        private void generateMtdACode(Op opcode, Method t, MtdInfo mapTo, DexMethodVisitor dmv, Method src) {
            DexCodeVisitor dcv = dmv.visitCode();
            int countArge = countArgs(t);
            boolean haveThis = haveThis(opcode);
            int registers = 4 + (haveThis ? 1 : 0) + countArge;
            dcv.visitRegister(registers);
            int argStart = 4;
            if (haveThis) {
                dcv.visitStmt2R(Op.MOVE_OBJECT, 0, argStart);
                argStart++;
            } else {
                dcv.visitConstStmt(Op.CONST_4, 0, 0);
            }
            if (t.getParameterTypes().length == 0) {
                dcv.visitConstStmt(Op.CONST_4, 1, 0);
            } else {
                dcv.visitConstStmt(Op.CONST, 1, t.getParameterTypes().length);
                dcv.visitTypeStmt(Op.NEW_ARRAY, 1, 1, "[Ljava/lang/Object;");
                for (int i = 0; i < t.getParameterTypes().length; i++) {
                    char type = t.getParameterTypes()[i].charAt(0);
                    dcv.visitConstStmt(Op.CONST, 2, i);
                    box(type, argStart, 3, dcv);
                    dcv.visitStmt3R(Op.APUT_OBJECT, 3, 1, 2);
                    if (type == 'J' || type == 'D') {
                        argStart += 2;
                    } else {
                        argStart += 1;
                    }
                }
            }
            int nextIdx = callbacks.size();
            dcv.visitConstStmt(Op.CONST, 2, nextIdx);
            String miTypeDesc = "L" + getCurrentInvocationName() + ";";
            dcv.visitTypeStmt(Op.NEW_INSTANCE, 3, 0, miTypeDesc);
            dcv.visitMethodStmt(Op.INVOKE_DIRECT, new int[] { 3, 0, 1, 2 }, new Method(miTypeDesc, "<init>", new String[] { "Ljava/lang/Object;", "[Ljava/lang/Object;", "I" }, "V"));
            Method call = build(mapTo);
            dcv.visitMethodStmt(Op.INVOKE_STATIC, new int[] { 3 }, call);
            if (!"V".equals(t.getReturnType())) {
                switch(call.getReturnType().charAt(0)) {
                    case '[':
                    case 'L':
                        dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, 0);
                        break;
                    case 'J':
                    case 'D':
                        dcv.visitStmt1R(Op.MOVE_RESULT_WIDE, 0);
                        break;
                    default:
                        dcv.visitStmt1R(Op.MOVE_RESULT, 0);
                        break;
                }
                unbox(t.getReturnType(), 0, dcv);
                switch(t.getReturnType().charAt(0)) {
                    case '[':
                    case 'L':
                        dcv.visitStmt1R(Op.RETURN_OBJECT, 0);
                        break;
                    case 'J':
                    case 'D':
                        dcv.visitStmt1R(Op.RETURN_WIDE, 0);
                        break;
                    default:
                        dcv.visitStmt1R(Op.RETURN, 0);
                        break;
                }
            } else {
                dcv.visitStmt0R(Op.RETURN_VOID);
            }
            Callback cb = new Callback();
            cb.idx = nextIdx;
            cb.callback = newMethodCallback(opcode, t);
            cb.target = src;
            cb.isSpecial = isSuper(opcode);
            cb.isStatic = isStatic(opcode);
            callbacks.add(cb);
        }

        private Method newMethodCallback(Op opcode, Method t) {
            boolean isStatic = !haveThis(opcode);
            boolean isSuper = isSuper(opcode);
            Method m;
            if (isSuper || isStatic) {
                m = new Method(t.getOwner(), buildCallbackMethodName(t.getName()), new String[] { "[Ljava/lang/Object;" }, "Ljava/lang/Object;");
            } else {
                m = new Method(t.getOwner(), buildCallbackMethodName(t.getName()), new String[] { "Ljava/lang/Object;", "[Ljava/lang/Object;" }, "Ljava/lang/Object;");
            }
            DexMethodVisitor dmv = superVisitDexMethod(DexConstants.ACC_PUBLIC | (isSuper ? 0 : DexConstants.ACC_STATIC), m);
            DexCodeVisitor dcv = dmv.visitCode();
            int totalRegs;
            int argStart;
            if (isStatic) {
                totalRegs = 1 + countArgs(t) + 1;
                argStart = totalRegs - 1;
            } else {
                totalRegs = 1 + countArgs(t) + 2;
                argStart = totalRegs - 2;
            }
            dcv.visitRegister(totalRegs);
            int[] args = new int[countArgs(t) + (isStatic ? 0 : 1)];
            int args_index = 0;
            int i = 1;
            if (!isStatic) {
                if (i != argStart) {
                    dcv.visitStmt2R(Op.MOVE_OBJECT, i, argStart);
                }
                if (!isSuper) {
                    dcv.visitTypeStmt(Op.CHECK_CAST, i, -1, t.getOwner());
                }
                args[args_index++] = i;
                i++;
                argStart++;
            }
            String[] parameterTypes = t.getParameterTypes();
            for (int i1 = 0; i1 < parameterTypes.length; i1++) {
                String argType = parameterTypes[i1];
                dcv.visitConstStmt(Op.CONST, 0, i1);
                dcv.visitStmt3R(Op.AGET_OBJECT, i, argStart, 0);
                unbox(argType, i, dcv);
                args[args_index++] = i;
                if (argType.charAt(0) == 'J' || argType.charAt(0) == 'D') {
                    args[args_index++] = i + 1;
                    i += 2;
                } else {
                    i += 1;
                }
            }
            dcv.visitMethodStmt(opcode, args, t);
            if ("V".equals(t.getReturnType())) {
                dcv.visitConstStmt(Op.CONST, 0, 0);
            } else {
                switch(t.getReturnType().charAt(0)) {
                    case '[':
                    case 'L':
                        dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, 0);
                        break;
                    case 'J':
                    case 'D':
                        dcv.visitStmt1R(Op.MOVE_RESULT_WIDE, 0);
                        break;
                    default:
                        dcv.visitStmt1R(Op.MOVE_RESULT, 0);
                        break;
                }
                box(t.getReturnType().charAt(0), 0, 0, dcv);
            }
            dcv.visitStmt1R(Op.RETURN_OBJECT, 0);
            return m;
        }

        private DexMethodVisitor superVisitDexMethod(int accessFlags, Method method) {
            return super.visitMethod(accessFlags, method);
        }
    };
}
Also used : Op(com.googlecode.d2j.reader.Op) HashMap(java.util.HashMap) Method(com.googlecode.d2j.Method) DexCodeNode(com.googlecode.d2j.node.DexCodeNode) DexMethodNode(com.googlecode.d2j.node.DexMethodNode) DexCodeVisitor(com.googlecode.d2j.visitors.DexCodeVisitor) DexClassVisitor(com.googlecode.d2j.visitors.DexClassVisitor) DexMethodVisitor(com.googlecode.d2j.visitors.DexMethodVisitor)

Aggregations

DexMethodVisitor (com.googlecode.d2j.visitors.DexMethodVisitor)20 DexCodeVisitor (com.googlecode.d2j.visitors.DexCodeVisitor)19 Method (com.googlecode.d2j.Method)18 Test (org.junit.Test)13 DexLabel (com.googlecode.d2j.DexLabel)9 Field (com.googlecode.d2j.Field)7 DexClassVisitor (com.googlecode.d2j.visitors.DexClassVisitor)4 HashMap (java.util.HashMap)3 Op (com.googlecode.d2j.reader.Op)2 DexAnnotationVisitor (com.googlecode.d2j.visitors.DexAnnotationVisitor)2 DexFieldVisitor (com.googlecode.d2j.visitors.DexFieldVisitor)2 File (java.io.File)2 DexFileWriter (com.googlecode.d2j.dex.writer.DexFileWriter)1 DexCodeNode (com.googlecode.d2j.node.DexCodeNode)1 DexMethodNode (com.googlecode.d2j.node.DexMethodNode)1 DexFileReader (com.googlecode.d2j.reader.DexFileReader)1 ASMifierFileV (com.googlecode.d2j.util.ASMifierFileV)1 DexAnnotationAble (com.googlecode.d2j.visitors.DexAnnotationAble)1 DexFileVisitor (com.googlecode.d2j.visitors.DexFileVisitor)1 Map (java.util.Map)1