通用 Thunk

http://tech.ddvip.com   2008年05月25日    社区交流

内容摘要:这篇文章提出了一种基于Thunk技术,让一个成员函数成为一个回调函数的通用方法。文章主要讨论原理,同时也提供了一份实现和示例。

  1. 保存 the oldESP 和 oldRet。

  2. 将被调用者的返回地址设置到 “member function return here!”。

  3. 将ECX设置为this指针。

  4. 跳转到成员函数

  当成员函数返回后,剩下的thunk代码将修改ESP然后返回到调用者。

  Hook函数被实现为:void __declspec( naked ) ThisToCdecl::Hook() {
  _asm {
    POP EAX      //1
    // p=&m_memFunc; &m_this=p+4; &oldESP=p+9; &oldRet=p+14
    
    // Save ESP
    MOV DWORD PTR [EAX+9],ESP  //3
    ADD DWORD PTR [EAX+9],4    //4
    // Save CallerReturn(by offset)
    //src=&JMP=p+13,dst=CallerReturn,offset=CallerReturn-p-13-5
    MOV ECX,DWORD PTR [ESP]    //3
    SUB ECX,EAX          //2
    SUB ECX,18          //3
    MOV DWORD PTR [EAX+14],ECX  //3
    // Set CalleeReturn
    MOV DWORD PTR [ESP],EAX    //3
    ADD DWORD PTR [ESP],8    //4
    // Set m_this
    MOV ECX,DWORD PTR [EAX+4]  //3
    // Jump to m_memFunc
    JMP DWORD PTR[EAX ]      //2
  }
}
我们使用 CALL offset(dword) 跳转到Hook,这个指令会将返回地址压栈。所以,CALL HOOK之后,堆栈如下 :

  …

  参数 m

  参数m-1

  …

  参数1

  调用者返回地址

  Hook返回地址 <- ESP

来源:vckbase    作者:OwnWaterloo    责编:豆豆技术应用

正在加载评论...