diff --git a/src/main/java/me/libraryaddict/disguise/utilities/reflection/asm/Asm13.java b/src/main/java/me/libraryaddict/disguise/utilities/reflection/asm/Asm13.java index 4a613cfc..8acdd10b 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/reflection/asm/Asm13.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/reflection/asm/Asm13.java @@ -1,42 +1,17 @@ package me.libraryaddict.disguise.utilities.reflection.asm; -import lombok.Getter; import org.objectweb.asm.*; -import java.io.File; import java.io.IOException; -import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Map; /** * Created by libraryaddict on 17/02/2020. */ -public class Asm13 implements IAsm { - @Getter - 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> illegalMethods) +public class Asm13 { + public byte[] createClassWithoutMethods(String className, ArrayList> illegalMethods) throws IOException, InvocationTargetException, IllegalAccessException, NoSuchFieldException { className = className.replace(".", "/") + ".class"; @@ -57,6 +32,6 @@ public class Asm13 implements IAsm { } }, 0); - libsJarFile.addClass(className, writer.toByteArray()); + return writer.toByteArray(); } } diff --git a/src/main/java/me/libraryaddict/disguise/utilities/reflection/asm/AsmDownloader.java b/src/main/java/me/libraryaddict/disguise/utilities/reflection/asm/AsmDownloader.java deleted file mode 100644 index 0e0c41a3..00000000 --- a/src/main/java/me/libraryaddict/disguise/utilities/reflection/asm/AsmDownloader.java +++ /dev/null @@ -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(); - } - } -} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/reflection/asm/AsmLoader.java b/src/main/java/me/libraryaddict/disguise/utilities/reflection/asm/AsmLoader.java new file mode 100644 index 00000000..3517581b --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/reflection/asm/AsmLoader.java @@ -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(); + } + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/reflection/asm/IAsm.java b/src/main/java/me/libraryaddict/disguise/utilities/reflection/asm/IAsm.java deleted file mode 100644 index cbf1cdc6..00000000 --- a/src/main/java/me/libraryaddict/disguise/utilities/reflection/asm/IAsm.java +++ /dev/null @@ -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> illegalMethods) throws IOException, InvocationTargetException, - IllegalAccessException, NoSuchMethodException, NoSuchFieldException; -} - - diff --git a/src/main/java/me/libraryaddict/disguise/utilities/reflection/asm/LibsJarFile.java b/src/main/java/me/libraryaddict/disguise/utilities/reflection/asm/LibsJarFile.java index ed120723..7ee3f405 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/reflection/asm/LibsJarFile.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/reflection/asm/LibsJarFile.java @@ -5,7 +5,6 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; -import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.zip.ZipEntry; diff --git a/src/main/java/me/libraryaddict/disguise/utilities/reflection/asm/WatcherSanitizer.java b/src/main/java/me/libraryaddict/disguise/utilities/reflection/asm/WatcherSanitizer.java index fcbc457f..bdc46a80 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/reflection/asm/WatcherSanitizer.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/reflection/asm/WatcherSanitizer.java @@ -2,15 +2,13 @@ package me.libraryaddict.disguise.utilities.reflection.asm; import com.google.gson.Gson; import me.libraryaddict.disguise.LibsDisguises; -import me.libraryaddict.disguise.utilities.reflection.NmsVersion; import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.java.JavaPluginLoader; -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.nio.charset.StandardCharsets; import java.util.*; @@ -75,8 +73,22 @@ public class WatcherSanitizer { ArrayList mapped = new ArrayList<>(); try (InputStream stream = LibsDisguises.getInstance().getResource("ANTI_PIRACY_ENCRYPTION")) { - new AsmDownloader(); - IAsm asm = new Asm13(); + AsmLoader loader = new AsmLoader(); + 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"); @@ -99,8 +111,16 @@ public class WatcherSanitizer { } for (Map.Entry>> entry : toRemove.entrySet()) { - asm.createClassWithoutMethods(entry.getKey(), entry.getValue()); + byte[] bytes = (byte[]) getBytes.invoke(obj, entry.getKey(), entry.getValue()); mapped.add(entry.getKey()); + + String name = entry.getKey().replace(".", "/") + ".class"; + + loader.getLibsJarFile().addClass(name, bytes); + } + + if (!loader.isAsmExists()) { + loader.unload(); } } catch (Throwable e) { e.printStackTrace();