EreTIk's Box » Заметки о WinDbg » Расширение !alpc для WinDbg


Раз - и ожило все вокруг,

Два - и замерло все внутри.

Открой глаза, посмотри, мой друг.

Да вокруг себя посмотри.

Ноль - "Прости, что не верил"


В документации к WinDbg описано расширение !lpc, которое может помочь при анализе LPC-взаимодействия. Но Windows Vista выпущена уже не один год назад, а там уже давно используется развитие этого IPC-механизма: ALPC. Microsoft почему-то умолчала о существовании более мощного и актуального расширения !alpc. Именно о нем и пойдет речь дальше, рассматриваться будет реализация в файле kdexts.dll версии 6.2.9200.16384.


Небольшое лирическое отступление: большое спасибо людям, которые делают Process Hacker. В частности, их заголовочный файл ntlpcapi.h достаточно точно описывает функции работы с ALPC. Хочется пожелать авторам развиваться дальше. И добавить описание функций, появившихся в Windows 8.


Если выполнить команду !alpc без параметров, то на экран будет выдан достаточно скудный хэлп на четыре команды:


Usage: !alpc /m MessageAddress Dumps the message at the specified address. !alpc /p PortAddress Dumps the port at the specified address. !alpc /lpc PortAddress Dumps all connections for the specified port. !alpc /lpp ProcessAddress Dumps all connections for the specified process.

Команды, безусловно, полезные. И делают несколько больше, чем просто печать полей структуры порта/сообщения. А вот если взглянуть внутрь реализации расширения, то можно обнаружить намного больше недокументированных команд. Вот их я и попытаюсь описать.


Некоторые команды требуют специальную сборку ядра: структры, поля структур и символы из nt и ntdll. Такие команды далее рассмотрены не будут.


Команда -graph


Команда -graph не требует дополнительных параметров. Такой вызов перечисляет все ALPC-порты в системе, выбирая только клиентские порты.


В результате выводится таблица с пятью столбцами, например:


fffffa80097e0c300000000000001488fffffa80084dfe600000000000000298ntsvcs
fffffa8010fe7c500000000000001488fffffa80085f2b200000000000000168senssvc
fffffa8009175bc00000000000001488fffffa8008b62380000000000000047cnlaapi

Первый столбец содержит адрес клиентского порта, второй - ID клиентского процесса, третий - адрес серверного connection-порта, четвертый - ID серверного процесса, а пятый - имя серверного connection-порта.


Для приведенного выше примера, первая строка означает: процесс 0x1488 клиентским ALPC-портом 0xfffffa80097e0c30 соединен с серверным портом 0xfffffa80084dfe60, имеющим имя "ntsvcs", созданным процессом 0x298.


Команда -lp


Команда -lp не требует дополнительных параметров. Такой вызов перечисляет все ALPC-порты в системе. По всем портам системы формируется сводная таблица следующего вида:


fffffa801379fe40CON0
fffffa801379f690CLI0
fffffa80136d5070SRV0

Первый столбец содержит адрес объекта порта, второй - тип порта (именованный connection-порт, серверный порт или клиентский порт). А третий столбец это сумма следующих полей объекта порта:

  • MainQueueLength
  • PendingQueueLength
  • LargeMessageQueueLength
  • CanceledQueueLength

Команда -lp0


Существует так же расширенная версия команды -lp: -lp0. В этом случае ищутся все объекты портов, количество описателей на которые равно 0. И для каждого такого порта печатается таблица, например:


fffffa8013548090 CON0 2621420 0 0 00

Первые два столбца совпадают со столбцами команды -lp. Дальше идут два столбца количества описателей и ссылок на объект порта соответственно. Следующие четыре столбца это четыре счетчика, которые суммируются в последнем столбце команды -lp. Последний столбец отображает количество клиентских портов, соединенных с connection-портом или 0 для других типов портов.


Команда -analyze


Команда -analyze не требует дополнительных параметров. Эта команда проверяет внутренне состояние сообщений и портов.


Команда -presl


Команда - presl принимает единственным параметром адрес порта. Для указанного порта выводится информация о связанной с ним секции (если есть) и отображениями (если есть).


Для печати детализированной информации можно использовать следующие команды (всем в качестве параметра необходимо передать адрес соответствующей структтуры):

  • -section печать KALPC_SECTION
  • -region печать KALPC_REGION
  • -view печать KALPC_VIEW

ΞρεΤΙκ