注入(4)--消息钩子注入(SetWindowsHookEX)

来源:互联网 发布:人工智能入门教程 编辑:程序博客网 时间:2024/05/08 04:50
SetWindowsHookEx函数是微软提供给程序开发人员进行消息拦截的一个API。不过,他的功能不仅可以用作消息拦截,还可以进行DLL注入。
SetWindowsHookEx原型声明如下:
WINUSERAPIHHOOKWINAPISetWindowsHookExW(    _In_ int idHook,    _In_ HOOKPROC lpfn,    _In_opt_ HINSTANCE hmod,    _In_ DWORD dwThreadId);

idHook:指示将要安装的挂钩处理过程的类型。例如,idHook为“WH_CALLWNDPROC”时代表安装一个挂钩处理过程,在系统将消息发送至目标窗口处理过程之前对该消息进行监视。
lpfn:指向相应的挂钩处理过程。
hmod:指示了一个DLL句柄。该DLL包含参数lpfn所指向的挂钩处理过程
dwThreadId:指示了一个线程标示符,挂钩处理过程与线程相关。若此参数值为0,则该挂钩处理过程与所有现存的线程相关。
如果去掉消息钩子,可以用UnhookWindowsHookEx函数

Windows消息处理流程:


插入SetWindowsHookEx之后流程:


下面来看代码:

// MessageHook.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <Windows.h>#include <Tlhelp32.h>BOOL SetWinHookInject(WCHAR * wzDllPath, WCHAR * wzProcessName);UINT32 GetTargetThreadIdFromProcessName(WCHAR *ProcessName);int main(){WCHAR wzProcessName[0x20] = L"Target.exe";WCHAR wzDllFullPath[0x20] = L"MessageHookDll.dll";if (!SetWinHookInject(wzDllFullPath, wzProcessName)){OutputDebugString(L"Set Hook Unsuccess!\r\n");return 0;}OutputDebugString(L"Inject Success!\r\n");    return 0;}////利用Windows API SetWindowsHookEx实现注入DLL//BOOL SetWinHookInject(WCHAR * wzDllPath, WCHAR * wzProcessName){HMODULE ModuleHandle = NULL;BOOL    bOk = FALSE;DWORD   FunctionAddress = NULL;UINT32  dwThreadId = 0;HHOOK   g_hHook = NULL;PVOID   pShareM = NULL;OutputDebugString(L"[+] SetWinHKInject Enter!\n");ModuleHandle = LoadLibrary(wzDllPath);if (!ModuleHandle){OutputDebugString(L"[+] LoadLibrary error!\n");goto Exit;}FunctionAddress = (DWORD)GetProcAddress(ModuleHandle, "MyMessageProc");if (!FunctionAddress){OutputDebugString(L"[+] GetProcAddress error!\n");goto Exit;}dwThreadId = GetTargetThreadIdFromProcessName(wzProcessName);if (!dwThreadId)goto Exit;//设消息钩子g_hHook = SetWindowsHookEx(WH_GETMESSAGE,//WH_KEYBOARD,//WH_CALLWNDPROC,(HOOKPROC)FunctionAddress,ModuleHandle,dwThreadId);if (!g_hHook){OutputDebugString(L"[-] SetWindowsHookEx error !\n");goto Exit;}OutputDebugString(L"[!] SetWinHKInject Exit!\n");bOk = TRUE;Exit:if (ModuleHandle)FreeLibrary(ModuleHandle);return bOk;}//通过进程名获得线程IDUINT32 GetTargetThreadIdFromProcessName(WCHAR *ProcessName){PROCESSENTRY32 pe;HANDLE SnapshotHandle = NULL;HANDLE ProcessHandle = NULL;BOOL Return, ProcessFound = FALSE;UINT32 pTID, ThreadID;SnapshotHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (SnapshotHandle == INVALID_HANDLE_VALUE){MessageBox(NULL, L"Error: unable to create toolhelp snapshot", L"Loader", NULL);return FALSE;}pe.dwSize = sizeof(PROCESSENTRY32);Return = Process32First(SnapshotHandle, &pe);while (Return){if (_wcsicmp(pe.szExeFile, ProcessName) == 0){ProcessFound = TRUE;break;}Return = Process32Next(SnapshotHandle, &pe);pe.dwSize = sizeof(PROCESSENTRY32);}CloseHandle(SnapshotHandle);//通过fs寄存器获取TID_asm {mov eax, fs:[0x18]add eax, 36mov[pTID], eax}ProcessHandle = OpenProcess(PROCESS_VM_READ, FALSE, pe.th32ProcessID);ReadProcessMemory(ProcessHandle,(LPCVOID)pTID, &ThreadID, 4, NULL);CloseHandle(ProcessHandle);return ThreadID;}

// dllmain.cpp : 定义 DLL 应用程序的入口点。#include "stdafx.h"#include <Windows.h>#pragma data_seg(SHARD_SEG_NAME)static HHOOK g_hHook;#pragma data_seg()BOOL APIENTRY DllMain( HMODULE hModule,                       DWORD  ul_reason_for_call,                       LPVOID lpReserved ){switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:{////加入你想在目标进程空间HOOK的代码//MessageBox(NULL, L"Inject Success!", L"Message", 0);}case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:break;}return TRUE;}__declspec(dllexport)LRESULT MyMessageProcess(int Code, WPARAM wParam, LPARAM lParam){////你自己对消息的处理//return CallNextHookEx(g_hHook, Code, wParam, lParam);}

0 0