-
Member
Obfuscated objectmanager object pointer function
Hi,
I've spent a few days trying figure out some things on my own and using information available on the forums. Thanks to all the people who have provided useful tips on the forums so far, it makes the process a lot easier! I have 2 questions, hopefully I can get an answer and clear this up for future noobs like myself
:
1. I was looking at ClntObjMgrObjectPrt after using dump GitHub - namreeb/dumpwow: Unpacker for World of Warcraft (thanks to Namreeb), the function looks obfuscated. I'm trying to make sense of what it does and what it returns. From what I can gather in IDA from calls and checking against reference builds (like 18179), it takes in pointer to GUID and object type, then I assume it traverses through the linked list to find the GUID match (not 100% sure about this due to mangled code). If this is correct, is the return of the function going to be a pointer to the base of the object in the object manager hash table? i.e. [obj_mgr+0x8]+0x8*obj_index, obj_index being computed using GUID and the hash constants. Or is it just the pointer to the "next" point of the object in the linked list?
Mangled pseudocode:
Code:
void *__fastcall ClntObjMgrObjectPtr(_GUID *a1, int a2)
{
__int64 v2; // rbp
wchar_t *v3; // r8
unsigned __int64 v5; // r9
__int64 v6; // rdx
_BYTE *v7; // rdi
__int64 v8; // rax
__int64 v10; // rax
__int64 v11; // rdx
__int64 v12; // r8
__int64 v13; // rcx
char v14; // of
char v15; // pf
char v16; // cf
char v17; // zf
__int64 v18; // [rsp-8B10h] [rbp-8B60h]
int v19; // [rsp-8B08h] [rbp-8B58h]
int v20; // [rsp-8B00h] [rbp-8B50h]
__int64 v21; // [rsp-8AF8h] [rbp-8B48h]
__int64 v22; // [rsp-8AF0h] [rbp-8B40h]
int v23; // [rsp-8AE8h] [rbp-8B38h]
__int64 v24; // [rsp-8AE0h] [rbp-8B30h]
v3 = obj_mgr;
if ( obj_mgr )
{
v5 = *(_QWORD *)a1->high;
if ( v5 >> 58 )
{
v6 = 25904i64;
v7 = (_BYTE *)(*((_QWORD *)NtCurrentTeb()->ThreadLocalStoragePointer + (unsigned int)dword_44A0450) + 25904i64);
if ( !*v7 )
{
v8 = *((_QWORD *)obj_mgr + 41) >> 58;
while ( 1 )
{
*v7 = 1;
if ( (_BYTE)v8 )
{
if ( *((_QWORD *)v3 + 40) != *(_QWORD *)&a1->low || *((_QWORD *)v3 + 41) != v5 )
break;
}
sub_2805690((__int64)a1, v6, (__int64)v3, v5, v18, v19, v20, v21, v22, v23, v24);
*v7 = 0;
if ( !v10 )
return 0i64;
v13 = *(unsigned __int8 *)(v10 + 8);
if ( (a2 & dword_3ABEF50[v13]) == 0 )
return 0i64;
if ( (a2 & dword_3ABEF50[v13]) < 0 || ((v11 & 0x8000) != 0) == v14 )
JUMPOUT(0x27FEC14i64);
LOBYTE(v11) = v11 - 57;
LOBYTE(v8) = ((__int64 (__fastcall *)(_QWORD, __int64, __int64, __int64))((char *)&loc_281B21B + 2))(
(unsigned int)(v23 - 52677568),
v11,
v12,
v10);
if ( v16 | v17 )
{
if ( !v15 )
{
BYTE1(a1) = 18;
((void (__fastcall *)(_GUID *))((char *)&loc_281C2C3 + 1))(a1);
*(_DWORD *)(v2 + 1285529633) += 117;
JUMPOUT(0x27FEC7Ai64);
}
JUMPOUT(0x2816F45i64);
}
}
*v7 = 0;
}
}
}
return 0i64;
}
2. I think I've deduced the address of what seems to be CGUnit_C::GetPredictedHealth, is it correct to assume that I can get a unit health by simply doing (if hash table assumption is correct) [[[obj_mgr+0x8]+0x8*obj_index]+offset_1]? Or am I completely misunderstanding this? So far my attempts to obtain unit health this way seems to be give me bogus values that make no sense.
Code:
__int64 __fastcall CGUnit_C::GetPredictedHealth(__int64 a1)
{
if ( *(_DWORD *)(g_predictedHealthCvar + 20) )
return *(_QWORD *)(a1 + offset1);
else
return *(_QWORD *)(a1 + offset2);
}
Btw want to thank Razzue for GitHub - Razzue/Wow-Dumper: A simple wow offset dumper works great!
-
Member
I think I figured out the first issue. I was missing a 0x18 offset after the obj_index. In CE it seems that the pointer to the base of the unit object is offset at 0x18 of the pointer from the hash index.
I did notice that, and maybe someone can clarify, the unit health is not given as an absolute value, instead it appears to be some kind of generic value that can be compared against max health to get the hp % (?). I'm decoding 0x82f while the mobs around me have a health of 50 - doesn't appear to be stored in float either. It does go down when target is attacked while max stays the same so it appears to be correct. Any hints/input would be appreciated.
-
-
Post Thanks / Like - 1 Thanks
goblin2kx (1 members gave Thanks to Razzue for this useful post)