Fixes + added def classmetadata reader to module context.

This commit is contained in:
zaxar163 2018-09-21 20:43:59 +03:00
parent 99d5d22eac
commit fb20550724
9 changed files with 147 additions and 134 deletions

View file

@ -1,23 +1,47 @@
package ru.gravit.launchserver.manangers; package ru.gravit.launchserver.manangers;
import java.io.File;
import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; 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.LauncherClassLoader;
import ru.gravit.launcher.modules.SimpleModuleManager; import ru.gravit.launcher.modules.SimpleModuleManager;
import ru.gravit.launchserver.LaunchServer; import ru.gravit.launchserver.LaunchServer;
import ru.gravit.launchserver.asm.ClassMetadataReader;
import ru.gravit.launchserver.modules.CoreModule; import ru.gravit.launchserver.modules.CoreModule;
import ru.gravit.launchserver.modules.LaunchServerModuleContext; import ru.gravit.launchserver.modules.LaunchServerModuleContext;
import ru.gravit.utils.helper.IOHelper;
public class ModulesManager extends SimpleModuleManager { public class ModulesManager extends SimpleModuleManager {
public final ClassMetadataReader metadataReader;
public ModulesManager(LaunchServer lsrv) { public ModulesManager(LaunchServer lsrv) {
modules = new ArrayList<>(1); 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()); classloader = new LauncherClassLoader(new URL[0], ClassLoader.getSystemClassLoader());
context = new LaunchServerModuleContext(lsrv, classloader); context = new LaunchServerModuleContext(lsrv, classloader, metadataReader);
registerCoreModule(); registerCoreModule();
} }
private void registerCoreModule() { private void registerCoreModule() {
load(new CoreModule()); 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) { }
}
} }

View file

@ -4,14 +4,18 @@
import ru.gravit.launcher.modules.ModuleContext; import ru.gravit.launcher.modules.ModuleContext;
import ru.gravit.launcher.modules.ModulesManagerInterface; import ru.gravit.launcher.modules.ModulesManagerInterface;
import ru.gravit.launchserver.LaunchServer; import ru.gravit.launchserver.LaunchServer;
import ru.gravit.launchserver.asm.ClassMetadataReader;
public class LaunchServerModuleContext implements ModuleContext { public class LaunchServerModuleContext implements ModuleContext {
public final LaunchServer launchServer; public final LaunchServer launchServer;
public final LauncherClassLoader classloader; public final LauncherClassLoader classloader;
public LaunchServerModuleContext(LaunchServer server, LauncherClassLoader classloader) public final ClassMetadataReader metadataReader;
public LaunchServerModuleContext(LaunchServer server, LauncherClassLoader classloader, ClassMetadataReader metadataReader)
{ {
launchServer = server; launchServer = server;
this.classloader = classloader; this.classloader = classloader;
this.metadataReader = metadataReader;
} }
@Override @Override
public Type getType() { public Type getType() {

View file

@ -17,107 +17,113 @@
public class AvanguardStarter { public class AvanguardStarter {
static class SecurityThread implements Runnable { static class SecurityThread implements Runnable {
@Override @Override
public void run() { public void run() {
while (!Thread.interrupted()) { while (!Thread.interrupted()) {
try { try {
if (!GuardBind.avnIsStarted()) { if (!GuardBind.avnIsStarted()) {
LogHelper.error("Avanguard stopped! Process stopped"); LogHelper.error("Avanguard stopped! Process stopped");
System.exit(5); System.exit(5);
} }
} catch (NullPointerException e) { } catch (NullPointerException e) {
LogHelper.error("Avanguard unloaded! Process stopped"); LogHelper.error("Avanguard unloaded! Process stopped");
System.exit(6); System.exit(6);
} }
try { try {
Thread.sleep(2000); Thread.sleep(2000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
if (!GuardBind.avnIsStarted()) { if (!GuardBind.avnIsStarted()) {
LogHelper.error("Thread stopped! Process stopped"); LogHelper.error("Thread stopped! Process stopped");
System.exit(7); System.exit(7);
} }
} }
} }
} }
} }
public static final String NAME = Launcher.getConfig().projectname; public static final String NAME = Launcher.getConfig().projectname;
public static String avn32 = null, avn64 = null; 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) { private static Path handle(Path mustdiedll, String resource) {
try { try {
InputStream in = IOHelper.newInput(IOHelper.getResourceURL(resource)); InputStream in = IOHelper.newInput(IOHelper.getResourceURL(resource));
byte[] orig = IOHelper.toByteArray(in); byte[] orig = IOHelper.toByteArray(in);
in.close(); in.close();
if (IOHelper.exists(mustdiedll)) { if (IOHelper.exists(mustdiedll)) {
if (!matches(mustdiedll, orig)) if (!matches(mustdiedll, orig))
transfer(orig, mustdiedll); transfer(orig, mustdiedll);
} else } else
transfer(orig, mustdiedll); transfer(orig, mustdiedll);
} catch (Exception e) { } catch (Exception e) {
if (e instanceof RuntimeException) if (e instanceof RuntimeException)
throw (RuntimeException) e; throw (RuntimeException) e;
throw new RuntimeException(e); throw new RuntimeException(e);
} }
return mustdiedll; return mustdiedll;
} }
public static void loadVared() { public static void loadVared() {
if (JVMHelper.JVM_BITS == 32) if (JVMHelper.JVM_BITS == 32)
GuardBind.startAbs(System.getProperty("avn32")); loadLib(System.getProperty("avn32"));
else if (JVMHelper.JVM_BITS == 64) else if (JVMHelper.JVM_BITS == 64)
GuardBind.startAbs(System.getProperty("avn64")); loadLib(System.getProperty("avn64"));
} }
public static void main(boolean init) { public static void start() {
if (init) loadVared();
GuardBind.init(); GuardBind.avnRegisterThreatNotifier((int threatType) -> {
GuardBind.avnRegisterThreatNotifier((int threatType) -> { System.err.println("Threat " + GuardBind.ThreatType.getThreat(threatType).name());
System.err.println("Threat " + GuardBind.ThreatType.getThreat(threatType).name()); LogHelper.error("Cheating == crash!");
LogHelper.error("Cheating == crash!"); System.exit(12);
System.exit(12); return false;
return false; });
}); // нужно делать до пуска таймера!
// нужно делать до пуска таймера! GuardBind.setCheckTime(3000);
GuardBind.setCheckTime(3000); GuardBind.avnStartDefence();
GuardBind.avnStartDefence(); CommonHelper.newThread("Security Thread", true, new SecurityThread()).start();
CommonHelper.newThread("Security Thread", true, new SecurityThread()).start(); }
}
private static boolean matches(Path mustdiedll, byte[] in) { private static boolean matches(Path mustdiedll, byte[] in) {
try { try {
return Arrays.equals(SecurityHelper.digest(DigestAlgorithm.MD5, in), return Arrays.equals(SecurityHelper.digest(DigestAlgorithm.MD5, in),
SecurityHelper.digest(DigestAlgorithm.MD5, mustdiedll)); SecurityHelper.digest(DigestAlgorithm.MD5, mustdiedll));
} catch (IOException e) { } catch (IOException e) {
return false; return false;
} }
} }
private static void processArched(Path arch32, Path arch64, Path wrapper32, Path wrapper64) { private static void processArched(Path arch32, Path arch64, Path wrapper32, Path wrapper64) {
System.setProperty("avn32", IOHelper.toAbs(arch32)); System.setProperty("avn32", IOHelper.toAbs(arch32));
System.setProperty("avn64", IOHelper.toAbs(arch64)); System.setProperty("avn64", IOHelper.toAbs(arch64));
avn32 = IOHelper.toAbs(arch32); avn32 = IOHelper.toAbs(arch32);
avn64 = IOHelper.toAbs(arch64); avn64 = IOHelper.toAbs(arch64);
wrap32 = IOHelper.toAbsPath(wrapper32); wrap32 = IOHelper.toAbsPath(wrapper32);
wrap64 = IOHelper.toAbsPath(wrapper64); wrap64 = IOHelper.toAbsPath(wrapper64);
} }
public static void start(Path path1) throws IOException { public static void init(Path path1) throws IOException {
Path path = path1.resolve("guard"); Path path = path1.resolve("guard");
processArched(handle(path.resolve("Avanguard32.dll"), "Avanguard32.dll"), processArched(handle(path.resolve("Avanguard32.dll"), "Avanguard32.dll"),
handle(path.resolve("Avanguard64.dll"), "Avanguard64.dll"), handle(path.resolve("Avanguard64.dll"), "Avanguard64.dll"),
handle(path.resolve(NAME + "32.exe"), "wrapper32.exe"), handle(path.resolve(NAME + "32.exe"), "wrapper32.exe"),
handle(path.resolve(NAME + "64.exe"), "wrapper64.exe")); handle(path.resolve(NAME + "64.exe"), "wrapper64.exe"));
HashedDir guard = new HashedDir(path,null,true,false); HashedDir guard = new HashedDir(path, null, true, false);
try(DirWatcher dirWatcher = new DirWatcher(path, guard, null, false)){ try (DirWatcher dirWatcher = new DirWatcher(path, guard, null, false)) {
CommonHelper.newThread("Guard Directory Watcher", true, dirWatcher).start(); CommonHelper.newThread("Guard Directory Watcher", true, dirWatcher).start();
} }
} }
private static void transfer(byte[] orig, Path mustdiedll) throws IOException { private static void transfer(byte[] orig, Path mustdiedll) throws IOException {
IOHelper.createParentDirs(mustdiedll); IOHelper.createParentDirs(mustdiedll);
if (!IOHelper.exists(mustdiedll)) if (!IOHelper.exists(mustdiedll))
mustdiedll.toFile().createNewFile(); mustdiedll.toFile().createNewFile();
IOHelper.transfer(orig, mustdiedll, false); IOHelper.transfer(orig, mustdiedll, false);
}
public static void loadLib(String path) {
LogHelper.debug("Anti-Cheat loading");
System.load(path);
LogHelper.debug("Anti-Cheat loaded");
} }
} }

View file

@ -67,7 +67,8 @@
import ru.gravit.launcher.serialize.stream.StreamObject; import ru.gravit.launcher.serialize.stream.StreamObject;
public class LauncherEngine { public class LauncherEngine {
@LauncherAPI private static final boolean isUsingGuard = true;
public static void addLauncherClassBindings(Map<String, Object> bindings) { public static void addLauncherClassBindings(Map<String, Object> bindings) {
bindings.put("LauncherClass", Launcher.class); bindings.put("LauncherClass", Launcher.class);
bindings.put("LauncherConfigClass", LauncherConfig.class); bindings.put("LauncherConfigClass", LauncherConfig.class);
@ -188,7 +189,6 @@ private void setScriptBindings() {
addLauncherClassBindings(bindings); addLauncherClassBindings(bindings);
} }
@LauncherAPI
public void start(String... args) throws Throwable { public void start(String... args) throws Throwable {
Launcher.modulesManager = new ClientModuleManager(this); Launcher.modulesManager = new ClientModuleManager(this);
LauncherConfig.getAutogenConfig().initModules(); //INIT LauncherConfig.getAutogenConfig().initModules(); //INIT
@ -205,9 +205,9 @@ public void start(String... args) throws Throwable {
LogHelper.info("Invoking start() function"); LogHelper.info("Invoking start() function");
Invocable invoker = (Invocable) engine; Invocable invoker = (Invocable) engine;
if (JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE) { if (JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE) {
AvanguardStarter.start((Path) invoker.invokeFunction("getPathDirHelper")); AvanguardStarter.init((Path) invoker.invokeFunction("getPathDirHelper"));
AvanguardStarter.loadVared(); AvanguardStarter.loadVared();
AvanguardStarter.main(false); if (isUsingGuard) AvanguardStarter.start();
} }
Launcher.modulesManager.postInitModules(); Launcher.modulesManager.postInitModules();
invoker.invokeFunction("start", (Object) args); invoker.invokeFunction("start", (Object) args);

View file

@ -149,6 +149,7 @@ public void write(HOutput output) throws IOException {
private static final String[] EMPTY_ARRAY = new String[0]; 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 String MAGICAL_INTEL_OPTION = "-XX:HeapDumpPath=ThisTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump";
private static final boolean isUsingWrapper = true; private static final boolean isUsingWrapper = true;
private static final boolean isUsingGuard = true;
@LauncherAPI @LauncherAPI
public static final String TITLE_PROPERTY = "launcher.title"; 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); Launcher.modulesManager = new ClientModuleManager(null);
LauncherConfig.getAutogenConfig().initModules(); //INIT LauncherConfig.getAutogenConfig().initModules(); //INIT
Launcher.modulesManager.preInitModules(); Launcher.modulesManager.preInitModules();
if (JVMHelper.OS_TYPE == OS.MUSTDIE) { if (JVMHelper.OS_TYPE == OS.MUSTDIE) runAvn();
AvanguardStarter.loadVared();
AvanguardStarter.main(false);
}
checkJVMBitsAndVersion(); checkJVMBitsAndVersion();
JVMHelper.verifySystemProperties(ClientLauncher.class, true); JVMHelper.verifySystemProperties(ClientLauncher.class, true);
LogHelper.printVersion("Client Launcher"); 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<Path> result = new LinkedList<>(); Collection<Path> result = new LinkedList<>();
for (String classPathEntry : classPath) { for (String classPathEntry : classPath) {
Path path = clientDir.resolve(IOHelper.toPath(classPathEntry)); Path path = clientDir.resolve(IOHelper.toPath(classPathEntry));

View file

@ -1,10 +1,6 @@
package ru.zaxar163; package ru.zaxar163;
import java.nio.file.Path;
import ru.gravit.launcher.LauncherAPI; import ru.gravit.launcher.LauncherAPI;
import ru.gravit.utils.helper.JVMHelper;
import ru.gravit.utils.helper.LogHelper;
@LauncherAPI @LauncherAPI
public final class GuardBind { public final class GuardBind {
@ -73,29 +69,7 @@ public int getValue() {
@LauncherAPI @LauncherAPI
public static native int getCheckTime(); 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 @LauncherAPI
public static native void setCheckTime(int time); 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");
}
} }

View file

@ -81,6 +81,7 @@ public void initModules() {
@LauncherAPI @LauncherAPI
public void load(Module module) { public void load(Module module) {
modules.add(module); modules.add(module);
module.preInit(context);
} }
@Override @Override
@ -107,9 +108,7 @@ public void loadModule(URL jarpath, String classname, boolean preload) throws Cl
classloader.addURL(jarpath); classloader.addURL(jarpath);
Class<?> moduleclass = Class.forName(classname, true, classloader); Class<?> moduleclass = Class.forName(classname, true, classloader);
Module module = (Module) moduleclass.newInstance(); Module module = (Module) moduleclass.newInstance();
modules.add(module); load(module, preload);
module.preInit(context);
if(!preload) module.init(context);
LogHelper.info("Module %s version: %s loaded",module.getName(),module.getVersion()); LogHelper.info("Module %s version: %s loaded",module.getName(),module.getVersion());
} }

View file

@ -34,7 +34,7 @@ public void init(ModuleContext context1) {
// Config may has boolean variable "hardAntiDecomp", which enables hard mode (needs -noverify to JVM) // Config may has boolean variable "hardAntiDecomp", which enables hard mode (needs -noverify to JVM)
LaunchServerModuleContext context = (LaunchServerModuleContext) context1; LaunchServerModuleContext context = (LaunchServerModuleContext) context1;
boolean hobf = context.launchServer.config.block.hasEntry("hardAntiDecomp") ? context.launchServer.config.block.getEntryValue("hardAntiDecomp", BooleanConfigEntry.class) : false; 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));
} }
} }

View file

@ -3,20 +3,24 @@
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import ru.gravit.launchserver.asm.ClassMetadataReader;
import ru.gravit.launchserver.asm.SafeClassWriter;
import ru.gravit.launchserver.manangers.BuildHookManager.Transformer; import ru.gravit.launchserver.manangers.BuildHookManager.Transformer;
public class TransformerClass implements Transformer { public class TransformerClass implements Transformer {
private final boolean context; private final boolean context;
private final ClassMetadataReader reader;
public TransformerClass(boolean hobf) { public TransformerClass(boolean hobf, ClassMetadataReader reader) {
this.context = hobf; this.context = hobf;
this.reader = reader;
} }
@Override @Override
public byte[] transform(byte[] input, CharSequence classname) { public byte[] transform(byte[] input, CharSequence classname) {
ClassReader classReader = new ClassReader(input); 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); classReader.accept(new AntiDecompileClassVisitor(writer, context), 0);
return writer.toByteArray(); return writer.toByteArray();
} }