View Full Version : World of Warcraft "reversing" / bot programming
n00bster
April 7th, 2006, 22:53
Hello all,
I'm looking for a bit of information on how I would go about writing an automated "bot" for the online game, World of Warcraft.
My idea first:
I'm planning to just use ReadProcessMemory and search for "monsters"(Not sure how I will identify them in memory yet) and when found, I'll use MouseEvent() api to send the appropriate mouse clicks to do the attacking, etc, it'll be very cheesy, but it's just a start, i guess.
My problem is, I don't know where to start reading in memory inside of the WoW.exe process? How can I find out approximately where "monster" data is kept, or, my "health" is kept. I thought I could just search for my health to give me a start, but should I start a address 0 in the programns memory ? when using ReadProcessMemory? I'm guessing no..
Anyways, if anyone can shed some light for me, it'd be much appreciated.
I apologize in advance if this is too off-topic, I figured since it consisted of the use of debugging apis/messing with another process it couldn't be that far off-topic, plz delete if it is.
thanks
Extrarius
April 8th, 2006, 07:28
I expect that you'll be quickly banned if you start randomly poking and prodding the WoW process, but the functions you want are:
GetModuleHandle
VirtualQueryEx
CreateToolhelp32Snapshot
Process32First / Process32Next
Heap32ListFirst / Heap32ListNext
Heap32First / Heap32Next
Toolhelp32ReadProcessMemory
Admiral
April 8th, 2006, 09:59
This sounds like quite a challenge. Locating monster objects in memory and extracting their positions isn't inconceivable, but forging input events to bring your character to the location, face the right direction and attack a moving target sounds pretty tricky.
In order to find the sensitive spots in memory, you'll have to take a few guesses as to how the game was written (I'll assume it's C++) and how the data are stored in memory. It's likely that each actor in the game is represented by some class or other. The monster and player classes are probably the same or similar (perhaps derived from the same base), and all characters (including yourself) are likely to be instances of the same class.
Considering that the world is so dynamic, the characters and monsters are probably stored in a resizable array.
More specifically, I'd guess that you're dealing with a std::vector of some class CPlayer, with your own character at index 0. Of course, this is just a guess, but the facts shouldn't be too different.
A good way to try to locate where you are stored in memory would be to note down your vitals (try to make them as 'unique' as you can - if you have a high level character this will be easier) and perform a binary search over the process heap for your character's name (almost certainly ASCII). You are likely to find it in several places but with enough probing and a bit of luck, you may find it sitting next to some other recognisable figures (health, magic etc.). Note that the integral variables (e.g. health) should be long/short ints, whereas your position is probably stored with floats. If you get this far, working out the struct definition is a matter of trial-and-error. Once you've worked out how player data are managed, advancing to monsters will be a little easier.
Bear in mind that this is the best-case scenario. You're likely to find a lot of red herrings and encounter problems that didn't occur to you. Be prepared to deal with the situation where names are stored as std::string (and so you won't have an ASCII string in the struct but a pointer). If you have a good debugger, using a tool to decode STL structures can save you a lot of effort.
You should probably try to get this sussed before even thinking about your feedback system. Let us know how you get on.
Regards
Admiral
Aimless
April 9th, 2006, 12:19
1. Go to Google.
2. Search for "Cheat Engine v5"
3. IMPORTANT: Go through the Cheat engine tutorials after installation.
4. WARNING: This is not a simple memory reader. It is VERY complicated piece of software, I sometimes use to break heavy time/number protected software.
5. Rest all should be OK
Have Phun
PS: Hope the WOW servers do not check the WOW process in memory for anything like their data etc.
squidge
April 10th, 2006, 17:08
Using ReadProcessMemory may be ok, but it seems anything that alters memory used by WoW.exe is certainly out of bounds. I was a little interested on the checks, and changed a single byte (part of what seemed like a name). Tried it twice, and got disconnected from the server between 1 - 3 minutes afterwards each time
Now this could be a coincidence, but considering the number of times a disconnection happens normally (very rarely), I think not...
I'd imagine therefore that after this happens X amount of times in Y amount of time, you'll get banned. So be warned!
LLXX
April 11th, 2006, 02:27
Quote:
[Originally Posted by squidge]I'd imagine therefore that after this happens X amount of times in Y amount of time, you'll get banned. So be warned! |
Many games have such protections... watch out for hooked system calls and constantly-checked memory. No doubt some more reversing can disable those checks

Silver
April 11th, 2006, 05:30
The problem with hacking online games is that the developers are wise to all the tricks. That doesn't mean they are competent to prevent them, but it does generally mean that data is validated at the server as well as by the client game software. You're always better off with "local" hacks (eg: wallhack in Halflife) than "global" hacks (eg: give your character $1000 in some MMORPG, where the stats of each player are stored on the server).
disavowed
April 11th, 2006, 11:20
You shouldn't need anything more than ReadProcessMemory since you can send fake input to the game (in the case of a bot) and you can draw on top of the screen with DirectX (in the case of a trainer). No need to overwrite the process's memory anywhere.
Silver
April 12th, 2006, 06:35
Note that drawing on the screen with DX is a good solution but it has some risks. Example, some of the Valve cheater-protection admin software takes screenshots of clients as they play the game, and sends those screenshots to the server. The server admin can then see exactly what you're seeing making any visual cheats very obvious. So don't just inject some DX drawing code, make sure you check out any suspicious code that might snapshot your screen or similar.
omega_red
April 20th, 2006, 06:18
This article may be a bit helpful for avoiding WoW self-checks

http://rootkit.com/blog.php?newsid=358
disavowed
April 20th, 2006, 09:42
Quote:
[Originally Posted by Silver]some of the Valve cheater-protection admin software takes screenshots of clients as they play the game, and sends those screenshots to the server. The server admin can then see exactly what you're seeing making any visual cheats very obvious. |
That's awesome!
Assuming that's true, you could create a networked trainer and have it display its information on another computer's screen.
squidge
April 20th, 2006, 14:50
I prefer this one myself:
h**p://w*w.wowsharp.net/forums/viewtopic.php?t=7024
Much more informative.
Silver
April 21st, 2006, 05:36
Quote:
[Originally Posted by disavowed]That's awesome!
Assuming that's true, you could create a networked trainer and have it display its information on another computer's screen. |
Nice, huh! The anticheat system is called PunkBuster, here's some info:
http://users.pandora.be/z/suggested/screen.html
My mistake, it's not by Valve it's by Even Balance Software but it was made for Valve products etc.
The networked trainer idea is nice actually, it wouldn't be hard to hook DX Present calls, grab the backbuffer and send it elsewhere.
squidge
April 21st, 2006, 05:46
I didn't think the anti-cheat in WoW was as bad as punk buster? As in, Punk Buster requires administrative priviledges before it'll run, for example.
Admiral
April 22nd, 2006, 13:50
it wouldn't be hard to hook DX Present calls, grab the backbuffer and send it elsewhere.
True, but then it would be all too easy to sidestep this method by drawing directly to the front-buffer. Nevertheless, the principle stands - it's just as easy to capture the contents of the screen buffer.
Silver
April 23rd, 2006, 11:44
Quote:
True, but then it would be all too easy to sidestep this method by drawing directly to the front-buffer |
Off the top of my head, 2 problems. First all sensible D3D(/any gfx) software uses double buffering to prevent nasty flickering and tearing. D3D itself is designed to work with 1 frontbuffer and N backbuffers - you draw to the backbuffer than flip it with a call to Present(). D3D, drivers and the card can then handle any synch/timing etc it needs to. So by not using a double buffering system to prevent cheaters from grabbing the backbuffer would cause far too much harm to your product.
Second I don't believe you can actually get the the real front buffer in D3D. The front buffer is of course the screen data itself - the entire screen resolution. If an app had access to that (remember, D3D apps can run windowed) then it would cause all sorts of nastiness to happen. There is a method called GetFrontBufferData() which puts a copy of the front buffer into an allocated memory buffer, but as far as I'm aware there's absolutely no way to get at the "real" bits in the "real" frontbuffer.
The normal way to accumulate drawing for manipulation is to use a rendertarget, then blit that wherever you want. Present() really is your last chance...
Admiral
April 23rd, 2006, 21:20
Silver, it seems I confused you.
What I meant was that if the developer checks for cheaters by intercepting calls to Present or Flip to dump the top back-buffer (in any N-buffered setup), like you said, then the hacker would need only make sure that they draw their cheat overlay directly to the front buffer. This way, the back-buffer screenshots would appear clean.
I haven't played with DirectX much since DX9 came out, but I do remember seeing an article on how you can use some hacky workaround to get access to the D3DDevice's screen memory (or something equivalent to it). I'm not entirely confident with DX's architecture, so as far as I know, even this isn't necessary - GetFrontBufferData may well pick up any and every render (hacky or otherwise) you throw at the screen.
Regards
Admiral
Silver
April 24th, 2006, 11:06
Quote:
the hacker would need only make sure that they draw their cheat overlay directly to the front buffer.....you can use some hacky workaround to get access to the D3DDevice's screen memory |
That's the problem though - as far as I know, you can't draw directly to the front buffer. D3D just doesn't let you get access to it. GetFrontBufferData is the closest you can get, and that is a simple blit of the front buffer to system memory. Remember that the frontbuffer is being read to match the sync rate once it's been flipped, so even if you could get access to it there's no guarantee you're not drawing to a part of the buffer that hasn't already been drawn onscreen.
Once the developer calls Present(), the current active backbuffer is flipped/copied (depending on D3D setup flags) to the front buffer and it's gone for good. Intercepting Present() is the last possible chance and only guaranteed way for the gamehacker to get the current frame. That's true even if the coder doesn't use the T&L pipeline and locks the backbuffer for manual putpixel type drawing. If the gamecoder calls GetFrontBufferData after the gamehacker has hooked Present() and done their cheat-drawing, the gamecoder will still retrieve any modifications to the last frame.
Maybe I'm misunderstanding what you're saying, in which case apologies. But as far as I know there's no way around the problem for the cheatcoder.
All of this, of course, assumes that the anti-cheat code implements a robust protection. For example, if the protection is simply diverting all rendering to an off-screen rendertarget, blitting that rendertarget as a screenshot then blitting it again to the backbuffer before calling Presnet(), then it's weak protection that occurs too early in the render cycle.
Also disavowed's comment about sending the display over the network and showing it on another monitor is also a good solution and would prevent any overlay drawing from showing up on a screencapture. The same principle would work for a machine with 2 graphics cards as you're also working on 2 different pipelines and buffers.
Admiral
April 24th, 2006, 22:00
It looks like I've been outwitted.
Like I say, I don't have too much experience of DX9

.
As of DirectX 7 (maybe DirectDraw 7 in particular), I'm fairly sure you were advised to draw to the back-buffer, but had access to the screen/front buffer if you so needed (regardless of the 'VSync' situation). If I'm not mistaken, this would allow for my proposed workaround. However, as it appears, DX9 doesn't give the developer such control.
So maybe I should quit while I'm behind, but that's not in my nature

My next idea is to use the GDI (maybe in a separate thread) to draw onto the screen after D3DDevice.Present.
Now you can't possibly claim that
that can be intercepted within DirectX

LLXX
April 24th, 2006, 23:36
A solution in hardware might work better than one in software for this... read the screen contents from the video signal going to the monitor and inject the data to be displayed into the signal, sort of like the OSD on the monitor. Now nothing from the injected signal will show up in any screenshots.
Quote:
[Originally Posted by Silver]Also disavowed's comment about sending the display over the network and showing it on another monitor is also a good solution and would prevent any overlay drawing from showing up on a screencapture. The same principle would work for a machine with 2 graphics cards as you're also working on 2 different pipelines and buffers. |
This "showing it on another monitor" was what prompted me to come up with the above idea.
Silver
April 25th, 2006, 10:31
Quote:
So maybe I should quit while I'm behind, but that's not in my nature
My next idea is to use the GDI (maybe in a separate thread) to draw onto the screen after D3DDevice.Present.
Now you can't possibly claim that that can be intercepted within DirectX |
Your tenacity is impressive

, but I do feel a bit guilty shooting another idea down...
The GDI is subject to exactly the same restrictions as D3D drawing. Namely, in D3D9 you can use the IDirect3DSurface9::GetDC() method to retrieve a pointer to a DC then draw as normal with GDI functions. However you still have exactly the same problem of doing something with that surface. Really you're just substituting D3D drawing with GDI drawing, you're subject to exactly the same restrictions as before (ie: you must draw to a surface before Present() is called).
Also, it's worse for DX8. There's no method to retrieve anything GDI-compatible from a D3D surface, the GetDC method was introduced in D3D9. Prior to DX9 the accepted method was to create a memory DC and DIB section, draw into it with the GDI then blit the DIB to a DX surface. That, of course, would have to be done well before Present().
The GDI works at a higher level than DX, and is more subject to windowing restrictions too. We haven't even touched memory pools and lost devices yet...
As for DX7, I have little experience or recollection of coding for it, so I'm sure what you're saying is correct.
LLXX, a hardware solution would work perfectly as long as no HDMI (DRM enabled) interfaces were used.
Admiral
April 25th, 2006, 11:48
</persistence>
Pah... Who wants to cheat multiplayer games anyway?

I suppose this is why PunkBuster works then
Regards
Admiral
goggles99
April 25th, 2006, 16:19
No hooking, or GDI required... Use a DirectDraw Overlay
http://www.gamedev.net/community/forums/topic.asp?topic_id=359319
Most all modern video cards support hardware overlays, and screenshots can't be taken of the overlay using normal means.
Also see the directx 6 or 7 SDK's "Mosquito" example.

Silver
April 26th, 2006, 06:58
Goggles99, interesting, I had to look into that as I'd not worked with overlays before. I found out why pretty quickly - they're only supported in DX7. You can't work on different interface revisions, ie: if the target app is D3D8 or D3D9 with D3D8/9 surfaces, you can't use DDraw(7) overlays.
goggles99
April 26th, 2006, 19:31
I do not think that it matters what the target app is using as it's graphics api, You can create an overlay over it with an external app (or injected dll) with no hooking by using DirectDraw.
For example...
Some gaming companion programs such as teamspeak, and X-fire used to use hooks to write chat/status messages to the screen. Eventually People were getting kicked by PunkBuster for the hooking (many cheats used these same type of hooks). Now X-Fire uses DirectDraw overlays instead to draw over directx 8/9 game screens, both in windowed mode and fullscreen.

Silver
April 27th, 2006, 05:06
That's very interesting. I'll have to look into that in more detail, I wasn't aware it was possible. Thanks!
Powered by vBulletin® Version 4.2.2 Copyright © 2018 vBulletin Solutions, Inc. All rights reserved.