Sunday, April 24, 2016

Clean C++ Member Function Detouring

Whenever I write detour code related to member functions things tend to get messy so today I decided not to be lazy and to do it properly. In order to write a detour for a member function cleanly you can do the following:

* Stop using __fastcall and use __thiscall as MSVC has support for declaring functions with __thiscall now
* Rebuild the entire class with its members, inheritance hierarchy and even the member functions just as if it were your code
* Use static pointers-to-member functions to manage your trampoline pointers
* Add support for member function detouring to your detour code
* Simple functions that return the address for each method

Example:

As an example I'll use a portion of Skype's Socket class. The first step is reversing a method (class function) that utilizes the data structure/class that is Socket so I found the Send/Receive methods which are Socket::Send and Socket::Receive.

Socket::Send Signature -

Socket::Send Pattern -

Socket::Receive Signature -
Socket::Receive Pattern -

Inside of hex-rays right-click the signature of the pseudo-subroutine and click 'Create new struct type' and you have the members declared for you.

Hex-rays gave me this data structure:

Now there's a start for creating the rest of the class. Now add the simple functions that return the address of the two methods after using a find pattern (or a hard-coded address depending on what you do).


At this point you know the signature of the methods Socket::Send and Socket::Receive and you have the members too (probably not every member). At this point you can construct a portion of the class using what you have and come up with something like this:


My definition of Socket::Send and Socket::Receive can be used when I want to call the function manually but I can also use it as my detour function that replaces the real Socket::Send and Socket::Receive. In order detour a member function you have to be able to store a pointer to it and for this you need a special cast which kokole posted:


In your normal detour class if you already provide a templated constructor for accepting the target and detour then just create a specialization like I did:


One final issue that you'll come across is declaring the trampoline. Normally I see people declaring trampolines as global variables that are pointer-to-functions but casting to a pointer-to-member function type isn't possible so you can't do:
But what you can do is use the __thiscall calling convention. Don't make the same mistake I did and assume __thiscall will do some magic that'll just pass on ecx to the function being called. The first parameter in a __thiscall pointer-to-member function declaration is a pointer to the class type. So what I did was:


I declared the trampolines oSocketSend and oSocketReceive as static objects variables inside of the class because it'll be easier to identify it later using Socket:Socket etc. Of course you'll have to define the variable in your implementation file (.cpp).

And yeah so you can finally write code like this:

Result (some stuff I was working on today):


No comments:

Post a Comment