[FIX] Удалил JavaAssist из JAConfigurator - для возможности сложной обфускации.

This commit is contained in:
Zaxar163 2019-08-21 17:41:27 +03:00
parent 898a3dd85d
commit e8ba2cc557
4 changed files with 98 additions and 115 deletions

View file

@ -1,109 +1,100 @@
package pro.gravit.launchserver.binary; package pro.gravit.launchserver.binary;
import java.io.IOException; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
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 javassist.CannotCompileException; import org.objectweb.asm.Type;
import javassist.ClassPool;
import javassist.CtClass; import pro.gravit.launcher.AutogenConfig;
import javassist.CtConstructor;
import javassist.CtMethod;
import javassist.NotFoundException;
import pro.gravit.launcher.LauncherConfig; import pro.gravit.launcher.LauncherConfig;
import pro.gravit.launchserver.binary.tasks.MainBuildTask; import pro.gravit.launcher.modules.Module;
import pro.gravit.launcher.modules.ModulesManager;
import pro.gravit.launchserver.asm.ClassMetadataReader;
import pro.gravit.launchserver.asm.SafeClassWriter;
public class JAConfigurator implements AutoCloseable { public class JAConfigurator {
public ClassPool pool; private static final String modulesManagerName = Type.getInternalName(ModulesManager.class);
public CtClass ctClass; private static final String registerModDesc = Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Module.class));
public CtConstructor ctConstructor; private static final String autoGenConfigName = Type.getInternalName(AutogenConfig.class);
public CtMethod initModuleMethod; private static final String stringName = Type.getInternalName(String.class);
String classname; private final ClassNode configclass;
StringBuilder body; private final MethodNode constructor;
StringBuilder moduleBody; private final MethodNode initModuleMethod;
int autoincrement;
public JAConfigurator(String configclass, MainBuildTask jarLauncherBinary) throws NotFoundException { public JAConfigurator(ClassNode configclass) {
pool = new ClassPool(false); this.configclass = configclass;
pool.appendSystemPath(); constructor = configclass.methods.stream().filter(e -> "<init>".equals(e.name)).findFirst().get();
classname = configclass; constructor.instructions = new InsnList();
ctClass = pool.get(classname); initModuleMethod = configclass.methods.stream().filter(e -> "initModules".equals(e.name)).findFirst().get();
ctConstructor = ctClass.getDeclaredConstructor(null); initModuleMethod.instructions = new InsnList();
initModuleMethod = ctClass.getDeclaredMethod("initModules");
body = new StringBuilder("{ isInitModules = false; ");
moduleBody = new StringBuilder("{ isInitModules = true; ");
autoincrement = 0;
} }
public void addModuleClass(String fullName) { public void addModuleClass(String fullName) {
moduleBody.append("pro.gravit.launcher.modules.Module mod"); initModuleMethod.instructions.insert(new MethodInsnNode(Opcodes.INVOKEINTERFACE, modulesManagerName, "registerModule", registerModDesc));
moduleBody.append(autoincrement); initModuleMethod.instructions.insert(new MethodInsnNode(Opcodes.INVOKESPECIAL, fullName.replace('.', '/'), "<init>", "()V"));
moduleBody.append(" = new "); initModuleMethod.instructions.insert(new TypeInsnNode(Opcodes.NEW, fullName.replace('.', '/')));
moduleBody.append(fullName);
moduleBody.append("();");
moduleBody.append("pro.gravit.launcher.Launcher.modulesManager.registerModule( mod");
moduleBody.append(autoincrement);
moduleBody.append(");");
autoincrement++;
} }
@Override public byte[] getBytecode(ClassMetadataReader reader) {
public void close() { ClassWriter cw = new SafeClassWriter(reader, ClassWriter.COMPUTE_FRAMES);
ctClass.defrost(); configclass.accept(cw);
} return cw.toByteArray();
public CtClass getCtClass() {
return ctClass;
}
public byte[] getBytecode() throws IOException, CannotCompileException {
return ctClass.toBytecode();
}
public void compile() throws CannotCompileException {
body.append("}");
moduleBody.append("}");
ctConstructor.setBody(body.toString());
initModuleMethod.insertAfter(moduleBody.toString());
if (ctClass.isFrozen()) ctClass.defrost();
} }
public String getZipEntryPath() { public String getZipEntryPath() {
return classname.replace('.', '/').concat(".class"); return configclass.name.concat(".class");
} }
public void setAddress(String address) { public void setAddress(String address) {
body.append("this.address = \""); constructor.instructions.add(new LdcInsnNode(address));
body.append(address); constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "address", stringName));
body.append("\";");
} }
public void setProjectName(String name) { public void setProjectName(String name) {
body.append("this.projectname = \""); constructor.instructions.add(new LdcInsnNode(name));
body.append(name); constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "projectname", stringName));
body.append("\";");
} }
public void setSecretKey(String key) { public void setSecretKey(String key) {
body.append("this.secretKeyClient = \""); constructor.instructions.add(new LdcInsnNode(key));
body.append(key); constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "secretKeyClient", stringName));
body.append("\";");
} }
public void setOemUnlockKey(String key) { public void setOemUnlockKey(String key) {
body.append("this.oemUnlockKey = \""); constructor.instructions.add(new LdcInsnNode(key));
body.append(key); constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "oemUnlockKey", stringName));
body.append("\";");
} }
public void setGuardType(String key) { public void setGuardType(String key) {
body.append("this.guardType = \""); constructor.instructions.add(new LdcInsnNode(key));
body.append(key); constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "guardType", stringName));
body.append("\";"); }
public 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) { public void setEnv(LauncherConfig.LauncherEnvironment env) {
int i = 2; int i = 2;
switch (env) {
switch (env) {
case DEV: case DEV:
i = 0; i = 0;
break; break;
@ -117,36 +108,35 @@ public void setEnv(LauncherConfig.LauncherEnvironment env) {
i = 3; i = 3;
break; break;
} }
body.append("this.env = "); push(i);
body.append(i); constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "env", Type.INT_TYPE.getInternalName()));
body.append(";");
} }
public void setClientPort(int port) { public void setClientPort(int port) {
body.append("this.clientPort = "); push(port);
body.append(port); constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "clientPort", Type.INT_TYPE.getInternalName()));
body.append(";");
} }
public void setWarningMissArchJava(boolean b) { public void setWarningMissArchJava(boolean b) {
body.append("this.isWarningMissArchJava = "); constructor.instructions.add(new InsnNode(b ? Opcodes.ICONST_1 : Opcodes.ICONST_0));
body.append(b ? "true" : "false"); constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "isWarningMissArchJava", Type.BOOLEAN_TYPE.getInternalName()));
body.append(";");
} }
public void setGuardLicense(String name, String key, String encryptKey) { public void setGuardLicense(String name, String key, String encryptKey) {
body.append("this.guardLicenseName = \""); constructor.instructions.add(new LdcInsnNode(name));
body.append(name); constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "guardLicenseName", stringName));
body.append("\";"); constructor.instructions.add(new LdcInsnNode(key));
body.append("this.guardLicenseKey = \""); constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "guardLicenseKey", stringName));
body.append(key); constructor.instructions.add(new LdcInsnNode(encryptKey));
body.append("\";"); constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "guardLicenseEncryptKey", stringName));
body.append("this.guardLicenseEncryptKey = \"");
body.append(encryptKey);
body.append("\";");
} }
public ClassPool getPool() { public void nullGuardLicense() {
return pool; constructor.instructions.add(new InsnNode(Opcodes.ACONST_NULL));
constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "guardLicenseName", stringName));
constructor.instructions.add(new InsnNode(Opcodes.ACONST_NULL));
constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "guardLicenseKey", stringName));
constructor.instructions.add(new InsnNode(Opcodes.ACONST_NULL));
constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "guardLicenseEncryptKey", stringName));
} }
} }

View file

@ -16,8 +16,9 @@
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream; import java.util.zip.ZipOutputStream;
import javassist.CannotCompileException; import org.objectweb.asm.ClassReader;
import javassist.NotFoundException; import org.objectweb.asm.tree.ClassNode;
import pro.gravit.launcher.AutogenConfig; import pro.gravit.launcher.AutogenConfig;
import pro.gravit.launcher.Launcher; import pro.gravit.launcher.Launcher;
import pro.gravit.launcher.LauncherConfig; import pro.gravit.launcher.LauncherConfig;
@ -115,22 +116,17 @@ public String getName() {
@Override @Override
public Path process(Path inputJar) throws IOException { public Path process(Path inputJar) throws IOException {
Path outputJar = server.launcherBinary.nextPath("main"); Path outputJar = server.launcherBinary.nextPath("main");
try (ZipOutputStream output = new ZipOutputStream(IOHelper.newOutput(outputJar)); try (ZipOutputStream output = new ZipOutputStream(IOHelper.newOutput(outputJar))) {
JAConfigurator jaConfigurator = new JAConfigurator(AutogenConfig.class.getName(), this)) { ClassNode cn = new ClassNode();
jaConfigurator.pool.insertClassPath(inputJar.toFile().getAbsolutePath()); new ClassReader(IOHelper.getResourceBytes(AutogenConfig.class.getName().replace('.', '/').concat(".class"))).accept(cn, 0);
server.launcherBinary.coreLibs.stream().map(e -> e.toFile().getAbsolutePath()) JAConfigurator jaConfigurator = new JAConfigurator(cn);
.forEach(t -> {
try {
jaConfigurator.pool.appendClassPath(t);
} catch (NotFoundException e2) {
LogHelper.error(e2);
}
});
BuildContext context = new BuildContext(output, jaConfigurator, this); BuildContext context = new BuildContext(output, jaConfigurator, this);
server.buildHookManager.hook(context); server.buildHookManager.hook(context);
jaConfigurator.setAddress(server.config.netty.address); jaConfigurator.setAddress(server.config.netty.address);
if (server.config.guardLicense != null) if (server.config.guardLicense != null)
jaConfigurator.setGuardLicense(server.config.guardLicense.name, server.config.guardLicense.key, server.config.guardLicense.encryptKey); jaConfigurator.setGuardLicense(server.config.guardLicense.name, server.config.guardLicense.key, server.config.guardLicense.encryptKey);
else
jaConfigurator.nullGuardLicense();
jaConfigurator.setProjectName(server.config.projectName); jaConfigurator.setProjectName(server.config.projectName);
jaConfigurator.setSecretKey(SecurityHelper.randomStringAESKey()); jaConfigurator.setSecretKey(SecurityHelper.randomStringAESKey());
jaConfigurator.setClientPort(32148 + SecurityHelper.newRandom().nextInt(512)); jaConfigurator.setClientPort(32148 + SecurityHelper.newRandom().nextInt(512));
@ -148,11 +144,12 @@ public Path process(Path inputJar) throws IOException {
LogHelper.error(e1); LogHelper.error(e1);
} }
}); });
String zPath = jaConfigurator.getZipEntryPath();
try (ZipInputStream input = new ZipInputStream(IOHelper.newInput(inputJar))) { try (ZipInputStream input = new ZipInputStream(IOHelper.newInput(inputJar))) {
ZipEntry e = input.getNextEntry(); ZipEntry e = input.getNextEntry();
while (e != null) { while (e != null) {
String filename = e.getName(); String filename = e.getName();
if (server.buildHookManager.isContainsBlacklist(filename) || e.isDirectory()) { if (server.buildHookManager.isContainsBlacklist(filename) || e.isDirectory() || zPath.equals(filename)) {
e = input.getNextEntry(); e = input.getNextEntry();
continue; continue;
} }
@ -204,12 +201,9 @@ public Path process(Path inputJar) throws IOException {
// Write launcher config file // Write launcher config file
output.putNextEntry(newZipEntry(Launcher.CONFIG_FILE)); output.putNextEntry(newZipEntry(Launcher.CONFIG_FILE));
output.write(launcherConfigBytes); output.write(launcherConfigBytes);
ZipEntry e = newZipEntry(jaConfigurator.getZipEntryPath()); ZipEntry e = newZipEntry(zPath);
output.putNextEntry(e); output.putNextEntry(e);
jaConfigurator.compile(); output.write(jaConfigurator.getBytecode(reader));
output.write(jaConfigurator.getBytecode());
} catch (CannotCompileException | NotFoundException e) {
throw new IOException(e);
} }
reader.close(); reader.close();
return outputJar; return outputJar;

View file

@ -4,8 +4,6 @@ public class AutogenConfig {
public String projectname; public String projectname;
public String address; public String address;
public int clientPort; public int clientPort;
@SuppressWarnings("unused")
private boolean isInitModules;
public String guardType; public String guardType;
public String secretKeyClient; public String secretKeyClient;
public String oemUnlockKey; public String oemUnlockKey;
@ -23,5 +21,6 @@ public class AutogenConfig {
} }
public void initModules() { public void initModules() {
} }
} }

@ -1 +1 @@
Subproject commit f6831f4df4633b9ba67edc194580833c7a19ce51 Subproject commit 36559441ba26db3cc71818bd8a93b6464f7f00e0