Загрузка класса драйвера 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 драйвер класса отдельно, с каким-то составным драйвером, чтобы связать их вместе, чтобы иметь возможность общаться, или иметь возможность для того или другого общаться через межпроцессное взаимодействие.

1 ответ

Решение

Строгое предупреждение

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

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

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

  1. ИНФ в стиле PNP Этот INF имеет:
    1. PORTS учебный класс
    2. AddService директива, которая устанавливает ваш драйвер службы
    3. CopyFiles директива, чтобы принести любые файлы, которые вам нужны
    4. Любые другие биты, необходимые для устройства PNP
  2. INFC в стиле NetCfg Этот INF имеет:
    1. NETSERVICE учебный класс
    2. Обычные вещи LWF: Characteristics=0x40000, FilterMediaTypes=xxx, FilterType=xxx, так далее.
    3. Ссылка на сервис, который вы установили в другом INF (HKR,Ndi,Service,,xxx)
    4. Не включайте AddService или же CopyFiles; об этом уже позаботился первый INF
  3. Один файл.sys. Этот драйвер делает:
    1. В DriverEntry, вызов NdisFRegisterFilterDriverи передайте название вашей услуги "ххх"
    2. В DriverEntry, вызов WdfDriverCreate или заполните DRIVER_OBJET таблица отправки, как обычно для любого другого драйвера PNP
    3. Воплощать в жизнь FilterAttach и тд нормально; реализовать ваши обработчики WDF EvtXxx или WDM IRP нормально
    4. Не забудьте позвонить NdisFDeregisterFilterDriver в EvtDriverUnload или же DriverUnload, а также в пути отказа для DriverEntry

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

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

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

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

Соустановщики, как правило, не рекомендуется и не поддерживаются для универсальных драйверов. Поэтому вам следует избегать Co-Installer, если у вас нет выбора. К сожалению, я не могу придумать какой-либо другой способ регистрации NWIS 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, но есть некоторые странные предостережения с этим, и я сам не до конца понимаю.

Другие вопросы по тегам