LPC 简单程序

断消息服务端

#include "..//..//Common/Common.h"
#include <stdio.h>
BOOL g_Stop = FALSE;
volatile LONG	g_dwCurrentClient = 0;
DWORD WINAPI CommunicationThread(LPVOID lParam)
{
	NTSTATUS	NtStatus = 0;
	TRANSFERED_MESSAGE RecvMessage = { 0 };
	TRANSFERED_MESSAGE SendMsg = { 0 };
	InitializeMessageHeader(&SendMsg.Header, sizeof(TRANSFERED_MESSAGE), 0);
	HANDLE		ServerCommunicationPortHandle = (HANDLE)lParam;
	InterlockedAdd(&g_dwCurrentClient, 1);
	while (!g_Stop)
	{
		printf("\r\n");
		ZeroMemory(&RecvMessage, sizeof(TRANSFERED_MESSAGE));
		NtStatus = NtRequestWaitReplyPort(ServerCommunicationPortHandle, &SendMsg.Header, &RecvMessage.Header);
		if (NtStatus != 0)
		{
			printf("NtRequestWaitReplyPort:%d\r\n", GetLastError());
			NtClose(ServerCommunicationPortHandle);
			break;
		}

		switch (RecvMessage.Command)
		{
		case LPC_COMMAND_REQUEST_NOREPLY:
		{
			printf("MessageType:%d\r\nClientID<%d,%d>\r\nToTalLength:%d\r\nMessage:%ws\r\n",
				RecvMessage.Header.u2.s2.Type,
				RecvMessage.Header.ClientId.UniqueProcess,
				RecvMessage.Header.ClientId.UniqueThread,
				RecvMessage.Header.u1.s1.TotalLength,
				RecvMessage.MessageText);
			break;
		}
		}
	}
	InterlockedExchange(&g_dwCurrentClient, g_dwCurrentClient - 1);

	return 0;
}

void StartServer(WCHAR* szServerPortName)
{
	SECURITY_DESCRIPTOR		SecurityDesc = { 0 };
	UNICODE_STRING			uniPortName;
	LSA_OBJECT_ATTRIBUTES	ObjectAttribute = { 0 };
	NTSTATUS				NtStatus = 0;
	HANDLE					hConnectionPort;
	CHAR RequestBuffer[sizeof(PORT_MESSAGE) + MAX_LPC_DATA] = { 0 };
	PTRANSFERED_MESSAGE LPCRequertMessage = PTRANSFERED_MESSAGE(RequestBuffer);
	
	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(&uniPortName, szServerPortName);
		InitializeObjectAttributes(&ObjectAttribute, &uniPortName, 0, NULL, &SecurityDesc);
		NtStatus = NtCreatePort(&hConnectionPort, &ObjectAttribute, NULL, sizeof(PORT_MESSAGE) + MAX_LPC_DATA, 0);
		if (NtStatus != 0)
		{
			printf("NtCreatePort:%d\r\n", GetLastError());
			break;
		}
		BOOL        bOk = TRUE;
		HANDLE      ServerCommunicationPortHandle = NULL;
		HANDLE		AcceptPortHandle = NULL;
		NTSTATUS	NtStatus = 0;
		TRANSFERED_MESSAGE	LPCRequertMessage = { 0 };


		while (!g_Stop)
		{
			// 清空RecvMsg 监听等待连接
			RtlZeroMemory(&LPCRequertMessage, sizeof(TRANSFERED_MESSAGE));
			NtStatus = NtListenPort(hConnectionPort, &LPCRequertMessage.Header);
			if (NtStatus != 0)
			{
				printf("NtListenPort:%d\r\n", GetLastError());
				g_Stop = TRUE;
				NtClose(hConnectionPort);
				break;
				
			}

			// 打印客户进程的一些信息
			printf("MessageType:%d\r\nClientID<%d,%d>\r\nToTalLength:%d\r\n",
				LPCRequertMessage.Header.u2.s2.Type,
				LPCRequertMessage.Header.ClientId.UniqueProcess,
				LPCRequertMessage.Header.ClientId.UniqueThread,
				LPCRequertMessage.Header.u1.s1.TotalLength);
			
			// 判断是否允许连接
			if (g_dwCurrentClient < MAX_COMMUN_NUMBER)
			{
				bOk = TRUE;
			}
			else
			{
				bOk = FALSE;
			}

			// 处理连接请求 - 根据bOk决定是否接受连接
			NtStatus = NtAcceptConnectPort(&ServerCommunicationPortHandle, 0, &LPCRequertMessage.Header, bOk, NULL, NULL);
			if (NtStatus != 0)
			{
				printf("SetSecurityDescriptorDacl:%d\r\n", GetLastError());
				g_Stop = TRUE;
				NtClose(hConnectionPort);
				break;
			}

			// 完成Connect
			NtStatus = NtCompleteConnectPort(ServerCommunicationPortHandle);
			if (NtStatus != 0)
			{
				printf("SetSecurityDescriptorDacl:%d\r\n", GetLastError());
				g_Stop = TRUE;
				NtClose(hConnectionPort);
				break;
			}
			CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CommunicationThread, ServerCommunicationPortHandle, 0, NULL);
		}
	}
	Sleep(1000);
}
int main()
{
	InitLpc();
	StartServer(SERVER_PORT_NAME);

	return 0;
}

短消息客户端

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

BOOL ConnectServer(WCHAR* szServerPortName,HANDLE & ClientCommunicationPortHandle)
{
	SECURITY_QUALITY_OF_SERVICE SecurityQos = { 0 };
	NTSTATUS NtStatus = 0;
	UNICODE_STRING uniServerName = { 0 };
	DWORD	MaxMessageLength;
	__try
	{
		RtlInitUnicodeString(&uniServerName, szServerPortName);
		SecurityQos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
		SecurityQos.ImpersonationLevel = SecurityImpersonation;
		SecurityQos.EffectiveOnly = FALSE;
		SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
		NtStatus = NtConnectPort(&ClientCommunicationPortHandle, &uniServerName, &SecurityQos, NULL, NULL, (PULONG)&MaxMessageLength, NULL, NULL);
		if (NtStatus != 0)
		{
			printf("NtConnectPort:%d\r\n", GetLastError());
		}
	}
	__finally
	{
		if (NtStatus != 0)
		{
			return FALSE;
		}
	}
	printf("NtConnectPort Success\r\n");
	return TRUE;
}
void CommunicateWithServer(HANDLE hClientCommunicate)
{
	USHORT MsgType = LPC_COMMAND_REQUEST_NOREPLY;
	TRANSFERED_MESSAGE LPCRecvMessage = { 0 };
	TRANSFERED_MESSAGE LPCSendMsg = { 0 };
	NTSTATUS NtStatus = 0;
	InitializeMessageHeader(&LPCRecvMessage.Header, sizeof(TRANSFERED_MESSAGE), 0);
	InitializeMessageHeader(&LPCSendMsg.Header, sizeof(TRANSFERED_MESSAGE), 0);
	NtReplyWaitReceivePort(hClientCommunicate, NULL, NULL, &LPCRecvMessage.Header);
	
	while (TRUE)
	{
		LPCSendMsg = LPCRecvMessage;
		switch (MsgType)
		{
		case LPC_COMMAND_REQUEST_NOREPLY:
			scanf_s("%ws", LPCSendMsg.MessageText, 48);
			LPCSendMsg.Command = MsgType;
			NtReplyWaitReceivePort(hClientCommunicate, NULL, &LPCSendMsg.Header, &LPCRecvMessage.Header);
			break;
		}


		if (NtStatus != 0)
		{
			printf("GetLastError:%d\r\n", GetLastError());
			break;
		}
	}
}
int main()
{
	InitLpc();
	HANDLE hClientCommunicate;
	if (ConnectServer(SERVER_PORT_NAME, hClientCommunicate) == TRUE)
	{
		CommunicateWithServer(hClientCommunicate);
	}

	return 0;
}

公共头文件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

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 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);
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");
}
#define SERVER_PORT_NAME	L”\\ServerPortName
注意:需要UAC,不支持Wow64
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值