-
Contributor
[1.12] Trouble with ClntObjMgrObjectPtr calling convention
Hi, I'm trying to call ClntObjMgrObjectPtr (0x468460) but I don't understand the calling convention
Looking at the disassembly, it looks like it has this signature to
uintptr_t __fastcall ClntObjMgrObjectPtr(uint64_t guid, int32_t filter)
However:
If I call it as shown above, esi and esp are not equal after the function has been called, causing a run-time exception
If I call it as __stdcall instead, it doesn't throw a runtime exception but it also doesn't work, as junk gets passed to ecx (the filter argument)
Is there a way for me to declare this function in such a way that Visual Studio can generate the correct assembly for me? I'd really like to avoid using raw assembly wherever possible 
Here is an example of correct assembly calling this function (edx is completely unused):
Code:
.text:00482CE1 push eax
.text:00482CE2 push ecx
.text:00482CE3 mov edx, offset aEBuildBuild_33 ; "E:\\build\\buildWoW\\WoW\\Source\\Ui\\W"...
.text:00482CE8 mov ecx, 1
.text:00482CED call ClntObjMgrObjectPtr
Thanks!
EDIT: I also tried calling it as __thiscall, as suggested here: http://www.ownedcore.com/forums/worl...ml#post2105431 ([WoW] 1.12.1.5875 Info Dump Thread)
This also causes a run-time error to occur, using signature
Code:
uint32_t(__thiscall *WoWFunc_GetObjectByGuid)(int32_t filter, uint64_t guid);
Last edited by Saridormi; 06-23-2016 at 10:10 PM.
-
While it may technically be __fastcall, I don't believe it actually does anything with ecx or edx. Therefore, you can call it as __stdcall with a signature like:
uintptr_t __stdcall ClntObjMgrObjectPtr(unsigned __int64 guid)
That should work, but be warned I am doing it from memory.
-
Post Thanks / Like - 1 Thanks
Saridormi (1 members gave Thanks to namreeb for this useful post)
-
Contributor
Originally Posted by
namreeb
While it may technically be __fastcall, I don't believe it actually does anything with ecx or edx. Therefore, you can call it as __stdcall with a signature like:
uintptr_t __stdcall ClntObjMgrObjectPtr(unsigned __int64 guid)
That should work, but be warned I am doing it from memory.
Thanks for the reply
Calling it as __stdcall doesn't crash the client, but whatever is passed to ecx sometimes causes a check inside the function to fail
The check appears to read the object type from the object descriptor and then does a test and jnz against ecx. If it doesn't jump, 0 (nullptr) is returned
edx is indeed useless, it is overwritten before being read
-
Established Member
ClntObjMgrObjectPtr takes 4 arguments, 2 of them are for debugging
int typemask,
uint64_t guid
int line,
char const* file
Arg order is different in newer builds but from the disassembly part you posted 1.12 seems to be something like this
CGObject_C* __fastcall ClntObjMgrObjectPtr(int typemask, char const* file, [guid], [line]) -- no idea about order of the last 2 just from that tiny asm snippet
Last edited by shauren; 06-24-2016 at 01:18 AM.
-
Post Thanks / Like - 1 Thanks
Saridormi (1 members gave Thanks to shauren for this useful post)
-
I checked my IDB file for the 1.12.1 client. You were right. Here is the prototype, and just because it's short and sweet, the whole function:
Code:
CGObject_C *__fastcall ClntObjMgrObjectPtr(unsigned int typeMask, const char *fileName, unsigned __int64 guid)
{
CGObject_C *result; // eax@1
result = GetObjectPtr(guid);
if ( result )
{
if ( !(typeMask & result->Descriptors[OBJECT_FIELD_TYPE]) )
result = NULL;
}
return result;
}
Edit: If you wanted to simplify things, you could also call GetObjectPtr() (0x464870) directly:
Code:
CGObject_C *__stdcall GetObjectPtr(unsigned __int64 guid)
{
CGObject_C *result; // eax@2
if ( guid )
result = FindActiveObj(guid);
else
result = NULL;
return result;
}
Last edited by namreeb; 06-24-2016 at 01:23 AM.
-
Post Thanks / Like - 2 Thanks
Saridormi,
lolp1 (2 members gave Thanks to namreeb for this useful post)
-
Contributor
Originally Posted by
shauren
ClntObjMgrObjectPtr takes 4 arguments, 2 of them are for debugging
int typemask,
uint64_t guid
int line,
char const* file
Arg order is different in newer builds but from the disassembly part you posted 1.12 seems to be something like this
CGObject_C* __fastcall ClntObjMgrObjectPtr(int typemask, char const* file, [guid], [line]) -- no idea about order of the last 2 just from that tiny asm snippet
This worked perfectly, thank you! +5 rep
Which debug builds are you referring to specifically? (And are there any binaries readily available for them?)
-
Established Member
Most recently mac x64 6.0.1.18719, mac 4.1.0.13850 or the very old old win 1.0.0.3368 with pdb, see this thread
http://www.ownedcore.com/forums/worl...lease-ptr.html ([WoW] Binary Collection (Release & PTR))
-
Post Thanks / Like - 1 Thanks
Saridormi (1 members gave Thanks to shauren for this useful post)