antivirus NDIS filter removal - windows

On our 1200 windows clients we are using KES 10 antivirus.
By error on some desktop workstation we installed the firewall component "klim6".
We need a silent uninstall. Not found within Kaspersky tools.
Which is the working and proper way ?
RUNDLL32.EXE SETUPAPI.DLL,InstallHinfSection DefaultUninstall 132 KES10.inf
NETCFG.EXE -v -u KLIM6
devcon.exe remove =net *klim6*
We need also the explanation of the different behaviour of these tools.
UPDATE : info from the INF file :
; KLIM6.INF -- NDIS Usermode I/O Driver
[version]
Class = NetService
DriverPackageType=Network
[Manufacturer]
%Klft%=KLFT,NTx86,NTia64,NTamd64

As you've noted, there are a variety of tools to work with .INF files. The reason is that there are different flavors of .INF, used for different purposes.
I don't know if there's any official terminology, but here's the terminology that I use:
DefaultInstall-style INFs. Use "rundll32.exe SetupApi.dll,InstallHinfSection" to work with these. You can identify this style of INF because they have "[DefaultInstall]" in them.
PNP-style INFs. Use pnputil.exe (built-in, so more convenient) or devcon.exe (more powerful) to work with these. You can identify PNP-style INFs because they have a "[Manufacturer]" section, and they are not NetCfg-style INFs.
NetCfg-style INFs. Use NetCfg.exe to work with these. You can identify NetCfg-style INFs by the line Class=NETTRANS or Class=NETSERVICE or Class=NETCLIENT. Only those 3 classes are NetCfg-style INFs -- in particular, Class=NET is not a NetCfg-style INF; it is a PNP-style INF.
There are other types of INFs used for Windows Drivers, e.g., storage minifilter-style, or upper/lower-filter style INFs. And other people use INFs for things that have nothing to do with Windows Drivers... so it's a confusing area.
That being said, it's often a mistake to attempt to manually remove a driver. Usually an application's installer will install many 100's of things, only one of which is the driver. If you delete only the driver from an application, you could easily leave dangling bits that damage the system in obvious or subtle ways.
If you really want to do this anyway, you should check the INF file. If it says Class=NET, then use devcon.exe. If it says Class=NETSERVICE, you should use NetCfg.exe.

I also had to remove kaspersky NDIS filter (for different reasons).
The proper way to do this is with netcfg.exe
You need to disabled the Kaspersky's Self-Defense mechanism and exit the product. You can then uninstall it with this command:
C:\Windows\System32\netcfg.exe /v /u kl_klim6
Unfortunatly, I couldn't find an easy way to uninstall the filter in Windows XP but one method is provided Here

Related

Using netcfg to remove an NDIS LWF doesn't remove it from the driver store?

When i try to remove my NDIS LWF using netcfg -u, i notice that it doesn't remove it from the driver store (can be seen with pnputil /enum-drivers).
This is causing problem because on some Windows 10 machines, if we uninstall the previous version of our NDIS LWF and install the new one using netcfg, for some unknown reason the old inf is still used to install it! And i assume its because the inf still has the same componentID? We are updating the INF file in order to attach to some virtual adapters that we previously couldn't attach. Note that this doesn't happen in Windows 7, and we can install the new one without any problem.
So my questions are:
Why is Windows still using the previous INF from driver store when we try to install the new updated driver that has a different INF?
What is the proper way to fully remove the previous NDIS LWF, including from driver store? If we need to use pnputil to fully remove it from driver store, then what is the proper way of finding the OEM number, considering that pnputil -d requires an OEM number?
Right, as you've noticed, netcfg.exe -i is not the exact opposite of netcfg.exe -u.
Installation does these steps:
Install the INF you provided with -l to the driver store (SetupCopyOEMInf)
Call INetCfgClassSetup::Install to:
Query PNP for the "best match" for the componentId you provided with -i (SetupDiBuildDriverInfoList, SetupDiSelectBestCompatDrv)
Run all the sections in the INF (AddReg, AddService, etc)
Register a LWF/Protocol/TDI driver with the system using info in the Ndi registry key
Uninstall does these steps:
Call INetCfgComponent::DeInstall to:
Deregister your LWF/Protocol/TDI driver with the system
Run the special .Remove section of the INF (which, hopefully, contains a DelReg, DelService to undo everything done during install step #2.2)
(The descriptions above ignore the driver refcount system (aka OBO_TOKEN), since it isn't often used — most drivers just use a single refcount. If you exclusively use netcfg.exe to manage your driver, then you too can ignore refcounts.)
You might be wondering: why is this so very less-than-awesome? The backstory here is that netcfg.exe was never really meant to be a general-purpose tool for 3rd party software to manage their drivers. It was only meant to be used internally, for the drivers that are built into the OS (ms_tcpip etc). The assumption was that 3rd party driver installers would want to call proper APIs like INetCfg, not CreateProcess some executable and screen-scrape the output. So netcfg.exe was only built up to be the minimum needed for our internal needs. In particular, very little attention was paid to uninstall, since built-in drivers are rarely uninstalled. (Likewise, argument parsing is inflexible, the help text is not helpful, and the error handling is not robust.)
Starting in Windows 10, built-in drivers are no longer installed using netcfg.exe, so the OS itself doesn't need netcfg.exe at all anymore. But by then, 3rd party products had discovered it and taken a dependency on it, so we couldn't just remove netcfg.exe anymore. Ah well.
Why is Windows still using the previous INF from driver store when we try to install the new updated driver that has a different INF?
This is a common gotcha. Note that, during install, steps #1 and #2 have no association between them. You could install a printer INF and a LWF at the same time — netcfg.exe -l foo.inf -i bar makes no effort whatsoever to ensure that the "best" component selected in step #2.2 actually came from the INF installed in step #1.
In order to ensure that the driver you want is the "best" driver, you have to ensure that your favored driver wins the PNP driver selection algorithm. I've personally been bitten by this because I didn't bump the DriverVer line during development iterations. Make sure you increment DriverVer every time you change the driver.
What is the proper way to fully remove the previous NDIS LWF, including from driver store? If we need to use pnputil to fully remove it from driver store, then what is the proper way of finding the OEM number, considering that pnputil -d requires an OEM number?
Honestly, if you want to do everything really correctly, I suggest avoiding netcfg.exe entirely. Use the underlying INetCfg APIs instead. Then your installer will have to manage the driver (SetupCopyOEMInf / SetupUninstallOEMInf).
You aren't losing much by ditching netcfg.exe and calling INetCfg yourself. netcfg.exe doesn't do anything particularly fancy with INetCfg: its own implementation is nearly exactly taken from this sample code. If you start with that and slap a call to SetupCopyOEMInf on top, you'll pretty much be at parity with netcfg.exe already. From there, you can improve it with more robust INF uninstall. You can even write some code to inventory all the INFs with your componentId, to make sure there aren't stale copies of your INF hiding around.
You still have to make that leap of trust from installing an INF to hoping that INetCfgClassSetup::Install thinks your recently-installed INF is the "best" INF. But if you've removed every other INF with that componentId, then you can be certain that the sole remaining INF must be the best match.

Loading a Windows Driver Class other than NetService to act as an NDIS Filter

Is it possible to take a Windows driver such as a Ports class driver, then have it also set itself up as an NDIS filter (NetService class) driver by calling NdisFRegisterFilterDriver() in it's DriverEntry()? This would be essentially having the driver work double duty as a Ports and NetService class driver, but within a single code base and binary.
I'm attempting to do this and I'm seeing the call to register the NDIS driver fail, specifically with the following trace message:
[0][mp]<==ndisCreateFilterDriverRegistry, FilterServiceName 807EFA18 Status c0000001
[0][mp]==>NdisFRegisterFilterDriver: DriverObject 84C6C428
[0][mp]==>ndisCreateFilterDriverRegistry, FilterServiceName 807EFA18
[0][mp]<==ndisCreateFilterDriverRegistry, FilterServiceName 807EFA18 Status c0000001
I've looked around and it seems that the NDIS driver is heavily dependent on the values placed in the registry from the INF and the INF itself. I've tried to spoof the registry keys by adding the NetCfgInstanceId by hand and calling that value out in my code before trying to register the NDIS filter, but have hit a point where it just seems like the wrong way to go about it.
What is the recommended way to go about this? At this point I'd imagine that this would require a Ports class driver and NetService class driver separately, with some kind of composite driver to tie them together to be able to communicate, or have a way for one or the other to communicate through interprocess communication.
A stern warning
Do not attempt to "install" a filter by manually writing registry keys. As you've noticed, it's not easy, and even if you seem to get it working, it will all collapse when the OS tries to install the next LWF. Furthermore, I added some additional hardening features designed exactly to prevent people from doing this to Windows 10; you'll have to do some significant damage to the OS before you can hijack network bindings in Windows 10.
How to structure your driver package
Anyway, what you're describing is indeed possible. The way to do it is to provide the following in your driver package:
A PNP-style INF. This INF has:
The PORTS class
An AddService directive, that installs your driver service
A CopyFiles directive to bring in any files you need
Any other bits you need for the PNP device
A NetCfg-style INF. This INF has:
The NETSERVICE class
The usual LWF stuff: Characteristics=0x40000, FilterMediaTypes=xxx, FilterType=xxx, etc.
A reference to the service you installed in the other INF (HKR,Ndi,Service,,xxx)
Do not include an AddService or CopyFiles; that's already taken care of by the first INF
One .sys file. This driver does:
In DriverEntry, call NdisFRegisterFilterDriver, and pass the name of your service "xxx"
In DriverEntry, call WdfDriverCreate or fill out the DRIVER_OBJET dispatch table as you normally would for any other PNP driver
Implement FilterAttach and etc normally; implement your WDF EvtXxx or WDM IRP handlers normally
Don't forget to call NdisFDeregisterFilterDriver in EvtDriverUnload or DriverUnload, and also in the failure path for DriverEntry
How to install this fine mess
The good news is that, with these 2 INFs, you can meet your requirement of having 1 .sys file do two things. The bad news is that you've now got 2 INFs. Worse, one of the INFs is a NetCfg-style INF, so you can't just Include+Need it. The only way to install a NetCfg-style INF is to call INetCfgClassSetup::Install (or NetCfg.exe, its command-line wrapper). Windows Update only knows how to install PNP-style INFs, and PNP only knows how to Include other PNP-style INFs.
So the simplest solution is to ship an installer exe/msi that invokes the INetCfg API. If you can do that, it's simply a matter of a couple calls to SetupCopyOemInf and the INetCfg boilerplate that you can find in the bindview sample.
But, if you have to support a hardware-first installation, you need to bring out the big guns. You'll need to write a Co-Installer and include it with your driver package. The Co-Installer's job is to call the INetCfg APIs when your driver package is installed, and deregister when the package is uninstalled.
Co-Installers are generally discouraged, and are not supported for Universal drivers. So you should avoid a Co-Installer unless you've got no choice. Unfortunately I cannot think of any other way to register an NDIS LWF when a PNP device driver is installed through Windows Update. (This doesn't mean there isn't a crafty way to do it; I don't know everything.)
Note that you'd need a Co-Installer anyway even if you were shipping 2 .sys files. The need to call INetCfg doesn't change just because you merged the driver binaries.
Limitations
You'll have a full-fledged NDIS LWF driver, as well as a full-fledged PNP device driver. The only (minor) thing that doesn't work is that you cannot call NdisRegisterDeviceEx in this driver. The reason is that when you call NdisRegisterDeviceEx from a LWF, NDIS will attempt to co-opt your driver's dispatch table. But in this PNP+LWF dual driver, the dispatch table is owned by WDF or by you. This limitation is no problem, since you can call WdfDeviceCreate, and this routine is easier to use and has more features than the NDIS one anyway.
With the above configuration, the driver service is owned by PNP. That means the lifetime of your .sys file is owned by PNP. You cannot manually "net start" a PNP driver service; the only way to get your .sys file loaded is to actually enumerate your hardware. That means you can't have your NDIS LWF running when the hardware is not present. Typically this is what you'd want anyway. If it's not, you can try messing with the ServiceName directive, but there's some weird caveats with that, and I don't fully understand it myself.

How to un-enumerate a PNP device in Windows?

I'm doing a bit of driver programming and I have a PNP driver for a pseudo-device that has it's own custom device setup class. The driver is a pseudo-bus enumerator and creates pseudo devices, not unlike the toaster example.
Anyways, I have a whole lot of old, unneeded entries in HKLM\SYSTEM\CurrentControlSet\Enum now. Is there some nice utility for removing old device enumerations in there? I don't seem to be able to do it with devcon or pnputil. I can delete it manually, but that's really tedious given that only SYSTEM has full control privileges over much of what's in Enum.
The reason that devcon remove isn't working is because devcon hardcodes the DIGCF_PRESENT flag, and your old unneeded devices are not currently present. As the devcon source code is publicly available, you can compile your own version that removes the flag.
Hint: start looking in the cmdRemove function.

The Uninstall section of my .INF

I'm working on extending an existing USB device driver, and have been struggling learn how the .INF file works. I believe that I have it right now, the driver installs and works. It also shows up in the "Add/Remove Programs" list.
I find that when I uninstall the driver from Add/Remove, it seems to do little if anything. This was in the .INF as I inherited it:
[myUninstall]
DelReg = myDelReg
[MyDelReg]
HKLM, "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\myName"
I can find no other references, not even where "myName" is installed in the registry Uninstall.
I've changed the .INF to have this:
[DefaultUninstall]
myUninstall
[myUninstall]
DelFiles = ... a list of files ...
DelDirs = UNINST.Dirs
DelReg = UNINST.Regs
Cleanup = 1
[UNINST.Dirs]
%16422%\%InstallDir%
[UNINST.Regs]
myDev.AddReg
myDev.CommonRegs
[myDev.AddReg] ; same definition used for installing
HKR,,Drivers,Subclasses,,"wave,midi,mixer,aux"
...
[myDev,CommonRegs] ; same definition used for installing
HKR, Parameters, BufferSize, 0x0010001, 256
...
Still, whether I uninstall from the Control Panel Add/Remove programs or do it from the device manager, the system doesn't complain and nothing seems to happen. I've looked at the output of "dpinst /c" and the setupapi.log, and neither tell me much. dpinst shows no error but is clearly not even trying to execute my uninstall section.
I find a lot of verbiage online and examples of uninstall sections, but very little in the way of explanation. I did stumble across one sentence in 1 forum today that implied that PnP device .INF's don't use Uninstall. Perhaps this is my issue?
am I wrong in thinking that I can have Uninstall in this .INF?
is there some other way to tell what is happening?
is my only recourse to write a separate uninstaller?
AFIK, the INF files do not participate in uninstallation.
You will need to write a separate uninstaller if you want to perform proper cleanup.
Further note that with Vista and beyond, Windows also includes a Driver Store, where it silently copies the driver package (inf and files references from the inf). If you want to perform a full cleanup, the driver store should also be cleaned up.
I don't think DefaultUninstall is a standard section in the way DefaultInstall is. Often you will see the UninstallString ARP entry just calling DefaultUninstall by name.
The documentation in this area is pretty bad and there is a split between the basic SetupAPI/SetupX INF files and the Advanced INF files (AdvPack).
The only 3rd-party exception I know of is TweakUI.inf from the Windows 95 PowerToys.
It has parts that look like this:
...
[Optional Components]
TweakUIInstall
[TweakUIInstall]
CopyFiles = ...
AddReg = ...
Ini2Reg = ...
...
InstallType = 10 ;Typical, Custom.
Uninstall = DefaultUnInstall
[DefaultUnInstall]
DelFiles = ...
DelReg = ...
But I think that only works with the optional components feature, not basic uninstallation. TweakUI v1.33 (Tweakui.exe SFX archive) has some more NT related entries and I believe the way it writes the UninstallString for NT even writes the wrong INF section. Wrong or not, it manually has to specify a INF section for normal uninstall.

How do I add the NULL device to Windows XP Embedded?

Windows XP Embedded is missing the NULL or "NUL" device. For one thing, Visual Studio seems to require it and trying to build a project aborts with a PRJ0015 error.
Anyone know how to configure an XPe image to include support for the NUL device?
"Null Device Driver" is available in the XPe Target Designer, but it's normally hidden. Apparently each component has a visibility level, and if it's lower than that set in the Target Designer options (Tools->Options), it's hidden. Null Device Driver is at level 200, so I set the level to 100 and could see it and install it.
There's another important situation where you're going to want the NUL device: if you're installing some or all of the Cygwin UNIX solutions for Windows. In particular, if you're doing something like, oh, I don't know, to pick a completely random example, trying to put an SSH server on the damned thing so you can, just on a lark, say, log in and maintain it.
That's right-- Cygwin actually maps its UNIX /dev/null device to the Windows NUL device. You know, for maximum compatibility. Just in case the platform-specific implementation of IMMEDIATELY THROWING DATA INTO THE TOILET AND OBLITERATING IT, NEVER TO BE SEEN AGAIN, UNTIL THE HEAT DEATH OF THE UNIVERSE, happened to be novel and innovative.
While cygwin will INSTALL without NUL available, it will not, in fact, actually enjoy a typical work day. This is most evident the first time you try to launch a bash shell, and notice a slew of error messages about /dev/null resulting in no such file or directory errors. One presumes the device is perhaps actually just an NTFS link, but who knows.
In any case, the fix is to add the "Null Device Driver" component, helpfully located under Software -> System -> Other, a surprisingly small category which also contains such useful components as Internet Checkers, the Schedule Service Command Line Utility, the 1394 Kernel Debugger Support Library, EBCDIC support for Microsoft Bob, some cheat codes for Zork, and the code pages to say "(A)bort, (R)etry, (I)gnore, (F)ail?" in Muppet Swedish ("(B)ork, b(o)rk, bo(r)k, bor(k)?")
Hope this helps,
Matt "Breakpoint" Heck
Running Visual Studio itself on XP Embedded doesn't seem like it'd be supported. You should build on a full OS and then just deploy your application to XP embedded.

Resources