Search in sources :

Example 1 with DexCodeVisitor

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

the class BaksmaliDumper method baksmaliCode.

public void baksmaliCode(DexMethodNode methodNode, DexCodeNode codeNode, Out out) {
    final List<DexLabel> allLabel = new ArrayList<>();
    final Set<DexLabel> usedLabel = new HashSet<>();
    codeNode.accept(new DexCodeVisitor() {

        @Override
        public void visitJumpStmt(Op op, int a, int b, DexLabel label) {
            usedLabel.add(label);
        }

        @Override
        public void visitPackedSwitchStmt(Op op, int aA, int first_case, DexLabel[] labels) {
            usedLabel.addAll(Arrays.asList(labels));
        }

        @Override
        public void visitTryCatch(DexLabel start, DexLabel end, DexLabel[] handler, String[] type) {
            usedLabel.add(start);
            usedLabel.add(end);
            usedLabel.addAll(Arrays.asList(handler));
        }

        @Override
        public void visitLabel(DexLabel label) {
            allLabel.add(label);
        }

        @Override
        public void visitSparseSwitchStmt(Op op, int ra, int[] cases, DexLabel[] labels) {
            usedLabel.addAll(Arrays.asList(labels));
        }
    });
    Map<DexLabel, List<DexDebugNode.DexDebugOpNode>> debugLabelMap = new HashMap<>();
    if (codeNode.debugNode != null) {
        DexDebugNode debugNode = codeNode.debugNode;
        for (DexDebugNode.DexDebugOpNode opNode : debugNode.debugNodes) {
            List<DexDebugNode.DexDebugOpNode> list = debugLabelMap.get(opNode.label);
            if (list == null) {
                list = new ArrayList<>(3);
                debugLabelMap.put(opNode.label, list);
            }
            list.add(opNode);
        }
    }
    int nextLabelNumber = 0;
    for (DexLabel label : allLabel) {
        if (usedLabel.contains(label)) {
            label.displayName = "L" + nextLabelNumber++;
        }
    }
    int inRegs = Utils.methodIns(methodNode.method, (methodNode.access & ACC_STATIC) != 0);
    DexCodeVisitor dexCodeVisitor = new BaksmaliCodeDumper(out, useParameterRegisters, useLocals, nextLabelNumber, codeNode.totalRegister - inRegs, usedLabel, debugLabelMap);
    accept(out, codeNode, dexCodeVisitor);
    dexCodeVisitor.visitEnd();
}
Also used : Op(com.googlecode.d2j.reader.Op) DexCodeVisitor(com.googlecode.d2j.visitors.DexCodeVisitor)

Example 2 with DexCodeVisitor

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

the class SmaliCodeVisitor method visitF31tStmt.

/* package */
void visitF31tStmt(final Op op, final int reg, final DexLabel label) {
    add(new DexStmtNode(op) {

        @Override
        public void accept(DexCodeVisitor cv) {
            int labelIndex = findLabelIndex(label);
            if (labelIndex < 0 || labelIndex >= needCareStmts.size()) {
                throw new RuntimeException("can't find label for " + op + " " + label);
            }
            switch(op) {
                case PACKED_SWITCH:
                    PackedSwitchStmt packedSwitchStmt = (PackedSwitchStmt) needCareStmts.get(labelIndex + 1);
                    cv.visitPackedSwitchStmt(op, reg, packedSwitchStmt.firstCase, packedSwitchStmt.labels);
                    break;
                case SPARSE_SWITCH:
                    SparseSwitchStmt sparseSwitchStmt = (SparseSwitchStmt) needCareStmts.get(labelIndex + 1);
                    cv.visitSparseSwitchStmt(op, reg, sparseSwitchStmt.cases, sparseSwitchStmt.labels);
                    break;
                case FILL_ARRAY_DATA:
                    ArrayDataStmt arrayDataStmt = (ArrayDataStmt) needCareStmts.get(labelIndex + 1);
                    Object v;
                    byte[] vs = arrayDataStmt.objs;
                    switch(arrayDataStmt.length) {
                        case 1:
                            {
                                v = vs;
                            }
                            break;
                        case 2:
                            {
                                short[] vs1 = new short[vs.length / 2];
                                for (int i = 0; i < vs1.length; i++) {
                                    vs1[i] = (short) ((vs[i * 2] & 0xFF) | ((vs[i * 2 + 1] & 0xFF) << 8));
                                }
                                v = vs1;
                            }
                            break;
                        case 4:
                            {
                                int[] vs1 = new int[vs.length / 4];
                                for (int i = 0; i < vs1.length; i++) {
                                    int base = i * 4;
                                    vs1[i] = (vs[base + 0] & 0xFF) | ((vs[base + 1] & 0xFF) << 8) | ((vs[base + 2] & 0xFF) << 16) | ((vs[base + 3] & 0xFF) << 24);
                                }
                                v = vs1;
                            }
                            break;
                        case 8:
                            {
                                long[] vs1 = new long[vs.length / 8];
                                for (int i = 0; i < vs1.length; i++) {
                                    int base = i * 8;
                                    int a = ((vs[base + 0] & 0xFF) << 0) | ((vs[base + 1] & 0xFF) << 8) | ((vs[base + 2] & 0xFF) << 16) | ((vs[base + 3] & 0xFF) << 24);
                                    int b = ((vs[base + 4] & 0xFF) << 0) | ((vs[base + 5] & 0xFF) << 8) | ((vs[base + 6] & 0xFF) << 16) | ((vs[base + 7] & 0xFF) << 24);
                                    vs1[i] = (((long) b) << 32) | a;
                                }
                                v = vs1;
                            }
                            break;
                        default:
                            throw new RuntimeException();
                    }
                    cv.visitFillArrayDataStmt(Op.FILL_ARRAY_DATA, reg, v);
                    break;
                default:
                    throw new RuntimeException();
            }
        }
    });
}
Also used : DexStmtNode(com.googlecode.d2j.node.insn.DexStmtNode) DexCodeVisitor(com.googlecode.d2j.visitors.DexCodeVisitor)

Example 3 with DexCodeVisitor

use of com.googlecode.d2j.visitors.DexCodeVisitor 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 4 with DexCodeVisitor

use of com.googlecode.d2j.visitors.DexCodeVisitor 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 5 with DexCodeVisitor

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

Aggregations

DexCodeVisitor (com.googlecode.d2j.visitors.DexCodeVisitor)23 DexMethodVisitor (com.googlecode.d2j.visitors.DexMethodVisitor)19 Method (com.googlecode.d2j.Method)18 Test (org.junit.Test)13 DexLabel (com.googlecode.d2j.DexLabel)9 Field (com.googlecode.d2j.Field)8 Op (com.googlecode.d2j.reader.Op)4 DexClassVisitor (com.googlecode.d2j.visitors.DexClassVisitor)4 HashMap (java.util.HashMap)4 DexMethodNode (com.googlecode.d2j.node.DexMethodNode)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 DexFieldNode (com.googlecode.d2j.node.DexFieldNode)1 DexStmtNode (com.googlecode.d2j.node.insn.DexStmtNode)1 DexFileReader (com.googlecode.d2j.reader.DexFileReader)1 ASMifierFileV (com.googlecode.d2j.util.ASMifierFileV)1 DexAnnotationAble (com.googlecode.d2j.visitors.DexAnnotationAble)1