进程通信——DLL共享节

简介

我们可以在 Dll 中申请一个共享节,当进程加载该 Dll 文件后,不同进程都可以实现对该共享节内存的读写,以此实现进程间的数据共享。其中,共享节的申请方式如下:

#pragma data_seg(".shared")
/* 全局变量, 必须初始化 */
#pragma data_seg()
#pragma comment(linker,"/section:.shared,rws")	// 声明该共享节的属性

//也可以使用以下方式定义全局变量, 必须初始化
//__declspec(allocate("Shared"))LPSTR lpszName = "walker";

/* 全局变量、函数的简便导出方法是在 *.def 文件中直接添加函数声明即可, 不必初始化。
	在程序调用时, 和函数调用一样, 使用 GetProcAddress 函数得到变量地址。
*/

需要注意的是,一般我们会将 Dll 中的全局变量封装在函数中进行操作,而不会直接导出。


在这里插入图片描述

可以看到,此时.shared 段已经具有可读、可写、可执行的权限。


测试代码如下:

Dll代码

#include <windows.h>
#include <TlHelp32.h>
#include <stdio.h>

extern HMODULE g_hModuleOfDll;

#pragma data_seg("shared")
HHOOK g_hHook = NULL;
BYTE g_szBuff[100] = {0};
DWORD g_dwBuffLen = 0;
DWORD g_dwBuffMax = sizeof(g_szBuff);
#pragma data_seg()
#pragma comment(linker,"/section:shared,rws")
BYTE szBuff[100];

// 提权函数:提升为DEBUG权限 (貌似没什么作用)
BOOL EnableDebugPrivilege()
{
	HANDLE hToken;
	BOOL fOk = FALSE;
	if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
	{
		TOKEN_PRIVILEGES tp;
		tp.PrivilegeCount = 1;
		LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);

		tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
		AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);

		fOk = (GetLastError() == ERROR_SUCCESS);
		CloseHandle(hToken);
	}
	return fOk;
}

BOOL Write(LPSTR lpszBuff, DWORD dwBuffLen)
{
	if(g_dwBuffMax < dwBuffLen)
		return FALSE;

	ZeroMemory(g_szBuff, g_dwBuffMax);
	memcpy(g_szBuff, lpszBuff, dwBuffLen);
	g_dwBuffLen = dwBuffLen;
	return TRUE;
}

DWORD Read(LPSTR lpszBuff, DWORD dwBuffLen)
{
	if(dwBuffLen < g_dwBuffLen)
		return 0;
	ZeroMemory(lpszBuff, dwBuffLen);
	memcpy(lpszBuff, g_szBuff, g_dwBuffLen);
	return g_dwBuffLen;
}

DWORD GetWindowThreadID(LPSTR lpszWindowName)
{
	// 初始化
	HANDLE hProcess;
	HANDLE hThreadSnap = NULL;	// 模块快照
	DWORD th32ThreadID = 0;
	DWORD dwPid = 0x00;
	THREADENTRY32 thread32 = { 0 };
	BOOL bMoreOfThread;

	//获取进程句柄
	HWND hwnd = FindWindow(NULL, lpszWindowName);
	if (!hwnd)
	{
		//printf("获取进程句柄失败!\n");
		return FALSE;
	}

	
	GetWindowThreadProcessId(hwnd, &dwPid);
	hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
	
	//获取线程ID
	thread32.dwSize = sizeof(thread32);

	hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
	if (hThreadSnap == INVALID_HANDLE_VALUE)
	{
		//printf("获取线程信息失败!\n");
		return FALSE;
	}

	bMoreOfThread = Thread32First(hThreadSnap, &thread32);
	while (bMoreOfThread)
	{
		if (thread32.th32OwnerProcessID == dwPid)
		{
			th32ThreadID = thread32.th32ThreadID;
			break;
		}
		bMoreOfThread = Thread32Next(hThreadSnap, &thread32);
	}

	CloseHandle(hThreadSnap);

	return th32ThreadID;
}

// 钩子回调函数
LRESULT MessageProc(
	int nCode,
	WPARAM wParam,
	LPARAM lParam)
{
	if (nCode == HC_ACTION)
	{
		PCWPSTRUCT pcw = (PCWPSTRUCT)lParam;
		if (pcw->message == WM_USER + 0x1)
		{
			OutputDebugString("receive data: ");
			OutputDebugString(g_szBuff);
			OutputDebugString("------\n");
			ZeroMemory(szBuff, sizeof(szBuff));
			sprintf(szBuff, "wParam: %d\nlParam: %d\nPID: %d\n", pcw->wParam, pcw->lParam,GetCurrentProcessId());
			//MessageBoxA(0, szBuff, "接收到自定义消息", 0);
			OutputDebugString(szBuff);
		}
	}
	//return TRUE;
	return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}

// 设置全局钩子
BOOL SetGlobalHook(int idHook, LPSTR lpszWindowName)
{
	DWORD threadID = GetWindowThreadID(lpszWindowName);
	if(!threadID)
	{
		MessageBox(NULL, "获取目标进程PID失败!", "note", MB_OK);
		return FALSE;
	}

	g_hHook = SetWindowsHookEx(idHook, (HOOKPROC)MessageProc, g_hModuleOfDll, threadID);
	if (NULL == g_hHook)
	{
		return FALSE;
	}
	return TRUE;
}

// 卸载钩子
BOOL UnsetGlobalHook()
{
	if (g_hHook)
	{
		UnhookWindowsHookEx(g_hHook);
		return TRUE;
	}
	else
		return FALSE;
}

测试程序代码

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

int main(int argc, CHAR* argv[])
{
	typedef BOOL(*typedef_SetGlobalHook)(int idHook, LPSTR lpszWindowName);
	typedef BOOL(*typedef_UnsetGlobalHook)();
	typedef BOOL(*typedef_Write)(LPSTR lpszBuff, DWORD dwBuffLen);
	typedef DWORD(*typedef_Read)(LPSTR lpszBuff, DWORD dwBuffLen);
	typedef BOOL(*typedef_CreateSharedMemory)();
	HMODULE hDll = NULL;
	typedef_SetGlobalHook SetGlobalHook = NULL;
	typedef_UnsetGlobalHook UnsetGlobalHook = NULL;
	typedef_CreateSharedMemory CreateSharedMemory;
	typedef_Write Write;
	typedef_Read Read;
	DWORD dwBuffLen;
	BYTE szBuff[100] = {0};
	BOOL bRet = FALSE;
	LPSTR lpszWindowName = "mfc";

	do
	{
		hDll = ::LoadLibrary("C:\\vc6++\\MyProjects\\GlobalHook\\Debug\\GlobalHook.dll");
		if (NULL == hDll)
		{
			printf("LoadLibrary Error[%d]\n", ::GetLastError());
			break;
		}
		SetGlobalHook = (typedef_SetGlobalHook)::GetProcAddress(hDll, "SetGlobalHook");
		if (NULL == SetGlobalHook)
		{
			printf("GetProcAddress Error[%d]\n", ::GetLastError());
			break;
		}
		bRet = SetGlobalHook(WH_CALLWNDPROC, lpszWindowName);
		if (bRet)
		{
			printf("SetGlobalHook OK.\n");
		}
		else
		{
			printf("SetGlobalHook ERROR.\n");
		}
	
		//write buff
		Write = (typedef_Write)GetProcAddress(hDll, "Write");
		if (NULL == Write)
		{
			printf("GetProcAddress Error[%d]\n", GetLastError());
			break;
		}
		
		bRet = Write("haha,walker!", 0x20);
		if (bRet)
		{
			printf("write success.\n");
		}
		else
		{
			printf("write error.\n");
		}
/*
		// read buff
		Read = (typedef_Read)GetProcAddress(hDll, "Read");
		if (NULL == Read)
		{
			printf("GetProcAddress Error[%d]\n", GetLastError());
			break;
		}
		
		dwBuffLen = sizeof(szBuff);
		dwBuffLen = Read((LPSTR)szBuff, dwBuffLen);
		if (dwBuffLen)
		{
			printf("Read data: %s\n", szBuff);
		}
		else
		{
			printf("Read error.\n");
		}
*/
		//获取进程句柄
		HWND hwnd = FindWindow(NULL, lpszWindowName);
		if (!hwnd)
		{
			//printf("获取进程句柄失败!\n");
			return FALSE;
		}
		SendMessage(hwnd, WM_USER + 0x1, 0x1234, 0x5678);

		UnsetGlobalHook = (typedef_UnsetGlobalHook)::GetProcAddress(hDll, "UnsetGlobalHook");
		if (NULL == UnsetGlobalHook)
		{
			printf("GetProcAddress Error[%d]\n", ::GetLastError());
			break;
		}
		bRet = UnsetGlobalHook();
		if(bRet)
			printf("UnsetGlobalHook OK.\n");
		else
			printf("UnsetGlobalHook falied.\n");
		SendMessage(hwnd, WM_USER + 0x1, 0x1234, 0x5678);
	}while(FALSE);
	FreeLibrary(hDll);
	return 0;
}

效果图

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值