PDA

View Full Version : Memory reading.



alar82
10-05-2016, 08:08 AM
I have always wanted to read values directly from rs client :). So I started to build a plugin for Simba to do that. After month of trying to understand concepts of programming and stealing code snippets from internets. ITS ready! Thanks everyone on forums who helped.

Join our discord: https://discord.gg/ywSDHbXmF5

To use it:
1)You need rs3 nxt client.
2)Simba 64 bit build. Old:https://github.com/MerlijnWajer/Simba/releases/tag/autobuild-421.
3)Plugin in plugins folder. https://github.com/pp9999/MemReading/releases/tag/0.1
https://i.postimg.cc/BvLzF1yr/arrow.png
4)Install mouse interception. Run as admin file bat. It should report success at console window : 28458
It should take couple of minutes to display debug window if script is ran.
Check Simbas console for progress.
Move manually mouse to start mouse interception and keyboard
RS client and Simba must be at same scaling level.
How to do it:
https://i.postimg.cc/8C9ML2vf/s1.png
https://i.postimg.cc/13YqZkJ7/s2.png
Try system or application, which works for you.
There also small tutorial here:https://villavu.com/forum/showthread.php?t=177695

SRL Resource Library discord, ask stupid questions there.
Uploaded code onto GitHub as private.
Wanto fixit? Ask invite from
discord: test8888#6298


How to use script:

program Test;
{$loadlib MemoryError}

begin
wait(199);
SetupRSReading(True," ",-1, 0);

repeat
wait(100+random(1099));
Writeln('Coordinates: ',GetPCoords());
Writeln('Floor: ',GetPFloorLv());
until(false)
end.


Some description for functions

SetupRSReading(True," ",-1,0);
Start plugin. Parameters: First is for starting graphical debug. Second is player name, it uses AOB to find it after all. Third is PID:
if it is 0 goes by first found.
If it is a number it tries to find client with this PID.
If it is -1, it opens up a list.
4th option is Mouse control method to be used:
0 is Inception driver.
1 is standard windows mouse commands they should be fine to use on remote desktop:https://villavu.com/forum/showthread.php?t=118173
2 don't bother with mouse emulation at all. Sends commands directly to client. For throwaway accounts should be fine.


GetPCoords();
Returns rs local player coordinates as Tpoint.


GetPFloorLv();
Returns rs local player groundplane level, ground 0, first floor 1 and so on.

in source


BOOLEAN FindNPCs1(int* id, int size , int dist, int accuracy, int lifepoint, WPOINT tilespot,int dist2, int action, SimbaString sidetext)


FindNPCs1([41],1,10,0,0,[0,0],0,0,'Attack');
For attacking/clicking npcs.
[41] = npc ids go there.
1 = amount of npc ids in box of [].
10 = how far to look for npcs in tiles. Range sort of.
0 = generate random non accuracy in pixels. For maximum leave at 0
0 = npc lifepoints. Can be left at 0
[0,0] = anchor of short. can be 0
0 = distance in tiles how far should function look from anchor. This part is to stop player clicking too far from anchor and getting lured away.
0 = clicking method. 0 left click, 1 right click, 2 move to npc, 3 do nothing.
'Attack' = Rs3 sidetext thing, works surprisingly well. Don't leave empty!.

More functions:

Use
if (not CheckPAnim(120)) then begin /code/ end; to check if players is animating. Number there is how many times to check vs 25 milliseconds. Some animations have huge caps between them.

Use
if (InveFull()) then begin /code/ end; to check if inventory is full or not.

Use
if (InveItemcount(item1)<3) then begin /code/ end; to count items in inventory, item1 is ID.

Use
if (InveFreecount()<9) then begin /code/ end; to check how many spots are free.

Use
ClickInv(item1,0); to click item in inventory. Warning there is no check if inventory is actually open. So yea some fail safes should be added.

To click decor object, same stuff as npc goes in:

FindDobj([99],1,16,[0,0],[0,0],False,0,'Deposit');

There also special cases where object does not disappear but changes, made some functions to check certain booleans.
FindDobjA1([99],1,16,[0,0],[0,0],False,0,'Excavate');

FindDobjA2([99],1,16,[0,0],[0,0],False,0,'Excavate');
Mainly using them for archaeology resource caches.

To click active objects(portables and such):

FindAobj([99],1,16,[0,0],[0,0],False,0,'Excavate');

Check if inventory is open, returns bool,

CheckInvOpen();
Check if loot window is open

CheckLootW();
Tries to open inventory

OpenInv()
Picks text from right click menu

SelectChooseOption('Trade');
'player' is a name of the player we wanto know about.
Return true if player is interacting with other player or npc. Works for local or other players.

PlayersInterActing('player');
Gets animation id, either local or other.

GetPlayersAnimation('player');
Loops 100 times animation check. If it hits anykind of animation before 100 returns true. Either local or other players.

IsPlayersAnimating('player',100);


There is more, check simbas list on the side to see them all.

Justin
10-05-2016, 10:21 AM
Very interesting.. nice to see some progress with getting data from the NXT client :)

Joopi
10-05-2016, 11:57 AM
Could you provide source for it so I can give you a few pointers (pun intended) on what you can improve, and source should be provided anyhoo also when open source community

KeepBotting
10-05-2016, 12:31 PM
Very nice. Interested in seeing the source as well -- is this plugin Windows-only, or would it be possible to build for Mac/Linux targets as well? I know the method for reading memory differs across systems.

alar82
10-06-2016, 08:54 AM
There isnt much to share, only few lines of code. I discovered that is almost impossible to find any pointers. Inventory is deleted when logged out and recreated in different spot. Obviously that command comes from somewhere and asm debuger on cheat engine shows something. But that asm thing is over my head :(

Hey guys can you make so that srl compiles on 64bit build also.

alar82
11-29-2016, 11:12 AM
Messed around with it:

https://s17.postimg.org/th5qxrjaz/test877.jpg (https://postimg.org/image/th5qxrjaz/)
Low res for ancient computers:
https://s17.postimg.org/cowg4fv9n/test8772.jpg (https://postimg.org/image/cowg4fv9n/)

Objects locations are not quite correct :D
Portal ID thing seems to be in almost right spot, also those vats 80, 83, 84 are off, rest is total mess.

Basically we know player position and object position in tiles. I tried to guess how much 1 tile is in pixels, seems like around 30 pixels. So player location - object location =x, (from game screen centre)x*30 almost got right object location in pixels.

Now with Rs curvature Plz help.

Joopi
11-29-2016, 08:32 PM
Post source already...
Also you will probably need to scan for things such as camera angle, rotation, zoom etc etc. Essentially recreating the W2S calculations the Reflection library uses, unless RS3 has any drastic changes.

alar82
11-30-2016, 06:07 AM
Hi. Had a look this w2s calculation.

X := X - Reflect.Compass.CameraX;
Y := Y - Reflect.Compass.CameraY;
Z := Z - Reflect.Compass.CameraZ;
CurveX := Reflect.Compass.GetYaw;
CurveY := Reflect.Compass.GetPitch;

GetYaw is degrees 0 to 360? So ill put it to 0, max north.
GetPitch is angle, rsbot shows its max is 85. So 85.

X := X - Reflect.Compass.CameraX;
Y := Y - Reflect.Compass.CameraY;
Z := Z - Reflect.Compass.CameraZ;
CurveX := 0;
CurveY := 85;

But what are thos Compass x,y? Are they in pixels? Are they camera center point=? z?
Edit2: It looks like current player position? Maybe? :)
Edit3: Decided to have look myself.



OurTile := Reflect.Tiles.GetGlobalTile;
writeln('Point('+ IntToStr(OurTile.x) + ',' + IntToStr(OurTile.y) +')');
writeln(Reflect.Compass.CameraX);
writeln(Reflect.Compass.CameraY);
writeln(Reflect.Compass.CameraZ);
writeln(Reflect.Compass.GetYaw);
writeln(Reflect.Compass.GetPitch);


Output was on tut island:
Point(3096,3107)
7018
5965
-3023
1942
383
Dno those numbers are crazy. Why is compass 1942 maxses at 2000? Why is pitch 383 instead powerbots 83. What are those numbers x and y they seem to change with camera turning and with player location;

Edit4:Npcs.
https://s27.postimg.org/iiodgr9kz/screen1.jpg
Once npcs array is found it takes milliseconds to read all npcs.
https://s27.postimg.org/3mb02j4xv/screen2.jpg
Coords might be slightly off

alar82
09-21-2017, 04:06 PM
Got bored :D and sauce is secret.
https://s26.postimg.cc/bhl2y67yx/test1.jpg
Mining guild.
https://s26.postimg.cc/80j0v78wp/test2.jpg
Burth.
https://s26.postimg.cc/uiz45f6jd/test3.jpg

Ross
09-22-2017, 09:03 PM
-snip-

This is great, but why post in an open source community if you don't want to share the code? I'd love to expand on it.

klamor
09-22-2017, 09:57 PM
that looks amazeballs... how detectable is your method of injection? using official nxt client?

Joopi
09-23-2017, 08:47 AM
klamor; it literally says in the title that it is Memory reading, thus it is not injection.

Also alar82 don't expect help if you don't provide source in an open source community, but it does look amazeballs.

Kasi
09-23-2017, 11:50 AM
klamor; it literally says in the title that it is Memory reading, thus it is not injection.

Also alar82 don't expect help if you don't provide source in an open source community, but it does look amazeballs.

? maybe he's assuming dll injection. Java injection isn't the only type of injection.

Joopi
09-23-2017, 12:25 PM
I have a memory of some threads that this guy made where I tried to explain everything to him how you memory read with simba and how pointers works etc etc
But sure that isn't given in this thread so it was wrong of me to berate him

Besides, who mentioned anything about java?
I dont understand why anyone would go through the troubles of memory reading if they have already modified the client

Kasi
09-23-2017, 01:41 PM
I have a memory of some threads that this guy made where I tried to explain everything to him how you memory read with simba and how pointers works etc etc
But sure that isn't given in this thread so it was wrong of me to berate him

Besides, who mentioned anything about java?
I dont understand why anyone would go through the troubles of memory reading if they have already modified the client

You said memory reading thus it is not injection (i assumed you were thinking about java because you said this). You can have memory reading with injection. Also, mention or quote, so i can reply faster.

Also, it's pretty impossible to raw memory-read a JVM. (I'm assuming that's what you mean by modified client)

alar82
09-23-2017, 02:09 PM
It uses AOB scan to locate resources, then just reads them. It shouldn't be any more detectable than screen color readers. As nothing is modified or injected to NXT client. No write rights to aplication are ever requested/changed. Detectability is zero as I botted a lot during double xp. Only way to jagex to catch it is by looking trough running processes and tag suspicious ones. Like wow warden anticheat or punkbuster. Jagex doesn't have anything like that :I

Joopi
09-23-2017, 02:50 PM
This is frikkin NXT there's no JVM Kasi;
And by modified client I mean the client is modified, has injected code in it (and since it's NXT, it is at least currently fairly easy to solely rely on Memory Reading). Still nothing to do with Java since this is NXT.

Joopi
09-23-2017, 02:55 PM
doesn't have anything like that :I
Not yet at least. Soon they'll start whisking around the memory locations just like the JVM on Java based clients does, and then it'll be hectic. And sure they can start detecting it with a VAC-like approach where they hook all the virtualQueryEx stuff (yes i dont know the specifics) and just record every process that request stuff from it.

klamor
09-23-2017, 07:25 PM
klamor; it literally says in the title that it is Memory reading, thus it is not injection.

Also alar82 don't expect help if you don't provide source in an open source community, but it does look amazeballs.

sorry, i'm a noob. I thought memory reading was injection... still learning :P

Brandon
09-23-2017, 08:42 PM
It uses AOB scan to locate resources, then just reads them. It shouldn't be any more detectable than screen color readers. As nothing is modified or injected to NXT client. No write rights to aplication are ever requested/changed. Detectability is zero as I botted a lot during double xp. Only way to jagex to catch it is by looking trough running processes and tag suspicious ones. Like wow warden anticheat or punkbuster. Jagex doesn't have anything like that :I



Just so ppl understand, AOB Scan = Array of Bytes Scan.. and he is using ReadProcessMemory or PTrace for that.

Kasi
09-23-2017, 10:14 PM
This is frikkin NXT there's no JVM Kasi;

I know, but why did you say this though...


klamor; it literally says in the title that it is Memory reading, thus it is not injection.

You can use injection and memory reading together though. You said it as if using one means it's not using the other. I assumed you meant java because of this. Sorry if i judged you by your scrubby SRL Jr Mem status.



I dont understand why anyone would go through the troubles of memory reading if they have already modified the client

ALOT of people do this. They inject and memory map DLLs and manually construct the headers/imports so that it doesn't show up on the PEB. (also look into reflective dll injection). Waay easier to hide a dll than to hide a process. Some games don't even allow you to run some programs like cheat engine whilst you're playing them (VAC).


Not yet at least. Soon they'll start whisking around the memory locations just like the JVM on Java based clients does, and then it'll be hectic. And sure they can start detecting it with a VAC-like approach where they hook all the virtualQueryEx stuff (yes i dont know the specifics) and just record every process that request stuff from it.

Huh, how do they hook VirtualQueryEx when he's operating in a different address space (not Injecting)? Without injecting and hooking VirtualQueryEx in every single process. It's impossible. VirtualQueryEx exists in kernel32 and is loaded by every process. Each process has it's own VirtualQueryEx. Hooking your own VirtualQueryEx has 0 effect on code executing in a different process / memory space since they don't call the one you hooked.

Also do you normally casually double-post?

Joopi
09-24-2017, 09:20 AM
I know, but why did you say this though...

Contradicts


Also, it's pretty impossible to raw memory-read a JVM. (I'm assuming that's what you mean by modified client)


But that's irrelevant so anyhoo.


Sorry if i judged you by your scrubby SRL Jr Mem status.

Just like you judged me based off my forums status, I judged Klamor based on his word choosing, "How detectable...", either it is, or it is not detectable, not really any middle ground. So what it really came down to is Klamor being lazy or simply did not understand how OP was doing this, and asked a typical question (How detectable is X) which just triggers many folks. You, in your whiteknight endeavours start getting technical and making fairly ambiguous statements not even knowing what game this is about, when all it really is about is OP's unambiguous concept and putting it to the test.

So before you go all "don't unfold in a thread that you don't even remotely know the technical details about", what it really is about is 2 foreign concepts that could be intertwined, but in this case aren't because this is pleb stuff, attracting pleb people, asking plebby questions.




Huh, how do they hook VirtualQueryEx... As I said I don't know the specifics, but what I meant was that OP shouldn't be naive to think that this will work for the rest of his days. Again, no point in splitting semantic hairs when the original question was as simple and uninformed as the next person.


Also do you normally casually double-post?
Only sometimes

Kasi
09-24-2017, 11:01 AM
Joopi;

Not sure what you mean by "Contradicts". Don't understand the context you used it in.

You said that is not injection because it is memory scanning which is straight up incorrect, you CAN use them both together. My thought process was what other type of injection could you possible be thinking of (This is the reason i brought up java injection - Pretty valid assumption regardless of the game, especially valid assumption since you seem to think injection and memory scanning shouldn't go hand in hand). If you read the brackets, i even said - (i'm assuming that's what you mean by modified client). Try reading posts in chronological order. In future - memory scanning and Injection can go hand in hand, and generally DO go hand in hand, but as OP said, he has no need to ATM.

Wasn't really judgement on your forum status, just a joke that you clearly overshot and misunderstood. What i am actually doing is pointing out some invalid information on a public forum, fair play if you wanna call it white knighting, I won't stop you, just one more incorrect thing you do.

I very much doubt this is "plebby". Personally, i prefer people asking questions that they don't know the answer to, than people answering questions to which they don't know the answer to.

Sure, the poster of the original question was mis-informed. But so are you, so don't answer questions you don't know the answer to or aren't informed well enough in :)

tldr; I made an incorrect assumption in order to understand what the fuck you were talking about. You were straight up wrong and spent a couple posts deflecting.

Anyhow, This will be my last post on this matter. I think it's been stretched far enough for "it is Memory reading, thus it is not injection.". Feel free to post some more incorrect shit that i might/might not post on.

Joopi
09-24-2017, 11:54 AM
Kasi;
Again. The question was pretty simple and straight forward, he was misinformed and I pointed him in the right direction. Despite the answer being missinformative, just like a lot of things you said, it got the point across and corrected him. Everything else is a cope and semantic hair splitting. I understand now that people use different approaches for cheating and combine them, but given the circumstances this was not the case, which I was aware of.

But just to make it clear, the problem wasn't with person asking the question, it was that he didn't even know what the topic was to begin with.


especially valid assumption since you seem to think injection and memory scanning shouldn't go hand in hand)
if we'd talk about java based bots, where injection and reflection(compare memory scanning) are used, I would not think this. but since it is NXT I do think that they shouldn't go hand in hand. So a lot of the stuff that you say is based on a false assumption that you further motivate by that false assumption itself.

Kasi
09-24-2017, 01:10 PM
Joopi; Solid deflecting. Not really sure how to get through to you. I know i said i wouldn't reply but you came up with some more stupid shit, i was just gonna PM but meh:

Firstly, He didn't know what the topic was to begin with, true. But you didn't help by telling him some incorrect info. He probably thinks that Memory Scanning and Injection shouldn't be used together now. Nice one. Whatever, i'll drop that now...

Mainly, why do you think Injection shouldn't be coupled with memory scanning? I know it's not needed but it adds a lot of benefits whilst reading memory. IE, not having to call ReadProcessMemory. Any rookie knows the overheads but i'll explain some just to appease you. You have to copy massive arrays/data unnecessarily, You can't do pointer math efficiently because of the overhead of ReadProcessMemory/VirtualQuery. Finally, the biggest point, All this shit is done cross-process so it's slow as fuck.

You wanna access a single model? that probably 6 different arrays (3 vert, 3 ind). You pass a pointer and a size to ReadProcessMemory, it'll copy the entire array back into your address space taking up 2x the data; a copy remotely, and one locally. You do this 6 times. Guess what? Works the same for every other struct. You have to make a copy of the entire block of data. You can do whatever math you want AFTER you've copied the entire data structure/array. Not to mention all this is Paged. Lets just say you're stupid enough to still think Injection is worthless with NXT. Please tell me why it is worthless? NXT doesn't detect injection AFAIK so go ahead, entertain me.

the bank
09-24-2017, 10:20 PM
Just wanted to stop in to say - of course memory reading can be detected. The most obvious way would be for them to hook/watch NtOpenProcess.

That's all. #TheBank2017 (https://villavu.com/forum/usertag.php?do=list&action=hash&hash=TheBank2017)

BotEngines
09-30-2017, 09:01 AM
It uses AOB scan to locate resources, then just reads them. It shouldn't be any more detectable than screen color readers. As nothing is modified or injected to NXT client. No write rights to aplication are ever requested/changed. Detectability is zero as I botted a lot during double xp. Only way to jagex to catch it is by looking trough running processes and tag suspicious ones. Like wow warden anticheat or punkbuster. Jagex doesn't have anything like that :I

There are ways around that too..
If Jagex ever builds a comprehensive "Anti Cheat" system.

You could run NXT on an OS inside a Hypervisor, and run your Memory reading engine Outside on the host OS. And send emulated mouse & keyboard events to the VM. No way in hell they could ever detect you then... Though it would be quite a lot more complex. Need to understand Extended Page Tables in depth.

I'm planning to try a prototype this against the "Big Guns" at Valve VAC.

the bank
09-30-2017, 01:02 PM
And send emulated mouse & keyboard events to the VM. No way in hell they could ever detect you

Issue #1 (https://villavu.com/forum/usertag.php?do=list&action=hash&hash=1) : emulated video card
Issue #2 (https://villavu.com/forum/usertag.php?do=list&action=hash&hash=2) : detection of the VMkernel with a hypervisor approach.
Issue #3 (https://villavu.com/forum/usertag.php?do=list&action=hash&hash=3) : https://villavu.com/forum/showthread.php?t=115467


But I do like where you're headed. Just needs some refinement. If they are looking for you they will find you no matter what you do. That's why it's a constant game of cat & mouse.

Citrus
09-30-2017, 01:57 PM
Issue #3 (https://villavu.com/forum/usertag.php?do=list&action=hash&hash=3) : https://villavu.com/forum/showthread.php?t=115467

The guest OS sees all input from the host as hardware input. At least that's what I found in my brief tests with Brandon's little fake input test in that thread.

CynicRus
09-30-2017, 10:39 PM
Also, for the mouse or keyboard emutalion a directinput hook can be used.

the bank
10-01-2017, 12:17 AM
Also, for the mouse or keyboard emutalion a directinput hook can be used.

Which they could (hypothetically) detect by iterating handle signatures looking for a start address in the range of, say, dinput8.dll. Therefore detecting that there's a directinput hook in the application being scanned. This can be done in user mode.

Kasi
10-01-2017, 01:19 AM
The guest OS sees all input from the host as hardware input. At least that's what I found in my brief tests with Brandon's little fake input test in that thread.

I also noticed the same on VMWare. However, it really depends on the drivers being used.

Detecting the VM is probably the biggest issue here imo. Its pretty hard to hide the fact that you're using a VM. If they're gonna go through the effort of scanning other processes/memory, they might as well just throw in VM detection.

slacky
10-01-2017, 02:40 AM
Detecting the VM is probably the biggest issue here imo.
But why is that an issue? :confused:
I feel it's like detecting that you are in fact using a PC to play RS in the sense that it doesn't really relate to whether you are botting or not, not sure how strong such a correlation would be.

The poker bots that has been around have always been using a VM to run the client, and the bot on the physical machine. I am not sure if this has changed the past 5 years since when I was looking into it. And these bots fight against pretty good anti-cheating measures.

BotEngines
10-01-2017, 02:50 AM
Issue #1 : emulated video card
Issue #2 : detection of the VMkernel with a hypervisor approach.
Issue #3 : ...


But I do like where you're headed. Just needs some refinement. If they are looking for you they will find you no matter what you do. That's why it's a constant game of cat & mouse.

I Don't mean to derail this post. I'm Fascinated by Alar82's Memory reading techniques! :-)

1. PCI passthrough your Graphics Hardware. I'm currently using it!

2. KVM has a feature called hidden state='on' Which removes virtualization "signatures". Fool guest into thinking it's running native hardware. Xen has even better isolation. People currently do this to get around Nvidia's detection (its against TOS). It's the only way you can install Nvidia's driver. Nvidia Want you to shell out $1000s for Tesla Workstation graphics. A real Anti-Cheat would probably detect you using DMI (firmware) information. But that could be emulated too!

It's also Wise to enable all processor extensions and "nested" virtualization, so CPU appears native.

3. Loved that thread & code! Looking forward to trying it! On a regular Native OS.

I think the Cat & mouse game is quite exciting! Last I checked something like 40% of all Pro eSport Gamers Cheat. ;-) Not that I care about that realm.

Kasi
10-01-2017, 03:06 AM
But why is that an issue? :confused:
I feel it's like detecting that you are in fact using a PC to play RS in the sense that it doesn't really relate to whether you are botting or not, not sure how strong such a correlation would be.

Do you normally play rs or cs:go through a vm? Why the fuck would anyone bottleneck like that unless the game straight up didn't natively support that OS? Even in that sense. There are ways to detect the underlying OS if not baremetal and check if the game supports it.

I personally don't know anyone that plays games legit on a VM.

Can't speak for poker bots, haven't really looked into them.

slacky
10-01-2017, 03:17 AM
Do you normally play rs or cs:go through a vm? Why the fuck would anyone bottleneck like that unless the game straight up didn't natively support that OS? Even in that sense. There are ways to detect the underlying OS if not baremetal and check if the game supports it.

I personally don't know anyone that plays games legit on a VM.

Can't speak for poker bots, haven't really looked into them.
The year I was using Linux as my OS, I used a Windows VM alongside it for a lot of stuff (mainly due to photoshop and such tools I could only get on Windows), but then if I had the VM open already I could jump into RS every now and then, and even some CS 1.6 [CS had no native support for Linux at that time].

But just asking me is pointless, I am/was one in a very large playerbase, only jagex, assuming they gather such data have such statistics, and know how it correlates to botting, now I am not saying it's common to use a VM, but there needs to be a solid correlation for it to be worth extra effort needed to figure out if you bot or not, which I am not sure if solely basing of if you use a VM is, or will be enough or not.

But I am gonna get out of this thread, not really interesting for me. Just wanted to point this out.

CynicRus
10-01-2017, 07:50 AM
Which they could (hypothetically) detect by iterating handle signatures looking for a start address in the range of, say, dinput8.dll. Therefore detecting that there's a directinput hook in the application being scanned. This can be done in user mode.

Sure. If you need the kernel mode emulation, you should use somethin like this: https://github.com/djpnewton/vmulti.

Brandon
10-01-2017, 01:28 PM
It's actually way easier to detect than anything mentioned above..

Scenario: Process A opens Process B in order to get a "HANDLE" to pass to ReadProcessMemory. To detect this, all we need to do is enumerate global list of handles.


1. Process-B will do: NtQuerySystemInformation with SYSTEM_HANDLE_TABLE_ENTRY_INFO.
2. Process-B will Duplicate each handle into itself.
3. Check if that process handle is its own.
4. If step-3 is true, get handle owner (Process-A) and scan it for RPM or hook RPM in that process (hook is nice because you can check if it is reading your process directly).
5. Take measures such as banning or blah..


With decent knowledge of WinAPI, almost anyone can do this and can find other ways too. Note: You don't even need to check handles.. Can do other checks too.


#define DUPLICATE_SAME_ATTRIBUTES 0x00000004
#define STATUS_INFO_LENGTH_MISMATCH 0xC0000004
#define STATUS_BUFFER_OVERFLOW 0x80000005

auto size = sizeof(SYSTEM_HANDLE_INFORMATION);
std::unique_ptr<std::byte> info(new std::byte[size]);
while (NtQuerySystemInformation(SystemHandleInformation, info.get(), size, &size) == STATUS_INFO_LENGTH_MISMATCH)
{
info.reset(new std::byte[size]); //awful.. but I know no other way..
}

SYSTEM_HANDLE_INFORMATION* shi = reinterpret_cast<SYSTEM_HANDLE_INFORMATION*>(info.get());

for (auto i = 0; i < shi->Count; ++i)
{
SYSTEM_HANDLE_ENTRY& sh = shi->Handle[i];

//Multiple options here.. Map the process and check what it does.. OR open it and check for RPM..
HANDLE hObj = nullptr;
HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, sh.OwnerPid);

if (hProcess)
{
if (DuplicateHandle(hProcess, reinterpret_cast<HANDLE>(sh.HandleValue), GetCurrentProcess(), &hObj, STANDARD_RIGHTS_REQUIRED, FALSE, DUPLICATE_SAME_ACCESS))
{
//Scan for RPM or Hook RPM.. if it is reading us and reading structures it shouldn't be reading.. handle it.
CloseHandle(hObj);
}

CloseHandle(hProcess);
}
}


I guess you can use it for garbage and memory leak monitoring too..

P.S. This is how VAC does it as well. But anyway, let's not derail further with "what-ifs".

alar82
10-08-2017, 02:00 AM
For mouse movements I use currently winapi stuff. There is alot of messages send to app if you look with spy++. But I could write directly into client mouse position, so windows mouse wouldn't be needed at all. Any issues with that?

alar82
01-20-2018, 11:31 AM
It's difficult to locate right click menu options. Any help would be nice. With cheat engine preferably.
Here is some progress:
https://s17.postimg.cc/yzdk0tcnf/int2.jpg (https://postimg.cc/image/yzdk0tcnf/)
It's total mess but some accurate data can be extracted from there, like inventory pixel perfect location every time.

Kompromaus
01-24-2018, 10:54 AM
How do you personally go about finding the vtable pointers (I assume that's what you use) after each update?

I wrote a program, Ulyaoth (C#), to match patterns, then I found reliable patterns:



using System;
using System.Collections.Generic;

using Gee.External.Capstone.X86;
using IniParser;
using IniParser.Model.Configuration;
using PeNet;
using PeNet.Structures;
using Gee.External.Capstone;

namespace Ulyaoth
{
class Pattern
{
List<int> m_pattern = new List<int>();
int m_offset;

public int InstructionOffset => m_offset;

public Pattern(string mask_pattern, int offset)
{
for (int i = 0; i + 1 < mask_pattern.Length; i += 2)
{
if (mask_pattern[i] == '.' && mask_pattern[i + 1] == '.')
{
m_pattern.Add(-1);
}
else
{
int value;
if (Int32.TryParse(
mask_pattern.Substring(i, 2),
System.Globalization.NumberStyles.HexNumber,
System.Globalization.CultureInfo.InvariantCulture,
out value))
{
m_pattern.Add(value);
}
}
}

m_offset = offset;
}

public bool TryMatch(byte[] data, int data_offset, out int result)
{
for (int i = 0; i + data_offset + m_pattern.Count < data.Length; ++i)
{
bool match = true;
for (int j = 0; j < m_pattern.Count; ++j)
{
if (!(data[data_offset + i + j] == m_pattern[j] || m_pattern[j] < 0))
{
match = false;
break;
}
else
{
match = true;
}
}

if (match)
{
result = i + m_offset;
return true;
}
}

result = 0;
return false;
}
}

class Program
{
static int Main(string[] arguments)
{
if (arguments.Length < 2)
{
Console.Error.WriteLine("ulyaoth <pattern> <executable>");
return 1;
}

Dictionary<string, Pattern> patterns = new Dictionary<string, Pattern>();
Dictionary<string, int> adjustments = new Dictionary<string, int>();
{
var parser = new FileIniDataParser();
var definitions = parser.ReadFile(arguments[0]);

foreach (var definition in definitions.Sections)
{
var mask_pattern = definition.Keys["signature"];
int offset;
if (Int32.TryParse(
definition.Keys["offset"].Substring(2),
System.Globalization.NumberStyles.HexNumber,
System.Globalization.CultureInfo.InvariantCulture,
out offset))
{
patterns.Add(definition.SectionName, new Pattern(mask_pattern, offset));
}


if (definition.Keys.ContainsKey("adjust"))
{
var adjustValue = definition.Keys["adjust"];
int adjust;
if (Int32.TryParse(adjustValue, out adjust))
{
adjustments.Add(definition.SectionName, adjust);
}
else
{
adjustments.Add(definition.SectionName, 0);
}
}
else
{
adjustments.Add(definition.SectionName, 0);
}
}
}

var data = System.IO.File.ReadAllBytes(arguments[1]);
var executable = new PeFile(data);
IMAGE_SECTION_HEADER text = null;
foreach (var section in executable.ImageSectionHeaders)
{
var name = System.Text.Encoding.UTF8.GetString(section.Name). Trim('\0');
if (name == ".text")
{
text = section;
}
}

if (text == null)
{
Console.Error.WriteLine("No .text section in executable.");
return 1;
}

foreach (var pattern in patterns)
{
int offset;
if (!pattern.Value.TryMatch(data, (int)text.PointerToRawData, out offset))
{
Console.Error.WriteLine("Failed to match pattern {0}.", pattern.Key);
Console.Error.WriteLine();
}
else
{
Console.WriteLine("Matched pattern {0} (+{1:X}).", pattern.Key, offset + text.VirtualAddress);

int otherMatch = 0;
if (pattern.Value.TryMatch(data, (int)text.PointerToRawData + offset + 1, out otherMatch))
{
Console.WriteLine("(Ambigious match.)");
}

using (var disassembler = CapstoneDisassembler.CreateX86Disassembler(Disasse mbleMode.Bit64))
{
disassembler.EnableDetails = true;
disassembler.Syntax = DisassembleSyntaxOptionValue.Intel;
var instructions = disassembler.DisassembleStream(data, offset + (int)text.PointerToRawData, text.VirtualAddress);

foreach (var instruction in instructions)
{
Console.WriteLine("{0:X}: \t {1} \t {2}", instruction.Address, instruction.Mnemonic, instruction.Operand);
Console.WriteLine("\t Id = {0}", instruction.Id);
foreach (var operand in instruction.ArchitectureDetail.Operands)
{
string operandValue = null;
switch (operand.Type)
{
case X86InstructionOperandType.FloatingPoint:
operandValue = operand.FloatingPointValue.Value.ToString("X");
break;
case X86InstructionOperandType.Immediate:
operandValue = operand.ImmediateValue.Value.ToString("X");
break;
case X86InstructionOperandType.Memory:
operandValue = "-->";
break;
case X86InstructionOperandType.Register:
operandValue = operand.RegisterValue.Value.ToString();
break;
}

Console.WriteLine("\t\t {0} = {1}", operand.Type, operandValue);

// Handle Memory Operand.
//
// ...
if (operand.Type == X86InstructionOperandType.Memory)
{
Console.WriteLine("\t\t\t Base Register = {0} ", operand.MemoryValue.BaseRegister);
Console.WriteLine("\t\t\t Displacement = {0:X} ", operand.MemoryValue.Displacement + offset + (int)text.PointerToRawData + instruction.Bytes.Length + 0xC00 + adjustments[pattern.Key]);
Console.WriteLine("\t\t\t Index Register = {0}", operand.MemoryValue.IndexRegister);
Console.WriteLine("\t\t\t Index Register Scale = {0}", operand.MemoryValue.IndexRegisterScale);
Console.WriteLine("\t\t\t Segment Register = {0}", operand.MemoryValue.SegmentRegister);
}
Console.WriteLine();
}

break;
}
}
}
}

return 0;
}
}
}


I can't post my offsets.ini publicly since it contains copyrighted Jagex binary code from the client. Feel free to PM me.

To find the offsets, I first found the target offset (e.g., vtable pointers) via Cheat Engine and did an xref to in IDA. From there, I used Radare2 to manually add the method and create the signature:



af+ <hex offset to method from IDA> <name of function> f
afb+ <name of function> 0 <size of function from IDA>
zaf <name of function>
z


The format of the INI is like so:



[entry_name]
; machine code (hexadecimal doublets) with .. as a masking character
signature = XX......XXXX
; offset of op-code giving displacement (i.e., offset to value)
offset = 0x0
; adjust (optional): value to add to displacement
adjust = 0


My current offsets.ini works from mid-November to now, and most entries work all the way up to the update back the week of September 11 2017.

The value of "Displacement" gives you of the offset from the base of the executable.

Here's my research into the data structures:


# terms
world units: 512x multiple of tile coordinates, usually floating point
tile units: aka in-game tile

## types
float: 4-byte single-precision floating point number
short: 2-byte integer
int: 4-byte integer
pointer: 8-byte (native word) pointer to object
string: EA STL string type

# table [npc_table, object_table, player_table]
- pool of used/unused objects
- NPC/object/players all have tables (*_table in offsets.ini)
+0x0000: pointer to pool
+0x????: pointer to array of indices for used entities
+0x????: pointer to array of indices for unused entities
+0x????: number of entities currently used (+0x0008?)

# item table ([global_item_table])
0x0000: pointer to item list
0x0008: list count, int
0x000C: list capacity (?)

# item table entry, not virtual
- size: ? (didn't write it down)
+0x0020: item ID, int
+0x0024: quantity, int
+0x0090: X (world units), float
+0x0094: Y (world units), float
+0x0098: Z (world units), float

# NPC table entry, virtual [npc_vtable]
- size: 0x2000 bytes
0x0128: name, string
0x035c: X (world units), float
0x0360: Y (world units), float
0x0364: Z (world units), float
0x05a7: animation ID (short)
0x0ff0: NPC ID #1 (sometimes different), int
0x0ff0: NPC ID #2 (always correct), int
0x1028: current health, int (? seems too high, maybe wrong)

# Player table entry, virtual
- size: 0x2000 bytes (?)
0x0128: name, string
0x035c: X (world units), float
0x0360: Y (world units), float
0x0364: Z (world units), float
0x05a7: animation ID (short)
0x1028: current health, int (? seems too high, maybe wrong)

# Object table entry, virtual [object_vtable]
- size: 0x298 bytes long
+0x0134: X (tile units), int
+0x0138: Z (tile units), int
+0x013c: Y (world units), int
+0x0100: pointer to structure
+0x0020: object ID (valid for static objects, maybe dynamic)
+0x0178: object ID (only valid for dynamic [?] objects)

# heap [heap]
- size: 0x130 bytes
- there's a size field and reserved field somewhere, didn't write it down
+0x0000: pointer to arena
+0x0044: pointer to free stack head
+0x0048: pointer to free stack tail

I never began reverse engineering the client since I moved on to other things and stopped playing RuneScape. A good starting point would be the functions that instantiate the aforementioned objects and methods in the vtable.

alar82
01-24-2018, 12:36 PM
That's superb coding skills you have there. Hm as I understand you use PeNet library to get sections executable of something erm. Then something-something of disassemble it with Capstone library,..Er.
My thing is much much simple, find pattern, read whats there, although it's limited.
I wonder did you make something useful with it. Bot program of sorts or send data to simba.

It's quite stable now:
Inventory: https://s17.postimg.CC/v4zw9txpr/inv.jpg
MiniMap: https://s17.postimg.CC/p427cw8kf/min.jpg
Main issue is that there isn't much of a point to bot rs3. Its just too easy.

alar82
04-13-2018, 01:44 PM
Hey guys even if I wanted to put my source up. It needs 2 additional libraries to work, but those are probably copyrighted. Blackbone for memory searching and imgui for debug. Can I zip whole stuff and upload?
https://github.com/DarthTon/Blackbone
https://github.com/ocornut/imgui

Clarity
04-14-2018, 09:44 AM
Hey guys even if I wanted to put my source up. It needs 2 additional libraries to work, but those are probably copyrighted. Blackbone for memory searching and imgui for debug. Can I zip whole stuff and upload?
https://github.com/DarthTon/Blackbone
https://github.com/ocornut/imgui

You can attach a .ZIP to a post, yeah. Looking forward to it, nice screenshots!

alar82
04-14-2018, 03:01 PM
Err forum upload limit is 100kb so mediafire it is.
Source:
It needs visual studio 2015 and windows sdk.
https://github.com/pp9999/MemoryError/tree/master
As source is kinda messy:
https://github.com/pp9999/MemoryError/releases

We can setup github if srl community is interested and fix the code.

Usage for nubs: Put MemoryError.dll into simbas plugins folder, you need simba 64 bit build and rs NXT client not old java.
Simba 64 bit build here:http://l0.lt/builders/master either Simba.x86_64-win64 7z or exe.
Script for RS3 festival area, super boring and 1 click activity.
28416
program Test;
//{$I srl-6/SRL.simba}
{$loadlib MemoryError}
var
Count:Int32;

begin
wait(random(199));
SetupRSReading(True,True);
repeat
wait(240+random(6500));
if (CheckPAnim3) then begin wait(100+random(11500)) end else
begin
Count:=Count+1;
if FindAobj([106662],1,20,0,0,0) then
begin
wait(2410+random(6500));
end;
end;
until(Count>1999)
end.

Log into your throwaway account and run the script.
It should take a minute max to find all needed addresses.
If debug has appeared there are some keys to see if it works correctly:
f1 = ground items
f2 = other players
f6 = inventory
f7 = active objects debug, above script uses this.
f8 = all objects debug
f9 = decor objects
f10 = npcs
With shift key they will be on minimap, no rotation however.
f11 = interfaces mess
f12 = hide always on debug
Page up = imps on minimap
shift+ctrl+f4 = varpbits

https://s18.postimg.cc/mncyiro0l/Untitled.jpg (https://postimg.cc/image/mncyiro0l/)

alar82
04-14-2018, 04:20 PM
FindAobj([106662],1,20,0,0,0)
Variables order is:
1st ids separated by commas([106662,1,2,3])
2nd how many ids(1 if 1 in [ ])
3rd range in tiles how far look for (20)
4th and 5th click adjustments in pixels
6th is how to click: 0 left click,1 right click,2 move to,3 return true and do nothing.

Joopi
04-14-2018, 09:41 PM
Good work alar82;
I'm curious about OffSets.h
Are these offsets not changed whenever an update changes anything concerning entities. Like for example if they add another attribute to an object, would this not mean that some of these pointer offsets get moved slightly or are they always added to the end? Alternatively does this page update whenever you run your "updater"?

alar82
04-15-2018, 05:24 AM
Good work alar82;
I'm curious about OffSets.h
Are these offsets not changed whenever an update changes anything concerning entities. Like for example if they add another attribute to an object, would this not mean that some of these pointer offsets get moved slightly or are they always added to the end? Alternatively does this page update whenever you run your "updater"?

I think offsets will change when game engine is modified, so far once per half a year. Adding new attribute to ncps would broke it too me thinks and I have to manually re-find them. No updater, only cheat engine.

Kompromaus
04-25-2018, 03:05 AM
I'm trying to understand your code. To find things of interest (e.g., NPCs), you:

1) Search the entire address space of the RuneScape process for a specific pattern.
2) When the pattern is matched, you extract relevant data and resume searching the address space from that point forward.

Is that right?

There is a better way of doing that. There is a table of NPCs stored at 0x6E3018. How the game keeps track of which NPCs are valid or not I don't know, but valid NPCs have a vtable pointer set to 0x52D370. (These values are relative to the base address of the process and thus change due to ASLR; they also change every update, but with the pattern matching tool I posted earlier, given the right pattern, the correct offsets can be regenerated without trouble after each update).

Thus, I am able to iterate over the NPCs without much of a performance penalty using ReadProcessMemory:


NPC 458 ('Father Urhney'):
- location: 3209, 869, 3149
- animation: 65535
NPC 12348 ('Giant rat'):
- location: 3218, 555, 3198
- animation: 65535
NPC 16898 ('Ysondria'):
- location: 3220, 325, 3183
- animation: 65535
NPC 8828 ('Giant rat'):
- location: 3225, 194, 3190
- animation: 65535
NPC 8828 ('Giant rat'):
- location: 3238, 799, 3171
- animation: 65535
NPC 8829 ('Giant rat'):
- location: 3230, 234, 3182
- animation: 65535

The same goes for players, objects, and ground items. I've yet to find where the root GUI node/widget(s) are stored, but the heirarchy can be generate from any widget downwards. (I don't think the parent widget is stored).

Here's a program you can run to see for yourself:


using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace Meeseek
{
class Program
{
static readonly IntPtr NPC_TABLE = new IntPtr(0x6E3018);
static readonly IntPtr NPC_VTABLE = new IntPtr(0x52D370);

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
[Out] byte[] lpBuffer,
int dwSize,
out IntPtr lpNumberOfBytesRead);

static int Main(string[] args)
{
Console.WriteLine("Enter PID:");
int pid = Int32.Parse(Console.ReadLine());
var process = Process.GetProcessById(pid);
var executable = process.Modules[0];
var npcTableAddress = new IntPtr(executable.BaseAddress.ToInt64() + NPC_TABLE.ToInt64());
var npcVTableAddress = new IntPtr(executable.BaseAddress.ToInt64() + NPC_VTABLE.ToInt64());

IntPtr numBytesRead;
IntPtr npcTablePointer;
{
byte[] buffer = new byte[8];
ReadProcessMemory(process.Handle, npcTableAddress, buffer, 8, out numBytesRead);
if (numBytesRead.ToInt64() < 8)
{
Console.WriteLine("Woops, didn't read enough bytes (NPC table pointer)!");
return 1;
}

npcTablePointer = new IntPtr(BitConverter.ToInt64(buffer, 0) + 0x20);
}

byte[] npcBuffer = new byte[0x10f0];
for (int i = 0; i < 255; ++i)
{
IntPtr npcPointer = new IntPtr(npcTablePointer.ToInt64() + i * npcBuffer.Length);
if (!ReadProcessMemory(process.Handle, npcPointer, npcBuffer, npcBuffer.Length, out numBytesRead))
{
Console.WriteLine("Woops, didn't read enough bytes (NPC {0})!", i);
return 1;
}

// EASTL string but most NPC names are short enough
IntPtr vtable = new IntPtr(BitConverter.ToInt64(npcBuffer, 0));
if (vtable != npcVTableAddress)
{
continue;
}

string name = "";
for (int j = 0; j < 0x20; ++j)
{
if (npcBuffer[j + 0x128] == 0)
{
break;
}
name += Char.ConvertFromUtf32(npcBuffer[j + 0x128]);
}

int x = (int)(BitConverter.ToSingle(npcBuffer, 0x35c) / 512);
int y = (int)(BitConverter.ToSingle(npcBuffer, 0x360));
int z = (int)(BitConverter.ToSingle(npcBuffer, 0x364) / 512);
ushort animation = BitConverter.ToUInt16(npcBuffer, 0xd48);
int id = BitConverter.ToInt32(npcBuffer, 0xff4);

Console.WriteLine("NPC {0} ('{1}'):", id, name);
Console.WriteLine("- location: {0}, {1}, {2}", x, y, z);
Console.WriteLine("- animation: {0}", animation);
}

return 0;
}
}
}

Enter the PID of the RuneScape 2 NXT client (64-bit only) before the next update. You must be logged in to a world (otherwise it'll try and deference a null pointer and everything fails). It's not very pretty but it was just a proof of concept.

alar82
04-25-2018, 07:55 PM
Did you know that different nxt executable is loaded based on your operating system windows 7 vs 10.
However I see you take exe modulebase and add NPC_TABLE.
Using that info I came up with these numbers: RS base:13f830000+6E3018=13FF13018
Points to:
28440
Erm is it right spot?
Looks like random bytes=)
Edit: compiled your program, it gives error "Woops, didn't read enough bytes (NPC {0})!"
Changed bit a code to wait so i could see errors.


using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

namespace Meeseek
{
class Program
{
static readonly IntPtr NPC_TABLE = new IntPtr(0x6E3018);
static readonly IntPtr NPC_VTABLE = new IntPtr(0x52D370);

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
[Out] byte[] lpBuffer,
int dwSize,
out IntPtr lpNumberOfBytesRead);

static int Main(string[] args)
{
Console.WriteLine("Enter PID:");
int pid = Int32.Parse(Console.ReadLine());
var process = Process.GetProcessById(pid);
var executable = process.Modules[0];
var npcTableAddress = new IntPtr(executable.BaseAddress.ToInt64() + NPC_TABLE.ToInt64());
Console.WriteLine("npcTableAddress:"+npcTableAddress.ToString("X"));
var npcVTableAddress = new IntPtr(executable.BaseAddress.ToInt64() + NPC_VTABLE.ToInt64());
Console.WriteLine("npcVTableAddress:" + npcVTableAddress.ToString("X"));

IntPtr numBytesRead;
IntPtr npcTablePointer;
{
byte[] buffer = new byte[8];
ReadProcessMemory(process.Handle, npcTableAddress, buffer, 8, out numBytesRead);
if (numBytesRead.ToInt64() < 8)
{
Console.WriteLine("Woops, didn't read enough bytes (NPC table pointer)!");
Thread.Sleep(15000);
return 1;
}
//Console.WriteLine("buffer:" + buffer);
npcTablePointer = new IntPtr(BitConverter.ToInt64(buffer, 0) + 0x20);
Console.WriteLine("buffer:" + npcTablePointer.ToString("X"));
}

byte[] npcBuffer = new byte[0x10f0];
for (int i = 0; i < 255; ++i)
{
IntPtr npcPointer = new IntPtr(npcTablePointer.ToInt64() + i * npcBuffer.Length);
if (!ReadProcessMemory(process.Handle, npcPointer, npcBuffer, npcBuffer.Length, out numBytesRead))
{
Console.WriteLine("Woops, didn't read enough bytes (NPC {0})!", i);
Thread.Sleep(15000);
return 1;
}

// EASTL string but most NPC names are short enough
IntPtr vtable = new IntPtr(BitConverter.ToInt64(npcBuffer, 0));
if (vtable != npcVTableAddress)
{
continue;
}

string name = "";
for (int j = 0; j < 0x20; ++j)
{
if (npcBuffer[j + 0x128] == 0)
{
break;
}
name += Char.ConvertFromUtf32(npcBuffer[j + 0x128]);
}

int x = (int)(BitConverter.ToSingle(npcBuffer, 0x35c) / 512);
int y = (int)(BitConverter.ToSingle(npcBuffer, 0x360));
int z = (int)(BitConverter.ToSingle(npcBuffer, 0x364) / 512);
ushort animation = BitConverter.ToUInt16(npcBuffer, 0xd48);
int id = BitConverter.ToInt32(npcBuffer, 0xff4);

Console.WriteLine("NPC {0} ('{1}'):", id, name);
Console.WriteLine("- location: {0}, {1}, {2}", x, y, z);
Console.WriteLine("- animation: {0}", animation);
Thread.Sleep(15000);
}

return 0;
}
}
}

Result looks same, magical bytes?
28442

Kompromaus
04-26-2018, 02:08 AM
Executables load at 0x140000000 without ASLR, so I'm not sure what's wrong. Is Modules[0] rs2client.exe?

If the Windows 7 executable is different from the Windows 10 one then the offsets won't work of course.

alar82
04-26-2018, 02:55 AM
On my old w7 laptop base address keeps changing every launch. Md5 hash however stays same. Ill try my w10 desktop pc at morning.
https://s7.postimg.cc/4w2nkdai3/test1.jpg

alar82
04-26-2018, 04:58 AM
Ok tryed at w10 pc.


Name:rs2client.exe Path:c:\programdata\jagex\launcher\rs2client.exe Base:7ff63ddd0000 Size:74d000
Client MD5 hash:788b1fa4ff3afd8471172701332e0008

Exe hash is same, would indicate that it is same exe as on windows 7.
Your code result:


Enter PID:
10180
npcTableAddress:7FF63E4B3018
npcVTableAddress:7FF63E2FD370
buffer:5B08F000030D15
Woops, didn't read enough bytes (NPC 0)!

Buffer reads same result, what should be there actually? Some values pointing to other places in memory?

Kompromaus
04-26-2018, 12:22 PM
On Windows 10, can you run the command "Get-FileHash -Algorithm MD5 ./rs2client.exe" in the ProgramData/Jagex/launcher directory via PowerShell?

I get 3F04078166CA5652BC12C58D64D6FA98 as of today (April 26).

There are multiple Windows clients (64-bit and 32-bit)--like 2 or 3 of them. The launcher downloads a different one depending on hardware and such. That's why I hacked together some custom launcher from someone's open source Linux launcher.

edit: ok I checked. You have client binary type 6 (64 bit Windows + DLLs). My offsets only work with client type 2. I ported this https://github.com/syldrathecat/nxtlauncher to Windows but it's a mess. I'll see if I can clean it up later and post it on my GitHub.

edit 2: How did you find the GUI pattern? I've found some GUI stuff (panels/buttons/items) and have a hierarchy but I can't quite figure out how to find out which "interface" they belong to (e.g., bank pin, bank window, inventory panel...).

alar82
05-09-2018, 02:42 PM
Updated and crashes possibly less.

alar82
05-10-2018, 01:36 PM
and I wonder how could I make minimap dots rotate. Nvrmind its was easy :D

alar82
05-16-2018, 11:01 AM
Srry couldnt stop spamming my own topic.

So I has investigated keyboard/mouse simulation methods. Most interesting ones are windows kernel ones. I has found a few and must ask software experts here which is best one to use.
It seems all of these install their own system dll and you can send your commands there.
InpOutx64 http://www.highrez.co.uk/downloads/inpout32/
Interception https://github.com/oblitum/Interception
WinRing0 https://github.com/QCute/WinRing0

Interception seems to best choice as it most maintained. But idno.
Edit: Can't find source code to his driver install.exe. I wanto check and install in source code.
Edit2: Well Interception works. But there is a huge issue. After using a fake mouse draw thing, as soon I move real mouse it jumps back to real mouse position. Nevermind I has given up on this thing :D

R0b0t1
05-20-2018, 06:22 AM
It will be easiest to use RDP. You should either try to look at MsRdpClient (https://msdn.microsoft.com/en-us/library/mt787050(v=vs.85).aspx) (and its variations) or FreeRDP (http://www.freerdp.com/) for a programmatic interface to the resulting connection. You will need to use RDPWrap (https://github.com/stascorp/rdpwrap). If you look in the RDPWrap repository there is a test program (https://github.com/stascorp/rdpwrap/blob/master/src-rdpcheck/MainUnit.pas) which uses MsRdpClient2 (https://msdn.microsoft.com/en-us/library/mt787053(v=vs.85).aspx) but it is written in Delphi. The project has very recently been migrating to C++ so that it is easier to develop for.

It was not possible in my tests to use MsRdpClient at any version from C#. I do not know why. I have not had the time to retry with COM from C++. Some testing in either direction should be easy to start.


If you really would prefer I can help you try to use the methods you are talking about but they do not allow you to use your computer while you are running a bot. If you use RDP you can continue to use your computer as well as have the input you are generating look authentic. The kernel is injecting it somewhere in the terminal services code running the RDP session and it will generate a WM_INPUT event.

You probably do not want InpOutx64 or WinRing0. The first is for accessing the pins of the processor and the PCIe interface directly. WinRing0 could do what you want, but you would need to provide a lot of supporting code. Interception would work and I have read about it. There is also the USB/IP driver (http://usbip.sourceforge.net/) for creating fake devices to be driven over a network. USB/IP is your best bet if you want to create a fake device.

alar82
05-20-2018, 03:34 PM
Inception works well... on desktop. But on remote window it tryes to control primary desktop mouse for some reason, even if it was started in remote desktop. Possible its driver sends info still to the REAL mouse from remote desktop. Now how does remote desktop mouse thing work? is it fake?

R0b0t1
05-20-2018, 08:00 PM
Inception works well... on desktop. But on remote window it tryes to control primary desktop mouse for some reason, even if it was started in remote desktop. Possible its driver sends info still to the REAL mouse from remote desktop. Now how does remote desktop mouse thing work? is it fake?By remote window do you mean RDP? There is no reason to use it with RDP. The best solution is to launch an RDP connection with the MS-provided class I referenced or to hook into the FreeRDP code. You would then be sending events over the network that the Microsoft Terminal Services code turns into input events.

Inception registers what looks to Windows like a hardware device. Session 1 is a privileged terminal services instance that receives all human interface device events. The fake hardware will only go to the local privileged session as a protection against keylogging. Connecting via RDP creates additional terminal services sessions that are not session 1 and can only interact with the machine's physical hardware in limited ways.

As far as anyone is aware, logging in with RDP is the only method that can create a new terminal services session, and thus, a new copy of the low level input stack.

alar82
05-24-2018, 04:34 AM
That RDP thing would be interesting but I has no idea what to do. Google doesn't wield any results on injecting mouse events on or onto remote desktop.

Patriq
05-24-2018, 04:06 PM
Nice job alar!
I am currently trying your plugin, it's pretty dope! Love the debug idea!

w2s doesn't seem to be working tho :(
Can't wait to start writing plugins with this beast!

EDIT: Trying your FindNpc example and for some reason, Simba is asking for 10 arguments, when you only provide 6. Looking at dllmain.cpp everything seems to be fine, I don't understand. Have any idea what is going on?

Here you can see:
28457

It compiles the first line, but the second one it doens't... Had to brute force parameter types to be able to compile the first one.

alar82
05-24-2018, 06:05 PM
Nice job alar!
I am currently trying your plugin, it's pretty dope! Love the debug idea!

w2s doesn't seem to be working tho :(
Can't wait to start writing plugins with this beast!

EDIT: Trying your FindNpc example and for some reason, Simba is asking for 10 arguments, when you only provide 6. Looking at dllmain.cpp everything seems to be fine, I don't understand. Have any idea what is going on?

Here you can see:
28457

It compiles the first line, but the second one it doens't... Had to brute force parameter types to be able to compile the first one.


Code has changed :P
But to kill some goblins.
FindNPCs1([66],1,25,0,0,0,0,True,0,"Attack")
66 replace with goblins id and it should work. BUT you must now install interception to move mouse with it. Ill update first post.
Edit: As for picking up items, that code is not finished...

R0b0t1
05-24-2018, 07:55 PM
That RDP thing would be interesting but I has no idea what to do. Google doesn't wield any results on injecting mouse events on or onto remote desktop.This thread (https://villavu.com/forum/showthread.php?t=118173) contains a summary. You don't actually need to do any programming, but you do need to install a program which modifies a system DLL. The only catch is that you can't minimize the RDP window. Microsoft's implementation they give you by default stops sending events when minimized. You could try connecting with FreeRDP and seeing if there is any difference.

Working with MsRdpClient directly would allow you to "minimize" the window or not even create one in the first place. But if you don't want to do that you don't have to. If you have the time look at the code in the RDPWrap repository that uses the terminal services DLL and try to adapt it to FreePascal or C/C++.

Olly
05-24-2018, 09:03 PM
Microsoft's implementation they give you by default stops sending events when minimized

SIKE. https://villavu.com/forum/showthread.php?t=118173&p=1391344#post1391344

alar82
05-24-2018, 10:21 PM
Interception calculations aren't quite correct yet. Anyhow if console window shows that mouse is found, only after that can be mouse controlled by script.

Patriq
05-24-2018, 11:16 PM
Ohh okay! Well I got the mouse found message. Been looking through the repository, the code could be cleaned a bit ;)

alar82
05-25-2018, 12:06 AM
Ohh okay! Well I got the mouse found message. Been looking through the repository, the code could be cleaned a bit ;)
Yes. Needs a lot of fixin too.
Updated plug, SetupRSReading changed.

Patriq
05-25-2018, 07:38 AM
Anything I can be helpful with?

alar82
05-25-2018, 08:56 AM
Well if you really wanto help....


VOID KeyPress_(char mK) {
HKL kbl = GetKeyboardLayout(0);
//no idea how to get shift characters
KeyboardPress(MapVirtualKeyEx(VkKeyScanEx(mK, kbl), MAPVK_VK_TO_VSC, kbl), 100,2000);
}

Figure out how to get any char to translated to keyboard scancode.
Currently it only does small case and not unicode.
Good luck :p

alar82
07-29-2018, 04:57 AM
Well I am still waiting for anyone help me with stiff chars.

But I have noticed that jagex is reluctant dismissing java. Guess they keep it as backup plan in case if nxt as c program utterly falls to the haxers. They also fired mod philip who was main developer of nxt and showed browser version of it 2 years ago. Since then barely any progress have been made. No vulkan/dx12 support.

rj
07-29-2018, 05:25 AM
Well I am still waiting for anyone help me with stiff chars.

But I have noticed that jagex is reluctant dismissing java. Guess they keep it as backup plan in case if nxt as c program utterly falls to the haxers. They also fired mod philip who was main developer of nxt and showed browser version of it 2 years ago. Since then barely any progress have been made. No vulkan/dx12 support.

he didn't get fired

alar82
07-29-2018, 05:42 AM
he didn't get fired

Well looks bit like it. Maybe they didn't pay him enough.

Guys, anyone has seen smart source? I can't find it. It would be interesting to see.

acow
07-29-2018, 02:51 PM
Well looks bit like it. Maybe they didn't pay him enough.

Guys, anyone has seen smart source? I can't find it. It would be interesting to see.

yup. It's available on benland100's github page

KeepBotting
07-29-2018, 04:09 PM
yup. It's available on benland100's github page

https://github.com/BenLand100/SMART

:D

acow
07-29-2018, 04:44 PM
https://github.com/BenLand100/SMART

:D

Wanted him to google the link himself :p

alar82
11-16-2018, 11:14 AM
Hi guys got bored and fixed it somewhat. Currently using it for portables.

alar82
05-06-2019, 05:45 AM
Now is wish Kompromaus would come back and explain some more about vtables =I
Edit:
Hey now messing around with x64dbg odd thing start happening when attaching to rs3 client. Mouse starts acting weird, like in slow-mo.
https://i.postimg.cc/fLFy82Nz/test.png
It seems there are some breakpoints added by client. Any comments?

jpeg2000
06-01-2019, 09:18 AM
When you debug, you should cancel the game's low-level mouse hook, or something strange will happen. The other two callback functions were added a long time ago. Acting on thread startup and thread stop, I haven't carefully looked at the two functions and guessed that you will be monitored when you start the thread inside the game. But this can be handled.

titandino
12-28-2019, 10:05 PM
Is anyone still working on this? As Java support is gone, it would be amazing to be able to have access to the NPC list from memory so I can dump their spawn locations.

alar82
12-29-2019, 06:53 PM
It still works and it is slow and fragile. Removed it, reason is: my code looks horrible :D

Current working one is uploaded here: https://github.com/pp9999/MemReading/releases/tag/0.1

To run it you put plugin into simba plugins folder and the run the Test script. 28682
Where it loads plugins and starts reading through memory. Open console window on simba and check the progress.
It should look something like this:
https://i.postimg.cc/5t3DdLxr/test1.png
Where main goal is to find LocalPlayer. Without it nothing works and you have to be logged in.
After that it should finish about in 5 minutes and display debug window.
Decorative object on minimap:
https://i.postimg.cc/1XwjBj3L/test2.png
Active objects on minimap:
There are invisible spider eggs at manor farm which are called invisible spider eggs :D
https://i.postimg.cc/63mXggwq/test3.png
NPCs:
https://i.postimg.cc/8ckBxXpF/test5.png

alar82
01-07-2020, 07:25 AM
When looking trough rs2client.exe hex there is a lot of references to webGL. I wonder why they use webGL for rendering. For a browser game it would be ok but it is installed game.
WebGl doesn't seem to be efficient as well, from looking at wiki: all graphic commands are done by sending string text(javascript?) and compiled in run-time. Wouldn't pre-compiled be much faster?
Why not use normal windows opengl.lib sdk thing :D Meh

It looks like further development of their old html5 client which was also javascript and webGl.

Hoodz
01-08-2020, 02:04 PM
When looking trough rs2client.exe hex there is a lot of references to webGL. I wonder why they use webGL for rendering. For a browser game it would be ok but it is installed game.
WebGl doesn't seem to be efficient as well, from looking at wiki: all graphic commands are done by sending string text(javascript?) and compiled in run-time. Wouldn't pre-compiled be much faster?
Why not use normal windows opengl.lib sdk thing :D Meh

It looks like further development of their old html5 client which was also javascript and webGl.

because the client is shit.

alar82
01-13-2020, 09:17 AM
You'l need 64 bit windows Simba. Download it from here: https://github.com/MerlijnWajer/Simba/releases/tag/autobuild-421. Some explation how to use new version of Simba is here:https://villavu.com/forum/showthread.php?t=118470. Unzip it somewhere and then put MemoryError.dll into plugins folder.
Probably breaks again after todays Rs3 update :/

alar82
01-14-2020, 03:19 PM
It is secret sauce now. For now.

alar82
01-25-2020, 09:44 PM
Nah this source wouldn't help you as it is shit. If you wanna learn something do it yourself. Post here I wan to see how are you doing.

alar82
01-31-2020, 12:28 AM
Well it is not total fail. Currently using this for afk event. Those brew hair caldrons give herb xps. Here is the script.


program Test;
{$loadlib MemoryError}
var
Count:Int32;

begin
wait(random(199));
SetupRSReading(True,0);
repeat
wait(340+random(4500));
if (random(100)>90)then begin writeln('P');PlayerIdle(); end;
Count:=Count+1;
begin
if (random(1000)>980)then begin
if FindAobj([114106],1,4,[0,0],[0,0],False,0,'Brew') then
begin
wait(1900+random(5500));
end;
end;
end;
until(Count>10000)
end.


Someone openend and closed github issue to fix BankOpen bool, it would require rewrite interaces logic to get right info. Too much effort.
Well to get character location just use cheat engine.

alar82
01-31-2020, 06:28 AM
Player coords are those x or y * 512 and search in float.

halfbreed9
01-31-2020, 07:04 AM
Oh so if I were at x coord 1000 the actual value of that x coord would be 512,000 ?

alar82
01-31-2020, 07:51 AM
Oh so if I were at x coord 1000 the actual value of that x coord would be 512,000 ?

Yes it would be. Lumby castle in front of top bank booth would be. (Minus half tile 256)
X=3208*512-256=1642752
Y=3220*512-256=1648896
There is also Z but we don't have proper WorldToScreen calculation so it is worthless.
With hex view it looks in memory like this:


00 88 C8 49 00 50 58 45
00 48 C9 49

alar82
02-02-2020, 06:27 PM
It should. Used this script for pickpocket draynor master farmers.

program Test;
{$loadlib MemoryError}

begin
wait(199);
SetupRSReading(True,0);

repeat
if (random(100)>98)then begin writeln('P');PlayerIdle(); end;
wait(1100+random(1099));
if (FindNPCs1([2234],1,28,[0,0],[0,0],False,0,'Pickpocket')) then
begin
writeln('FF');
wait(1400+random(9500));
end;
wait(1500+random(1099));
until(false)
end.

alar82
02-03-2020, 02:30 PM
Pointers will never work for rs. There is only 2 ways to get right spot. Dissecting executable somehow as some guy did here, or like me aob scan.

halfbreed9
02-04-2020, 10:56 PM
Do you happen to have the link to his post ?

alar82
02-05-2020, 06:27 AM
Do you happen to have the link to his post ?

It is on this thread check few pages back.

titandino
02-06-2020, 12:30 AM
I really wish this was open sourced so people can learn and contribute to it. Shame the same excitement that drives runelite doesn't drive RS3 developments. I am working on a 2012 remake of RS and there is a ton of information that I would be able to get saving me countless hours. NPC spawns, interface component animations, proj anims, spot anims, etc.

alar82
03-19-2020, 01:12 PM
Finally some progress. Bank has been found, with slots for all the items.
https://i.postimg.cc/VNTv0Fh1/bank.png
It is part of interfaces new reading method. Much more powerfull than before now getting all interfaces. Only bad part is finding starting point which is bit shit now. Works only in nxt compability mode and is under test.

go9090go
03-24-2020, 01:14 PM
I used your code last summer and found that the Components/Widgets/Interfaces are in the same structure as in the java client. Widgets have components and components do have child components. This way i was able to find all interfaces the same way as in the java client.

alar82
03-25-2020, 03:58 PM
I used your code last summer and found that the Components/Widgets/Interfaces are in the same structure as in the java client. Widgets have components and components do have child components. This way i was able to find all interfaces the same way as in the java client.

Throw some code here :P I don't know nothing about java.

Main issue is that ReadProcessMemory is horribly slow and if lot is read it goes to snail pace. I wonder how much faster would be read from inside process. Then again I am afraid mess with it, maybe they check loaded stuff.

titandino
03-26-2020, 05:15 AM
Throw some code here :P I don't know nothing about java.

Main issue is that ReadProcessMemory is horribly slow and if lot is read it goes to snail pace. I wonder how much faster would be read from inside process. Then again I am afraid mess with it, maybe they check loaded stuff.

I can guarantee they have no form of anticheat that checks for hooks.

halfbreed9
03-29-2020, 01:59 AM
You able to run multiple accounts with this? Or just one ?

Sin
04-02-2020, 05:31 PM
This is absolutely great work. Do you have Discord or something? Would love to combine this with some sort of ML model.

alar82
04-04-2020, 11:15 PM
@halfbreed9 It only works for 1 client, haven't bothered to add more as I use it only for my main for boring and simple tasks. Mostly I look how game world is made, that's quite fun.
Added now new interface scraper. Removed old one. New method might be difficult to find with AOB, but with pointer, it goes straight to it.
Now try to fix that BankOpen() bool.

St Semajian
05-13-2020, 04:04 PM
@halfbreed9 It only works for 1 client, haven't bothered to add more as I use it only for my main for boring and simple tasks. Mostly I look how game world is made, that's quite fun.
Added now new interface scraper. Removed old one. New method might be difficult to find with AOB, but with pointer, it goes straight to it.
Now try to fix that BankOpen() bool.

Hey - would love to help contribute to this. Have tried spinning it up locally - getting an error clicking an obj from FindAobj: Did not find varps:659

Happy to extend Sin's comments above - do you have discord? I'm a software engineer by day, admittedly haven't done alot with Simba but always happy to learn a new technology.

EDIT: Ignore my issue above. :duh:

However point still stands, RS3 community is really lacking in presence for botters - would be really happy to contribute and try to push it further.

alar82
05-13-2020, 08:47 PM
Dno... I like to keep it all to myself. Making it perfect and proper would lure lots of people here and it would paint huge red target onto it,... no thank you :)

But about FindAobj it works as FindNPC thing. Use AO debug to find thing to click. Things like portable fletchers are Active Objects.

Use
if (not CheckPAnim(120)) then begin /code/ end; to check if players is animating. Number there is how many times to check vs 25 milliseconds. Some animations have huge caps between them.

Use
if (InveFull()) then begin /code/ end; to check if inventory is full or not.

Use
if (InveItemcount(item1)<3) then begin /code/ end; to count items in inventory, item1 is ID.

Use
if (InveFreecount()<9) then begin /code/ end; to check how many spots are free.

Use
ClickInv(item1,0); to click item in inventory. Warning there is no check if inventory is actually open. So yea some fail safes should be added.

St Semajian
05-14-2020, 06:40 AM
Dno... I like to keep it all to myself. Making it perfect and proper would lure lots of people here and it would paint huge red target onto it,... no thank you :)

But about FindAobj it works as FindNPC thing. Use AO debug to find thing to click. Things like portable fletchers are Active Objects.

Use
if (not CheckPAnim(120)) then begin /code/ end; to check if players is animating. Number there is how many times to check vs 25 milliseconds. Some animations have huge caps between them.

Use
if (InveFull()) then begin /code/ end; to check if inventory is full or not.

Use
if (InveItemcount(item1)<3) then begin /code/ end; to count items in inventory, item1 is ID.

Use
if (InveFreecount()<9) then begin /code/ end; to check how many spots are free.

Use
ClickInv(item1,0); to click item in inventory. Warning there is no check if inventory is actually open. So yea some fail safes should be added.

Yep got it working in the end was use error.
That's a shame but I understand. Would you at least consider exposing a few more functions as getters to have a little more logic? :D

BeatDat
05-14-2020, 01:57 PM
Can this be used with other programs other than Simba, like AHK or AutoIt?

St Semajian
05-18-2020, 01:37 PM
Looks like latest game update has broken the sidetext functionality - Is there anything we can provide in the action string parameter that returns immediately? I.E instead of "Mine"? Right now a workaround is to use MouseClick() after the object find - but by the looks of it the FindAObj is trying (3?) times to find the sidetext before closing the statement so it jumps a little before clicking

alar82
05-18-2020, 05:30 PM
Quick fix applied.
Edit:
It tries few times before giving up, at slightly different pixels to find a match at sidetext.
As for skipping sidetext check, I could add a keyword like " "=space to skip match checking.

alar82
05-30-2020, 08:19 PM
Anyone know what bot those cursed energy bots use? I tried asking them but nothin, herders didn't wanto spill anything either.

halfbreed9
06-07-2020, 07:40 AM
It's not just 1 person it's two actually. I know both of them. How did you go about getting the GameObjects ? Trees mining rocks bank stalls etc?

titandino
06-10-2020, 07:00 PM
Anyone know what bot those cursed energy bots use? I tried asking them but nothin, herders didn't wanto spill anything either.

Hey, I am working on programming Herblore Habitat for my RSPS and I am in need of the actual spawns list of invisible jadinkos within the area. Your tool shows them on the minimap, but doesn't give the ID or location elsewhere or any way of looping over the list.

I would pay you for the simple source code just to retrieve a list of NPCs and their IDs/Positions that are being updated (whether or not they are being rendered or hidden via varbits).

alar82
06-11-2020, 03:33 AM
Hey, I am working on programming Herblore Habitat for my RSPS and I am in need of the actual spawns list of invisible jadinkos within the area. Your tool shows them on the minimap, but doesn't give the ID or location elsewhere or any way of looping over the list.

I would pay you for the simple source code just to retrieve a list of NPCs and their IDs/Positions that are being updated (whether or not they are being rendered or hidden via varbits).

Had a look, yes there are invisible npcs. Can't add them to 3d world debug, they don't have clickbox. Added some more debug options to npc minimap, NPCInfoMap1 switches between name and id. Nothing is simple :D
Currently using it to watch seren spirit spawn. Clicking npcs is odd, needs rework. Found also booleans for inventory closed and open states.

titandino
06-11-2020, 05:04 PM
Had a look, yes there are invisible npcs. Can't add them to 3d world debug, they don't have clickbox. Added some more debug options to npc minimap, NPCInfoMap1 switches between name and id. Nothing is simple :D
Currently using it to watch seren spirit spawn. Clicking npcs is odd, needs rework. Found also booleans for inventory closed and open states.

Yeah when I said simple, I meant even a stripped simple CLI program that only reads NPCs and nothing else.

alar82
06-13-2020, 01:46 PM
At tit nah.
At halfbreed9 all are on tiles. Players are on tiles, npcs are, objects are.

Lucidity
06-13-2020, 02:04 PM
Very cool stuff, I checked it out. You should definitely expand the include so it could be used for multiple instances, seems primarily based for PvM. Would like to see some interaction options with players, options to click on tiles instead of on the minimap (TileWalk?). Keep it up!

alar82
06-14-2020, 05:19 PM
Well player interaction would be possible if someone had time to code it.
Added 2 new functions:

CheckInvOpen(); - to check if inventory is open or closed.

OpenInv(); - to check if inventory is open and if not then try to open it with menu icon. Menu icon must be in front and not in slider menus. Slider menus are like labyrinth, I don't have no time and brainpower to dissect them.


program Test;
{$loadlib MemoryError}

begin
wait(199);
SetupRSReading(True,0);
wait(100+random(1099));
repeat
wait(5000+random(1099));
Writeln(CheckInvOpen());
OpenInv();

//Writeln(BankOpen());
//Writeln('Coordinates: ',GetPCoords());
//Writeln('Floor: ',GetPFloorLv());
//Writeln('HP: ',GetHP());
until(false)
end.
Edit: Crash Fixes. Now can open inventory tab if it is on wrong one.
Edit: Added area loot window debug.
Edit: Today investigating camera I has discovered that camera is on tile.
https://i.postimg.cc/FRVN9snW/tilec.png
That z goes to small numbers if camera is moved close to ground. That is funny, like it would be psychical camera.
I was looking for viewport stuff. Like osrs has. Trough power of openosrs:
OverlayUtil.renderTextLocation( graphics, new Point(client.getCanvasWidth() / 11, 20), "x " + String.valueOf(client.getCameraX()), Color.WHITE);
Osrs:
https://i.postimg.cc/8PNQpSh9/tilec2.png
Dosent look similar numbers, maybe it would have diffrent values if I could directly read raw values of hooks.
But maybe I am reading wrong spot from rs3

mkmk4
07-04-2020, 02:38 AM
Would love to be able to use this in a python bot I'm working on... For now I'm just using OpenCV to detect objects (doesn't work too well for npcs tho). I also tried machine learning but it is too resource intensive. Could you share source maybe on junior forums so it's not just out for the public? I would be willing to contribute and we could all learn a lot from it. I did some messing around with cheat engine and was able to get the coordinates and figure out some of the inventory stuff but beyond that I'm lost at how to find the npc objects and their values...

userNote
07-06-2020, 04:25 PM
Hey, great stuff you have been doing!, already made use of your dll and it seems great!, atm im making my own, but having trouble finding viewMatrix for runescape 3, could u give me a hand or a tip?? thanks!!

alar82
07-14-2020, 05:29 PM
@mkmk4 Yes putting it all together from cheatengine hex is a difficult.
@userNote If you get that viewmatrix working please loan it :D It would help a lot.

Added
GetAllNPCs; gets all npc into Simba.
For v1400 of Simba. Older gives access error.
https://github.com/ollydev/Simba/releases


program Test;
{$loadlib MemoryError}

var
i,hi: Integer;
store: Array of AllObjects;
begin
wait(199);
SetupRSReading(True,0);
wait(100+random(1099));
repeat
wait(5000+random(1099));
//Writeln(GetAllNPCs());
store:=GetAllNPCs();
hi := High(store);

for i := 0 to hi do
begin
writeln(
"Name:",store[i].Name,
". Hitpoints:",store[i].Life,
". ID:",store[i].Id,
". X:",store[i].TileX,
". Y:",store[i].TileY,
". Z:",store[i].TileZ
);
end;

until(false)
end.

Little test script for it.
Also discovered that if I move my plugins vector arrays from headers to cpp-s it gets much faster. Probably something to do with CPUs L2/L3 cashe.

userNote
07-14-2020, 05:34 PM
hey yeah, found the viewmatrix, but i cant send links here :P nor images, so how am i about to send it?

alar82
07-14-2020, 05:38 PM
hey yeah, found the viewmatrix, but i cant send links here :P nor images, so how am i about to send it?

Paste code here or github. OR https://postimages.org/
Uploaded new plug into github btw.

userNote
07-16-2020, 03:59 AM
Hey sorry for the late reply, well I didn't write the code yet, been busy with other stuff, as I mentioned earlier, I can't send links here nor write code ( the forum don't allow me to post any links or image and so on, cause I'm new here ) don't u have any contact info like discord or anything similar ( villavu requires me to have 10+ posts )

alar82
07-19-2020, 11:05 AM
Nah no discord. Found another crash cause.
Edit: Found more and fixed them hopefully.
Edit2: Found out that pixels for AllObjects were wrongfully copy pasted.
@Lucidity I has my doubts. Someday?
Edit3: Made npcs/objects cleanup cleaner.

alar82
08-17-2020, 02:39 AM
Hey guys i noticed this thread on another forums.>https://guidedhacking.com/threads/how-to-find-the-runescape-viewmatrix.15435/
Has anyone managed get that viewmatrix thing working? I can find it easily and load those 16 floats into that formula. But nothing sensible comes out of it. Tryed many diffrent spots aswell to sorta bruteforce it.
https://i.postimg.cc/T1YxJwJd/ce2244.png
Yea it leads to here.
Tried to use that 0.99 as start and 1.79, read from that point 4 byte size floats in 16 times into array of floats and then unload them onto matrix multi thing.
Entity is raw float of our character location.


float screenW = entity.x * Mx.at(3) + entity.y * Mx.at(7) + entity.z * Mx.at(11) + Mx.at(15);
float screenX = (entity.x * Mx.at(0) + entity.y * Mx.at(4) + entity.z * Mx.at(8) + Mx.at(12)) / screenW;
float screenY = (entity.x * Mx.at(1) + entity.y * Mx.at(5) + entity.z * Mx.at(9) + Mx.at(13)) / screenW;

WPOINT rs = GetRsResolution2();
float camX = rs.x / 2.f;
float camY = rs.y / 2.f;
float screenx = (camX * screenX) + (screenX + camX);
float screeny = -(camY * screenY) + (screenY + camY);

return{ screenx, screeny };

userNote
08-18-2020, 02:28 AM
You're in luck haha, I'm Rablidad, i said you before i had the viewmatrix, what happens is that runescape is a weird game and they use Row major with OpenGL

alar82
08-18-2020, 06:33 AM
You're in luck haha, I'm Rablidad, i said you before i had the viewmatrix, what happens is that runescape is a weird game and they use Row major with OpenGL

Thanks for hint, now i can start messing with it again. You can start pm-ing people here if you get higher forum rank. Need like 30 post for that.

alar82
08-19-2020, 08:19 AM
Hey Rabli
Any idea what floats should I start from :D ? and are those floats in normal order? x y z?

Clarity
09-01-2020, 07:46 PM
Interesting progress over the years. Do you have plans to re-open the source or are you keeping it closed forever?
Good luck :)

alar82
09-11-2020, 03:36 AM
Hey thanks Clarity. I am waiting userNote to share is WorldToScreen - ViewMatrix, it would take displaying stuff to another level. Any minute now.
Edit: Answering a question.

Is there capability to right click NPCs to select an option that isnt left clickable? Can only see how to do it crass atm by mousemoving with TPoint of MouseLoc on right click.
Hello. You mean choose option menu and choose option from there? Sadly it is a separate thing from interfaces. So my reader has no idea what is in it. However I have found location in memory that contains all that info but it has to be reconstructed to make use of it. Maybe someday.

But as you said you can use static coordinates to aim for option.
FindNPCs1([66],1,20,[0,0],[0,0],False,0,'Attack');
That 0 between False and Attack is mouse options. 0 left click, 1 right click, 2 move mouse.
So maybe you can use:
Aim for npc menu and if we get lucky it opens it
FindNPCs1([66],1,20,[0,0],[0,0],False,1,'Attack');
Using Simba:
Get current mouse position.
GetMousePos(X,Y);
Add static pixels to the option needed. Mouse is always at top of choose option menu and in middle so + to go down.
MoveMouse(X,Y+40);
ClickMouse(X,Y+40);
Using plugins mouse functions. Proper way to do it:

Pos_xy:Tpoint;
//War Npc in wars retreat, opens up shop option.
if (FindNPCs1([26773],1,20,[0,0],[0,0],False,1,'Talk')) then
begin
Pos_xy:=MousePos();
Pos_xy.Y:=Pos_xy.Y+40;
MouseClick(Pos_xy,TRUE);
wait(5000);
end;
Updated plug again. Hey added new method of interfaces thing stuff something.

willin275
11-07-2020, 10:36 PM
How do i use your plugin? i have downloaded plugins.7z

alar82
11-07-2020, 10:44 PM
How do i use your plugin? i have downloaded plugins.7z

Put MemoryError.dll into plugins folder. Then when u use script that uses it, press run and check console window to see if anything is happening. I would use older simba(1.3) because it keeps plugin running even if script is stopped.

willin275
11-07-2020, 11:08 PM
thanks for the fast reply, now when i run a script i get a warning that the apps are not on the same scaling level?

alar82
11-07-2020, 11:20 PM
thanks for the fast reply, now when i run a script i get a warning that the apps are not on the same scaling level?

They must be at same size thing. Right click at simba exe and choose properties and from there compatibility. From there change high dpi setting and override dpi. Switch between application and system to see which one works.

forest seed
11-09-2020, 05:08 AM
They must be at same size thing. Right click at simba exe and choose properties and from there compatibility. From there change high dpi setting and override dpi. Switch between application and system to see which one works.

hi alar82, do you have a discord i can add?, im attempting to develop the sauce into a standalone application.

alar82
11-13-2020, 03:00 PM
hi alar82, do you have a discord i can add?, im attempting to develop the sauce into a standalone application.
Try SRL discord.

Lucidity
12-08-2020, 05:04 PM
The function:

GetPCoords()

is displaying incorrect values, at least on the Y variable in my testings.

Used the latest update and the PlayerInArea function was reading false even though code hasn't changed. Determined cause to GetPCoords()

- Could you release source so we could fix issues like this ourselves?

alar82
12-08-2020, 08:50 PM
Hmm I tested it at it looks fine.

Writeln(GetPCoords());

It gives out those exact coordinates that are in upper corner of debug(rounded down).
At least it should.
What number are you getting from there?

Edit: updated plugin.
Removed all scripts and added up again.

Lucidity
12-09-2020, 03:02 AM
Hmm I tested it at it looks fine.

Writeln(GetPCoords());

It gives out those exact coordinates that are in upper corner of debug(rounded down).
At least it should.
What number are you getting from there?

Edit: updated plugin.
Removed all scripts and added up again.

It's showing up as X 0 and Y 0 for me.

alar82
12-09-2020, 08:22 PM
Yes. FIX it.

Uploaded code onto GitHub as private. Wanto fixit? Ask invite from
https://discord.gg/ywSDHbXmF5

Edit fixes for localplayer finding.

ogustuce
02-21-2021, 03:44 AM
@alar82 why when i copy paste your functions i get too many parameters error? like i understand i'd have to teak the parameters but they straight up don't work

BeatDat
02-21-2021, 06:36 PM
Post a snippet of the code so we can see what is going on.

alar82
03-28-2021, 06:37 PM
https://i.postimg.cc/MGHGKsJT/testg4.png

Recently trying to make somekind of GUI to it.

alar82
06-18-2021, 04:52 AM
https://i.postimg.cc/NjzJ150r/fishin.png
Works fine.

alar82
07-24-2022, 12:07 PM
Still working.