EreTIk's Box » Cтатьи, исходники » Размер буфера данных при соединении с [A]LPC-портом


Для создания LPC-порта в ядре ОС присутствуют две функции:


NTSTATUS
NTAPI
NtCreatePort (
    __out PHANDLE PortHandle,
    __in POBJECT_ATTRIBUTES ObjectAttributes,
    __in ULONG MaxConnectionInfoLength,
    __in ULONG MaxMessageLength,
    __in_opt ULONG MaxPoolUsage
    );
                

и


NTSTATUS
NTAPI
NtCreateWaitablePort (
    __out PHANDLE PortHandle,
    __in POBJECT_ATTRIBUTES ObjectAttributes,
    __in ULONG MaxConnectionInfoLength,
    __in ULONG MaxMessageLength,
    __in_opt ULONG MaxPoolUsage
    );
                

Функция NtCreateWaitablePort появилась в ядре Windows 2000 (в NT ее не было), то есть можно считать, что она присутствует на всех машинах. Обе функции имеют одинаковые параметры, среди которых есть MaxConnectionInfoLength. Этот параметр содержит максимальный размер буфера данных, который может быть передан при соединении с объектом порта. На самом деле параметр довольно странный потому, что основной цикл обработки входящих сообщений, включая сообщения о входящем соединении, как правило, организуется в одной функции и буфер для данных выделяется один. Его размер, в данном случае, должен быть максимальным значением из MaxConnectionInfoLength и MaxMessageLength.


Если посмотреть на ядро ОС Vista+, то можно увидеть, что там присутствует еще одна функция, которая создает ALPC-порт:


NTSTATUS
NTAPI
NtAlpcCreatePort(
    __out PHANDLE PortObject,
    __in POBJECT_ATTRIBUTES ObjectAttributes,
    __in PALPC_PORT_ATTRIBUTES pPortInformation
);
                

Если немного поковырять pdb-файлы, то можно получить структуру _ALPC_PORT_ATTRIBUTES:


typedef struct _ALPC_PORT_ATTRIBUTES {
    ULONG Flags;
    SECURITY_QUALITY_OF_SERVICE SecurityQos;
    ULONG MaxMessageLength;
    ULONG MemoryBandwidth;
    ULONG MaxPoolUsage;
    ULONG MaxSectionSize;
    ULONG MaxViewSize;
    ULONG MaxTotalSectionSize;
    ULONG DupObjectTypes;
} ALPC_PORT_ATTRIBUTES, *PALPC_PORT_ATTRIBUTES;
                

Внимательно взглянув на эту структуру, мы поймем, что параметр максимальной длины данных сообщения connect'а в ней нет. Затем обратимся к реализации функций NtCreatePort и NtCreateWaitablePort. Можно видеть, что все три функции (в том числе и NtAlpcCreatePort) сводятся к вызову внутренней не экспортируемой функции nt!AlpcpCreateConnectionPort(...). Но параметр MaxConnectionInfoLength в функциях NtCreatePort и NtCreateWaitablePort просто не используется. Как показал дальнейший анализ, максимальный размер данных сообщения connect'а для всех портов эквивалентен значению максимального размера сообщения для этого порта.


Это не критично, в свете написанного выше. Но следует учитывать, что на ОС Vista+, даже если мы создадим порт со значением MaxConnectionInfoLength большим, чем максимальный размер данных сообщений, то послать такое сообщение будет невозможным.


ΞρεΤΙκ