diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/asm/ConfigGenerator.java b/LaunchServer/src/main/java/pro/gravit/launchserver/asm/ConfigGenerator.java new file mode 100644 index 00000000..20854354 --- /dev/null +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/asm/ConfigGenerator.java @@ -0,0 +1,66 @@ +package pro.gravit.launchserver.asm; + +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.FieldInsnNode; +import org.objectweb.asm.tree.InsnList; +import org.objectweb.asm.tree.InsnNode; +import org.objectweb.asm.tree.LdcInsnNode; +import org.objectweb.asm.tree.MethodInsnNode; +import org.objectweb.asm.tree.MethodNode; +import org.objectweb.asm.tree.VarInsnNode; + +public class ConfigGenerator { + protected static final String stringDesc = Type.getDescriptor(String.class); + protected final ClassNode configclass; + protected final MethodNode constructor; + + public ConfigGenerator(ClassNode configclass) { + this.configclass = configclass; + constructor = this.configclass.methods.stream().filter(e -> "".equals(e.name)).findFirst().get(); + constructor.instructions = new InsnList(); + constructor.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); + constructor.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), "", "()V")); + } + + public byte[] getBytecode(ClassMetadataReader reader) { + constructor.instructions.add(new InsnNode(Opcodes.RETURN)); + ClassWriter cw = new SafeClassWriter(reader, ClassWriter.COMPUTE_FRAMES); + configclass.accept(cw); + return cw.toByteArray(); + } + + public String getZipEntryPath() { + return configclass.name.concat(".class"); + } + + public void setStringField(String name, String value) + { + constructor.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); + constructor.instructions.add(NodeUtils.getSafeStringInsnList(value)); + constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, configclass.name, name, stringDesc)); + } + + public void setIntegerField(String name, int value) + { + constructor.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); + constructor.instructions.add(NodeUtils.push(value)); + constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, configclass.name, name, Type.INT_TYPE.getInternalName())); + } + + public void setLongField(String name, long value) + { + constructor.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); + constructor.instructions.add(new LdcInsnNode(value)); + constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, configclass.name, name, Type.INT_TYPE.getInternalName())); + } + + public void setBooleanField(String name, boolean b) + { + constructor.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); + constructor.instructions.add(new InsnNode(b ? Opcodes.ICONST_1 : Opcodes.ICONST_0)); + constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, configclass.name, name, Type.BOOLEAN_TYPE.getInternalName())); + } +} diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/asm/NodeUtils.java b/LaunchServer/src/main/java/pro/gravit/launchserver/asm/NodeUtils.java index c669f763..13e80273 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/asm/NodeUtils.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/asm/NodeUtils.java @@ -2,7 +2,6 @@ import java.io.IOException; import java.io.InputStream; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -163,7 +162,7 @@ public static int opcodeEmulation(AbstractInsnNode e) { public static InsnList getSafeStringInsnList(String string) { InsnList insnList = new InsnList(); - if (string.length() * 2 < MAX_SAFE_BYTE_COUNT) { + if ((string.length() * 3) < MAX_SAFE_BYTE_COUNT) { // faster check insnList.add(new LdcInsnNode(string)); return insnList; } @@ -219,4 +218,17 @@ public static int getUtf8CharSize(char c) { } return 3; } + + public static InsnList push(final int value) { + InsnList ret = new InsnList(); + if (value >= -1 && value <= 5) + ret.add(new InsnNode(Opcodes.ICONST_0 + value)); + else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) + ret.add(new IntInsnNode(Opcodes.BIPUSH, value)); + else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) + ret.add(new IntInsnNode(Opcodes.SIPUSH, value)); + else + ret.add(new LdcInsnNode(value)); + return ret; + } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/binary/LauncherConfigurator.java b/LaunchServer/src/main/java/pro/gravit/launchserver/binary/LauncherConfigurator.java index 9494a143..e81b20de 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/binary/LauncherConfigurator.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/binary/LauncherConfigurator.java @@ -1,42 +1,28 @@ package pro.gravit.launchserver.binary; -import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.FieldInsnNode; import org.objectweb.asm.tree.InsnList; import org.objectweb.asm.tree.InsnNode; -import org.objectweb.asm.tree.IntInsnNode; -import org.objectweb.asm.tree.LdcInsnNode; import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.TypeInsnNode; -import org.objectweb.asm.tree.VarInsnNode; -import pro.gravit.launcher.AutogenConfig; import pro.gravit.launcher.LauncherConfig; import pro.gravit.launcher.modules.LauncherModule; -import pro.gravit.launchserver.asm.ClassMetadataReader; -import pro.gravit.launchserver.asm.SafeClassWriter; +import pro.gravit.launchserver.asm.ConfigGenerator; -public class LauncherConfigurator { +public class LauncherConfigurator extends ConfigGenerator { private static final String modulesManagerName = "pro/gravit/launcher/modules/LauncherModulesManager"; private static final String launcherName = "pro/gravit/launcher/LauncherEngine"; private static final String modulesManagerDesc = "Lpro/gravit/launcher/client/ClientModuleManager;"; private static final String registerModDesc = Type.getMethodDescriptor(Type.getType(LauncherModule.class), Type.getType(LauncherModule.class)); - private static final String autoGenConfigName = Type.getInternalName(AutogenConfig.class); - private static final String stringDesc = Type.getDescriptor(String.class); - private final ClassNode configclass; - private final MethodNode constructor; private final MethodNode initModuleMethod; public LauncherConfigurator(ClassNode configclass) { - this.configclass = configclass; - constructor = configclass.methods.stream().filter(e -> "".equals(e.name)).findFirst().get(); - constructor.instructions = new InsnList(); - constructor.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); - constructor.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), "", "()V")); + super(configclass); initModuleMethod = configclass.methods.stream().filter(e -> "initModules".equals(e.name)).findFirst().get(); initModuleMethod.instructions = new InsnList(); } @@ -49,18 +35,6 @@ public void addModuleClass(String fullName) { initModuleMethod.instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE, modulesManagerName, "loadModule", registerModDesc)); } - public byte[] getBytecode(ClassMetadataReader reader) { - constructor.instructions.add(new InsnNode(Opcodes.RETURN)); - initModuleMethod.instructions.add(new InsnNode(Opcodes.RETURN)); - ClassWriter cw = new SafeClassWriter(reader, ClassWriter.COMPUTE_FRAMES); - configclass.accept(cw); - return cw.toByteArray(); - } - - public String getZipEntryPath() { - return configclass.name.concat(".class"); - } - public void setAddress(String address) { setStringField("address", address); } @@ -81,36 +55,17 @@ public void setOemUnlockKey(String key) { setStringField("oemUnlockKey", key); } - private void setStringField(String name, String value) - { - constructor.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); - constructor.instructions.add(new LdcInsnNode(value)); - constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, name, stringDesc)); - } - public void setGuardType(String key) { setStringField("guardType", key); } + public void setSecureCheck(String hash, String salt) { setStringField("secureCheckHash", hash); setStringField("secureCheckSalt", salt); } - - private void push(final int value) { - if (value >= -1 && value <= 5) - constructor.instructions.add(new InsnNode(Opcodes.ICONST_0 + value)); - else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) - constructor.instructions.add(new IntInsnNode(Opcodes.BIPUSH, value)); - else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) - constructor.instructions.add(new IntInsnNode(Opcodes.SIPUSH, value)); - else - constructor.instructions.add(new LdcInsnNode(value)); - } - + public void setEnv(LauncherConfig.LauncherEnvironment env) { - constructor.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); int i = 2; - switch (env) { case DEV: i = 0; @@ -125,29 +80,14 @@ public void setEnv(LauncherConfig.LauncherEnvironment env) { i = 3; break; } - push(i); - constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "env", Type.INT_TYPE.getInternalName())); + setIntegerField("env", i); } public void setClientPort(int port) { setIntegerField("clientPort", port); } - public void setIntegerField(String name, int value) - { - constructor.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); - push(value); - constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, name, Type.INT_TYPE.getInternalName())); - } - public void setWarningMissArchJava(boolean b) { setBooleanField("isWarningMissArchJava", b); } - - private void setBooleanField(String name, boolean b) - { - constructor.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); - constructor.instructions.add(new InsnNode(b ? Opcodes.ICONST_1 : Opcodes.ICONST_0)); - constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, name, Type.BOOLEAN_TYPE.getInternalName())); - } }