进程间通信——自定义消息方式实现(SetWindowsHookEx)

本文演示如何使用自定义消息来实现进程间通信。
原理:使用SetWindowsHookEx给目标进程添加一段HOOK程序,用来处理自定义消息,然后用SendMessage向目标进程发送自定义消息,从而实现进程间通信。

项目分为两部分:设置HOOK的DLL和消息发送程序。

DLL

定义3个函数,分别用于安装钩子,卸载钩子和自定义消息处理函数。其中前两个函数是导出函数,由消息发送程序调用。
代码如下:

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#define _CRT_SECURE_NO_WARNINGS
#include "framework.h"
#include <stdio.h>

HHOOK g_HookProc;
extern "C" void __declspec(dllexport) SetHook(); // 安装HOOK
extern "C" void __declspec(dllexport) UnHook(); // 卸载HOOK
LRESULT CALLBACK MessageHookProc(int nCode, WPARAM wParam, LPARAM lParam); //消息处理函数

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

extern "C" void __declspec(dllexport) SetHook()
{
	g_HookProc = SetWindowsHookEx(WH_CALLWNDPROC, MessageHookProc, GetModuleHandle(TEXT("MessageHook.dll")), 0);
}

extern "C" void __declspec(dllexport) UnHook()
{
	if (NULL != g_HookProc)
		UnhookWindowsHookEx(g_HookProc);
}

LRESULT CALLBACK MessageHookProc(int nCode, WPARAM wParam, LPARAM lParam)  //我们自己的程序处理             
{
	if (nCode == HC_ACTION)
	{
		PCWPSTRUCT pcw = (PCWPSTRUCT)lParam;
		if (pcw->message == WM_USER + 0x1)
		{
			char szBuf[200] = { 0 };
			sprintf(szBuf, "wParam: %d\nlParam: %d\nPID: %d\n", pcw->wParam, pcw->lParam,GetCurrentProcessId());
			MessageBoxA(0, szBuf, "接收到自定义消息", 0);
		}
	}
	return CallNextHookEx(g_HookProc, nCode, wParam, lParam); //继续调用钩子过程
}

其中,安装钩子和卸载钩子由消息发送程序调用,自定义消息处理函数则被目标程序加载后,在目标程序的4GB地址空间内执行,在该函数内获取当前进程id,会发现是目标程序的pid。

消息发送程序

这个程序的工作是设置全局钩子,然后向目标程序发送消息,消息自动转交给自定义消息处理函数MessageHookProc处理。
代码如下:

#include <Windows.h>
#include <stdio.h>

BOOL Inject()
{
	// 安装HOOK
	HMODULE hModule = LoadLibrary(TEXT("MessageHook.dll"));
	if (hModule == NULL)
	{
		printf("LoadLibrary失败\n");
		return FALSE;
	}
	typedef void(*PFNSETHOOK)();
	PFNSETHOOK pFnSetHook = (PFNSETHOOK)GetProcAddress(hModule, "SetHook");
	if (NULL == pFnSetHook)
	{
		printf("获取函数地址失败\n");
		return FALSE;
	}
	pFnSetHook();
	// 发送自定义消息
	HWND hWnd = FindWindow(NULL, TEXT("扫雷"));
	if (!hWnd)
	{
		printf("获取窗口句柄失败\n");
		return FALSE;
	}
	SendMessage(hWnd, WM_USER + 0x1, (DWORD)100, (DWORD)200);
	return TRUE;
}

int main()
{
	Inject();
	return 0;
}

运行结果:
在这里插入图片描述

通过运行结果可以看到,自定义消息已经发送给了扫雷进程,并且由MessageHookProc处理,打印了两个参数和扫雷的PID,另外,可以借助工具查看,我们的DLL已经注入到了扫雷进程中。

在这里插入图片描述


---------------------
作者:hambaga
来源:CSDN
原文:https://blog.csdn.net/Kwansy/article/details/108039802
版权声明:本文为作者原创文章,转载请附上博文链接!
内容解析By:CSDN,CNBLOG博客文章一键转载插件

猜你喜欢

转载自blog.csdn.net/weixin_41875267/article/details/108466863