什么是Hook?
Hook:钩子的意思
Hook技术主要指的是拦截程序原有的信息,数据,代码
使得有机会对拦截到的信息数据做处理,然后再交给原来的程序去使用,从而能够截获到程序的关键信息,可以查看,也可以修改
能够修改程序的部分功能
Hook是怎么分类的?
在Windows系统下,有两类Hook:
- Windows消息Hook, Windows提供的能够让程序员截获到所有窗口程序消息的机制
消息Hook也是一种Dll注入手段 自定义Hook(非常普遍的Hook方式,也是通常意义所说的Hook)
Windows消息钩子
SetWindowsHookEx这个函数,能够实现的功能是- 截获系统中所有的窗口程序的消息
- 某一个线程的窗口消息
- 截获到了消息,必然是需要执行自己的代码,自己的代码需要放置在一个dll中,然后消息钩子设置成功之后,会将dll注入到目标进程,从而使得自己的回调函数能够在对方的进程中执行
BTW:窗口程序的消息是被某一个线程获取到的,哪一个线程创建了窗口,哪一个线程就能够获得此窗口的消息。此线程在创建完窗口之后,就变成了GUI线程
HHOOK SetWindowsHookExA(
int idHook, 要截获的是哪种类型的消息
HOOKPROC lpfn, 截获到消息之后,调用的回调函数
HINSTANCE hmod, 回调函数所在的模块,这个模块需要是一个dll
DWORD dwThreadId 填0表示获取系统中所有的窗口的消息,填线程ID就表示仅截获此线程的窗口信息
);
// 当钩子使用完毕之后,卸载钩子
BOOL WINAPI UnhookWindowsHookEx(
_In_ HHOOK hhk //填充返回的句柄
);
在钩子的消息拦截函数的最后,应该调用这个函数,因为程序可能会有多个钩子,新添加的在最上面,为了不影响其他钩子的功能,需要调用这个函数
WINUSERAPI
LRESULT
WINAPI
CallNextHookEx(
_In_opt_ HHOOK hhk, //钩子的句柄
_In_ int nCode,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
inline-Hook原理
内联钩子 修改存储函数地址变量的钩子
在高危代码的首地址处写入跳转指令,跳转到新代码
任何位置,都可以修改为jmp,使其执行到此处时,能够跳转到自定义代码处执行
- 被修改的指令,如果有作用,就需要在自定义代码中,将有用的指令复写一遍,使其能够在自定义代码中执行
- jmp指令一般是5个字节,所以选取的指令最好也是5个字节,如果不是5个字节,那么会发生指令截断。
跳转回来的时候,就需要考虑跳转到完整的指令后去执行程序原本的代码 - jmp指令OPCODE的操作数 = 要跳转的目标地址-hook点所在的地址-5