-
Contributor
Avid Ailurophile
Originally Posted by
Reghero
So I have the new object manager offset at:
Code:
private const int ObjManager = 0x2D297C8;
private const int firstObjectOffset = 0x18;
private const int nextObjectOffset = 0x70;
I can only get a value at 0x68:
Code:
this.objManagerAddress = basePointer.Read<IntPtr>(ObjManager);
this.localGuid = this.process[objManagerAddress].Read<ulong>(0x68);
My guid: 3024378824124
CurMgr: 0x2C030E56BD0
0x58 gets me an odd value:
Code:
this.objManagerAddress = basePointer.Read<IntPtr>(ObjManager);
this.localGuid = this.process[objManagerAddress].Read<ulong>(0x58);
My guid: 56
CurMgr: 0x2C030E56BD0
Are you just adding GUID offsets right to Basemodule + ObjectManager pointer?.. cause... Yeah
This is what i tried, and seemed to work so far, though the location values are... unexpected:
Code:
public static int ObjManager = 0x2D297C8;
public static IntPtr PlayerBase()
{
var ObjManager = V.Read<IntPtr>(V.ObjectManager);
if (ObjManager == IntPtr.Zero) return IntPtr.Zero;
var CurrentObj_Base = V.Read<IntPtr>(ObjManager + 0x1B8);
var NextObject_Base = V.Read<IntPtr>(CurrentObj_Base + 0x70);
var _PlayerGUID = V.V<int>(V.PlayerGUID);
if (NextObject_Base == IntPtr.Zero) return IntPtr.Zero;
while (NextObject_Base.ToInt64() % 2 == 0 && NextObject_Base != IntPtr.Zero)
{
var WowObj = V.Read<WowObject>(NextObject_Base);
// if (WowObj.GUID.high == _PlayerGUID) return NextObject_Base;
if (WowObj.Type == 5) return NextObject_Base;
NextObject_Base = V.Read<IntPtr>(NextObject_Base + 0x70);
}
return IntPtr.Zero;
}
}
Code:
while (InGame)
{
var Player = new Local_Player(V.PlayerBase());
if (Player != null && LastHealth != Player.Health)
{
LastHealth = Player.Health;
Console.WriteLine($"Health: {Player.Health} | Max Health: {Player.MaxHealth} | Level: {Player.Level}");
Console.WriteLine($"TypeID: {Player.Type} : Guid: 0x{Player.GUID.high.ToString("X")}");
}
Console.WriteLine($"X: {Player.LocX} | Y: {Player.LocY} | Z: {Player.LocZ}");
Thread.Sleep(15);
}
public class Local_Player
{
public static IntPtr Base;
public Local_Player(IntPtr BaseAddress)
{
Base = BaseAddress;
}
public int Level = V.ReadChain<int>(Base, new[] { 0x10, 0x134 });
public int Health = V.ReadChain<int>(Base, new[] { 0x10, 0xDC });
public int MaxHealth = V.ReadChain<int>(Base, new[] { 0x10, 0xFC });
public byte Type = V.ReadChain<byte>(Base, new[] { 0x20 });
public _guid GUID = V.ReadChain<_guid>(Base, new[] { 0x58 });
public float LocX = V.ReadChain<float>(Base ,new []{ 0x1600});
public float LocY = V.ReadChain<float>(Base, new[] { 0x1604 });
public float LocZ = V.ReadChain<float>(Base, new[] { 0x1608 });
}
Output:
Capture.PNG
Last edited by Razzue; 06-25-2021 at 04:20 PM.
-
Post Thanks / Like - 1 Thanks
Reghero (1 members gave Thanks to Razzue for this useful post)
-
Originally Posted by
charles420
ya i find everything in ida worst case i compare old versions i have labeled i have a script that dumps most offsets for me besides a few patterns broke i take that back i have a mod version of reclass i use to find struts like playername cach etc i was working on a list of all my offsets with a list of how to find each one in ida since alot of people spam me asking
Looking forward to seeing this !
Also, while I have you here. Do you know of any safe way to interact with the client externally, ideally without having the client in-focus.
Toying with the idea of just using KDmapper and the Interception Driver but would rather do that as a last resort.
-
Post Thanks / Like - 1 Thanks
Razzue (1 members gave Thanks to Dupheadss for this useful post)
-
Contributor
personlly i tried interception driver then came to fact they haven't started using this to detect bots yet but theres a few ways to bypass this without the use of a driver thats not saying blizz wont start using this method to find bots but at this moment and time they havent i have a few accounts i only bot on that only use fake keypresses still fine
Last edited by charles420; 06-26-2021 at 12:33 PM.
-
Post Thanks / Like - 1 Thanks
Razzue (1 members gave Thanks to charles420 for this useful post)
-
-
Post Thanks / Like - 1 Thanks
Reghero (1 members gave Thanks to Razzue for this useful post)
-
Member
Originally Posted by
Razzue
So after playing around a bit.. X/Y ARENT in x1600/x1604?
Where i am in game:
Cheat engine struct dissector:
showoff3.PNG
Coord of area as per wow.tools
Capture2.PNG
Or maybe im doing something horribly wrong? though other things seem to still be fine.. idk O.o
Exactly the issue I'm having, Y appears to change when I rotate the character.
For anyone interesting in reading the object manager, or at least getting to the point I'm at (and it sounds like Razzue is at too). I've thrown together a little WPF example that uses Rx etc to display some info in a table, nothing fancy.
GitHub - jjbrunton/WoWTest: Simple test WPF application that will list objects available in the object manager as well as local player information.
-
Contributor
Vector3 position; // 0x650 - 0x658
int unk;
float rotation;
That’s retail. Tbc:
player+0x198]+0x20 I think
Tbc has all the special descriptor offsets and 198 is something like PlayerInfo. You shouldn’t need offsets in the struct that far out, that’s a retail thing.
Last edited by ChrisIsMe; 06-27-2021 at 10:00 AM.
-
Post Thanks / Like - 2 Thanks
Reghero,
Razzue (2 members gave Thanks to ChrisIsMe for this useful post)
-
Member
Originally Posted by
ChrisIsMe
Vector3 position; // 0x650 - 0x658
int unk;
float rotation;
Is this:
X = curObj + 0x650
Y = curObj + 0x654
Z = curObj + 0x658
?
If so, that doesn't look right.
Also, would you be able to point me in the direction of any info as to how you got the position offsets?
-
Contributor
Avid Ailurophile
Originally Posted by
Reghero
Is this:
X = curObj + 0x650
Y = curObj + 0x654
Z = curObj + 0x658
?
If so, that doesn't look right.
Also, would you be able to point me in the direction of any info as to how you got the position offsets?
Get local player base address
Add to pointers manually
Ctrl+d =>Copy address=> Ctrl+d=> paste address => create new struct and .. explore xD (using modified cheat engine)
This is what i've found after ~5 minutes of poking around :
Code:
Player + 0x15F8 = X
Player + 0x15FC = Y
Player + 0x1600 = Z
Player + 0x1604 = Rotation
Player + 0x10 + 0x1FC = Strength
Player + 0x10 + 0x200 = Agility
Player + 0x10 + 0x204 = Stamina
Player + 0x10 + 0x208 = Intellect
Player + 0x10 + 0x20C = Spirit
Player + 0x10 + 0x238 = Armor
Last edited by Razzue; 06-27-2021 at 09:52 AM.
-
Contributor
Originally Posted by
Razzue
Get local player base address
Add to pointers manually
Ctrl+d =>Copy address=> Ctrl+d=> paste address => create new struct and .. explore xD (using modified cheat engine)
This is what i've found after ~5 minutes of poking around :
Code:
Player + 0x15F8 = X
Player + 0x15FC = Y
Player + 0x1600 = Z
Player + 0x1604 = Rotation
Player + 0x10 + 0x1FC = Strength
Player + 0x10 + 0x200 = Agility
Player + 0x10 + 0x204 = Stamina
Player + 0x10 + 0x208 = Intellect
Player + 0x10 + 0x20C = Spirit
Player + 0x10 + 0x238 = Armor
Or reverse CGUnit_C::GetRawPosition // CGUnit_C::GetPosition VTable methods...
Or Script_UnitPosition()
Code:
struct CGPlayerInformation {
char _pad1[0x20];
Vector3 position;
} __attribute__((packed));
struct CGPlayer {
char _padObj[0x198];
CGUnitInformation* info; // 0x198
} __attribute__((packed));
for object in objects do
CGPlayer* player = (CGPlayer*)object;
end
Here's my structs for TBC dumbed down.
Last edited by ChrisIsMe; 06-27-2021 at 09:56 AM.
-
Post Thanks / Like - 2 Thanks
Razzue,
Reghero (2 members gave Thanks to ChrisIsMe for this useful post)
-
Contributor
Originally Posted by
Reghero
Is this:
X = curObj + 0x650
Y = curObj + 0x654
Z = curObj + 0x658
?
If so, that doesn't look right.
Also, would you be able to point me in the direction of any info as to how you got the position offsets?
I updated my reply, I default to Retail WoW.
-
Post Thanks / Like - 1 Thanks
Reghero (1 members gave Thanks to ChrisIsMe for this useful post)
-
Member
Success, thanks for all the contributions!
Imgur: The magic of the Internet
Onto the next few challenges:- Unit name and CTM
-
Active Member
Originally Posted by
Reghero
I'd reverse engineer vtable index 15 for object names. As for CTM, it seems like you're external. Not sure how you plan on calling that function unless you do some funny codecave stuff.
-
Post Thanks / Like - 1 Thanks
Reghero (1 members gave Thanks to scimmy for this useful post)
-
Member
Originally Posted by
scimmy
I'd reverse engineer vtable index 15 for object names. As for CTM, it seems like you're external. Not sure how you plan on calling that function unless you do some funny codecave stuff.
Cheers. I've been reading my way back from 2009 to present and the more I read, the more it sounds like it's worthwhile to get something injected. Although over the years, it does look like it's possible to write the destination coords to the CTM struct and write face (used to be 0x04), is that not the case anymore?
Currently reading https://drewkestell.us/Article/6/Chapter/1 in between work meetings
One thing (and not to take this thread too off topic) that I was confused about initially with the in process injection: you are still reliant on pointers to the required functions, correct? So in the blog above, he makes use of EnumerateVisibleObjects (presumably that's just a given name, something different internal), there's not much info as to reversing the locations of these functions. Looking into IDA, while I can see references to strings like CastSpell etc... there's no easy way to jump to the function from what I can (clearly missing something).
-
Contributor
Originally Posted by
Reghero
Cheers. I've been reading my way back from 2009 to present and the more I read, the more it sounds like it's worthwhile to get something injected. Although over the years, it does look like it's possible to write the destination coords to the CTM struct and write face (used to be 0x04), is that not the case anymore?
Currently reading
https://drewkestell.us/Article/6/Chapter/1 in between work meetings
One thing (and not to take this thread too off topic) that I was confused about initially with the in process injection: you are still reliant on pointers to the required functions, correct? So in the blog above, he makes use of EnumerateVisibleObjects (presumably that's just a given name, something different internal), there's not much info as to reversing the locations of these functions. Looking into IDA, while I can see references to strings like CastSpell etc... there's no easy way to jump to the function from what I can (clearly missing something).
CTM Structs are now xor encrypted, it flips between 5 or 6 encryption methods every time they patch the game. I would just use keyboard inputs or something instead to be honest, it's quite a hassle externally now.
But, it's all still possible.
This thread is becoming a feast though, have fun...
Last edited by ChrisIsMe; 06-28-2021 at 08:24 AM.
-
Post Thanks / Like - 1 Thanks
Reghero (1 members gave Thanks to ChrisIsMe for this useful post)
-
Contributor
CGObject_C + 0x10 is a pointer to the object's descriptors (as listed here ([Classic TBC] 2.5.1.38988 object descriptors))
CGUnit_C + 0x198 is a pointer to CMovement structure, CGUnit_C + 0x1598 is the start of CMovement structure
Code:
// size = 0x238
struct CMovement : CPassenger
{
//CPassenger passenger; // 0x000
uintptr_t unk_048; // 0x048
uintptr_t unk_050; // 0x050
MovementFlags Flags; // 0x058
uint32_t unk_05C; // 0x058
float x; // 0x060
float y; // 0x064
float z; // 0x068
float facing; // 0x06C
// etc...
};
just to clarify some offsets posted earlier
-
Post Thanks / Like - 2 Thanks
Reghero,
Razzue (2 members gave Thanks to ejt for this useful post)