Closed leumasme closed 1 year ago
This may seem like the correct behavior at first, but it presents an issue when using it with package managers like Scoop.
It is the correct behavior. Windows is resolving (and removing) directory symlinks during process creation.
A symlink apps/systeminformer-nightly/current is then created that's always linked to the latest version folder. When updating via scoop, a new version folder is created, the settings ("persisted files") are synced over and the current folder is relinked.
This design is busted. The kernel removes folder symlinks from the process image path. The only exception is when files are symlinked instead of the folder.
You'd expect apps launched from the current folder to act as if they were installed there (this is the purpose of Symlinks - otherwise you'd just create a shortcut)
This is only possible on Windows when you create symlinks for the executable not the folder.
Instead, SystemInformer seems to resolve the Folder Symlink
We're using QueryFullProcessImageName: https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-queryfullprocessimagenamew
The filename is normalized during process creation and cached in EPROCESS. QueryFullProcessImageName verbatim copies the filename from the cache by calling NtQueryInformationProcess with ProcessImageFileName -> PsQueryFullProcessImageName -> EPROCESS -> SeAuditProcessCreationInfo -> ImageFileName.
You can view the ImageFileName by right-clicking any process and selecting Properties -> General: https://user-images.githubusercontent.com/1306177/218852621-c004181a-0cea-486f-bdc2-f6387e54c6ca.png
We're also using GetMappedFileName: https://learn.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-getmappedfilenamew
GetMappedFileName verbatim copies the filename from the file handle/section object. NtQueryVirtualMemory with MemoryMappedFilenameInformation -> MmQueryVirtualMemory -> SECTION -> MiSectionControlArea -> FILE_OBJECT -> ObQueryNameString
You can view the MappedFileName by right-clicking any process and selecting Properties -> Modules: https://user-images.githubusercontent.com/1306177/218878418-aa5ae3ef-d844-4860-875e-3327c7ac0381.png
windows does so itself too, ex. when right-clicking apps/systeminformer-nightly/current/SystemInformer.exe -> Pin to (Taskbar | Start Menu)
Windows Explorer shows the path but the Windows kernel doesn't and the kernel removes folder symlinks on the current path. The only exception is when the file is a symlink instead of the folder.
If you view the handles tab for Explorer.exe when browsing the \current\ symlink folder... It's faking the \current\ path in the address bar and removes the symlinks from the path: https://user-images.githubusercontent.com/1306177/218883516-1e1aa3f3-7c1a-4e07-8f0c-a6d6c48c9b6c.png
the current path is used as the target. The "Replace Task Manager" action in System Informer should thus also use the current path if that's how it was started.
The scoop current
path from the shortcut is passed via the command line (highlighted red) but we can't use it:
https://user-images.githubusercontent.com/1306177/218852621-c004181a-0cea-486f-bdc2-f6387e54c6ca.png
The replace Task Manager option uses the filename as the debugger for taskmgr.exe located in HKEY_LOCAL_MACHINE
and using strings from the command line as the filename would create a security vulnerability.
The problem is Scoop using symlinks incorrectly. All they need to do is just rename the current
folder to/from the latest version without using any symlinks:
1) Download into update
folder.
2) Rename current
to x.x.x.x_version
3) Rename update
to current
Same semantics and more reliable than symlinks.
Thank you for the elaborate response and for correcting me. I've mentioned it in a scoop issue that i believe is relevant here. (Should this be closed?)
Brief description of your issue
When starting SystemInformer from a Symlink and then using Replace Default Task Manager, the registry key will be set to the location of the actual file instead of the symlink.
Steps to reproduce (optional)
Expected behavior (optional)
This may seem like the correct behavior at first, but it presents an issue when using it with package managers like Scoop. Scoop installs applications by putting them in a folder for their currently installed version (ex
apps/systeminformer-nightly/3.0.5974
). A symlinkapps/systeminformer-nightly/current
is then created that's always linked to the latest version folder. When updating via scoop, a new version folder is created, the settings ("persisted files") are synced over and thecurrent
folder is relinked. You'd expect apps launched from thecurrent
folder to act as if they were installed there (this is the purpose of Symlinks - otherwise you'd just create a shortcut) - windows does so itself too, ex. when right-clickingapps/systeminformer-nightly/current/SystemInformer.exe
->Pin to (Taskbar | Start Menu)
, thecurrent
path is used as the target. The "Replace Task Manager" action in System Informer should thus also use thecurrent
path if that's how it was started.Actual behavior (optional)
Instead, SystemInformer seems to resolve the Folder Symlink and use the exact version path as the
taskmgr.exe/Debugger
registry key, causing it to break if it's updated via scoop.Environment (optional)
No response