Tutorial How to load up other local scripts

Discussion in 'Tutorials & Resources' started by Exia, Feb 2, 2015.

  1. 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 bot if I ever get around to writing it. The hack an exploit in Java's Class system that allows access to a the script bot 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 bots, but to allow for scripts bots 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 bot, this one is just easy and simple):
    Code (Text):
    2. import com.runemate.game.api.script.framework.LoopingScript;
    4. public class TestScript extends LoopingScript   {
    6.     @Override
    7.     public void onLoop() {
    8.         System.out.println("Hello World!");
    9.     }
    10. }
    This is just to test the system out, here is the real meat of the hack:
    Code (Text):
    2. import java.lang.reflect.Field;
    3. import java.util.Scanner;
    4. import java.util.Vector;
    6. import com.runemate.game.api.script.framework.AbstractScript;
    7. import com.runemate.game.api.script.framework.LoopingScript;
    9. public class BatHacker extends LoopingScript{
    11.     private AbstractScript scriptInstance;
    13.     @Override
    14.     public void onStart(String... args){
    15.         try {
    16.             //First grab the ClassLoader for the script
    17.             ClassLoader loader = this.getClass().getClassLoader();
    19.             //Now grab the loader's class
    20.             Class<?> loaderClass = loader.getClass().getSuperclass();
    22.             //Grab the Field object from that class via reflection
    23.             Field classesField = loaderClass.getDeclaredField("classes");
    25.             //Change the Field from private to public (roughly)
    26.             classesField.setAccessible(true);
    28.             //Grab that "classes" field from out specific ClassLoader object
    29.             //At this point we should have all of the script that the client sees
    30.             Vector<?> scripts = (Vector<?>) classesField.get(loader);
    32.             //This part prompts the user to choose a script from the list
    33.             //Note that this uses the class names, not the script names
    34.             //TODO: implement as a GUI
    35.             System.out.println("Select the script you wish to start by choosing the number: ");
    36.             for (int i = 0; i < scripts.size(); i++) {
    37.                 System.out.println(i + ". " + ((Class<?>)scripts.get(i)).getSimpleName());
    38.             }
    40.             //Grab the number that the user chose
    41.             @SuppressWarnings("resource")
    42.             Scanner in = new Scanner(System.in);
    43.             int scriptIndex = in.nextInt();
    44.             //in.close(); DO NOT CLOSE THIS SCANNER SINCE IT WILL CLOSE System.in AS WELL
    46.             //Make sure that class is actually a script
    47.             Object scriptOb = scripts.get(scriptIndex);
    48.             if(scriptOb instanceof Class){
    50.                 //Create a new instance of the script
    51.                 Class<?> script = (Class<?>)scriptOb;
    52.                 scriptInstance = (AbstractScript)script.newInstance();
    53.             }
    55.             if(scriptInstance == null){
    56.                 System.out.println("Failed to load scriprt!");
    57.             }else{
    58.                 //TODO: maybe prompt for arguments
    59.                 scriptInstance.onStart("");
    60.             }
    62.         } catch (Exception e) {
    63.             e.printStackTrace();
    64.         }
    65.     }
    67.     @Override
    68.     public void onLoop() {
    69.         //This is how you would access the loop of the script
    70.         //If the script is a TaskScript, simply cast to that instead
    71.         if(scriptInstance != null){
    72.             LoopingScript loopInstance = (LoopingScript)scriptInstance;
    73.             loopInstance.onLoop();
    74.         }
    75.     }
    76. }
    Read the comments in the code, but feel free to post any questions.

    Theoretically this should work with store scripts bots if run from the store since store scripts bots 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.
  2. So, would this work with epicbot?
  3. 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.
  4. okay, thanks
  5. That's pretty funny. You should demonstrate it in a video or something. :p
  6. Best I can do is some screen caps:
    This is a simple example, the main script bot just outputs the login status, and the test script bot simply logs out.
    Here is the test script bot loop
    Code (Text):
    2.     public void onLoop() {
    3.         System.out.println("This is the test script, Hi there");
    4.         while(!RuneScape.isLoggedIn());
    5.         RuneScape.logout();
    6.     }
    Here is main script bot's loop
    Code (Text):
    2.     public void onLoop() {
    3.         while(!RuneScape.isLoggedIn());
    4.         System.out.println("Logged in:" + RuneScape.isLoggedIn());
    5.         Execution.delay(1000);
    6.         System.out.println("Hello from the script loader!");
    7.         //This is how you would access the loop of the script
    8.         //If the script is a TaskScript, simply cast to that instead
    9.         if(scriptInstance != null){
    10.             LoopingScript loopInstance = (LoopingScript)scriptInstance;
    11.             loopInstance.onLoop();
    12.         }
    13.         while(Mouse.isMoving())Execution.delay(2000);
    15.         System.out.println("Logged in:" + RuneScape.isLoggedIn());
    16.         stop();
    17.     }
    Here is the output
    You can see that the main script bot does not log the user out, yet the user is still logged out by the other script bot.
    #6 Exia, Feb 5, 2015
    Last edited: Feb 5, 2015
    Bertrand likes this.
  7. 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 bots in my script bot scheduler :) Thanks bat
  8. It shouldn't work on store scripts bots because we don't load them until they're needed, and even then they all have a unique class loader.
  9. 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.
  10. I don't remember class loaders having references to their child loaders.
  11. 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.
  12. 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.

Share This Page