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](https://www.ownedcore.com/forums/attachments/world-of-warcraft/world-of-warcraft-bots-programs/wow-memory-editing/4809d1443816546t-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.