mirror of
https://github.com/GravitLauncher/Launcher
synced 2025-03-31 05:28:15 +03:00
Merge fb20550724
into 84475c3b00
This commit is contained in:
commit
b76f44e4d9
17 changed files with 356 additions and 152 deletions
|
@ -10,11 +10,8 @@
|
|||
import java.nio.file.Paths;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import ru.gravit.utils.helper.IOHelper;
|
||||
import ru.gravit.utils.helper.JVMHelper;
|
||||
import ru.gravit.utils.helper.LogHelper;
|
||||
import ru.gravit.utils.helper.SecurityHelper;
|
||||
|
||||
|
|
|
@ -0,0 +1,173 @@
|
|||
package ru.gravit.launchserver.asm;
|
||||
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
import ru.gravit.utils.helper.IOHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
/**
|
||||
* Позволяет искать методы внутри незагруженных классов
|
||||
* и общие суперклассы для чего угодно. Работает через поиск class-файлов в classpath.
|
||||
*/
|
||||
public class ClassMetadataReader {
|
||||
private final List<JarFile> list;
|
||||
|
||||
public ClassMetadataReader() {
|
||||
this.list = new ArrayList<>();
|
||||
}
|
||||
|
||||
public ClassMetadataReader(List<JarFile> list) {
|
||||
this.list = new ArrayList<>(list);
|
||||
}
|
||||
|
||||
public void add(JarFile jar) {
|
||||
list.add(jar);
|
||||
}
|
||||
|
||||
public byte[] getClassData(String className) throws IOException {
|
||||
String classResourceName = className.replace('.', '/') + ".class";
|
||||
for (JarFile jar : list) {
|
||||
if (jar.getJarEntry(classResourceName) != null) return IOHelper.read(jar.getInputStream(jar.getJarEntry(classResourceName)));
|
||||
}
|
||||
return IOHelper.read(ClassMetadataReader.class.getResourceAsStream('/' + classResourceName));
|
||||
}
|
||||
|
||||
public void acceptVisitor(byte[] classData, ClassVisitor visitor) {
|
||||
new ClassReader(classData).accept(visitor, 0);
|
||||
}
|
||||
|
||||
public void acceptVisitor(String className, ClassVisitor visitor) throws IOException {
|
||||
acceptVisitor(getClassData(className), visitor);
|
||||
}
|
||||
|
||||
public MethodReference findVirtualMethod(String owner, String name, String desc) {
|
||||
ArrayList<String> superClasses = getSuperClasses(owner);
|
||||
for (int i = superClasses.size() - 1; i > 0; i--) { // чекать текущий класс смысла нет
|
||||
String className = superClasses.get(i);
|
||||
MethodReference methodReference = getMethodReference(className, name, desc);
|
||||
if (methodReference != null) {
|
||||
System.out.println("found virtual method: " + methodReference);
|
||||
return methodReference;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private MethodReference getMethodReference(String type, String methodName, String desc) {
|
||||
try {
|
||||
return getMethodReferenceASM(type, methodName, desc);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected MethodReference getMethodReferenceASM(String type, String methodName, String desc) throws IOException {
|
||||
FindMethodClassVisitor cv = new FindMethodClassVisitor(methodName, desc);
|
||||
acceptVisitor(type, cv);
|
||||
if (cv.found) {
|
||||
return new MethodReference(type, cv.targetName, cv.targetDesc);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected boolean checkSameMethod(String sourceName, String sourceDesc, String targetName, String targetDesc) {
|
||||
return sourceName.equals(targetName) && sourceDesc.equals(targetDesc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает суперклассы в порядке возрастающей конкретности (начиная с java/lang/Object
|
||||
* и заканчивая данным типом)
|
||||
*/
|
||||
public ArrayList<String> getSuperClasses(String type) {
|
||||
ArrayList<String> superclasses = new ArrayList<String>(1);
|
||||
superclasses.add(type);
|
||||
while ((type = getSuperClass(type)) != null) {
|
||||
superclasses.add(type);
|
||||
}
|
||||
Collections.reverse(superclasses);
|
||||
return superclasses;
|
||||
}
|
||||
public String getSuperClass(String type) {
|
||||
try {
|
||||
return getSuperClassASM(type);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected String getSuperClassASM(String type) throws IOException {
|
||||
CheckSuperClassVisitor cv = new CheckSuperClassVisitor();
|
||||
acceptVisitor(type, cv);
|
||||
return cv.superClassName;
|
||||
}
|
||||
|
||||
private class CheckSuperClassVisitor extends ClassVisitor {
|
||||
|
||||
String superClassName;
|
||||
|
||||
public CheckSuperClassVisitor() {
|
||||
super(Opcodes.ASM5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String signature,
|
||||
String superName, String[] interfaces) {
|
||||
this.superClassName = superName;
|
||||
}
|
||||
}
|
||||
|
||||
protected class FindMethodClassVisitor extends ClassVisitor {
|
||||
|
||||
public String targetName;
|
||||
public String targetDesc;
|
||||
public boolean found;
|
||||
|
||||
public FindMethodClassVisitor(String name, String desc) {
|
||||
super(Opcodes.ASM5);
|
||||
this.targetName = name;
|
||||
this.targetDesc = desc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
||||
System.out.println("visiting " + name + "#" + desc);
|
||||
if ((access & Opcodes.ACC_PRIVATE) == 0 && checkSameMethod(name, desc, targetName, targetDesc)) {
|
||||
found = true;
|
||||
targetName = name;
|
||||
targetDesc = desc;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MethodReference {
|
||||
|
||||
public final String owner;
|
||||
public final String name;
|
||||
public final String desc;
|
||||
|
||||
public MethodReference(String owner, String name, String desc) {
|
||||
this.owner = owner;
|
||||
this.name = name;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return Type.getMethodType(desc);
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return "MethodReference{" +
|
||||
"owner='" + owner + '\'' +
|
||||
", name='" + name + '\'' +
|
||||
", desc='" + desc + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package ru.gravit.launchserver.asm;
|
||||
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* ClassWriter с другой реализацией метода getCommonSuperClass: при его использовании не происходит загрузки классов.
|
||||
* Однако, сама по себе загрузка классов редко является проблемой, потому что инициализация класса (вызов статических
|
||||
* блоков) происходит не при загрузке класса. Проблемы появляются, когда изменения вставляются в зависимые друг от друга
|
||||
* классы, тогда стандартная реализация отваливается с ClassCircularityError.
|
||||
*/
|
||||
public class SafeClassWriter extends ClassWriter {
|
||||
private final ClassMetadataReader classMetadataReader;
|
||||
|
||||
public SafeClassWriter(ClassMetadataReader classMetadataReader, int flags) {
|
||||
super(flags);
|
||||
this.classMetadataReader = classMetadataReader;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCommonSuperClass(String type1, String type2) {
|
||||
ArrayList<String> superClasses1 = classMetadataReader.getSuperClasses(type1);
|
||||
ArrayList<String> superClasses2 = classMetadataReader.getSuperClasses(type2);
|
||||
int size = Math.min(superClasses1.size(), superClasses2.size());
|
||||
int i;
|
||||
for (i = 0; i < size && superClasses1.get(i).equals(superClasses2.get(i)); i++);
|
||||
if (i == 0) {
|
||||
return "java/lang/Object";
|
||||
} else {
|
||||
return superClasses1.get(i-1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
package ru.gravit.launchserver.auth.hwid;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
package ru.gravit.launchserver.auth.provider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import com.eclipsesource.json.Json;
|
||||
import com.eclipsesource.json.JsonObject;
|
||||
|
@ -20,9 +15,6 @@
|
|||
import ru.gravit.launcher.serialize.config.entry.StringConfigEntry;
|
||||
|
||||
public final class JsonAuthProvider extends AuthProvider {
|
||||
private static final int TIMEOUT = Integer.parseInt(
|
||||
System.getProperty("launcher.connection.timeout", Integer.toString(1500)));
|
||||
|
||||
private final URL url;
|
||||
private final String userKeyName;
|
||||
private final String passKeyName;
|
||||
|
|
|
@ -3,10 +3,6 @@
|
|||
import ru.gravit.launchserver.LaunchServer;
|
||||
import ru.gravit.launchserver.command.Command;
|
||||
import ru.gravit.launchserver.socket.NettyServerSocketHandler;
|
||||
import ru.gravit.utils.HttpDownloader;
|
||||
import ru.gravit.utils.helper.LogHelper;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
public class TestCommand extends Command {
|
||||
public TestCommand(LaunchServer server) {
|
||||
|
|
|
@ -1,21 +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) { }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<String, Object> 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);
|
||||
|
|
|
@ -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<Path> result = new LinkedList<>();
|
||||
for (String classPathEntry : classPath) {
|
||||
Path path = clientDir.resolve(IOHelper.toPath(classPathEntry));
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
import com.sun.javafx.collections.NonIterableChange;
|
||||
import com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList;
|
||||
|
||||
import javafx.beans.InvalidationListener;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.collections.ListChangeListener;
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
public class LauncherSSLContext {
|
||||
public SSLServerSocketFactory ssf;
|
||||
public SSLSocketFactory sf;
|
||||
private SSLContext sc;
|
||||
public LauncherSSLContext(KeyStore ks,String keypassword) throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException, UnrecoverableKeyException, KeyManagementException {
|
||||
TrustManager[] trustAllCerts = new TrustManager[] {
|
||||
new LauncherTrustManager()
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue