SRL Archive - NOTA

Please Explain How Injection/Reflection/Java Bots work


YoHoJo

2013-09-22 19:55:31

Be as detailed but also as concise as you can, state it in a way anyone (noobs) could understand.

I'm assuming all java bots use one of these two methods (PowreBot, EpicBot, TriBot, OSBot, etc.)

If any of them use some other method or some other special techniques that you know of please include that too.

About 2 paragraphs or so should suffice, but explain it as you please!
Thanks!

rj

2013-09-22 20:18:16

K so Reflection and injections need to access client variables to run. You can download the client in .jar format and extract it and then use a java decompiler to see all of the classes. All of the classes contain values like position, animation, objects, NPCs and all that and the bot pretty much reads them via hooks. These classes are pretty much a shatstorm of randoms names those and are very hard to read(done on purpose). Anyway: Hooks have to be updated because these classes change therfor you would no longer be getting the correct value.

Example:

the class "as" contains the variable "d". d is the players current animation. So the hook for player animation would be "as.d". Some of these values you have to multiply (such as animation) to get the correct value. I have no idea how they get the multipliers for these things but the hook for player position would look like "as.d" * somelongnumber


So yea pretty much these devs write some wizzard code that correctly returns the classes that have desired values.

Wetish

2013-09-22 21:20:15

If you are interested in coding one.

NKN

2013-09-22 21:22:31

I'm not good enough? </3

I'll repost mine. If I said something wrong, lemme know pls.

A RuneScape bot is an automation software that can utilize third party code to simulate player actions. These bots work by being able to read obfuscated code on the client side. Basically, obfuscated code is just code that's been changed by a computer to be random and un-readable by humans. The bots can use two different methods to read this code, injection, and reflection.

Typically, bots use the injection approach. Injection is when you add "getter" methods into the code. These getter methods simply return a variable, say you had a variable called playerName, a getter for it would be return playerName. This would give us the playerName. They do this for many more variables, allowing scripters to read the data and make scripts that act apon it.

Some bots use reflection. Think of reflection like a copy machine. It takes a copy of the code, and then you can do what ever you want with it. So instead of inserting those getter methods, you can just read the code through reflection without having to bother about modifying the source code of the client sided RuneScape.

Both methods read the client side source code, and both have to use bytecode patters to be able to deobfuscate the code and figure out what all the variables are. It's up to the preference of the bot writer, to be honest.

Method

2013-09-22 21:24:41

From: Officer Barbrady
Some of these values you have to multiply (such as animation) to get the correct value. I have no idea how they get the multipliers for these things but the hook for player position would look like "as.d" * somelongnumber


That's part of the client's obfuscation that helps to make runtime analysis more difficult. The basic idea behind it is to encode the actual value before storing it and decode it when retrieving it. The technique the client uses makes use of multiplicative inverses to encode and decode values.

When you are retrieving the value in as.d (player.animation, let's say), as in your example above, you're actually getting player.animation * e, where e is the encoding value. Thus, to get player.animation, you need to multiply it by d, the decoding value, to get player.animation * e * d = player.animation * 1 = player.animation.

rj

2013-09-22 21:25:40

From: Method
That's part of the client's obfuscation that helps to make runtime analysis more difficult. The basic idea behind it is to encode the actual value before storing it and decode it when retrieving it. The technique the client uses makes use of multiplicative inverses to encode and decode values.

When you are retrieving the value in as.d (player.animation, let's say), as in your example above, you're actually getting player.animation * e, where e is the encoding value. Thus, to get player.animation, you need to multiply it by d, the decoding value, to get player.animation * e * d = player.animation * 1 = player.animation.


Shh I know but he said in noob terms :p

Brandon

2013-09-22 21:30:33

:l One does not simply ask how something complex and large works without explaining why they want to know?


There is absolutely no "noob" way to explain reflection or injection at all.



When you write a program, instructions are stored in memory or translated to assembly. Java is a language that is both compiled and interpreted. The JVM uses JIT (Just In Time Compiling) sometimes to compile the byte-code down to machine code on the fly so that the CPU can understand it.

TLDR, Java is compiled to byte code which can be interpreted or compiled down to machine code. All implementation defined.

Now that we understand this, we can move onto reflection. Brace yourself.. I'll be showing code in both compiled (C), assembled(ASM) and interpreted (Java/Bytecode) below..

Let us say you have a structure in a compiled language such as C or ASM:


struct foo
{
short a; /* 2 bytes */
int b; /* 4 bytes */
char c[6]; /* 6 bytes */
};

int main()
{
//Do whatever with foo here..
return 0;
}

when this is compiled to Assembly, it can look like:


section .data
struct:
struc Foo ;This name is usually replaced with something the compiler chooses.
a: resw 1 ;reserve word
b: resd 1 ;reserve dword
c: resb 6 ;reserve byte
endstruc

FooSize: dd $ - struct



section .text
global main
extern printf
extern scanf
extern malloc

main:

push ebp
mov ebp,esp


;Do whatever with struct here..

add esp, 4
mov esp, ebp
pop ebx
mov eax, 0 ;Return 0.
ret

and a function in C such as:


void Bar(int I)
{
//Function's body.
}


__ZB@4: ;This all depends on the compiler/calling convention.. The compiler will name this function. 4 is the size of the argument aka an integer.
push ebp
mov ebp,esp

;Function's body.

pop ebx
mov eax, 0
ret


Now looking at the above, in memory and registers, the CPU has no idea wtf a structure or a function is.. All it knows is instructions and addresses of things.. In fact, even your compiled program knows nothing about the structure of "Foo". When you want to access the variables or functions inside the "Foo" structure, you're telling it to just retrieve something stored at a specific address. Notice that Meh is actually just a label for convenience that you can jump to. That's really what a function looks like.

Another example is functions like the below in Java:


void print(String Str) {
System.out.println(Str);
}

Integer inc(Integer I){
return I + 1;
}

void foo(int A, char B, int C)
{
return 0;
}

Turns into:


print(Ljava/lang/String;)V;
Code:
0: getstatic #1; //Field java/lang/System.out:Ljava/io/PrintStream;
3: aload_0
4: invokevirtual #2; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
7: return


inc(Ljava/lang/Integer) Ljava/lang/Integer;
Code:
0: aload_1
1: invokevirtual #3; //Method java/lang/Integer.intValue:()I
4: iconst_1
5: iadd
6: invokestatic #4; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
9: areturn

foo(IZI)V; //Notice the arguments this time.
Code:
0: aload_1
.
. //Getting tired typing all out..
.
5: return

And as you can see, it actually keeps the signature of each function in a "Class file" which the JVM interprets or compiles. It stores accessors as well (private, public, static, protected, etc).. It also sometimes stores the names of the functions and whatever else.. Because it stores this information, the reader or observer of the class can actually retrieve information about a specified type or variable or function. The biggest point I'm trying to make is that the bytecode actually has information that you can use.. However, the compiled code (C/ASM) has no information at all. Just a bunch of addresses and registers whereas the bytecode has everything mentioned above.

Retrieving and using this information is known as reflection (you cannot do this in C or ASM or any compiled language that does not store such info).

When you run a java application, the JVM instantiates a "ClassLoader" that reads the class files and figures out what to do with each instruction and the information. In order to load RS into Smart or any Java bots, the authors need to instantiate a class loader and load all the classes within the jar file. They then need to instantiate an instance of the required classes such as the "RS2Applet.class" or the "Client.class"..

However, taking it a step further, you can store all classes loaded into an array and given the "path" to a class (usually "PackageName\ClassName" or "StaticClassName.FieldName" or "ClassInstance.FieldName"), you can use the following to access information about a field or function/member:


Class c = myClassLoaderInstance.loadClass("ClassNameHere");
Field f = c.getDeclaredField("nameOfSomeVariableOrFieldHere");
f.setAccessible(true);
f.get(null);

the above uses the classLoader that loaded the applet and all the RS classes. It then gets a field/variable holding some valuable information. You need to set that variable accessible in order to do anything with it.

That's just the tip of the iceburg but yeah.. That's basically all there is to reflection really.. You just get the classname/class instance and the field you want to access and you use the above to retrieve the information about it.


Injection however requires that you insert code into the client and then you can call your injected function which can spit out information that it retrieved. Most of the time you do not need to to call your injected function because the client calls it for you (depends entirely on where you inject the code). Usually you inject a getter or setter into a class or class member/function.

Take for example the following Java code:

void Foo()
{
//Foo was called.
}

And in ASM:

__Foo_Func:
push ebp
mov ebp,esp

;Foo was called.

pop ebx
mov eax, 0
ret

Now if we want to inject into that function, what we have to do is make that code call our function. It'd look like this:


void MyFunc()
{
}

void Foo()
{
MyFunc(); //When Foo is called, it automatically calls my function.
}


And in ASM, this is the equivalent of a technique called the trampoline technique requiring two JMP instructions.

__Foo_Func:
push ebp
mov ebp,esp

push eax, [0x1000h] ;Push this address before the call.. Lets call this addr 0x0998h;
jmp __MyFunc_Func ;Call MyFunc..
;This is the address after the call.. Lets call this addr 0x1000h;

pop ebx
mov eax, 0
ret


__MyFunc_Func:
push ebp
mov ebp,esp

;Body of MyFunc..
;Run my code here..

pop ebx
mov eax, 0
ret eax; ;Can either jmp to addr 0x1000h above or just return to the caller.

In the above, it works like this:

Foo is called. Foo calls MyFunc by jumping to the address of MyFunc. My func is ran and it has two choices. Either return the results to Foo or simply jump back to the "address after the call".


In java, injection is usually done through a Visitor using the ASM framework v4.XX. Practically the exact same thing as what I wrote above using ASM is going on under the hood of a Java bot.

YoHoJo

2013-09-23 04:02:17

From: Brandon
:l One does not simply ask how something complex and large works without explaining why they want to know?


There is absolutely no "noob" way to explain reflection or injection at all.


Although VERY informative, it's not exactly what I was looking for :/.

@Officer Barbrady and @NKN's explanations are more along the lines of what I waned, that's how you'd generally explain injection/reflection to someone who had no understanding of them.

Anyone else care to input please?

EngageTheRage

2013-09-23 06:40:46

From: Brandon
:l One does not simply ask how something complex and large works without explaining why they want to know?

……



thanks for taking the time to write that up!

i found it really interesting, do you happen to know of any resources that would explain further so that i could look at getting involved with the reflection side of it?

NKN

2013-09-23 06:43:25

From: EngageTheRage
thanks for taking the time to write that up!

i found it really interesting, do you happen to know of any resources that would explain further so that i could look at getting involved with the reflection side of it?


Do you want to write reflection, or script with reflection?

EngageTheRage

2013-09-23 06:48:42

From: NKN
Do you want to write reflection, or script with reflection?


the java behind it, not scripts :D

NKN

2013-09-23 06:53:22

From: EngageTheRage
the java behind it, not scripts :D


You can go here:
http://docs.oracle.com/javase/tutorial/reflect/

If you want to learn about client hacking, head over to:
http://javahacking.org

EngageTheRage

2013-09-23 06:54:28

From: NKN
You can go here:
http://docs.oracle.com/javase/tutorial/reflect/

If you want to learn about client hacking, head over to:
http://javahacking.org


thanks buddy :)

rj

2013-09-23 15:03:19

From: YoHoJo
Although VERY informative, it's not exactly what I was looking for :/.

@Officer Barbrady and @NKN's explanations are more along the lines of what I waned, that's how you'd generally explain injection/reflection to someone who had no understanding of them.

Anyone else care to input please?


Just curious were you looking on how to explain this in a tutorial video or did you secretly want to know how it worked :d

Kevin

2013-09-23 17:53:21

From: YoHoJo
Be as detailed but also concise as you can,make it accessible, state it in a way anyone (noobs) could understand.


YoHoJo

2013-09-23 19:15:35

From: Officer Barbrady
Just curious were you looking on how to explain this in a tutorial video or did you secretly want to know how it worked :d


Not for myself, mayyyybe for a video but I don't think so, for something else :X.
Anyone else care to explain in their words!

YoHoJo

2013-10-04 20:54:59

More More?

rj

2013-10-04 23:09:14

From: YoHoJo
More More?


Imagine if you had a simba script that could read all of the info in records of another simba script. Except the records and their properties and random letters