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.nosession.tweaks.InitialTweaker; 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.management.ManagementFactory; import java.lang.management.RuntimeMXBean; 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.FileAlreadyExistsException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.Properties; import java.util.Random; public class Utils { public static int PORT = -1; public static long ID = -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() { if (PORT == -1) { Socket socket = null; int port = 0; for (int i = BASE_PORT; i < BASE_PORT + 10; i++) { try { socket = new Socket(); socket.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), i)); socket.getOutputStream().write("id\n".getBytes(StandardCharsets.UTF_8)); String value = readString(socket.getInputStream(), '\n'); if (value.equals(Long.toString(ID))) { port = i; break; } } catch (Exception ignored) {} } PORT = port; return socket; } else { try { Socket socket = new Socket(); socket.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), PORT)); return socket; } catch (IOException e) { PORT = -1; return getProperSocket(); } } } 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 s) { // if (s.lastIndexOf("!") == -1) { // return s; // } // } public static File getLibraryPathAsFile(Class c) throws URISyntaxException { return new File(c.getProtectionDomain().getCodeSource().getLocation().getPath()); } public static String getLibraryPath(Class c) throws URISyntaxException { return getLibraryPathAsFile(c).getAbsolutePath(); } public static String getClasspath(Properties p) throws URISyntaxException { try { // try to be smart return String.join( p.getProperty("path.separator"), getLibraryPath(Utils.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) ); } catch (URISyntaxException | IllegalArgumentException e) { e.printStackTrace(); // fallback to "dumb" method RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean(); return runtimeMXBean.getClassPath() + p.getProperty("path.separator") + getLibraryPath(Utils.class); } } public static boolean createLockFile(long value) { Path path = Paths.get(System.getProperty("java.io.tmpdir"), "NoSessionLock" + value); try { Files.createFile(path); } catch (FileAlreadyExistsException e) { LogManager.getLogger().info("You won the lottery! Two NoSession instances used the same ID. The chance that a new NoSession instance uses the same ID as an old one is (NoSession instances) / 2^64"); return false; } catch (IOException e) { LogManager.getLogger().warn("Failed to create lockfile " + e.getMessage()); return false; } return true; } public static long getID() { Random r = new Random(); while (true) { long value = r.nextLong(); if (createLockFile(value)) { Runtime.getRuntime().addShutdownHook( new Thread(() -> { try { Files.delete(Paths.get(System.getProperty("java.io.tmpdir"), "NoSessionLock" + value)); } catch (Exception ignored) {} }) ); return value; } } } 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 { long value = getID(); ID = value; Properties p = getJavaProperties(); System.out.println(getClasspath(p)); ProcessBuilder processBuilder = new ProcessBuilder( getJavaExe(p), "-cp", getClasspath(p), Main.class.getName(), Long.toString(value) ); 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(); } }