Alpc通信

Alpc通信
作者我也只是班门弄斧的学习一下这方面, 驱动代码如下
#if DBG
#define DBG_PRINT(format, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "CPU:[%d] -- [%s]:" format, KeGetCurrentProcessorNumber(), __FUNCTION__, __VA_ARGS__)
#else
#define DBG_PRINT(...)
#endif
#define ALPC_TAG 'alpc'
#define MAX_MSG_LEN 0x500
NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegeditPath);
VOID CreatePortAndListen(
_In_ LPCWSTR PortName
);
NTSTATUS DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegeditPath
)
{
NTSTATUS status = STATUS_SUCCESS;
HANDLE hThread;
PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS, NULL, NULL, NULL, (PKSTART_ROUTINE)&CreatePortAndListen, L"\\RPC Control\\NameOfPort");
return status;
}
LPVOID AllocMsgMem(
_In_ SIZE_T Size
)
{
/*
It's important to understand that after the PORT_MESSAGE struct is the message data
*/
LPVOID pointer = ExAllocatePoolWithTag(NonPagedPool, Size + sizeof(PORT_MESSAGE), ALPC_TAG);
if (pointer) RtlSecureZeroMemory(pointer, Size + sizeof(PORT_MESSAGE));
return pointer;
}
VOID CreatePortAndListen(
_In_ LPCWSTR PortName
)
{
ALPC_PORT_ATTRIBUTES serverPortAttr;
OBJECT_ATTRIBUTES objPort;
UNICODE_STRING usPortName;
PORT_MESSAGE pmRequest;
PORT_MESSAGE pmReceive;
NTSTATUS ntRet;
BOOLEAN bBreak;
HANDLE hConnectedPort;
HANDLE hPort;
SIZE_T nLen;
LPVOID lpMem;
BYTE bTemp;
RtlInitUnicodeString(&usPortName, PortName);
InitializeObjectAttributes(&objPort, &usPortName, 0, 0, 0);
RtlSecureZeroMemory(&serverPortAttr, sizeof(serverPortAttr));
serverPortAttr.MaxMessageLength = MAX_MSG_LEN; // For ALPC this can be max of 64KB
_NtAlpcCreatePort NtAlpcCreatePort = (_NtAlpcCreatePort)GetSsdtFunctionAddress("NtAlpcCreatePort");
_NtAlpcSendWaitReceivePort NtAlpcSendWaitReceivePort = (_NtAlpcSendWaitReceivePort)GetSsdtFunctionAddress("NtAlpcSendWaitReceivePort");
_NtAlpcAcceptConnectPort NtAlpcAcceptConnectPort = (_NtAlpcAcceptConnectPort)GetSsdtFunctionAddress("NtAlpcAcceptConnectPort");
ntRet = NtAlpcCreatePort(&hPort, &objPort, &serverPortAttr);
DBG_PRINT("[i] NtAlpcCreatePort: 0x%X\n", ntRet);
if (!ntRet)
{
nLen = sizeof(pmReceive);
ntRet = NtAlpcSendWaitReceivePort(hPort, 0, NULL, NULL, &pmReceive, &nLen, NULL, NULL);
if (!ntRet)
{
RtlSecureZeroMemory(&pmRequest, sizeof(pmRequest));
pmRequest.MessageId = pmReceive.MessageId;
pmRequest.u1.s1.DataLength = 0x0;
pmRequest.u1.s1.TotalLength = pmRequest.u1.s1.DataLength + sizeof(PORT_MESSAGE);
ntRet = NtAlpcAcceptConnectPort(&hConnectedPort, hPort, 0, NULL, NULL, NULL, &pmRequest, NULL, TRUE); // 0
DBG_PRINT("[i] NtAlpcAcceptConnectPort: 0x%X\n", ntRet);
if (!ntRet)
{
bBreak = TRUE;
while (bBreak)
{
nLen = MAX_MSG_LEN;
lpMem = AllocMsgMem(nLen);
NtAlpcSendWaitReceivePort(hPort, 0, NULL, NULL, (PPORT_MESSAGE)lpMem, &nLen, NULL, NULL);
pmReceive = *(PORT_MESSAGE*)lpMem;
if (!strcmp((CHAR*)((BYTE*)lpMem + sizeof(PORT_MESSAGE)), "exit\n"))
{
}
else
{
DBG_PRINT("[i] Received Data: ");
for (int i = 0; i < pmReceive.u1.s1.DataLength; i++)
{
bTemp = *(BYTE*)((BYTE*)lpMem + i + sizeof(PORT_MESSAGE));
if (bTemp >= 32 && bTemp <= 126) {
DBG_PRINT("%c", bTemp);
}
else if (bTemp == '\r') {
DBG_PRINT("\\r");
}
else if (bTemp == '\n') {
DBG_PRINT("\\n");
}
else {
DBG_PRINT(" 0x%X ", bTemp);
}
}
DBG_PRINT("\r\n");
ExFreePoolWithTag(lpMem, ALPC_TAG);
}
}
}
}
}
PsTerminateSystemThread(0);
}
用户层代码如下:
#include <Windows.h>
#include <winternl.h>
#include <stdio.h>
#include "ntalpcapi.h"
#define MSG_LEN 0x100
LPVOID CreateMsgMem(PPORT_MESSAGE PortMessage, SIZE_T MessageSize, LPVOID Message)
{
/*
It's important to understand that after the PORT_MESSAGE struct is the message data
*/
LPVOID lpMem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MessageSize + sizeof(PORT_MESSAGE));
memmove(lpMem, PortMessage, sizeof(PORT_MESSAGE));
memmove((BYTE*)lpMem + sizeof(PORT_MESSAGE), Message, MessageSize);
return(lpMem);
}
void main()
{
UNICODE_STRING usPort;
PORT_MESSAGE pmSend;
PORT_MESSAGE pmReceive;
NTSTATUS ntRet;
BOOLEAN bBreak;
SIZE_T nLen;
HANDLE hPort;
LPVOID lpMem;
CHAR szInput[MSG_LEN];
printf("ALPC-Example Client\n");
RtlInitUnicodeString(&usPort, L"\\RPC Control\\NameOfPort");
RtlSecureZeroMemory(&pmSend, sizeof(pmSend));
pmSend.u1.s1.DataLength = MSG_LEN;
pmSend.u1.s1.TotalLength = pmSend.u1.s1.DataLength + sizeof(pmSend);
lpMem = CreateMsgMem(&pmSend, MSG_LEN, L"Hello World!");
ntRet = NtAlpcConnectPort(&hPort, &usPort, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL);
printf("[i] NtAlpcConnectPort: 0x%X\n", ntRet);
if (!ntRet)
{
printf("[i] type 'exit' to disconnect from the server\n");
bBreak = TRUE;
while (bBreak)
{
RtlSecureZeroMemory(&pmSend, sizeof(pmSend));
RtlSecureZeroMemory(&szInput, sizeof(szInput));
printf("[.] Enter Message > ");
fgets(&szInput, MSG_LEN, stdin);
pmSend.u1.s1.DataLength = strlen(szInput);
pmSend.u1.s1.TotalLength = pmSend.u1.s1.DataLength + sizeof(PORT_MESSAGE);
lpMem = CreateMsgMem(&pmSend, pmSend.u1.s1.DataLength, &szInput);
ntRet = NtAlpcSendWaitReceivePort(hPort, 0, (PPORT_MESSAGE)lpMem, NULL, NULL, NULL, NULL, NULL);
printf("[i] NtAlpcSendWaitReceivePort: 0x%X\n", ntRet);
HeapFree(GetProcessHeap(), 0, lpMem);
}
}
getchar();
return;
}
参考资料:ALPC_Example

浙公网安备 33010602011771号