LPC 简单应用长消息

公共头文件Common.h

#include <windows.h>
#include <NTSecAPI.h>
using namespace std;

#define MAX_LPC_DATA		0x148
#define LPC_MESSAGE_LENGTH  48
#define MAX_COMMUN_NUMBER	10
#define LARGE_MESSAGE_SIZE	0x10000
typedef struct _CLIENT_ID
{
	HANDLE UniqueProcess;
	HANDLE UniqueThread;
} CLIENT_ID, *PCLIENT_ID;

typedef struct _PORT_MESSAGE
{
	union
	{
		struct
		{
			USHORT DataLength;          // Length of data following the header (bytes)
			USHORT TotalLength;         // Length of data + sizeof(PORT_MESSAGE)
		} s1;
		ULONG Length;
	} u1;

	union
	{
		struct
		{
			USHORT Type;
			USHORT DataInfoOffset;
		} s2;
		ULONG ZeroInit;
	} u2;

	union
	{
		CLIENT_ID ClientId;
		double   DoNotUseThisField;     // Force quadword alignment
	};

	ULONG  MessageId;                   // Identifier of the particular message instance

	union
	{
		ULONG_PTR ClientViewSize;       // Size of section created by the sender (in bytes)
		ULONG  CallbackId;              // 
	};

} PORT_MESSAGE, *PPORT_MESSAGE;

typedef struct _TRANSFERED_MESSAGE
{
	PORT_MESSAGE Header;
	ULONG   Command;
	WCHAR   MessageText[48];

} TRANSFERED_MESSAGE, *PTRANSFERED_MESSAGE;

//
// Define structure for initializing shared memory on the caller's side of the port
//

typedef struct _PORT_VIEW {

	ULONG  Length;                      // Size of this structure
	HANDLE SectionHandle;               // Handle to section object with
										// SECTION_MAP_WRITE and SECTION_MAP_READ
	ULONG  SectionOffset;               // The offset in the section to map a view for
										// the port data area. The offset must be aligned 
										// with the allocation granularity of the system.
	SIZE_T ViewSize;                    // The size of the view (in bytes)
	PVOID  ViewBase;                    // The base address of the view in the creator
										// 
	PVOID  ViewRemoteBase;              // The base address of the view in the process
										// connected to the port.
} PORT_VIEW, *PPORT_VIEW;

//
// 定义来自远程端口的共享内存
//

typedef struct _REMOTE_PORT_VIEW {

	ULONG  Length;                      // 结构体大小
	SIZE_T ViewSize;                    // view大小
	PVOID  ViewBase;                    // view 基地址

} REMOTE_PORT_VIEW, *PREMOTE_PORT_VIEW;
typedef struct _COMMUNICATE_
{
	PORT_VIEW			ServerView;
	REMOTE_PORT_VIEW	ClientView;
	HANDLE				hCommunicateHandle;
	HANDLE				hSectionHandle;
}COMMUNICATE, *PCOMMUNICATE;
#define InitializeMessageHeader(ph, l, t)                              \
{                                                                      \
	(ph)->u1.s1.TotalLength      = (USHORT)(l);                        \
	(ph)->u1.s1.DataLength       = (USHORT)(l - sizeof(PORT_MESSAGE)); \
	(ph)->u2.s2.Type             = (USHORT)(t);                        \
	(ph)->u2.s2.DataInfoOffset   = 0;                                  \
	(ph)->ClientId.UniqueProcess = NULL;                               \
	(ph)->ClientId.UniqueThread  = NULL;                               \
	(ph)->MessageId              = 0;                                  \
	(ph)->ClientViewSize         = 0;                                  \
}

#define InitializeObjectAttributes( p, n, a, r, s ) {   \
	(p)->Length = sizeof( LSA_OBJECT_ATTRIBUTES );      \
	(p)->RootDirectory = r;                             \
	(p)->Attributes = a;                                \
	(p)->ObjectName = n;                                \
	(p)->SecurityDescriptor = s;                        \
	(p)->SecurityQualityOfService = NULL;               \
}

enum LPC_MSG_TYPE
{
	LPC_COMMAND_REQUEST_NOREPLY,
	LPC_COMMAND_REQUEST_REPLY,
	LPC_COMMAND_STOP
};
NTSTATUS(NTAPI* NtCreatePort)(PHANDLE PortHandle, PLSA_OBJECT_ATTRIBUTES ObjectAttributes, ULONG MaxConnectionInfoLength, ULONG MaxMessageLength, PULONG MaxPoolUsage);
NTSTATUS(NTAPI* NtAcceptConnectPort)(PHANDLE PortHandle, PVOID PortContext, PPORT_MESSAGE ConnectionRequest, BOOL AcceptConnection, PVOID ServerView, PVOID ClientView);
NTSTATUS(NTAPI* NtCompleteConnectPort)(HANDLE PortHandle);
NTSTATUS(NTAPI* NtReplyWaitReceivePort)(HANDLE PortHandle, PVOID* PortContext, PPORT_MESSAGE ReplyMessage, PPORT_MESSAGE ReceiveMessage);
NTSTATUS(NTAPI* NtRequestWaitReplyPort)(HANDLE PortHandle, PPORT_MESSAGE RequestMessage, PPORT_MESSAGE ReplyMessage);
NTSTATUS(NTAPI* RtlInitUnicodeString)(PUNICODE_STRING DestinationString, PCWSTR SourceString);
NTSTATUS(NTAPI* NtListenPort)(HANDLE PortHandle, PPORT_MESSAGE ConnectionRequest);
NTSTATUS(NTAPI* NtReplyPort)(HANDLE PortHandle, PPORT_MESSAGE ReplyMessage);
NTSTATUS(NTAPI* NtClose)(HANDLE Handle);
NTSTATUS(NTAPI* NtConnectPort)(PHANDLE PortHandle, PUNICODE_STRING PortName, PSECURITY_QUALITY_OF_SERVICE SecurityQos, PVOID ClientView, PVOID ServerView, PULONG MaxMessageLength, PVOID ConnectionInformation, PULONG ConnectionInformationLength);
NTSTATUS(NTAPI* NtRequestPort)(HANDLE PortHandle, PPORT_MESSAGE RequestMessage);

NTSTATUS(NTAPI* NtCreateSection)(
	OUT PHANDLE SectionHandle,
	IN  ACCESS_MASK DesiredAccess,
	IN  PLSA_OBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
	IN  PLARGE_INTEGER MaximumSize OPTIONAL,
	IN  ULONG SectionPageProtection,
	IN  ULONG AllocationAttributes,
	IN  HANDLE FileHandle OPTIONAL
);
void InitLpc()
{
	HMODULE NtdllModule = GetModuleHandleW(L"ntdll.dll");
	if (NtdllModule == NULL)
	{
		return;
	}
	(FARPROC&)NtCreatePort = GetProcAddress(NtdllModule, "NtCreatePort");
	(FARPROC&)NtAcceptConnectPort = GetProcAddress(NtdllModule, "NtAcceptConnectPort");
	(FARPROC&)NtCompleteConnectPort = GetProcAddress(NtdllModule, "NtCompleteConnectPort");
	(FARPROC&)NtReplyWaitReceivePort = GetProcAddress(NtdllModule, "NtReplyWaitReceivePort");
	(FARPROC&)NtRequestWaitReplyPort = GetProcAddress(NtdllModule, "NtRequestWaitReplyPort");
	(FARPROC&)RtlInitUnicodeString = GetProcAddress(NtdllModule, "RtlInitUnicodeString");
	(FARPROC&)NtListenPort = GetProcAddress(NtdllModule, "NtListenPort");
	(FARPROC&)NtReplyPort = GetProcAddress(NtdllModule, "NtReplyPort");
	(FARPROC&)NtClose = GetProcAddress(NtdllModule, "NtClose");
	(FARPROC&)NtConnectPort = GetProcAddress(NtdllModule, "NtConnectPort");
	(FARPROC&)NtRequestPort = GetProcAddress(NtdllModule, "NtRequestPort");
	(FARPROC&)NtCreateSection = GetProcAddress(NtdllModule, "NtCreateSection");
}
#define SERVER_PORT_NAME	L"\\ServerPortName"

服务器

#include "..//..//Common//Common.h"
#include <stdio.h>
BOOL g_Stop = FALSE;
volatile LONG	g_dwCurrentClient = 0;
DWORD WINAPI CommunicationThread(LPVOID lParam)
{
	NTSTATUS	NtStatus = 0;
	PCOMMUNICATE		pCommunicate = (PCOMMUNICATE)lParam;
	PORT_MESSAGE		RecvMsg;
	PORT_MESSAGE		SendMsg;
	InterlockedAdd(&g_dwCurrentClient, 1);
	while (!g_Stop)
	{
		InitializeMessageHeader(&SendMsg, sizeof(PORT_MESSAGE), 0);
		ZeroMemory(&RecvMsg, sizeof(PORT_MESSAGE));
		NtStatus = NtRequestWaitReplyPort(pCommunicate->hCommunicateHandle,
			&SendMsg,
			&RecvMsg);
		if (NtStatus != 0)
		{
			CloseHandle(pCommunicate->hSectionHandle);
			NtClose(pCommunicate->hCommunicateHandle);
			printf("NtReplyWaitReceivePort:%d\r\n", GetLastError());
			break;
		}
		printf("MessageType:%d\r\nClientID<%d,%d>\r\nToTalLength:%d\r\nMessage:%ws\r\n",
			RecvMsg.u2.s2.Type,
			RecvMsg.ClientId.UniqueProcess,
			RecvMsg.ClientId.UniqueThread,
			RecvMsg.u1.s1.TotalLength,
			pCommunicate->ClientView.ViewBase);
	}
	InterlockedExchange(&g_dwCurrentClient, g_dwCurrentClient - 1);

	return 0;
}

void StartServer(WCHAR* szServerPortName)
{
	NTSTATUS	 Status = 0;
	PORT_MESSAGE LpcMessage;
	LSA_OBJECT_ATTRIBUTES	ObjAttr;
	UNICODE_STRING		PortName;
	HANDLE				hSectionHandle;
	HANDLE				hServerConnectionHandle;
	SECURITY_DESCRIPTOR		SecurityDesc = { 0 };
	
	LARGE_INTEGER SectionSize = { LARGE_MESSAGE_SIZE };
	g_Stop = FALSE;
	while (!g_Stop)
	{
		if (!InitializeSecurityDescriptor(&SecurityDesc, SECURITY_DESCRIPTOR_REVISION))
		{
			printf("InitializeSecurityDescriptor:%d\r\n", GetLastError());
			break;
		}

		if (!SetSecurityDescriptorDacl(&SecurityDesc, TRUE, NULL, FALSE))
		{
			printf("SetSecurityDescriptorDacl:%d\r\n", GetLastError());
			break;
		}

		RtlInitUnicodeString(&PortName, SERVER_PORT_NAME);
		InitializeObjectAttributes(&ObjAttr, &PortName, 0, NULL, &SecurityDesc);
		Status = NtCreatePort(&hServerConnectionHandle,
			&ObjAttr,
			NULL,
			sizeof(PORT_MESSAGE),
			0
		);

		if (Status != 0)
		{
			printf("NtCreatePort:%d\r\n", GetLastError());
			break;
		}

		while (!g_Stop)
		{
			HANDLE		hServerCommunicateHandle;
			Status = NtListenPort(hServerConnectionHandle, &LpcMessage);

			if (Status != 0)
			{
				printf("NtListenPort:%d\r\n", GetLastError());
				g_Stop = TRUE;
				break;
			}
			if (g_dwCurrentClient < MAX_COMMUN_NUMBER)
			{
				PCOMMUNICATE pThreadPara = new COMMUNICATE;

				Status = NtCreateSection(&pThreadPara->hSectionHandle,
					SECTION_MAP_READ | SECTION_MAP_WRITE,
					NULL,// 使用页文件,而不是文件映射
					&SectionSize,
					PAGE_READWRITE,
					SEC_COMMIT,
					NULL);
				if (Status != 0)
				{
					printf("NtCreateSection:%d\r\n", GetLastError());
					break;
				}

				//
				// 接受端口的连接
				//
				pThreadPara->ServerView.Length = sizeof(PORT_VIEW);
				pThreadPara->ServerView.SectionHandle = pThreadPara->hSectionHandle;
				pThreadPara->ServerView.SectionOffset = 0;
				pThreadPara->ServerView.ViewSize = LARGE_MESSAGE_SIZE;
				pThreadPara->ClientView.Length = sizeof(REMOTE_PORT_VIEW);


				Status = NtAcceptConnectPort(&pThreadPara->hCommunicateHandle,
					NULL,
					&LpcMessage,
					TRUE,
					&pThreadPara->ServerView,
					&pThreadPara->ClientView);
				if (Status != 0)
				{
					printf("NtAcceptConnectPort:%d\r\n", GetLastError());
					g_Stop = TRUE;
					CloseHandle(pThreadPara->hSectionHandle);
					break;
				}
				//
				// 完成连接请求Complete the connection
				//
				
				Status = NtCompleteConnectPort(pThreadPara->hCommunicateHandle);
				if (Status != 0)
				{
					printf("NtCompleteConnectPort:%d\r\n", GetLastError());
					g_Stop = TRUE;
					CloseHandle(pThreadPara->hSectionHandle);
					break;
				}
				printf("MessageType:%d\r\nClientID<%d,%d>\r\nToTalLength:%d\r\nServerBase:%p\tServerSize:%x\r\nClientBase:%p\tClientSize:%x\r\n",
					LpcMessage.u2.s2.Type,
					LpcMessage.ClientId.UniqueProcess,
					LpcMessage.ClientId.UniqueThread,
					LpcMessage.u1.s1.TotalLength,
					pThreadPara->ServerView.ViewBase, pThreadPara->ServerView.ViewSize,
					pThreadPara->ClientView.ViewBase, pThreadPara->ClientView.ViewSize);

				CreateThread(NULL, 0, CommunicationThread, pThreadPara, 0, NULL);
			}
			else
			{
				NtAcceptConnectPort(&hServerCommunicateHandle,NULL,
					&LpcMessage,
					FALSE,
					NULL, NULL);
			}
		}
	}
}
int main()
{
	InitLpc();
	StartServer(SERVER_PORT_NAME);

	return 0;
}

客户端

#include "..//..//Common//Common.h"
#include <stdio.h>


BOOL ConnectServer(WCHAR* szServerPortName, COMMUNICATE & ClientCommunicate)
{
	SECURITY_QUALITY_OF_SERVICE SecurityQos;
	UNICODE_STRING	PortName;
	PORT_MESSAGE	LpcMessage;
	PORT_MESSAGE	LpcReply;


	NTSTATUS Status = 0;


	LARGE_INTEGER	SectionSize = { LARGE_MESSAGE_SIZE };
	__try
	{
		Status = NtCreateSection(&ClientCommunicate.hSectionHandle,
			SECTION_MAP_READ | SECTION_MAP_WRITE,
			NULL,
			&SectionSize,
			PAGE_READWRITE,
			SEC_COMMIT,
			NULL);
		if (Status != 0)
		{
			printf("NtReplyWaitReceivePort:%d\r\n", GetLastError());
			__leave;
		}
		RtlInitUnicodeString(&PortName, szServerPortName);
		SecurityQos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
		SecurityQos.ImpersonationLevel = SecurityImpersonation;
		SecurityQos.EffectiveOnly = FALSE;
		SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;


		ClientCommunicate.ServerView.Length = sizeof(PORT_VIEW);
		ClientCommunicate.ServerView.SectionHandle = ClientCommunicate.hSectionHandle;
		ClientCommunicate.ServerView.SectionOffset = 0;
		ClientCommunicate.ServerView.ViewSize = LARGE_MESSAGE_SIZE;
		ClientCommunicate.ClientView.Length = sizeof(REMOTE_PORT_VIEW);


		Status = NtConnectPort(&ClientCommunicate.hCommunicateHandle,
			&PortName,
			&SecurityQos,
			&ClientCommunicate.ServerView,
			&ClientCommunicate.ClientView,
			0,
			NULL,
			NULL);


		if (Status != 0)
		{
			CloseHandle(ClientCommunicate.hSectionHandle);
			printf("NtConnectPort:%d\r\n", GetLastError());
			__leave;
		}
	}
	__finally
	{
		if (Status != 0)
		{
			return FALSE;
		}
	}
	printf("NtConnectPort Success\r\n");
	return TRUE;
}
void CommunicateWithServer(COMMUNICATE& ClientCommunicate)
{
	PORT_MESSAGE	LpcSndMsg = { 0 };
	PORT_MESSAGE	LpcRecvMsg = { 0 };
	InitializeMessageHeader(&LpcRecvMsg, sizeof(TRANSFERED_MESSAGE), 0);
	NTSTATUS NtStatus = 0;
	NtStatus = NtReplyWaitReceivePort(ClientCommunicate.hCommunicateHandle, NULL, NULL, &LpcRecvMsg);


	while (NtStatus == 0)
	{
		LpcSndMsg = LpcRecvMsg;


		scanf_s("%ws", ClientCommunicate.ServerView.ViewBase, 0x1000);
		NtStatus = NtReplyWaitReceivePort(ClientCommunicate.hCommunicateHandle, NULL, &LpcSndMsg, &LpcRecvMsg);
		if (NtStatus != 0)
		{
			NtClose(ClientCommunicate.hCommunicateHandle);
			CloseHandle(ClientCommunicate.hSectionHandle);
			printf("GetLastError:%d\r\n", GetLastError());
			break;
		}
	}
}
int main()
{
	InitLpc();
	COMMUNICATE	ClientCommunicate = { 0 };
	if (ConnectServer(SERVER_PORT_NAME, ClientCommunicate) == TRUE)
	{
		CommunicateWithServer(ClientCommunicate);
	}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值