diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/manangers/ModulesManager.java b/LaunchServer/src/main/java/ru/gravit/launchserver/manangers/ModulesManager.java index d86675bc..f4393dc7 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/manangers/ModulesManager.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/manangers/ModulesManager.java @@ -1,23 +1,47 @@ package ru.gravit.launchserver.manangers; +import java.io.File; +import java.io.IOException; import java.net.URL; import java.util.ArrayList; +import java.util.Collections; +import java.util.jar.JarFile; +import ru.gravit.launcher.Launcher; +import ru.gravit.launcher.LauncherAPI; import ru.gravit.launcher.LauncherClassLoader; import ru.gravit.launcher.modules.SimpleModuleManager; import ru.gravit.launchserver.LaunchServer; +import ru.gravit.launchserver.asm.ClassMetadataReader; import ru.gravit.launchserver.modules.CoreModule; import ru.gravit.launchserver.modules.LaunchServerModuleContext; +import ru.gravit.utils.helper.IOHelper; public class ModulesManager extends SimpleModuleManager { + public final ClassMetadataReader metadataReader; + public ModulesManager(LaunchServer lsrv) { modules = new ArrayList<>(1); + ClassMetadataReader metadataReader = null; + try { + metadataReader = new ClassMetadataReader(Collections.singletonList(new JarFile(new File(IOHelper.getCodeSource(Launcher.class).toUri())))); + } catch (IOException e) { } + this.metadataReader = metadataReader; classloader = new LauncherClassLoader(new URL[0], ClassLoader.getSystemClassLoader()); - context = new LaunchServerModuleContext(lsrv, classloader); + context = new LaunchServerModuleContext(lsrv, classloader, metadataReader); registerCoreModule(); } private void registerCoreModule() { load(new CoreModule()); } + + @Override + @LauncherAPI + public void loadModule(URL jarpath, String classname, boolean preload) throws ClassNotFoundException, IllegalAccessException, InstantiationException { + super.loadModule(jarpath, classname, preload); + try { + if (metadataReader != null) metadataReader.add(new JarFile(new File(IOHelper.getCodeSource(Launcher.class).toUri()))); + } catch (IOException e) { } + } } diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/modules/LaunchServerModuleContext.java b/LaunchServer/src/main/java/ru/gravit/launchserver/modules/LaunchServerModuleContext.java index d1162039..e38b8254 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/modules/LaunchServerModuleContext.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/modules/LaunchServerModuleContext.java @@ -4,14 +4,18 @@ import ru.gravit.launcher.modules.ModuleContext; import ru.gravit.launcher.modules.ModulesManagerInterface; import ru.gravit.launchserver.LaunchServer; +import ru.gravit.launchserver.asm.ClassMetadataReader; public class LaunchServerModuleContext implements ModuleContext { public final LaunchServer launchServer; public final LauncherClassLoader classloader; - public LaunchServerModuleContext(LaunchServer server, LauncherClassLoader classloader) + public final ClassMetadataReader metadataReader; + + public LaunchServerModuleContext(LaunchServer server, LauncherClassLoader classloader, ClassMetadataReader metadataReader) { launchServer = server; this.classloader = classloader; + this.metadataReader = metadataReader; } @Override public Type getType() { diff --git a/Launcher/src/main/java/ru/gravit/launcher/AvanguardStarter.java b/Launcher/src/main/java/ru/gravit/launcher/AvanguardStarter.java index 98d9ff35..3384701a 100644 --- a/Launcher/src/main/java/ru/gravit/launcher/AvanguardStarter.java +++ b/Launcher/src/main/java/ru/gravit/launcher/AvanguardStarter.java @@ -17,107 +17,113 @@ public class AvanguardStarter { static class SecurityThread implements Runnable { - @Override - public void run() { - while (!Thread.interrupted()) { - try { - if (!GuardBind.avnIsStarted()) { - LogHelper.error("Avanguard stopped! Process stopped"); - System.exit(5); - } - } catch (NullPointerException e) { - LogHelper.error("Avanguard unloaded! Process stopped"); - System.exit(6); - } - try { - Thread.sleep(2000); - } catch (InterruptedException e) { - if (!GuardBind.avnIsStarted()) { - LogHelper.error("Thread stopped! Process stopped"); - System.exit(7); - } - } - } - } - } + @Override + public void run() { + while (!Thread.interrupted()) { + try { + if (!GuardBind.avnIsStarted()) { + LogHelper.error("Avanguard stopped! Process stopped"); + System.exit(5); + } + } catch (NullPointerException e) { + LogHelper.error("Avanguard unloaded! Process stopped"); + System.exit(6); + } + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + if (!GuardBind.avnIsStarted()) { + LogHelper.error("Thread stopped! Process stopped"); + System.exit(7); + } + } + } + } + } + public static final String NAME = Launcher.getConfig().projectname; public static String avn32 = null, avn64 = null; - public static Path wrap32 = null, wrap64 = null; + public static Path wrap32 = null, wrap64 = null; - private static Path handle(Path mustdiedll, String resource) { - try { - InputStream in = IOHelper.newInput(IOHelper.getResourceURL(resource)); - byte[] orig = IOHelper.toByteArray(in); - in.close(); - if (IOHelper.exists(mustdiedll)) { - if (!matches(mustdiedll, orig)) + private static Path handle(Path mustdiedll, String resource) { + try { + InputStream in = IOHelper.newInput(IOHelper.getResourceURL(resource)); + byte[] orig = IOHelper.toByteArray(in); + in.close(); + if (IOHelper.exists(mustdiedll)) { + if (!matches(mustdiedll, orig)) transfer(orig, mustdiedll); - } else + } else transfer(orig, mustdiedll); - } catch (Exception e) { - if (e instanceof RuntimeException) - throw (RuntimeException) e; + } catch (Exception e) { + if (e instanceof RuntimeException) + throw (RuntimeException) e; throw new RuntimeException(e); - } - return mustdiedll; - } + } + return mustdiedll; + } - public static void loadVared() { - if (JVMHelper.JVM_BITS == 32) - GuardBind.startAbs(System.getProperty("avn32")); - else if (JVMHelper.JVM_BITS == 64) - GuardBind.startAbs(System.getProperty("avn64")); - } + public static void loadVared() { + if (JVMHelper.JVM_BITS == 32) + loadLib(System.getProperty("avn32")); + else if (JVMHelper.JVM_BITS == 64) + loadLib(System.getProperty("avn64")); + } - public static void main(boolean init) { - if (init) - GuardBind.init(); - GuardBind.avnRegisterThreatNotifier((int threatType) -> { - System.err.println("Threat " + GuardBind.ThreatType.getThreat(threatType).name()); - LogHelper.error("Cheating == crash!"); - System.exit(12); - return false; - }); - // нужно делать до пуска таймера! - GuardBind.setCheckTime(3000); - GuardBind.avnStartDefence(); - CommonHelper.newThread("Security Thread", true, new SecurityThread()).start(); - } + public static void start() { + loadVared(); + GuardBind.avnRegisterThreatNotifier((int threatType) -> { + System.err.println("Threat " + GuardBind.ThreatType.getThreat(threatType).name()); + LogHelper.error("Cheating == crash!"); + System.exit(12); + return false; + }); + // нужно делать до пуска таймера! + GuardBind.setCheckTime(3000); + GuardBind.avnStartDefence(); + CommonHelper.newThread("Security Thread", true, new SecurityThread()).start(); + } - private static boolean matches(Path mustdiedll, byte[] in) { - try { - return Arrays.equals(SecurityHelper.digest(DigestAlgorithm.MD5, in), - SecurityHelper.digest(DigestAlgorithm.MD5, mustdiedll)); - } catch (IOException e) { - return false; - } - } + private static boolean matches(Path mustdiedll, byte[] in) { + try { + return Arrays.equals(SecurityHelper.digest(DigestAlgorithm.MD5, in), + SecurityHelper.digest(DigestAlgorithm.MD5, mustdiedll)); + } catch (IOException e) { + return false; + } + } - private static void processArched(Path arch32, Path arch64, Path wrapper32, Path wrapper64) { - System.setProperty("avn32", IOHelper.toAbs(arch32)); - System.setProperty("avn64", IOHelper.toAbs(arch64)); - avn32 = IOHelper.toAbs(arch32); - avn64 = IOHelper.toAbs(arch64); - wrap32 = IOHelper.toAbsPath(wrapper32); - wrap64 = IOHelper.toAbsPath(wrapper64); - } + private static void processArched(Path arch32, Path arch64, Path wrapper32, Path wrapper64) { + System.setProperty("avn32", IOHelper.toAbs(arch32)); + System.setProperty("avn64", IOHelper.toAbs(arch64)); + avn32 = IOHelper.toAbs(arch32); + avn64 = IOHelper.toAbs(arch64); + wrap32 = IOHelper.toAbsPath(wrapper32); + wrap64 = IOHelper.toAbsPath(wrapper64); + } - public static void start(Path path1) throws IOException { - Path path = path1.resolve("guard"); - processArched(handle(path.resolve("Avanguard32.dll"), "Avanguard32.dll"), - handle(path.resolve("Avanguard64.dll"), "Avanguard64.dll"), - handle(path.resolve(NAME + "32.exe"), "wrapper32.exe"), - handle(path.resolve(NAME + "64.exe"), "wrapper64.exe")); - HashedDir guard = new HashedDir(path,null,true,false); - try(DirWatcher dirWatcher = new DirWatcher(path, guard, null, false)){ - CommonHelper.newThread("Guard Directory Watcher", true, dirWatcher).start(); - } - } + public static void init(Path path1) throws IOException { + Path path = path1.resolve("guard"); + processArched(handle(path.resolve("Avanguard32.dll"), "Avanguard32.dll"), + handle(path.resolve("Avanguard64.dll"), "Avanguard64.dll"), + handle(path.resolve(NAME + "32.exe"), "wrapper32.exe"), + handle(path.resolve(NAME + "64.exe"), "wrapper64.exe")); + HashedDir guard = new HashedDir(path, null, true, false); + try (DirWatcher dirWatcher = new DirWatcher(path, guard, null, false)) { + CommonHelper.newThread("Guard Directory Watcher", true, dirWatcher).start(); + } + } - private static void transfer(byte[] orig, Path mustdiedll) throws IOException { - IOHelper.createParentDirs(mustdiedll); - if (!IOHelper.exists(mustdiedll)) - mustdiedll.toFile().createNewFile(); - IOHelper.transfer(orig, mustdiedll, false); + private static void transfer(byte[] orig, Path mustdiedll) throws IOException { + IOHelper.createParentDirs(mustdiedll); + if (!IOHelper.exists(mustdiedll)) + mustdiedll.toFile().createNewFile(); + IOHelper.transfer(orig, mustdiedll, false); + } + + public static void loadLib(String path) { + LogHelper.debug("Anti-Cheat loading"); + System.load(path); + LogHelper.debug("Anti-Cheat loaded"); } } diff --git a/Launcher/src/main/java/ru/gravit/launcher/LauncherEngine.java b/Launcher/src/main/java/ru/gravit/launcher/LauncherEngine.java index fa0f1583..dc93aab1 100644 --- a/Launcher/src/main/java/ru/gravit/launcher/LauncherEngine.java +++ b/Launcher/src/main/java/ru/gravit/launcher/LauncherEngine.java @@ -67,7 +67,8 @@ import ru.gravit.launcher.serialize.stream.StreamObject; public class LauncherEngine { - @LauncherAPI + private static final boolean isUsingGuard = true; + public static void addLauncherClassBindings(Map bindings) { bindings.put("LauncherClass", Launcher.class); bindings.put("LauncherConfigClass", LauncherConfig.class); @@ -188,7 +189,6 @@ private void setScriptBindings() { addLauncherClassBindings(bindings); } - @LauncherAPI public void start(String... args) throws Throwable { Launcher.modulesManager = new ClientModuleManager(this); LauncherConfig.getAutogenConfig().initModules(); //INIT @@ -205,9 +205,9 @@ public void start(String... args) throws Throwable { LogHelper.info("Invoking start() function"); Invocable invoker = (Invocable) engine; if (JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE) { - AvanguardStarter.start((Path) invoker.invokeFunction("getPathDirHelper")); + AvanguardStarter.init((Path) invoker.invokeFunction("getPathDirHelper")); AvanguardStarter.loadVared(); - AvanguardStarter.main(false); + if (isUsingGuard) AvanguardStarter.start(); } Launcher.modulesManager.postInitModules(); invoker.invokeFunction("start", (Object) args); diff --git a/Launcher/src/main/java/ru/gravit/launcher/client/ClientLauncher.java b/Launcher/src/main/java/ru/gravit/launcher/client/ClientLauncher.java index ec198b10..165d46ae 100644 --- a/Launcher/src/main/java/ru/gravit/launcher/client/ClientLauncher.java +++ b/Launcher/src/main/java/ru/gravit/launcher/client/ClientLauncher.java @@ -149,6 +149,7 @@ public void write(HOutput output) throws IOException { private static final String[] EMPTY_ARRAY = new String[0]; private static final String MAGICAL_INTEL_OPTION = "-XX:HeapDumpPath=ThisTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump"; private static final boolean isUsingWrapper = true; + private static final boolean isUsingGuard = true; @LauncherAPI public static final String TITLE_PROPERTY = "launcher.title"; @@ -378,10 +379,7 @@ public static void main(String... args) throws Throwable { Launcher.modulesManager = new ClientModuleManager(null); LauncherConfig.getAutogenConfig().initModules(); //INIT Launcher.modulesManager.preInitModules(); - if (JVMHelper.OS_TYPE == OS.MUSTDIE) { - AvanguardStarter.loadVared(); - AvanguardStarter.main(false); - } + if (JVMHelper.OS_TYPE == OS.MUSTDIE) runAvn(); checkJVMBitsAndVersion(); JVMHelper.verifySystemProperties(ClientLauncher.class, true); LogHelper.printVersion("Client Launcher"); @@ -436,7 +434,11 @@ public static void main(String... args) throws Throwable { } } - private static URL[] resolveClassPath(Path clientDir, String... classPath) throws IOException { + private static void runAvn() { + if (isUsingGuard) AvanguardStarter.start(); // так компилятор с гарантией вырежет + } + + private static URL[] resolveClassPath(Path clientDir, String... classPath) throws IOException { Collection result = new LinkedList<>(); for (String classPathEntry : classPath) { Path path = clientDir.resolve(IOHelper.toPath(classPathEntry)); diff --git a/Launcher/src/main/java/ru/zaxar163/GuardBind.java b/Launcher/src/main/java/ru/zaxar163/GuardBind.java index 0ddfd2cc..382163fe 100644 --- a/Launcher/src/main/java/ru/zaxar163/GuardBind.java +++ b/Launcher/src/main/java/ru/zaxar163/GuardBind.java @@ -1,10 +1,6 @@ package ru.zaxar163; -import java.nio.file.Path; - import ru.gravit.launcher.LauncherAPI; -import ru.gravit.utils.helper.JVMHelper; -import ru.gravit.utils.helper.LogHelper; @LauncherAPI public final class GuardBind { @@ -73,29 +69,7 @@ public int getValue() { @LauncherAPI public static native int getCheckTime(); - - public static void init() { - LogHelper.debug("Anti-Cheat loading"); - if (JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE) - if (JVMHelper.JVM_BITS == 32) - System.loadLibrary("Avanguard32"); - else if (JVMHelper.JVM_BITS == 64) - System.loadLibrary("Avanguard64"); - LogHelper.debug("Anti-Cheat loaded"); - } - + @LauncherAPI public static native void setCheckTime(int time); - - public static void start(Path path) { - LogHelper.debug("Anti-Cheat loading"); - System.load(path.normalize().toAbsolutePath().toFile().getAbsolutePath()); - LogHelper.debug("Anti-Cheat loaded"); - } - - public static void startAbs(String path) { - LogHelper.debug("Anti-Cheat loading"); - System.load(path); - LogHelper.debug("Anti-Cheat loaded"); - } } diff --git a/libLauncher/src/main/java/ru/gravit/launcher/modules/SimpleModuleManager.java b/libLauncher/src/main/java/ru/gravit/launcher/modules/SimpleModuleManager.java index 91861b24..dcec4680 100644 --- a/libLauncher/src/main/java/ru/gravit/launcher/modules/SimpleModuleManager.java +++ b/libLauncher/src/main/java/ru/gravit/launcher/modules/SimpleModuleManager.java @@ -81,6 +81,7 @@ public void initModules() { @LauncherAPI public void load(Module module) { modules.add(module); + module.preInit(context); } @Override @@ -107,9 +108,7 @@ public void loadModule(URL jarpath, String classname, boolean preload) throws Cl classloader.addURL(jarpath); Class moduleclass = Class.forName(classname, true, classloader); Module module = (Module) moduleclass.newInstance(); - modules.add(module); - module.preInit(context); - if(!preload) module.init(context); + load(module, preload); LogHelper.info("Module %s version: %s loaded",module.getName(),module.getVersion()); } diff --git a/modules/NeverDecomp/src/main/java/ru/gravit/launcher/neverdecomp/NeverDecompModule.java b/modules/NeverDecomp/src/main/java/ru/gravit/launcher/neverdecomp/NeverDecompModule.java index 1304b4ff..480a6b79 100644 --- a/modules/NeverDecomp/src/main/java/ru/gravit/launcher/neverdecomp/NeverDecompModule.java +++ b/modules/NeverDecomp/src/main/java/ru/gravit/launcher/neverdecomp/NeverDecompModule.java @@ -34,7 +34,7 @@ public void init(ModuleContext context1) { // Config may has boolean variable "hardAntiDecomp", which enables hard mode (needs -noverify to JVM) LaunchServerModuleContext context = (LaunchServerModuleContext) context1; boolean hobf = context.launchServer.config.block.hasEntry("hardAntiDecomp") ? context.launchServer.config.block.getEntryValue("hardAntiDecomp", BooleanConfigEntry.class) : false; - context.launchServer.buildHookManager.registerClassTransformer(new TransformerClass(hobf)); + context.launchServer.buildHookManager.registerClassTransformer(new TransformerClass(hobf, context.metadataReader)); } } diff --git a/modules/NeverDecomp/src/main/java/ru/gravit/launcher/neverdecomp/asm/TransformerClass.java b/modules/NeverDecomp/src/main/java/ru/gravit/launcher/neverdecomp/asm/TransformerClass.java index 8eb08695..f5c9c858 100644 --- a/modules/NeverDecomp/src/main/java/ru/gravit/launcher/neverdecomp/asm/TransformerClass.java +++ b/modules/NeverDecomp/src/main/java/ru/gravit/launcher/neverdecomp/asm/TransformerClass.java @@ -3,20 +3,24 @@ import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; +import ru.gravit.launchserver.asm.ClassMetadataReader; +import ru.gravit.launchserver.asm.SafeClassWriter; import ru.gravit.launchserver.manangers.BuildHookManager.Transformer; public class TransformerClass implements Transformer { private final boolean context; + private final ClassMetadataReader reader; - public TransformerClass(boolean hobf) { + public TransformerClass(boolean hobf, ClassMetadataReader reader) { this.context = hobf; + this.reader = reader; } @Override public byte[] transform(byte[] input, CharSequence classname) { ClassReader classReader = new ClassReader(input); - ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); + ClassWriter writer = new SafeClassWriter(reader, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); classReader.accept(new AntiDecompileClassVisitor(writer, context), 0); return writer.toByteArray(); }