Загрузка класса драйвера Windows, отличного от NetService, для работы в качестве фильтра NDIS

Можно ли взять драйвер Windows, такой как драйвер класса Ports, а затем настроить его как драйвер фильтра NDIS (класс NetService), вызвав NdisFRegisterFilterDriver() в его DriverEntry()? По сути, это будет означать, что драйвер будет выполнять двойную функцию как драйвер классов Ports и NetService, но в рамках единой кодовой базы и двоичного кода.

Я пытаюсь это сделать и вижу, что вызов для регистрации драйвера NDIS не работает, в частности, со следующим сообщением трассировки:

[0][mp]<==ndisCreateFilterDriverRegistry, FilterServiceName 807EFA18 Status c0000001
[0][mp]==>NdisFRegisterFilterDriver: DriverObject 84C6C428      
[0][mp]==>ndisCreateFilterDriverRegistry, FilterServiceName 807EFA18
[0][mp]<==ndisCreateFilterDriverRegistry, FilterServiceName 807EFA18 Status c0000001

Я осмотрелся, и кажется, что драйвер NDIS сильно зависит от значений, помещенных в реестр из INF и самого INF. Я пытался подделать ключи реестра, добавив NetCfgInstanceId вручную и вызвав это значение в своем коде, прежде чем пытаться зарегистрировать фильтр NDIS, но наткнулся на момент, когда это кажется неправильным способом.

Каков рекомендуемый способ сделать это? На данный момент я полагаю, что для этого потребуется драйвер класса Ports и драйвер класса NetService отдельно, с каким-то составным драйвером, чтобы связать их вместе, чтобы иметь возможность общаться, или иметь способ для одного или другого общаться через межпроцессный коммуникация.


person Preston    schedule 10.06.2015    source источник


Ответы (1)


Суровое предупреждение

Не пытайтесь «установить» фильтр, вручную написав разделы реестра. Как вы заметили, это непросто, и даже если вам кажется, что это работает, все это рухнет, когда ОС попытается установить следующий LWF. Кроме того, я добавил некоторые дополнительные функции повышения безопасности, предназначенные именно для того, чтобы люди не делали этого в Windows 10; вам придется нанести значительный ущерб ОС, прежде чем вы сможете взломать сетевые привязки в Windows 10.

Как структурировать пакет драйверов

В любом случае, то, что вы описываете, действительно возможно. Это можно сделать, предоставив в пакете драйвера следующее:

  1. A PNP-style INF. This INF has:
    1. The PORTS class
    2. Директива AddService, которая устанавливает службу вашего драйвера.
    3. Директива CopyFiles для загрузки любых файлов, которые вам нужны.
    4. Любые другие биты, необходимые для устройства PNP
  2. A NetCfg-style INF. This INF has:
    1. The NETSERVICE class
    2. Обычный материал LWF: Characteristics=0x40000, FilterMediaTypes=xxx, FilterType=xxx и т.д.
    3. Ссылка на службу, которую вы установили в другом INF (HKR,Ndi,Service,,xxx)
    4. Не включайте AddService или CopyFiles; об этом уже позаботился первый INF
  3. One .sys file. This driver does:
    1. In DriverEntry, call NdisFRegisterFilterDriver, and pass the name of your service "xxx"
    2. В DriverEntry позвоните WdfDriverCreate или заполните таблицу диспетчеризации DRIVER_OBJET, как обычно для любого другого водителя PNP.
    3. Реализовать FilterAttach и т. д. в обычном режиме; реализовать обработчики WDF EvtXxx или WDM IRP в обычном режиме
    4. Не забудьте вызвать NdisFDeregisterFilterDriver в EvtDriverUnload или DriverUnload, а также в пути отказа для DriverEntry

Как установить этот прекрасный беспорядок

Хорошей новостью является то, что с этими двумя INF-файлами вы можете удовлетворить свое требование, чтобы один файл .sys выполнял две задачи. Плохая новость в том, что теперь у вас есть 2 INF. Хуже того, одна из INF является INF в стиле NetCfg, так что вы не можете просто Include+Need ее. Единственный способ установить INF-файл в стиле NetCfg — это вызвать INetCfgClassSetup::Install (или NetCfg.exe, его оболочку командной строки). Центр обновления Windows знает только, как установить INF-файлы в стиле PNP, а PNP умеет только Include устанавливать другие INF-файлы в стиле PNP.

Таким образом, самым простым решением является поставка установщика exe/msi, который вызывает INetCfg API. Если вы можете это сделать, это просто вопрос пары вызовов SetupCopyOemInf и шаблона INetCfg, который вы можете найти в образец bindview.

Но если вам нужно поддерживать установку, ориентированную на оборудование, вам нужно использовать большие пушки. Вам нужно будет написать Co-Installer и включите его в свой пакет драйверов. Работа Co-Installer состоит в том, чтобы вызывать INetCfg API, когда ваш пакет драйверов установлен, и отменять регистрацию, когда пакет удаляется.

Совместные установщики обычно не рекомендуются и не поддерживаются для универсальных драйверов. Поэтому вам следует избегать Co-Installer, если у вас нет выбора. К сожалению, я не могу придумать другого способа зарегистрировать NDIS LWF, когда драйвер устройства PNP установлен через Центр обновления Windows. (Это не значит, что нет хитрого способа сделать это; я не знаю всего.)

Обратите внимание, что вам в любом случае понадобится Co-Installer, даже если вы отправляете 2 файла .sys. Необходимость вызова INetCfg не изменится только потому, что вы объединили двоичные файлы драйвера.

Ограничения

У вас будет полноценный драйвер NDIS LWF, а также полноценный драйвер устройства PNP. Единственная (незначительная) вещь, которая не работает, это то, что вы не можете вызвать NdisRegisterDeviceEx в этом драйвере. Причина в том, что когда вы вызываете NdisRegisterDeviceEx из LWF, NDIS попытается кооптировать таблицу диспетчеризации вашего драйвера. Но в этом двойном драйвере PNP+LWF таблица диспетчеризации принадлежит WDF или вам. Это ограничение не является проблемой, так как вы можете вызвать WdfDeviceCreate, и эта подпрограмма проще в использовании и в любом случае имеет больше возможностей, чем подпрограмма NDIS.

В приведенной выше конфигурации служба драйвера принадлежит PNP. Это означает, что время жизни вашего файла .sys принадлежит PNP. Вы не можете вручную «сетевой запуск» службы драйвера PNP; единственный способ загрузить ваш файл .sys - это фактически перечислить ваше оборудование. Это означает, что вы не можете запустить NDIS LWF, если аппаратное обеспечение отсутствует. Как правило, это то, что вы хотели бы в любом случае. Если это не так, вы можете попробовать возиться с директивой ServiceName, но с этим есть несколько странных предостережений, и я сам не совсем понимаю это.

person Jeffrey Tippet    schedule 12.06.2015
comment
Отлично, я только что доказал это, и фильтр загружается в бинарном файле двойного назначения - большое спасибо за такой хорошо написанный и подробный ответ! - person Preston; 13.06.2015