Coding

 Reply to this postStart new topic

Explicit thiscall

LINK/2012
post Jul 26 2012, 03:14 AM
Post #1


I will kill you

Posts: 126
Joined: 13-May 11



I want to hook a thiscall method call, Is there any way to explicitly define a thiscall method?
something like:
CODE
void __thiscall A__B(void* ThisPtr)
{
// ...
}


Go to the top of the page
 
+Quote Post
Wesser
post Jul 26 2012, 12:31 PM
Post #2


The Assistant

Posts: 84
From: Matera, IT
Joined: 16-June 11



You cannot do it directly. The calling convention closest to __thiscall is __fastcall as the first argument is stored in the ECX pointer:

CODE
class CClass
{
  public:
    int m_iMember;
};

/*
* The fastcall calling convention puts the first 2 arguments
* into ECX and EDX registers from left to right, whereas the
* next arguments are pushed onto the stack from right to left.
*/
int __fastcall CClass__Method(CClass *pclThis, void *pvUnused, int iArgument)
{
    pclThis->m_iMember = iArgument;

    // The rest of the code

    return 0;
}


This post has been edited by Wesser: Jul 26 2012, 02:22 PM
Go to the top of the page
 
+Quote Post
Silent
post Jul 26 2012, 11:17 PM
Post #3


The master of cut retort

Group Icon

Posts: 239
From: Warsaw, PL
Joined: 21-July 10



The other ways may be to actually define a class (fake or real), or use a wrapper to 'convert' thiscall to regular call. Both are easy.

This post has been edited by Silent: Jul 26 2012, 11:18 PM
Go to the top of the page
 
+Quote Post
LINK/2012
post Jul 27 2012, 02:23 AM
Post #4


I will kill you

Posts: 126
Joined: 13-May 11



@Wesser
Thanks...
The only problem with the fastcall way is that it's Callee clean-up and the thiscall is Caller clean-up (well, the method that I'm looking is Caller clean-up).
But that's not a problem in my case because I don't want the params.

@Silent
Yeah, I thought in this way, but maybe there was a fastest way that I don't need to define a class, so I decided to ask.

Go to the top of the page
 
+Quote Post
Wesser
post Jul 27 2012, 10:51 AM
Post #5


The Assistant

Posts: 84
From: Matera, IT
Joined: 16-June 11



Are you sure? I've just tested __thiscall and __fastcall can be both caller and callee clean-up. It depends on whether the arguments number is variadic or not. Maybe we have to take into account that the __fastcall behaviour it's MS specific. If so, you rarely use an undefined number of arguments with methods, thus using it is fine most of the time. smile.gif

Another possible solution may be declaring your function like a __stdcall and store the ECX pointer into a local variable:

CODE
int __stdcall CClass__Method(int iArgument)
{
    CClass *pclThis;

    __asm mov    pclThis, ecx

    pclThis->m_iMember = iArgument;

    // The rest of the code

    return 0;
}

Shame, it's performance loss. However, an optimization can be done:

CODE
int __stdcall CClass__Method(int iArgument)
{
    register CClass *pclThis;

    __asm mov    eax, ecx

    pclThis->m_iMember = iArgument;

    // The rest of the code

    return 0;
}

As far as I know, the best way is defining a class of your hooking methods.

This post has been edited by Wesser: Jul 27 2012, 01:10 PM
Go to the top of the page
 
+Quote Post
Silent
post Jul 27 2012, 12:08 PM
Post #6


The master of cut retort

Group Icon

Posts: 239
From: Warsaw, PL
Joined: 21-July 10



Register? Wow, I didn't know about that keyword tongue.gif

It would be safer to still use __asm mov pclThis, ecx with 'register', just in case the compiler won't be willing to accept this tongue.gif
Go to the top of the page
 
+Quote Post
Wesser
post Jul 27 2012, 01:15 PM
Post #7


The Assistant

Posts: 84
From: Matera, IT
Joined: 16-June 11



Indeed, it was my first try. Unfortunately, the compiler ignores the register keyword in that way. tongue.gif
Go to the top of the page
 
+Quote Post
Silent
post Jul 28 2012, 12:45 PM
Post #8


The master of cut retort

Group Icon

Posts: 239
From: Warsaw, PL
Joined: 21-July 10



Shame it does.

Anyway, untested, but you might alternatively try this too:

Redirect the game to

CODE
void __declspec(naked) CClass__MethodWrapper()
{
    _asm
    {
        mov        [esp], ecx
        call    CClass__Method
        retn 4
    }
}



then just use your 'real' function as

CODE
int CClass__Method(CClass* pclThis, int iArgument)
{
    [...]
}


I hope I wasn't mistaken on the esp part.

Edit:
Edited, my stdcall would screw up the stack.

This post has been edited by Silent: Jul 28 2012, 12:47 PM
Go to the top of the page
 
+Quote Post
Reply to this postStart new topic

2 User(s) are reading this topic (2 Guests and 0 Anonymous Users)
0 Members: