zoukankan      html  css  js  c++  java
  • HOOK学习

    HOOK学习

    Hook技术又叫钩子函数,在系统没有调用该函数之前,钩子程序就先获取该消息,钩子函数先得到控制权,这时钩子函数既可以加工处理该函数的执行行为,还可以强制结束消息的传递。

    Hook分类

    Hook分为应用层(Ring3)Hook和内核层(Ring0)Hook,应用层Hook适用于x86和x64,而内核层Hook一般仅在x86平台适用。

    应用层Hook:

    • 消息Hook
    • 注入Hook
    • 调试Hook

    消息Hook

    技术原理

    当发生键盘输入事件时,WM_KEYDOWN消息被添加到[OS message queue]。

    OS判断哪个应用程序中发生了事件,然后从[OS message queue]取出消息,添加到相应应用程序的[application message queue]中

    应用程序监视自身的[application message queue],发现新添加的WM_KEYDOWN消息后,调用相应的事件处理程序处理。

    所以,只需要在[OS message queue]和[application message queue]之间安装钩子即可窃取键盘消息,并实现恶意操作。

    Windows函数SetWindowsHookEx()用于设置消息Hook,只需要调用该API就能简单地实现消息Hook。

    SetWindowsHookEx(

    WH_KEYBOARD, //键盘消息

    KeyboardProc,//钩子函数

    hInstance,//钩子函数所在DLL的handle

    0 //该参数用于设定要Hook得线程ID,为0时表示监视所有线程)

    钩子的类型,表示在什么时机调用钩子。

    • WH_CALLWNDPROC(4):安装一个挂钩处理过程,在系统消息发送至目标窗口处理过程之前,对该消息进行监视。WH_CALLWNDPROC钩子监视SendMessage消息的传递,不管是系统内部调用的SendMessage()函数还是用户进程中调用的SendMessage函数。

      SendMessage()把消息直接交给窗口过程WndProc()来处理,WndProc()处理完消息后SendMessage()函数才返回。

      如果设置了WH_CALLWNDPROC类型的钩子,则当SendMessage()把消息交给WndProc时,在WndProc尚未执行前,系统调用CallWndProc钩子函数,钩子函数执行后才执行窗口过程WndProc。

      WH_CALLWNDPROC只能监视消息而不能修改

    • WH_CALLWNDPROCRET(12):安装一个挂钩处理过程,它对已被目标窗口处理过程处理过的消息进行监视。

    • WH_CBT(5):安装一个挂钩处理过程,接受对CBT应用程序有用的消息。

      在窗口激活、创建、销毁、最小化、最大化、移动或改变尺寸的前一刻。系统会调用WH_CBT钩子过程,钩子过程的返回值决定了系统是允许或阻止这些操作。WB_CBT钩子主要用于基于计算机的教学应用。

    • WH_DEBUG(9):安装一个挂钩处理过程以便对其它挂钩处理过程进行调试。

      在调用与系统中的其它钩子关联的钩子过程前,系统会调用WH_DEBUG钩子过程。可以用这个钩子来决定是否允许系统调用其它类型钩子的钩子函数。

    • WH_FOREGROUNDIDLE(11):安装一个钩子处理过程,该处理过程当应用程序的前台线程即将进入空闲状态时被调用,它有助于在空闲时间内执行低优先级的任务。

    • WH_GETMESSAGE(3):安装一个钩子处理过程对发送至消息队列的消息进行监视。让应用能够监视将要被GetMessage或PeekMessage函数返回的消息。可以使用WH_GETMESSAGE钩子来监视鼠标键盘输入,以及其它投递到消息队列的消息。

    • WH_JOURNALPLAYBACK(1):安装一个钩子处理过程,对此前由WH_JOURNALRECORD挂钩处理过程记录的消息进行寄送。

    • WH_JOURNALRECORD(0):安装一个钩子处理过程,对寄送至系统消息队列的输入消息进行记录。

    • WH_KEYBOARD(2):安装一个钩子处理过程对键盘消息进行监视。

    • WH_KEYBOARD_LL(13):此钩子只能在Windows NT中被安装,用来对底层的键盘输入事件进行监视。

    • WH_MOUSE(7):安装一个钩子处理过程,对鼠标消息进行监视。

    • WH_MOUSE_LL(4):此钩子只能安装在Windows NT中,用来对底层的鼠标输入事件进行监视。

    • WH_MSGFILTER(-1):监视由对话框、消息框、菜单栏、或滚动条中输入事件引发的消息。

    • WH_SHELL(10):接收对外壳应用程序有用的通知。

    核心函数:SetWindowsHookEx(),UnhookWindowsHookEx(),CallNextHookEx()

    示例:

    #include "msg.h"
    #include<Windows.h>
    #include<iostream>
    using namespace std;
    
    LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wparam, LPARAM lParam);
    
    //钩子处理函数
    
    LRESULT CALLBACK MouseProc(int nCode, WPARAM wParan, LPARAM lParam);
    LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParan, LPARAM lParam);
    
    HHOOK mouseHook;
    HHOOK keyHook;
    HWND g_hwnd;
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int cmdShow)
    {
    	TCHAR szAppClassName[] = TEXT("DunKaiEDU张三");
    
    	WNDCLASS wc = { 0 };
    	wc.cbClsExtra = 0;
    	wc.cbWndExtra = 0;
    	wc.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH);
    	wc.hCursor = ::LoadCursor(nullptr, IDC_ARROW);
    	wc.hIcon = nullptr;
    	wc.hInstance = hInstance;
    	wc.lpfnWndProc = WindowProc;
    	wc.lpszClassName = szAppClassName;
    	wc.lpszMenuName = nullptr;
    	wc.style = CS_HREDRAW | CS_VREDRAW;
    
    	// 注册窗口类
    	RegisterClass(&wc);
    
    	HWND hwnd = ::CreateWindow(szAppClassName, TEXT("福州成"), WS_OVERLAPPEDWINDOW, 100, 100, 800, 600, nullptr, nullptr, hInstance, nullptr);
    	::g_hwnd = hwnd;
    	::ShowWindow(hwnd, SW_SHOW);
    	::UpdateWindow(hwnd);
    
    	//消息循坏
    	//WIndows应用程序时通过消息机制驱动运行
    	MSG msg = { 0 };
    	while (GetMessage(&msg, nullptr, 0, 0)) 
    	{
    		::TranslateMessage(&msg);
    		::DispatchMessage(&msg);
    	}
    	return 0;
    }
    LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wparam, LPARAM lParam)
    {
    	switch (uMsg)
    	{
    	case WM_CREATE://窗口创建消息
    		//::mouseHook = SetWindowsHookEx(WH_MOUSE, MouseProc, nullptr, ::GetCurrentThreadId());
    		::keyHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, nullptr, ::GetCurrentThreadId());
    		break;
    	case WM_LBUTTONDOWN://鼠标按下消息
    	{
    		MessageBox(hwnd, L"hell", L"sdf", MB_YESNO);
    	}
    	break;
    	case WM_KEYDOWN:
    		MessageBox(nullptr, L"sdf", L"dsfs", MB_OK);
    		break;
    	case WM_MOUSEMOVE:
    	{
    		//根据鼠标当前的位置
    		int x = LOWORD(lParam);
    		int y = HIWORD(lParam);
    		TCHAR str[255] = { 0 };
    		wsprintf(str, L"当前鼠标坐标(%d,%d)", x, y);
    		::SetWindowText(hwnd, str);
    	}
    		break;
    	case WM_CLOSE:
    		{
    		
    		}
    		break;
    	case WM_DESTROY:
    		{
    		PostQuitMessage(0);
    		return 0;
    		}
    		break;
    	}
    	return ::DefWindowProc(hwnd, uMsg, wparam, lParam);
    }
    LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
    	return ::CallNextHookEx(::mouseHook, nCode, wParam, lParam);//传递给下一个钩子函数
    }
    LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
    	if (wParam == VK_F2)
    	{
    		//卸载所有钩子
    		::UnhookWindowsHookEx(::keyHook);
    		return 1;
    	}
    	else
    	{
    		return 1;
    	}
    	
    }
    
  • 相关阅读:
    C语言第五次作业
    C语言第四次作业
    C语言第三次作业

    第一次作业
    C语言第五次作业
    C语言第四次作业
    C语言第三次作业
    C语言理论作业—2
    燕勇鹏-160809318
  • 原文地址:https://www.cnblogs.com/zzr-stdio/p/15232706.html
Copyright © 2011-2022 走看看