Change how I load asm

This commit is contained in:
libraryaddict 2021-05-15 16:29:55 +12:00
parent 1e68eeb74d
commit 1eb5225389
6 changed files with 137 additions and 129 deletions

View File

@ -1,42 +1,17 @@
package me.libraryaddict.disguise.utilities.reflection.asm; package me.libraryaddict.disguise.utilities.reflection.asm;
import lombok.Getter;
import org.objectweb.asm.*; import org.objectweb.asm.*;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Map; import java.util.Map;
/** /**
* Created by libraryaddict on 17/02/2020. * Created by libraryaddict on 17/02/2020.
*/ */
public class Asm13 implements IAsm { public class Asm13 {
@Getter public byte[] createClassWithoutMethods(String className, ArrayList<Map.Entry<String, String>> illegalMethods)
private final LibsJarFile libsJarFile;
public Asm13() throws Throwable {
ClassLoader pluginClassLoader = getClass().getClassLoader();
Class c = Class.forName("org.bukkit.plugin.java.PluginClassLoader");
Field file = c.getDeclaredField("file");
file.setAccessible(true);
libsJarFile = new LibsJarFile((File) file.get(pluginClassLoader));
Field field = c.getDeclaredField("jar");
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(pluginClassLoader, libsJarFile);
}
public void createClassWithoutMethods(String className, ArrayList<Map.Entry<String, String>> illegalMethods)
throws IOException, InvocationTargetException, IllegalAccessException, NoSuchFieldException { throws IOException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
className = className.replace(".", "/") + ".class"; className = className.replace(".", "/") + ".class";
@ -57,6 +32,6 @@ public class Asm13 implements IAsm {
} }
}, 0); }, 0);
libsJarFile.addClass(className, writer.toByteArray()); return writer.toByteArray();
} }
} }

View File

@ -1,77 +0,0 @@
package me.libraryaddict.disguise.utilities.reflection.asm;
import lombok.AccessLevel;
import lombok.Getter;
import me.libraryaddict.disguise.LibsDisguises;
import me.libraryaddict.disguise.utilities.reflection.NmsVersion;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
/**
* Created by libraryaddict on 20/02/2020.
*/
@Getter(value = AccessLevel.PRIVATE)
public class AsmDownloader {
// private String urlToGrab = "https://repository.ow2.org/nexus/content/repositories/releases/org/ow2/asm/asm/7
// .3" +
// ".1/asm-7.3.1.jar";
/**
* Using maven
*/
private String urlToGrab = "https://search.maven.org/remotecontent?filepath=org/ow2/asm/asm/9.1/asm-9.1.jar";
private File filePath = new File(LibsDisguises.getInstance().getDataFolder(), "libs/org-ow2-asm-9.1.jar");
public AsmDownloader() {
try {
Class.forName("org.objectweb.asm.ClassReader");
return;
}
catch (NoClassDefFoundError | ClassNotFoundException ex) {
// It doesn't exist, good! Lets load it!
}
if (!hasASM()) {
LibsDisguises.getInstance().getLogger().info("Downloading required library for asm!");
downloadASM();
LibsDisguises.getInstance().getLogger().info("Downloaded!");
}
try {
Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
method.setAccessible(true);
method.invoke(getClass().getClassLoader(), filePath.toURI().toURL());
}
catch (Throwable t) {
t.printStackTrace();
}
}
private boolean hasASM() {
return filePath.exists();
}
private void downloadASM() {
filePath.getParentFile().mkdirs();
try (BufferedInputStream in = new BufferedInputStream(
new URL(getUrlToGrab()).openStream()); FileOutputStream fileOutputStream = new FileOutputStream(
getFilePath())) {
byte[] dataBuffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
fileOutputStream.write(dataBuffer, 0, bytesRead);
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,108 @@
package me.libraryaddict.disguise.utilities.reflection.asm;
import lombok.Getter;
import me.libraryaddict.disguise.LibsDisguises;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
/**
* Created by libraryaddict on 20/02/2020.
*/
@Getter
public class AsmLoader {
// private String urlToGrab = "https://repository.ow2.org/nexus/content/repositories/releases/org/ow2/asm/asm/7
// .3" +
// ".1/asm-7.3.1.jar";
/**
* Using maven
*/
private final String urlToGrab = "https://search.maven.org/remotecontent?filepath=org/ow2/asm/asm/9.1/asm-9.1.jar";
private final File filePath = new File(LibsDisguises.getInstance().getDataFolder(), "libs/org-ow2-asm-9.1.jar");
private boolean asmExists;
private URLClassLoader classLoader;
private LibsJarFile libsJarFile;
public AsmLoader() {
try {
Class.forName("org.objectweb.asm.ClassReader");
asmExists = true;
} catch (NoClassDefFoundError | ClassNotFoundException ex) {
// It doesn't exist, good! Lets load it!
}
}
public void loadClassloader() {
try {
classLoader = URLClassLoader.newInstance(new URL[]{filePath.toURI().toURL(), LibsDisguises.getInstance().getFile().toURI().toURL()});
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
public void load() {
try {
ClassLoader pluginClassLoader = getClass().getClassLoader();
Class c = Class.forName("org.bukkit.plugin.java.PluginClassLoader");
Field file = c.getDeclaredField("file");
file.setAccessible(true);
libsJarFile = new LibsJarFile((File) file.get(pluginClassLoader));
Field field = c.getDeclaredField("jar");
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(pluginClassLoader, libsJarFile);
} catch (Throwable e) {
e.printStackTrace();
}
}
public void unload() {
try {
classLoader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void doDownloadIfRequired() {
if (!hasASM()) {
LibsDisguises.getInstance().getLogger().info("Downloading required library for asm!");
downloadASM();
LibsDisguises.getInstance().getLogger().info("Downloaded!");
}
}
private boolean hasASM() {
return filePath.exists();
}
private void downloadASM() {
filePath.getParentFile().mkdirs();
try (BufferedInputStream in = new BufferedInputStream(new URL(getUrlToGrab()).openStream());
FileOutputStream fileOutputStream = new FileOutputStream(getFilePath())) {
byte[] dataBuffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
fileOutputStream.write(dataBuffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -1,17 +0,0 @@
package me.libraryaddict.disguise.utilities.reflection.asm;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Map;
/**
* Created by libraryaddict on 17/02/2020.
*/
public interface IAsm {
void createClassWithoutMethods(String className,
ArrayList<Map.Entry<String, String>> illegalMethods) throws IOException, InvocationTargetException,
IllegalAccessException, NoSuchMethodException, NoSuchFieldException;
}

View File

@ -5,7 +5,6 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.HashMap; import java.util.HashMap;
import java.util.jar.JarEntry;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;

View File

@ -2,15 +2,13 @@ package me.libraryaddict.disguise.utilities.reflection.asm;
import com.google.gson.Gson; import com.google.gson.Gson;
import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.LibsDisguises;
import me.libraryaddict.disguise.utilities.reflection.NmsVersion;
import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.java.JavaPluginLoader; import org.bukkit.plugin.java.JavaPluginLoader;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.*; import java.util.*;
@ -75,8 +73,22 @@ public class WatcherSanitizer {
ArrayList<String> mapped = new ArrayList<>(); ArrayList<String> mapped = new ArrayList<>();
try (InputStream stream = LibsDisguises.getInstance().getResource("ANTI_PIRACY_ENCRYPTION")) { try (InputStream stream = LibsDisguises.getInstance().getResource("ANTI_PIRACY_ENCRYPTION")) {
new AsmDownloader(); AsmLoader loader = new AsmLoader();
IAsm asm = new Asm13(); loader.load();
Object obj;
Method getBytes;
if (!loader.isAsmExists()) {
loader.doDownloadIfRequired();
loader.loadClassloader();
obj = Class.forName("me.libraryaddict.disguise.utilities.reflection.asm.Asm13", true, loader.getClassLoader()).newInstance();
} else {
obj = new Asm13();
}
getBytes = obj.getClass().getMethod("createClassWithoutMethods", String.class, ArrayList.class);
String[] lines = new String(ReflectionManager.readFully(stream), StandardCharsets.UTF_8).split("\n"); String[] lines = new String(ReflectionManager.readFully(stream), StandardCharsets.UTF_8).split("\n");
@ -99,8 +111,16 @@ public class WatcherSanitizer {
} }
for (Map.Entry<String, ArrayList<Map.Entry<String, String>>> entry : toRemove.entrySet()) { for (Map.Entry<String, ArrayList<Map.Entry<String, String>>> entry : toRemove.entrySet()) {
asm.createClassWithoutMethods(entry.getKey(), entry.getValue()); byte[] bytes = (byte[]) getBytes.invoke(obj, entry.getKey(), entry.getValue());
mapped.add(entry.getKey()); mapped.add(entry.getKey());
String name = entry.getKey().replace(".", "/") + ".class";
loader.getLibsJarFile().addClass(name, bytes);
}
if (!loader.isAsmExists()) {
loader.unload();
} }
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();