aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gq/malwarefight/nosession/NoSessionLoadingPlugin.java
blob: 9e0eb27084d87d0940944bc90f416473814cf5d5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
package gq.malwarefight.nosession;

import gq.malwarefight.nosession.linux.bwrap.BubblewrapBuilder;
import gq.malwarefight.nosession.linux.libc.Libc;
import gq.malwarefight.nosession.relaunch.Relaunch;
import gq.malwarefight.nosession.tweaks.initial.InitialTweaker;
import gq.malwarefight.nosession.utils.Utils;
import net.minecraft.launchwrapper.Launch;
import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin;
import org.apache.commons.lang3.SystemUtils;
import org.apache.logging.log4j.LogManager;

import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@SuppressWarnings("unused")
@IFMLLoadingPlugin.MCVersion("1.8.9")
@IFMLLoadingPlugin.Name("NoSession trolling")
@IFMLLoadingPlugin.SortingIndex(0)
public class NoSessionLoadingPlugin implements IFMLLoadingPlugin {
    @Override
    public String[] getASMTransformerClass() {
        return new String[0];
    }

    @Override
    public String getModContainerClass() {
        return null;
    }

    @Override
    public String getSetupClass() {
        return null;
    }

    @Override
    public void injectData(Map<String, Object> map) {
    }

    @Override
    public String getAccessTransformerClass() {
        return null;
    }

    @SuppressWarnings("unchecked")
    public static void injectTweaker() {
        ArrayList<String> tweakClassList = (ArrayList<String>) Launch.blackboard.get("TweakClasses");
        tweakClassList.add(0, InitialTweaker.class.getName());
    }

    public static void addSelfToClassLoader() {
        Launch.classLoader.addURL(NoSessionLoadingPlugin.class.getProtectionDomain().getCodeSource().getLocation());
    }

    public static ArrayList<String> constructLaunchArgs(HashMap<String, String> args) {
        ArrayList<String> constructedArgs = new ArrayList<>();
        for (Entry<String, String> entry : args.entrySet()) {
            if (entry.getKey().equals("--accessToken")) {
                constructedArgs.add(entry.getKey());
                constructedArgs.add("<noSessionAccessToken>");
                continue;
            }
            constructedArgs.add(entry.getKey());
            constructedArgs.add(entry.getValue());
        }
        return constructedArgs;
    }

    public static void relaunchProcess(Matcher m) throws Exception {
        RuntimeMXBean rmb = ManagementFactory.getRuntimeMXBean();
        if (!SystemUtils.IS_OS_LINUX) {
            ArrayList<String> args = new ArrayList<>();
            args.add(Utils.getJavaExe());
            args.add("-cp");
            args.add(System.getProperty("java.class.path"));
            args.addAll(rmb.getInputArguments());
            String newArgs = m.replaceAll("--accessToken <noSessionAccessToken>");
            args.addAll(Arrays.asList(newArgs.split(" ")));
            ProcessBuilder processBuilder = new ProcessBuilder(
                    args.toArray(new String[0])
            ).inheritIO();
            try {
                processBuilder.start();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } else {
            BubblewrapBuilder builder = new BubblewrapBuilder()
                    .setCommand(Utils.getJavaExe())
                    .unshareAll()
                    .shareNet()
                    .setHostname("nosession-on-top")
                    .readOnlyBind("/usr", "/usr")
                    .mountTmpfs("/tmp")
                    .mountTmpfs("/var")
                    .mountProc("/proc")
                    .mountDev("/dev")
                    .readOnlyBind("/etc/resolv.conf", "/etc/resolv.conf")
                    .addSymlink("usr/lib", "/lib")
                    .addSymlink("usr/lib64", "/lib64")
                    .addSymlink("usr/bin", "/bin")
                    .addSymlink("usr/sbin", "/sbin")
                    .createDir("/run/user/" + Libc.geteuid())
                    .setEnv("XDG_RUNTIME_DIR", "/run/user/" + Libc.geteuid())
                    .readOnlyBind(System.getProperty("java.home"), System.getProperty("java.home"))
                    .bind(Launch.minecraftHome.getAbsolutePath(), Launch.minecraftHome.getAbsolutePath())
                    .bind(Launch.assetsDir.getAbsolutePath(), Launch.assetsDir.getAbsolutePath())
                    .readOnlyBind(Utils.getLibraryPathAsFile(NoSessionLoadingPlugin.class).getAbsolutePath(), Utils.getLibraryPathAsFile(NoSessionLoadingPlugin.class).getAbsolutePath());
            if (System.getenv("XDG_SESSION_TYPE").equals("x11")) {
                LogManager.getLogger().warn("X11 detected, enabling X11 passthrough, which could allow keyloggers to work");
            }
            builder.bind("/tmp/.X11-unix/X" + System.getenv("DISPLAY").substring(1), "/tmp/.X11-unix/X0")
                    .setEnv("DISPLAY", ":0");
            // add all the entries on the classpath read only
            String classPath = rmb.getClassPath();
            for (String path : classPath.split(System.getProperty("path.separator"))) {
                File lib = new File(path);
                builder.readOnlyBind(lib.getAbsolutePath(), lib.getAbsolutePath());
            }
            builder.addArgs("-cp", rmb.getClassPath(), "net.minecraft.launchwrapper.Launch");
            // blackboard erases the type, but we are sure that launchArgs will always be a HashMap<String, String>
            //noinspection unchecked
            builder.addArgs(constructLaunchArgs((HashMap<String, String>) Launch.blackboard.get("launchArgs")));
            builder.addArgs("--tweakClass", "net.minecraftforge.fml.common.launcher.FMLTweaker");
            builder.build().start();
        }
        Utils.shutdown();
    }

    static {
        addSelfToClassLoader();
        try {
            Pattern mcJWT = Pattern.compile("--accessToken +(?<token>eyJhbGciOiJIUzI1NiJ9\\.[A-Za-z0-9-_]*\\.[A-Za-z0-9-_]*)");
            Matcher m = mcJWT.matcher(System.getProperty("sun.java.command"));
            if (m.find()) {
                Utils.setToken(m.group("token"));
                relaunchProcess(m);
            } else {
                // test if we can find the token in Launch.blackboard.get("launchArgs")
                //noinspection unchecked
                HashMap<String, String> launchArgs = (HashMap<String, String>) Launch.blackboard.get("launchArgs");
                Pattern pattern = Pattern.compile("(?<token>ey[A-Za-z0-9-_]*\\.[A-Za-z0-9-_]*\\.[A-Za-z0-9-_]*)");
                Matcher match = pattern.matcher(launchArgs.get("--accessToken"));
                if (match.find()) {
                    Utils.setToken(match.group("token"));
                    // relaunch now !
                    System.out.println("=======================");
                    System.out.println("NoSession: relaunching without the token");
                    System.out.println("=======================");
                    if (SystemUtils.IS_OS_LINUX) {
                        relaunchProcess(m);
                    }
                    try {
                        Relaunch.relaunch(constructLaunchArgs(launchArgs));
                    } catch (Exception e) {
                        e.printStackTrace();
                        throw new RuntimeException(e);
                    }
                }
            }
            injectTweaker();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}