![]() ![]() |
![]() 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) { // ... } |
![]() 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 |
![]() Post #3 | |
![]() The master of cut retort ![]() 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 |
![]() 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. |
![]() 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. ![]() 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 |
![]() Post #6 | |
![]() The master of cut retort ![]() Posts: 239 From: Warsaw, PL Joined: 21-July 10 ![]() | Register? Wow, I didn't know about that keyword ![]() 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 ![]() |
![]() 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. ![]() |
![]() Post #8 | |
![]() The master of cut retort ![]() 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 |
![]() ![]() |