[C#] A Memory Enumerator for Walking The Objects menu

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 15 of 17
  1. #1
    EmilyStrange's Avatar Active Member
    Reputation
    34
    Join Date
    Jul 2009
    Posts
    125
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [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.

    [C#] A Memory Enumerator for Walking The Objects
  2. #2
    Neverhaven's Avatar Member
    Reputation
    12
    Join Date
    Sep 2009
    Posts
    25
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    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 +Rep

  3. #3
    namelessgnome's Avatar Contributor
    Reputation
    108
    Join Date
    May 2007
    Posts
    263
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    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.

  4. #4
    Hyru's Avatar Active Member
    Reputation
    39
    Join Date
    Jun 2008
    Posts
    39
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Neverhaven View Post
    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 +Rep
    Don't forget LINQ:

    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);

  5. #5
    Neverhaven's Avatar Member
    Reputation
    12
    Join Date
    Sep 2009
    Posts
    25
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That reminds me, I still need to learn some more about lambda operators.

  6. #6
    Shutzler's Avatar Member
    Reputation
    3
    Join Date
    Sep 2009
    Posts
    48
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    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).

  7. #7
    Robske's Avatar Contributor
    Reputation
    305
    Join Date
    May 2007
    Posts
    1,062
    Thanks G/R
    3/4
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Shutzler View Post
    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?


    Originally Posted by Shutzler View Post
    Could you paste WowObject structure? (the whole thingy, what do you grab and so).

    Why not ask for the entire folder instead?
    "Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." - Martin Golding
    "I cried a little earlier when I had to poop" - Sku

  8. #8
    Shutzler's Avatar Member
    Reputation
    3
    Join Date
    Sep 2009
    Posts
    48
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Robske View Post

    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 ++

  9. #9
    Ellesar1's Avatar Member
    Reputation
    20
    Join Date
    Feb 2009
    Posts
    78
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    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.

    +Rep 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. #10
    Robske's Avatar Contributor
    Reputation
    305
    Join Date
    May 2007
    Posts
    1,062
    Thanks G/R
    3/4
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Ellesar1 View Post
    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.

    +Rep 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)
    "Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." - Martin Golding
    "I cried a little earlier when I had to poop" - Sku

  11. #11
    EmilyStrange's Avatar Active Member
    Reputation
    34
    Join Date
    Jul 2009
    Posts
    125
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    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);
            }

  12. #12
    EmilyStrange's Avatar Active Member
    Reputation
    34
    Join Date
    Jul 2009
    Posts
    125
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    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.

  13. #13
    Robske's Avatar Contributor
    Reputation
    305
    Join Date
    May 2007
    Posts
    1,062
    Thanks G/R
    3/4
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by EmilyStrange View Post

    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.
    "Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." - Martin Golding
    "I cried a little earlier when I had to poop" - Sku

  14. #14
    Tanaris4's Avatar Contributor Authenticator enabled
    Reputation
    148
    Join Date
    Oct 2008
    Posts
    646
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    @Emily thanks, new post created
    Last edited by Tanaris4; 10-07-2009 at 08:11 AM.

  15. #15
    EmilyStrange's Avatar Active Member
    Reputation
    34
    Join Date
    Jul 2009
    Posts
    125
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    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.

Page 1 of 2 12 LastLast

Similar Threads

  1. Got banned for using the swzx swzx ESP aimbot memory hack
    By themegamaster in forum Overwatch Exploits|Hacks
    Replies: 18
    Last Post: 03-10-2019, 06:41 PM
  2. Replies: 5
    Last Post: 06-17-2015, 07:19 AM
  3. Finding the memory area for Resolution for Flawless Widescreen
    By quaddragon in forum Diablo 3 Memory Editing
    Replies: 1
    Last Post: 09-08-2014, 04:09 AM
  4. Is adt/v23 the correct structure for Cataclysm terrain/object data?
    By hoobiedoobie in forum WoW ME Questions and Requests
    Replies: 8
    Last Post: 12-26-2010, 02:53 PM
  5. Prepping for Vaelastrasz the easy way
    By Matt in forum World of Warcraft Guides
    Replies: 0
    Last Post: 04-01-2006, 10:11 AM
All times are GMT -5. The time now is 09:27 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search