SRL Archive - Research & Development Lounge

Memory reading?


maigel

2012-01-24 18:37:11

Hi,

Before runescape, I've been making bots for other games too. (Mostly in AutoIt / C#).
The difference was however, these games were downloadable games which had an exe to run.
The technique most people (including me) used to make bots for these kind of games was memory adress reading. You would use a program to find the memory adress for hp, mana, player coordinates, … (http://www.cheatengine.org).
Now, I was wondering, has something likes this been done before or would it be possible at all? Because if it is, it could be very usefull to find coordinates etc for a good and fast positioning system.

P.S.: I've looked into reflection but what I'm talking about is something different, reflection injected code, this would just look into the memory.

x[Warrior]x3500

2012-01-24 19:10:14

injection injects the code, reflection reflects it ;) the only way i see this being able to work is if we can hook OGL. reflection would have been wat u r tlking about though

maigel

2012-01-25 05:42:25

I'm pretty sure reflection isn't 100% what I mean, but I might be wrong though.
I added some example to clear out what I mean, In the example below I found the memory adress that refers too "Amount of items on inventory slot 1". This is still pretty basic put I'm pretty sure that if I dig deeper into it I can find item IDs on slot x etc etc.



momotron

2012-01-25 05:50:33

Can you explain how this would work better? I haven't fully grasped the concept yet :S

maigel

2012-01-25 05:57:46

From: momotron
Can you explain how this would work better? I haven't fully grasped the concept yet :S


I'll try the best I can:
So, basically every program that runs on your computer (including java/runescape) has it's own "memory place" assigned. In this "place of memory" it stores all data that's relevant to the program like program code, save data, current player position, …
What this thing actually does is, it "invades" runescape's "memory place" and reads some of the memory. (Like in my example above, the amount of items on inventory slot 1)

Now, if we could integrate this in a bot it would allow 100% correct data since it's directly read from the program's memory (compared to colour, which might lead to wrong results from time to time) resulting in a way more accurate bot.

KingKong

2012-01-25 05:58:13

What you're talking about is not reflection or injection. But I think its actually a good idea that you gave. If this could be implemented in simba it would be awesome, as long as its undetectable.

Daniel

2012-01-25 06:17:25

I seriously doubt this would be possible with Jagex's new system of generating a new client every 6 hours..

superuser

2012-01-25 06:43:50

From: Daniel
I seriously doubt this would be possible with Jagex's new system of generating a new client every 6 hours..


It doesn't matter how often the client is "generated", it's nevertheless very hard to construct structures from 3rd party process' memory space. For instance, depending on the variable type, the information can or cannot be in continuous address space.

So, everytime you load the client the memory structure is different. And btw, this is injection indeed.

maigel

2012-01-25 06:50:21

From: superuser
It doesn't matter how often the client is "generated", it's nevertheless very hard to construct structures from 3rd party process' memory space. For instance, depending on the variable type, the information can or cannot be in continuous address space.

So, everytime you load the client the memory structure is different. And btw, this is injection indeed.


For other games this wasn't really that hard (don't know about java / rs though). You would basically just find the base pointer which is static every time you start the program.

Edit:
I'm trying to see if I can find a base pointer for the inventory slot as we speak.

KingKong

2012-01-25 07:43:53

From: superuser
It doesn't matter how often the client is "generated", it's nevertheless very hard to construct structures from 3rd party process' memory space. For instance, depending on the variable type, the information can or cannot be in continuous address space.

So, everytime you load the client the memory structure is different. And btw, this is injection indeed.


It is possible to map memory spaces once you find one of them, ive used it a lot of times in the same way. Oh and how is this injection? I don't see any modification or decompiling jagex's code, if anything, its close to reflection.

alar82

2012-01-25 08:21:53

You sir are genius, even old reflection based id s work:

124 !!! cabbage amount at 1 slot
1966 noted cabbage id !!! its the same as reflection one!

edit:only thing is addres change when client is loaded.
If this memory reading thing could be maked into plugin-that would be rad.

masterBB

2012-01-25 08:41:45

Doesn't the memory address change every time you reload the game?

maigel

2012-01-25 08:46:26

From: masterBB
Doesn't the memory address change every time you reload the game?


Well … Yes, this is the main problem. However, it can be solved by finding a base pointer or something similar. I've not been able to find a static adress yet. Altough I've hooked a disassembler into the java.exe and I found an adress for the instruction where the adress is calculated. This instruction adress stays the same whenever you relog!

I haven't quite worked it out very well but now that I know that the reflection IDs can be found etc (thanks to alar82 for that ;)) I'll see what I can do with some bits of assembly code. I'll report all the progress I manage to make in this topic :)

NickMystre

2012-01-25 10:51:22

I'd be surprised if the memory locations were static - probably use memory hopping techniques to prevent that sort of thing en masse.

superuser

2012-01-25 10:51:51

From: KingKong
It is possible to map memory spaces once you find one of them, ive used it a lot of times in the same way. Oh and how is this injection? I don't see any modification or decompiling jagex's code, if anything, its close to reflection.


I'm not sure you understand what injection means. It means literally injecting your code into other process' address space. It doesn't involve decompiling or modifications at all.

From: NickMystre
I'd be surprised if the memory locations were static - probably use memory hopping techniques to prevent that sort of thing en masse.


Exactly. On top of that, as we know at a high level, your program is split in to 3 sections: code, data, and stack. The OS places these where it sees fit, and the memory manager controls what and where you can see stuff.

go9090go

2012-01-25 11:20:00

If you can hook the x and y coordinat, simba will be over powered. the only thing that makes reflexion better then color is the player position. Maybe try to make a plugin for player locations. and if you made it, make a guide how to d
o it. im sure many people will help you

JN13

2012-01-25 11:31:52

From: superuser
The OS places these where it sees fit, and the memory manager controls what and where you can see stuff.


So would it be possible to direct your OS to load the memory in a specific location? I've used memory manipulators before, and as long as you don't change any variables, its pretty hard to catch.

If its not possible to find a static location, maybe make a procedure to find it at the beginning of a load?

Nice idea!

Olly

2012-01-25 12:06:15

This is pretty interesting good work =]

maigel

2012-01-25 12:16:39

For those who were talking about it not being possible because the memory changes, the memory does change but here's what I've found out so far:

At adress 025FBA0D theres the machine instruction mov eax,[edx+eax*4+0C].
Now what this does is:
- EDX the base adress of the "iventory stuff array"
- EAX: the inventory slot you want (each inventory item amount takes up 4 bytes, hence the *4)
- 0C: a static offset

Now, I've injected a detour that changes
mov eax,[edx+eax*4+0C]
into
mov [slotAddress], edx
mov eax,[edx+eax*4+0C]

et voila, slotAddress now contains the address of the inventory array :)


EDIT:
025FBA0D doesn't seem to be static either BUT the pattern of instructions is (ofcourse, its the program code).
Now I've seen people making "code pattern searchers" to inject something in the right position before, I don't know how to do this yet though.
I'm pretty sure this is perfectly doable, I didn't say it's gonna be easy though :) I'll keep trying ^^

superuser

2012-01-25 12:30:00

From: maigel
For those who were talking about it not being possible because the memory changes, the memory does change but here's what I've found out so far:

At adress 025FBA0D theres the machine instruction mov eax,[edx+eax*4+0C].
Now what this does is:
- EDX the base adress of the "iventory stuff array"
- EAX: the inventory slot you want (each inventory item amount takes up 4 bytes, hence the *4)
- 0C: a static offset

Now, I've injected a detour that changes
mov eax,[edx+eax*4+0C]
into
mov [slotAddress], edx
mov eax,[edx+eax*4+0C]

et voila, slotAddress now contains the address of the inventory array :)


EDIT:
025FBA0D doesn't seem to be static either BUT the pattern of instructions is (ofcourse, its the program code).
Now I've seen people making "code pattern searchers" to inject something in the right position before, I don't know how to do this yet though.
I'm pretty sure this is perfectly doable, I didn't say it's gonna be easy though :) I'll keep trying ^^


Spot on. Btw, don't use detours, try EasyHook instead :)

RISK

2012-01-25 12:31:35

I am honestly more interested in the ability to create a 'Bot' for an MMO with Simba like other 'Bots' are since it is the language I know most fluently. Not the color based way, but memory reading way or whatever it is that other 'Bots' do.

maigel

2012-01-25 12:36:19

From: superuser
Spot on. Btw, don't use detours, try EasyHook instead :)

I don't really know if it is a detour, I just called it that … :p (I'm still pretty new with all this assembly stuff)
I used CheatEngine's inbuilt AutoAssemble code injection function

putonajonny

2012-01-25 13:21:17

I think you guys should have a look at this:
http://www.youtube.com/watch?v=knkd4J9Doto

nokkasiili

2012-01-25 13:23:58

Some of aimbots and stuff use advanced address finding it could help here.

KingKong

2012-01-25 20:05:26

From: maigel
For those who were talking about it not being possible because the memory changes, the memory does change but here's what I've found out so far:

At adress 025FBA0D theres the machine instruction mov eax,[edx+eax*4+0C].
Now what this does is:
- EDX the base adress of the "iventory stuff array"
- EAX: the inventory slot you want (each inventory item amount takes up 4 bytes, hence the *4)
- 0C: a static offset

Now, I've injected a detour that changes
mov eax,[edx+eax*4+0C]
into
mov [slotAddress], edx
mov eax,[edx+eax*4+0C]

et voila, slotAddress now contains the address of the inventory array :)


EDIT:
025FBA0D doesn't seem to be static either BUT the pattern of instructions is (ofcourse, its the program code).
Now I've seen people making "code pattern searchers" to inject something in the right position before, I don't know how to do this yet though.
I'm pretty sure this is perfectly doable, I didn't say it's gonna be easy though :) I'll keep trying ^^


I think you're trying too hard to map the addresses, try using artmoney, it has the ability to map addresses if you can find one in a list. PM me your msn, im going to see what I can do.

alar82

2012-01-26 07:38:12

Looked little deeper into byte array:

Found inventory id array: (Death runes at first slot)
30 02 00 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
Amount : (11100)
5c 2b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

They are quite close each other.
But constantly switching places in memory. Always in pair with each other only few bytes apart.
As no pointers exsist in java quite cheatproof.
Edit:
2 diffrent memory locations.
Blue for inventory ids.
Red for inv amount.
Green for similar patterns.

chemicstry

2012-01-28 15:06:15

I had written a small program in C++ and I was able to find inventory by patterns so this seems promising.

The question is, does simba support c++ plugins? Or does it have some memory reading functions? This might sound noobish but pascal is really not my cup of tea.

EDIT: It's a bit tricky to find player position as reflection tiles are incorrect (did they change positioning system?).
EDIT2: http://pastebin.com/VMzwv6VT some research on banking

alar82

2012-01-29 02:04:17

Inventori spots will not always be written out as zeros when inventori is empty, only needed spots, rest skipped.
When adding items to inventory memory location will be sifted and additional spots added.
Reading about it in internetz, it said that java has high memory optimizition and has dynamic memory re-location stuff to prevent abuse.

Pascal seems to be limited to basic loops only, at least here in simba forums its only needed for simple scripting.
Those cc language pointer stuffwont work ever, read above, code patterns maybe if you are real fanatic about it.

Edit:
I mean really really really insane about code patterns:p and obsessed.

Supertrent1

2012-01-29 02:21:02

I don't think you can, Reflection broke because Runesacpe updates its addresses every 6 hours randomly. It prob updates these too.

chemicstry

2012-01-29 05:09:22

From: Supertrent1
I don't think you can, Reflection broke because Runesacpe updates its addresses every 6 hours randomly. It prob updates these too.


Yes, this makes it unable to find addresses by offset because they change frequently but we can search by a pattern.

Inventory and bank structure seems similar.

79 00 00 00 E0 18 A6 38 0E 00 00 00
A B C

A - This part is usually a small number (like now) but when it's high it means that address will change shortly
B - Constant value (It didn't change after new client generation but might change on new patch)
C - Inventory item count (If you have item in last inv slot it will be 28 and all other slots will be filled with 0xFFFFFFFF)

The problem is that "E0 18 A6 38" repeats in many memory locations but we could find inventory location like this:
1. Search for "E0 18 A6 38"
2. Check if second 4byte value is less than 28 (max inv count)
3. Loop through item id's
4. Skip 4 bytes (It's the "A" value that is completely random)
5. Check if we have "E0 18 A6 38" here
6. Loop through item stacks

I tried this pattern and it seems to work, the only problem is that runescape leaves some inventory memory unfreed when logging in again (memory leak hehe) and then there are 2 inventory locations of which one of them is real.

KingKong

2012-01-29 06:38:57

From: chemicstry
I had written a small program in C++ and I was able to find inventory by patterns so this seems promising.

The question is, does simba support c++ plugins? Or does it have some memory reading functions? This might sound noobish but pascal is really not my cup of tea.

EDIT: It's a bit tricky to find player position as reflection tiles are incorrect (did they change positioning system?).
EDIT2: http://pastebin.com/VMzwv6VT some research on banking


Yes simba does support c++ plugins, but you have to export them in a certain way. There is a thread about it somewhere.

alar82

2012-01-29 09:03:49

Hm fake inventory.
Maybe I cecked that-.-
Yea when I tried patern search it did find lot places 6 up to 20.
Anyway great work chemicstry!