Search in sources :

Example 1 with DexMethodVisitor

use of com.googlecode.d2j.visitors.DexMethodVisitor 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 DexMethodVisitor

use of com.googlecode.d2j.visitors.DexMethodVisitor 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 DexMethodVisitor

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

the class DexWeaverCmd method doCommandLine.

@Override
protected void doCommandLine() throws Exception {
    if (remainingArgs.length == 0) {
        throw new HelpException("no odex");
    }
    final Map<String, Method> map = new HashMap<>();
    for (String ln : Files.readAllLines(config, StandardCharsets.UTF_8)) {
        if (ln.startsWith("#") || ln.length() == 0) {
            continue;
        }
        String[] x = ln.split("=");
        map.put(x[0], parseMethod(x[1]));
    }
    DexFileWriter out = new DexFileWriter();
    DexFileVisitor fv = new DexFileVisitor(out) {

        @Override
        public DexClassVisitor visit(int access_flags, String className, String superClass, String[] interfaceNames) {
            DexClassVisitor dcv = super.visit(access_flags, className, superClass, interfaceNames);
            if (dcv != null) {
                return new DexClassVisitor(dcv) {

                    @Override
                    public DexMethodVisitor visitMethod(int accessFlags, Method method) {
                        DexMethodVisitor dmv = super.visitMethod(accessFlags, method);
                        if (dmv != null) {
                            return new DexMethodVisitor(dmv) {

                                @Override
                                public DexCodeVisitor visitCode() {
                                    DexCodeVisitor code = super.visitCode();
                                    if (code != null) {
                                        return new DexCodeVisitor(code) {

                                            @Override
                                            public void visitMethodStmt(Op op, int[] args, Method method) {
                                                Method replaceTo = map.get(method.toString());
                                                if (replaceTo != null) {
                                                    switch(op) {
                                                        case INVOKE_DIRECT:
                                                        case INVOKE_INTERFACE:
                                                        case INVOKE_STATIC:
                                                        case INVOKE_SUPER:
                                                        case INVOKE_VIRTUAL:
                                                            super.visitMethodStmt(Op.INVOKE_STATIC, args, replaceTo);
                                                            break;
                                                        case INVOKE_DIRECT_RANGE:
                                                        case INVOKE_INTERFACE_RANGE:
                                                        case INVOKE_STATIC_RANGE:
                                                        case INVOKE_SUPER_RANGE:
                                                        case INVOKE_VIRTUAL_RANGE:
                                                            super.visitMethodStmt(Op.INVOKE_STATIC_RANGE, args, replaceTo);
                                                            break;
                                                        default:
                                                    }
                                                } else {
                                                    super.visitMethodStmt(op, args, method);
                                                }
                                            }
                                        };
                                    }
                                    return code;
                                }
                            };
                        }
                        return dmv;
                    }
                };
            }
            return dcv;
        }

        @Override
        public void visitEnd() {
        }
    };
    for (String f : remainingArgs) {
        byte[] data = ZipUtil.readDex(new File(f).toPath());
        DexFileReader r = new DexFileReader(data);
        r.accept(fv);
    }
    if (stub != null) {
        byte[] data = ZipUtil.readDex(stub);
        DexFileReader r = new DexFileReader(data);
        r.accept(new DexFileVisitor(out) {

            @Override
            public void visitEnd() {
            }
        });
    }
    out.visitEnd();
    byte[] data = out.toByteArray();
    Files.write(output, data);
}
Also used : Op(com.googlecode.d2j.reader.Op) HashMap(java.util.HashMap) DexFileWriter(com.googlecode.d2j.dex.writer.DexFileWriter) DexFileReader(com.googlecode.d2j.reader.DexFileReader) Method(com.googlecode.d2j.Method) DexFileVisitor(com.googlecode.d2j.visitors.DexFileVisitor) DexCodeVisitor(com.googlecode.d2j.visitors.DexCodeVisitor) DexClassVisitor(com.googlecode.d2j.visitors.DexClassVisitor) File(java.io.File) DexMethodVisitor(com.googlecode.d2j.visitors.DexMethodVisitor)

Example 4 with DexMethodVisitor

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

the class I121Test method i121.

@Test
public static void i121(DexClassVisitor cv) {
    DexMethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, new Method("La;", "a", new String[] { "Ljava/lang/String;", "Ljava/lang/String;" }, "Ljava/lang/String;"));
    DexCodeVisitor code = mv.visitCode();
    int p0 = 2;
    int p1 = 3;
    int v0 = 0;
    int v1 = 1;
    DexLabel cond_7 = new DexLabel();
    DexLabel try_start_2 = new DexLabel();
    DexLabel try_end_9 = new DexLabel();
    DexLabel catch_a = new DexLabel();
    DexLabel goto_2 = new DexLabel();
    code.visitTryCatch(try_start_2, try_end_9, new DexLabel[] { catch_a }, new String[] { "Ljava/io/UnsupportedEncodingException;" });
    code.visitRegister(4);
    code.visitJumpStmt(IF_EQZ, p1, -1, cond_7);
    code.visitLabel(goto_2);
    code.visitLabel(try_start_2);
    code.visitMethodStmt(INVOKE_STATIC, new int[] { p0, p1 }, new Method("Ljava/net/URLEncoder;", "encode", new String[] { "Ljava/lang/String;", "Ljava/lang/String;" }, "Ljava/lang/String;"));
    code.visitStmt1R(MOVE_RESULT_OBJECT, v0);
    code.visitStmt1R(RETURN_OBJECT, v0);
    code.visitLabel(cond_7);
    code.visitConstStmt(CONST_STRING, p1, "ISO-8859-1");
    code.visitLabel(try_end_9);
    code.visitJumpStmt(GOTO, -1, -1, goto_2);
    code.visitLabel(catch_a);
    code.visitStmt1R(MOVE_EXCEPTION, v0);
    code.visitTypeStmt(NEW_INSTANCE, v1, -1, "Ljava/lang/IllegalArgumentException;");
    code.visitMethodStmt(INVOKE_DIRECT, new int[] { v1, v0 }, new Method("Ljava/lang/IllegalArgumentException;", "<init>", new String[] { "Ljava/lang/Throwable;" }, "V"));
    code.visitStmt1R(THROW, v1);
    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) Test(org.junit.Test)

Example 5 with DexMethodVisitor

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

the class I168Test method i168.

@Test
public static void i168(DexClassVisitor cv) {
    DexMethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, new Method("La;", "a", new String[] {}, "I"));
    DexCodeVisitor code = mv.visitCode();
    // 2000 locals
    code.visitRegister(2000);
    for (int i = 0; i < 2000; i++) {
        // 2000 insns
        code.visitConstStmt(Op.CONST, i, i);
    }
    for (int i = 0; i < 18000; i++) {
        // 18000 insns
        code.visitConstStmt(Op.CONST, 25, i);
    }
    code.visitStmt1R(Op.RETURN, 25);
    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)

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