Hook钩子技术

Hook技术

1 什么是Hook,这个概念应该从何说起???
Hook:是钩子的意思
Hook技术主要指的是拦截程序原有的信息,数据,代码,
1 使得你有机会对拦截到的信息数据做处理。然后再交给原来的程序去使用,从而能够截获到程序的关键信息。可以查看,也可以修改。
2 能够修改程序的部分功能。
2 Hook是怎么分类的??
在windows系统下,有两类Hook:
2.1 windows消息Hook。windows提供的能够让程序员截获到所有窗口程序消息的机制。
消息Hook也是我们的一种Dll注入手段。

 2.2  自定义Hook   非常普遍的Hook方式,也是我们通常意义所说的Hook。
        2.2.1  修改程序的代码,使得其能够执行到Hook者提供的“善意代码”中。  inline-Hook
        2.2.2  修改存储函数地址的变量,当程序从变量中获取函数地址并调用的时候,就会调用到Hook者提供的“善意代码”了。
                  IAT-Hook  
                  IDT-Hook
                  SYSENTR-Hook

3 windows消息钩子的实现的原理以及代码
3.1 windows消息钩子的实现的原理
SetWindowsHookEx这个函数,能够实现的功能是截获
1 系统中所有的窗口程序的消息或者
2 某一个线程的窗口消息。
截获到了消息,必然是需要执行自己的代码,自己的代码需要放置在一个dll中,然后消息钩子设置成功之后,会将dll注入到目标进程,从而使得自己的回调函数能够在对方的进程中执行。
额外的知识点:窗口程序的消息是被某一个线程获取到的,哪一个线程创建了窗口,哪一个线程就能够获得此窗口的消息。此线程在创建完窗口之后,就变成了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);

3.1 消息钩子的代码

#define _countof(a) sizeof(a)/sizeof(a[0])
HHOOK g_Hook = 0;
//拦截消息的回调函数
LRESULT CALLBACK KeyboardProc(
    int code,           // 消息类型
    WPARAM wParam,      // 虚拟码
    LPARAM lParam) {    // 按键信息
    // 判断是否wParam与lParam都有键盘消息,是的话则执行打印操作
    if (code == HC_ACTION) {
        // 将256个虚拟键的状态拷贝到指定的缓冲区中,如果成功则继续
        BYTE KeyState[256] = { 0 };
        if (GetKeyboardState(KeyState)) {
            // 得到第16–23位,键盘虚拟码
            LONG  KeyInfo = lParam;
            UINT  keyCode = (KeyInfo >> 16) & 0x00ff;
            WCHAR wKeyCode = 0;
            ToAscii((UINT)wParam, keyCode, KeyState, (LPWORD)&wKeyCode, 0);
            // 将其打印出来
            WCHAR szInfo[512] = { 0 };
            swprintf_s(szInfo, _countof(szInfo), L"Hook_%c", (char)wKeyCode);
            OutputDebugString(szInfo);
            return 0;
        }
    }
    return CallNextHookEx(g_Hook, code, wParam, lParam);
}
//开启Hook的函数
void OnHook()
{
    HMODULE hModule =  GetModuleHandle(L"MessageHookdll.dll");
    g_Hook = SetWindowsHookEx(
        WH_KEYBOARD,
        KeyboardProc,
        hModule,
        NULL
    );
}
//关闭Hook的函数
void UnHook()
{
    if (g_Hook!=0)
    {
        UnhookWindowsHookEx(g_Hook);
        g_Hook = 0;
    }
}

被拦截到消息的程序,也被注入了dll。

4 自定义钩子:
自定义钩子两大类:内联钩子 修改存储函数地址变量的钩子
4.1 什么是内联钩子 inline-Hook

任何位置,都可以修改为jmp,使其执行到此处时,能够跳转到我们自己的代码去执行:
1 被修改的指令,是否是有用的,如果是有用的,那么你就需要在你自己的代码中,将有用的指令写一遍,使其在你代码中能够执行。
2 jmp指令一般是5个字节,所以我们选取的指令最好也是5个字节,如果不是5个字节,那么会发生指令截断,跳转回来的时候,就需要考虑跳转到完整的指令后去执行程序本身的代码。
3 jmp指令OPCODE的操作数怎么求得,也是Hook的关键知识点

jmp指令OPCODE的操作数 = 要跳转的目标地址-hook点所在的地址-5


–转载15pb高老师

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值