| #pragma pack(push,1) //该结构必须以字节对齐 struct Thunk { BYTE Call; int Offset; WNDPROC Proc; BYTE Code[5]; CMyWnd* Window; BYTE Jmp; BYTE ECX; }; #pragma pack(pop) |
类定义:
| class CMyWnd { public: BOOL Create(...); LRESULT WINAPI WindowProc(UINT,WPARAM,LPARAM); static LRESULT WINAPI InitProc(HWND,UINT,WPARAM,LPARAM); static LRESULT WINAPI stdProc(HWND,UINT,WPARAM,LPARAM); WNDPROC CreateThunk(); WNDPROC GetThunk(){return m_thunk} ... private: WNDPROC m_thunk } |
在创建窗口的时候把窗口过程设定为this->m_thunk,m_thunk的类型是WNDPROC,因此是完全合法的,当然这个m_thunk还没有初始化,在创建窗口前必须初始化:
| WNDPROC CMyWnd::CreateThunk() { Thunk* thunk = new Thunk; /////////////////////////////////////////////// // //系统调用m_thunk时的堆栈: //ret HWND MSG WPARAM LPARAM //------------------------------------------- //栈顶 栈底 /////////////////////////////////////////////// //call Offset //调用code[0],call执行时会把下一条指令压栈,即把Proc压栈 thunk->Call = 0xE8; // call [rel]32 thunk->Offset = (size_t)&(((Thunk*)0)->Code)-(size_t)&(((Thunk*)0)->Proc); // 偏移量,跳过Proc到Code[0] thunk->Proc = CMyWnd::stdProc; //静态窗口过程 |
|