Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

Sign up now!

Tutorial How to load up other local scripts

Joined
Nov 3, 2013
Messages
609
I've got a fun little hack here that I have been working on. I plan to use this for my player owned port script if I ever get around to writing it. The hack an exploit in Java's Class system that allows access to a the script Classloader and from there with a bit of Reflection the other classes that have been loaded by that loader. As it stands, this is a sort of Beta to the hack and I plan to actually make it work with a gui and implement some sample logic for future use. The main idea here is not steal data or other scripts, but to allow for scripts that have some sort of long wait time in between actions to better use their idle time. A good example of this is farming trees where it might take several hours for a single tree to grow, and those hours could be spent crafting nature runes. So here it is.

Here is the first class you will need (or any local script, this one is just easy and simple):
Code:
import com.runemate.game.api.script.framework.LoopingScript;

public class TestScript extends LoopingScript	{

	@Override
	public void onLoop() {
		System.out.println("Hello World!");
	}
}
This is just to test the system out, here is the real meat of the hack:
Code:
import java.lang.reflect.Field;
import java.util.Scanner;
import java.util.Vector;

import com.runemate.game.api.script.framework.AbstractScript;
import com.runemate.game.api.script.framework.LoopingScript;

public class BatHacker extends LoopingScript{
	
	private AbstractScript scriptInstance;
	
	@Override
	public void onStart(String... args){
		try {
			//First grab the ClassLoader for the script
			ClassLoader loader = this.getClass().getClassLoader();
			
			//Now grab the loader's class
			Class<?> loaderClass = loader.getClass().getSuperclass();
			
			//Grab the Field object from that class via reflection
			Field classesField = loaderClass.getDeclaredField("classes");
			
			//Change the Field from private to public (roughly)
			classesField.setAccessible(true);
			
			//Grab that "classes" field from out specific ClassLoader object
			//At this point we should have all of the script that the client sees
			Vector<?> scripts = (Vector<?>) classesField.get(loader);
			
			//This part prompts the user to choose a script from the list
			//Note that this uses the class names, not the script names
			//TODO: implement as a GUI
			System.out.println("Select the script you wish to start by choosing the number: ");
			for (int i = 0; i < scripts.size(); i++) {
				System.out.println(i + ". " + ((Class<?>)scripts.get(i)).getSimpleName());
			}
			
			//Grab the number that the user chose
			@SuppressWarnings("resource")
			Scanner in = new Scanner(System.in);
			int scriptIndex = in.nextInt();
			//in.close(); DO NOT CLOSE THIS SCANNER SINCE IT WILL CLOSE System.in AS WELL
			
			//Make sure that class is actually a script
			Object scriptOb = scripts.get(scriptIndex);
			if(scriptOb instanceof Class){
				
				//Create a new instance of the script
				Class<?> script = (Class<?>)scriptOb;
				scriptInstance = (AbstractScript)script.newInstance();
			}
			
			if(scriptInstance == null){
				System.out.println("Failed to load scriprt!");
			}else{
				//TODO: maybe prompt for arguments
				scriptInstance.onStart("");
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void onLoop() {
		//This is how you would access the loop of the script
		//If the script is a TaskScript, simply cast to that instead
		if(scriptInstance != null){
			LoopingScript loopInstance = (LoopingScript)scriptInstance;
			loopInstance.onLoop();
		}
	}
}

Read the comments in the code, but feel free to post any questions.

Theoretically this should work with store scripts if run from the store since store scripts aren't loaded in sdk mode. I'll have to wait for a comment from @Cloud since this would obviously be a security risk if put on the store, but I would be curious enough just to try it.

DISCLAIMER: Use this at your own risk.
 
Joined
Nov 3, 2013
Messages
609
So, would this work with epicbot?
Everything in java needs to be loaded by a ClassLoader (not including some special cases) so theoretically, yes it should. I've never personally worked with EB, so I'm not sure how locked down the client is, they might have completely barred Reflection via a security manager. It might be worth a try though, reflection is a trial and error art, you won't know until you dive in an can actually figure out their class structures.
 
Joined
Dec 27, 2014
Messages
287
Everything in java needs to be loaded by a ClassLoader (not including some special cases) so theoretically, yes it should. I've never personally worked with EB, so I'm not sure how locked down the client is, they might have completely barred Reflection via a security manager. It might be worth a try though, reflection is a trial and error art, you won't know until you dive in an can actually figure out their class structures.
okay, thanks
 
12 year old normie
Joined
Jan 8, 2015
Messages
2,768
That's pretty funny. You should demonstrate it in a video or something. :p
 
Joined
Nov 3, 2013
Messages
609
That's pretty funny. You should demonstrate it in a video or something. :p
Best I can do is some screen caps:
This is a simple example, the main script just outputs the login status, and the test script simply logs out.
Here is the test script loop
Code:
    public void onLoop() {
        System.out.println("This is the test script, Hi there");
        while(!RuneScape.isLoggedIn());
        RuneScape.logout();
    }
Here is main script's loop
Code:
    public void onLoop() {
        while(!RuneScape.isLoggedIn());
        System.out.println("Logged in:" + RuneScape.isLoggedIn());
        Execution.delay(1000);
        System.out.println("Hello from the script loader!");
        //This is how you would access the loop of the script
        //If the script is a TaskScript, simply cast to that instead
        if(scriptInstance != null){
            LoopingScript loopInstance = (LoopingScript)scriptInstance;
            loopInstance.onLoop();
        }
        while(Mouse.isMoving())Execution.delay(2000);

        System.out.println("Logged in:" + RuneScape.isLoggedIn());
        stop();
    }
Here is the output
L8J5MmP.png]

You can see that the main script does not log the user out, yet the user is still logged out by the other script.
 
Last edited:
Author of MaxiBots
Joined
Dec 3, 2013
Messages
7,032
Very interesting, i was actually trying to do this the other week but couldn't work out the reflection stuff as i haven't really touched reflection. I might use this to see if i can schedule multiple scripts in my script scheduler :) Thanks bat
 
Engineer
Joined
Jul 28, 2013
Messages
2,776
It shouldn't work on store scripts because we don't load them until they're needed, and even then they all have a unique class loader.
 
Joined
Nov 3, 2013
Messages
609
It shouldn't work on store scripts because we don't load them until they're needed, and even then they all have a unique class loader.
Theoretically, if I were to keep working my way up the classloader's classloaders, I should be able to find a common parent and work my way back down the "classloader tree" via other paths. I was working on another hack that would have been much cooler (I would not have released that one if I did get it working lol), but I got banned on RS and have kind of lost my motivation for things RS. If I get my account back, we'll see what happens though.
 
Engineer
Joined
Jul 28, 2013
Messages
2,776
Theoretically, if I were to keep working my way up the classloader's classloaders, I should be able to find a common parent and work my way back down the "classloader tree" via other paths. I was working on another hack that would have been much cooler (I would not have released that one if I did get it working lol), but I got banned on RS and have kind of lost my motivation for things RS. If I get my account back, we'll see what happens though.
I don't remember class loaders having references to their child loaders.
 
Joined
Nov 3, 2013
Messages
609
I don't remember class loaders having references to their child loaders.
They should have a reference to any class they loaded, classloaders included. Even still, there's probably some stupid reflection crap that I could use to get to it. That's a lot of work though, and not really worth my time lol.
 
Engineer
Joined
Jul 28, 2013
Messages
2,776
They should have a reference to any class they loaded, classloaders included. Even still, there's probably some stupid reflection crap that I could use to get to it. That's a lot of work though, and not really worth my time lol.
They may have the class object for the loader, however I don't believe they store the object instances for them. And I'm also rather sure that if a child loader loads a class, it doesn't get stored in the parent class loaders. It only goes up the hierarchy if the current loader is unable to load a class.
 
Top