В современном мире операционных систем и сетевых коммуникаций Windows занимает особое место благодаря своей архитектуре и разнообразию средств для работы с сетью. Одним из ключевых компонентов, обеспечивающих сетевую функциональность, является драйвер AFD.sys — Ancillary Function Driver, который, несмотря на свою важность, остается сравнительно малоизученным из-за недостаточной официальной документации и закрытости внутренней реализации. Эта статья — глубокое погружение в работу AFD.sys на примере Windows 11, где рассматривается создание TCP-сокетов напрямую через низкоуровневые вызовы ядра, обходя привычный слой Winsock и связанные с ним библиотеки.
Главная цель такого подхода — получить детальное понимание внутренней логики и структуры AFD.sys, а также подготовить почву для разработки специализированных библиотек и инструментов для работы с сетевыми соединениями на самом базовом уровне. Winsock и его роль в сетевой коммуникации в Windows хорошо известна: она предоставляет высокоуровневые и удобные интерфейсы для работы с TCP и UDP, позволяя большинству приложений оставаться в рамках стандартных API. Однако Winsock на самом деле основывается на более низкоуровневом компоненте mswsock.dll, а уже ниже — именно на AFD.
sys. Этот драйвер занимается трансляцией запросов из пользовательского режима в понятные TCP/IP стэку IRP (I/O Request Packets). Таким образом, AFD.sys выполняет роль мостика между приложениями и сетевой подсистемой ядра. Исследование AFD.
sys с пропуском слоя Winsock позволяет избежать некоторых ограничений и защитных механизмов, направленных на перехват и модификацию сетевых вызовов на уровне Winsock — часто используемых системами защиты от читов и вредоносного ПО. Кроме того, прямое взаимодействие с AFD.sys раскрывает детали того, как операционная система реализует работу с сетевыми сокетами под капотом — от создания дескрипторов до управления состояниями соединения. Первая задача в изучении AFD.sys — научиться создавать рабочие «сокеты» через это ядро.
В отличие от привычного понимания, в Windows сокетом от AFD считается просто дескриптор, полученный путем открытия объекта \Device\Afd\Endpoint с помощью системного вызова NtCreateFile. Для этого необходимо сформировать специфическую структуру расширенных атрибутов (Extended Attributes), которая указывает параметры будущего сокета, такие как адресное семейство, тип сокета и протокол. Важно заметить, что без правильного построения этой структуры AFD.sys просто отклонит запрос, и процесс не сможет получить валидный дескриптор. Процесс изучения и выбора корректных параметров не был тривиален.
Большинство доступных в интернете примеров — это переборки или практические примеры, связанные с исследованием уязвимости CVE-2024-38193, что не всегда подходило для обычных случаев использования. Для более точного понимания авторы исследовали реальный трафик и системные вызовы через WinDbg, специальный отладчик ядра Windows. Анализ действий процесса, создающего сеть через обычный Winsock, позволил зафиксировать реальные данные, которые он отправлял в AFD.sys при создании и конфигурации сокета. Обнаружилось, что структура расширенных атрибутов, которую принимает AFD.
sys, занимает ровно 57 байт и имеет четко выделенные поля. Среди них есть поля, указывающие флаги сокета (например, флаги подключения без установления соединения, режим сообщения, raw-сокеты и другие), параметры группы, адресное семейство (IPv4 или IPv6), тип сокета (STREAM, DGRAM и т.д.) и протокол (TCP или UDP). Однако не все байты структуры удалось сразу однозначно расшифровать.
В частности, присутствовал блок из девяти неизвестных байтов, функциональное назначение которых не было найдено ни в официальной документации, ни в открытых исходниках нескольких подобных проектов типа ReactOS или Dr. Memory. Исследование mswsock.dll (части Winsock) через инструменты реверс-инжиниринга указало, что этот блок чаще всего просто копируется напрямую без применения значимых трансформаций. Можно предположить, что эти байты либо содержат служебную или служебно-ориентированную информацию, либо нужны для выравнивания или специфической поддержки старых/специфичных протоколов.
Выводы из анализа показывают, что создание сокета с помощью AFD.sys — это вызов низкоуровневой функции NtCreateFile с корректно сформированной структурой расширенных атрибутов и правильным именем устройства \Device\Afd\Endpoint. Результатом будет дескриптор, который работает как сокет, но управлять им придется вручную через набор IoControl-запросов (IOCTL), которые тоже необходимо изучить отдельно. Этот подход предоставляет полный контроль над процессом сетевого взаимодействия и потенциал для обхода защитных механизмов, основанных на перехвате вызовов Winsock. Помимо технических деталей важно отметить историю и контекст.
AFD.sys формировался как промежуточный драйвер, выступающий клиентом для низкоуровневого интерфейса Transport Driver Interface (TDI). TDI представляет собой устаревшую абстракцию транспортного уровня для сетевых протоколов в ядре Windows, которая упрощала взаимодействие протоколов с клиентами. AFD.sys строит IRP, которые подаются на транспортный драйвер (например, \Device\Tcp), используя стандартные коды TDI_SEND, TDI_RECEIVE, TDI_CONNECT и пр.
Понимание связи между AFD и TDI является ключевым для последующих этапов изучения, таких как реализация процесса трехстороннего рукопожатия TCP. Полученные знания открывают перспективы создания специализированных библиотек на C/C++, которые позволят формировать и отправлять IRP непосредственно в AFD.sys, минуя высокоуровневые API. Дополнительная обвязка на Python и Rust обещает быструю прототипизацию и расширяемость — сюда входит возможность шеллинга сетевых операций, обхода антивирусных и античитовых механизмов, а также обучение и исследование принципов работы сетевых драйверов Windows. Экспериментальный подход, подкрепленный отладкой в WinDbg и реверс-инжинирингом DLL-библиотек Microsoft, позволил автору составить работающий код, который создает TCP-сокет через AFD.
sys. Эта реализация включает определение точных размеров структур, правильное заполнение полей и специфику вызовов. Таким образом был получен технический и практический фундамент для последующего выполнения операций bind и connect через IOCTL-запросы этого же драйвера. В заключение стоит подчеркнуть, что несмотря на закрытость и сложность Windows ядра, с помощью инструментов отладки, знаний о внутренностях системных вызовов и анализа бинарных модулей возможно достичь глубокого понимания и даже контроля над такими фундаментальными компонентах, как AFD.sys.
Это позволяет не только создать «нестандартные» средства работы с сетью, но и способствует расширенному пониманию внутренней архитектуры Windows, что крайне полезно для специалистов по безопасности, разработчиков драйверов и системных инженеров. Следующая часть исследования будет посвящена реализации полноценного TCP трёхстороннего рукопожатия с использованием IOCTL-запросов AfdBind и AfdConnect, что позволит не просто создавать дескрипторы, но и полноценно использовать их для сетевого взаимодействия на самом низком уровне. Такой подход открывает перед исследователями и разработчиками новый формат взаимодействия с сетевой подсистемой Windows, расширяя горизонты классических API и инструментов.