3

I am trying to hook an undocumented function which has the signature:

(void(__thiscall*)(int arg1, int arg2))0x6142E0;

I have looked at the detours sample "member" where it explains:

By default, C++ member functions use the __thiscall calling convention. In order to Detour a member function, both the trampoline and the detour must have exactly the same calling convention as the target function. Unfortunately, the VC compiler does not support a __thiscall, so the only way to create legal detour and trampoline functions is by making them class members of a "detour" class.

In addition, C++ does not support converting a pointer to a member function to an arbitrary pointer. To get a raw pointer, the address of the member function must be moved into a temporary member-function pointer, then passed by taking it's address, then de-referencing it. Fortunately, the compiler will optimize the code to remove the extra pointer operations.

I have copied some code from the example and modified it but I cant seem to get this to work(original example code here):

class CDetour {
public:
    void Mine_Target(int arg1, int arg2);
    static void (CDetour::* Real_Target)(int arg1, int arg2);
};

void CDetour::Mine_Target(int arg1, int arg2) {
    printf("  CDetour::Mine_Target! (this:%p)\n", this);
    (this->*Real_Target)(arg1, arg2);
}

void (CDetour::* CDetour::Real_Target)(int arg1, int arg2) = (void(CDetour::*)(int arg1, int arg2)) (0x6142E0);

void hoo()
{
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    DetourAttach(&(PVOID&)CDetour::Real_Target, (PVOID)(&(PVOID&)CDetour::Mine_Target));
    DetourTransactionCommit();
}

I am not sure how to get this to work. The a bow code has two compiler errors:

void (CDetour::* CDetour::Real_Target)(int arg1, int arg2) = (void(CDetour::*)(int arg1, int arg2)) (0x6142E0);
//Error C2440   'type cast': cannot convert from 'int' to 'void (__thiscall CDetour::* )(int,int)'

and:

DetourAttach(&(PVOID&)CDetour::Real_Target, (PVOID)(&(PVOID&)CDetour::Mine_Target));
//Error C2440   'type cast': cannot convert from 'void (__thiscall CDetour::* )(int,int)' to 'PVOID &'

I hope someone can help me in the right direction because I am bout to give up on hooking __thiscall functions...

I am considering writing a global "__declspec(naken) void MyFunc(int, int)" function with inline assembly in order to preserve the "this pointer" as suggested here.

Community
  • 1
  • 1
Michael
  • 892
  • 2
  • 10
  • 28
  • Does this answer your question? [Detours - Hooking a Classes Member Function - Syntax for setting function offset of target?](https://stackoverflow.com/questions/10559323/detours-hooking-a-classes-member-function-syntax-for-setting-function-offset) – theultramage Jun 23 '22 at 16:28

2 Answers2

0

Try using a more powerful alternative http://www.nektra.com/products/deviare-api-hook-windows/deviare-in-process/ which is open source.

Paul Exchange
  • 2,637
  • 3
  • 26
  • 33
  • Unfortunately, Deviare only does it nicely in CSharp mode, using the builtin Type.InvokeMember() reflection-based mechanism. In its C-based NktHookLib, it retypes a helper pointer's memory location to void** and then dereferences it to write the numeric offset. Same as in my sample at https://stackoverflow.com/a/50647835/2057095 , This works for simple code but will crash in the presence of virtual multiple inheritance, for example, where the helper pointer could actually be complex 32-byte data structure. – theultramage Jun 23 '22 at 16:23
-1

Detours is fairly old. Explicit compiler support for __thiscall is fairly new. Looks like there's support for it in Visual C++ 2005 and later. It seems the Detours documentation was never updated.

eh9
  • 7,340
  • 20
  • 43