[Question] Object Manager relationships. menu

User Tag List

Results 1 to 3 of 3
  1. #1
    Twarwizard's Avatar Corporal
    Reputation
    40
    Join Date
    Aug 2011
    Posts
    15
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [Question] Object Manager relationships.

    Hi. I am an engineering and comp science student in South Africa and I have been trying to learn about memory reading by using WoW as my first test case.

    In class we use C and Java, so C# is new to me (although very similar to Java)

    I have been reading threads in this section rigorously for the past few days to try and understand how exactly the pointers in the object manager fit together, yet from all the examples and such that I have been able to find I have found some contradicting information, making it difficult to understand exactly how the relationships between the pointers work.

    I made this basic diagram to show my understanding of how it works:
    [Question] Object Manager relationships.-objects-jpg

    To test my understanding I wrote the following basic code (using Blackmagic):
    Code:
        public enum ClientOffsets : uint
        {
            StaticClientConnection = 0x980558,
            ObjectManagerOffset = 0x463C,
            FirstObjectOffset = 0xB4,
            LocalGuidOffset = 0xB8,
            NextObjectOffset = 0x3C,
            LocalTargetGUID = 0xA98C88,
            CurrentContinent = 0x86B620
        }
    
        public enum WowObjectFields : uint
        {
            OBJECT_FIELD_GUID = 0x0,     //4.2
            OBJECT_FIELD_TYPE = 0x10,    //4.2     
            OBJECT_FIELD_ENTRY = 0x14,   //4.2
            OBJECT_FIELD_SCALE_X = 0x18, //4.2
            OBJECT_FIELD_DATA = 0x8,     //4.2
            OBJECT_FIELD_PADDING = 0x1C, //4.2
        }
    
        public enum ObjectOffsets : uint
        {
            Type = 0x10,
            Pos_X = 0x790,
            Pos_Y = Pos_X + 0x4,
            Pos_Z = Pos_X + 0x8,
            Rot = Pos_X + 0x10,
            GameObjectX = 0x110,                //4.2
            GameObjectY = GameObjectX + 0x4,    //4.2
            GameObjectZ = GameObjectX + 0x8    //4.2
        }
    Code:
    using System;
    using Magic;
    
    
    namespace WoW
    {
    
        class MyFirstClass
        {
            static void Main(string[] args)
            {
                BlackMagic wow = new BlackMagic();
                wow.OpenProcessAndThread(SProcess.GetProcessFromProcessName("Wow"));//Getting procces from name Wow
                Console.WriteLine("WoW is hooked now.");
                IntPtr baseWoW = wow.MainModule.BaseAddress;//Gets Base Address
                Console.WriteLine("Base Address = {0}", baseWoW);
    
                uint ClientConnection = wow.ReadUInt((uint)baseWoW + (uint)ClientOffsets.StaticClientConnection);
                uint ObjectManager = wow.ReadUInt(ClientConnection + (uint)ClientOffsets.ObjectManagerOffset);
                uint FirstObject = wow.ReadUInt(ObjectManager + (uint)ClientOffsets.FirstObjectOffset);
                UInt64 LocaltargetGuid = wow.ReadUInt64((uint)baseWoW + (uint)ClientOffsets.LocalTargetGUID);
                UInt64 LocalplayerGuid = wow.ReadUInt64(ObjectManager + (uint)ClientOffsets.LocalGuidOffset);
                
                string player = wow.ReadASCIIString((uint)baseWoW + 0x980598, 20);
                Console.WriteLine("Player name = {0}", player);                        //returns right name (works)
                Console.WriteLine("LocalPlayerGuid = {0}", LocalplayerGuid);    // returns 216172782174585723 
                Console.WriteLine("First Object  = {0}", FirstObject);                 //
    
                UInt64 Objectguid = wow.ReadUInt64(FirstObject, false);
                Console.WriteLine("First Object guid = {0}", Objectguid);
                UInt64 AltObjGuid = wow.ReadUInt64(FirstObject + 0x30, false);
                Console.WriteLine("AltOnjGuid = {0}", AltObjGuid);
                float xpos = wow.ReadFloat(FirstObject + (uint)ObjectOffsets.Pos_X);
                Console.WriteLine("XPos = {0}", xpos);
                float ypos = wow.ReadFloat(FirstObject + (uint)ObjectOffsets.Pos_Y);
                Console.WriteLine("YPos = {0}", ypos);
                float zpos = wow.ReadFloat(FirstObject + (uint)ObjectOffsets.Pos_Z);
                Console.WriteLine("ZPos = {0}", zpos);
    
                short type = wow.ReadShort(FirstObject + (uint)WowObjectFields.OBJECT_FIELD_TYPE);
                Console.WriteLine("Type = {0}", type);                        //returns 0
                short alttype = wow.ReadShort(FirstObject + 0x8 + (uint)WowObjectFields.OBJECT_FIELD_TYPE );
                Console.WriteLine("AltType = {0}", alttype);              //returns -1
                
    
                Console.ReadLine();
    
            }
        }
    }
    My confusion as to how the pointers relate to each other is obvious form the above code. The problem is that in a lot of different example code that I examined the people did different things, but also with different versions of WoW, which made it hard to compare the differences.

    For instance, one example is of a person doing the following (and it working):
    Code:
    private ulong GetObjectGuidByBase(uint Base)
            {
                return WowReader.ReadUInt64((IntPtr)(Base + ObjectOffsets.Guid));
            }
    This code was written for WoW 3.3.5a, and it returns the base of an object based on its GUID. The part that confuses me is that his offset ( ObjectOffsets.Guid ) is 0x30. I went through the 3.3.5a info dump thread and couldn't find such an offset anywhere. This is the reason that I read two Object Guids, thinking that I could see which one was right by trail and error. The other one I just used the base since OBJECT_FIELD_GUID = 0x0, so no use to add that to it.

    Another extract from his source code is this:
    Code:
    LocalTarget.Type = (short)WowReader.ReadUInt32((IntPtr)(LocalTarget.BaseAddress + ObjectOffsets.Type));
    Since he renamed his offsets a bit I assume the offset he refers to is OBJECT_FIELD_TYPE = 0x10.
    Another person randomly added 0x8 to that address to get the type however, which is why I again tried to get both. ( I also searched the info dump thread for what that address could possibly refer to and couldnt find anything)
    I am obviously doing something wrong though as the type I get back is 0 in the one case and -1 in the other.

    I also tried to read the XYZ coordinates, but I know I need to check the type first before that would make sense.

    I know this is a newb question, but I have been searching for days and the fact that I am getting contradicting information combined with different versions of WoW making comparison harder, I thought that the best way to clear up the confusion was to just ask here. So can someone please point out my error? A great start would be just to show me which the right way is to get the type and GUID (I'm sure I'd be able to figure the rest out from there[hopefully!])

    Thanks in Advance.
    Last edited by Twarwizard; 09-19-2011 at 08:18 AM. Reason: code block was wrong

    [Question] Object Manager relationships.
  2. #2
    MaiN's Avatar Elite User
    Reputation
    335
    Join Date
    Sep 2006
    Posts
    1,047
    Thanks G/R
    0/10
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    First off I would like to thank you for your post - it seems like you have done your home work and your post is well formulated. So well done.

    Originally Posted by Twarwizard View Post
    Hi. I am an engineering and comp science student in South Africa and I have been trying to learn about memory reading by using WoW as my first test case.

    In class we use C and Java, so C# is new to me (although very similar to Java)

    I have been reading threads in this section rigorously for the past few days to try and understand how exactly the pointers in the object manager fit together, yet from all the examples and such that I have been able to find I have found some contradicting information, making it difficult to understand exactly how the relationships between the pointers work.

    I made this basic diagram to show my understanding of how it works:
    [Question] Object Manager relationships.-objects-jpg
    That diagram looks correct.
    Originally Posted by Twarwizard View Post
    To test my understanding I wrote the following basic code (using Blackmagic):
    Code:
        public enum ClientOffsets : uint
        {
            StaticClientConnection = 0x980558,
            ObjectManagerOffset = 0x463C,
            FirstObjectOffset = 0xB4,
            LocalGuidOffset = 0xB8,
            NextObjectOffset = 0x3C,
            LocalTargetGUID = 0xA98C88,
            CurrentContinent = 0x86B620
        }
    
        public enum WowObjectFields : uint
        {
            OBJECT_FIELD_GUID = 0x0,     //4.2
            OBJECT_FIELD_TYPE = 0x10,    //4.2     
            OBJECT_FIELD_ENTRY = 0x14,   //4.2
            OBJECT_FIELD_SCALE_X = 0x18, //4.2
            OBJECT_FIELD_DATA = 0x8,     //4.2
            OBJECT_FIELD_PADDING = 0x1C, //4.2
        }
    
        public enum ObjectOffsets : uint
        {
            Type = 0x10,
            Pos_X = 0x790,
            Pos_Y = Pos_X + 0x4,
            Pos_Z = Pos_X + 0x8,
            Rot = Pos_X + 0x10,
            GameObjectX = 0x110,                //4.2
            GameObjectY = GameObjectX + 0x4,    //4.2
            GameObjectZ = GameObjectX + 0x8    //4.2
        }
    Code:
    using System;
    using Magic;
    
    
    namespace WoW
    {
    
        class MyFirstClass
        {
            static void Main(string[] args)
            {
                BlackMagic wow = new BlackMagic();
                wow.OpenProcessAndThread(SProcess.GetProcessFromProcessName("Wow"));//Getting procces from name Wow
                Console.WriteLine("WoW is hooked now.");
                IntPtr baseWoW = wow.MainModule.BaseAddress;//Gets Base Address
                Console.WriteLine("Base Address = {0}", baseWoW);
    
                uint ClientConnection = wow.ReadUInt((uint)baseWoW + (uint)ClientOffsets.StaticClientConnection);
                uint ObjectManager = wow.ReadUInt(ClientConnection + (uint)ClientOffsets.ObjectManagerOffset);
                uint FirstObject = wow.ReadUInt(ObjectManager + (uint)ClientOffsets.FirstObjectOffset);
                UInt64 LocaltargetGuid = wow.ReadUInt64((uint)baseWoW + (uint)ClientOffsets.LocalTargetGUID);
                UInt64 LocalplayerGuid = wow.ReadUInt64(ObjectManager + (uint)ClientOffsets.LocalGuidOffset);
                
                string player = wow.ReadASCIIString((uint)baseWoW + 0x980598, 20);
                Console.WriteLine("Player name = {0}", player);                        //returns right name (works)
                Console.WriteLine("LocalPlayerGuid = {0}", LocalplayerGuid);    // returns 216172782174585723 
                Console.WriteLine("First Object  = {0}", FirstObject);                 //
    
                UInt64 Objectguid = wow.ReadUInt64(FirstObject, false);
                Console.WriteLine("First Object guid = {0}", Objectguid);
                UInt64 AltObjGuid = wow.ReadUInt64(FirstObject + 0x30, false);
                Console.WriteLine("AltOnjGuid = {0}", AltObjGuid);
                float xpos = wow.ReadFloat(FirstObject + (uint)ObjectOffsets.Pos_X);
                Console.WriteLine("XPos = {0}", xpos);
                float ypos = wow.ReadFloat(FirstObject + (uint)ObjectOffsets.Pos_Y);
                Console.WriteLine("YPos = {0}", ypos);
                float zpos = wow.ReadFloat(FirstObject + (uint)ObjectOffsets.Pos_Z);
                Console.WriteLine("ZPos = {0}", zpos);
    
                short type = wow.ReadShort(FirstObject + (uint)WowObjectFields.OBJECT_FIELD_TYPE);
                Console.WriteLine("Type = {0}", type);                        //returns 0
                short alttype = wow.ReadShort(FirstObject + 0x8 + (uint)WowObjectFields.OBJECT_FIELD_TYPE );
                Console.WriteLine("AltType = {0}", alttype);              //returns -1
                
    
                Console.ReadLine();
    
            }
        }
    }
    My confusion as to how the pointers relate to each other is obvious form the above code. The problem is that in a lot of different example code that I examined the people did different things, but also with different versions of WoW, which made it hard to compare the differences.


    For instance, one example is of a person doing the following (and it working):
    Code:
    private ulong GetObjectGuidByBase(uint Base)
            {
                return WowReader.ReadUInt64((IntPtr)(Base + ObjectOffsets.Guid));
            }
    This code was written for WoW 3.3.5a, and it returns the base of an object based on its GUID. The part that confuses me is that his offset ( ObjectOffsets.Guid ) is 0x30. I went through the 3.3.5a info dump thread and couldn't find such an offset anywhere. This is the reason that I read two Object Guids, thinking that I could see which one was right by trail and error. The other one I just used the base since OBJECT_FIELD_GUID = 0x0, so no use to add that to it.
    The code is getting the GUID, from the base, not the base from the GUID (this requires a lookup). The reason for there being two 'GUID' offsets is simple - the GUID is actually stored twice.
    Blizzard have something, which we over the years have come to know as descriptors (or "fields" - I don't know if this name was sniffed from the alpha client or if the name simply caught on - there may even be string refs).
    The purpose of the descriptors is to make it easier for the server to send updates about an object. There are descriptors for all types of objects - objects, units, items, players and so on. It is a classic class hierarchy. The object descriptors contain the GUID of the object. But even though the object descriptors contain this GUID, the GUID is also stored directly in the struct. This is why you see 2 offsets for the GUID - there is the offset into the object descriptors, and the offset directly into the struct. For more information about descriptors, try checking out an emulator like WCell or Mangos.
    WoW objects contain a pointer to their descriptors, and for the base 'object' class, this pointer can be found at +0x8 (which makes the GUID in the descriptors accessible by: [[base+0x8]+OBJECT_FIELD_GUID]).


    Originally Posted by Twarwizard View Post
    Another extract from his source code is this:
    Code:
    LocalTarget.Type = (short)WowReader.ReadUInt32((IntPtr)(LocalTarget.BaseAddress + ObjectOffsets.Type));
    Since he renamed his offsets a bit I assume the offset he refers to is OBJECT_FIELD_TYPE = 0x10.
    Another person randomly added 0x8 to that address to get the type however, which is why I again tried to get both. ( I also searched the info dump thread for what that address could possibly refer to and couldnt find anything)
    I am obviously doing something wrong though as the type I get back is 0 in the one case and -1 in the other.
    Here we are referring to two different types. One of the types (OBJECT_FIELD_TYPE) is a bit field, while the other isn't. The bit field is in the descriptors, while the normal type is directly in the struct.
    As you read above, the descriptors can be accessed at +0x8. So the person who "randomly added 0x8 to that address" was accessing the bit field type. The code you are quoting there is not trying to get the bit field, but getting the type instead -- so ObjectOffsets.Type is not the same as OBJECT_FIELD_TYPE here (they are offsets into two different structs).

    To sum up:
    GUID: [[base+0x8]+0x0] OR [base+0x30]
    Type bit field: [[base+0x8]+0x10]
    Type: [base+?] (can't remember the offset, won't bother to look it up.)
    Last edited by MaiN; 09-19-2011 at 10:40 AM.
    [16:15:41] Cypher: caus the CPU is a dick
    [16:16:07] kynox: CPU is mad
    [16:16:15] Cypher: CPU is all like
    [16:16:16] Cypher: whatever, i do what i want

  3. #3
    Twarwizard's Avatar Corporal
    Reputation
    40
    Join Date
    Aug 2011
    Posts
    15
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ah, It all makes sense now (and works!)
    Thank you very much for the information!

Similar Threads

  1. Object manager question
    By para_ in forum WoW Memory Editing
    Replies: 6
    Last Post: 02-20-2016, 09:53 AM
  2. [Bot] Question: Lazy Bot Object Manager Pointers and Offsets
    By gxavier in forum WoW Memory Editing
    Replies: 1
    Last Post: 07-29-2015, 11:31 AM
  3. [Question] How to use Object Manager
    By Akaike in forum Wildstar Memory Editing
    Replies: 17
    Last Post: 05-16-2014, 09:57 AM
  4. Replies: 9
    Last Post: 04-16-2010, 02:52 PM
  5. [Question] Object Manager
    By hestas in forum WoW Memory Editing
    Replies: 11
    Last Post: 10-31-2009, 02:02 PM
All times are GMT -5. The time now is 05:42 PM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search