-
Active Member
57171 Retail 11.0.5 objectmgr changes
Seems the objectmgr on this version changed a lot, Still figuring out how to read it
-
Contributor
Originally Posted by
garenmain
Seems the objectmgr on this version changed a lot, Still figuring out how to read it
It has indeed. What appears is that there is no longer the linked list on the curmgr. You can still search the active objects string to find the chained hash array. The entries used to be pair<guid, object*>, but now in the initializer it's the entity builder instead of the object pointer. The entity builder contains the guid, and the object pointer at 0x20
-
Active Member
Originally Posted by
scizzydo
It has indeed. What appears is that there is no longer the linked list on the curmgr. You can still search the active objects string to find the chained hash array. The entries used to be pair<guid, object*>, but now in the initializer it's the entity builder instead of the object pointer. The entity builder contains the guid, and the object pointer at 0x20
How are you traversing it? I was trying to use 0x49F26E8 + 0x8 and found some list that size equals 0x49F26D8 + 0x40 but not able to get the correct object pointer from it
Think
So far I tried iterating with the total count and doing this
var entityPtr = process.Memory.Read<IntPtr>(process.Memory.Read<IntPtr>(objManagerAddress + 32) + 8 * i);
I'm able to read the guid at 0x10 with that, however still looking for ObjectType
Last edited by garenmain; 10-22-2024 at 08:08 PM.
-
Post Thanks / Like - 2 Thanks
-
Contributor
Originally Posted by
garenmain
How are you traversing it? I was trying to use 0x49F26E8 + 0x8 and found some list that size equals 0x49F26D8 + 0x40 but not able to get the correct object pointer from it
Think
So far I tried iterating with the total count and doing this
var entityPtr = process.Memory.Read<IntPtr>(process.Memory.Read<IntPtr>(objManagerAddress + 32) + 8 * i);
I'm able to read the guid at 0x10 with that, however still looking for ObjectType
The structure it points to is a chained hash. 0x0 is the capacity, 0x8 is the data and 0x10 is the number of elements. The data is the chained hash node, with 0x0 being the pointer to the next node, and 0x8 being the data. The node data is a pair<guid, entitybuilder<object*>*> (I called it EntityBuilder looking at the RTTI where it's used). The entity builder has the GUID at 0x10. Then the object pointer at 0x20. From the object, the type is at 0x8
-
Post Thanks / Like - 7 Thanks
-
Active Member
Originally Posted by
scizzydo
The structure it points to is a chained hash. 0x0 is the capacity, 0x8 is the data and 0x10 is the number of elements. The data is the chained hash node, with 0x0 being the pointer to the next node, and 0x8 being the data. The node data is a pair<guid, entitybuilder<object*>*> (I called it EntityBuilder looking at the RTTI where it's used). The entity builder has the GUID at 0x10. Then the object pointer at 0x20. From the object, the type is at 0x8
Thanks, that's what I was missing!
-
Member
I can't find the latest transport matrix on transport units ( like zepplin , it was at transport+0x118 before ), any idea on how to find it ?
Last edited by Lumi666; 10-23-2024 at 12:56 PM.
Reason: error in offset
-
Contributor
Originally Posted by
Lumi666
I can't find the latest transport matrix on transport units ( like zepplin , it was at transport+0x110 before ), any idea on how to find it ?
You can look at 0x1426D6D10 to get the matrix. Its the function the game uses to get an objects matrix
-
Member
Can't find this addr in my dump, can you double check and confirm pls ? Thanks for your help
-
Contributor
Originally Posted by
Lumi666
Can't find this addr in my dump, can you double check and confirm pls ? Thanks for your help
It's rebased to 0x140000000, so base + 26D6D10
-
Member
I got the transport position and the rotation but can't figure where is the transport matrix ... Do you mind sharing an IDA screenshot of the function before this patch ? Can't find this function in my previous dump
-
Active Member
-
Active Member
Originally Posted by
scizzydo
The structure it points to is a chained hash. 0x0 is the capacity, 0x8 is the data and 0x10 is the number of elements. The data is the chained hash node, with 0x0 being the pointer to the next node, and 0x8 being the data. The node data is a pair<guid, entitybuilder<object*>*> (I called it EntityBuilder looking at the RTTI where it's used). The entity builder has the GUID at 0x10. Then the object pointer at 0x20. From the object, the type is at 0x8
hmm, i didn't managed to fix my object manager loop, can you post a small code example?
is 0x49F26E8 the current start ptr (for the structure)?
thank you!
-
Active Member
I'm using this
Code:
struct om_obj {
void **vmt; /* 0x00 - 0x08 */
uint8_t otype; /* 0x08 - 0x09 */
};
struct entity_builder {
char fill[0x10]; /* 0x00 - 0x10 */
wGUID guid; /* 0x10 - 0x20 */
struct om_obj *obj; /* 0x20 - 0x30 */
};
struct hashent {
struct hashent *next; /* 0x00 - 0x08 */
wGUID guid; /* 0x08 - 0x18 */
struct entity_builder *eb; /* 0x18 - 0x28 */
};
struct objMgr {
uint64_t numslots; /* 0x00 - 0x08 */
struct hashent **slots; /* 0x08 - 0x10 */
};
Code:
for (int slot_ix = 0; slot_ix < (*ps_curMgr)->numslots; slot_ix++) {
struct hashent *e;
for (e = (*ps_curMgr)->slots[slot_ix]; e != NULL; e = e->next) {
//L("got obj entguid %x%x ebguid %x%x", e->guid.high, e->guid.low, e->eb->guid.high, e->eb->guid.low);
guids[added_ix] = e->guid;
otypes[added_ix] = e->eb->obj->otype;
added_ix++;
assert(added_ix < MAX);
}
}
Code:
struct om_obj *
get_obj(wGUID guid) {
uint32_t k2 = 0xA2AA033B * guid.high;
uint32_t k1 = 0xD6D018F5 * guid.low;
uint32_t index = (k1 + k2) % (*ps_curMgr)->numslots;
struct hashent *pent;
for(pent = (*ps_curMgr)->slots[index]; pent != NULL; pent = pent->next) {
if (GUID_EQ(pent->guid, guid)) {
return pent->eb->obj;
}
}
return NULL;
}
The obj manager in 57171 is 0x1449f26e8. In 57212 its 0x144724718.
Last edited by thateuler; 10-24-2024 at 05:08 AM.
Reason: add hashmap lookup code
-
Post Thanks / Like - 4 Thanks
-
Active Member
For the folks who call blizz code to get object positions. I was reading through my crash logs and found this.
Local Player: JackHuman, Player-69-ABCDEFG, (2444, (2179.57, -726.739, 4.63765))
Those last 3 floats look like world coords hey. Seaching for Local Player lead me to the function at 0x142463020 (patch 57212).
-
Post Thanks / Like - 1 Thanks
aeo (1 members gave Thanks to thateuler for this useful post)
-
Originally Posted by
thateuler
I'm using this
Code:
struct om_obj {
void **vmt; /* 0x00 - 0x08 */
uint8_t otype; /* 0x08 - 0x09 */
};
struct entity_builder {
char fill[0x10]; /* 0x00 - 0x10 */
wGUID guid; /* 0x10 - 0x20 */
struct om_obj *obj; /* 0x20 - 0x30 */
};
struct hashent {
struct hashent *next; /* 0x00 - 0x08 */
wGUID guid; /* 0x08 - 0x18 */
struct entity_builder *eb; /* 0x18 - 0x28 */
};
struct objMgr {
uint64_t numslots; /* 0x00 - 0x08 */
struct hashent **slots; /* 0x08 - 0x10 */
};
Code:
for (int slot_ix = 0; slot_ix < (*ps_curMgr)->numslots; slot_ix++) {
struct hashent *e;
for (e = (*ps_curMgr)->slots[slot_ix]; e != NULL; e = e->next) {
//L("got obj entguid %x%x ebguid %x%x", e->guid.high, e->guid.low, e->eb->guid.high, e->eb->guid.low);
guids[added_ix] = e->guid;
otypes[added_ix] = e->eb->obj->otype;
added_ix++;
assert(added_ix < MAX);
}
}
Code:
struct om_obj *
get_obj(wGUID guid) {
uint32_t k2 = 0xA2AA033B * guid.high;
uint32_t k1 = 0xD6D018F5 * guid.low;
uint32_t index = (k1 + k2) % (*ps_curMgr)->numslots;
struct hashent *pent;
for(pent = (*ps_curMgr)->slots[index]; pent != NULL; pent = pent->next) {
if (GUID_EQ(pent->guid, guid)) {
return pent->eb->obj;
}
}
return NULL;
}
The obj manager in 57171 is 0x1449f26e8. In 57212 its 0x144724718.
Thanks for this, super useful.
I have it iterating through the list fine and I can find the active player however it seems to also contain objects which are not visible / active.
Is there some flag on om_obj which can be used to determine if the object is visible to the player?