You are on page 1of 3

Welcome!

Since you've stumbled upon this thread, I'll take it for granted that you are in
terested in creating RSPS bots.
Some of you may be here to re-consolidate what you know, and some of you may be
completely new to this.
In my tutorials, I like to create "gaps" that would make you think about specifi
c concepts, and to help accelerate your learning process (if you're new, of cour
se).
So here are my recommendations before starting.
Recommendations (note that these are recommendations, and not requirements):
Competency with Java (or atleast a bit more than the basics).
Knowledge of ASM and atleast one of the APIs (Core, Tree)
Knowledge of bytecode and the JVM specifications. Learning bytecode is STRONGLY
recommended.
Knowledge of how the JVM works to an extent.
The skill to adapt to new "surroundings" while on your journey of reverse engine
ering an RSPS client.
All of my work will be using ASM as my bytecode manipulation tool. The only exce
ption to this is Part One of my tutorials (i.e. this thread).
If you don't know what ASM is and its framework of at least the Core API, it wil
l be hard to understand this tutorial. I'll try my best to explain what's happen
ing throughout my various tutorials.
Alright. So let's get started!
1.1 - Understanding how this Works
So what are you doing by hacking into the RSPS client? How does this all work?
Well, I can tell you straight off the bat that we're not going to modify the cli
ent's code to do something that alters the game itself. We're going to modify th
e client so that we can get its values.
The intention of this is to replicate the useful game code based on what we have
as an end-user. This will ultimately gives us access to these values; for use i
n a bot client.
To give a broader picture; imagine coding a simple program. Let's say that its i
ntention is to modify an integer, and we have created custom methods to modify i
t.
Having access to all of these fields, methods, classes, and its members is like
having your own, personal "control panel" for your use in order to modify and to
gain values of your variables and methods in your program.
Now imagine that there is a "backdoor" control panel (i.e. ASM). This control pa
nel does not give you as much access as the original control panel, but it still
gives you access to what you want. You could also alter the program through thi
s "control panel" but it can result instability if you don't know what you're do
ing.
Not to mention that if the program is run off of a server, you cannot modify the
game content itself. But who cares, you have access to variables and the values
of the variables that's on your machine.
1.2 - Altering a Java Class
Now that you have a basic idea of what we're trying to do, we need to create a "
tool" that would help alter these classes. Before we get started, you need to co
nsider the following:
-> How do we alter a class so that we can gain these values?
-> How do we use these altered classes to access these values when the main clas
s is compiled and executed?
The answer is quite simple. It's something that we programmers use quite frequen
tly. Take a guess?
Answer:
Spoiler
So lets put this into practice!
1.3 - The Dummy Class
Consider the following program:
/**
* A dummy class.
* @author trDna
*/
public class TheProgram {
public static String theSecretString = "Hello. My name is Bob.";
public static void main(String... args){ //Pretend its some sort of epic program
.
System.out.println("TheProgram's string value = " + theSecretString);
}
}
Let's say that we want to get the value of theSecretString. Using an editor of y
our choice, create a method that would return that value.
No peeking
Answer:
Spoiler
To get the value of the method that you hypothetically "injected", what do you n
eed to do if the variable IS NOT static?
You'll need to add an interface that has a method that returns a value of your c
hoice (in this case, a String object).
So here's an accessor's interface:
public interface Accessor {
public String getTheSecretString();
}
After using an injector (which we will get to in Part 2), the program should loo
k like this:
import com.dna.asm.accessors.Accessor;
/**
* A dummy class.
* @author trDna
*/
public class TheProgram implements Accessor { //<-----
public static String theSecretString = "Hello. My name is Bob.";
public static void main(String[]args){ //Pretend its some sort of epic program.
System.out.println("TheProgram's string value = " + theSecretString);
}
public String getTheSecretString(){
return theSecretString;
}
}
1.4 Pulling it altogether
Now hypothetically, you could get access to the value of theSecretString.
To make this seem more realistic, export TheProgram.jar into a jar file. Name it
"TheProgramJar.jar". Put it in your project folder.
You need to get that value by obtaining an instance of the altered main class, T
heProgram.java, or TheProgram.class when compiled (which is what we should be wo
rking with).
So lets make another class called Displayer. This class should be the class that
loads "TheProgram.class" and uses its accessor interface to return the value of
the string.
Let's use a URLClassLoader (replace the directory with wherever the modified The
Program.class is).
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
public class Displayer {
public static void main(String... args) throws MalformedURLException {
ClassLoader cl = new URLClassLoader(new URL[]{new URL("file:TheProgramJ
ar.jar")});
}
}
Now we're going to need to load the class file from inside the jar. Store this i
nto an Object (not necessary, but I'm just using it for flexibility).
try {
Object clazz = cl.loadClass("TheProgram").newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Once you have done that, simply cast clazz to an Accessor object (which is what
we used to implement the accessor method):
Accessor theAccessor = (Accessor) clazz;
Thanks to the Accessor cast, now we have access to Accessor's methods of the cla
ss.
Now simply call your method from theAccessor. Print it out to see what it says.
System.out.println(theAccessor.getTheSecretString());
If you have done it correctly, you should get "Hello. My name is Bob."
--------------------------------------------------------------------------------
----------------------------
I hope that now you have some sort of idea of what you need to do to get a wante
d value. We will get into the more interesting topic of injection. I will introd
uce "adapters" and their uses in injection. The next tutorial is where things ge
t interesting!
If you want to see what's ahead, you can take a look at my repository, and go to
the 'com.dna.asm.core.adapters' package. Don't worry if you don't understand it
, as the next tutorial will be released hopefully by tommorow or the weekend.

You might also like