龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > VC开发 >

MFC:thunk技术实现窗口类的封装[图](2)

时间:2009-12-30 15:42来源:未知 作者:admin 点击:
分享到:
类定义: 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,WP

  类定义:

   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;  //静态窗口过程
 
   //pop ecx,Proc已压栈,弹出Proc到ecx
  thunk->Code[0] = 0x59;  //pop ecx
  
  //mov dword ptr [esp+0x4],this
  //Proc已弹出,栈顶是返回地址,紧接着就是HWND了。
  //[esp+0x4]就是HWND
  thunk->Code[1] = 0xC7;  // mov
  thunk->Code[2] = 0x44;  // dword ptr
  thunk->Code[3] = 0x24;  // disp8[esp]
  thunk->Code[4] = 0x04;  // +4
  thunk->Window = this;
  
  //偷梁换柱成功!跳转到Proc
  //jmp [ecx]
  thunk->Jmp = 0xFF;     // jmp [r/m]32
  thunk->ECX = 0x21;     // [ecx]
  
  m_thunk = (WNDPROC)thunk;
  return m_thunk;
  }

精彩图集

赞助商链接