ring3 Inline Hook 恢复(附源码)

链 接: http://bbs.pediy.com/showthread.php?t=145825

最近调试一网游,加了tmd壳,HOOK了三个API:DbgBreakPoint、DbgUiRemoteBreakin、DbgUserBreakPoint,平时调试前都用XT还原,突然想自己试试自己编码还原,于是简单写了个类,用于ring3 Inline Hook的还原。

    先回顾一下ring3 Inline Hook的步骤:
    1、获取被HOOK api的地址
    2、用VirtualProtect为该地址添加写入权限
    3、在该地址写入jmp指令,将代码跳转到自定义的函数。用VirtualProtect将权限改回去
    4、将被修改的指令拷贝到自定义的函数执行,做堆栈平衡和自己的处理后,JMP回去
    比较麻烦的是,被修改的指令的长度处理 和 它是否依赖于状态寄存器或堆栈。这里不考虑多线程情况下正好有一条线程跑到还未被完全修改的代码处,其实也不用考虑,大不了程序异常崩溃。

    还原HOOK的方法很简单,获取被修改处原来的内容,用原来的内容写回去即可。有以下几种办法可以获取原来HOOK的内容:
    1、从PE文件读取,需要算出API距离节头部的偏移,然后从PE文件直接读出来。
    2、拷贝一份DLL后,再载入,然后获取内容再释放载入的DLL
      3、在被HOOK前,先拷贝一份

    我的程序已先于游戏模块初始化,因而我选择第三种方式。代码如下:


//lanbinfeng 2012-01-20
class HookFix
{
public:
  HookFix(char* _dllName,char* _funcname,int _fixLenth)
  {
    m_fixLenth=0;
    m_fixBuffer=NULL;

    HMODULE hDll=::LoadLibrary(_dllName);
    if(hDll==0)
      return;
    char*  pFunction=(char*)::GetProcAddress(hDll,_funcname);
    if(pFunction==NULL)
      return;

    m_fixBuffer  =new char[_fixLenth];
    m_fixLenth  =_fixLenth;
    m_dllName  =_dllName;
    m_funcname  =_funcname;
    memcpy(m_fixBuffer,pFunction,m_fixLenth);
  }

  BOOL fix()
  {
    if(m_fixBuffer==NULL)
      return FALSE;

    HMODULE hDll=::GetModuleHandle(m_dllName.c_str());
    if(hDll==0)
      return FALSE;
    char*  pFunction=(char*)::GetProcAddress(hDll,m_funcname.c_str());
    if(pFunction==NULL)
      return FALSE;

    DWORD tmp;
    ::VirtualProtect(pFunction,m_fixLenth,PAGE_EXECUTE_READWRITE,&tmp);
    memcpy(pFunction,m_fixBuffer,m_fixLenth);
    ::VirtualProtect(pFunction,m_fixLenth,tmp,&tmp);

    delete[] m_fixBuffer;
    m_fixBuffer=NULL;
    return TRUE;
  }
  ~HookFix()
  {
    if(m_fixBuffer!=NULL)
    {
      delete[] m_fixBuffer;
      m_fixBuffer=NULL;
    }
  }
private:
  std::string m_dllName;
  std::string m_funcname;
  int      m_fixLenth;
  char*    m_fixBuffer;
};


///


使用时,直接定义全局变量。构造函数的三个参数分别是:dll名称或路径、api名称、还原长度
HookFix apifix[]={
  HookFix("ntdll.dll","DbgBreakPoint",1),
  HookFix("ntdll.dll","DbgUiRemoteBreakin",5),
  HookFix("ntdll.dll","DbgUserBreakPoint",7)
}; 

在需要还原点的地方执行以下代码
for(int i=0;i<sizeof(apifix)/sizeof(HookFix);i++)
  apifix[i].fix();


该类非常容易改为使用方式2获取原始数据,若使用方式2则不需要先于HOOK定义全局变量。 
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值