Modifying LWF Driver - Error injecting ARP packet below Native WiFi Filter

Hello.

We are dealing with an issue concerning a NDIS LWF injecting frames to a WiFi NIC (through Native WiFi Filter).

Based on the Microsoft?s passthru LWF driver, our filter intercepts and processes NDIS packets, and its INF parameters are:

  • FilterType -> 0x00010001, 0x00000002 (MODIFYING)
  • FilterRunType -> 0x00010001, 2 (OPTIONAL)
  • FilterMediaTypes -> “ethernet, tokenring, fddi, wan”
  • FilterClass -> compression

The filter works making a copy of the original NDIS packets and dropping the original ones. After processing the copies, new NBLs are generated with them and injected in either send or receive direction. This mechanism is working well and no issue has been found.

Nevertheless, sometimes we need to inject a crafted ARP packet generated by the filter, but when NDIS calls FilterReturnNetBufferLists function, the following error code is received in the NBL status field:

0xC023001F STATUS_NDIS_MEDIA_DISCONNECTED The I/O operation failed because the network media is disconnected or the wireless access point is out of range.

After investigation, we have delimited the problem and see that, despite being a modifying filter, it sometimes (and we don?t know why) is located below the Native WiFi Filter Driver (from now on, NWF), in both Windows 7 and Windows 8 (and 8.1) operating systems. When this happens, we have two different behaviors:

* In Windows 7, the packet is successfully injected.
* In Windows 8 and Windows 8.1, we get the previously detailed error.

On the other hand, if our filter is above the NWF, the injection is always correctly performed.

It?s important to note that the rest of the traffic is being correctly injected, and that the ARP packet seems to be well crafted, comparing it to a real one.

Finally, we have observed that when the system is already started and we ensure that the issue is happening, if we stop and start our LWF driver, the injections works well.

Our questions are:

  1. What could be the problem? What could we be doing wrong?
  2. As we have seen in other posts, a modifying LWF is supposed not to be below the NWF. How could this happen? Does it make sense? Is there a problem with the OS or could it be a bug in our INF file for example?
  3. Is there something strange with Windows 8 and Windows 8.1 that provokes this behavior?
  4. It?s possible that we ensure our driver to be always above the NFW? How can we achieve that (programmatically, INF file, etc.)?

We would appreciate it very much if anyone could help us with this issue. Thank you in advance

I’m not too surprised that the packets don’t work if your driver gets stuck below NWIFI. We don’t support drivers doing that, because you need to decorate your packets in a special way & synchronize with the WLAN state machine, etc.

So the question is how did your LWF get stuck below NWIFI.

Thanks for providing a detailed description; that’s helpful. One thing that wasn’t clear from your description, though. When you encounter a system in this bad state, does it recover after a reboot? If not, does it recover if you uninstall the NIC and reinstall it (do this from Device Manager)? If not, does it recover if you uninstall your LWF and reinstall it?

Your summary of your INF looks good. (Although I suggest pasting in the exact INF syntax, in case you accidentally fixed a typo when you retyped it into email.) From what I see, your LWF should bind exactly once to t

I rewrote the NDIS engine that attaches LWFs in Windows 8.1. So I would expect that Windows 7 and Windows 8 have similar behavior; and Windows 8.1 has potentially different behavior. It’s unlikely that there’s an NDIS binding/attaching bug in both Windows 8 and Windows 8.1, since those two operating systems have such different NDISes.

I’m aware of only 1 bug in Windows 8.1 that affects filter attach order. If your driver’s INF said that the filter was FilterClass=X, and you update to a new version of the INF that says the filter is FilterClass=Y, then NDIS won’t actually move your LWF until you reboot the system. (This bug is fixed in Windows 10.) I presume you aren’t updating from an INF that has a different FilterClass, though?

That all is what I use to convince myself that the problem is not in your INF and it’s not in NDIS. The remaining target for blame is netcfg. Netcfg might have installed your LWF incorrectly. Check the miniport’s Linkage key to see if the FilterList has your filter in the correct place. The Linkage key is

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class{4d36e972-e325-11ce-bfc1-08002be10318}####\Linkage

Where “####” is the index for your WLAN NIC. You can find it by browsing through all the indexes until you find one that has strings that mention your NIC’s name. Under the Linkage key, there’s a FilterList value. That is a list of all the LWFs on this miniport. Your LWF is identified by the NetCfgInstanceId={guid} line from your INF. The GUID for NWIFI is E475CF9A… You should see your LWF before NWIFI.

If the FilterList is correct, then the bug really is in NDIS. If the FilterList is incorrect, then the bug is in your INF or netcfg.

Hi Jeffrey.

First of all, thanks a lot for your help, dedication and promptness of your reply.

The following results have been

Regarding the question of packets not working, we would like to remark that except the ARP packet, every other traffic works well in spite of the fact that our LWF is below NWF.

The system does not recover either after a reboot or after uninstalling the WiFi NIC and reinstalling it. In contrast, if we uninstall and reinstall our LWF, the problem is solved and, what’s more, if we just stop and start the LWF, the problem is solved again.

With respect to the INF, at the end of this reply you can see the whole file copied and pasted. We hope not to flood you with too much information.

Talking about the FilterClass, it does not affect our case because our LWF has had the same parameter since the beginnings, years ago.

Apart from this, what we have seen in the registry is that our LWF is ALWAYS below the NWF, in both the working and not working cases. So as you said it seems to be a problem with the inf or netcfg.

The FilterList registry entry is:

{247296B6-A5D0-4153-92FD-80329CFD73DF}-{3BFD7820-D65C-4C1B-9FEA-983A019639EA}-0000 WFP Native MAC Layer LightWeight Filter
{247296B6-A5D0-4153-92FD-80329CFD73DF}-{5CBF81BF-5055-47CD-9055-A76B2B4E3698}-0000 Virtual WiFi Filter Driver
{247296B6-A5D0-4153-92FD-80329CFD73DF}-{E475CF9A-60CD-4439-A75F-0079CE0E18A1}-0000 >>> NativeWiFi Filter <<<
{247296B6-A5D0-4153-92FD-80329CFD73DF}-{C98E08D2-C96C-4F43-947D-E63428BE1BBA}-0000 *** Our LWF ***
{247296B6-A5D0-4153-92FD-80329CFD73DF}-{B5F4D659-7DAA-4565-8E41-BE220ED60542}-0000 QoS Packet Scheduler
{247296B6-A5D0-4153-92FD-80329CFD73DF}-{B70D6460-3635-4D42-B866-B8AB1A24454C}-0000 WFP 802.3 MAC Layer LightWeight Filter

After stopping and starting the LWF, what solves the issue, we have observed that the FilterList does not change, but with the !ndiskd.netreport command the order is correct, with the LWF above the NWF. In contrast, in error cases the ndiskd shows the LWF below the NWF and the registry entries remain invariable. So it looks like the registry key list is just fixed and is not updated, whereas the ndiskd extension gives us the exact configuration. Is this true? How does it work?

We have a tool that installs and uninstalls the LWF using the functions provided by the NetCfg library. To discard it, we have tested installing the LWF manually, via INF, from network adapter properties. The results have been the same that we have presented, so we believe it’s nothing to do with that tool but with the INF or the Netcfg library.

Finally we must say that we have tested the case with a bunch of different wifi devices, and some of them worked well in the same conditions that the initial one failed. That makes us consider the possibility that even though the LWF is below the NWF (at least in the registry), the right behaviour may be influenced by the WiFi NIC driver. Does this make sense?

Again thanks a lot for your time and help. Have a good day.

*********************************************************************************************
--------------------------------------------- INF FILE --------------------------------------
*********************************************************************************************

;-------------------------------------------------------------------------
; – NNSNAHSL.INF –
;
; NDIS Kernelmode I/O Driver
;
; Copyright (c) 2014, Panda Security, S.L. All rights reserved.
;-------------------------------------------------------------------------

[version]
Signature = “$Windows NT$”
Class = NetService
ClassGUID = {4D36E974-E325-11CE-BFC1-08002BE10318}
Provider = %Panda%
DriverVer = 12/31/2014,4.1.0.47
CatalogFile = nnsnahsl.cat

[Manufacturer]
%Panda%=PANDA,NTx86,NTia64,NTamd64

[PANDA]
%NNSNAHSL_Desc%=Install, NNSNAHSL

[PANDA.NTx86]
%NNSNAHSL_Desc%=Install, NNSNAHSL

[PANDA.NTia64]
%NNSNAHSL_Desc%=Install, NNSNAHSL

[PANDA.NTamd64]
%NNSNAHSL_Desc%=Install, NNSNAHSL

;-------------------------------------------------------------------------
; Installation Section
;-------------------------------------------------------------------------
[Install]
AddReg=Inst_Ndi
Characteristics=0x40000 ; NCF_NDIS_PROTOCOL
NetCfgInstanceId=“{c98e08d2-c96c-4f43-947d-e63428be1bba}”
Copyfiles = NNSNAHSL.copyfiles.sys
CopyInf = nnsnahsl.inf

[SourceDisksNames]
1=%NNSNAHSL_Desc%,“”,

[SourceDisksFiles]
NNSNAHSL.sys=1

[DestinationDirs]
DefaultDestDir=12
NNSNAHSL.copyfiles.sys=12

[NNSNAHSL.copyfiles.sys]
NNSNAHSL.sys,2

;-------------------------------------------------------------------------
; Ndi installation support
; - ethernet: ethernet & MobileBroadband support for XP/Vista
; - ppip : Added for MobileBroadband support in Win7/8/8.1
;-------------------------------------------------------------------------
[Inst_Ndi]
HKR, Ndi,Service,“NNSNAHSL”
HKR, Ndi,CoServices,0x00010000,“NNSNAHSL”
HKR, Ndi,HelpText,%NNSNAHSL_HelpText%
HKR, Ndi,FilterClass, compression
HKR, Ndi,FilterType,0x00010001,0x00000002
HKR, Ndi\Interfaces,UpperRange,“noupper”
HKR, Ndi\Interfaces,LowerRange,“nolower”
HKR, Ndi\Interfaces, FilterMediaTypes,“ethernet, tokenring, fddi, wan, ppip”
HKR, Ndi\Interfaces, LowerExclude, , “ndisatm, ndiscowan, ndiswan, ndiswanasync, ndiswanipx, ndiswannbf, vpnva”
HKR, Ndi,FilterRunType, 0x00010001, 2 ; OPTIONAL Filter | This is an optional filter module

;-------------------------------------------------------------------------
; Service installation support
;-------------------------------------------------------------------------
[Install.Services]
AddService=NNSNAHSL,NNSNAHSL_Service_Inst

[NNSNAHSL_Service_Inst]
DisplayName = %NNSNAHSL_Desc%
ServiceType = 1 ;SERVICE_KERNEL_DRIVER
StartType = 1 ;SERVICE_SYSTEM_START
ErrorControl = 1 ;SERVICE_ERROR_NORMAL
ServiceBinary = %12%\NNSNAHSL.sys
LoadOrderGroup = NDIS
Description = %NNSNAHSL_Desc%
AddReg = Common.Params.reg

[Install.Remove.Services]
DelService = NNSNAHSL,0x200

[Install.Remove]
DelFiles = NNSNAHSL.copyfiles.sys

[Common.Params.reg]

HKR, FilterDriverParams\DriverParam, ParamDesc, , “Driverparam for lwf”
HKR, FilterDriverParams\DriverParam, default, , “5”
HKR, FilterDriverParams\DriverParam, type, , “int”

HKR, FilterAdapterParams\AdapterParam, ParamDesc, , “Adapterparam for lwf”
HKR, FilterAdapterParams\AdapterParam, default, , “10”
HKR, FilterAdapterParams\AdapterParam, type, , “int”

;-------------------------------------------------------------------------
; Strings Section
;-------------------------------------------------------------------------

[Strings]
Panda = “Panda Security, S.L.”
NNSNAHSL_Desc = “Network Activity Hook Server LightWeight Filter Driver”
NNSNAHSL_HelpText = “Network Activity Hook Server LWF Packet Interception Driver”

It’s interesting to me that your filter has a LowerExclude directive. Most INFs don’t use that. It’s possible that netcfg has a bug when handling that directive. But the FilterList is correct, so I’m not sure how a hypothetical bug in netcfg would work. Can you try deleting the LowerExclude bit and see if that resolves the issue?

the ndiskd extension gives us the exact configuration. Is this true? How does it work?

Yes, ndiskd gets its information by looking at what NDIS is *actually* doing right now. In theory that’s supposed to be the same as what’s in the registry. (Modulo drivers that are missing because they aren’t running, and a few special case drivers that get added automatically.) So the flow of data is:

[All the INFs] —> [netcfg] —> [Linkage key in registry] —> [NDIS in kernel] —> [!ndiskd]

We have a tool that installs and uninstalls the LWF using the functions provided by the NetCfg library

Your tool is almost certainly not to blame. There’s only 1 function the tool needs to call, INetCfgClassSetup::Install, and that only takes 1 relevant parameter. So there’s no opportunity to mess that up!

the right behaviour may be influenced by the WiFi NIC driver. Does this make sense?

Oh absolutely. The purpose of NWIFI is to help hide the 802.11 MAC from you. 802.11 doesn’t really have Ethernet broadcast like your LWF is expecting, so NWIFI fakes it for you. But if you bind below NWIFI, then you’re at the mercy of the NIC driver to notice that you’re sending an illegal packet.

Hello.

We reckon that the LowerExclude directive has nothing to do with this case, because the issue occurred without that directive too.

Another symptom of the issue is in Windows 8 and Windows 8.1 the NICs behave in the same way in the same conditions, both those ones that work well and the one that doesn’t work. In contrast, in Windows 7 the issue is not reproduced.

Sorry for making a little mess with the registry-ndiskd thing. We were looking erroneously at the !ndiskd.netreport information.

However, we have observed that both the FilterList and the ndiskd information are correct in both the good and the bad behaviour. That leads us to your first reply, when you said “If the FilterList is correct, then the bug really is in NDIS. If the FilterList is incorrect, then the bug is in your INF or netcfg.”. But we are sceptic about a bug in NDIS. What do yo believe? Another possibility is a bug in the WiFi NIC driver.

Finally we would like to set out a possible solution. We are seriously thinking about migrating our (NDIS-based) ARP packet injection functionality to a new WFP-based from Windows 8 on (_MAC_FRAME_ETHERNET layer). Will we be allowed to inject an ARP packet crafted by us without any problem? Do you recommend us to undertake the migration from LWF to WFP?

Lots of thanks again for your dedication and help.