不以物喜,不以己悲

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;
	}
	
}
posted @ 2021-09-06 10:34  这种人  阅读(164)  评论(0编辑  收藏  举报