本文演示如何使用自定义消息来实现进程间通信。
原理:使用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博客文章一键转载插件