重命名的类中的重复字段(ASM + Jar)

时间:2015-11-30 07:58:03

标签: java bytecode java-bytecode-asm

对于我正在尝试使用ASM重命名jar文件中的类的项目。我已经开始工作......但是有一个问题。在jar中重命名的每个类都将它的字段重复。

这是我的代码:

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.commons.Remapper;
import org.objectweb.asm.commons.RemappingClassAdapter;
import org.objectweb.asm.commons.SimpleRemapper;
import org.objectweb.asm.tree.ClassNode;
//Imports showing which ASM (5.0.4) classes I'm using

private static void doStuff() throws IOException {
    File jar = new File("Input.jar");
    //Get's the ClassNodes for each class in a jar
    ArrayList<ClassNode> nodes = BCU.loadClasses(jar);
    //Appends '_Test' to each class except for the main class.
    Remapper mapper = new SimpleRemapper(getRename(nodes));
    //Loop through the ClassNodes updating references to renamed classes
    for (ClassNode cn : nodes) {
         ClassReader cr = new ClassReader(BCU.getNodeBytes(cn));
         ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS); 
         RemappingClassAdapter rca = new RemappingClassAdapter(cw, mapper); 
         cr.accept(rca, ClassReader.EXPAND_FRAMES); 
         cr = new ClassReader(cw.toByteArray()); 
         cr.accept(cn,ClassReader.EXPAND_FRAMES);
    }
    //Export the nodes as a new jar file and copy over the META-INF folder
    BCU.saveAsJar(nodes, "Output.jar");
}

示例输出:

public static String VERSION;
public static final ConfigFile config;
public static String VERSION;
public static final ConfigFile_Test config;

编辑(2016年3月28日):在了解了有关ASM的更多信息后回来了解应该如何完成:

for (ClassNode cn : nodes.values()) {
    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    //mapper is a Remapper instance
    ClassVisitor remapper = new RemappingClassAdapter(cw, mapper);
    cn.accept(remapper);
    //out = Map<String, byte[]>
    out.put(renamed.get(cn.name).getRenamed(), cw.toByteArray());
}

锑是对的。我发布这个时的原始想法是编辑ClassNode本身(我有一个处理所有内容的ClassNode扩展。它非常讨厌)。自从迁移到Remapper实现以来,事情变得更好了。

1 个答案:

答案 0 :(得分:1)

cr.accept(cn,ClassReader.EXPAND_FRAMES);

问题是你在现有的ClassNode上调用accept。 ClassNode.visitField 将字段添加到类节点。因此,ClassNode中的所有内容都会加倍 - 现有数据中的一个副本和您添加的一个副本。