首页
社区
课程
招聘
[原创]代码实战硬件断点hook
发表于: 2022-1-18 23:07 11621

[原创]代码实战硬件断点hook

2022-1-18 23:07
11621

见字如面,我是东北码农。

上文我们介绍了硬件断点,大家可以回顾一下。本文将介绍使用硬件断点+veh,实现硬件断点hook。

关注后,聊天框回复“硬件断点hook”,可以获取本文源码。

硬件断点这个手法,我还是分析外挂时学到的。开始做反外挂时候,只会用xuetr、pchunter等工具查看游戏进程的inlinehook,分析修改了游戏的哪些代码,然后再防御。然后有一天,我发现了一个外挂不按套路出牌,没有修改任何代码实现了透视功能,我就很纳闷这个外挂是怎么实现的呢,不改代码我怎么防啊?

后来经过不断学习,才知道hook的方式有很多种,硬件断点hook就是其中一种比较隐蔽的hook方式,可以在不修改源函数的前提实现hook,这一点比inlinehook强。

我们先来介绍一下VEH,先放一段微软官方描述。

参考资料:https://docs.microsoft.com/en-us/windows/win32/debug/vectored-exception-handling

<font color=gray size=2>
Vectored exception handlers are an extension to structured exception handling. An application can register a function to watch or handle all exceptions for the application. Vectored handlers are not frame-based, therefore, you can add a handler that will be called regardless of where you are in a call frame. Vectored handlers are called in the order that they were added, after the debugger gets a first chance notification, but before the system begins unwinding the stack.
</font>

大概意思是,程序可以注册异常回调函数链表。当程序触发异常时,回调函数就会按照用户指定的顺序依次调用。

向VEH链注册一个异常处理函数,可以使用windows提供的API,

接下来看一下异常处理函数,PVECTORED_EXCEPTION_HANDLER 的定义:

唯一的参数_EXCEPTION_POINTERS指向异常信息,定义如下:

定义如下:

异常处理函数的返回值很重要,控制着异常处理的后续行为:

<font color=gray size=2>
To return control to the point at which the exception occurred, return EXCEPTION_CONTINUE_EXECUTION (0xffffffff). To continue the handler search, return EXCEPTION_CONTINUE_SEARCH (0x0).

</font>

返回-1:异常已处理,继续执行;

返回0:继续调用VEH链的其它处理函数。

介绍完硬件断点和veh后,我们就可以实现硬件断点hook了。我们先介绍一下思路:

设置VEH链异常处理函数。

设置硬件断点,监控原函数的执行事件。

执行原函数时,会触发异常调用我们的异常处理函数。

异常处理函数判断,如果是原函数地址,则修改rip寄存器,跳转到hook函数。

异常处理函数,xx_hw_bp_veh的实现一会再介绍。

先记录一下原函数和hook函数的映射关系,再使用上文硬件断点封装好的xx_set_hw_bp设置硬件断点。

先通过异常地址,找到对应的hook函数地址。若找到,则修改Rip(指令寄存器)实现跳转;找不到则不是我们关心的异常,交给VEH链继续处理吧。

使用时先制作跳板,再hook。制作跳板复用inlinehook的代码。由于不修改代码,所以跳板值需要复制一条指令即可。复制的代码少,所以也基本不用考虑重定位问题。

欢迎大家点赞、转发、再看、留言交流~

 
 
 
 
 
 
PVOID AddVectoredContinueHandler(
  ULONG                       First,
  PVECTORED_EXCEPTION_HANDLER Handler
);
PVOID AddVectoredContinueHandler(
  ULONG                       First,
  PVECTORED_EXCEPTION_HANDLER Handler
);
LONG PvectoredExceptionHandler(
  [in] _EXCEPTION_POINTERS *ExceptionInfo
)
LONG PvectoredExceptionHandler(
  [in] _EXCEPTION_POINTERS *ExceptionInfo
)
 
typedef struct _EXCEPTION_POINTERS {
  PEXCEPTION_RECORD ExceptionRecord;// 异常信息记录
  PCONTEXT          ContextRecord;// 寄存器信息
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
typedef struct _EXCEPTION_POINTERS {
  PEXCEPTION_RECORD ExceptionRecord;// 异常信息记录
  PCONTEXT          ContextRecord;// 寄存器信息
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
 
static bool xx_init_hwbp_hook() {
  return xx_add_veh(CALL_FIRST, xx_hw_bp_veh);
}
static bool xx_init_hwbp_hook() {
  return xx_add_veh(CALL_FIRST, xx_hw_bp_veh);
}
class xx_hw_bp
{
public:
  struct bp_info {
    void* src_ = nullptr;
    void* dst_ = nullptr;
  };
public:
  void hook(void* src,void* dst,HANDLE thread,int idx)
{
    //记录原函数与hook函数关系。
    // TODO idx check
    info_[idx].src_ = src;
    info_[idx].dst_ = dst;
    // 设置硬件断点
    xx_set_hw_bp(thread, idx, src, RW_EXE);
  }
    // 获取原函数与hook函数映射
  void* get_dst(void* src) {
    for (int i = 0; i < 4; ++i) {
      if (src == info_[i].src_)
      {
        return info_[i].dst_;
      }
    }
    return nullptr;
  }
  bp_info info_[4];
};
 
xx_hw_bp g_hwbp_;// 全局类,方便异常处理函数访问
class xx_hw_bp
{
public:
  struct bp_info {
    void* src_ = nullptr;
    void* dst_ = nullptr;
  };
public:
  void hook(void* src,void* dst,HANDLE thread,int idx)
{
    //记录原函数与hook函数关系。
    // TODO idx check
    info_[idx].src_ = src;
    info_[idx].dst_ = dst;
    // 设置硬件断点
    xx_set_hw_bp(thread, idx, src, RW_EXE);
  }

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 5
支持
分享
最新回复 (1)
雪    币: 14872
活跃值: (6093)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
楼主忘记了还有SEH
2022-1-19 09:27
0
游客
登录 | 注册 方可回帖
返回
//