什么是Hook?

Hook:钩子的意思
Hook技术主要指的是拦截程序原有的信息,数据,代码
使得有机会对拦截到的信息数据做处理,然后再交给原来的程序去使用,从而能够截获到程序的关键信息,可以查看,也可以修改
能够修改程序的部分功能

Hook是怎么分类的?

在Windows系统下,有两类Hook:

  • Windows消息Hook, Windows提供的能够让程序员截获到所有窗口程序消息的机制
    消息Hook也是一种Dll注入手段
  • 自定义Hook(非常普遍的Hook方式,也是通常意义所说的Hook)

    • 修改程序的代码,使得其能够执行到Hook者提供的“善意代码”中(inline-Hook)
    • 修改存储函数地址的变量,当程序从变量中获取函数地址并调用的时候,就会调用到Hook者提供的“善意代码”
      IAT-Hook
      IDT-Hook
      SYSENTR-Hook

      Windows消息钩子实现的原理

  • Windows消息钩子
    SetWindowsHookEx这个函数,能够实现的功能是

    • 截获系统中所有的窗口程序的消息
    • 某一个线程的窗口消息
  • 截获到了消息,必然是需要执行自己的代码,自己的代码需要放置在一个dll中,然后消息钩子设置成功之后,会将dll注入到目标进程,从而使得自己的回调函数能够在对方的进程中执行

BTW:窗口程序的消息是被某一个线程获取到的,哪一个线程创建了窗口,哪一个线程就能够获得此窗口的消息。此线程在创建完窗口之后,就变成了GUI线程

  1. HHOOK SetWindowsHookExA(
  2. int idHook, 要截获的是哪种类型的消息
  3. HOOKPROC lpfn, 截获到消息之后,调用的回调函数
  4. HINSTANCE hmod, 回调函数所在的模块,这个模块需要是一个dll
  5. DWORD dwThreadId 0表示获取系统中所有的窗口的消息,填线程ID就表示仅截获此线程的窗口信息
  6. );
  1. // 当钩子使用完毕之后,卸载钩子
  2. BOOL WINAPI UnhookWindowsHookEx(
  3. _In_ HHOOK hhk //填充返回的句柄
  4. );

在钩子的消息拦截函数的最后,应该调用这个函数,因为程序可能会有多个钩子,新添加的在最上面,为了不影响其他钩子的功能,需要调用这个函数

  1. WINUSERAPI
  2. LRESULT
  3. WINAPI
  4. CallNextHookEx(
  5. _In_opt_ HHOOK hhk, //钩子的句柄
  6. _In_ int nCode,
  7. _In_ WPARAM wParam,
  8. _In_ LPARAM lParam);

inline-Hook原理

内联钩子 修改存储函数地址变量的钩子
在高危代码的首地址处写入跳转指令,跳转到新代码
任何位置,都可以修改为jmp,使其执行到此处时,能够跳转到自定义代码处执行

  1. 被修改的指令,如果有作用,就需要在自定义代码中,将有用的指令复写一遍,使其能够在自定义代码中执行
  2. jmp指令一般是5个字节,所以选取的指令最好也是5个字节,如果不是5个字节,那么会发生指令截断。
    跳转回来的时候,就需要考虑跳转到完整的指令后去执行程序原本的代码
  3. jmp指令OPCODE的操作数 = 要跳转的目标地址-hook点所在的地址-5
    image.png