Search in sources :

Example 1 with RemappingClassAdapter

use of org.objectweb.asm.commons.RemappingClassAdapter in project storm by apache.

the class DefaultShader method addRemappedClass.

private void addRemappedClass(RelocatorRemapper remapper, JarOutputStream jos, String name, InputStream is) throws IOException {
    LOG.debug("Remapping class... " + name);
    if (!remapper.hasRelocators()) {
        try {
            LOG.debug("Just copy class...");
            jos.putNextEntry(new JarEntry(name));
            IOUtil.copy(is, jos);
        } catch (ZipException e) {
            LOG.info("zip exception ", e);
        }
        return;
    }
    ClassReader cr = new ClassReader(is);
    // We don't pass the ClassReader here. This forces the ClassWriter to rebuild the constant pool.
    // Copying the original constant pool should be avoided because it would keep references
    // to the original class names. This is not a problem at runtime (because these entries in the
    // constant pool are never used), but confuses some tools such as Felix' maven-bundle-plugin
    // that use the constant pool to determine the dependencies of a class.
    ClassWriter cw = new ClassWriter(0);
    final String pkg = name.substring(0, name.lastIndexOf('/') + 1);
    ClassVisitor cv = new RemappingClassAdapter(cw, remapper) {

        @Override
        public void visitSource(final String source, final String debug) {
            LOG.debug("visitSource " + source);
            if (source == null) {
                super.visitSource(source, debug);
            } else {
                final String fqSource = pkg + source;
                final String mappedSource = remapper.map(fqSource);
                final String filename = mappedSource.substring(mappedSource.lastIndexOf('/') + 1);
                LOG.debug("Remapped to " + filename);
                super.visitSource(filename, debug);
            }
        }
    };
    try {
        cr.accept(cv, ClassReader.EXPAND_FRAMES);
    } catch (Throwable ise) {
        throw new IOException("Error in ASM processing class " + name, ise);
    }
    byte[] renamedClass = cw.toByteArray();
    // Need to take the .class off for remapping evaluation
    String mappedName = remapper.map(name.substring(0, name.indexOf('.')));
    LOG.debug("Remapped class name to " + mappedName);
    try {
        // Now we put it back on so the class file is written out with the right extension.
        jos.putNextEntry(new JarEntry(mappedName + ".class"));
        jos.write(renamedClass);
    } catch (ZipException e) {
        LOG.info("zip exception ", e);
    }
}
Also used : RemappingClassAdapter(org.objectweb.asm.commons.RemappingClassAdapter) ClassReader(org.objectweb.asm.ClassReader) ZipException(java.util.zip.ZipException) ClassVisitor(org.objectweb.asm.ClassVisitor) JarEntry(java.util.jar.JarEntry) ClassWriter(org.objectweb.asm.ClassWriter)

Example 2 with RemappingClassAdapter

use of org.objectweb.asm.commons.RemappingClassAdapter in project MinecraftForge by MinecraftForge.

the class DeobfuscationTransformer method transform.

// COMPUTE_FRAMES causes classes to be loaded, which could cause issues if the classes do not exist.
// However in testing this has not happened. {As we run post SideTransformer}
// If reported we need to add a custom implementation of ClassWriter.getCommonSuperClass
// that does not cause class loading.
@Override
public byte[] transform(String name, String transformedName, byte[] bytes) {
    if (bytes == null) {
        return null;
    }
    ClassReader classReader = new ClassReader(bytes);
    ClassWriter classWriter = new ClassWriter(WRITER_FLAGS);
    RemappingClassAdapter remapAdapter = new FMLRemappingAdapter(classWriter);
    classReader.accept(remapAdapter, READER_FLAGS);
    return classWriter.toByteArray();
}
Also used : RemappingClassAdapter(org.objectweb.asm.commons.RemappingClassAdapter) FMLRemappingAdapter(net.minecraftforge.fml.common.asm.transformers.deobf.FMLRemappingAdapter) ClassReader(org.objectweb.asm.ClassReader) ClassWriter(org.objectweb.asm.ClassWriter)

Example 3 with RemappingClassAdapter

use of org.objectweb.asm.commons.RemappingClassAdapter in project dex2jar by pxb1988.

the class InvocationWeaver method wrapper.

public ClassVisitor wrapper(final ClassVisitor cv) {
    return new RemappingClassAdapter(cv, remapper) {

        Map<MtdInfo, MtdInfo> toCreate = new HashMap<MtdInfo, MtdInfo>();

        String clzName;

        private MtdInfo newMethodA(int opcode, MtdInfo t, MtdInfo mapTo) {
            MtdInfo n = toCreate.get(t);
            if (n != null) {
                return n;
            }
            n = new MtdInfo();
            n.owner = t.owner;
            n.name = buildMethodAName(t.name);
            boolean hasThis = opcode != INVOKESTATIC;
            if (hasThis) {
                Type[] args = Type.getArgumentTypes(t.desc);
                Type ret = Type.getReturnType(t.desc);
                List<Type> ts = new ArrayList<>(args.length + 1);
                ts.add(Type.getType(t.owner));
                ts.addAll(Arrays.asList(args));
                n.desc = Type.getMethodDescriptor(ret, ts.toArray(new Type[ts.size()]));
            } else {
                n.desc = t.desc;
            }
            toCreate.put(t, n);
            MethodVisitor mv = cv.visitMethod(ACC_SYNTHETIC | ACC_PRIVATE | ACC_STATIC, n.name, n.desc, null, null);
            mv.visitCode();
            genMethodACode(opcode, t, mapTo, mv, t);
            return n;
        }

        private void genMethodACode(int opcode, MtdInfo t, MtdInfo mapTo, MethodVisitor mv, MtdInfo src) {
            boolean hasThis = opcode != INVOKESTATIC;
            Type[] args = Type.getArgumentTypes(t.desc);
            Type ret = Type.getReturnType(t.desc);
            final int start;
            mv.visitTypeInsn(NEW, getCurrentInvocationName());
            mv.visitInsn(DUP);
            if (hasThis) {
                mv.visitVarInsn(ALOAD, 0);
                start = 1;
            } else {
                mv.visitInsn(ACONST_NULL);
                start = 0;
            }
            if (args.length == 0) {
                mv.visitInsn(ACONST_NULL);
            } else {
                mv.visitLdcInsn(args.length);
                mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
                for (int i = 0; i < args.length; i++) {
                    mv.visitInsn(DUP);
                    mv.visitLdcInsn(i);
                    mv.visitVarInsn(args[i].getOpcode(ILOAD), i + start);
                    box(args[i], mv);
                    mv.visitInsn(AASTORE);
                }
            }
            int nextIdx = callbacks.size();
            mv.visitLdcInsn(nextIdx);
            mv.visitMethodInsn(INVOKESPECIAL, getCurrentInvocationName(), "<init>", "(Ljava/lang/Object;[Ljava/lang/Object;I)V");
            mv.visitMethodInsn(INVOKESTATIC, toInternal(mapTo.owner), mapTo.name, mapTo.desc);
            unBox(ret, Type.getReturnType(mapTo.desc), mv);
            mv.visitInsn(ret.getOpcode(IRETURN));
            mv.visitMaxs(-1, -1);
            mv.visitEnd();
            Callback cb = new Callback();
            cb.idx = nextIdx;
            cb.callback = newMethodCallback(opcode, t);
            cb.target = src;
            cb.isSpecial = opcode == INVOKESPECIAL;
            cb.isStatic = opcode == INVOKESTATIC;
            callbacks.add(cb);
        }

        private MtdInfo newMethodCallback(int opcode, MtdInfo t) {
            MtdInfo n = new MtdInfo();
            n.owner = "L" + className + ";";
            n.name = buildCallbackMethodName(t.name);
            if (opcode == INVOKESPECIAL || opcode == INVOKESTATIC) {
                n.desc = "([Ljava/lang/Object;)Ljava/lang/Object;";
            } else {
                n.desc = "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;";
            }
            MethodVisitor mv = cv.visitMethod(opcode == INVOKESPECIAL ? ACC_PUBLIC : ACC_PUBLIC | ACC_STATIC, n.name, n.desc, null, null);
            mv.visitCode();
            int start;
            if (opcode != INVOKESTATIC) {
                mv.visitVarInsn(ALOAD, 0);
                if (opcode != INVOKESPECIAL) {
                    mv.visitTypeInsn(CHECKCAST, toInternal(t.owner));
                }
                start = 1;
            } else {
                start = 0;
            }
            Type[] args = Type.getArgumentTypes(t.desc);
            for (int i = 0; i < args.length; i++) {
                mv.visitVarInsn(ALOAD, start);
                mv.visitLdcInsn(i);
                mv.visitInsn(AALOAD);
                unBox(args[i], OBJECT_TYPE, mv);
            }
            mv.visitMethodInsn(opcode, toInternal(t.owner), t.name, t.desc);
            Type ret = Type.getReturnType(t.desc);
            box(ret, mv);
            mv.visitInsn(ARETURN);
            mv.visitMaxs(-1, -1);
            mv.visitEnd();
            return n;
        }

        @Override
        public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
            super.visit(version, access, name, signature, superName, interfaces);
            clzName = name;
        }

        public MethodVisitor visitMethod(int access, final String name, String desc, String signature, String[] exceptions) {
            final MethodVisitor superMv = superMethodVisitor(access, name, desc, signature, exceptions);
            final MtdInfo mapTo = findDefinedTargetMethod("L" + clzName + ";", name, desc);
            if (mapTo != null) {
                final MtdInfo t1 = new MtdInfo();
                t1.owner = "L" + clzName + ";";
                t1.name = buildMethodAName(name);
                t1.desc = desc;
                final MtdInfo t = t1;
                final MtdInfo src = new MtdInfo();
                src.owner = t.owner;
                src.name = name;
                src.desc = desc;
                return new MethodNode(Opcodes.ASM4, access, name, desc, signature, exceptions) {

                    @Override
                    public void visitEnd() {
                        InsnList instructions = this.instructions;
                        List<TryCatchBlockNode> tryCatchBlocks = this.tryCatchBlocks;
                        List<LocalVariableNode> localVariables = this.localVariables;
                        this.instructions = new InsnList();
                        this.tryCatchBlocks = new ArrayList<>();
                        this.localVariables = new ArrayList<>();
                        this.maxLocals = -1;
                        this.maxStack = -1;
                        accept(superMv);
                        int opcode;
                        if (Modifier.isStatic(access)) {
                            opcode = Opcodes.INVOKESTATIC;
                        } else {
                            opcode = Opcodes.INVOKEVIRTUAL;
                        }
                        genMethodACode(opcode, t, mapTo, superMv, src);
                        // make sure public
                        int newAccess = (access & ~(ACC_PRIVATE | ACC_PROTECTED)) | ACC_PUBLIC;
                        MethodVisitor rmv = wrap(superMethodVisitor(newAccess, t.name, desc, null, null));
                        if (rmv != null) {
                            rmv.visitCode();
                            int n, i;
                            n = tryCatchBlocks == null ? 0 : tryCatchBlocks.size();
                            for (i = 0; i < n; ++i) {
                                tryCatchBlocks.get(i).accept(rmv);
                            }
                            instructions.accept(rmv);
                            n = localVariables == null ? 0 : localVariables.size();
                            for (i = 0; i < n; ++i) {
                                localVariables.get(i).accept(rmv);
                            }
                            rmv.visitMaxs(-1, -1);
                            rmv.visitEnd();
                        }
                    }
                };
            } else {
                return wrap(superMv);
            }
        }

        private MethodVisitor superMethodVisitor(int access, String name, String desc, String signature, String[] exceptions) {
            return super.visitMethod(access, name, desc, signature, exceptions);
        }

        MethodVisitor wrap(MethodVisitor mv) {
            return mv == null ? null : new ReplaceMethodVisitor(mv);
        }

        class ReplaceMethodVisitor extends MethodVisitor {

            public ReplaceMethodVisitor(MethodVisitor mv) {
                super(Opcodes.ASM4, mv);
            }

            @Override
            public void visitMethodInsn(int opcode, String owner, String name, String desc) {
                MtdInfo mapTo = findTargetMethod("L" + owner + ";", name, desc);
                if (mapTo != null) {
                    boolean isStatic = opcode == INVOKESTATIC;
                    Type orgRet = Type.getReturnType(desc);
                    Type[] orgArgs = Type.getArgumentTypes(desc);
                    Type nRet = Type.getReturnType(mapTo.desc);
                    Type[] nArgs = Type.getArgumentTypes(mapTo.desc);
                    if (orgRet.getSort() != Type.VOID && nRet.getSort() == Type.VOID) {
                        throw new RuntimeException("can't cast " + nRet + " to " + orgRet);
                    }
                    if (nArgs.length == 1 && nArgs[0].getDescriptor().equals(invocationInterfaceDesc)) {
                        MtdInfo t = new MtdInfo();
                        t.owner = "L" + owner + ";";
                        t.name = name;
                        t.desc = desc;
                        MtdInfo n = newMethodA(opcode, t, mapTo);
                        super.visitMethodInsn(INVOKESTATIC, clzName, n.name, n.desc);
                    } else {
                        // checking for invalid replace
                        if (isStatic) {
                            if (!Arrays.deepEquals(orgArgs, nArgs)) {
                                throw new RuntimeException("arguments not equal: " + owner + "." + name + desc + " <> " + mapTo.owner + "." + mapTo.name + mapTo.desc);
                            }
                        } else {
                            if (nArgs.length != orgArgs.length + 1) {
                                throw new RuntimeException("arguments not equal: " + owner + "." + name + desc + " <> " + mapTo.owner + "." + mapTo.name + mapTo.desc);
                            }
                            if (orgArgs.length > 0) {
                                for (int i = 0; i < orgArgs.length; i++) {
                                    if (!orgArgs[i].equals(nArgs[i + 1])) {
                                        throw new RuntimeException("arguments not equal: " + owner + "." + name + desc + " <> " + mapTo.owner + "." + mapTo.name + mapTo.desc);
                                    }
                                }
                            }
                        }
                        // replace it!
                        super.visitMethodInsn(INVOKESTATIC, toInternal(mapTo.owner), mapTo.name, mapTo.desc);
                        unBox(orgRet, nRet, this.mv);
                    }
                } else {
                    super.visitMethodInsn(opcode, owner, name, desc);
                }
            }
        }
    };
}
Also used : TryCatchBlockNode(org.objectweb.asm.tree.TryCatchBlockNode) InsnList(org.objectweb.asm.tree.InsnList) LocalVariableNode(org.objectweb.asm.tree.LocalVariableNode) MethodNode(org.objectweb.asm.tree.MethodNode) RemappingClassAdapter(org.objectweb.asm.commons.RemappingClassAdapter)

Example 4 with RemappingClassAdapter

use of org.objectweb.asm.commons.RemappingClassAdapter in project bytecode-viewer by Konloch.

the class Refactorer method run.

public void run() {
    if (getHooks() == null)
        return;
    RefactorMapper mapper = new RefactorMapper(getHooks());
    Map<String, ClassNode> refactored = new HashMap<>();
    for (ClassNode cn : BytecodeViewer.getLoadedClasses()) {
        String oldName = cn.name;
        ClassReader cr = new ClassReader(getClassNodeBytes(cn));
        ClassWriter cw = new ClassWriter(cr, 0);
        RemappingClassAdapter rca = new RemappingClassAdapter(cw, mapper);
        cr.accept(rca, ClassReader.EXPAND_FRAMES);
        cr = new ClassReader(cw.toByteArray());
        cn = new ClassNode();
        cr.accept(cn, 0);
        refactored.put(oldName, cn);
    }
    /*for (Map.Entry<String, ClassNode> factor : refactored.entrySet()) {
            BytecodeViewer.relocate(factor.getKey(), factor.getValue());
        }*/
    mapper.printMap();
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) HashMap(java.util.HashMap) RemappingClassAdapter(org.objectweb.asm.commons.RemappingClassAdapter) ClassReader(org.objectweb.asm.ClassReader) ClassWriter(org.objectweb.asm.ClassWriter)

Example 5 with RemappingClassAdapter

use of org.objectweb.asm.commons.RemappingClassAdapter in project ignite by apache.

the class HadoopHelperImpl method loadReplace.

/** {@inheritDoc} */
@Override
public byte[] loadReplace(InputStream in, final String originalName, final String replaceName) {
    ClassReader rdr;
    try {
        rdr = new ClassReader(in);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
    ClassWriter w = new ClassWriter(Opcodes.ASM4);
    rdr.accept(new RemappingClassAdapter(w, new Remapper() {

        /** */
        String replaceType = replaceName.replace('.', '/');

        /** */
        String nameType = originalName.replace('.', '/');

        @Override
        public String map(String type) {
            if (type.equals(replaceType))
                return nameType;
            return type;
        }
    }), ClassReader.EXPAND_FRAMES);
    return w.toByteArray();
}
Also used : RemappingClassAdapter(org.objectweb.asm.commons.RemappingClassAdapter) Remapper(org.objectweb.asm.commons.Remapper) ClassReader(org.objectweb.asm.ClassReader) IOException(java.io.IOException) ClassWriter(org.objectweb.asm.ClassWriter)

Aggregations

RemappingClassAdapter (org.objectweb.asm.commons.RemappingClassAdapter)9 ClassReader (org.objectweb.asm.ClassReader)7 ClassWriter (org.objectweb.asm.ClassWriter)7 ClassVisitor (org.objectweb.asm.ClassVisitor)3 JarEntry (java.util.jar.JarEntry)2 ZipException (java.util.zip.ZipException)2 Remapper (org.objectweb.asm.commons.Remapper)2 ClassNode (org.objectweb.asm.tree.ClassNode)2 AndroidDependencyTree (com.taobao.android.builder.dependency.AndroidDependencyTree)1 AwbBundle (com.taobao.android.builder.dependency.model.AwbBundle)1 MtlBaseTaskAction (com.taobao.android.builder.tasks.manager.MtlBaseTaskAction)1 ExecutorServicesHelper (com.taobao.android.builder.tools.concurrent.ExecutorServicesHelper)1 File (java.io.File)1 FileFilter (java.io.FileFilter)1 FileInputStream (java.io.FileInputStream)1 FileOutputStream (java.io.FileOutputStream)1 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1