Alpc通信

image

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

posted @ 2025-08-14 19:09  旅行者-林小小  阅读(37)  评论(0)    收藏  举报