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

Set program as a service #7

Open
lucamaia9 opened this issue May 26, 2020 · 4 comments
Open

Set program as a service #7

lucamaia9 opened this issue May 26, 2020 · 4 comments
Labels
help wanted Extra attention is needed

Comments

@lucamaia9
Copy link

I have tried to set the .exe file as a service on windows, so it can start working even before I logon and can auto restart, using nssm (https://nssm.cc/) but it does not work if launched through it.
Do you have in mind making it work as a process?

@mcmonkey4eva mcmonkey4eva added the help wanted Extra attention is needed label May 27, 2020
@kairisku
Copy link

Windows services run in a separate session that have no access to the interactive desktop or its keyboard, so what you are trying to do is simply not possible.

@ForbiddenEra
Copy link

Windows services run in a separate session that have no access to the interactive desktop or its keyboard, so what you are trying to do is simply not possible.

While this sounded correct to me at first, I thought a little longer and checked something - turns out it's not and this is incorrect information. Perhaps there's some classifiers that can affect things, even though I've used every Windows OS since Win3.1, mostly as primary, it's still a mess of an enigma to me (whereas anything Unix-like I understand very well, though to be fair MS hasn't always and still doesn't always have the clearest, most transparent or comprehensive documentation on internal functionality - opensource for the win here)

Anyway, I use barrier, an opensource keyboard/mouse sharing software (it's a synergy fork, input-leap is also a fork, multiplicity was another similar one, etc) and was pretty sure this behavior was a thing for it...

It runs two processes, barriers.exe and barrierd.exe .. at first I figured that while the server may be a service, the other process probably runs as an interactive user to capture keys - but since I was already digging around on my system w/SI procexp64 (nothing personal to the author - but this software is basically part keylogger by design, best would be to self-compile it but that's a fair bit of work, definitely more than doing a quick signature/behavior/VT check) and I had just read this post, I thought I'd peek*.

Both processes run as NT AUTHORITY\SYSTEM with barrierd.exe having an autostart location of HKLM\System\CurrentControlSet\Services\Barrier and shows in the Services MMC snap.

I thought perhaps that the other (barriers.exe) did run 'interactively' and was responsible for showing the UI and icon in the system tray, however I just checked and while it's functioning fine and loaded at startup, it wasn't showing in the tray, so I opened the shortcut for the UI and a third executable, barrier.exe, loaded as my local user providing the UI bits.

To make my verification even more solid, since I didn't remember if this worked exactly (I knew I could login to my Mac from my PC but not if I could control other PCs at the login screen) so I locked my PC and was still able to control my secondary system via Barrier.

This tells me that somehow it is possible, the core function of Barrier is quite similar, it listens to keyboard/mouse input and also blocks the input from the main machine when you've moved the mouse to a secondary system while injecting those inputs to that system instead.

Also, since Barrier is open source (https://github.com/debauchee/barrier) it should be able to reasonably grok how this was accomplished from it's source or it's upstream or other downstream forks, if not otherwise able to be found documented somewhere.

*PS/Side note; I expected some heuristic/ML results on VT since it monitors keyboard input, which was indeed the case (https://www.virustotal.com/gui/file/7b1c0a4ba92d67271d8978ca76dd07c698985b468d84c037f4f79650ccb19cdd/detection) but mostly looked fine (other than some of the IPs under relations, though I'm not convinced that's completely a red flag and so far it has not touched the network nor any concerning disk access which is a good sign) but I also noticed that the processes for barrier didn't show any heuristic results, perhaps it's method of access is less 'evil' to ML/heuristics (perhaps even just that it's running as a service?), might be worth looking into for better user trust and/or even getting it signed/putting it in the app store as signed or something, though I'd think most savvy enough to check VT would understand ML/heuristic results are often FAPs and come with a grain of salt.

PS2: Thankful that I can procrastinate tearing down/cleaning/possibly replacing key switches my keyboard a little longer; filterkeys didn't quite do it and killed intentional repeat completely. Procrastination FTW!

@mcmonkey4eva
Copy link
Member

Barrier looks like it dynamically converts how it behaves depending on launch, so it can launch as service or client or etc. and just reroutes what codepath runs accordingly, as seen eg at https://github.com/debauchee/barrier/blob/master/src/lib/barrier/win32/AppUtilWindows.cpp#L148-L153 - technically any program can run anywhere, it's just a matter of calling the appropriately relevant code functions for the context you're running in.
They have dedicated code for everything, even eg entire specialty classes for handling the case of a windows PC with a screensaver up https://github.com/debauchee/barrier/blob/master/src/lib/platform/MSWindowsScreenSaver.cpp

This is deeply complex C++ code. I tried tracking down how keystrokes are sent and it routes through 20 functions to eventually hit
https://github.com/debauchee/barrier/blob/653e4badeb88f61de901581667d4465d7b1e2d52/src/lib/platform/XWindowsImpl.cpp#L188-L192

int XWindowsImpl::XTestFakeKeyEvent(Display* display, unsigned int keycode,
                                    int is_press, unsigned long delay)
{
    return ::XTestFakeKeyEvent(display, keycode, is_press, delay);
}

what appears to be a function that mindlessly calls itself? wut?
I'm lost just trying to find where its low level calls to windows API / driver logic wind up.


Hypothetically a lot of things become unlocked when operating as a service, at a cost of significant complexity, both in how the code needs to work, and in ... well, dealing with Microsoft registration/licensing/etc.
In theory the ultimate level of control over everything is unlocked by registering as a fake input driver (a "virtual keyboard") that starts by intercepting the real keyboard. That allows for working in any/every context, at the cost of significantly higher code complexity and significant worse potential issues if any bugs surface.


The original suggestion in this thread of using nssm to just shove this exe as a service would most likely not actually enable it to work on login screens even if doesn't break outright from the start, as it would need to actually use service/driver code to get there, not just be launched as a service but still using standard userland win32 calls on the inside.

@ForbiddenEra
Copy link

No idea really, Windows isn't my strong suit compared to anything nx, I just realized that was a similar case; at least you looked into it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

4 participants