In part 1 I’ve described the theoretical parts needed for a custom autologon application implementation.

But there are some practical problems which I will describe here.

1) I use the LsaLogonUser function to log in the user. However, if I do not pass not null for the LocalGroups parameter, msgina.dll fails to process the logon.

Why? Because it looks for the SE_GROUP_LOGON_ID SID and treat it as logon SID. So we have to add the logon SID manually:

2) In case we want to create a token using NtCreateToken, we need to add the Everyone Group (otherwise Winlogon will fail to load the user profile):

3) On the X64 versions of Windows XP and all version of Windows 2003 a service process doesn’t have the SeCreateTokenName privilege. But we can open lsass.exe process and copy it’s token:

4) In case we create the token manually, we have to specify the logon session. As there is no way to create a session without injecting into lsass.exe, I use a SYSTEM luid as a logon session luid. It has the side-effect of showing the user as SYSTEM regardless of the actual used SID.

5) Sometimes opening the pipe fails (it may have been connected to some other session’s winlogon). I try to open the pipe with short timeout and post a disconnect pipe message:

6) In Windows 2003 (or on XP x64) you should read the BOOL variable from the pipe after you’ve written to it. But it may not work as Winlogon simply writes the value and then disconnects the pipe, so sometimes the data can not be read (subject to threading issue). I simply ignore the read error, since even if it shows that the credentials were accepted by Winlogon, they may have been rejected by gina

7) In some extremely rare cases our process may exit before Winlogon has read the credentials and duplicated them (actuallyI was able to repeat this only under debugging winlogon).

To be sure that our credentials have been correctly processed, I create a different thread and wait for console logon event:

8‌) If Fast User Switching is enabled and we are on a Workstation OS, Winlogon ignores the WLX_SAS_TYPE_AUTHENTICATED message. However, before execution we can disable the AllowMultipleTSSessions key, and enable it again after the execution. Of course, we do have to remember that under WOW we need to use the special registry flag to access real HKLM hive.

9) In case session 0 has a logged-on user, Winlogon also ignores the WLX_SAS_TYPE_AUTHENTICATED message. I use WTSQueryUserToken to get the token of the logged on user. If the function succeeds, then a user is logged on. There are some problems calling this function on 64 bit systems, and they are described in Querying a user token under 64 bit version of 2003/XP

10) If the screensaver is running, we’ll have to wait until someone breaks the screensaver. So we need to stop screensaver programmatically. MSDN recommends posting the WM_CLOSE message to the foreground window, so let’s do it:

11) Although you can send an empty username, some GINA’s, at least msgina.dll require it to be not-null. So we can use an empty string (#0) instead. You may need to overwrite this procedure to increase compatibility with your GINA:

12) There is incompatibility with some custom GINA’s, for example, with FMLogin, which subclasses “Sas Window”. I’ve tested the sample with original msgina.dll, so the further compatibility should be tested with the exact gina.

13) Getting a session process list on x64 may fail if you do not allocate buffers correctly – described here

So we’re ready to go on to the implementation which will be described in the part 3.