# Forum > World of Warcraft > World of Warcraft Bots and Programs > WoW Memory Editing >  [Guide-kind of] How I handle objects.

## jbrauman

I've got a bit of time up my sleeve so I thought I would post an (intermediate) guide to the way that I get data from the object manager, to give back to the community a little. The code in this guide is written in C# but it shouldn't be too hard to port to any other OOP language. Note that you should already know how to retrieve data out of the object manager. The thing I use to read memory is a library that I don't know the author of (If you are the author, tell me!) Also note that I say things such as 'all object have an XYZ value' - this is not true. For example, items and containers do not. But in this guide we're only going to be dealing with in-game objects.


If you take a sit back and think about it, what is the Object Manager (from now on referred to as OM) in Wow? In the broadest terms possible, it is an object that handles other objects. We know that once we have the base address of an WowObject (the object that the OM handles), we can get different information about it depending on the type of object it is. 

So it makes sense then, to build one object to handle WowObjects, and then build the WowObjects themselves. Lets jot down some information here:
- Our OM needs a way to 'load' and find the base address of the in-game Object Manager.
- Our OM needs to iterate through the in-game Object Manager and get two peices of information about each object - the base address, and the type. Using this information, we can create a new "WowObject" and store it.
- Our OM needs to be able to store all the objects (arrays of WowObjects anyone?)
- Our WowObjects, given a base address and type, need to be able to get information about themselves and return it to whoever is asking, on the fly.

WowObjects

The first thing that I started out with was the WowObjects themselves. As you (should) know, the objects in the in-game Object Manager can be of seven different types:


```
1 -Items
2 - Contains
3 - NPC's
4 - Players
5 - GameObjects (Nodes etc)
6 - DynamicObjects (Spells and stuff)
7 - Corpses
```

In this guide, we're only going to deal with 3 through 7.

What you may not know, however is that each object has attributes that are common to 'all' objects. Note that XYZ isn't common to 'all', but in this guide we're only dealing with actual in-game objects (instead of items etc). Things that are common between all of these in-game objects are:
- A GUID (Globally Unique Id)
- A base address
- A type
- An X,Y,Z position
- A rotation value
- Descriptor fields
There are actually more but these are all we are interested in for now. So if we have things in common, wouldn't it make sense to make a base class that all the other objects inherit from? I give you (very creatively named): *WowObject*



```
class WowObject
    {
        protected const uint GuidOffset = 0x30,
            NextObjectOffset = 0x3C,
            TypeOffset = 0x14,
            XPositionOffset = 0x7D0,
            YPositionOffset = 0x7D4,
            ZPositionOffset = 0x7D8,
            RotationOffset = 0x7DC,
            DescriptorFieldsOffset = 0x8;
        protected uint baseAddress;
        public WowObject(uint baseAddress)
        {
            this.baseAddress = baseAddress;
        }
        public uint BaseAddress
        {
            get { return baseAddress; }
            set { baseAddress = value; }
        }
        public uint DescriptorFields
        {
            get { return ObjectManager.WowReader.ReadUInt32((IntPtr)(BaseAddress + DescriptorFieldsOffset)); }
        }
        public int Type
        {
            get { return ObjectManager.WowReader.ReadInt32((IntPtr)(BaseAddress + TypeOffset)); }
        }
        public virtual ulong Guid
        {
            get { return ObjectManager.WowReader.ReadULong((IntPtr)(BaseAddress + GuidOffset)); }
            set { return; }
        }
        public virtual float XPosition
        {
            get { return ObjectManager.WowReader.ReadFloat((IntPtr)(BaseAddress + XPositionOffset)); }
        }
        public virtual float YPosition
        {
            get { return ObjectManager.WowReader.ReadFloat((IntPtr)(BaseAddress + YPositionOffset)); }
        }
        public virtual float ZPosition
        {
            get { return ObjectManager.WowReader.ReadFloat((IntPtr)(BaseAddress + ZPositionOffset)); }
        }
        public float Rotation
        {
            get { return ObjectManager.WowReader.ReadFloat((IntPtr)(BaseAddress + RotationOffset)); }
        }
    }
```

You'll notice that, providing only the base address to this class, we are able to get some interesting information. Now we can do some really nifty stuff! For example, say in another part of our project we created a WowObject with the name *George.* If we want to know George's X position, all we'd have to write (assuming that George already knows his base address) is this:



```
MessageBox.Show(George.XPosition.ToString());
```

George already knows how to get his XPosition, so he scrambles off and gets it and returns it to us whenever we need it!

Note that the in-game Object Manager does not actually hold any of these types of objects. It holds more specific objects. It can be thought about in an OOP way like this:



```
WowObject[] ObjectList = new WowObject[5];
ObjectList[0] = new NpcObject();
ObjectList[1] = new GameObject();
// and so on
```

Speaking of more specific objects, our WowObject class isn't going to be useful on its own, since no object in our OM's array is going to be a plain old WowObject! We need it to hold more specific objects. What is the best way to describe this in an OOP language? _Subclasses that inherit._ Therefore, I'll give you the rest of our WowObject (and subclasses) declarations:



```
class CreatureObject : WowObject
    {
        protected const uint LevelOffset = 0x35 * 4,
            CurrentHealthOffset = 0x17 * 4,
            MaxHealthOffset = 0x1F * 4,
            CurrentManaOffset = 0x18 * 4,
            MaxManaOffset = 0x20 * 4,
            TargetGuidOffset = 0x12 * 4;
        public CreatureObject(uint BaseAddress)
            : base(BaseAddress)
        { }
        public float Pitch
        {
            get { return ObjectManager.WowReader.ReadFloat((IntPtr)(ObjectManager.WowReader.ReadUInt32((IntPtr)(baseAddress + 0x110)) + 0x20)); }
        }
        public ulong TargetGuid
        {
            get { return ObjectManager.WowReader.ReadULong((IntPtr)(DescriptorFields + TargetGuidOffset)); }
        }
        public int Level
        {
            get { return ObjectManager.WowReader.ReadInt32((IntPtr)(DescriptorFields + LevelOffset)); }
        }
        public int CurrentHealth
        {
            get { return ObjectManager.WowReader.ReadInt32((IntPtr)(DescriptorFields + CurrentHealthOffset)); }
        }
        public int MaxHealth
        {
            get { return ObjectManager.WowReader.ReadInt32((IntPtr)(DescriptorFields + MaxHealthOffset)); }
        }
        public int CurrentMana
        {
            get { return ObjectManager.WowReader.ReadInt32((IntPtr)(DescriptorFields + CurrentMana)); }
        }
        public int MaxMana
        {
            get { return ObjectManager.WowReader.ReadInt32((IntPtr)(DescriptorFields + MaxManaOffset)); }
        }
        public int HealthPercent
        {
            get
            {
                double percentage = CurrentHealth / MaxHealth;
                percentage = percentage * 100;
                return (int)Math.Round(percentage);
            }
        }
    }
    class NpcObject : CreatureObject
    {
        protected const uint SummonedByOffset = 0xE * 4,
            AttackingGuidOffset = 0x0A38;
        public NpcObject(uint BaseAddress)
            : base(BaseAddress)
        { }
        public string Name
        {
            get { return ObjectManager.WowReader.ReadString((IntPtr)(ObjectManager.WowReader.ReadUInt32((IntPtr)(ObjectManager.WowReader.ReadUInt32((IntPtr)(baseAddress + 0x9B0)) + 0x3C)))); }
        }
        public ulong AttackingGuid
        {
            get { return ObjectManager.WowReader.ReadULong((IntPtr)(BaseAddress + AttackingGuidOffset)); }
        }
        public ulong SummonedBy
        {
            get { return ObjectManager.WowReader.ReadULong((IntPtr)(DescriptorFields + SummonedByOffset)); }
        }
        public int GetAggroRadius(CreatureObject LocalPlayer)
        {
            // if they are the same level as us, the aggro radius is roughly 20 yards
            int AggroRadius = 20;
            // aggro radius varies with level difference at a rate of roughly 1 yard/level
            if (LocalPlayer.Level > Level)
                AggroRadius -= (int)BotControl.DifferenceBetween(LocalPlayer.Level, Level);
            if (LocalPlayer.Level < Level)
                AggroRadius += (int)BotControl.DifferenceBetween(LocalPlayer.Level, Level);
            if (AggroRadius < 5)
                AggroRadius = 5;
            AggroRadius += 3; // give us a bit of leeway
            return AggroRadius;
        }
    }
    class PlayerObject : CreatureObject
    {
        protected const uint CurrentRageOffset = 0x19 * 4,
            CurrentEnergyOffset = 0x1B * 4,
            MaxEnergyOffset = 0x23 * 4;
        public PlayerObject(uint BaseAddress)
            : base(BaseAddress)
        { }
        public int CurrentRage
        {
            get
            {
                int RageTemp = ObjectManager.WowReader.ReadInt32((IntPtr)(DescriptorFields + CurrentRageOffset));
                return (int)(Math.Floor((double)(RageTemp / 10)));
            }
        }
        public int MaxRage
        {
            get { return 100; }
        }
        public int CurrentEnergy
        {
            get { return ObjectManager.WowReader.ReadInt32((IntPtr)(DescriptorFields + CurrentEnergyOffset)); }
        }
        public int MaxEnergy
        {
            get { return ObjectManager.WowReader.ReadInt32((IntPtr)(DescriptorFields + MaxEnergyOffset)); }
        }
    }
    class GameObject : WowObject
    {
        protected const uint gameObject_XPosition = 0x10 * 4,
            gameObject_YPosition = 0x11 * 4,
            gameObject_ZPosition = 0x12 * 4,
            displayId = 0x8 * 4;
        public GameObject(uint BaseAddress)
            : base(BaseAddress)
        { }
        public string Print()
        {
            return "Name: " + Name + " X: " + XPosition.ToString() + " Y: " + YPosition.ToString() + " Z: " + ZPosition.ToString();
        }
        public string Name
        {
            get
            {
                return ObjectManager.WowReader.ReadString((IntPtr)(ObjectManager.WowReader.ReadUInt32((IntPtr)(baseAddress + 0x1f4)) + 0x078));
            }
        }
        public override float XPosition
        {
            get { return ObjectManager.WowReader.ReadFloat((IntPtr)(DescriptorFields + gameObject_XPosition)); }
        }
        public override float YPosition
        {
            get { return ObjectManager.WowReader.ReadFloat((IntPtr)(DescriptorFields + gameObject_YPosition)); }
        }
        public override float ZPosition
        {
            get { return ObjectManager.WowReader.ReadFloat((IntPtr)(DescriptorFields + gameObject_ZPosition)); }
        }
        public int DisplayId
        {
            get { return ObjectManager.WowReader.ReadInt32((IntPtr)(DescriptorFields + displayId)); }
        }
    }
    class DynamicObject : WowObject
    {
        protected const uint dynamicObject_XPosition = 0xB * 4,
            dynamicObject_YPosition = 0xC * 4,
            dynamicObject_ZPosition = 0xD * 4;
        public DynamicObject(uint BaseAddress)
            : base(BaseAddress)
        { }
        public override float XPosition
        {
            get { return ObjectManager.WowReader.ReadFloat((IntPtr)(DescriptorFields + dynamicObject_XPosition)); }
        }
        public override float YPosition
        {
            get { return ObjectManager.WowReader.ReadFloat((IntPtr)(DescriptorFields + dynamicObject_YPosition)); }
        }
        public override float ZPosition
        {
            get { return ObjectManager.WowReader.ReadFloat((IntPtr)(DescriptorFields + dynamicObject_ZPosition)); }
        }
    }
    class CorpseObject : WowObject
    {
        protected const uint corpseObject_XPosition = 0xB * 4,
                corpseObject_YPosition = 0xC * 4,
                corpseObject_ZPosition = 0xD * 4;
        public CorpseObject(uint BaseAddress)
            : base(BaseAddress)
        { }
        public override float XPosition
        {
            get { return ObjectManager.WowReader.ReadFloat((IntPtr)(DescriptorFields + corpseObject_XPosition)); }
        }
        public override float YPosition
        {
            get { return ObjectManager.WowReader.ReadFloat((IntPtr)(DescriptorFields + corpseObject_YPosition)); }
        }
        public override float ZPosition
        {
            get { return ObjectManager.WowReader.ReadFloat((IntPtr)(DescriptorFields + corpseObject_ZPosition)); }
        }
    }
```

Hopefully you can understand what is going on in the above code. Two things to note however. The first and simplest: in the GameObject, DynamicObject and CorpseObject classes, *the X,Y,Z are retrieved in a different way.* Therefore, we _override_ the XYZ properties and retrieve them how they should be retrieved.

Secondly, if you were thinking about concept of object inheritance in realation to our OM for the first time, this would be an appropriate diagram to draw:


However, upon closer inspection of the descriptors, there are attributes that both NpcObject and PlayerObject both have, and they are obtained in exactly the same way (for example, health is obtained from UnitFields+HealthOffset). Why dont we make a base class for both of these two that incorporate this 'sameness'. _Note: this class will never actually be used. An in game object can be a NpcObject, or a PlayerObject, which both inherit things from CreatureObject, however you can never be just a CreatureObject._

Here is our updated diagram:


Note that the code provided above already has these changes. Now if we have an NpcObject named *John*, we can write code like this:



```
MessageBox.Show("Johns health is: "+John.CurrentHealth.ToString());
```

And Johns health would automatically be read and returned to us.

Object Manager

Now that we have the objects that we will be using downpat, lets look again at what our OM needs to do:




> - Our OM needs a way to 'load' and find the base address of the in-game Object Manager.
> - Our OM needs to iterate through the in-game Object Manager and get two peices of information about each object - the base address, and the type. Using this information, we can create a new "WowObject" and store it.
> - Our OM needs to be able to store all the objects (arrays of WowObjects anyone?)


Before we start doing some coding, we need to think about who will be using this class. Do we need more than one of these OM's? It depends. Are we going to be getting information from multiple copies of WoW? In most cases, we're only going to be worrying about one copy of WoW at a time. Instead of having to make new copies of our OM, lets make it *static*. Thefore, instead of using this code:



```
ObjectManager myObjectManager = new ObjectManager();
myObjectManager.DoSomething();
```

We're able to just do this:


```
ObjectManager.DoSomething();
```

If you look in the above code for the WowObjects, they are getting ObjectManager.WowReader to do something. What is WowReader? In this project, I decided the only memory reading I was going to need to do was to enumerate through the linked list of objects and pull data about them. So it seems reasonable then to include another object, a _memory reading object_ inside of our Object Manager. I can't remember where I found this MemoryReader .dll, or whom the author is unfortunately. 
Edit: Seem's I have been using alek900's (perhaps private) memory reading dll by accident. But you should be able to apply the concepts to any decent memory reading class.

So far, this is what our ObjectManager class looks like:


```
static class ObjectManager
{
public static Memory WowReader = new Memory();}
```

Now, whenever we're doing any work with the in-game Object Manager, we need to find it's address. Granted, this isn't hard, but it is worth having a method for. Also, we need a place to _store_ the base address of the in-game Object Manager, as well, and also have some meaningful constants that represent what addresses we're going to be working with.



```
static class ObjectManager
{
public static Memory WowReader = new Memory();
 
private const uint staticClientConnection = 0x011CB310, // client connection, same address every boot
objectManagerOffset = 0x28A4,                                  // offset from the ClientConnection to the object manager
localGuidOffset = 0xC0,                                             // offset from the object manager to the local guid
firstObjectOffset = 0xAC,                                          // offset from the object manager to the first object
nextObjectOffset = 0x3C;                                          // offset from one object to the next
static private uint objectManagerBase;                       // the address off the object manager
static private ulong localGuid;                                   // the local guid.
 
public static void LoadAddresses()
{
WowReader.SetProcess("Wow", "read");
objectManagerBase = WowReader.ReadUInt32((IntPtr)(WowReader.ReadUInt32((IntPtr)(staticClientConnection)) + objectManagerOffset));
localGuid = WowReader.ReadUInt32((IntPtr)(objectManagerBase + localGuidOffset));}}
```

I'll just quickly describe the method that we've added. It is the job of *LoadAddresses* to find out the base address of the object manager, and our local players guid. The first line lets our memory reading class know that we will be reading from WoW.exe.

But why did we get our local players Guid? Can't we simply access it through our WowObjects properties (SomeObject.Guid)? We most certainly could do that, and that would work to get the guid of any object. But how do we know which object is ourselves? Say we load a list of 10 objects into an imaginary array. The only details about these objects that we know are the base address and type.



```
WowObject[] ImaginaryArray = new WowObject[9];
ImaginaryArray.ImaginaryFill();
```

Now that we've put that information in there, we can get the guid of any object. But how do we know which object is ourselves, just by our guid? That is why we retrieve our players guid _beforehand_. Basically, _by storing our local guid before hand, we have a way to single out the object that references our local player in-game._

No doubt that the object whose information we want to know most is the local player. Lets add in an easy way to access information about our local player. Just before LoadAddresses(), put this in:



```
public static PlayerObject LocalPlayer;
```

Soon, we will able to access information about the local player from any part of our code, eg: ObjectManager.LocalPlayer.CurrentHealth;

Now we need a way to store our objects. We're going to store all of our objects in different *IDictionary*'s, one dictionary for each type of object we will be dealing with. We _could_ have stored them all in one array of WowObjects, but then we would need to deal with complicated issues of downcasting.

_But what is an IDictionary?_ An IDictionary is basically an easy to use array. When declaring the IDictionary, you give it two values: the key for accessing, and the value it will hold. The keys for an IDictionary need to be unique, so we're going to use our WowObjects Guid's, and the values are going to be the WowObjects themselves. Just under "public static PlayerObject LocalPlayer", add this:



```
public static IDictionary<ulong, PlayerObject> PlayerObjectList = new Dictionary<ulong, PlayerObject>();
public static IDictionary<ulong, NpcObject> NpcObjectList = new Dictionary<ulong, NpcObject>();
public static IDictionary<ulong, GameObject> GameObjectList = new Dictionary<ulong, GameObject>();
```

Of course, you can add an IDictionary for the missing objects yourself. Now pretend for a moment our IDictionary's were full of objects. We had the guid of a creature who was attacking us, and we wanted to find out its health. How would we do that? By the magic of IDictionarys!



```
ulong AttackingMonsterGuid = GetAttackingMonsterGuid();
int MonsterHealth = ObjectManager.NpcObjectList[AttackingMonsterGuid].CurrentHealth;
```

This is all fine and dandy, but we don't have any data to work with at the moment, all we have are empty IDictionarys. We need a way to populate our lists, and we should be able to do this whenever we want. Lets add a new method to our OM - *PopulateLists*



```
public static void PopulateLists()
{
 
}
```

To start off we want to clear out all of our current lists - if we don't, we're going to end up with multiple copies of each object.



```
PlayerObjectList.Clear();
NpcObjectList.Clear();
GameObjectList.Clear();
```

To iterate through the object list, we're going to need somewhere to store the data we need (base address and type) before we actually make a new object. Lets make a generic WowObject to handle this. We also know the base address of the first object in the in-game Object Manager, so thats where we will start reading from.



```
WowObject CurrentObject = new WowObject(WowReader.ReadUInt32((IntPtr)(objectManagerBase + firstObjectOffset)));
```

Now we're going to loop through the in-game Object Manager from first object to last, so lets open a while loop. It should look something like this: _while the object we're reading from is a valid object, read the base address and the type of the object, then add a new object to the list that corrosponds to the obejects type, giving it a base address._ Doesn't seem too hard. Thus I give you:



```
public static void PopulateLists()
{
    PlayerObjectList.Clear();
    NpcObjectList.Clear();
    GameObjectList.Clear();
 
    WowObject CurrentObject = new WowObject(WowReader.ReadUInt32((IntPtr)(objectManagerBase + firstObjectOffset)));
 
    while (CurrentObject.BaseAddress != 0 && CurrentObject.BaseAddress % 2 == 0)
    {
        if (CurrentObject.Type == 3)  // a npc
            NpcObjectList.Add(CurrentObject.Guid, new NpcObject(CurrentObject.BaseAddress);
        if (CurrentObject.Type == 4) // a player
            PlayerObjectList.Add(CurrentObject.Guid, new PlayerObject(CurrentObject.BaseAddress);
        if (CurrentObject.Type == 5) // a gameobject
            GameObjectList.Add(CurrentObject.Guid, new GameObject(CurrentObject.BaseAddress);
 
        CurrentObject.BaseAddress = WowReader.ReadUInt32((IntPtr)(CurrentObject.BaseAddress + nextObjectOffset));
    }
}
```

What the last line does is it changes the base address of CurrentObject to the base address of the next object in the list (effectively setting CurrentObject to equal the next object).

A final thing...
The most commonly accessed object in our OM is going to be the local player (to see our current health, our position, etc). We can now access the local player from any of our code doing this (assuming you have called PopulateLists() beforehand:



```
int OurHealth = ObjectManager.PlayerObjectList[ObjectManager.localGuid].CurrentHealth;
```

However, lets add a a little extra goody to make our code easier to read, and easier to type. In our ObjectManager class, add this line up the top somewhere near the declarations:



```
public static PlayerObject LocalPlayer;
```

Change this line in PopulateLists():



```
if (CurrentObject.Type == 4) // a player
    PlayerObjectList.Add(CurrentObject.Guid, new PlayerObject(CurrentObject.BaseAddress);
```

to this:



```
if (CurrentObject.Type == 4) { // a player
    PlayerObjectList.Add(CurrentObject.Guid, new PlayerObject(CurrentObject.BaseAddress);
    if (CurrentObject.Guid == localGuid) // it is the local player
        LocalPlayer = PlayerObjectList[localGuid];
}
```

And you should be good to go! Happy hacking (or memory reading, enumerating, being nerdy, etc.) :wave:

----------


## SKU

I hope my post isn't somehow destroying your well structured guide. Feel free to contact a mod to have this post deleted. This is going to be a very helpful look-up thread. +2rep 'cause I can.

----------


## Pixion

Thanks to you.  :Smile:

----------


## naa

Nice guide, thank you +Rep

----------


## jbrauman

> Why do you have "Object" at the end of all your classes? Just because they are objects in WoW doesn't mean your naming convention has to suffer.


This is just how I do it. Makes it clearer for me, other people can do it any way they want. Each to thier own. I'm using code that is actually in my projects, and that was the way I did it.

----------


## jbrauman

Finished the guide. Tell us if there are any mistakes.

----------


## Robske

It's a matter of opinion, but I prefer to use the static pointer to the playerbase instead of looping through the object manager for it. 3 reads are faster than (num objects)*(2) (worst case scenario)

----------


## RiseAndShine

Yeah nice write-up! Reminded me that i'll desperately needed to refactor my code. I've been throwing everything in one big LinkedList, with every object being the same class. :> So now after not being able to successfully compile this mess for some hours, i got nice inheritance and HashTables, too! yay.
Although I prefer to pre-read all fields of an object in a threaded loop, rather than reading them as you request them.

----------


## jbrauman

> Although I prefer to pre-read all fields of an object in a threaded loop, rather than reading them as you request them.


This is what I was doing at first - but I found it was entirely unnecessary. You don't need ALL the information on ALL the objects at once - and reading so much from Wow, ALL the time, creates alot of in-game lag and unnecessary reading.

----------


## g3gg0

some additional code to creatureobject  :Wink: 



```
    protected const int BuffCountOffset = 0xC58;
    protected const int BuffTypeOffset = 0xDE0;
    protected const int BuffTableOffset = 0xDE4;
    protected const int BuffBaseOffset = 0xC5C;
    protected const int BuffEntrySize = 24;

    public UnitBuffInfo GetUnitBuffInfo( int pos )
    {
        UnitBuffInfo result = null;
        int addr = 0;

        if (pos >= GetUnitBuffCount())
            return result;
        else
        {
            if (WoW.ReadInteger(baseAddress + BuffTypeOffset) != 0)
                addr = WoW.ReadInteger(baseAddress + BuffTableOffset);
            else
                addr = baseAddress + BuffBaseOffset;
        }

        return new UnitBuffInfo(WoW, addr + BuffEntrySize * pos);
    }

    public UnitBuffInfo[] GetUnitBuffInfo() /* didnt test since thats too expensive */
    {
        UnitBuffInfo[] result = null;
        int addr = 0;
        int entries = GetUnitBuffCount();

        result = new UnitBuffInfo[entries];

        if (WoW.ReadInteger(baseAddress + BuffTypeOffset) != 0)
            addr = WoW.ReadInteger(baseAddress + BuffTableOffset);
        else
            addr = baseAddress + BuffBaseOffset;

        for (int pos = 0; pos < entries; pos++)
            result[pos] = new UnitBuffInfo(WoW, addr + BuffEntrySize * pos);

        return result;
    }

    public int GetUnitBuffCount()
    {
        return WoW.ReadInteger(baseAddress + BuffCountOffset);
    }
```

----------


## bugs181

I know this guide is for learning purposes. But could I perhaps request you upload demo source code? By the way, great tut/guide!! +Rep

----------


## SKU

The entire source code is in the [.code] brackets.

----------


## alek900

wow, I need to rewrite some of stuff now :P

also,


```
int Aggro_Range= 17 - (Playerlvl - Creaturelvl);
if (Aggro_Range > 45)
     Aggro_Range = 45;
else if (Aggro_Range < 5)
     Aggro_Range = 5;
```

----------


## bugs181

WOW! Dumb me.. I was requesting the source code because I didn't fully understand how this all fit together. After reading it, then re-reading it, and about 5 re-reads later, I understand it.

It could be the fact that I don't understand the C# syntax all the much.
I'm more of a C++ person. Yes, the two are similar, but their both different in various ways.

However, I am finally grasping the concept to all this, mostly due to putting this together
AND Kynox’s WoW Object Dumper source code together.

You can then see the differences, and how it all comes together.
The most confusing for me to understand was how the WoW reader was reading from memory. 

Anyways, sorry for the ramble. Definitely a great guide - keep up the amazing work.
+Rep from me, sorry for the stupid request earlier.

-Bugz

----------


## jbrauman

> WOW! Dumb me.. I was requesting the source code because I didn't fully understand how this all fit together. After reading it, then re-reading it, and about 5 re-reads later, I understand it.
> 
> It could be the fact that I don't understand the C# syntax all the much.
> I'm more of a C++ person. Yes, the two are similar, but their both different in various ways.
> 
> However, I am finally grasping the concept to all this, mostly due to putting this together
> AND Kynox’s WoW Object Dumper source code together.
> 
> You can then see the differences, and how it all comes together.
> ...


It took me a long time to understand how to do it as well, but once you get your head around the idea its easier. Just updated the static client connection offset to the 3.0.9 one

----------


## doggy99

could some one plzz tell me how to add spells to objects i was able to like 2 mounths ago now i cant. i had the option of adding a spell but now there isent one plzz help me  :Smile:

----------


## SKU

```
class MyObject
{
    public MyObject()
    {

    }

    ~MyObject()
    {

    }

    public void CastFireball()
    {
        WoWLua.DoString("CastSpellByName(\"Fireball\")");
    }
}
```

Or you could post the code that's not working.

----------


## TaskMarster

WoW! Great guide, +rep. Thank you for taking the time and effort to make this available. This was exactly what I needed to get started with memory editing. Thanks again!

----------


## ajox86

Tnx alot man!
This was exactly what i needed to start messing around with wow. I will probebly rewrite the ++ parts to plain C with structures. I never got around to learn ++  :Frown: 
Tnx again, looking forward to more of your guides.

----------


## Robske

> Tnx alot man!
> This was exactly what i needed to start messing around with wow. I will probebly rewrite the ++ parts to plain C with structures. I never got around to learn ++ 
> Tnx again, looking forward to more of your guides.


C++ parts? Where?

----------


## Therrm

Awesome post !!! +rep

----------


## Aryan

Thanks, your post inspired me start WoW hacking again after a few months break. The first thing I decided to do was convert my out of process OM from an exe to a dll because thats where I was before I 'quit' and I'm having lots of fun. Great post.

----------


## bouh2

Thanks, good post !

I have a problem : I have player guid and player base adress but CurrentObject.XPosition doesn't work.
How have position of player object ?

Sry for my very bad english i'm french.

Edit : Ok i'm stupid, now that's work ><

----------


## luthien23

I just started today messing with reading WoW memory and this has been a very useful thread. Thanks a lot.
I've managed to get the objects from the linked list that object manager is. And I've managed to read the name for object types 5. But I'm struggling with NPCs (type 3).

I understand this is the relevant code :


```
    class NpcObject : CreatureObject
    {
        protected const uint SummonedByOffset = 0xE * 4,
            AttackingGuidOffset = 0x0A38;
        public NpcObject(uint BaseAddress)
            : base(BaseAddress)
        { }
        public string Name
        {
            get { return ObjectManager.WowReader.ReadString((IntPtr)(ObjectManager.WowReader.ReadUInt32((IntPtr)(ObjectManager.WowReader.ReadUInt32((IntPtr)(baseAddress + 0x9B0)) + 0x3C)))); }
        }
```

So let's say I have a type 3 object in curObject. The pointer to the first char in the string holding the name of that npc would be :
[ [curObject + 0x9B0] + 0x3C ]
I'm I right? :confused:

Also characters are in ASCII I guess, since that it's what they seem to be in for Type 5 objects...

----------


## SKU

pName = [[UnitBaseAddress + 0x970] + 0x3C] // 3.0.9

----------


## masho

UAU! That's an amazing guide! for the first time i was able to get some data from reading wow's memory! many thanks jbrauman.

I am trying to get the current spell that the player is casting, and the casttime of it, can someone point me to a descriptor?

----------


## RobinLD

Really helpful guide. Thanks mate.

Robin.

----------


## miceiken

Thanks alot!

----------


## YetiHunter

Wow! thanks alot. thats exactly what i needed!

----------


## notme13

Have any of the mentioned offsets changed since 3.1.1 was released, i can't seem to find X, Y, Z position offsets anywhere but here.

Thanks.

----------


## Shynd

You need to read some more of the threads in this forum, then.

----------


## opulent

I used this guide to get started and I found it extremely helpful. I translated some of it into C++ (albeit very poorly) and I'm pasting it here jic someone would like to toy around with it.

All credit goes to the OP - Jbrauman. Offsets are for 3.0.9

C++ Code for ObjectManager:


```
class oManager
{
public:
    oManager()
    {
        Memory::AddDebugPrivileges(); //Required as no instance of the class has been made.
        LoadAddresses();
    }

    void LoadAddresses()
    {
        DWORD  clientConnection = Memory::Read<DWORD>(0x11CB310); //Get Client Connection:
        objectManagerBase = Memory::Read<DWORD>(clientConnection + 0x28A4);
        localGuid = Memory::Read<INT64>(objectManagerBase + 0xC0); //Object manager base + localGUID offset
    }


    list<oNpc> oNpcList;
    list<oGame> oGameList;
    list<oPlayer> oPlayerList;


    void PopulateLists()
    {
        oNpcList.erase(oNpcList.begin(), oNpcList.end());
        oGameList.erase(oGameList.begin(), oGameList.end());
        oPlayerList.erase(oPlayerList.begin(), oPlayerList.end());

        WowObject CurrentObject = WowObject(Memory::Read<DWORD>(objectManagerBase + firstObjectOffset));

        while (CurrentObject.baseAddress != 0 && CurrentObject.baseAddress % 2 == 0)
        {
            if (CurrentObject.GetType() == 3)  // a npc
                oNpcList.push_back(oNpc(CurrentObject.baseAddress));
            if (CurrentObject.GetType() == 4) // a player
                oPlayerList.push_back(oPlayer(CurrentObject.baseAddress));
            if (CurrentObject.GetType() == 5) // a gameobject
                oGameList.push_back(oGame(CurrentObject.baseAddress));

            DWORD CurrentBase = CurrentObject.baseAddress;
            CurrentObject = WowObject(Memory::Read<DWORD>(CurrentBase + nextObjectOffset));
        }
    }

    void populatePlayer()
    {
        //DWORD constPlayerBase = Memory::Read<DWORD>(Memory::Read<DWORD>(Memory::Read<DWORD>(0x127F13C) + 0x30) + 0x28);
        DWORD oFirst = Memory::Read<DWORD>(objectManagerBase + firstObjectOffset);
        DWORD oThis = oFirst;
        INT64 oGuid = NULL;
        while (oGuid != localGuid)
        {
            oGuid = Memory::Read<INT64>(oThis + 0x30);
            if (oGuid == localGuid)
            {
                //This is where your player will be!!
            }
            oFirst = oThis;
            oThis = Memory::Read<DWORD>(oFirst + nextObjectOffset);
        }
    }


private:
    const static DWORD firstObjectOffset = 0xAC;      // offset from the object manager to the first object
    const static DWORD nextObjectOffset = 0x3C;       // offset from one object to the next
    DWORD objectManagerBase;                          // the address off the object manager
    INT64 localGuid;                                  // the local guid.

};
```

C++ Code for the other Objects
*Note that string names don't function due to my lack of skill.



```
class WowObject
{
public:

    WowObject(DWORD baseAddress)
    {
        this -> baseAddress = baseAddress;
        RefreshFields();
    }

    void RefreshFields()
    {
        SetDescriptorFields();
        SetType();
        SetGuid();
        SetXPosition();
        SetYPosition();
        SetZPosition();
        SetRotation();
    }
    void SetDescriptorFields()
    {
        this -> descriptorFields = Memory::Read<DWORD>(baseAddress + descriptorFieldsOffset);
    }
    int GetDescriptorFields()
    {
        return descriptorFields;
    }
    void SetType()
    {
        this -> type = Memory::Read<int>(baseAddress + typeOffset);
    }
    int GetType()
    {
        return type;
    }
    void SetGuid()
    {
        this -> guid = Memory::Read<INT64>(baseAddress + guidOffset);
    }
    INT64 GetGuid()
    {
        return guid;
    }
    virtual void SetXPosition()
    {
        this -> xPosition = Memory::Read<float>(baseAddress + xPositionOffset);
    }
    float GetXPosition()
    {
        return xPosition;
    }
    virtual void SetYPosition()
    {
        this -> yPosition = Memory::Read<float>(baseAddress + yPositionOffset);
    }
    float GetYPosition()
    {
        return yPosition;
    }
    virtual void SetZPosition()
    {
        this -> zPosition = Memory::Read<float>(baseAddress + zPositionOffset);
    }
    float GetZPosition()
    {
        return zPosition;
    }
    void SetRotation()
    {
        this -> rotation =  Memory::Read<float>(baseAddress + rotationOffset);
    }
    float GetRotation()
    {
        return rotation;
    }

    DWORD baseAddress;
    DWORD descriptorFields;
    float zPosition,
    yPosition,
    xPosition,
    rotation;
    INT64 guid;
    int	 type;


protected:
    const static DWORD guidOffset = 0x30;
    const static DWORD nextObjectOffset = 0x3C;
    const static DWORD typeOffset = 0x14;
    const static DWORD xPositionOffset = 0x7D0;
    const static DWORD yPositionOffset = 0x7D4;
    const static DWORD zPositionOffset = 0x7D8;
    const static DWORD rotationOffset = 0x7DC;
    descriptorFieldsOffset = 0x08;
};



class Creature : public WowObject
{
public:

    Creature(DWORD baseAddress) : WowObject(baseAddress)
    {
        this -> baseAddress = baseAddress;
        RefreshFields();
    }
    void RefreshFields()
    {
        SetTargetGuid();
        SetLevel();
        SetCurrentHealth();
        SetMaxHealth();
        SetHealthPercent();
        SetCurrentMana();
        SetMaxMana();
        SetPitch();
    }

    void SetPitch()
    {
        this -> pitch = Memory::Read<float>(Memory::Read<DWORD>(baseAddress + 0x110) + 0x20);
    }
    float GetPitch()
    {
        return this -> pitch;
    }
    void SetTargetGuid()
    {
        this -> targetGuid = Memory::Read<INT64>(descriptorFields + targetGuidOffset);
    }
    INT64 GetTargetGuid()
    {
        return this -> targetGuid;
    }
    void SetLevel()
    {
        this -> level = Memory::Read<int>(descriptorFields + levelOffset);
    }
    int GetLevel()
    {
        return this -> level;
    }
    void SetCurrentHealth()
    {
        this -> currentHealth = Memory::Read<int>(descriptorFields + currentHealthOffset);
    }
    int GetCurrentHealth()
    {
        return this -> currentHealth;
    }
    void SetMaxHealth()
    {
        this -> maxHealth = Memory::Read<int>(descriptorFields + maxHealthOffset);
    }
    int GetMaxHealth()
    {
        return this -> maxHealth;
    }
    void SetCurrentMana()
    {
        this -> currentMana = Memory::Read<int>(descriptorFields + currentManaOffset);
    }
    int GetCurrentMana()
    {
        return this -> currentMana;
    }
    void SetMaxMana()
    {
        this -> maxMana = Memory::Read<int>(descriptorFields + maxManaOffset);
    }
    int GetMaxMana()
    {
        return this -> maxMana;
    }
    void SetHealthPercent()
    {
        double percentage = static_cast<double>(currentHealth) / static_cast<double>(maxHealth);
        percentage = percentage * 100;
        this -> healthPercent = static_cast<int>(floor(percentage));
    }
    int GetHealthPercent()
    {
        return this -> healthPercent;
    }
    virtual void SetName()
    {

    }


    //Other Public Identifiers:
    INT64 targetGuid;
    int level;
    int maxHealth;
    int currentHealth;
    int healthPercent;
    int currentMana;
    int maxMana;
    float pitch;
    string name;


protected:
    const static DWORD levelOffset = 0x35 * 4;
    const static DWORD currentHealthOffset = 0x17 * 4;
    const static DWORD maxHealthOffset = 0x1F * 4;
    const static DWORD currentManaOffset = 0x18 * 4;
    const static DWORD maxManaOffset = 0x20 * 4;
    const static DWORD targetGuidOffset = 0x12 * 4;

};




class oPlayer : public Creature
{
public:
    oPlayer(DWORD baseAddress) : Creature(baseAddress)
    {
        RefreshFields();
    }
    void RefreshFields()
    {
        SetCurrentRage();
        SetCurrentEnergy();
        SetMaxEnergy();
    }
    void SetCurrentRage()
    {
        int rageTemp = Memory::Read<int>(descriptorFields + currentRageOffset);
        this -> currentRage = static_cast<int>(floor(static_cast<double>(rageTemp) / 10));
    }
    int GetCurrentRage()
    {
        return this -> currentRage;
    }
    int GetMaxRage()
    {
        return 100;
    }
    void SetCurrentEnergy()
    {
        this -> currentEnergy = Memory::Read<int>(descriptorFields + currentEnergyOffset);
    }
    int GetCurrentEnergy()
    {
        return this -> currentEnergy;
    }
    void SetMaxEnergy()
    {
        this -> maxEnergy = Memory::Read<int>(descriptorFields + maxEnergyOffset);
    }
    int GetMaxEnergy()
    {
        return this -> maxEnergy;
    }
    void SetName()
    {

    }


    //Other Public Identifiers
    int maxEnergy;
    int currentEnergy;
    int maxRage;
    int currentRage;


protected:
    const static DWORD currentRageOffset = 0x19 * 4;
    const static DWORD currentEnergyOffset = 0x1B * 4;
    const static DWORD maxEnergyOffset = 0x23 * 4;

};


class oNpc : public Creature
{
public:
    oNpc(DWORD baseAddress) : Creature(baseAddress)
    {
        RefreshFields();
    }
    void RefreshFields()
    {
        SetName();
        SetAttackingGuid();
        SetSummonedBy();
    }
    void SetName()
    {
       
    }
    string GetName()
    {
     
    }
    void SetAttackingGuid()
    {
        this -> attackingGuid = Memory::Read<INT64>(baseAddress + attackingGuidOffset);
    }
    INT64 GetAttackingGuid()
    {
        return this -> attackingGuid;
    }
    void SetSummonedBy()
    {
        this -> summonedBy = Memory::Read<INT64>(descriptorFields + summonedByOffset);
    }
    INT64 GetSummonedBy()
    {
        return this -> summonedBy;
    }
    /*int GetAggroRadius(CreatureObject LocalPlayer)
    {
        // if they are the same level as us, the aggro radius is roughly 20 yards
        int AggroRadius = 20;
        // aggro radius varies with level difference at a rate of roughly 1 yard/level
        if (LocalPlayer.Level > Level)
            AggroRadius -= (int)BotControl.DifferenceBetween(LocalPlayer.Level, Level);
        if (LocalPlayer.Level < Level)
            AggroRadius += (int)BotControl.DifferenceBetween(LocalPlayer.Level, Level);
        if (AggroRadius < 5)
            AggroRadius = 5;
        AggroRadius += 3; // give us a bit of leeway
        return AggroRadius;
    }*/

    //Other Public Identifiers
    INT64 summonedBy;
    INT64 attackingGuid;
  

protected:
    const static INT64 summonedByOffset = 0xE * 4;
    const static INT64 attackingGuidOffset = 0x0A38;

};


class oGame : public WowObject
{
public:
    oGame(DWORD baseAddress) : WowObject(baseAddress)
    {
    }
    void SetName()
    {
    
    }
    string GetName()
    {
       
    }
    void SetXPosition()
    {
        this -> xPosition = Memory::Read<float>(descriptorFields + gameObject_XPositionOffset);
    }
    void SetYPosition()
    {
        this -> yPosition = Memory::Read<float>(descriptorFields + gameObject_YPositionOffset);
    }
    void SetZPosition()
    {
        this -> zPosition = Memory::Read<float>(descriptorFields + gameObject_ZPositionOffset);
    }
    void SetDisplayId()
    {
        this -> displayId = Memory::Read<int>(descriptorFields + displayIdOffset);
    }
    int GetDisplayId()
    {
        return this -> displayId;
    }

    string name;

protected:
    const static DWORD gameObject_XPositionOffset = 0x10 * 4;
    const static DWORD gameObject_YPositionOffset = 0x11 * 4;
    const static DWORD gameObject_ZPositionOffset = 0x12 * 4;
    const static DWORD displayIdOffset = 0x8 * 4;

private:
    int displayId;
};


class oDynamic : public WowObject
{
public:
    oDynamic(DWORD baseAddress) : WowObject(baseAddress)
    {
    }
    void SetXPosition()
    {
        this -> xPosition = Memory::Read<float>(descriptorFields + dynamicObject_XPositionOffset);
    }
    void SetYPosition()
    {
        this -> yPosition = Memory::Read<float>(descriptorFields + dynamicObject_YPositionOffset);
    }
    void SetZPosition()
    {
        this -> zPosition = Memory::Read<float>(descriptorFields + dynamicObject_ZPositionOffset);
    }
protected:
    const static DWORD dynamicObject_XPositionOffset = 0xB * 4;
    const static DWORD dynamicObject_YPositionOffset = 0xC * 4;
    const static DWORD dynamicObject_ZPositionOffset = 0xD * 4;
};
```

It's messy, I wanted to keep members private but ended up getting extremely sloppy and throwing them into the public. Easy fixed Copy/Pasta in any case.


Below: 
I included these functions in the object manager calling them immediately after populating the lists. This makes a very basic object dumper (Without names).



```
void PrintoNpcToScreen(list<oNpc> oNpcList)
{
    list<oNpc>::iterator i;

    for (i = oNpcList.begin(); i != oNpcList.end(); i++)
    {
        cout << "Name: " << (*i).name;
        cout << "  Type: " << (*i).type << "\n";
        cout << "x: " << (*i).xPosition << " y: " << (*i).yPosition << " z: " << (*i).zPosition << "\n";
        cout << endl;
    }
}

void PrintoGameToScreen(list<oGame> oGameList)
{
    list<oGame>::iterator i;

    for (i = oGameList.begin(); i != oGameList.end(); i++)
    {
        cout << "Name: " << (*i).name;
        cout << "  Type: " << (*i).type << "\n";
        cout << "x: " << (*i).xPosition << " y: " << (*i).yPosition << " z: " << (*i).zPosition << "\n";
        cout << endl;
    }
}

void PrintoPlayerToScreen(list<oPlayer> oPlayerList)
{
    list<oPlayer>::iterator i;

    for (i = oPlayerList.begin(); i != oPlayerList.end(); i++)
    {
        cout << "Name: " << (*i).name;
        cout << "  Type: " << (*i).type << "\n";
        cout << "x: " << (*i).xPosition << " y: " << (*i).yPosition << " z: " << (*i).zPosition << "\n";
        cout << endl;
    }
}
```

i know this is sloppy code and all criticism is welcome. I hope this can still be of use to somebody.

Again. All credit goes to the OP.

----------


## YetiHunter

thanks. i wanted to port this to c++ ... this gives a nice base

----------


## dekz

good guide man, a lot of effort put into this. +Rep

----------


## Azzie2k8

Does this really work for you opulent ?
My visual studio is throwing errors at me because of it.
it seems that it does not recognize the constructor ... or something...



```
    list<oNpc> oNpcList;
    list<oGame> oGameList;
    list<oPlayer> oPlayerList;
```

----------


## asmodei

> Does this really work for you opulent ?
> My visual studio is throwing errors at me because of it.
> it seems that it does not recognize the constructor ... or something...
> 
> 
> 
> ```
>     list<oNpc> oNpcList;
>     list<oGame> oGameList;
> ...


Should be List with a capital "L", and you'll need a using statement for System.Collections.Generic. What exactly is the error you get?

----------


## Azzie2k8

> Should be List with a capital "L", and you'll need a using statement for System.Collections.Generic. What exactly is the error you get?





> memory.h(522) : error C2143: syntax error : missing ';' before '<'
> error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
> error C2238: unexpected token(s) preceding ';'


just edited the capital L.

does not work yet. I guess it doesn't accept the classes as type ?

----------


## asmodei

> just edited the capital L.
> 
> does not work yet. I guess it doesn't accept the classes as type ?


Wow, my mistake, I only took a glance and thought you were writing C#.

----------


## Azzie2k8

> Wow, my mistake, I only took a glance and thought you were writing C#.


nope its cpp.

anyone ?

----------


## schlumpf

```
#include <list>
typedef std::list<fnameStruct> LISTSTRUCT;
LISTSTRUCT listStruct;
LISTSTRUCT::iterator i;
```

I guess, you don't use the standard namespace.

----------


## Azzie2k8

> ```
> #include <list>
> typedef std::list<fnameStruct> LISTSTRUCT;
> LISTSTRUCT listStruct;
> LISTSTRUCT::iterator i;
> ```
> 
> I guess, you don't use the standard namespace.




```
using namespace std;
```

this is right after my includes...if you meant that

----------


## schlumpf

Hm .

----------


## Azzie2k8

> Hm .


okay I think I found the problem I have to overwrite the list class so it accepts my objects ...

stupid me. Sorry I didn't get your point

I just used std::list<type> this time. +rep for you my country neighbour ^^

----------


## deCutter

Really helpful guide, thanks.
But still i cant understand, what is this one for?


```
        public float Pitch
        {
            get { return ObjectManager.WowReader.ReadFloat((IntPtr)(ObjectManager.WowReader.ReadUInt32((IntPtr)(baseAddress + 0x110)) + 0x20)); }
        }
```

----------


## Robske

> Really helpful guide, thanks.
> But still i cant understand, what is this one for?
> 
> 
> ```
>         public float Pitch
>         {
>             get { return ObjectManager.WowReader.ReadFloat((IntPtr)(ObjectManager.WowReader.ReadUInt32((IntPtr)(baseAddress + 0x110)) + 0x20)); }
>         }
> ```


I believe baseAddress + 0x110 used to point to movement related structure. One of that structures members was the pitch of the player at 0x20

If you don't know what pitch is... go google a picture  :Smile:

----------


## amadmonk

Or google flight controls: pitch, yaw, roll.

WoW implements pitch (upwards/downwards factin) and yaw (which is just heading). Roll would be... interesting.

----------


## schlumpf

You can actually get a roll-like effect with editing bone flags. (It actually some weird billboarding then. Pretty funny. Just edit the root bone and try a bit. Got pretty nice results.)

Of course that's not real roll.

----------


## Azzie2k8

This is one of those posts I can read over and over again and I still find new things in it and all those smalle details I have been missing before.

Anyways this post has been really helpful and I want to learn from it. So far I am trying to make this work but once again I am facing my own stupidty.

I included Shynd's BM and replaced some of those Wowreader commands so it would fit BM.

What I dont get is what does WowReader.SetProcess("Wow", "read") do ? I mean okay I am pretty sure that it tells the class which process to open and so on but I am just not completely sure how to handle this ? does this set debug priveleges as well ?

I know this might be stupid and I am sorry if it is but thats just me  :Wink: 

-Azzie

----------


## vulcanaoc

> What I dont get is what does WowReader.SetProcess("Wow", "read") do ? I mean okay I am pretty sure that it tells the class which process to open and so on but I am just not completely sure how to handle this ? does this set debug priveleges as well ?
> 
> I know this might be stupid and I am sorry if it is but thats just me 
> 
> -Azzie



This calls the underlying Win32 OpenProcess so that things like ReadProcessMemory and WriteProcessMemory can be called and most probably creates debug privileges as well.

(of course, i don't have the code; this is all assumed.)

----------


## Azzie2k8

I am facing some new problems and I have no idea why they are caused.

It seems that whenever I call this


```
objectManagerBase = WowReader.ReadUInt((WowReader.ReadUInt(staticClientConnection) + objectManagerOffset));
```

I get this exception




> ************** Exception Text **************
> System.Exception: ReadUInt failed.
> at Magic.SMemory.ReadUInt(IntPtr hProcess, UInt32 dwAddress, Boolean bReverse)
> at Magic.BlackMagic.ReadUInt(UInt32 dwAddress, Boolean bReverse)
> at Magic.BlackMagic.ReadUInt(UInt32 dwAddress)
> at FishBot.ObjectManager.LoadAddresses() in E:\Fishbot\FishBot\ObjectManager.cs:line 33
> at FishBot.Form1.Attach_Click(Object sender, EventArgs e) in E:\Fishbot\FishBot\Form1.cs:line 23
> at System.Windows.Forms.Control.OnClick(EventArgs e)
> at System.Windows.Forms.Button.OnClick(EventArgs e)
> ...


The adresses I use are still the same as in the guide



```
        private static uint staticClientConnection = 0x011CB310; // client connection, same address every boot
        private const uint objectManagerOffset = 0x28A4;
```

I havent looked up the new ones since it really won't matter if I don't get this ObjectManager working first.

ReadUInt works if I am only reading a normal static adress but as soon as I use the above code everything crashes.
I dunno what might be causing this because even if the adress and offset would be wrong it woul just read some jibberish, right ?

-Azrael

----------


## Quarters

Not sure why it's not working however your addresses and offsets are out of date I think and you need them to be up to date for it to work I would have thought... I'd check over the sticky in the memory editing section for the newest ones. I think its called "3.1.3 info dump" or something similar.

Quarters.

----------


## Azzie2k8

> Not sure why it's not working however your addresses and offsets are out of date I think and you need them to be up to date for it to work I would have thought... I'd check over the sticky in the memory editing section for the newest ones. I think its called "3.1.3 info dump" or something similar.
> 
> Quarters.


well I will just throw ida pro on and go and search for it. people arent updating static for clientconnect ( at least I havent found any) since they have those cool searchpatterns

----------


## vulcanaoc

> well I will just throw ida pro on and go and search for it. people arent updating static for clientconnect ( at least I havent found any) since they have those cool searchpatterns


http://www.mmowned.com/forums/wow-me...-patterns.html

Though it deals with patterns, I suggest reading it. It contains 3.1.3's statics too, anyway.

----------


## Azzie2k8

> http://www.mmowned.com/forums/wow-me...-patterns.html
> 
> Though it deals with patterns, I suggest reading it. It contains 3.1.3's statics too, anyway.


I just tried it with the updated addresses and yep they were causing the issue.

Thanks for the guide I will implement those patterns soon so this wont happen again.

-Azrael

----------


## vulcanaoc

Sounds like you made ObjectManager static. Check for the 'static' keyword in the class definition and, really, in any method it contains.

----------


## Azzie2k8

> Sounds like you made ObjectManager static. Check for the 'static' keyword in the class definition and, really, in any method it contains.


damn it...you read my post before I edited it...yes it is static and it is supposed to be static. I will just acces it directly

----------


## Azzie2k8

So everything with this worked fine so far. There is only one thing that bothers me atm.

LocalPlayer is always null.

I can find the local Player in the list but it does not safe the LocalPlayer at populating the list.



```
                if (CurrentObject.Type == 4)
                { // a player
                    PlayerObjectList.Add(CurrentObject.Guid, new PlayerObject(CurrentObject.BaseAddress));
                    if (CurrentObject.Guid == localGuid) // it is the local player
                    {
                        LocalPlayer = PlayerObjectList[localGuid];
                    }
                }
```

As Local Guid Offset I am using 0xC0 which I have looked up at several places and seems to be up to date.



```
            localGuid = WowReader.ReadUInt(objectManagerBase + localGuidOffset);
```

The ObjectManager works fine beside that so I am getting ObjectManagerBase and so on.

If anyone could enlighten me ?  :Wink: 

-Azrael

----------


## SKU

you may want to read the GUID as an UInt64.

----------


## Azzie2k8

> you may want to read the GUID as an UInt64.


Oh no...now I have to punish myself for being stupid...

thanks alot +Rep

----------


## flo8464

Edit: nvm, already found my answer.
Any hints where I could start reversing to find position-offsets myself?

----------


## SKU

VM 9

fillerlololo

----------


## flo8464

Use a debugger/disassembler and reverse some functions.

----------


## qjlex

```
public void ObjectMethod()
        {
            uint g_clientConnection = BotContro1l.memReader.ReadUInt((IntPtr)0x1139F80);
            uint s_curMgr = BotContro1l.memReader.ReadUInt((IntPtr)(g_clientConnection + 0x2C34));
            uint curObj = BotContro1l.memReader.ReadUInt((IntPtr)(s_curMgr + 0xAC));
            uint nextObj = 0;

            while (curObj != 0 && (curObj & 1) == 0)
            {
                ulong currentGUID = BotContro1l.memReader.ReadUInt((IntPtr)(curObj + 0x30));
                uint Name = BotContro1l.memReader.ReadUInt((IntPtr)(curObj + 420));
                Name = BotContro1l.memReader.ReadUInt((IntPtr)(Name + 0x88));
                string oName = BotContro1l.mem.ReadASCIIString(Name, 100);
                oName = Encode(oName);


                  listBox2.Items.Add(oName);
                  listBox2.Items.Add("HP: " + BotContro1l.memReader.ReadFloat(BotContro1l.memReader.ReadUInt((IntPtr)curObj + 0x08) + 0x40));
                  listBox2.Items.Add("Xpos: " + (int)BotContro1l.memReader.ReadFloat((IntPtr)(curObj + 0x7D0)));
                  listBox2.Items.Add("Ypos: " + (int)BotContro1l.memReader.ReadFloat((IntPtr)(curObj + 0x7D4)));
                  listBox2.Items.Add("Zpos: " + (int)BotContro1l.memReader.ReadFloat((IntPtr)(curObj + 0x7D8)));
                  listBox2.Items.Add("--------------------------");

                  nextObj = BotContro1l.memReader.ReadUInt((IntPtr)(curObj + 0x3C));
                  curObj = nextObj;
                
            }
        }
```


Not correctly issued to XYZ. Why?
Тут есть хоть кто-нибудь кто говорит по русски?

----------


## vulcanaoc

> ```
> public void ObjectMethod()
>         {
>             uint g_clientConnection = BotContro1l.memReader.ReadUInt((IntPtr)0x1139F80);
>             uint s_curMgr = BotContro1l.memReader.ReadUInt((IntPtr)(g_clientConnection + 0x2C34));
>             uint curObj = BotContro1l.memReader.ReadUInt((IntPtr)(s_curMgr + 0xAC));
>             uint nextObj = 0;
> 
>             while (curObj != 0 && (curObj & 1) == 0)
> ...


You're doing something wrong, tard!

HINT: jbrauman wrote this for an OLDER VERSION OF THE GAME.

----------


## Pimpace

Anybody knows how can I get combo point?

----------


## Robske

> Anybody knows how can I get combo point?


On my rogue I can get combopoints with either cheapshot, garotte, premeditation, sinister strike, mutilate, shiv, backstab and through talents...

----------


## Pimpace

> On my rogue I can get combopoints with either cheapshot, garotte, premeditation, sinister strike, mutilate, shiv, backstab and through talents...


Oh, sorry... for misunderstood. I mean how can I get combo point number from wow's memory? Which func? Or which object with? We can get hp, mana, etc, but combo point attached to player's target isn't it? Where can I get this point/func to get combo point?

----------


## Robske

> Oh, sorry... for misunderstood. I mean how can I get combo point number from wow's memory? Which func? Or which object with? We can get hp, mana, etc, but combo point attached to player's target isn't it? Where can I get this point/func to get combo point?


http://www.wowwiki.com/API_GetComboPoints

Even if you fail to reverse it, ... use a ghetto memory scanner to find the static that holds the number of combo points of the localplayer.

----------


## Seifer

Thanks a million, this really helped me out a bunch. <3

// Edit

I wanted to put in a check that checks if our target is either Npc or Player, and this is what I'm using currently:


```
// If we've got a target, update the target conditions.
            if (OManager.LocalPlayer.HasTarget == true)
            {
                try
                {
                    // We're targeting an NPC.
                    if (OManager.NpcObjectList.ContainsKey(OManager.LocalPlayer.TargetGuid))
                    {
                        lbl_THealth.Text = OManager.NpcObjectList[OManager.LocalPlayer.TargetGuid].CurrentHealth.ToString();
                        lbl_TMana.Text = OManager.NpcObjectList[OManager.LocalPlayer.TargetGuid].CurrentMana.ToString();
                    }

                    // We're targeting a Player.
                    if (OManager.PlayerObjectList.ContainsKey(OManager.LocalPlayer.TargetGuid))
                    {
                        lbl_THealth.Text = OManager.PlayerObjectList[OManager.LocalPlayer.TargetGuid].CurrentHealth.ToString();
                        lbl_TMana.Text = OManager.PlayerObjectList[OManager.LocalPlayer.TargetGuid].CurrentMana.ToString();
                    }

                }
                catch (Exception ex)
                {
                    lst_Log.Items.Add(ex.ToString());
                }
            }
```

Thought I'd share, in case anyone wondered.

----------


## Cypher

> On my rogue I can get combopoints with either cheapshot, garotte, premeditation, sinister strike, mutilate, shiv, backstab and through talents...


This thread has already been necro'd, so I just wanted to add:
That made me lol.

----------


## jbrauman

**Rises from the dead**

Wow, long time since I posted this! Haven't played WoW for ages now (or been on this forum), nice to see this place is still kicking along.

This thread is majorly out of date (and the source-code is kind of gross, albeit I was 15-16 when I wrote it), however I'm glad it helped some people.

Adios :wave:

----------


## fab92

> I can't remember where I found this MemoryReader .dll, or whom the author is unfortunately.


Someone can upload this dll ? I do not find it

----------


## dalisto1

This is a great guide, and has helped me a lot

I have been searching through mmowned for the past few days almost nonstop trying to grasp memory editing in the hopes of creating my own bot
However, i am trying to do it without the built libraries (blackmagic, etc), and only using ReadProcessMemory...

I have a question.. when trying to read and loop through the objects in the object manager, I am debugging my program and seeing that the 
value for clientConnection is 0, and I just don't know why this is. Believe me, I have searched through this entire forum on anything related to
the object manager, but almost everything uses separate libraries, and not ReadProcessMemory directly. I realize that it should be
relatively easy to convert from using a library to not using one, but I still have the same problem. The code i have is:



```
public enum ObjectManager : uint
{
            clientConnection = 0x8B2F78,
            objectManager = 0x462C,
            firstObject = 0xB4,
            nextObject = 0x3C,
}
```



```
uint clientConnection = BitConverter.ToUInt32(WoWScanner.ReadProcessMemory((IntPtr)((uint)WoWBaseAddress + (uint)Constants.ObjectManager.clientConnection), 4), 0);

uint objManager = BitConverter.ToUInt32(WoWScanner.ReadProcessMemory((IntPtr)(clientConnection + (uint)Constants.ObjectManager.objectManager), 4), 0);

uint firstObj = BitConverter.ToUInt32(WoWScanner.ReadProcessMemory((IntPtr)(objManager + (uint)Constants.ObjectManager.firstObject), 4), 0);
```

Now I have done lots of research on this, and tried many different things, even things I thought wouldn't work.. and it seems so simple but
I can't understand why clientconnection is 0. If you could point me in the right direction It would be greatly appreciated.

----------


## Megamike55

clientConnection = 0x8B2F78,

this is an offset not rebased to 0x1000

add 0x1000 and try again.

----------


## Lysolfs

sorry for bringing this up again.
Im trying to do this stuff obviously, but im not quite familiar with the syntax of c#, so i hope someone can help me with these (actually easy) things, i just dont know what the error code is supposed to mean. 
"Expected class, delegate, enum, interface, or struct (CS151 :Cool: "
is what it says, when im declaring variables like...


```
	public static PlayerObject LocalPlayer;
	
	public static IDictionary<ulong, PlayerObject> PlayerObjectList = new Dictionary<ulong, PlayerObject>();
	public static IDictionary<ulong, NpcObject> NpcObjectList = new Dictionary<ulong, NpcObject>();
	public static IDictionary<ulong, GameObject> GameObjectList = new Dictionary<ulong, GameObject>();
```

sorry. but im just familiar with basic dialects...^^

----------


## Bananenbrot

Like in Java you cannot declare any global variables. You must package them into a class, this is obvious and was omitted in the guide.
Program in C++ if you are more comfortable with it.

----------


## lionsq

Thanks a lot, this post is of great help for me.

----------


## Require

If this is considered a bump, sorry for that. Just wanted to say this tutorial was very useful to me. You should have explained what the staticClient offset is that would make it more obvious. (Well atleast for me). Thanks for this tutorial  :Smile:

----------


## Subhuman

Very nice guide!

----------


## hb123220

thx so much,,it helps me a lot~~but you made a mistake~~
 :Frown: mistake→


```
 public int CurrentMana
        {
            get { return ObjectManager.WowReader.ReadInt32((IntPtr)(DescriptorFields + CurrentMana)); }
```

 :Wink: correct→


```
 public int CurrentMana
        {
            get { return ObjectManager.WowReader.ReadInt32((IntPtr)(DescriptorFields + CurrentManaoffset)); }
```

----------

