mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-12-22 16:41:46 +03:00
Пофиксил ASM. Требуется тест! (#216)
* [FIX] ASM bundling. * Revert "[FIX] Agent работает." This reverts commit76a9c07a48
. * Revert "[FIX] Удалена sm часть LauncherAgent" This reverts commit54c7526a66
. * [FIX] Закрываем ресурсы в LauncherAgent. * [FIX] Не загруженный java.awt.Robot. * [FIX] getRAM работает на OpenJDK 11+ * [FIX] Жуткий RequestAuthHandler. * [FIX] Грамматика английского языка в RequestAuthHandler. * [ANY] Опять RequestAuthHandler ошибки в грамматике.
This commit is contained in:
parent
2180bd989e
commit
75e781d08e
7 changed files with 184 additions and 72 deletions
|
@ -30,7 +30,8 @@
|
|||
jar {
|
||||
dependsOn parent.childProjects.Launcher.tasks.build
|
||||
from { configurations.pack.collect { it.isDirectory() ? it : zipTree(it) } }
|
||||
from(parent.childProjects.Launcher.tasks.jar.archivePath, parent.childProjects.Launcher.tasks.genRuntimeJS.archivePath)
|
||||
from(parent.childProjects.Launcher.tasks.shadowJar.archivePath)
|
||||
from(parent.childProjects.Launcher.tasks.genRuntimeJS.archivePath)
|
||||
manifest.attributes("Main-Class": mainClassName,
|
||||
"Premain-Class": mainAgentName,
|
||||
"Can-Redefine-Classes": "true",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package ru.gravit.launchserver.auth.handler;
|
||||
|
||||
import ru.gravit.utils.helper.CommonHelper;
|
||||
import ru.gravit.utils.helper.IOHelper;
|
||||
import ru.gravit.utils.helper.LogHelper;
|
||||
|
||||
|
@ -8,100 +9,78 @@
|
|||
import java.util.UUID;
|
||||
|
||||
public final class RequestAuthHandler extends CachedAuthHandler {
|
||||
private String url;
|
||||
private String secretKey;
|
||||
private String usernameFetch;
|
||||
private String uuidFetch;
|
||||
|
||||
private String typeLine;
|
||||
private String uuidLine;
|
||||
private String usernameLine;
|
||||
private String accessTokenLine;
|
||||
private String serverIDLine;
|
||||
private String secretKeyLine;
|
||||
private String updateAuth;
|
||||
private String updateServerID;
|
||||
|
||||
private String TypeFetchByUUID;
|
||||
private String TypeFetchByUsername;
|
||||
private String TypeSetAccessTokenAndUUID;
|
||||
private String TypeSetServerID;
|
||||
private String splitSymbol;
|
||||
private String splitSymbol = ":";
|
||||
private String goodResponse = "OK";
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
if (url == null)
|
||||
LogHelper.error("[Verify][AuthHandler] url cannot be null");
|
||||
if (secretKey == null)
|
||||
LogHelper.error("[Verify][AuthHandler] secretKey cannot be null");
|
||||
// Default
|
||||
if (typeLine == null)
|
||||
typeLine = "type";
|
||||
if (uuidLine == null)
|
||||
uuidLine = "uuid";
|
||||
if (usernameLine == null)
|
||||
usernameLine = "username";
|
||||
if (accessTokenLine == null)
|
||||
accessTokenLine = "accessToken";
|
||||
if (serverIDLine == null)
|
||||
serverIDLine = "serverID";
|
||||
if (secretKeyLine == null)
|
||||
secretKeyLine = "secretKey";
|
||||
if (TypeFetchByUUID == null)
|
||||
TypeFetchByUUID = "FetchByUUID";
|
||||
if (TypeFetchByUsername == null)
|
||||
TypeFetchByUsername = "FetchByUsername";
|
||||
if (TypeSetAccessTokenAndUUID == null)
|
||||
TypeSetAccessTokenAndUUID = "SetAccessTokenAndUUID";
|
||||
if (TypeSetServerID == null)
|
||||
TypeSetServerID = "SetServerID";
|
||||
if (splitSymbol == null)
|
||||
splitSymbol = ":";
|
||||
if (usernameFetch == null)
|
||||
LogHelper.error("[Verify][AuthHandler] usernameFetch cannot be null");
|
||||
if (uuidFetch == null)
|
||||
LogHelper.error("[Verify][AuthHandler] uuidFetch cannot be null");
|
||||
if (updateAuth == null)
|
||||
LogHelper.error("[Verify][AuthHandler] updateAuth cannot be null");
|
||||
if (updateServerID == null)
|
||||
LogHelper.error("[Verify][AuthHandler] updateServerID cannot be null");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Entry fetchEntry(UUID uuid) throws IOException {
|
||||
String response = IOHelper.request(new URL(url + "?" + IOHelper.urlEncode(typeLine) + "=" + TypeFetchByUUID + "&" + secretKeyLine + "=" + IOHelper.urlEncode(secretKey) + "&" + IOHelper.urlEncode(uuidLine) + "=" + IOHelper.urlEncode(uuid.toString())));
|
||||
String response = IOHelper.request(new URL(CommonHelper.replace(uuidFetch, "uuid", IOHelper.urlEncode(uuid.toString()))));
|
||||
String[] parts = response.split(splitSymbol);
|
||||
String username = parts[0];
|
||||
String accessToken = parts[1];
|
||||
String serverID = parts[2];
|
||||
LogHelper.debug("[AuthHandler] Getted username: " + username);
|
||||
LogHelper.debug("[AuthHandler] Getted accessToken: " + accessToken);
|
||||
LogHelper.debug("[AuthHandler] Getted serverID: " + serverID);
|
||||
LogHelper.debug("[AuthHandler] Getted UUID: " + uuid);
|
||||
return query(uuid, username, accessToken, serverID);
|
||||
if (LogHelper.isDebugEnabled()) {
|
||||
LogHelper.debug("[AuthHandler] Got username: " + username);
|
||||
LogHelper.debug("[AuthHandler] Got accessToken: " + accessToken);
|
||||
LogHelper.debug("[AuthHandler] Got serverID: " + serverID);
|
||||
LogHelper.debug("[AuthHandler] Got UUID: " + uuid);
|
||||
}
|
||||
return new Entry(uuid, username, accessToken, serverID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Entry fetchEntry(String username) throws IOException {
|
||||
String response = IOHelper.request(new URL(url + "?" + IOHelper.urlEncode(typeLine) + "=" + TypeFetchByUsername + "&" + secretKeyLine + "=" + IOHelper.urlEncode(secretKey) + "&" + IOHelper.urlEncode(usernameLine) + "=" + IOHelper.urlEncode(username)));
|
||||
String response = IOHelper.request(new URL(CommonHelper.replace(usernameFetch, "user", IOHelper.urlEncode(username))));
|
||||
String[] parts = response.split(splitSymbol);
|
||||
UUID uuid = UUID.fromString(parts[0]);
|
||||
String accessToken = parts[1];
|
||||
String serverID = parts[2];
|
||||
LogHelper.debug("[AuthHandler] Getted username: " + username);
|
||||
LogHelper.debug("[AuthHandler] Getted accessToken: " + accessToken);
|
||||
LogHelper.debug("[AuthHandler] Getted serverID: " + serverID);
|
||||
LogHelper.debug("[AuthHandler] Getted UUID: " + uuid);
|
||||
return query(uuid, username, accessToken, serverID);
|
||||
if (LogHelper.isDebugEnabled()) {
|
||||
LogHelper.debug("[AuthHandler] Got username: " + username);
|
||||
LogHelper.debug("[AuthHandler] Got accessToken: " + accessToken);
|
||||
LogHelper.debug("[AuthHandler] Got serverID: " + serverID);
|
||||
LogHelper.debug("[AuthHandler] Got UUID: " + uuid);
|
||||
}
|
||||
|
||||
private Entry query(UUID uuid, String username, String accessToken, String serverID) {
|
||||
return new Entry(uuid, username, accessToken, serverID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean updateAuth(UUID uuid, String username, String accessToken) throws IOException {
|
||||
String response = IOHelper.request(new URL(url + "?" + IOHelper.urlEncode(typeLine) + "=" + TypeSetAccessTokenAndUUID + "&" + secretKeyLine + "=" + IOHelper.urlEncode(secretKey) + "&" + IOHelper.urlEncode(uuidLine) + "=" + IOHelper.urlEncode(uuid.toString()) + "&" + IOHelper.urlEncode(accessTokenLine) + "=" + IOHelper.urlEncode(accessToken) + "&" + IOHelper.urlEncode(usernameLine) + "=" + IOHelper.urlEncode(username)));
|
||||
String response = IOHelper.request(new URL(CommonHelper.replace(updateAuth, "user", IOHelper.urlEncode(username), "uuid", IOHelper.urlEncode(uuid.toString()), "token", IOHelper.urlEncode(accessToken))));
|
||||
if (LogHelper.isDebugEnabled()) {
|
||||
LogHelper.debug("[AuthHandler] Set accessToken: " + accessToken);
|
||||
LogHelper.debug("[AuthHandler] Set UUID: " + uuid);
|
||||
LogHelper.debug("[AuthHandler] For this username: " + username);
|
||||
return response.equals("OK");
|
||||
}
|
||||
return goodResponse.equals(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean updateServerID(UUID uuid, String serverID) throws IOException {
|
||||
String response = IOHelper.request(new URL(url + "?" + IOHelper.urlEncode(typeLine) + "=" + TypeSetServerID + "&" + secretKeyLine + "=" + IOHelper.urlEncode(secretKey) + "&" + IOHelper.urlEncode(uuidLine) + "=" + IOHelper.urlEncode(uuid.toString()) + "&" + IOHelper.urlEncode(serverIDLine) + "=" + IOHelper.urlEncode(serverID)));
|
||||
String response = IOHelper.request(new URL(CommonHelper.replace(updateAuth, "serverid", IOHelper.urlEncode(serverID), "uuid", IOHelper.urlEncode(uuid.toString()))));
|
||||
if (LogHelper.isDebugEnabled()) {
|
||||
LogHelper.debug("[AuthHandler] Set serverID: " + serverID);
|
||||
LogHelper.debug("[AuthHandler] For this UUID: " + uuid);
|
||||
return response.equals("OK");
|
||||
}
|
||||
return goodResponse.equals(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
apply plugin: 'com.github.johnrengelman.shadow'
|
||||
|
||||
String mainClassName = "ru.gravit.launcher.ClientLauncherWrapper"
|
||||
String mainAgentName = "ru.gravit.launcher.LauncherAgent"
|
||||
|
||||
|
@ -17,7 +19,7 @@
|
|||
}
|
||||
|
||||
jar {
|
||||
from { configurations.pack.collect { it.isDirectory() ? it : zipTree(it) } }
|
||||
classifier = 'clean'
|
||||
manifest.attributes("Main-Class": mainClassName,
|
||||
"Premain-Class": mainAgentName,
|
||||
"Can-Redefine-Classes": "true",
|
||||
|
@ -25,11 +27,18 @@
|
|||
"Can-Set-Native-Method-Prefix": "true")
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
classifier = null
|
||||
relocate 'org.objectweb.asm', 'ru.gravit.repackage.org.objectweb.asm'
|
||||
configurations = [project.configurations.pack]
|
||||
exclude 'module-info.class'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
pack project(':LauncherAPI') // Not error on obf.
|
||||
bundle 'com.github.oshi:oshi-core:3.13.0'
|
||||
compileOnly 'org.ow2.asm:asm-all:5.0.3'
|
||||
bundle 'com.jfoenix:jfoenix:8.0.8'
|
||||
pack 'org.ow2.asm:asm-tree:7.1'
|
||||
}
|
||||
|
||||
task genRuntimeJS(type: Zip) {
|
||||
|
@ -44,4 +53,4 @@ task dumpLibs(type: Copy) {
|
|||
}
|
||||
|
||||
|
||||
build.dependsOn tasks.genRuntimeJS, tasks.dumpLibs
|
||||
build.dependsOn tasks.genRuntimeJS, tasks.dumpLibs, tasks.shadowJar
|
||||
|
|
|
@ -43,9 +43,119 @@ public static void premain(String agentArgument, Instrumentation instrumentation
|
|||
if (trimmedArg.contains("r")) rt = false;
|
||||
}
|
||||
}
|
||||
if (rt || pb) replaceClasses(pb, rt);
|
||||
}
|
||||
|
||||
public static boolean isStarted() {
|
||||
return isAgentStarted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author https://github.com/Konloch/JVM-Sandbox
|
||||
* Replaces the Runtime class via instrumentation, transforms the class via ASM
|
||||
*/
|
||||
private static void replaceClasses(boolean pb, boolean rt) {
|
||||
java.awt.Robot.class.getName();
|
||||
for(Class<?> c : inst.getAllLoadedClasses()) {
|
||||
if(rt && c.getName().equals("java.lang.Runtime")) {
|
||||
try {
|
||||
inst.redefineClasses(new java.lang.instrument.ClassDefinition(java.lang.Runtime.class, transformClass(c.getName(), getClassFile(c))));
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if(pb && c.getName().equals("java.lang.ProcessBuilder")) {
|
||||
try {
|
||||
inst.redefineClasses(new java.lang.instrument.ClassDefinition(java.lang.ProcessBuilder.class, transformClass(c.getName(), getClassFile(c))));
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if(c.getName().equals("java.awt.Robot")) {
|
||||
try {
|
||||
inst.redefineClasses(new java.lang.instrument.ClassDefinition(java.lang.ProcessBuilder.class, transformClass(c.getName(), getClassFile(c))));
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author https://github.com/Konloch/JVM-Sandbox
|
||||
* Use ASM to modify the byte array
|
||||
*/
|
||||
private static byte[] transformClass(String className, byte[] classBytes) {
|
||||
if (className.equals("java.lang.Runtime")) {
|
||||
ClassReader cr=new ClassReader(classBytes);
|
||||
ClassNode cn=new ClassNode();
|
||||
cr.accept(cn,ClassReader.EXPAND_FRAMES);
|
||||
|
||||
for (Object o : cn.methods.toArray()) {
|
||||
MethodNode m = (MethodNode) o;
|
||||
if(m.name.equals("exec")) {
|
||||
m.instructions.insert(new InsnNode(ARETURN));
|
||||
m.instructions.insert(new InsnNode(ACONST_NULL));
|
||||
}
|
||||
}
|
||||
ClassWriter cw=new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||
cn.accept(cw);
|
||||
return cw.toByteArray();
|
||||
} else if (className.equals("java.lang.ProcessBuilder")) {
|
||||
ClassReader cr=new ClassReader(classBytes);
|
||||
ClassNode cn=new ClassNode();
|
||||
cr.accept(cn,ClassReader.EXPAND_FRAMES);
|
||||
|
||||
for (Object o : cn.methods.toArray()) {
|
||||
MethodNode m = (MethodNode) o;
|
||||
if(m.name.equals("start")) {
|
||||
m.instructions.insert(new InsnNode(ARETURN));
|
||||
m.instructions.insert(new InsnNode(ACONST_NULL));
|
||||
}
|
||||
}
|
||||
ClassWriter cw=new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||
cn.accept(cw);
|
||||
return cw.toByteArray();
|
||||
} else if (className.equals("java.awt.Robot")) {
|
||||
ClassReader cr=new ClassReader(classBytes);
|
||||
ClassNode cn=new ClassNode();
|
||||
cr.accept(cn,ClassReader.EXPAND_FRAMES);
|
||||
|
||||
for (Object o : cn.methods.toArray()) {
|
||||
MethodNode m = (MethodNode) o;
|
||||
if( m.name.equals("createScreenCapture") || m.name.equals("getPixelColor") ||
|
||||
m.name.equals("keyPress") || m.name.equals("keyRelease") ||
|
||||
m.name.equals("mouseMove") || m.name.equals("mousePress") ||
|
||||
m.name.equals("mouseWheel"))
|
||||
{
|
||||
m.instructions.insert(new InsnNode(ARETURN));
|
||||
m.instructions.insert(new InsnNode(ACONST_NULL));
|
||||
}
|
||||
}
|
||||
ClassWriter cw=new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||
cn.accept(cw);
|
||||
return cw.toByteArray();
|
||||
}
|
||||
return classBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author https://github.com/Konloch/JVM-Sandbox
|
||||
* Do not remove this method. Do not to cause classloading!
|
||||
* Grab the byte array from the loaded Class object
|
||||
* @param clazz
|
||||
* @return array, respending this class in bytecode.
|
||||
* @throws IOException
|
||||
*/
|
||||
private static byte[] getClassFile(Class<?> clazz) throws IOException {
|
||||
try (InputStream is = clazz.getResourceAsStream( "/" + clazz.getName().replace('.', '/') + ".class");
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
||||
int r = 0;
|
||||
byte[] buffer = new byte[8192];
|
||||
while((r=is.read(buffer))>=0) {
|
||||
baos.write(buffer, 0, r);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -355,7 +355,7 @@ public static Process launch(
|
|||
Collections.addAll(context.args, profile.getJvmArgs());
|
||||
profile.pushOptionalJvmArgs(context.args);
|
||||
Collections.addAll(context.args, "-Djava.library.path=".concat(params.clientDir.resolve(NATIVES_DIR).toString())); // Add Native Path
|
||||
Collections.addAll(context.args, "-javaagent:".concat(pathLauncher).concat("=pr"));
|
||||
Collections.addAll(context.args, "-javaagent:".concat(pathLauncher));
|
||||
LauncherGuardManager.guard.addCustomParams(context);
|
||||
Collections.addAll(context.args, ClientLauncher.class.getName());
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
plugins {
|
||||
id 'com.github.johnrengelman.shadow' version '5.0.0' apply false
|
||||
}
|
||||
|
||||
configure(subprojects.findAll { it.name != 'modules' && it.name != 'Radon' }) {
|
||||
apply plugin: 'idea'
|
||||
apply plugin: 'eclipse'
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.OperatingSystemMXBean;
|
||||
import java.lang.management.RuntimeMXBean;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
|
@ -136,8 +138,15 @@ public static String getEnvPropertyCaseSensitive(String name) {
|
|||
}
|
||||
|
||||
private static int getRAMAmount() {
|
||||
// TODO Normal fix.
|
||||
int physicalRam = (int) (((com.sun.management.OperatingSystemMXBean) OPERATING_SYSTEM_MXBEAN).getTotalPhysicalMemorySize() >> 20);
|
||||
int physicalRam = 1024;
|
||||
try {
|
||||
final Method getTotalPhysicalMemorySize = OPERATING_SYSTEM_MXBEAN.getClass().getDeclaredMethod("getTotalPhysicalMemorySize");
|
||||
getTotalPhysicalMemorySize.setAccessible(true);
|
||||
physicalRam = (int) ((long)getTotalPhysicalMemorySize.invoke(OPERATING_SYSTEM_MXBEAN) >> 20);
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException
|
||||
| SecurityException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
return Math.min(physicalRam, OS_BITS == 32 ? 1536 : 32768); // Limit 32-bit OS to 1536 MiB, and 64-bit OS to 32768 MiB (because it's enough)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue