getPlayerName != GetObjectName??? I mean type 4 objects name as far as I thought used a different way of finding name than the type 5 (objects) or the type 3(units).
Would you kind enough to post an IDA example retriving getPlayerName current offsets PLZ :angel:
As you can see on this screen capture, player text is the only thing left that my tracker app needs (would be a pitty to use injection for just 1 thing).
Screen Capture:
http://img9.imageshack.us/img9/3954/tracker99done.jpg
Last edited by mordok; 05-07-2009 at 03:44 PM.
"I'm not going to expose my methods for time bending, as i don't want to do get nerfed!"-Kynox
You know whats sad? u post that in here, and dont open a new thread for it! Thats sad, ur getting reply's back and i dont![]()
Thanks Shynd that would be so generous of you like alwayas ^^.
GRB im terribly sorry I wish the moderators aproved my thread on this exact same subject, but as soon as they read Player name they asume its garbage reject it coz it has been covered
(although the dont realize that non-injecting method to read players name is not covered ; ( at all )
Since this thread is very similar to my question, I thought I was a good idea to post it here. Im sorry if it bothered, in return of this ill help you as much I can with your question.
For GRB:
This is what I suggest you to do.
Steps:
1-Find objectManager
2-Find your local player GUID(your toon identification)Code:g_clientConnection = READ(0x1132F60); s_curMgr = READ( g_clientConnection + 0x2C24);
3-Now go through all the objects in the objectManager finding their GUIDS and compareing them to your localGUID to find the object we want (your toons object).Code:localGUID = READ( s_curMgr + 0xC0);
A bit tricky so pay extra attention.
Hope this helped ^^, credit for the clienntConnection method goes to Kynox, descriptors to Cypher, and how to iterate through objects like that to Shynd. You should check his blog journal . BTW sorry for using pseudo, I dont autoit. Im affraid that If used it Cypher would flame me to death so keep it C# at least. Also note they are more efficient ways of doing this.Code://Go to the first object of the object manager 0xAC is the offset to the first. currentObject = READ(s_curMgr + 0xAC); While(true) { //note, this will go on forever //find that objects GUID currentGUID = READ(currentObject + 0x30); //Compare it to your localGUID, is it the same?. If yes this is the object of your player, if not this isnt it so jump to de next object and do the same comparisson. if(currentGUID == localGUID) { //This is the one of its your player //**BINGO WE HAVE OUR PLAYER OBJECT NOW WHAT?** //to find its HP just go to the "array" at 0x8 of that object arrayAt8 = (currentObject + 0x08); //and use Cypher descriptors * 4. Hp = 0x17 hp = (arrayAt8 + (0x17*4) ); //THERE YOU GO! } else { //this is the case that its any other objec thats not your player. Then will jump to the next object + 0x3C currentObejct = READ(currentObject + 0x3C); } }
Last edited by mordok; 05-07-2009 at 09:36 PM.
"I'm not going to expose my methods for time bending, as i don't want to do get nerfed!"-Kynox
@ mordok, thank you for explained how to write the full program on a loop, but for catching the hp i was already able to do it just with
But atm im not interessed in writting a program on the loop, just want to pop a MsgBox, saying the value or if its true or not. But u did a nice job explaining all the things for all the lines u did wrote so i could understand better. But my question keeps the same, for finding a certain buff i could do a loop to check all the buffs till i find the one i wanted, but the biggest problem is that i dont know if the way i got the HEX for the Seal of Command was the correct one or neither how can i get it if its not! But probably when i will write the full code i will take ur example, thank you.Code:Global $PlayerBaseStatic = 0x010B65F4 ;Static Offset SetPrivilege('SeDebugPrivilege', 1) $DllInformation = _memoryopen(WinGetProcess("World of Warcraft")) ;Open WoW If @error = 1 then ;WoW Open MsgBox(0, 'Error', 'World of Warcraft Process not found, closing program...') Exit EndIf ;Gets base addresses $lvl1Pointer = _MemoryRead('0x' & hex($PlayerBaseStatic), $DllInformation , 'uint') $lvl2Pointer = _MemoryRead('0x' & hex($lvl1Pointer + 0x34), $DllInformation , 'uint') $PlayerBase = _MemoryRead('0x' & hex($lvl2Pointer + 0x24), $DllInformation , 'uint') $p1 = 0x8 $pchp = 0x5C ;Current HP $pmhp = 0x7C ;Max HP ;#cs $hp = _MemoryRead(($PlayerBase + $p1), $DllInformation , 'uint') $chp = _MemoryRead(($hp + $pchp), $DllInformation, 'uint') ; Current HP $mhp = _MemoryRead(($hp + $pmhp), $DllInformation, 'uint') ; Max HP MsgBox(0, 'Current HP & Max HP', $chp &" :: "& $mhp)
Btw ur 'currentObj' is the same things as my $PlayerBase
P.S - One other question why the array is at 0x08 like u told in here
Any special reason for beeing 8?Code://This is the one of its your player //**BINGO WE HAVE OUR PLAYER OBJECT NOW WHAT?** //to find its HP just go to the "array" at 0x8 of that object arrayAt8 = (currentObject + 0x08);
Last edited by GRB; 05-08-2009 at 02:36 AM.
What you need to do is read the first four bytes of the obj base, then find the vmt offset and multiply it by four(the function ptrs are 4 bytes long) then go to that address in IDA and see how the virtual function does it.
Tell me if im wright,
steps
1- I find the object I want looping through the object manager.
2- once I found the one I want I get the first 4 bytes of that adress and trim the rest of the adress.
3- I add the vmt offset * 4 (name 47 i think)
so it would be
idaAdress = READ(4bytesOfObject + (47*4));
4- I check that adress in IDA an find how it works.
This is wierd. ;(
Last edited by mordok; 05-08-2009 at 12:08 PM.
"I'm not going to expose my methods for time bending, as i don't want to do get nerfed!"-Kynox
Oh the boredom. Nothing major changed.
After I realized that it was really all the same I just copied Shynd's code (yes shynd, this snippet will haunt you down!).Code:// Original code by Shynd using System; using System.Collections.Generic; using System.Linq; using System.Text; using Magic; namespace playername { class Program { // BlackMagic instance static BlackMagic Memory; // ecx for 3.1.1 static uint ADDRESS = 0x1137CE0; /// <summary> /// test main-method /// </summary> /// <param name="args">don't care</param> static void Main(string[] args) { // get 'em wow Memory = new BlackMagic(SProcess.GetProcessFromProcessName("Wow.exe")); // just to be sure ~~ if (Memory.OpenProcessAndThread(SProcess.GetProcessFromProcessName("Wow.exe"))) { // Don't have an up-to-date C# framework anymore, hardcoded playerbase, // mhhhh, chocolate. Console.WriteLine(GetPlayerName(0x1E6E2338 /* dwBase here*/)); } else { Console.WriteLine("WoW not found, biatch."); } Console.ReadKey(); } /// <summary> /// Do you want to reverse it yourself? sub_67D3D0 /// Nothing changed however, and I wasted over an hour reversing it again. -.- /// </summary> /// <param name="player">player baseaddress</param> /// <returns>playername, yo</returns> static string GetPlayerName(uint player) { //read the object's GUID from obj+0x30 (again, pretty basic) UInt64 GUID = Memory.ReadUInt64(player + 0x30); //some sort of list index int var1 = Memory.ReadInt(((ADDRESS + 0x8) + 0x24)); if (var1 == -1) return "Unknown Player"; //here we're getting the pointer to the start of the linked list int var2 = Memory.ReadInt(((ADDRESS + 0x8) + 0x1C)); var1 &= (int)GUID; var1 += var1 * 2; var1 = (var2 + (var1 * 4) + 4); var1 = Memory.ReadInt((uint)(var1 + 4)); //iterate through the linked list until the current entry has //the same GUID as the object whose name we want while (Memory.ReadInt((uint)var1) != (int)GUID) { int var3 = Memory.ReadInt((uint)((ADDRESS + 0x8) + 0x1C)); var2 = (int)GUID; var2 &= Memory.ReadInt((uint)((ADDRESS + 0x8) + 0x24)); var2 += var2 * 2; var2 = Memory.ReadInt((uint)(var3 + (var2 * 4))); var2 += var1; var1 = Memory.ReadInt((uint)(var2 + 4)); } //now that we have the correct entry in the linked list, //read its name from entry+0x20 return Memory.ReadASCIIString((uint)(var1 + 0x20), 40); } } }
If you want to reverse it yourself: This is the 'important' subcall: sub_67D3D0
Ill try skus, for the names, and as soon I get them ill try to find how it works by following what lanman92 sed and paying extra attention at sub_67D3D0.
Really, really, really THANK U GUYS.
Btw thanks Sku for spending 1h of ur life to help me, I would hug you, but since I dont know u the least I can do is give u this symbolic virtual award called REP.
Last edited by mordok; 05-08-2009 at 09:01 PM.
"I'm not going to expose my methods for time bending, as i don't want to do get nerfed!"-Kynox
Now that im done with modifing my app to find players name (AGAIN THANKS FOR THIS ^^)
I started to look at IDA sub_67D3D0, and for my surprise It was easy enough to follow comparing the C# code to the ASM in IDA.
But I was wondering 2 things? How did you found that sub_67D3D0 was getPlayerName¿¿?? How woud you spot it in an upcoming patch¿¿??
Last edited by mordok; 05-09-2009 at 09:55 PM.
"I'm not going to expose my methods for time bending, as i don't want to do get nerfed!"-Kynox