通用 Thunk

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

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

  2. 被调用者如何得到参数与返回地址?(它希望何种方式?)

  一个和上述普通C函数具有相同参数列表,使用__stdcall的成员函数,希望参数,返回地址和this指针像这样准备 :

  参数 m <- ESP + 8 + N

  参数 m-1

  …

  参数 1 < -ESP + 8

  this < -ESP +4

  返回地址 <-ESP

  3. 被调用者如何返回?

  它使用 RET N+4 返回。

  所以我们的工作是在参数1和返回地址之间插入this指针,然后跳转到成员函数。

  (我们插入了一个this指针使得栈增加了4,所以被调用者使用 RET N+4 是正确的)

  在设计 StdToStd 之前,让我们定义一些有用的宏。

  相信我,这将使得源代码更加容易阅读和改进。

MachineCodeMacro.h
#undef CONST
#undef CODE
#undef CODE_FIRST
#ifndef THUNK_MACHINE_CODE_IMPLEMENT
#define CONST const
#define CODE(type,name,value) type name;
#define CODE_FIRST(type,name,value) type name;
#else
#define CONST
#define CODE(type,name,value) ,name(value)
#define CODE_FIRST(type,name,value) :name(value)
#endif
ThunkBase.h
#include “MachineCodeMacro.h”
namespace Thunk {
  typedef unsigned char byte;
  typedef unsigend short word;
  typedef int dword;
  typedef const void* dword_ptr;
}
StdToStd.h
#include <ThunkBase.h>
#define STD_TO_STD_CODES()          
/*  POP EAX  */              
CONST  CODE_FIRST(byte,POP_EAX,0x58)      
/*  PUSH m_this  */            
CONST  CODE(byte,PUSH,0x68)        
    CODE(dword_ptr,m_this,0)        
/*  PUSH EAX  */              
CONST  CODE(byte,PUSH_EAX,0x50)        
/*  JMP m_memFunc(offset)  */        
CONST  CODE(byte,JMP,0xE9)          
CONST  CODE(dword,m_memFunc,0)
namespace Thunk {
  class StdToStd {
  public:
    StdToStd(const void *Obj = 0,int memFunc = 0);
    StdToStd(const StdToStd &src);
    const void* Attach(const void *newObj);
    int Attach(int newMemFunc);
  private:
#pragma pack( push ,1 )
  STD_TO_STD_CODES()
#pragma pack( pop )
};
StdToStd.cpp
#include <StdToStd.h>
#define THUNK_MACHINE_CODE_IMPLEMENT
#include <MachineCodeMacro.h>
namespace Thunk {
  StdToStd::StdToStd(dword_ptr Obj,dword memFunc)
    STD_TO_STD_CODES()
  {
    Attach(Obj);
    Attach(memFunc);
  }
  StdToStd::StdToStd(const StdToStd &src)
    STD_TO_STD_CODES()
  {
    Attach(src.m_this);
    Attach( GetTransferDST(&src.JMP) );
  }
  dwrod_ptr StdToStd::Attach(dword_ptr newObj) {
    dword_ptr oldObj = m_this;
    m_this = newObj;
    return oldObj;
  }
  dword StdToStd::Attach(dword newMemFunc) {
    dword oldMemFunc = GetTransferDST(&JMP);
    SetTransferDST(&JMP,newMemFunc);
    return oldMemFunc;
  }
}
宏 CONST CODE_FIRST(byte,POP_EAX,0x58) 在StdToStd.h 中,将被替换成: “const byte POP_EAX;”

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

正在加载评论...