The phrase of the day is: Virtual Table. Read up on Object Oriented Programming, class inheritance, and virtual functions. I probably don’t understand all of these things as well as I should, so I will not cloud the issue by summarizing what my understanding of the above subjects is.
Suffice it to say that the table of virtual functions associated with a class object–a class object might be a GameObject, a GameUnit, a GamePlayer, etc., as it applies to World of Warcraft–are things that can be called almost as a part of the object. For instance, instead of calling a function like Interact(GameObject obj), you’d simply call it like obj.Interact(), which, in my opinion, simplifies things greatly.
Anyway, you should all know, by now, how to find the base address of whatever object you want to interact with (generally it will be either a mob or a mining/herbalism/quest node). Loop through whatever objects you find until you find the one you want to kill, target it, walk up to it, call it.Interact() and, voila, you’re attacking it. So, once you have the base address of the object, read the VERY FIRST pointer, at offset zero. ReadDword(WoWhProcess, objectbaseaddress); This will be a pointer to its virtual table of functions associated with that class object.
The virtual table consists of pointers to subroutines associated with the object. In other words, each entry in the table is a DWORD pointing to the start address of a function that can be used with–or as a part of–the object. If you want to call obj.Interact(), you need only know which place in the virtual table .Interact() occupies. Well, here: it occupies position number 34. That, by the way, is credit, ONCE AGAIN, to bobbysing’s WoWX hack base, so think of him and anyone else that helped him find the information when you use it–I did literally nothing to find it except page through his source code.
So, you’ve got your pointer to the virtual table by reading at the base address of the object, and now you read from (virtualtablepointer + (34 * 4)) in order to find the address of the .Interact() function associated with the object (yes, it’s a different address for GameObjects and GameUnits, so you really do have to read its address from the virtual table associated with the object each time you call it). Remember, it’s in position 34, and each position consists of a DWORD (4-byte) pointer to a function, so, to read from position 34, we read from VTable+(34*4). Hope that’s clear.
If we’re calling a class method from an external thread–and we are–then we have to make sure our thread is as close as possible to resembling the thread that NORMALLY would call the method. We pretty much all, at this point, use the TLS method for iterating through loaded objects, so I hope this is not new to anyone who needs to know how to target a unit–in other words, if you’re reading this post and hoping to apply it to your bot/tool, you should probably understand what I’m talking about. A pointer to the linked-list of objects in the WoW client is held in the TIB, or Thread Information Block, of the calling thread. Since we are creating an external thread, as in my last article, to call this method, we need to modify our thread’s TIB to emulate WoW’s. A few simple ASM instructions and one memory write should do the trick!
Get your pointer to the s_curMgr ready, you’re going to need it. Currently, you can get a pointer to the s_curMgr with two memory reads: [[0xD495B0]+0×2218]. This is what we’re going to use to update the TIB of our thread.
At this point, you’re going to want to make sure you’ve read my SelectUnit article because much of what I’m going to breeze through right now is covered there, with code examples. We’re going to have to allocate memory, inject code, and call CreateRemoteThread, just as outlined in the SelectUnit article.
So, allocate your chunk of memory using VirtualAllocEx. It doesn’t have to be huge, but making it a full 0×1000 byte chunk won’t hurt for our purposes. For this example, assume your code injects at address 0×1230000; here is the ASM we will be injecting:
MOV EDX,DWORD PTR DS:[DEADBEEF] ;DEADBEEF==placeholder for our s_curMgr pointer MOV EAX,DWORD PTR FS:[2C] ;start accessing our TIB MOV EAX,DWORD PTR DS:[EAX] ;do it like WoW does it ADD EAX,08 ;same MOV DWORD PTR DS:[EAX],EDX ;move the s_curMgr pointer into our TIB MOV ECX,DWORD PTR DS:[DEADBEEF] ;ECX = the base address of the object we're interacting with CALL WoW.DEADBEEF ;DEADBEEF = placeholder for the address of the virtual function RETN ;always return so we don't crash
So, like before, we have to patch a few relative moves and calls. First, remember that pointer to the s_curMgr you read from memory? Write it to CodeCave+2 (in this example, 0×1230002). Now, write the base address of the object with which you wish to interact to CodeCave+0×100 (0×1230100) and patch the second occurence of DEADBEEF (CodeCave+21) with the value of CodeCave+0×100 (this will tell it to move the value at address 0×1230100 into ECX on line 6). Lastly, patch your relative Interact call on line 7 by writing (interactfunction – (CodeCave + 30)) to CodeCave+26. When it’s all injected, and you look at it in OLLYDBG, it should look normalized, with all the addresses correct and no more DEADBEEF (spoiled meat stinks anyway).
Now you just CreateRemoteThread on it and watch as your player loots it, attacks it, mines it, or gathers it. Magic.
As is my usual practice, here’s a bit of code on which to chew.
Until we meet again.