package gq.malwarefight.nosession.utils; import com.google.common.annotations.Beta; import com.google.common.collect.ForwardingMultimap; import com.google.gson.Gson; import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; import gq.malwarefight.tokenapp.Main; import org.apache.commons.io.ByteOrderMark; import org.apache.commons.lang3.CharEncoding; import org.apache.commons.lang3.SystemUtils; import org.apache.commons.lang3.Validate; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.objectweb.asm.Opcodes; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.nio.file.Paths; import java.util.Arrays; import java.util.Properties; import java.util.UUID; public class Utils { public static int PORT = -1; private static final int BASE_PORT = 47777; public static byte[] read(InputStream i, Character delimiter) throws IOException { byte[] buffer = new byte[512]; int index = 0; while (true) { int in = i.read(); if (in == -1 || (delimiter != null && delimiter == in)) { return Arrays.copyOfRange(buffer, 0, index); } if (index == buffer.length) { // grow the buffer byte[] newBuffer = new byte[buffer.length * 2]; System.arraycopy( buffer, 0, newBuffer, 0, buffer.length ); buffer = newBuffer; } buffer[index] = (byte) in; index++; } } public static String readString(InputStream i, Character delimiter) throws IOException { return new String(read(i, delimiter), StandardCharsets.UTF_8); } public static Socket getProperSocket(UUID id) { if (PORT == -1) { Socket socket = null; int port; for (int i = BASE_PORT; i < BASE_PORT + 10; i++) { try { socket = new Socket(); socket.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), i)); socket.getOutputStream().write("uuid\n".getBytes(StandardCharsets.UTF_8)); String value = readString(socket.getInputStream(), '\n'); if (UUID.fromString(value).equals(id)) { port = i; PORT = port; break; } } catch (Exception exception) { socket = null; } } return socket; } else { try { Socket socket = new Socket(); socket.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), PORT)); return socket; } catch (IOException e) { PORT = -1; return getProperSocket(id); } } } public static String normalizeUUID(String uuid) { return uuid.replaceFirst( "(\\p{XDigit}{8})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}+)", "$1-$2-$3-$4-$5" ); } public static void setStaticValue(Class cls, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException { Field f = cls.getDeclaredField(fieldName); f.setAccessible(true); if ((f.getModifiers() & Modifier.FINAL) != 0) { // if it is final Field modifiers = Field.class.getDeclaredField("modifiers"); modifiers.setAccessible(true); int modifiersValue = modifiers.getInt(f); modifiersValue &= ~Modifier.FINAL; modifiers.setInt(f, modifiersValue); } f.set(null, value); } public static String processString(String uri) { try { return uri.substring(uri.indexOf('/'), uri.lastIndexOf('!')); } catch (Exception e) { e.printStackTrace(); return uri; } } public static File getLibraryPathAsFile(Class c) throws URISyntaxException { String uri = c.getProtectionDomain().getCodeSource().getLocation().toURI().toString().replace("%20", " "); // code breakage in 3, 2, 1... if (uri.endsWith(".class")) { uri = processString(uri); // stupid reference to a class within a jar } return new File(uri); } public static String getLibraryPath(Class c) throws URISyntaxException { return getLibraryPathAsFile(c).getAbsolutePath(); } private static String getClasspath(Properties p) throws URISyntaxException { return String.join( p.getProperty("path.separator"), getLibraryPath(Main.class), getLibraryPath(YggdrasilAuthenticationService.class), getLibraryPath(Gson.class), getLibraryPath(LogManager.class), getLibraryPath(Validate.class), getLibraryPath(ForwardingMultimap.class), getLibraryPath(Beta.class), getLibraryPath(CharEncoding.class), getLibraryPath(ByteOrderMark.class), getLibraryPath(Logger.class), getLibraryPath(Opcodes.class) ); } public static Properties getJavaProperties() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Properties p = new Properties(); Method m = System.class.getDeclaredMethod("initProperties", Properties.class); m.setAccessible(true); m.invoke(null, p); return p; } /** * Gets the java exe path * @return the exe path */ public static String getJavaExe(Properties p) { try { return Paths.get(String.join( p.getProperty("file.separator"), p.getProperty("java.home"), "bin", "java" + (SystemUtils.IS_OS_WINDOWS ? ".exe" : "") )).toFile().getAbsolutePath(); } catch (Exception e) { throw new RuntimeException(e); } } public static void setToken(String token) throws IOException, InvocationTargetException, NoSuchMethodException, IllegalAccessException, URISyntaxException { Properties p = getJavaProperties(); ProcessBuilder processBuilder = new ProcessBuilder( getJavaExe(p), "-XX:+DisableAttachMechanism", "-cp", getClasspath(p), Main.class.getName() ); processBuilder.redirectOutput(ProcessBuilder.Redirect.INHERIT).redirectError(ProcessBuilder.Redirect.INHERIT); Process c = processBuilder.start(); c.getOutputStream().write((token + "\n").getBytes(StandardCharsets.UTF_8)); c.getOutputStream().flush(); } }