#if defined(_M_IX86) #pragma pack(push,1) struct _stdcallthunk { DWORD m_mov; // mov dword ptr [esp+0x4], pThis (esp+0x4 is hWnd) DWORD m_this; // BYTE m_jmp; // jmp WndProc DWORD m_relproc; // relative jmp void Init(DWORD_PTR proc, void* pThis) { m_mov = 0x042444C7; //C7 44 24 0C m_this = PtrToUlong(pThis); m_jmp = 0xe9; m_relproc = DWORD((INT_PTR)proc - ((INT_PTR)this+sizeof(_stdcallthunk))); // write block from data cache and // flush from instruction cache FlushInstructionCache(GetCurrentProcess(), this, sizeof(_stdcallthunk)); } //some thunks will dynamically allocate the memory for the code void* GetCodeAddress() { return this; } }; #pragma pack(pop) #elif defined (_M_ALPHA) // For ALPHA we will stick the this pointer into a0, which is where // the HWND is. However, we don't actually need the HWND so this is OK. #pragma pack(push,4) struct _stdcallthunk //this should come out to 20 bytes { DWORD ldah_at; // ldah at, HIWORD(func) DWORD ldah_a0; // ldah a0, HIWORD(this) DWORD lda_at; // lda at, LOWORD(func)(at) DWORD lda_a0; // lda a0, LOWORD(this)(a0) DWORD jmp; // jmp zero,(at),0 void Init(DWORD_PTR proc, void* pThis) { ldah_at = (0x279f0000 | HIWORD(proc)) + (LOWORD(proc)>>15); ldah_a0 = (0x261f0000 | HIWORD(pThis)) + (LOWORD(pThis)>>15); lda_at = 0x239c0000 | LOWORD(proc); lda_a0 = 0x22100000 | LOWORD(pThis); jmp = 0x6bfc0000; // write block from data cache and // flush from instruction cache FlushInstructionCache(GetCurrentProcess(), this, sizeof(_stdcallthunk)); } void* GetCodeAddress() { return this; } };