I tried that already
Using this code: NoMorePasting.com
And just changing the 34 to be 36 and setting the program to Interact when I mouse over'd a gameobject, passing it the address of the current gameobject, I tried lots of things and nothing happened, game didn't crash either, but it was late and couldn't figure out what was wrong.
Last edited by shauno; 10-22-2008 at 05:41 PM.
Object.GetName and Object.Interact POC (3.0.2)
That's what you want. Yeah, it uses an as-yet unreleased memory-reading class library that I'm currently finishing, but you should be able to port everything over. I've got less time to program for WoW since I'm actually playing again (paladin isn't boring now!), but I should roll out a few little proof-of-concept out-of-process sorta things in the next week or so, hopefully including the memory/process manipulation class library (BlackMagic, in the above example).Code:using System; using System.Collections.Generic; using System.Linq; using System.Diagnostics; using System.Text; using Magic; namespace BlackMagicTest { class Program { const uint CLIENT_CONNECTION = 0x011C8248; const uint CURMGR_OFFSET = 0x285C; const int FIRST_OBJECT = 0xAC; const int VMT_GETNAME = 47 * 4; const int VMT_INTERACT = 36 * 4; const int OBJECT_TYPE = 0x14; const int OBJECT_GUID = 0x30; const int OBJECT_NEXT = 0x3C; static void Main(string[] args) { BlackMagic wow = new BlackMagic(); if (wow.OpenProcessAndThread(SProcess.GetProcessFromProcessName("wow"))) { uint ObjectManager, ClientConnection; uint codecave; uint curObject, nextObject; uint VMT; int curType; UInt64 curGUID; uint pCurName; string curName = String.Empty; bool bInteracted = false; while ((ClientConnection = wow.ReadUInt(CLIENT_CONNECTION)) == 0) System.Threading.Thread.Sleep(100); while ((ObjectManager = wow.ReadUInt(ClientConnection + CURMGR_OFFSET)) == 0) System.Threading.Thread.Sleep(100); codecave = wow.AllocateMemory(); while ((curObject = wow.ReadUInt(ObjectManager + FIRST_OBJECT)) == 0) System.Threading.Thread.Sleep(100); while (curObject != 0 && (curObject & 1) == 0) { curGUID = wow.ReadUInt64(curObject + OBJECT_GUID); curType = wow.ReadInt(curObject + OBJECT_TYPE); //first four bytes point to the virutal method table VMT = wow.ReadUInt(curObject); wow.Asm.Clear(); wow.Asm.AddLine("fs mov eax, [0x2C]"); wow.Asm.AddLine("mov eax, [eax]"); wow.Asm.AddLine("add eax, 8"); wow.Asm.AddLine("mov dword [eax], {0}", ObjectManager); wow.Asm.AddLine("mov ecx, {0}", curObject); wow.Asm.AddLine("call {0}", wow.ReadUInt(VMT + VMT_GETNAME)); //read pointer to GetName method wow.Asm.AddLine("retn"); try { pCurName = wow.Asm.InjectAndExecute(codecave); if (pCurName != uint.MaxValue) curName = wow.ReadASCIIString(pCurName, 100); else curName = String.Empty; if (!bInteracted && curName.Equals("Mana Wyrm")) { wow.Asm.Clear(); wow.Asm.AddLine("fs mov eax, [0x2C]"); wow.Asm.AddLine("mov eax, [eax]"); wow.Asm.AddLine("add eax, 8"); wow.Asm.AddLine("mov dword [eax], {0}", ObjectManager); wow.Asm.AddLine("mov ecx, {0}", curObject); wow.Asm.AddLine("call {0}", wow.ReadUInt(VMT + VMT_INTERACT)); //read pointer to Interact method wow.Asm.AddLine("retn"); wow.Asm.InjectAndExecute(codecave); bInteracted = true; } } catch (Exception ex) { Console.WriteLine("Exception during Object.GetName or Object.Interact: {0}", ex.Message); } finally { Console.WriteLine("GUID: 0x{0:X016} | TYPE: {1} | NAME: {2}", curGUID, curType, curName); } nextObject = wow.ReadUInt(curObject + OBJECT_NEXT); if (nextObject == 0 || nextObject == curObject) break; curObject = nextObject; } wow.FreeMemory(codecave); } else { Console.WriteLine("World of Warcraft could not be opened for read/write."); } Console.ReadLine(); } } }
Edit: Is that code a bit more readable than my previous Object.Interact, Chazz? =p (**** you, by the way)
Last edited by Shynd; 10-22-2008 at 07:00 PM. Reason: Had to add a flame to Cypher, of course.
Awesome Shynd!
The Object.Interact() code worked perfectly
However I keep getting gibberish back on the Object.GetName()
Would you be able to share your code for your ReadASCIIString() method? Right now I'm using the uint result of Inject/Execute and using BitConverter.GetBytes and Encoding.ASCII.GetString but I'm just getting question marks and other various symbols >_<
Even though it shares the exact same code as the Interact.. besides the VMT index weird.
The return value of .GetName is the address of the string in memory. You have to read the bytes of the string out of memory.
Here are a few static classes that will help you read memory. I'm currently finishing these up, but they're functional anyway.
Win32Imports.cs
SMemory.cs
Awesome, awesome stuff! Thanks a lot!
Was just about to try checking the address for the string too >_< but yep, that did the trick
Cool class, handy, I didn't have a string reading method, was just looping adding bytes >_<
Cheers man.
GetName returns a char*. You need to deference the pointer to read the "string".
NoMorePasting.com
I dunno, something to play with. Seems overkill to me but just the fact that you can use injected ASM to gather all information necessary with one memory read seemed like a cool idea. I was thinking of having it call GetPosition, GetFacing, GetUnitRelation relative to local player, GetName, GetItemIdByName, etc., and then using one memory read to grab all of the values out of memory. Would do away with having to update offsets for shit like position and name, but creates more overhead than I really care to think about. Eh, it was fun to write. Makes me want to go back and finish my in-process tool![]()
Lol I like it, just because of the namespace name ^.^
I hacked 127.0.0.1
Sweet, got my SetHeading() function sorted.
I found using frequent updates and multiple keystrokes to set the heading and check the new heading everytime wasn't that accurate or fast.
After doing a couple of tests I found that a full rotation from 0-0 radians is about 2000~ milliseconds give or take. (basically scanned memory as fast as possible, spun around in circles and had it output anything on 0.0xxxx, it took a while to get two to match up due to the refresh of memory not being fast enough to pick it up on that number)..
So by that, I find the radian difference between current heading and where the player should be heading (atan2 of course) and use that as a percentage of 6.3 to work out how long to hold the key down for, between 0-2000ms --- it's working out very very well and seems to be extremely accurate even on somewhat long distance. Of course it works 100% on close up objects. In any waypointing routine, I will still check the heading and the atan2 calculation of the next waypoint to make sure it's staying within a heading tolerance and can adjust itself if need be, since it can be done while running, its pretty good.
I wish I didn't fail maths in school.
u can overwrite ure facing in memory to make ure toon turn instantley. just check what curFacing are then substract targetFaing with curFacing to get how much u need to turn then, calculate if left/right is the shortest and make a loop. and make sure you convert it to radians before you inject it.