Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Npcap OEM 0.9990: Silent upgrade fails when DLL files are in use #2015

Closed
akontsevoy opened this issue Apr 18, 2020 · 7 comments
Closed

Npcap OEM 0.9990: Silent upgrade fails when DLL files are in use #2015

akontsevoy opened this issue Apr 18, 2020 · 7 comments

Comments

@akontsevoy
Copy link

When trying to upgrade an existing Npcap installation that's currently being used in silent mode (npcap-0.9990-oem.exe /loopback_support=no /admin_only=yes /dot11_support=no /winpcap_mode=no /S), the installer fails and/or hangs indefinitely for several reasons:

  1. NPFInstall.exe is called with -kill_proc_polite instead of -kill_proc, even in silent mode. -kill_proc_polite is supposed to ask the user, which in unattended mode (e.g. when run in a system session) does nothing and never returns -- the process remains running.
    Contents of NPFInstall.log:
[000013A8] 2020-04-03 02:57:04 --> wmain
[000013A8] 2020-04-03 02:57:04     _tmain: executing, argv[0] = C:\Program Files\Npcap\NPFInstall.exe.
[000013A8] 2020-04-03 02:57:04     _tmain: executing, argv[1] = -n.
[000013A8] 2020-04-03 02:57:04     _tmain: executing, argv[2] = -check_dll.
[000013A8] 2020-04-03 02:57:04 --> getInUseProcesses
[000013A8] 2020-04-03 02:57:04 --> enumProcesses
[000013A8] 2020-04-03 02:57:04     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = System, dwProcessID = 4.
[000013A8] 2020-04-03 02:57:04     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = Registry, dwProcessID = 96.
[000013A8] 2020-04-03 02:57:04     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = smss.exe, dwProcessID = 420.
[000013A8] 2020-04-03 02:57:04     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = csrss.exe, dwProcessID = 512.
[000013A8] 2020-04-03 02:57:04     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = wininit.exe, dwProcessID = 608.
[000013A8] 2020-04-03 02:57:04     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = csrss.exe, dwProcessID = 624.
[000013A8] 2020-04-03 02:57:04     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = services.exe, dwProcessID = 680.
[000013A8] 2020-04-03 02:57:05     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = SgrmBroker.exe, dwProcessID = 2276.
[000013A8] 2020-04-03 02:57:05     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = svchost.exe, dwProcessID = 7984.
[000013A8] 2020-04-03 02:57:05     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = SecurityHealthService.exe, dwProcessID = 4808.
[000013A8] 2020-04-03 02:57:05 --> getFileProductName
[000013A8] 2020-04-03 02:57:05     VerQueryValue: error.
[000013A8] 2020-04-03 02:57:05 <-- getFileProductName
[000013A8] 2020-04-03 02:57:05 --> getFileProductName
[000013A8] 2020-04-03 02:57:05 <-- getFileProductName
[000013A8] 2020-04-03 02:57:05     enumDLLs: succeed, strProcessName = al-tmhost.exe.current, strModulePathName = c:\windows\system32\npcap\packet.dll.
[000013A8] 2020-04-03 02:57:05 <-- enumProcesses
[000013A8] 2020-04-03 02:57:05 <-- getInUseProcesses
[000013A8] 2020-04-03 02:57:05     _tmain: error, nStatus = -1.
[000013A8] 2020-04-03 02:57:05 <-- wmain
[00002614] 2020-04-03 02:57:05 --> wmain
[00002614] 2020-04-03 02:57:05     _tmain: executing, argv[0] = C:\Program Files\Npcap\NPFInstall.exe.
[00002614] 2020-04-03 02:57:05     _tmain: executing, argv[1] = -n.
[00002614] 2020-04-03 02:57:05     _tmain: executing, argv[2] = -kill_proc_polite.
[00002614] 2020-04-03 02:57:05 --> killInUseProcesses_Polite
[00002614] 2020-04-03 02:57:05 --> enumProcesses_PID
[00002614] 2020-04-03 02:57:05     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = System, dwProcessID = 4.
[00002614] 2020-04-03 02:57:05     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = Registry, dwProcessID = 96.
[00002614] 2020-04-03 02:57:05     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = smss.exe, dwProcessID = 420.
[00002614] 2020-04-03 02:57:05     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = csrss.exe, dwProcessID = 512.
[00002614] 2020-04-03 02:57:05     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = wininit.exe, dwProcessID = 608.
[00002614] 2020-04-03 02:57:05     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = csrss.exe, dwProcessID = 624.
[00002614] 2020-04-03 02:57:05     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = services.exe, dwProcessID = 680.
[00002614] 2020-04-03 02:57:06     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = SgrmBroker.exe, dwProcessID = 2276.
[00002614] 2020-04-03 02:57:06     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = svchost.exe, dwProcessID = 7984.
[00002614] 2020-04-03 02:57:06     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = SecurityHealthService.exe, dwProcessID = 4808.
[00002614] 2020-04-03 02:57:06 --> getFileProductName
[00002614] 2020-04-03 02:57:06     VerQueryValue: error.
[00002614] 2020-04-03 02:57:06 <-- getFileProductName
[00002614] 2020-04-03 02:57:06 --> getFileProductName
[00002614] 2020-04-03 02:57:06 <-- getFileProductName
[00002614] 2020-04-03 02:57:06     enumDLLs: succeed, strProcessName = al-tmhost.exe.current, strModulePathName = c:\windows\system32\npcap\packet.dll.
[00002614] 2020-04-03 02:57:06 <-- enumProcesses_PID
[00002614] 2020-04-03 02:57:06 --> killProcess_Soft
[00002440] 2020-04-03 02:57:06 --> wmain
[00002440] 2020-04-03 02:57:06     _tmain: executing, argv[0] = C:\Program Files\Npcap\NPFInstall.exe.
[00002440] 2020-04-03 02:57:06     _tmain: executing, argv[1] = -n.
[00002440] 2020-04-03 02:57:06     _tmain: executing, argv[2] = -check_dll.
[00002440] 2020-04-03 02:57:06 --> getInUseProcesses
[00002440] 2020-04-03 02:57:06 --> enumProcesses
[00002440] 2020-04-03 02:57:06     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = System, dwProcessID = 4.
[00002440] 2020-04-03 02:57:06     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = Registry, dwProcessID = 96.
[00002440] 2020-04-03 02:57:06     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = smss.exe, dwProcessID = 420.
[00002440] 2020-04-03 02:57:06     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = csrss.exe, dwProcessID = 512.
[00002440] 2020-04-03 02:57:06     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = wininit.exe, dwProcessID = 608.
[00002440] 2020-04-03 02:57:06     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = csrss.exe, dwProcessID = 624.
[00002440] 2020-04-03 02:57:06     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = services.exe, dwProcessID = 680.
[00002440] 2020-04-03 02:57:07     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = SgrmBroker.exe, dwProcessID = 2276.
[00002440] 2020-04-03 02:57:07     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = svchost.exe, dwProcessID = 7984.
[00002440] 2020-04-03 02:57:07     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = SecurityHealthService.exe, dwProcessID = 4808.
[00002440] 2020-04-03 02:57:07 --> getFileProductName
[00002440] 2020-04-03 02:57:07     VerQueryValue: error.
[00002440] 2020-04-03 02:57:07 <-- getFileProductName
[00002440] 2020-04-03 02:57:07 --> getFileProductName
[00002440] 2020-04-03 02:57:07 <-- getFileProductName
[00002440] 2020-04-03 02:57:07     enumDLLs: succeed, strProcessName = al-tmhost.exe.current, strModulePathName = c:\windows\system32\npcap\packet.dll.
[00002440] 2020-04-03 02:57:07 <-- enumProcesses
[00002440] 2020-04-03 02:57:07 <-- getInUseProcesses
[00002440] 2020-04-03 02:57:07     _tmain: error, nStatus = -1.
[00002440] 2020-04-03 02:57:07 <-- wmain
[00000F34] 2020-04-03 02:57:07 --> wmain
[00000F34] 2020-04-03 02:57:07     _tmain: executing, argv[0] = C:\Program Files\Npcap\NPFInstall.exe.
[00000F34] 2020-04-03 02:57:07     _tmain: executing, argv[1] = -n.
[00000F34] 2020-04-03 02:57:07     _tmain: executing, argv[2] = -kill_proc_polite.
[00000F34] 2020-04-03 02:57:07 --> killInUseProcesses_Polite
[00000F34] 2020-04-03 02:57:07 --> enumProcesses_PID
[00000F34] 2020-04-03 02:57:07     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = System, dwProcessID = 4.
[00000F34] 2020-04-03 02:57:07     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = Registry, dwProcessID = 96.
[00000F34] 2020-04-03 02:57:07     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = smss.exe, dwProcessID = 420.
[00000F34] 2020-04-03 02:57:07     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = csrss.exe, dwProcessID = 512.
[00000F34] 2020-04-03 02:57:07     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = wininit.exe, dwProcessID = 608.
[00000F34] 2020-04-03 02:57:07     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = csrss.exe, dwProcessID = 624.
[00000F34] 2020-04-03 02:57:07     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = services.exe, dwProcessID = 680.
[00000F34] 2020-04-03 02:57:08     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = SgrmBroker.exe, dwProcessID = 2276.
[00000F34] 2020-04-03 02:57:08     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = svchost.exe, dwProcessID = 7984.
[00000F34] 2020-04-03 02:57:08     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = SecurityHealthService.exe, dwProcessID = 4808.
[00000F34] 2020-04-03 02:57:08 --> getFileProductName
[00000F34] 2020-04-03 02:57:08     VerQueryValue: error.
[00000F34] 2020-04-03 02:57:08 <-- getFileProductName
[00000F34] 2020-04-03 02:57:08 --> getFileProductName
[00000F34] 2020-04-03 02:57:08 <-- getFileProductName
[00000F34] 2020-04-03 02:57:08     enumDLLs: succeed, strProcessName = al-tmhost.exe.current, strModulePathName = c:\windows\system32\npcap\packet.dll.
[00000F34] 2020-04-03 02:57:08 <-- enumProcesses_PID
[00000F34] 2020-04-03 02:57:08 --> killProcess_Soft
[00000418] 2020-04-03 02:57:08 --> wmain
[00000418] 2020-04-03 02:57:08     _tmain: executing, argv[0] = C:\Program Files\Npcap\NPFInstall.exe.
[00000418] 2020-04-03 02:57:08     _tmain: executing, argv[1] = -n.
[00000418] 2020-04-03 02:57:08     _tmain: executing, argv[2] = -check_dll.
[00000418] 2020-04-03 02:57:08 --> getInUseProcesses
[00000418] 2020-04-03 02:57:08 --> enumProcesses
[00000418] 2020-04-03 02:57:08     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = System, dwProcessID = 4.
[00000418] 2020-04-03 02:57:08     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = Registry, dwProcessID = 96.
[00000418] 2020-04-03 02:57:08     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = smss.exe, dwProcessID = 420.
[00000418] 2020-04-03 02:57:08     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = csrss.exe, dwProcessID = 512.
[00000418] 2020-04-03 02:57:08     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = wininit.exe, dwProcessID = 608.
[00000418] 2020-04-03 02:57:08     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = csrss.exe, dwProcessID = 624.
[00000418] 2020-04-03 02:57:08     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = services.exe, dwProcessID = 680.
[00000418] 2020-04-03 02:57:09     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = SgrmBroker.exe, dwProcessID = 2276.
[00000418] 2020-04-03 02:57:09     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = svchost.exe, dwProcessID = 7984.
[00000418] 2020-04-03 02:57:09     enumDLLs::OpenProcess: error, errCode = 0x00000005, strProcessName = SecurityHealthService.exe, dwProcessID = 4808.
[00000418] 2020-04-03 02:57:09 --> getFileProductName
[00000418] 2020-04-03 02:57:09     VerQueryValue: error.
[00000418] 2020-04-03 02:57:09 <-- getFileProductName
[00000418] 2020-04-03 02:57:09 --> getFileProductName
[00000418] 2020-04-03 02:57:09 <-- getFileProductName
[00000418] 2020-04-03 02:57:09     enumDLLs: succeed, strProcessName = al-tmhost.exe.current, strModulePathName = c:\windows\system32\npcap\packet.dll.
[00000418] 2020-04-03 02:57:09 <-- enumProcesses
[00000418] 2020-04-03 02:57:09 <-- getInUseProcesses
[00000418] 2020-04-03 02:57:09     _tmain: error, nStatus = -1.
[00000418] 2020-04-03 02:57:09 <-- wmain

... etc, ad infinitum. (al-tmhost.exe.current is the application using Npcap in this case -- it never got terminated.)

Expected behavior: For silent (un)installs, -kill_proc should be used instead of -kill_proc_polite (again, silent installation should never ever ask anything of the user).

  1. If we manually move the DLLs and allow the uninstaller to proceed, it still fails because it cannot stop the npcap driver while captures are active. The driver goes into STOP_PENDING state and refuses to snap out of it until all pcap handles are closed.

Expected behavior: Npcap driver should always honor the STOP command, irregardless of any open handles. Open handles should then return an error result from their calls and any attempts to open new handles should fail.

  1. Even if NPFInstall.exe -kill_proc is run manually (which does kill the offending process), the process (in our case) is immediately restarted by its supervisor, and just starts using Npcap again (holding the DLLs open). The uninstaller still cannot remove or replace them and fails.

Expected behavior: The uninstaller should move or rename the Npcap DLLs before trying to kill any processes using them. Any newly started processes would then not be able to find the DLLs and the uninstall/upgrade can proceed in peace.

This issue is preventing reliable automated upgrades on Npcap distributed with our product.

@dmiller-nmap
Copy link

Thanks for another very detailed bug report. We'll look into getting these fixed for the next release.

@dmiller-nmap
Copy link

For the first issue, -kill_proc_polite is supposed to use taskkill without the /f (force) parameter, which allows users of GUI programs to save their work before quitting. But the logs show that NPFInstall.exe never leaves the killProcess_Soft() function. Probably it is crashing there, because there isn't another reason why it would suddenly stop logging.

I will investigate that crash, and also impose some limits on how many retries are allowed before considering the installation a failure (probably just 1).

dmiller-nmap pushed a commit to nmap/npcap that referenced this issue Apr 18, 2020
@dmiller-nmap
Copy link

The driver is currently undergoing some major changes, but I will ensure that the driver can be unloaded in a timely manner.

fengjixuchui added a commit to fengjixuchui/npcap that referenced this issue Apr 18, 2020
Catch errors from _itot_s(). See nmap/nmap#2015
@akontsevoy
Copy link
Author

Thanks; I think the most important thing is to rename/move the old DLLs before killing, so they cannot be used until upgraded, and to make the killing actually work in unattended mode. I think that should allow the upgrade to succeed in the overwhelming majority of cases.

@dmiller-nmap
Copy link

We can't really shut down open device handles when the driver service is STOP_PENDING because of how Windows drivers and devices work. The driver is requested to stop, and the I/O manager flags all its devices with DOE_UNLOAD_PENDING. In this state, new handles cannot be opened. Once all existing handles have been closed, it calls the DriverUnload function for the driver. That is our first indication that something is happening.

Using kernel debugging, I found that we can inspect the DEVICE_OBJECT's DeviceObjectExtension->ExtensionFlags, which is where the DOE_UNLOAD_PENDING flag is set, but all the documentation says this is an opaque object and we can't depend on it. I think you're right that the best approach is to control things at the process level: kill existing processes and ensure they can't restart. It wouldn't stop some other process from opening a handle to Npcap's device, which would prevent the driver from stopping, but that seems very unlikely to happen.

@dmiller-nmap
Copy link

Npcap 0.9991, released yesterday, should solve this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants
@akontsevoy @dmiller-nmap and others