ClientLoader

Makes scraping/loading hooks a bit more robust/safer
Dumps protected RS methods to Hooks on update (not really needed but will keep for now)
This commit is contained in:
zeruth
2019-04-18 18:39:14 -04:00
parent 8680c08533
commit 07a8b2daf1
2 changed files with 40 additions and 8 deletions

View File

@@ -45,13 +45,16 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory; import java.security.cert.CertificateFactory;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.jar.Attributes; import java.util.jar.Attributes;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
@@ -88,6 +91,7 @@ public class ClientLoader
private final ClientConfigLoader clientConfigLoader; private final ClientConfigLoader clientConfigLoader;
private ClientUpdateCheckMode updateCheckMode; private ClientUpdateCheckMode updateCheckMode;
private JarOutputStream target; private JarOutputStream target;
private boolean scrapedHooks = false;
@Inject @Inject
private ClientLoader( private ClientLoader(
@@ -231,22 +235,31 @@ public class ClientLoader
Gson gson = new Gson(); Gson gson = new Gson();
Hooks hooks = gson.fromJson(new BufferedReader(new FileReader(hooksFile)), Hooks.class); Hooks hooks = gson.fromJson(new BufferedReader(new FileReader(hooksFile)), Hooks.class);
if (hooks.clientInstance.equals("")|| if (hooks == null && !scrapedHooks) {
System.out.println("[RuneLit] Bad hooks, re-scraping.");
ByteCodePatcher.clientInstance = initVanillaInjected(ByteCodeUtils.injectedClientFile.getPath());
ByteCodePatcher.findHooks(injectedClientFile.getPath());
scrapedHooks=true;
}
if ((hooks.clientInstance.equals("")||
hooks.projectileClass.equals("") || hooks.projectileClass.equals("") ||
hooks.actorClass.equals("") || hooks.actorClass.equals("") ||
hooks.playerClass.equals("")) { hooks.playerClass.equals("")) && !scrapedHooks) {
System.out.println("[RuneLit] Bad hooks, re-scraping."); System.out.println("[RuneLit] Bad hooks, re-scraping.");
ByteCodePatcher.clientInstance = getClientInstance(ByteCodeUtils.injectedClientFile.getPath()); ByteCodePatcher.clientInstance = initVanillaInjected(ByteCodeUtils.injectedClientFile.getPath());
ByteCodePatcher.findHooks(injectedClientFile.getPath()); ByteCodePatcher.findHooks(injectedClientFile.getPath());
} else { scrapedHooks=true;
} else if (!scrapedHooks) {
ByteCodePatcher.clientInstance = hooks.clientInstance; ByteCodePatcher.clientInstance = hooks.clientInstance;
ByteCodePatcher.applyHooks(ByteCodeUtils.injectedClientFile, hooks); ByteCodePatcher.applyHooks(ByteCodeUtils.injectedClientFile, hooks);
System.out.println("[RuneLit] Loaded hooks"); System.out.println("[RuneLit] Loaded hooks");
scrapedHooks=true;
} }
} else { } else {
System.out.println("[RuneLit] Hooks file not found, scraping hooks."); 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()); ByteCodePatcher.findHooks(injectedClientFile.getPath());
} }
@@ -335,7 +348,9 @@ public class ClientLoader
return certificates.toArray(new Certificate[certificates.size()]); return certificates.toArray(new Certificate[certificates.size()]);
} }
public static String getClientInstance(String jarFile) { public static String initVanillaInjected(String jarFile) {
List<String> protectedMethods = new ArrayList<>();
String clientInstance = "";
JarClassLoader jcl = new JarClassLoader(); JarClassLoader jcl = new JarClassLoader();
try { try {
ClassPool classPool = new ClassPool(true); ClassPool classPool = new ClassPool(true);
@@ -363,17 +378,23 @@ public class ClientLoader
try { try {
jcl2.add(new FileInputStream(ByteCodeUtils.injectedClientFile)); jcl2.add(new FileInputStream(ByteCodeUtils.injectedClientFile));
Field[] fields = classToLoad.getDeclaredFields(); Field[] fields = classToLoad.getDeclaredFields();
Method[] methods = classToLoad.getMethods();
for (Field f : fields) { for (Field f : fields) {
try { try {
if (f.getType().getName()=="client") { if (f.getType().getName()=="client") {
ByteCodePatcher.hooks.clientInstance = classToLoad.getName()+"."+f.getName(); ByteCodePatcher.hooks.clientInstance = classToLoad.getName()+"."+f.getName();
System.out.println("[RuneLit] Found client instance at "+classToLoad.getName()+"."+f.getName()); System.out.println("[RuneLit] Found client instance at "+classToLoad.getName()+"."+f.getName());
return classToLoad.getName()+"."+f.getName(); clientInstance = classToLoad.getName()+"."+f.getName();
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
for (Method m : methods) {
if (m.getName().contains("protect")) {
protectedMethods.add(classToLoad.getName()+":"+m.getName());
}
}
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -391,6 +412,13 @@ public class ClientLoader
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); 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;
} }
} }

View File

@@ -1,11 +1,15 @@
package net.runelite.client.rs.bytecode; package net.runelite.client.rs.bytecode;
import java.lang.reflect.Method;
import java.util.List;
public class Hooks { public class Hooks {
public String clientInstance = ""; public String clientInstance = "";
public String actorClass = ""; public String actorClass = "";
public String projectileClass = ""; public String projectileClass = "";
public String playerClass = ""; public String playerClass = "";
public String[] protectedMethods;
public Hooks() { public Hooks() {
} }