diff --git a/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java b/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java index ed1fa46452..47a8bba151 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java @@ -51,13 +51,16 @@ import javax.inject.Singleton; import java.applet.Applet; import java.io.*; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.jar.*; import java.util.logging.Logger; @@ -66,27 +69,33 @@ import static net.runelite.client.rs.ClientUpdateCheckMode.*; @Slf4j @Singleton -public class ClientLoader { - public static File hooksFile = new File(RuneLite.RUNELITE_DIR + "/hooks-" + RuneLiteAPI.getVersion() + "-.json"); - private final ClientConfigLoader clientConfigLoader; - private ClientUpdateCheckMode updateCheckMode; - private JarOutputStream target; +public class ClientLoader +{ + public static File hooksFile = new File(RuneLite.RUNELITE_DIR+"/hooks-"+ RuneLiteAPI.getVersion() +"-.json"); + private final ClientConfigLoader clientConfigLoader; + private ClientUpdateCheckMode updateCheckMode; + private JarOutputStream target; + private boolean scrapedHooks = false; - @Inject - private ClientLoader( - @Named("updateCheckMode") final ClientUpdateCheckMode updateCheckMode, - final ClientConfigLoader clientConfigLoader) { - this.updateCheckMode = updateCheckMode; - this.clientConfigLoader = clientConfigLoader; - } + @Inject + private ClientLoader( + @Named("updateCheckMode") final ClientUpdateCheckMode updateCheckMode, + final ClientConfigLoader clientConfigLoader) + { + this.updateCheckMode = updateCheckMode; + this.clientConfigLoader = clientConfigLoader; + } - private static Certificate[] getJagexCertificateChain() throws CertificateException { - CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); - Collection certificates = certificateFactory.generateCertificates(ClientLoader.class.getResourceAsStream("jagex.crt")); - return certificates.toArray(new Certificate[certificates.size()]); - } - - public static String getClientInstance(String jarFile) { + private static Certificate[] getJagexCertificateChain() throws CertificateException + { + CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); + Collection certificates = certificateFactory.generateCertificates(ClientLoader.class.getResourceAsStream("jagex.crt")); + return certificates.toArray(new Certificate[certificates.size()]); + } + + public static String initVanillaInjected(String jarFile) { + List protectedMethods = new ArrayList<>(); + String clientInstance = ""; JarClassLoader jcl = new JarClassLoader(); try { ClassPool classPool = new ClassPool(true); @@ -114,8 +123,10 @@ public class ClientLoader { try { jcl2.add(new FileInputStream(ByteCodeUtils.injectedClientFile)); Field[] fields = classToLoad.getDeclaredFields(); + Method[] methods = classToLoad.getMethods(); for (Field f : fields) { try { + if (f.getType().getName() == "client") { ByteCodePatcher.hooks.clientInstance = classToLoad.getName() + "." + f.getName(); System.out.println("[RuneLit] Found client instance at " + classToLoad.getName() + "." + f.getName()); @@ -125,6 +136,11 @@ public class ClientLoader { e.printStackTrace(); } } + for (Method m : methods) { + if (m.getName().contains("protect")) { + protectedMethods.add(classToLoad.getName()+":"+m.getName()); + } + } } catch (FileNotFoundException e) { e.printStackTrace(); } @@ -142,7 +158,14 @@ public class ClientLoader { } catch (Exception e) { e.printStackTrace(); } - return ""; + String[] hooksProtectedMethods = new String[protectedMethods.size()]; + int i = 0; + for (String s : protectedMethods) { + hooksProtectedMethods[i] = s; + i++; + } + ByteCodePatcher.hooks.protectedMethods = hooksProtectedMethods; + return clientInstance; } public Applet load() { @@ -262,10 +285,10 @@ public class ClientLoader { if (hooks.clientInstance.equals("") || hooks.projectileClass.equals("") || hooks.actorClass.equals("") || - hooks.mainClientInstance.equals("") || + hooks.clientInstance.equals("") || hooks.playerClass.equals("")) { System.out.println("[RuneLit] Bad hooks, re-scraping."); - ByteCodePatcher.clientInstance = getClientInstance(ByteCodeUtils.injectedClientFile.getPath()); + ByteCodePatcher.clientInstance = ByteCodeUtils.injectedClientFile.getPath(); ByteCodePatcher.findHooks(injectedClientFile.getPath()); } else { ByteCodePatcher.clientInstance = hooks.clientInstance; @@ -275,7 +298,7 @@ public class ClientLoader { } else { System.out.println("[RuneLit] Hooks file not found, scraping hooks."); - ByteCodePatcher.clientInstance = getClientInstance(ByteCodeUtils.injectedClientFile.getPath()); + ByteCodePatcher.clientInstance = initVanillaInjected(ByteCodeUtils.injectedClientFile.getPath()); ByteCodePatcher.findHooks(injectedClientFile.getPath()); } diff --git a/runelite-client/src/main/java/net/runelite/client/rs/bytecode/ByteCodePatcher.java b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/ByteCodePatcher.java index 555d47a970..9b1b614cc4 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/bytecode/ByteCodePatcher.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/ByteCodePatcher.java @@ -7,10 +7,7 @@ import javassist.CtClass; import javassist.NotFoundException; import net.runelite.client.RuneLite; import net.runelite.client.rs.ClientLoader; -import net.runelite.client.rs.bytecode.transformers.ActorTransform; -import net.runelite.client.rs.bytecode.transformers.PlayerTransform; -import net.runelite.client.rs.bytecode.transformers.ProjectileTransform; -import net.runelite.client.rs.bytecode.transformers.getProjectileTransform; +import net.runelite.client.rs.bytecode.transformers.*; import net.runelite.http.api.RuneLiteAPI; import org.xeustechnologies.jcl.JarClassLoader; @@ -43,11 +40,10 @@ public class ByteCodePatcher { transformActor(actorClass); Class projectileClass = Class.forName(hooks.projectileClass, false, child); transformProjectile(projectileClass); - Class getProjectileClass = Class.forName(hooks.mainClientInstance, false, child); - transformGetProjectile(getProjectileClass); Class playerClass = Class.forName(hooks.playerClass, false, child); transformPlayer(playerClass); - + Class clientClass = Class.forName(hooks.clientClass, false, child); + transformClient(clientClass); ByteCodeUtils.updateHijackedJar(); } catch (Exception e) { e.printStackTrace(); @@ -101,8 +97,8 @@ public class ByteCodePatcher { Class classToLoad = Class.forName(entry.getName().replace(".class", ""), false, child); checkActor(classToLoad); checkProjectile(classToLoad); - checkgetProjectiles(classToLoad); checkPlayer(classToLoad); + checkClient(classToLoad); } catch (Exception e) { e.printStackTrace(); } @@ -157,28 +153,6 @@ public class ByteCodePatcher { pt.modify(projectile); } - public static void checkgetProjectiles(Class getprojectile) { - try { - Method method = getprojectile.getDeclaredMethod("getProjectiles"); - if (method != null) { - hooks.mainClientInstance = getprojectile.getName(); - System.out.println("[RuneLit] Transforming Projectile at class: " + getprojectile.getName()); - getProjectileTransform gpt = new getProjectileTransform(); - gpt.modify(getprojectile); - } - } catch (NoSuchMethodException e) { - //e.printStackTrace(); - } catch (NoClassDefFoundError e) { - //e.printStackTrace(); - } - } - - public static void transformGetProjectile(Class current) { - System.out.println("[RuneLit] Transforming getProjectile at class: " + current.getName()); - getProjectileTransform gpt = new getProjectileTransform(); - gpt.modify(current); - } - public static void checkPlayer(Class current) { try { Method method = current.getDeclaredMethod("getSkullIcon"); @@ -188,6 +162,20 @@ public class ByteCodePatcher { PlayerTransform pt = new PlayerTransform(); pt.modify(current); } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void checkClient(Class current) { + try { + Method method = current.getDeclaredMethod("getProjectiles"); + if (method != null) { + hooks.clientInstance = current.getName(); + System.out.println("[RuneLit] Transforming Projectile at class: " + current.getName()); + ClientTransform ct = new ClientTransform(); + ct.modify(current); + } } catch (NoSuchMethodException e) { //e.printStackTrace(); } catch (NoClassDefFoundError e) { @@ -195,6 +183,12 @@ public class ByteCodePatcher { } } + public static void transformClient(Class client) { + System.out.println("[RuneLit] Transforming Client at class: " + client.getName()); + ClientTransform ct = new ClientTransform(); + ct.modify(client); + } + public static void transformPlayer(Class player) { System.out.println("[RuneLit] Transforming Player at class: " + player.getName()); PlayerTransform pt = new PlayerTransform(); diff --git a/runelite-client/src/main/java/net/runelite/client/rs/bytecode/Hooks.java b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/Hooks.java index e4d197b2bf..a879bb6aae 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/bytecode/Hooks.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/Hooks.java @@ -1,12 +1,16 @@ package net.runelite.client.rs.bytecode; +import java.lang.reflect.Method; +import java.util.List; + public class Hooks { public String clientInstance = ""; public String actorClass = ""; public String projectileClass = ""; - public String mainClientInstance = ""; public String playerClass = ""; + public String clientClass = "client"; //Always named client + public String[] protectedMethods; public Hooks() { } diff --git a/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/getProjectileTransform.java b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/ClientTransform.java similarity index 89% rename from runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/getProjectileTransform.java rename to runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/ClientTransform.java index 4242c88f59..75e4f6ff93 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/getProjectileTransform.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/ClientTransform.java @@ -3,27 +3,26 @@ package net.runelite.client.rs.bytecode.transformers; import javassist.CtClass; import javassist.CtMethod; import javassist.CtNewMethod; +import javassist.NotFoundException; import javassist.bytecode.AnnotationsAttribute; import javassist.bytecode.ClassFile; import javassist.bytecode.ConstPool; import net.runelite.client.rs.bytecode.ByteCodePatcher; - -public class getProjectileTransform { +public class ClientTransform { public CtClass ct = null; - public void modify(Class getprojectile) { + public void modify(Class client) { try { - ct = ByteCodePatcher.classPool.get(getprojectile.getName()); - - transformGetProjectile(); + ct = ByteCodePatcher.classPool.get(client.getName()); + transformGetProjectiles(); ByteCodePatcher.modifiedClasses.add(ct); - } catch (Exception e) { + } catch (NotFoundException e) { e.printStackTrace(); } } - public void transformGetProjectile() { + public void transformGetProjectiles() { CtMethod getProjectiles; try { @@ -53,4 +52,5 @@ public class getProjectileTransform { e.printStackTrace(); } } + } diff --git a/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/PlayerTransform.java b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/PlayerTransform.java index 86222601d4..475cb578fd 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/PlayerTransform.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/transformers/PlayerTransform.java @@ -1,4 +1,3 @@ - package net.runelite.client.rs.bytecode.transformers; import javassist.CtClass; @@ -61,4 +60,5 @@ public class PlayerTransform { e.printStackTrace(); } } -} \ No newline at end of file +} +