Now, I haven’t done nearly as much research into this particular part of WoW hacking as I probably should, but I’m looking at it from a IJW (it just works!) standpoint. Other people, before you and me, have done the really hard work and we’re privileged enough to simply ride along atop their findings. Never–and I mean never–let their work go unappreciated.
WoW stores its game objects inside what’s called its Thread Local Storage (hereafter referred to as TLS). There’s pointers to pointers to its linked-list of game objects (hereafter referred to as the object manager) but, thanks to Kynox, we can make it VERY easy to access the object manager inside WoW’s TLS. Seriously, any time you have the opportunity, thank Kynox. This method is so much easier than any of the others I’ve come across.
So, as of the current patch on June 14th, 2008, (2.4.2 I think?), there is a pointer to the object manager at [0x00D495B0]+0×2218. See this thread on how I access the object manager in my application. Basically, if you are content with your tool only working for the current version of the client and you don’t mind having to manually update for new client versions, just read from memory like so:
- Define a DWORD variable named g_clientConnection and read from 0×00D495B0 into it.
- Define another DWORD variable named s_curMgr and read from ( g_clientConnection + 0×2218 ) into it.
- s_curMgr is now your pointer to the object manager.
Now that we have our object manager, we can start reading objects from the linked-list. I now turn you over to Kynox’s WoW Object Dumper so you can peruse its source, which I will also outline in just a second.
Once you have your object manager pointer, you can read from ( s_curMgr + 0xC0 ) and gain your localGUID (it’s an int64, not a DWORD). Save this so you can compare it to the GUIDs in the linked-list and determine which is your own (useful for teleportation hacks, setting your facing direction by writing to memory, etc.).
Read from ( s_curMgr + 0xAC ) for a pointer to the start of the linked-list. Each object in the linked-list contains a pointer to the next object, so we’re going to need two DWORD variables here: curObj and nextObj. We’ll loop through the list, reading information from curObj, including a pointer to nextObj, determine if nextObj is valid, and then setting our current object (curObj) to the next one in the list (nextObj) and doing it all over again, only stopping when nextObj is null. This is all a part of Kynox’s WoW Object Dumper, but I will show you my C# source for the same exact thing here. You can find the Memory library in use in that example here.
This allows you access to the positional data on all of the loaded objects. This is as far as I have currently gotten, but I will be pushing on very, very soon. Stay tuned.
I apologize for my lack of knowledge, but I am trying to rewrite this code myself, in C++.
I’m having trouble with Memory.ReadUInt, I tried replacing it with ReadProcessMemory but it doesn’t take 2 parameters and I don’t want to lose information of course.
My code is as follows:
typedef unsigned int uint; //search for the code pattern that we want (in this case, WoW TLS) uint tlscode = dwFindPattern(hProcess, 0x410000, 0x400000, "EB 02 33 00 64 8B 15 2C 00 00 00 8B 0D 00 00 00 00 8B 0C 8A", "xxx?xxxxxxxxx????xxx"); //read Kynox's g_clientConnection from memory uint g_clientConnection = ReadProcessMemory(hProcess, ReadProcessMemory(hProcess, (tlscode + 0x16))); //first, the offset for the curMgr inside g_clientConnection is read, //then s_curMgr is read from g_clientConnection + that offset (which may change version to version, //I honestly don't know) uint s_curMgr = ReadProcessMemory(hProcess, (g_clientConnection + ReadProcessMemory(hProcess, tlscode + 0x22))); //output to console //Console.WriteLine("TLS code: 0x{0:X08}\ng_clientConnection: 0x{1:X08}\ns_curMgr: 0x{2:X08}", tlscode, g_clientConnection, s_curMgr); cout << "TLS code: 0x{0:X08}\ng_clientConnection: 0x{1:X08}\ns_curMgr: 0x{2:X08}" << tlscode << g_clientConnection << s_curMgr << endl;I already have full debugging privileges and stuff, just trying to learn how to read information from WoW.
Thanks for your time.
Comment by fabolous1 — June 15, 2009 @ 2:22 am
Sorry, the code is here:
http://www.nomorepasting.com/getpaste.php?pasteid=27051
Comment by fabolous1 — June 15, 2009 @ 2:23 am
oops sorry, this is including the 2 dwfindpattern and datacompare functions I found:
http://www.nomorepasting.com/getpaste.php?pasteid=27052
errors i’m getting:
1>c:\documents and settings\owner.earth\my documents\visual studio 2008\projects\unknowncheathack\unknowncheathack\main.cpp(95) : error C2660: ‘dwFindPattern’ : function does not take 5 arguments
1>c:\documents and settings\owner.earth\my documents\visual studio 2008\projects\unknowncheathack\unknowncheathack\main.cpp(98) : error C2660: ‘ReadProcessMemory’ : function does not take 2 arguments
1>c:\documents and settings\owner.earth\my documents\visual studio 2008\projects\unknowncheathack\unknowncheathack\main.cpp(98) : error C2660: ‘ReadProcessMemory’ : function does not take 2 arguments
1>c:\documents and settings\owner.earth\my documents\visual studio 2008\projects\unknowncheathack\unknowncheathack\main.cpp(103) : error C2660: ‘ReadProcessMemory’ : function does not take 2 arguments
1>c:\documents and settings\owner.earth\my documents\visual studio 2008\projects\unknowncheathack\unknowncheathack\main.cpp(103) : error C2660: ‘ReadProcessMemory’ : function does not take 2 arguments
1>unknowncheathack – 5 error(s), 0 warning(s)
Comment by fabolous1 — June 15, 2009 @ 2:33 am