| | WoW Memory Editing WoW Memory Editing for learning purposes only.
This section is more advanced than others on MMOwned Read the section specific rules, infractions will be given out if u break them!That is including the expectations! - If you don't meet them then don't post |  | | 
10-01-2009
| | Corporal | | | Join Date: Jul 2009 Location: Los Angeles, CA
Posts: 27
Reputation: 18 Level up: 54%, 186 Points needed |  | | | [C#] A Memory Enumerator for Walking The Objects This is a mini-tutorial that explains how to create an enumerator to walk the list of objects in the object manager.
Objects in the memory space of the World of Warcraft game client are held in a linked list that can be iterated over once you have the base address of the in-game Object Manager class. Walking that list of memory addresses can be a troublesome issue for many would-be developers. The easiest way that I have found, for C# development, is to create an enumerable list of memory addresses which can be treated just like any other collection to be iterated over.
Fortunately for C# developrs, creating a list of memory addresses is trivial using the enumerator interfaces built in to .NET.
The two classes provided below work by taking the pointer to the game client object manager class, and iterating over the linked list structure in-situ. Rather than doing the dirty work of juggling pointers in your own code, and trying to detect if you have run off the end of the linked list, you can simply use the built-in “foreach” loop structure of whatever your favourite .NET language is to retrieve the memory address of each game object. From there it is possible to write a wrapper class to manipulate the game object, or overlay the appropriate game object structure at the memory address.
A trivial example that makes use of the enumerable and enumerator classes is provided that walks the linked list of Warcraft game objects.
In the Enumerator class given below the “ObjectManagerPtr” is determined in the usual manner for accessing the list of locally cached in-game objects. Code: public class ObjectMemoryAddresses : IEnumerable
{
public ObjectMemoryAddresses()
{
}
public IEnumerator GetEnumerator()
{
return (new ObjectMemoryAddressesEnumerator());
}
}
public class ObjectMemoryAddressesEnumerator : IEnumerator
{
// The following two offsets apply to the 3.2.2a game client.
public const uint OBJECT_LIST_OFFSET = 0x70;
public const uint NEXT_OBJECT_OFFSET = 0x3C;
private uint m_currentAddress = 0;
public ObjectMemoryAddressesEnumerator()
{
}
private uint GetNextAddress()
{
if (m_currentAddress == 0)
{
m_currentAddress = ObjectManagerPtr + OBJECT_LIST_OFFSET;
}
return MemoryEditor.ReadUInt(m_currentAddress + NEXT_OBJECT_OFFSET);
}
private bool IsValidAddress(uint address)
{
if (address == 0)
{
return (false);
}
if ((address & 1) != 0)
{
return (false);
}
if (address == m_currentAddress)
{
return (false);
}
return (true);
}
public bool MoveNext()
{
uint newAddress = GetNextAddress();
if (!IsValidAddress(newAddress))
{
m_currentAddress = uint.MaxValue;
return (false);
}
m_currentAddress = newAddress;
return (true);
}
public void Reset()
{
m_currentAddress = 0;
}
public object Current
{
get
{
if ((m_currentAddress == 0) || (m_currentAddress == uint.MaxValue))
{
throw new InvalidOperationException();
}
return (m_currentAddress);
}
}
}
Example usage: Code: List<WowObject> objectList = new List<WowObject>();
ObjectMemoryAddresses objectMemory = new ObjectMemoryAddresses();
// get the memory address of each object
foreach (uint memoryAddress in objectMemory)
{
objectList.Add(GetWoWObjectFromPtr(memoryAddress));
}
You can also apply this same enumerator technique to walking the player name cache or the auras. I believe that the auras and the player name cache are both stored in a C++ STL Map or something similar because of the “two lists” that are apparent in the memory structure. Most game client name cache functions found in the wild emulate the functionality of a C++ STL Map lookup. | Donate to remove ads, get your "DONATOR title, and get access to the MMOwned community's elite Shoutbawx. 
10-01-2009
| | Corporal | | | Join Date: Sep 2009 Location: localhost
Posts: 16
Reputation: 5 Level up: 5%, 381 Points needed | | | Looks very good, and it's informative. It's nice to see someone using C# and actually using the features. It's sad to see people making stuff in C# and just treating it like a basic script language.
Anyways | 
10-02-2009
|  | Contributor | | | Join Date: May 2007 Location: Sweden
Posts: 263
Reputation: 100 Level up: 24%, 381 Points needed | | | | Great job! +REP
I agree with Neverhaven about people being unable to use the functionality of the .net framework. IEnumerable is very important to master because it is the foundation of the entire System.Collections namespace.
__________________ 
Get a signature like this one for free
http://www.mmowned.com/forums/graphics/249322-service-video-effects-userbars-signatures.htm | 
10-02-2009
| | Sergeant | | | Join Date: Jun 2008
Posts: 41
Reputation: 36 Level up: 36%, 320 Points needed | | | Quote:
Originally Posted by Neverhaven Looks very good, and it's informative. It's nice to see someone using C# and actually using the features. It's sad to see people making stuff in C# and just treating it like a basic script language.
Anyways  | Don't forget LINQ: Quote:
var friends = Client.World.GetAllPlayers().Where(x => x.Value.IsAlive && Notoriety.IsFriend(Client.World.Character, x.Value));
var health = friends.OrderBy(x => x.Value.HPCur);
| | 
10-02-2009
| | Corporal | | | Join Date: Sep 2009 Location: localhost
Posts: 16
Reputation: 5 Level up: 5%, 381 Points needed | | | | That reminds me, I still need to learn some more about lambda operators. | 
10-04-2009
| | New User | | | Join Date: Sep 2009
Posts: 51
Reputation: 3 Level up: 53%, 189 Points needed | | | | nice done!
However, some things are still missing(when you miss it all).
I have my own memory read functions but where do you put in where to start reading objects?
AND
Could you paste WowObject structure? (the whole thingy, what do you grab and so). | 
10-04-2009
|  | Contributor | | | Join Date: May 2007 Location: Dragon Shores
Posts: 690
Reputation: 167 Level up: 28%, 651 Points needed |     | | Quote:
Originally Posted by Shutzler nice done!
However, some things are still missing(when you miss it all).
I have my own memory read functions but where do you put in where to start reading objects? | Code: if (m_currentAddress == 0)
{
m_currentAddress = ObjectManagerPtr + OBJECT_LIST_OFFSET;
}
return MemoryEditor.ReadUInt(m_currentAddress + NEXT_OBJECT_OFFSET);
But it seems she accesses the first object in a different manner than I'm used to. If ObjectManagerPtr + 0x70 points to the first object, doesn't this implementation skip the first object? Quote:
Originally Posted by Shutzler Could you paste WowObject structure? (the whole thingy, what do you grab and so). |
Why not ask for the entire folder instead?
__________________ “Saying that Java is nice because it works on all OSes is like saying that anal sex is nice because it works on all genders.”
“If Java had true garbage collection, most programs would delete themselves upon execution.” | 
10-04-2009
| | New User | | | Join Date: Sep 2009
Posts: 51
Reputation: 3 Level up: 53%, 189 Points needed | | | Quote:
Originally Posted by Robske
Why not ask for the entire folder instead? | I dont understand, entire folder? I just want a list of offset to stuff. like within playeobject or targetobj(for its HP), where to find xp, mana, rage, position ++ | 
10-06-2009
| | Site Donator | | | Join Date: Feb 2009
Posts: 60
Reputation: 12 Level up: 36%, 323 Points needed |    | | he wants to say that you should be satisfied with what was written by the thread author. If you have the WowObject structure you could soon ask for a complete bot and therefore "for the entire folder" (where the source is stored)
For me as a beginner to all this memory editing stuff I am happy that one shows an easy example on how to get the objects from the wow memory. The objects are the base for nearly every useful bot.  for the tutorial.
i still have the question:
how is the "ObjectManagerPtr" exactly defined which you are using in the following line Code: m_currentAddress = ObjectManagerPtr + OBJECT_LIST_OFFSET;
| 
10-06-2009
|  | Contributor | | | Join Date: May 2007 Location: Dragon Shores
Posts: 690
Reputation: 167 Level up: 28%, 651 Points needed |     | | Quote:
Originally Posted by Ellesar1 For me as a beginner to all this memory editing stuff I am happy that one shows an easy example on how to get the objects from the wow memory. The objects are the base for nearly every useful bot.  for the tutorial.
i still have the question:
how is the "ObjectManagerPtr" exactly defined which you are using in the following line Code: m_currentAddress = ObjectManagerPtr + OBJECT_LIST_OFFSET;
| I have no clue as to where it came from. But it should work if m_currentAddress is assigned the address of the first object in the linked list.
Which is: [[[g_ClientConnection]+curMgrOffset]+firstObjectOffset]
(That would however still skip the first object)
__________________ “Saying that Java is nice because it works on all OSes is like saying that anal sex is nice because it works on all genders.”
“If Java had true garbage collection, most programs would delete themselves upon execution.” | 
10-06-2009
| | Corporal | | | Join Date: Jul 2009 Location: Los Angeles, CA
Posts: 27
Reputation: 18 Level up: 54%, 186 Points needed |  | | | Equivocal or equivalent? If there is an error, or I have misinterpreted how the object list is laid out in memory, I will gladly provide a fix...
However, run this code against whatever solution you are currently using to retrieve your objects and see if they return identical results.
At the offset 0xAC in the Object Manager class is a pointer to the first object.
At the offset 0x3C within each object is a pointer to the next object.
Ergo:
Object Manager Ptr + 0x70 + 0x3C, i.e. Object Manager Ptr + 0xAC is a pointer to the first object
Current Object Ptr + 0x3C is a pointer to the next object
Odd that... don't you think?
This is the code I derived my solution from, and I modified this code from other sources found on the 'net by cleaning it up and renaming variables to make it more understandable. Code: public const uint FIRST_OBJECT_OFFSET = 0xAC;
public const uint NEXT_OBJECT_OFFSET = 0x3C;
public List<WowObject> GetObjects()
{
List<WowObject> objectList = new List<WowObject>();
uint currentObjectPtr = GetFirstObjectPtr();
uint previousObjectPtr = 0;
while ((currentObjectPtr != 0) && ((currentObjectPtr & 1) == 0) && (currentObjectPtr != previousObjectPtr))
{
System.Diagnostics.Debug.WriteLine("Object Addr = 0x" + currentObjectPtr.ToString("X"));
objectList.Add(GetWoWObjectFromPtr(currentObjectPtr));
previousObjectPtr = currentObjectPtr;
currentObjectPtr = GetNextObjectPtr(currentObjectPtr);
}
return objectList;
}
private uint GetFirstObjectPtr()
{
return m_gameClient.MemoryEditor.ReadUInt(m_gameClient.ObjectManagerPtr + GameClient.FIRST_OBJECT_OFFSET);
}
private uint GetNextObjectPtr(uint CurrentObject)
{
return m_gameClient.MemoryEditor.ReadUInt(CurrentObject + GameClient.NEXT_OBJECT_OFFSET);
}
| 
10-06-2009
| | Corporal | | | Join Date: Jul 2009 Location: Los Angeles, CA
Posts: 27
Reputation: 18 Level up: 54%, 186 Points needed |  | | | If I run both versions whilst stood in Stormwind City, I get 410 objects returned, both with an identical list of addresses. And the Warcraft Radar shows 410 objects around me too. Let me know if I messed up my pointer arithmetic. | 
10-06-2009
|  | Contributor | | | Join Date: May 2007 Location: Dragon Shores
Posts: 690
Reputation: 167 Level up: 28%, 651 Points needed |     | | Quote:
Originally Posted by EmilyStrange
Object Manager Ptr + 0x70 + 0x3C, i.e. Object Manager Ptr + 0xAC is a pointer to the first object | Dang, ofcourse. My assumption was false, no object is skipped.
__________________ “Saying that Java is nice because it works on all OSes is like saying that anal sex is nice because it works on all genders.”
“If Java had true garbage collection, most programs would delete themselves upon execution.” | 
10-06-2009
| | Sergeant Major | | | Join Date: Oct 2008
Posts: 146
Reputation: 12 Level up: 54%, 231 Points needed |  | | | @Emily thanks, new post created
Last edited by Tanaris4; 10-07-2009 at 10:11 AM.
| 
10-06-2009
| | Corporal | | | Join Date: Jul 2009 Location: Los Angeles, CA
Posts: 27
Reputation: 18 Level up: 54%, 186 Points needed |  | | | Not here... I don't believe your question is very applicable to this thread, and neither is the Objective-C code snippet when this thread is clearly about using a C# enumerator?
If you want to move your post to a separate thread, I would be willing to help you there on locating and reading the Object Manager and pointers, but all you have done now is confuse the issue for other people reading this. |  | |
Posting Rules
| You may not post new threads You may not post replies You may not post attachments You may not edit your posts HTML code is Off | | | All times are GMT -4. The time now is 03:18 PM. |