Last active
February 5, 2024 11:15
-
-
Save rbrick/8e615031e3fbeb9e9825072c80ad7a2e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ClassReader reader = new ClassReader(bungeecordJar.getInputStream(jarEntry)); | |
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); | |
ClassNode node = new ClassNode(); { | |
reader.accept(node, 0); | |
} | |
for (int i = 0; i < node.fields.size(); i++) { | |
// prevent duplicates if the jar is already patched | |
if (node.fields.get(i).name.equals("lcServer")) { | |
node.fields.remove(node.fields.get(i--)); | |
} | |
} | |
node.fields.add(new FieldNode(ACC_PRIVATE, "lcServer", "Ljava/lang/String;", null, null)); | |
for (MethodNode mn: node.methods) { | |
if (mn.name.equalsIgnoreCase("<init>")) { | |
InsnList insnList = new InsnList(); { | |
// this.lcServer = "Server Name"; | |
insnList.add(new VarInsnNode(ALOAD, 0)); | |
insnList.add(new LdcInsnNode(server)); | |
insnList.add(new FieldInsnNode(PUTFIELD, "net/md_5/bungee/api/ServerPing", "lcServer", "Ljava/lang/String;")); | |
} | |
for (int i = 0; i < mn.instructions.size(); i++) { | |
// insert at the very end | |
if (mn.instructions.get(i).getOpcode() == INVOKESPECIAL) { | |
if (mn.instructions.get(i) instanceof MethodInsnNode) { | |
if (!((MethodInsnNode) mn.instructions.get(i)).desc.equalsIgnoreCase("()V")) { | |
// likely an constructor similar to this(x, y, z); | |
// we want to skip these. | |
break; | |
} | |
} | |
} | |
if (mn.instructions.get(i).getOpcode() == PUTFIELD) { | |
if (((FieldInsnNode) mn.instructions.get(i)).name.equalsIgnoreCase("lcServer")) { | |
// We want to prevent possible duplicates if the jar is already patched | |
for (int j = 0; j < 3; j++) { | |
mn.instructions.remove(mn.instructions.get(i--)); | |
} | |
} | |
} | |
// Inject right before the RETURN statement | |
// We don't need to worry about anything like IRETURN. This is a void function | |
if (mn.instructions.get(i).getOpcode() == RETURN) { | |
mn.instructions.insertBefore(mn.instructions.get(i), insnList); | |
break; | |
} | |
} | |
} | |
} | |
node.accept(classWriter); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment