Wednesday, March 4, 2015

Disabling Ctrl Alt Del in Windows 7 32-bit and Windows 8.1 32-bit

I'm surprised there is such scarce documentation on this topic, and even more surprised that I can't find a working implementation to disable Ctrl+Alt+Del. So I reverse engineered and found it out!

TLDR: Here's the executable. Note: you have to run it as the user nt authority\system. The easiest way is to run the command psexec -i -s -d DisableCtrlAltDelPatchWinlogon.exe in an elevated command prompt.

TDLR programmers: here's the code.

If you like to read about my process:

First, I read up the background information on Special Attention Sequences, which include Ctrl+Alt+Del (CAD). I found that 'When Winlogon encounters a SAS event or when a SAS is delivered to Winlogon by the GINA, Winlogon sets the state accordingly, changes to the Winlogon desktop, and calls one of the SAS processing functions of the GINA.' My first thoughts are, maybe I should reverse engineer the GINA, but then I found out the GINAs only exist for Windows XP and below. 'In Windows Vista, the GINA scheme has been replaced with a system of Credential Providers, which moves some of that functionality into WINLOGON itself...'

So now I know that Winlogon.exe is in charge of CAD, and it switches to the Winlogon desktop whenever it encounters a CAD, if I place a breakpoint at the time that it does a desktop switch, I could potentially see all the preceding functions and stack calls. So I took a look at the imports of Winlogon.exe, and sure enough, I found user32!SwitchDesktop. Its time for WinDbg!

I kernel debugged my Win 7 x86 machine and broke into the context of Winlogon.exe:

kd> !process 0 0
**** NT ACTIVE PROCESS DUMP ****

PROCESS 8520f530  SessionId: 1  Cid: 018c    Peb: 7ffd7000  ParentCid: 0158
    DirBase: 197a4000  ObjectTable: 9506ead0  HandleCount: 123.
    Image: winlogon.exe


kd> .process /i 8520f530  
You need to continue execution (press 'g' ) for the context
to be switched. When the debugger breaks in again, you will be in
the new process context.
kd> g
Break instruction exception - code 80000003 (first chance)
nt!RtlpBreakWithStatusInstruction:
82893d00 cc              int     3

Then I placed a breakpoint on SwitchDesktop:

kd> bp user32!SwitchDesktop
kd> g

Then I triggered CAD:

Breakpoint 0 hit
USER32!SwitchDesktop:
001b:77d1476b 8bff            mov     edi,edi
kd> kv
ChildEBP RetAddr  Args to Child              
0023fcec 01002147 000000b8 0103c144 002b1ff8 USER32!SwitchDesktop (FPO: [Non-Fpo])
0023fd04 01002d04 000000b8 00000001 00000000 winlogon!ResilientSwitchDesktopWithFade+0x2a (FPO: [Non-Fpo])
0023fd60 01014387 00000000 0023fd88 00000000 winlogon!CSession::SwitchDesktop+0x1c0 (FPO: [Non-Fpo])
0023fd78 010266c8 0103c378 00000000 00000000 winlogon!WlAccessibilitySwitchDesktop+0x1b (FPO: [Non-Fpo])
0023fdd8 01028f8a 0006fd98 000003ff 0103c144 winlogon!HandleSecurityOptions+0x48 (FPO: [Non-Fpo])
0023fdec 0100222f 0006fd98 77f32ba4 000a1a90 winlogon!WLGeneric_CAD_Execute+0x5e (FPO: [Non-Fpo])
0023fe04 77ed2661 0023fe64 0006fd88 000a1a90 winlogon!StateMachineWorkerCallback+0x67 (FPO: [Non-Fpo])
0023fe28 77ef0842 0023fe64 000a1af0 77dbb0c4 ntdll!TppWorkpExecuteCallback+0x10f (FPO: [Non-Fpo])
0023ff88 77e33c45 00092250 0023ffd4 77f237f5 ntdll!TppWorkerThread+0x572 (FPO: [Non-Fpo])
0023ff94 77f237f5 00092250 77dbb098 00000000 kernel32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo])
0023ffd4 77f237c8 77ef03e7 00092250 00000000 ntdll!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])
0023ffec 00000000 77ef03e7 00092250 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])

So here's a list of all the functions I should investigate. WLGeneric_CAD_Execute turns out to be the function that I was looking for, so all I had to do is the patch the starting code in that function to get it to return immediately, and CAD has been disabled!