From 1fd28e12fb4236b885b56af0ceb72b25a071b803 Mon Sep 17 00:00:00 2001 From: ME1312 Date: Fri, 15 Mar 2024 13:34:00 -0400 Subject: [PATCH] Invoke helper methods directly --- ...erarchyVisitor.java => SourceScanner.java} | 12 +-- java/vanillacord/packaging/Bundle.java | 4 +- java/vanillacord/packaging/FatJar.java | 4 +- java/vanillacord/patch/DedicatedServer.java | 11 ++- java/vanillacord/patch/HandshakeListener.java | 9 ++- java/vanillacord/patch/LoginListener.java | 78 ++++++++++++------- java/vanillacord/patch/LoginPacket.java | 9 ++- java/vanillacord/server/VanillaCord.java | 22 +----- pom.xml | 2 +- 9 files changed, 90 insertions(+), 61 deletions(-) rename java/vanillacord/data/{HierarchyVisitor.java => SourceScanner.java} (88%) diff --git a/java/vanillacord/data/HierarchyVisitor.java b/java/vanillacord/data/SourceScanner.java similarity index 88% rename from java/vanillacord/data/HierarchyVisitor.java rename to java/vanillacord/data/SourceScanner.java index 11a8fda..f934a56 100644 --- a/java/vanillacord/data/HierarchyVisitor.java +++ b/java/vanillacord/data/SourceScanner.java @@ -6,12 +6,12 @@ import org.objectweb.asm.Opcodes; import vanillacord.packaging.Package; -public class HierarchyVisitor extends HierarchyScanner { +public class SourceScanner extends HierarchyScanner { private final Package file; private ClassData data; private boolean hasTID; - public HierarchyVisitor(Package file) { + public SourceScanner(Package file) { super(Opcodes.ASM9, file.types); this.file = file; } @@ -42,15 +42,15 @@ public void visitLdcInsn(Object value) { if (value instanceof String) { if ("Server console handler".equals(value)) { System.out.print("Found the dedicated server: "); - System.out.println(HierarchyVisitor.super.name); + System.out.println(SourceScanner.super.name); file.sources.startup = data; } else if ("Unexpected hello packet".equals(value)) { System.out.print("Found the login listener: "); - System.out.println(HierarchyVisitor.super.name); + System.out.println(SourceScanner.super.name); file.sources.login = data; } else if (hasTID && "Payload may not be larger than 1048576 bytes".equals(value)) { System.out.print("Found a login extension packet: "); - System.out.println(HierarchyVisitor.super.name); + System.out.println(SourceScanner.super.name); if (file.sources.send == null) { file.sources.send = data; } else { @@ -58,7 +58,7 @@ public void visitLdcInsn(Object value) { } } else if ("multiplayer.disconnect.incompatible".equals(value) || "multiplayer.disconnect.outdated_server".equals(value) || ((String) value).startsWith("Outdated client! Please use")) { System.out.print("Found the handshake listener: "); - System.out.println(HierarchyVisitor.super.name); + System.out.println(SourceScanner.super.name); file.sources.handshake = data; } } diff --git a/java/vanillacord/packaging/Bundle.java b/java/vanillacord/packaging/Bundle.java index 4b416c9..a6ea7ed 100644 --- a/java/vanillacord/packaging/Bundle.java +++ b/java/vanillacord/packaging/Bundle.java @@ -4,7 +4,7 @@ import org.objectweb.asm.ClassReader; import vanillacord.Patcher; import vanillacord.data.Digest; -import vanillacord.data.HierarchyVisitor; +import vanillacord.data.SourceScanner; import java.io.*; import java.net.URL; @@ -63,7 +63,7 @@ List load(ClassLoader bundle, String name, Consumer actio public ZipInputStream read(File file) throws Throwable { URLClassLoader bundle = new URLClassLoader(new URL[]{ (this.file = file).toURI().toURL() }, null); load(bundle, "libraries", reader -> reader.accept(new HierarchyScanner(types), ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG)); - List versions = load(bundle, "versions", reader -> reader.accept(new HierarchyVisitor(this), ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG)); + List versions = load(bundle, "versions", reader -> reader.accept(new SourceScanner(this), ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG)); if (versions.size() != 1) throw new IllegalStateException("More or less than one version was distributed"); return new ZipInputStream(bundle.getResourceAsStream("META-INF/versions/" + (server = versions.get(0))[2])); } diff --git a/java/vanillacord/packaging/FatJar.java b/java/vanillacord/packaging/FatJar.java index ce5ffd5..56e517b 100644 --- a/java/vanillacord/packaging/FatJar.java +++ b/java/vanillacord/packaging/FatJar.java @@ -1,7 +1,7 @@ package vanillacord.packaging; import org.objectweb.asm.ClassReader; -import vanillacord.data.HierarchyVisitor; +import vanillacord.data.SourceScanner; import java.io.File; import java.io.FileInputStream; @@ -17,7 +17,7 @@ public ZipInputStream read(File file) throws Throwable { try (ZipInputStream zis = new ZipInputStream(new FileInputStream(file))) { for (ZipEntry entry; (entry = zis.getNextEntry()) != null;) { if (entry.getName().endsWith(".class")) { - new ClassReader(zis).accept(new HierarchyVisitor(this), ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG); + new ClassReader(zis).accept(new SourceScanner(this), ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG); } } } diff --git a/java/vanillacord/patch/DedicatedServer.java b/java/vanillacord/patch/DedicatedServer.java index 893ae87..d66c2d3 100644 --- a/java/vanillacord/patch/DedicatedServer.java +++ b/java/vanillacord/patch/DedicatedServer.java @@ -34,15 +34,24 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str @Override public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) { super.visitMethodInsn(opcode, owner, name, descriptor, isInterface); - if (state == 0 && opcode == INVOKEVIRTUAL && owner.equals("java/lang/Thread") && descriptor.equals("()V")) { + if (state == 0 && opcode == INVOKEVIRTUAL && owner.equals("java/lang/Thread") && name.equals("start") && descriptor.equals("()V")) { state = 1; } else if (state == 3 && opcode == INVOKEINTERFACE && owner.endsWith("/Logger")) { + Label start, end, jump, handler; + mv.visitTryCatchBlock(start = new Label(), end = new Label(), handler = new Label(), "java/lang/ExceptionInInitializerError"); + mv.visitLabel(start); mv.visitFieldInsn(GETSTATIC, "vanillacord/server/VanillaCord", "helper", "Lvanillacord/server/ForwardingHelper;" ); mv.visitInsn(POP); + mv.visitLabel(end); + mv.visitJumpInsn(GOTO, jump = new Label()); + mv.visitLabel(handler); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/ExceptionInInitializerError", "getCause", "()Ljava/lang/Throwable;", false); + mv.visitInsn(ATHROW); + mv.visitLabel(jump); state = 4; } } diff --git a/java/vanillacord/patch/HandshakeListener.java b/java/vanillacord/patch/HandshakeListener.java index c8e88a2..7a6bb8e 100644 --- a/java/vanillacord/patch/HandshakeListener.java +++ b/java/vanillacord/patch/HandshakeListener.java @@ -42,6 +42,11 @@ public void visitMethodInsn(int opcode, String owner, String name, String descri super.visitMethodInsn(opcode, owner, name, descriptor, isInterface); if (vanilla && opcode == INVOKEVIRTUAL && file.sources.connection.type.type.getInternalName().equals(owner)) { mv.visitLabel(new Label()); + mv.visitFieldInsn(GETSTATIC, + "vanillacord/server/VanillaCord", + "helper", + "Lvanillacord/server/ForwardingHelper;" + ); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, connection.owner.clazz.type.getInternalName(), @@ -49,8 +54,8 @@ public void visitMethodInsn(int opcode, String owner, String name, String descri connection.descriptor ); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKESTATIC, - "vanillacord/server/VanillaCord", + mv.visitMethodInsn(INVOKEVIRTUAL, + "vanillacord/server/ForwardingHelper", "parseHandshake", "(Ljava/lang/Object;Ljava/lang/Object;)V", false diff --git a/java/vanillacord/patch/LoginListener.java b/java/vanillacord/patch/LoginListener.java index c53963d..d16c091 100644 --- a/java/vanillacord/patch/LoginListener.java +++ b/java/vanillacord/patch/LoginListener.java @@ -55,6 +55,11 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions); mv.visitCode(); mv.visitLabel(new Label()); + mv.visitFieldInsn(GETSTATIC, + "vanillacord/server/VanillaCord", + "helper", + "Lvanillacord/server/ForwardingHelper;" + ); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, file.sources.connection.owner.clazz.type.getInternalName(), @@ -68,8 +73,8 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str "()Ljava/lang/String;", false ); - mv.visitMethodInsn(INVOKESTATIC, - "vanillacord/server/VanillaCord", + mv.visitMethodInsn(INVOKEVIRTUAL, + "vanillacord/server/ForwardingHelper", "injectProfile", "(Ljava/lang/Object;Ljava/lang/String;)Lcom/mojang/authlib/GameProfile;", false @@ -87,6 +92,11 @@ public void visitLabel(Label label) { super.visitLabel(label); if (prelabel) { label = new Label(); + mv.visitFieldInsn(GETSTATIC, + "vanillacord/server/VanillaCord", + "helper", + "Lvanillacord/server/ForwardingHelper;" + ); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, file.sources.connection.owner.clazz.type.getInternalName(), @@ -95,8 +105,8 @@ public void visitLabel(Label label) { ); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKESTATIC, - "vanillacord/server/VanillaCord", + mv.visitMethodInsn(INVOKEVIRTUAL, + "vanillacord/server/ForwardingHelper", "completeTransaction", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Z", false @@ -112,17 +122,20 @@ public void visitLabel(Label label) { return new MethodVisitor(ASM9, super.visitMethod(access, name, descriptor, signature, exceptions)) { private final LinkedList undo = new LinkedList(); private final MethodVisitor mv = super.mv; - private int state = 0; + private byte state = 0; private Label skip; @Override public void visitVarInsn(int opcode, int index) { if (state == 1 && opcode == ALOAD && index == 0) { - undo.add(() -> super.visitVarInsn(opcode, index)); + undo.add(() -> super.visitVarInsn(ALOAD, 0)); state = 2; return; - } else { - undo(); + } + undo(); + if (state == 6 && opcode == ALOAD && index == 0) { + undo.add(() -> super.visitVarInsn(ALOAD, 0)); + return; } super.visitVarInsn(opcode, index); } @@ -144,17 +157,12 @@ public void visitFieldInsn(int opcode, String owner, String name, String desc) { } else if (state == 2 && opcode == GETFIELD && desc.equals("Lnet/minecraft/server/MinecraftServer;")) { state = 3; - undo.add(() -> super.visitFieldInsn(opcode, owner, name, desc)); + undo.add(() -> super.visitFieldInsn(GETFIELD, owner, name, "Lnet/minecraft/server/MinecraftServer;")); + return; + } else if (state == 6 && opcode == GETFIELD && desc.equals("Ljava/lang/String;") && file.sources.login.owner.clazz.type.getInternalName().equals(owner)) { + state = 7; + undo.add(() -> super.visitFieldInsn(GETFIELD, owner, name, "Ljava/lang/String;")); return; - } else if (state == -6 && opcode == GETFIELD && desc.equals("Ljava/lang/String;") && file.sources.login.owner.clazz.type.getInternalName().equals(owner)) { - state = -7; - mv.visitFieldInsn( - GETFIELD, - file.sources.connection.owner.clazz.type.getInternalName(), - file.sources.connection.name, - file.sources.connection.descriptor - ); - mv.visitVarInsn(ALOAD, 0); } else { undo(); } @@ -168,14 +176,27 @@ public void visitMethodInsn(int opcode, String owner, String name, String desc, undo.clear(); state = 4; return; - } else if (state == -7 && opcode == INVOKESTATIC && desc.equals("(Ljava/lang/String;)Lcom/mojang/authlib/GameProfile;")) { - mv.visitMethodInsn(INVOKESTATIC, + } else if (state == 7 && opcode == INVOKESTATIC && desc.equals("(Ljava/lang/String;)Lcom/mojang/authlib/GameProfile;")) { + mv.visitFieldInsn(GETSTATIC, "vanillacord/server/VanillaCord", + "helper", + "Lvanillacord/server/ForwardingHelper;" + ); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn( + GETFIELD, + file.sources.connection.owner.clazz.type.getInternalName(), + file.sources.connection.name, + file.sources.connection.descriptor + ); + undo(); + mv.visitMethodInsn(INVOKEVIRTUAL, + "vanillacord/server/ForwardingHelper", "injectProfile", "(Ljava/lang/Object;Ljava/lang/String;)Lcom/mojang/authlib/GameProfile;", false ); - state = -8; + state = 8; return; } else { undo(); @@ -186,7 +207,7 @@ public void visitMethodInsn(int opcode, String owner, String name, String desc, @Override public void visitJumpInsn(int opcode, Label label) { if (state == 4 && opcode == IFEQ) { - state = -5; + state = 5; skip = label; } else { undo(); @@ -196,9 +217,9 @@ public void visitJumpInsn(int opcode, Label label) { @Override public void visitLabel(Label label) { - if (state == -5 && skip == label) { + if (state == 5 && skip == label) { super.mv = mv; - state = -6; + state = 6; } super.visitLabel(label); } @@ -211,15 +232,20 @@ public void visitTypeInsn(int opcode, String type) { @Override public void visitEnd() { - if (state >= 0) throw new IllegalStateException("Inject failed: 0x0" + state); + if (state != 8 && state != 6) throw new IllegalStateException("Inject failed: 0x0" + state); super.visitEnd(); } private void undo() { - if (state > 1) { + byte s; + if ((s = state) > 1 && s < 5) { for (Runnable action : undo) action.run(); undo.clear(); state = 1; + } else if (s > 5 && s < 8) { + for (Runnable action : undo) action.run(); + undo.clear(); + state = 6; } } }; diff --git a/java/vanillacord/patch/LoginPacket.java b/java/vanillacord/patch/LoginPacket.java index 3915279..ff5e34b 100644 --- a/java/vanillacord/patch/LoginPacket.java +++ b/java/vanillacord/patch/LoginPacket.java @@ -38,6 +38,11 @@ public void visitLabel(Label label) { super.visitLabel(label); if (prelabel) { label = new Label(); + mv.visitFieldInsn(GETSTATIC, + "vanillacord/server/VanillaCord", + "helper", + "Lvanillacord/server/ForwardingHelper;" + ); mv.visitVarInsn(ALOAD, 1); if (!file.sources.login.owner.clazz.type.equals(args[0])) { mv.visitTypeInsn(CHECKCAST, file.sources.login.owner.clazz.type.getInternalName()); @@ -48,8 +53,8 @@ public void visitLabel(Label label) { file.sources.connection.descriptor ); mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESTATIC, - "vanillacord/server/VanillaCord", + mv.visitMethodInsn(INVOKEVIRTUAL, + "vanillacord/server/ForwardingHelper", "initializeTransaction", "(Ljava/lang/Object;Ljava/lang/Object;)Z", false diff --git a/java/vanillacord/server/VanillaCord.java b/java/vanillacord/server/VanillaCord.java index f78e123..8107ad3 100644 --- a/java/vanillacord/server/VanillaCord.java +++ b/java/vanillacord/server/VanillaCord.java @@ -59,7 +59,7 @@ public class VanillaCord { writer.println(); writer.println("# Some forwarding standards require a seecret key to function."); writer.println("# Specify that here. Repeat this line to specify multiple."); - if (seecrets.isEmpty()) { + if (seecrets.size() == 0) { writer.println("seecret = "); } else { for (String s : seecrets) { @@ -86,7 +86,7 @@ public class VanillaCord { helper = (ForwardingHelper) MethodHandles.lookup().findConstructor(VelocityHelper.class, MethodType.methodType(void.class, LinkedList.class)).invoke(seecrets); break; default: - throw new IllegalArgumentException("Unknown forwarding option: " + forwarding); + throw new IllegalArgumentException("Unknown forwarding provider: " + forwarding); } } catch (NoClassDefFoundError e) { throw new UnsupportedOperationException(forwarding.substring(0, 1).toUpperCase(Locale.ROOT) + forwarding.substring(1).toLowerCase(Locale.ROOT) + " forwarding is not available in this version"); @@ -96,22 +96,6 @@ public class VanillaCord { } private VanillaCord() { - - } - - public static void parseHandshake(Object connection, Object handshake) { - helper.parseHandshake(connection, handshake); - } - - public static boolean initializeTransaction(Object connection, Object hello) { - return helper.initializeTransaction(connection, hello); - } - - public static boolean completeTransaction(Object connection, Object login, Object response) { - return helper.completeTransaction(connection, login, response); - } - - public static GameProfile injectProfile(Object connection, String username) { - return helper.injectProfile(connection, username); + // this constructor is never called } } diff --git a/pom.xml b/pom.xml index 226492e..8597a54 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ - 24w08b + 24w11a