【发布时间】:2022-06-15 21:36:23
【问题描述】:
我想编辑一个带有字节码的 jar 文件,我创建了一个项目来编辑它。 我有 2 个功能:
public static byte[] transform(byte[] buf){
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader(buf);
classReader.accept(classNode, ClassReader.EXPAND_FRAMES);
for (MethodNode method : classNode.methods) {
if(method.name.equals(shouldSideBeRenderedMethod) && method.desc.startsWith("(L") && method.desc.endsWith(";IIII)Z")){
System.out.println("[*] Patching bytecode of shouldSideBeRendered...");
InsnList insnList = new InsnList();
Label label0 = new Label();
insnList.add(new LabelNode(label0));
insnList.add(new VarInsnNode(ALOAD, 0));
insnList.add(new FieldInsnNode(GETFIELD, blockClass.replaceAll("\\.", "/"), unlocalizedNameField, "Ljava/lang/String;"));
insnList.add(new LdcInsnNode("stone"));
insnList.add(new MethodInsnNode(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false));
Label label1 = new Label();
insnList.add(new JumpInsnNode(IFNE, new LabelNode(label1)));
insnList.add(new InsnNode(ICONST_1));
Label label2 = new Label();
insnList.add(new JumpInsnNode(GOTO, new LabelNode(label2)));
insnList.add(new LabelNode(label1));
insnList.add(new FrameNode(Opcodes.F_SAME, 0, null, 0, null));
insnList.add(new InsnNode(ICONST_0));
insnList.add(new LabelNode(label2));
insnList.add(new FrameNode(Opcodes.F_SAME1, 0, null, 1, new Object[]{Opcodes.INTEGER}));
insnList.add(new InsnNode(IRETURN));
Label label3 = new Label();
insnList.add(new LabelNode(label3));
method.instructions.insertBefore(method.instructions.getFirst(), insnList);
}
}
return new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES).toByteArray();
}
和
JarFile jarFile = new JarFile(jarPath);
List<JarEntry> entries = Collections.list(jarFile.entries());
HashMap<String, byte[]> classMap = new HashMap<>();
entries.forEach(jarEntry -> {
try {
if(jarEntry.getName().equals(blockClass.replaceAll("\\.", "/") + ".class")){
classMap.put(jarEntry.getName(), transform(IOUtils.toByteArray(jarFile.getInputStream(jarEntry))));
}else{
classMap.put(jarEntry.getName(), IOUtils.toByteArray(jarFile.getInputStream(jarEntry)));
}
} catch (IOException e) {
e.printStackTrace();
}
});
System.out.println("[+] Jar loaded !");
System.out.println("[*] Writing patched jar...");
try {
JarOutputStream jarOutputStream = new JarOutputStream(new FileOutputStream("output.jar"));
for (Map.Entry<String, byte[]> entry : classMap.entrySet()) {
JarEntry jarEntry = new JarEntry(entry.getKey());
jarOutputStream.putNextEntry(jarEntry);
jarOutputStream.write(entry.getValue());
jarOutputStream.closeEntry();
}
jarOutputStream.close();
System.out.println("[+] Patched jar successfully written to output.jar !");
} catch (Exception e) {
e.printStackTrace();
}
代码有效,我得到了 jar,但是当我启动它时:线程“main”java.lang.UnsupportedClassVersionError 中的异常:net/minecraft/m/d 已由 Java 运行时的更新版本编译( class 文件版本 0.0),此版本的 Java Runtime 仅识别最高 52.0 的 class 文件版本
我试图找到一种方法来设置类文件版本,但找不到,请知道吗?
【问题讨论】: