Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I want to disable CTRL+ALT+DEL in Windows XP in my ANSI-C code?

Tags:

c

windows

I want to disable CTRL+ALT+DEL in Windows XP in my ANSI-C code. Is it possible to do it?

like image 924
Badr Avatar asked Mar 12 '10 11:03

Badr


6 Answers

First of all, Trapping Ctrl-Alt-Del (Secure Attention Sequence) and disabling it are two different things. Despite misconceptions of many it is possible to disable SAS.

Here are 3 ways to do it:

  1. Set HKCU/Software/Microsoft/Windows/CurrentVersion/Policies/System/DisableTaskMgr = 1

  2. Replace msgina.dll with your own or write a keyboard driver.

  3. Go to the Start menu, select Run, and type "gpedit.msc" to run the Group Policy editor. Look in User Configuration | Administrative Templates | System and you'll find a section called Ctrl+Alt+Del Options - "Remove Task Manager"

In order to trap SAS, you could write a GINA stub, create a keyboard driver or replace TaskMgr.exe

These requirements arise mainly for embedded systems and you have control over how the WinXP image is made.

Reference: MSDN Mag Sept 2002

like image 72
Indy9000 Avatar answered Nov 15 '22 15:11

Indy9000


Yes it is.

CTRL+ALT+DEL, known as the Secure Attention Sequence (SAS), can't be intercepted through the common Global Windows Hook mechanism though.

The option you have to intercept SAS that I know of, not mattering the situation, is just one: a driver.

But it doesn't need to be a full blown device driver, it can be a simpler one known as a filter driver. You'll need to learn how to do kernel development which is not so trivial and will require you to do, for example, kernel debugging with two machines. If you expect to use your driver at other machines with newer Windows, you'll need to sign your driver since Windows Vista x64 and newer will not load non-signed drivers, only the x86 version of these operating systems are allowed to do it. And you'll get the risk of getting some funny BSOD in the way.

The official microsoft sample for a keyboard filter driver is the kbfiltr sample.

Now, there's a much simpler way to circumvent all of this: use some library that communicates with a driver to do all this dirty work. And this is what I have tried to do.

I've developed a library, which I call Interception, that allows one to, well..., intercept device input from a common user mode program while using the powers of a device driver. It's a small and simple C api that internally communicates with drivers which I've properly signed.

You must use an installer to install the drivers at your system before using the API.

At my web site there's already a sample for SAS interception and you can also check it out here, at github. I'll leave it here for reference:

#include <iostream>

#include <utils.h>
#include <interception.h>

using namespace std;

namespace scancode {
    enum {
        esc  = 0x01,
        ctrl = 0x1D,
        alt  = 0x38,
        del  = 0x53,
    };
}

InterceptionKeyStroke ctrl_down = {scancode::ctrl, INTERCEPTION_KEY_DOWN                      , 0};
InterceptionKeyStroke alt_down  = {scancode::alt , INTERCEPTION_KEY_DOWN                      , 0};
InterceptionKeyStroke del_down  = {scancode::del , INTERCEPTION_KEY_DOWN | INTERCEPTION_KEY_E0, 0};
InterceptionKeyStroke ctrl_up   = {scancode::ctrl, INTERCEPTION_KEY_UP                        , 0};
InterceptionKeyStroke alt_up    = {scancode::alt , INTERCEPTION_KEY_UP                        , 0};
InterceptionKeyStroke del_up    = {scancode::del , INTERCEPTION_KEY_UP | INTERCEPTION_KEY_E0  , 0};

bool operator==(const InterceptionKeyStroke &first,
                const InterceptionKeyStroke &second) {
    return first.code == second.code && first.state == second.state;
}

bool shall_produce_keystroke(const InterceptionKeyStroke &kstroke) {
    static int ctrl_is_down = 0, alt_is_down = 0, del_is_down = 0;

    if (ctrl_is_down + alt_is_down + del_is_down < 2) {
        if (kstroke == ctrl_down) { ctrl_is_down = 1; }
        if (kstroke == ctrl_up  ) { ctrl_is_down = 0; }
        if (kstroke == alt_down ) { alt_is_down = 1;  }
        if (kstroke == alt_up   ) { alt_is_down = 0;  }
        if (kstroke == del_down ) { del_is_down = 1;  }
        if (kstroke == del_up   ) { del_is_down = 0;  }
        return true;
    }

    if (ctrl_is_down == 0 && (kstroke == ctrl_down || kstroke == ctrl_up)) {
        return false;
    }

    if (alt_is_down == 0 && (kstroke == alt_down || kstroke == alt_up)) {
        return false;
    }

    if (del_is_down == 0 && (kstroke == del_down || kstroke == del_up)) {
        return false;
    }

    if (kstroke == ctrl_up) {
        ctrl_is_down = 0;
    } else if (kstroke == alt_up) {
        alt_is_down = 0;
    } else if (kstroke == del_up) {
        del_is_down = 0;
    }

    return true;
}

int main() {
    InterceptionContext context;
    InterceptionDevice device;
    InterceptionKeyStroke kstroke;

    raise_process_priority();

    context = interception_create_context();

    interception_set_filter(context, interception_is_keyboard,
                            INTERCEPTION_FILTER_KEY_ALL);

    while (interception_receive(context, device = interception_wait(context),
                                (InterceptionStroke *)&kstroke, 1) > 0) {
        if (!shall_produce_keystroke(kstroke)) {
            cout << "ctrl-alt-del pressed" << endl;
            continue;
        }

        interception_send(context, device, (InterceptionStroke *)&kstroke, 1);

        if (kstroke.code == scancode::esc)
            break;
    }

    interception_destroy_context(context);

    return 0;
}
like image 21
pepper_chico Avatar answered Nov 15 '22 14:11

pepper_chico


Putting hooks into the keyboard system is not going to do the trick, despite what some here are saying.

The keyboard system works by issuing a particular hardware interrupt. The OS traps this interrupt and responds to it appropriately. This would be the thing affected by keyboard hooks.

The sequence CTRL-ALT-DEL issues a separate hardware interrupt from the other keys. This was done originally so that the reboot command would be available even when the other keyboard commands were frozen. (Although a terminate-stay-resident application in MS-DOS could still trap and handle the interrupt.)

The reason the key sequence is used now for log-in is because of this behavior. Since it issues a separate hardware interrupt, the sequence is used to verify that some other application hasn't put its hooks in. This is to prevent spoofing the login prompt.

I am not saying that it is impossible to trap this interrupt and modify its behavior. I don't know that it's not. But it will not be as simple as putting hooks into the keyboard handling code.

like image 26
Jeffrey L Whitledge Avatar answered Nov 15 '22 15:11

Jeffrey L Whitledge


Winlogon just calls SetWindowsHookEx on the default desktop to trap CAD. Since only a thread that called SetWindowsHookEx can unregister the hook, it is made sure that no other process can steal it. In addition the keyboard hook only works on the process desktop. You can try to switch to a new desktop and hit CAD. Some internal info you'll find here.

like image 30
ChristianWimmer Avatar answered Nov 15 '22 16:11

ChristianWimmer


Why do all the answers say it isn't possible? It is very much possible, for example here's how to enable it in case a virus has disabled it:

Click Start
Click Run
Enter gpedit.msc in the Open box and click OK
In the Group Policy settings window

Select User Configuration
Select Administrative Templates
Select System
Select Ctrl+Alt+Delete options
Select Enable Task Manager

How to make this disable it and how to do it from code I'll let you figure out (hint: you'll probably want to edit some registry keys) as this question is pretty fishy.

You can also install various keyboard hooks that alter the functionality of ctrl + alt + delete.

You can read about the registry API here.

If you want NOTHING to happen when you press ctrl alt delete, look into windows hooks and windows API hooking. Those are not easy to code; if you want API hooking then I suggest this library - you might be able to do this with classic windows hooks however. You'll need to write your own msgina.dll to rigurously hook this function. If you don't absolutely have to cut off any response to this command (and you probably don't), then you can most likely get away with simpler methods.

like image 21
IVlad Avatar answered Nov 15 '22 16:11

IVlad


This is in response to what the OP wants to do, not the question itself...

The easiest way accomplish your goal would be to write a keyboard filter driver, which discards all input. (This is really the only correct way of disabling all input I can think of, and is the method used by products such as LogMeIn)

like image 27
Billy ONeal Avatar answered Nov 15 '22 15:11

Billy ONeal