• LPC


    下面示例仅支持x64

    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"
    

    server.cpp

    #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(const 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;
    }
    

      client.cpp

    #include "..//..//Common//Common.h"
    #include <stdio.h>
    #include <iostream>
    
    
    BOOL ConnectServer(const 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)
    		{
    			DWORD err = GetLastError();
    
    			std::cout << "NtConnectPort Status " << Status << " error " << err << "\n";
    			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;
    }
    

      

  • 相关阅读:
    ABAPHow to use TEXTEDIT(SAP 的样例摘抄)
    ABAPwhat is the difference between V1 ,V2&V3 update?
    BASIS关于Netweaver 2005的架构平台说明
    ABAP如何在SELECT语句中指定索引(example)
    ABAPHow to use Toolbar control(SAP样例摘抄)
    ABAP如何读取地址信息
    ABAP如何使用REUSE_ALV_GRID_DISPLAY函数删除内表数据(样例代码,感谢依风提供)
    ABAP一个极好的调用外部java程序的Search Help Exit的实例(RFC好例子)
    ABAP如何在ALV Grid打印页上加入页号
    ABAP一个实现Search Help Exits的完整样例
  • 原文地址:https://www.cnblogs.com/chunyou128/p/16005666.html
Copyright © 2020-2023  润新知