header image

Running processes on the Winlogon desktop

Disclaimer: this is a Bad Idea unless you know exactly what you’re doing, why you’re doing it and there are no alternatives. Please use responsibly.

There may be circumstances where you’d like to programmatically interact with the Winlogon desktop (the one that houses the LogonUI process responsible for displaying logon tiles and the rest of, well, logon UI). Test automation, seamless VM integration, whatever. It’s not easy though, and for good reasons:

  • Logon desktop created by Winlogon has ACL that only grants access to the SYSTEM account. We need a service to access it. Changing that ACL to allow other accounts is a very bad idea.
  • When a user chooses “Switch user” from the Start Menu or when the system first boots and displays the logon UI, it’s all done in a separate session. If a new user logs on, the Winlogon session is reused for that user’s interactive logon. If there is no new logon (but a user switch or unlocking a locked session for example), the Winlogon session is destroyed.
Temporary processes in a Winlogon session after quick user switch

Temporary processes in a Winlogon session after locking/unlocking user session

So, our service needs to monitor session changes and act when a Winlogon session is created (and made interactive). The code below demonstrates how you can create a process that runs on the Winlogon desktop and can interact with it.

Service code Show

You can install the service using following command (mind the spaces):

C:\>sc create QTestService binPath= d:\test\QService.exe type= own start= demand
[SC] CreateService SUCCESS

Then start it with:

sc start QTestService

After starting, choose “Switch user” or “Lock” from the Start Menu. You should see a console window on the logon screen.

~ by omeg on January 29, 2014.

GUI, winapi, windows internals

6 Responses to “Running processes on the Winlogon desktop”

  1. Hi i am very interreted by this post so i want to know if it’s possible to have source exemple.

    thx in advance

  2. The Process handle returned by GetCurrentProcess() is a “pseudo handle”, which does not need to be closed by CloseHandle() (but calling the API has “no effect”)

  3. You should use CloseHandle for newToken, pi.hProcess and pi.hThread

Leave a Reply