How do I thunk an arbitrary function with an arbitrary (fixed) number of arguments, on x86 and x64?
(I don\'t need floating-point, SSE, or the like. The arguments ar
Here is a modification for thiscall functions
The vbind() stub generator above is meant to be used for C++ member functions as well, although it is not clear how to proceed. Here's what I've come up with:
// experimental x64 thiscall thunking
class TestHook {
public:
typedef void (TestHook::*TMFP)();
TestHook(DWORD num)
{
m_context = num;
union { void* (*func)(); TMFP method; } addr;
addr.method = (TMFP)CBTHook_stub;
// pass "this" as the first fixed argument
void *args[] = { this };
size_t thunk_size = vbind(addr.func, 4, m_thunk, 0, args, 1);
ATLASSERT(thunk_size < sizeof(m_thunk));
unsigned long old;
VirtualProtect(m_thunk, thunk_size, PAGE_EXECUTE_READWRITE, &old);
FlushInstructionCache(GetCurrentProcess(), m_thunk, thunk_size);
}
FARPROC GetThunk() const { return (FARPROC)(void*)m_thunk; }
protected:
// test thiscall: one integer and two 8-byte arguments
LRESULT CBTHook_stub(int nCode, WPARAM wParam, LPARAM lParam)
{
ATLTRACE(_T("this=%p, code=%d, wp=%x, lp=%x, context=%x\n"), this, nCode, wParam, lParam, m_context);
return lParam;
}
DWORD m_context;
unsigned char m_thunk[1024]; // fixed; don't know size required apriori!
};
#ifndef _WIN64
#error does not work for win32
#endif
void main(void)
{
TestHook tmp(0xDeadBeef);
HOOKPROC proc = (HOOKPROC)tmp.GetThunk();
ATLTRACE(_T("object %p return value=%d\n"), &tmp, proc(1, 2, 3));
}
I am not an assembly gury but this code correctly stubs into the member function for 64 bit code. There are some implicit assumptions (I'm not 100% sure if valid, please correct me if I'm wrong):
in x64 (amd / microsoft VS) all function arguments are passed as 8 bytes long. So although vbind was just for pointer-type arguments, it is possible to thunk into other function prototypes (e.g. the HOOKPROC takes one integer and two __int64)
"this" pointer is passed as the first stack argument in x64 instead of ECX. I used the bounded argument to pass "this" pointer and provide context to the C++ object