Jose's Blog

Simulate Ctrl-Alt-Del


Simulating Ctrl-Alt-Del in code has always been a nightmare for developers, namely for logins with remote access software or other scenarios.
I never figured out the reason Microsoft hides and undocuments the procedure.
For Windows XP and older releases all the way down to Windows NT 3.51 a solution has been found that spreaded all over the internet. I don’t know who found it, but it works pretty well.

Then enters Windows Vista. The old procedure ceased to work. Microsoft announced that would provide a C library called SASLIB for people requesting it from a certain email address. In most cases, requests deserved no reply from Microsoft, I was one of those cases! I don’t know what was their selection criteria, but I have legal software and I don’t live in a country for which export restrictions are enforced.

Given that state of affairs, a couple of years ago I made some investigation on my own by analyzing the import table of OSK.EXE. This is a utility bundled with Windows, intended to provide some functionality for users with limited mobility, and it can produce Ctrl-Alt-Del through the virtual keyboard.
I found a mysterious function called WmsgSendMessage exported by a not less mysterious WMsgAPI.dll. I experimented a bit with that function, but at the time was unable to unveil a few details and had to give up due to time constraints.
Actually, I was on the right track. WmsgSendMessage works by invoking the client RPC mechanism lodged inside WMsgAPI.dll. Your application only needs to have the TcbPrivilege, i.e the privilege to Act as Part of the Operating System. LocalSystem services already have that privilege, and have it enabled by default.  The local security policy of the computer needs also be configured to allow services to produce Ctrl-Alt-Del (or Security Attention Sequence, SAS, as Microsoft calls it), but this can be done on the spot by changing a simple Registry value before the SAS request.
Very easy, too easy indeed, here is the prototype of the function:
typedef DWORD (WINAPI* lpfnWmsgSendMessage)(DWORD dwSessionId, UINT magicNumber, WPARAM pid, LPARAM lParam);
The magicNumber is 0x208 (there are a few other magic numbers in this function but this one is what we want)
The pid (process id) can be left to zero.
The fourth parameter is just a LONG_PTR to a LONG_PTR initialized to NULL.
Note that the first parameter is the session where you want the Ctrl-Alt-Del to be issued. You can issue a Ctrl-Alt-Del from the console to any Terminal Services session and you can as well issue it from any Terminal Services session to another session including the console! Yes, this is amazing.
With the release of Windows 7 and Windows Server 2008R2, Microsoft shipped a SAS.DLL that can be used to simulate Ctrl-Alt-Del from a LocalSystem service. Windows Vista and Windows Server 2008 do not have it but you can get it through the Windows 7 SDK. With SAS.DLL you can only produce Ctrl-Alt-Del to the session you are in (fair enough in most cases).
There is another way to produce Ctrl-Alt-Del, it is called AsUser, here you don’t need to launch a LocalSystem service to issue the Ctrl-Alt-Del. On the other hand, the application needs to be signed with authenticode, needs to have a manifest with the uiAccess attribute of the requestedExecutionLevel element set to true, UAC must be turned on, needs to be lodged in a secure folder (like Program Files or System32) and the local security policy must be configured to allow applications to simulate a SAS. Five conditions, but not too much of an inconvenience, nowadays most serious developers already sign their software, it is easy as well to set to true the uiAccess of the manifest and most users already install applications in the Program Files folder and keep UAC turned on (at least with Windows 7 and above). The local security policy can be set directly in the Registry if the application is elevated, otherwise launch Gpedit.msc and under Computer Configuration | Administrative Templates | Windows Components | Windows Logon Options | Disable or enable software Secure Attention Sequence set it to Ease of Access Applications or to Services and Ease of Access Applications.

Understanding what WmsgSendMessage does is relatively easy, when we take for granted that WMsgAPI.dll is a black box that just performs what we want. However, producing Ctrl-Alt-Del as AsUser does not make use of the WmsgSendMessage function at all. Then it becomes more difficult, and not a lot of developers are comfortable with RPC, this alone explains why no one ever found the way until now.

In this case, there is no System Dll ready to perform the work for us, as there is when we call WmsgSendMessage from a LocalSystem account.
We do need a RPC client able to send the correct message to rpcrt4.dll (this is sort of middleman that interprets and dispatches RPC requests to the correct handler). The message itself is very simple, it does not even contains Identity Authentication. Even simple, finding it was not easy at all because there is no oicf MIDL decompilers and all the inner RPC workings are largely undocumented or confusing. The best explanation ever written about how it all works is now 11 years old, it appeared in the Microsoft System Journal of January 1999 but is still available in the internet.

While lots of people reverse engineer the Windows internals, and some write books and end getting nice jobs at Microsoft, I have not actually done any reverse engineering. I have just observed, experimented and produced my own solution!

Now, it is important to state this question: Can you guarantee that your solution will work on any future Service Pack or new Windows Release?
The answer is: No, but WmsgSendMessage and other APIs, even if not documented are being commonly used by OSK.EXE, SAS.DLL and other software distributed by Microsoft to produce Ctrl-Alt-Del. I believe the core functionality will remain for a long time. However, Microsoft may remove the capability to produce Ctrl-Alt-Del to different Terminal Server sessions.
I am making available a complete package, completely free, with easy integration sample source code  (actually, there is only one function call that needs to be integrated) in C++ and Delphi. The package includes DLLs for 32-bit and 64-bit applications, which allow you to use the functionality in any application you develop; it includes also signed demo standalone applications and signed demo applications making use of the DLLs, compiled both as 32-bit and 64-bit. I just do not include the source code of the Ctrl-Alt-Del library itself, but you can purchase it (it is really worthwhile).

Update March 2016: We are making also available for purchase, a class for integration with C#, when using as Service. So no DLL will be needed.

Download fileDownload the FREE AW_SAS (AW_SASLIB.ZIP)

All articles are written by Jose Pascoa and if you quote them you must not misrepresent were you took the information from!

Advertisements

46 Comments »

  1. Wow, Wow, that has been a headache. Interesting read, it gave me some other ideas as well.

    Comment by RayCon — May 5, 2010 @ 8:46 am

  2. I have some questions, but will send you in a private message

    Comment by Jeff Long — May 5, 2010 @ 6:20 pm

  3. Is it possible to use from C#? Do I need to run as Service?

    Comment by Bennis Ditto — May 11, 2010 @ 8:37 pm

    • You can run it with any .Net language, including C#. You don’t have to run it as a service, you can run it as asUser. Same considerations apply both to unmanaged and mansged.

      Comment by jp2712 — May 14, 2010 @ 2:37 pm

  4. Hi, when I run the demo as a user I get:
    Error #29 (Refer to error codes table)
    which the error doc defines as:
    CTRLALTDEL_SASSECUREREQERROR 29

    Comment by tony — August 16, 2010 @ 7:46 pm

    • Hi Toni,
      Place the demo in a folder under Program Files and it should work.
      Regards
      Jose

      Comment by jp2712 — August 16, 2010 @ 8:59 pm

  5. Hi Jose,
    Ran into a major issue with the DLL, you have apparently compiled it with VS 2008 and it’s setup with a side by side manifest configuration and it’s super difficult to use on older Version of XP. Anyway you could compile it with a older version of VS or change the config so it does not require a manifest.
    I know it does not work on XP anyway and my app only calls the function if it’s running on vista and above, but because of the whole manifest mess it won’t load up the app on XP where the side by side DLL manifest hell is not already configured.

    Getting errors like this:
    generate activation context failed for C:\program files\Remote Gateway Service\aw_sas32.dll
    dependent assembly microsoft. vc90.crt could not be found

    I have msvcr90.dll in the same directory as the exe, but it’s complaining about this manfifest and side by side configuration.

    Comment by tony — September 17, 2010 @ 5:02 pm

    • With your application you can also distribute and install the Microsoft Visual C++ 2008 Redistributable Package.
      http://www.microsoft.com/downloads/en/details.aspx?familyid=9B2DA534-3E03-4391-8A4D-074B9F2BC1BF&displaylang=en
      However, 99.9% of XP computers have already all required components, due to software they had installed along their life.

      I can not remove it from the manifest, unless I link statically. You can remove with a resource handling software like …. (there are many) and will see what happens.
      I know old versions of Visual Studio don’t need a manifest because they link with Msvcrt.dll. New version can’t without doing some not recommended tricks, but that is a long story.

      Comment by jp2712 — September 17, 2010 @ 6:03 pm

  6. Hello,

    thank you for creating the AW_SAS library.

    I’m really inetrested in purchasing it, but I still have an problem I cannot solve.

    It seems the Ctrl Alt Del command doesn’t work on Windows Server 2008.

    I’ve tried it on 2008 32-bit and 2008 R2 64-bit. Same result.
    I’ve also activated the SAS policy, as recommended in some forums.
    I’ve tried with RealVNC and it works fine.

    What I’ve forgotten ?
    Can you please confirm me the library works on Server 2008 ?
    Otherwise, can you give me a new version that works on Server 2008 ?

    Thanks in advance

    Best Regards

    Comment by Alberto — October 6, 2010 @ 1:43 pm

    • Hi Alberto,

      It works fine with Windows Server 2008 and 2008 R2 in 32-bit and 64-bit.
      I am going to email you.

      Jose

      Comment by jp2712 — October 6, 2010 @ 2:13 pm

  7. Hello Sir
    Great work. This is all I wanted to say. It was useful for my project

    L S – India

    Comment by HelloMr — November 19, 2010 @ 7:28 am

  8. DemoStandAlone(32/64) not working on Server 2008 R2 Essential(system privileges), static dll load failing with (0xc0150002).
    On Vista 32, Windows 7(32/64), Server 2008 R2 Standard everything works fine.

    Tested with non signeed app (system privileges) with static and dynamic dll loading.

    Great stuff

    Comment by Ivica Jercic — December 30, 2010 @ 12:03 am

    • From ntstatus.h:
      // MessageId: STATUS_SXS_CANT_GEN_ACTCTX
      // Windows was not able to process the application binding information.
      // Please refer to your System Event Log for further information.
      #define STATUS_SXS_CANT_GEN_ACTCTX ((NTSTATUS)0xC0150002L)
      ———————————

      I think it is related to the included manifest which contains ‘microsoft.windows.common-controls’ version=’6.0.0.0′ and your system is not providing automatic redirection for a newer version.

      Comment by jp2712 — December 30, 2010 @ 10:44 am

  9. Wow..great work. Can you send a control-alt-delete if there is no active session? With all sessions disconnected at the Control-Alt-Delete screen I want to sent a CAD from a service event…is this possible?

    thanks in advance,

    Chris

    Comment by ChrisG — June 30, 2011 @ 9:10 pm

  10. how to use the dll file in a C# project ?

    Comment by wan — July 11, 2011 @ 8:50 pm

    • In the same way you use any non managed dll

      Comment by jp2712 — July 12, 2011 @ 3:15 am

  11. […] SASLIB, Security Attention Sequence — jp2712 @ 9:26 pm As promised, I am posting today an amazing jewel. Follow the link or click the page called simulate ctrl-alt-del on the side bar. If you are the […]

    Pingback by Simulate Ctrl-Alt-Del « Jose's Blog — February 20, 2012 @ 2:43 pm

  12. Can you please email me (or post it here) the signature for this dll if used in a vb.net app? I’ve been trying to use:

    Declare Auto Function sendCtrlAltDel Lib “aw_sas32.dll” (ByVal asUser As Boolean, ByVal iSession As Integer) As Integer

    and

    _
    Public Shared Function sendCtrlAltDel(ByVal asUser As Boolean, ByVal iSession As Int32) As Integer
    End Function

    to no avail.

    Thanks,
    – Pete

    Comment by Pete — May 23, 2012 @ 10:54 pm

    • I don’t use such fancy languages, but what you tried looks good, so the error is probably elsewhere. Read carefully the article.

      Comment by jp2712 — May 24, 2012 @ 5:53 am

  13. Don’t work on Windows 7
    Error 7 for Local system
    Error 29 for User

    Comment by Anton Karpenko — June 9, 2013 @ 12:43 pm

    • Of course, it does work. Read again the article.

      Comment by jp2712 — June 9, 2013 @ 1:16 pm

  14. Download link does not seem to work

    Comment by Zoheb — November 25, 2013 @ 12:07 pm

  15. Dear Jose,
    I have turned on UAC, configured local security policy,run gpupdate /force and lodged “DemoApp32.exe” file in Program Files folder.
    But when in run program and select “As User”, it still appear error 29.
    Can you help me?
    What requirement did i miss?
    Thank you!

    Comment by Minh — February 20, 2014 @ 8:11 am

    • There are five conditions to be met and you mentioned only three.
      All of them are required, have a look at it

      Jose

      Comment by jp2712 — February 20, 2014 @ 2:12 pm

  16. this is great! I’ve been looking for something like this to help support my users who refuse to give passwords and expect support guys to fix their problems whilst they go on lunch locking their machines!

    I’ve been trying to add the dll as a reference in C# (VS 2010) but keep getting an error that it’s not a valid COM file. I doubt that is the case based on what you said, what am I doing wrong? I’ve used dll’s in various projects before without any issues and have ensured I’ve installed 2008 C++ runtime. Any help would be appreciated.

    Comment by Abz — August 8, 2014 @ 8:14 pm

    • It is not COM, it is an UNMANAGED Dll.

      Comment by jp2712 — August 8, 2014 @ 8:26 pm

      • thanks for the quick response! I’ve done managed to add it. For others who have similar issues here’s what I did.

        added the dll to the bin\debug folder
        referenced dll using dllimport like so

        public partial class Form1 : Form
        {
        [DllImport(“aw_sas32.dll”, CharSet = CharSet.Unicode)]
        public static extern int sendCtrlAltDel(bool asUser, int iSession);

        public Form1()
        {
        InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
        int x = sendCtrlAltDel(true, 0);

        MessageBox.Show(Convert.ToString(x));
        }
        }

        Comment by Abz — August 8, 2014 @ 8:39 pm

      • Unless you run under the system account, for security reasons Windows requires you to place the executable in a protected folder, sign it, etc.
        This is explained in the text.

        Comment by jp2712 — August 9, 2014 @ 9:23 am

  17. The sample app works great from Program Files in Win7 but if I build the sample app from source (without any changes other than importing to VS 2013) I get error 29. Also, if I call the dll from a python script, I get error 29. The sample app, py.exe, the dll, and the script are all in the Program Files directory. Am I missing something?

    Comment by Jeff — July 17, 2015 @ 1:41 am

    • It is true, as mentioned above “needs to be lodged in a secure folder (like Program Files or System32)”.
      Only if run As System, not necessary.

      Comment by jp2712 — July 17, 2015 @ 3:59 am

      • Thank you, but maybe it wasn’t clear enough. Everything I’ve tried has been in the Program Files directory – I do understand that requirement. Something else is factoring into my issue. What else could be wrong?

        Comment by Jeff — July 17, 2015 @ 4:12 am

    • You are right, I misread it.
      Make sure these conditions are met:
      “the application needs to be signed with authenticode, needs to have a manifest with the uiAccess attribute of the requestedExecutionLevel element set to true,”

      Comment by jp2712 — July 17, 2015 @ 4:27 am

      • Ah, got it. So those steps aren’t done by Visual Studio when building – it’s a manual post-processing step? I’ve never done that before so I’ll have to read up on how that’s done. Maybe it’s worth adding a note about that to the sample code folder in the download zip. Thank you!

        Comment by Jeff — July 17, 2015 @ 5:01 am

      • I did not know you were using VS.
        The DLL works with any programming language I can remember.

        Comment by jp2712 — October 27, 2017 @ 7:29 am

  18. Hello, this is my error, help me please, i’m execute in administrator mode and the files i paste in the program files path.

    “Se ha intentado cargar un programa con un formato incorrecto. (Excepción de HRESULT: 0x8007000B)”

    Comment by pperez04072013@gmal.com — September 12, 2017 @ 8:24 pm

    • May be you are in a AnyCPU .Net application loading a x86 DLL in x64 OS.:

      Comment by jp2712 — September 13, 2017 @ 6:01 am

  19. hello, how can implement this, because i use this code, but not started the function “ctrl + alt + delete”

    namespace Simulador
    {
    public partial class Form1 : Form
    {
    [DllImport(“aw_sas32.dll”, CharSet = CharSet.Unicode)]
    public static extern int sendCtrlAltDel(bool asUser, uint iSession);

    public Form1()
    {
    InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
    try
    {
    int x = sendCtrlAltDel(true, 0);
    MessageBox.Show(Convert.ToString(x));
    }
    catch (Exception ex)
    {
    MessageBox.Show(ex.ToString());
    }
    }
    }
    }

    thanks for your help

    Comment by Miguel Diaz — September 13, 2017 @ 12:35 pm

    • Instead of int x = sendCtrlAltDel(true, 0); use int x = sendCtrlAltDel(true);

      Comment by jp2712 — September 14, 2017 @ 5:38 am

      • hello, so sorry i’m, used this (int x = sendCtrlAltDel(true);) and the function return a int value, but i want that execute the action like if i used (ctrl + alt + del) with the keyboard, because i paste the build in the program files folder and this no execute the (ctrl + alt + del). thank you for your help.

        Comment by Miguel Diaz — September 14, 2017 @ 11:48 am

      • It appears you have not read the article yet:
        quote
        On the other hand, the application needs to be signed with authenticode, needs to have a manifest with the uiAccess attribute of the requestedExecutionLevel element set to true, UAC must be turned on, needs to be lodged in a secure folder (like Program Files or System32) and the local security policy must be configured to allow applications to simulate a SAS. Five conditions

        Comment by jp2712 — September 15, 2017 @ 4:25 am

  20. Can i also disable CTRL+ALT+DEL keys with this DLL?

    Comment by Edi Gunawan — October 18, 2017 @ 10:01 am

  21. Using SASLIB from a Local System Service works great. Only “problem”: how to know that the boot sequence is in a state where the Ctrl+Alt+Del will be correctly processed?

    Comment by manuell — October 26, 2017 @ 4:39 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply to pperez04072013@gmal.com Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: