进程间通信——DLL共享节

DLL共享节技术可以让使用同一个DLL的多个进程共享一块内存(共享节),下面我通过一个项目来演示使用方法。

首先准备一个受害者程序,我选用了xp的扫雷,您也可以用任意喜欢的程序。

在这里插入图片描述

然后,编写DLL,DLL中需要设置共享节,然后在本项目中,DLL被注入到扫雷进程,然后循环打印共享节中的数据,这个数据可以被控制程序修改。
下面是DLL代码,g_buffer就是共享节的数据。

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

#pragma data_seg("Shared")
char g_buffer[0x1000] = {0};
#pragma data_seg()
#pragma comment(linker,"/section:Shared,rws")

extern "C"  __declspec(dllexport) void SetData(char *buf, DWORD dwDataLen)
{
    ZeroMemory(g_buffer, 0x1000);
    memcpy(g_buffer, buf, dwDataLen);
}

extern "C"  __declspec(dllexport) void GetData(char *buf)
{    
    memcpy(buf, g_buffer, 0x1000);
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    {
        // 区分是目标进程(游戏)还是控制进程(WG)
        // 如果是扫雷进程(winmine.exe)则开始接收数据
        char szModule[MAX_PATH] = { 0 };
        GetModuleFileNameA(NULL, szModule, MAX_PATH);
        if (strstr(szModule, "winmine") != NULL)
        {            
            MessageBoxA(NULL, "扫雷程序注入DLL成功", "", MB_OK);
            while (1)
            {
                if (strcmp(g_buffer, "quit") == 0) break; // 控制程序给的退出信号
                MessageBoxA(NULL, g_buffer, szModule, MB_OK);
            }
        }
        break;
    }
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}


然后是控制端代码,就是不停的修改共享节的数据而已。。

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

BOOL InjectDLL();
BOOL EnableDebugPrivilege();

int main()
{
	if (FALSE == InjectDLL())
	{
		printf("注入DLL失败\n");
		return -1;
	}
	else
	{
		printf("注入DLL成功\n");
	}
	
	HMODULE hModule = LoadLibraryA("DLLShareSection-DLL.dll");
	if (hModule == NULL)
	{
		printf("获取DLL句柄失败\n");
		return -1;
	}
	typedef void (*PFNSETDATA)(char *, DWORD);
	typedef void (*PFNGETDATA)(char *);
	PFNSETDATA pFnSetData = (PFNSETDATA)GetProcAddress(hModule, "SetData");
	PFNGETDATA pFnGetData = (PFNGETDATA)GetProcAddress(hModule, "GetData");
	char szBuffer[0x1000];	
	while (1)
	{
		printf("输入要发送的数据: ");
		ZeroMemory(szBuffer, 0x1000);
		scanf("%s", szBuffer);
		pFnSetData(szBuffer, strlen(szBuffer));
		//pFnGetData(szBuffer);
		//printf("修改数据成功,当前数据: %s\n", szBuffer);
		if (strcmp(szBuffer, "quit") == 0) break;
	}

	return 0;
}

// 远程线程注入
BOOL InjectDLL()
{
	// 提权(win10)
	EnableDebugPrivilege();
	// 根据窗口名获取进程句柄
	HWND hWnd = FindWindowA(NULL, "扫雷");
	if (hWnd == NULL)
	{
		printf("获取窗口句柄失败\n");
		return FALSE;
	}
	DWORD dwPid = -1;
	GetWindowThreadProcessId(hWnd, &dwPid);
	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
	if (hProcess == INVALID_HANDLE_VALUE)
	{
		printf("打开进程失败\n");
		return FALSE;
	}
	// 在要注入的进程中申请一块内存,作为LoadLibrary的参数
	char szDllName[MAX_PATH] = "DLLShareSection-DLL.dll";
	LPVOID pAddress = VirtualAllocEx(hProcess, NULL, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
	WriteProcessMemory(hProcess, pAddress, szDllName, strlen(szDllName), NULL);
	// 创建远程线程,线程入口设置为LoadLibrary,这样就可以自动加载dll
	HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA, pAddress, 0, NULL);	
	//VirtualFreeEx(hProcess, pAddress, 0, MEM_RELEASE);
	CloseHandle(hProcess);
	return TRUE;
}

// 提权函数:提升为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;
}

运行结果

注意要把扫雷,控制端程序和DLL放在相同目录下运行

在这里插入图片描述

先启动扫雷,在启动控制程序。
在这里插入图片描述

在控制台输入数据,修改共享节的缓冲区内容,对话框打印的内容就会变。

在这里插入图片描述


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

猜你喜欢

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