[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;
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 javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtMethod;
import javassist.NotFoundException;
import org.objectweb.asm.Type;
import pro.gravit.launcher.AutogenConfig;
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 ClassPool pool;
public CtClass ctClass;
public CtConstructor ctConstructor;
public CtMethod initModuleMethod;
String classname;
StringBuilder body;
StringBuilder moduleBody;
int autoincrement;
public class JAConfigurator {
private static final String modulesManagerName = Type.getInternalName(ModulesManager.class);
private static final String registerModDesc = Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Module.class));
private static final String autoGenConfigName = Type.getInternalName(AutogenConfig.class);
private static final String stringName = Type.getInternalName(String.class);
private final ClassNode configclass;
private final MethodNode constructor;
private final MethodNode initModuleMethod;
public JAConfigurator(String configclass, MainBuildTask jarLauncherBinary) throws NotFoundException {
pool = new ClassPool(false);
pool.appendSystemPath();
classname = configclass;
ctClass = pool.get(classname);
ctConstructor = ctClass.getDeclaredConstructor(null);
initModuleMethod = ctClass.getDeclaredMethod("initModules");
body = new StringBuilder("{ isInitModules = false; ");
moduleBody = new StringBuilder("{ isInitModules = true; ");
autoincrement = 0;
public JAConfigurator(ClassNode configclass) {
this.configclass = configclass;
constructor = configclass.methods.stream().filter(e -> "<init>".equals(e.name)).findFirst().get();
constructor.instructions = new InsnList();
initModuleMethod = configclass.methods.stream().filter(e -> "initModules".equals(e.name)).findFirst().get();
initModuleMethod.instructions = new InsnList();
}
public void addModuleClass(String fullName) {
moduleBody.append("pro.gravit.launcher.modules.Module mod");
moduleBody.append(autoincrement);
moduleBody.append(" = new ");
moduleBody.append(fullName);
moduleBody.append("();");
moduleBody.append("pro.gravit.launcher.Launcher.modulesManager.registerModule( mod");
moduleBody.append(autoincrement);
moduleBody.append(");");
autoincrement++;
initModuleMethod.instructions.insert(new MethodInsnNode(Opcodes.INVOKEINTERFACE, modulesManagerName, "registerModule", registerModDesc));
initModuleMethod.instructions.insert(new MethodInsnNode(Opcodes.INVOKESPECIAL, fullName.replace('.', '/'), "<init>", "()V"));
initModuleMethod.instructions.insert(new TypeInsnNode(Opcodes.NEW, fullName.replace('.', '/')));
}
@Override
public void close() {
ctClass.defrost();
}
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 byte[] getBytecode(ClassMetadataReader reader) {
ClassWriter cw = new SafeClassWriter(reader, ClassWriter.COMPUTE_FRAMES);
configclass.accept(cw);
return cw.toByteArray();
}
public String getZipEntryPath() {
return classname.replace('.', '/').concat(".class");
return configclass.name.concat(".class");
}
public void setAddress(String address) {
body.append("this.address = \"");
body.append(address);
body.append("\";");
constructor.instructions.add(new LdcInsnNode(address));
constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "address", stringName));
}
public void setProjectName(String name) {
body.append("this.projectname = \"");
body.append(name);
body.append("\";");
constructor.instructions.add(new LdcInsnNode(name));
constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "projectname", stringName));
}
public void setSecretKey(String key) {
body.append("this.secretKeyClient = \"");
body.append(key);
body.append("\";");
constructor.instructions.add(new LdcInsnNode(key));
constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "secretKeyClient", stringName));
}
public void setOemUnlockKey(String key) {
body.append("this.oemUnlockKey = \"");
body.append(key);
body.append("\";");
constructor.instructions.add(new LdcInsnNode(key));
constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "oemUnlockKey", stringName));
}
public void setGuardType(String key) {
body.append("this.guardType = \"");
body.append(key);
body.append("\";");
constructor.instructions.add(new LdcInsnNode(key));
constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "guardType", stringName));
}
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) {
int i = 2;
switch (env) {
case DEV:
i = 0;
break;
@ -117,36 +108,35 @@ public void setEnv(LauncherConfig.LauncherEnvironment env) {
i = 3;
break;
}
body.append("this.env = ");
body.append(i);
body.append(";");
push(i);
constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "env", Type.INT_TYPE.getInternalName()));
}
public void setClientPort(int port) {
body.append("this.clientPort = ");
body.append(port);
body.append(";");
push(port);
constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "clientPort", Type.INT_TYPE.getInternalName()));
}
public void setWarningMissArchJava(boolean b) {
body.append("this.isWarningMissArchJava = ");
body.append(b ? "true" : "false");
body.append(";");
constructor.instructions.add(new InsnNode(b ? Opcodes.ICONST_1 : Opcodes.ICONST_0));
constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "isWarningMissArchJava", Type.BOOLEAN_TYPE.getInternalName()));
}
public void setGuardLicense(String name, String key, String encryptKey) {
body.append("this.guardLicenseName = \"");
body.append(name);
body.append("\";");
body.append("this.guardLicenseKey = \"");
body.append(key);
body.append("\";");
body.append("this.guardLicenseEncryptKey = \"");
body.append(encryptKey);
body.append("\";");
constructor.instructions.add(new LdcInsnNode(name));
constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "guardLicenseName", stringName));
constructor.instructions.add(new LdcInsnNode(key));
constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "guardLicenseKey", stringName));
constructor.instructions.add(new LdcInsnNode(encryptKey));
constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "guardLicenseEncryptKey", stringName));
}
public ClassPool getPool() {
return pool;
public void nullGuardLicense() {
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.ZipOutputStream;
import javassist.CannotCompileException;
import javassist.NotFoundException;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.ClassNode;
import pro.gravit.launcher.AutogenConfig;
import pro.gravit.launcher.Launcher;
import pro.gravit.launcher.LauncherConfig;
@ -115,22 +116,17 @@ public String getName() {
@Override
public Path process(Path inputJar) throws IOException {
Path outputJar = server.launcherBinary.nextPath("main");
try (ZipOutputStream output = new ZipOutputStream(IOHelper.newOutput(outputJar));
JAConfigurator jaConfigurator = new JAConfigurator(AutogenConfig.class.getName(), this)) {
jaConfigurator.pool.insertClassPath(inputJar.toFile().getAbsolutePath());
server.launcherBinary.coreLibs.stream().map(e -> e.toFile().getAbsolutePath())
.forEach(t -> {
try {
jaConfigurator.pool.appendClassPath(t);
} catch (NotFoundException e2) {
LogHelper.error(e2);
}
});
try (ZipOutputStream output = new ZipOutputStream(IOHelper.newOutput(outputJar))) {
ClassNode cn = new ClassNode();
new ClassReader(IOHelper.getResourceBytes(AutogenConfig.class.getName().replace('.', '/').concat(".class"))).accept(cn, 0);
JAConfigurator jaConfigurator = new JAConfigurator(cn);
BuildContext context = new BuildContext(output, jaConfigurator, this);
server.buildHookManager.hook(context);
jaConfigurator.setAddress(server.config.netty.address);
if (server.config.guardLicense != null)
jaConfigurator.setGuardLicense(server.config.guardLicense.name, server.config.guardLicense.key, server.config.guardLicense.encryptKey);
else
jaConfigurator.nullGuardLicense();
jaConfigurator.setProjectName(server.config.projectName);
jaConfigurator.setSecretKey(SecurityHelper.randomStringAESKey());
jaConfigurator.setClientPort(32148 + SecurityHelper.newRandom().nextInt(512));
@ -148,11 +144,12 @@ public Path process(Path inputJar) throws IOException {
LogHelper.error(e1);
}
});
String zPath = jaConfigurator.getZipEntryPath();
try (ZipInputStream input = new ZipInputStream(IOHelper.newInput(inputJar))) {
ZipEntry e = input.getNextEntry();
while (e != null) {
String filename = e.getName();
if (server.buildHookManager.isContainsBlacklist(filename) || e.isDirectory()) {
if (server.buildHookManager.isContainsBlacklist(filename) || e.isDirectory() || zPath.equals(filename)) {
e = input.getNextEntry();
continue;
}
@ -204,12 +201,9 @@ public Path process(Path inputJar) throws IOException {
// Write launcher config file
output.putNextEntry(newZipEntry(Launcher.CONFIG_FILE));
output.write(launcherConfigBytes);
ZipEntry e = newZipEntry(jaConfigurator.getZipEntryPath());
ZipEntry e = newZipEntry(zPath);
output.putNextEntry(e);
jaConfigurator.compile();
output.write(jaConfigurator.getBytecode());
} catch (CannotCompileException | NotFoundException e) {
throw new IOException(e);
output.write(jaConfigurator.getBytecode(reader));
}
reader.close();
return outputJar;

View file

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

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