重命名 类 (ASM + Jar) 中的重复字段
Duplicate fields in renamed classes (ASM + Jar)
对于我正在处理的项目,我正在尝试使用 ASM 重命名 jar 文件中的 classes。我让它工作了......但有一个陷阱。每个在 jar 中重命名的 class 都有重复的字段。
这是我的代码:
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 实施以来,一切都变得更好了。
cr.accept(cn,ClassReader.EXPAND_FRAMES);
问题是您在现有 ClassNode 上调用 accept。 ClassNode.visitField 添加 一个字段到 class 节点。因此 ClassNode 中的所有内容都加倍 - 一份来自现有数据的副本和一份您添加的副本。
对于我正在处理的项目,我正在尝试使用 ASM 重命名 jar 文件中的 classes。我让它工作了......但有一个陷阱。每个在 jar 中重命名的 class 都有重复的字段。
这是我的代码:
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 实施以来,一切都变得更好了。
cr.accept(cn,ClassReader.EXPAND_FRAMES);
问题是您在现有 ClassNode 上调用 accept。 ClassNode.visitField 添加 一个字段到 class 节点。因此 ClassNode 中的所有内容都加倍 - 一份来自现有数据的副本和一份您添加的副本。