meet-dream

a simple template hook class for function and member functions

Some times,we need too hook some function to do something that's not so easy to do with normally add somecode.A solution is to hook focused functions and interface.Here is a template hook class maybe help your work easier,which complie with vs2005.It midify the jmp table to replace the function,maybe not properly  for other compliers.

class HookPfn
{
 struct make_writeable
 {
  void* p;
  MEMORY_BASIC_INFORMATION mbi_thunk;
  make_writeable(void* _p):p(_p)
  {
   VirtualQuery(p, &mbi_thunk, sizeof(MEMORY_BASIC_INFORMATION));
   VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize, PAGE_READWRITE, &mbi_thunk.Protect);
  
  }
  ~make_writeable()
  {
   VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize, mbi_thunk.Protect,&mbi_thunk.Protect);
  }
 };
public:
 template<class F>
 void restore(F pfn,unsigned long handle)
 {
  
  void* p;
  __asm mov eax,[pfn]
  __asm mov dword ptr[p],eax
  make_writeable write(p);
  __asm push ecx
  __asm mov eax,pfn
  __asm inc eax
  __asm mov ecx,handle
  __asm mov dword ptr[eax],ecx
  __asm pop ecx
 }
 template<class F1,class F2>
 unsigned long redirect(F1 pfn1,F2 pfn2)
 {
   //should use restrict object prevent F1 and F2 's arguments and type not same
  void* p;
  __asm mov eax,[pfn1]
  __asm mov dword ptr[p],eax
  make_writeable write(p);

  unsigned long bas1,bas2,of1,of2,of;
  __asm push ecx
  __asm mov eax,pfn1
  __asm mov bas1,eax
  __asm inc eax
  __asm mov ecx,dword ptr[eax]
  __asm mov of1,ecx

  __asm mov eax,pfn2
  __asm mov bas2,eax
  __asm inc eax
  __asm mov ecx,dword ptr[eax]
  __asm mov of2,ecx

  of=(bas2-bas1+of2-of1)+of1;

  __asm mov eax,pfn1
  __asm inc eax
  __asm mov ecx,of
  __asm mov dword ptr[eax],ecx
  __asm pop ecx
  return of1;
 }
 
};

class mmt
{
public:
 void donothing()
{
}
 void donothing(int)
{
}
  void dosomething()
{
}
};

void fastcall(int a,int b)
{
}
void askcall(int,int)
{
}


It can be used as example:
int main()
{
 HookMemberFunction sh;
 unsigned long hd=sh.redirect(&fastcall,&askcall);//test api
 fastcall(0,0);//two function
 askcall(0,0);
 sh.restore(&fastcall,hd);
 askcall(0,0);
 fastcall(0,0);
//test overlay functions(donothing)
 typedef void (mmt::*sp)(void);
 sp p1=&mmt::dosomething;
 sp p2=&mmt::donothing;
 hd=sh.redirect(p1,p2);
 mmt mt;//a class
 mt.donothing();
 mt.dosomething();
 sh.restore(p1,hd);
 mt.donothing();
 mt.dosomething();

}
Although it can be work right,addtionly we may be use it not properly.Youcan add some strict class to prevent bad use of it by check if the argument and return type is strictly same.,if you need it.

posted on 2007-03-05 23:51 meet-dream 阅读(645) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理