我想在我的ANSI-C代码中禁用Windows XP中的CTRL + ALT + DEL?

时间:2022-02-10 21:06:37

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

我想在我的ANSI-C代码中禁用Windows XP中的CTRL + ALT + DEL。有可能吗?

6 个解决方案

#1


15  

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.

首先,捕获Ctrl-Alt-Del(安全注意序列)并禁用它是两回事。尽管许多人有误解,但仍有可能禁用SAS。

Here are 3 ways to do it:

以下是3种方法:

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

    设置HKCU / Software / Microsoft / Windows / CurrentVersion / Policies / System / DisableTaskMgr = 1

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

    用您自己的msgina.dll替换或写一个键盘驱动程序。

  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"

    转到“开始”菜单,选择“运行”,然后键入“gpedit.msc”以运行组策略编辑器。查看用户配置|管理模板|系统,你会找到一个名为Ctrl + Alt + Del选项的部分 - “删除任务管理器”

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

为了捕获SAS,您可以编写GINA存根,创建键盘驱动程序或替换TaskMgr.exe

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

这些要求主要针对嵌入式系统,您可以控制WinXP图像的制作方式。

Reference: MSDN Mag Sept 2002

参考:MSDN Mag 2002年9月

#2


4  

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.

但是,CTRL + ALT + DEL(称为安全注意序列(SAS))无法通过通用的全局Windows Hook机制拦截。

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

无论情况如何,你必须拦截我所知道的SAS的选项只是一个:驱动程序。

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.

但它不需要是一个完整的设备驱动程序,它可以是一个更简单的过滤器驱动程序。您将需要学习如何进行内核开发,这不是那么简单,并且需要您进行,例如,使用两台机器进行内核调试。如果您希望在具有较新Windows的其他计算机上使用您的驱动程序,则需要签署驱动程序,因为Windows Vista x64和更新版本不会加载未签名的驱动程序,只允许这些操作系统的x86版本执行此操作。并且你将有可能获得一些有趣的BSOD。

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

键盘过滤器驱动程序的官方微软样本是kbfiltr样本。

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.

我已经开发了一个库,我称之为拦截,它允许一个人在使用设备驱动程序的功能时拦截来自普通用户模式程序的设备输入。它是一个小而简单的C api,它与我已经正确签名的驱动程序进行内部通信。

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

在使用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:

在我的网站上已有一个SAS拦截样本,您也可以在这里查看github。我会留在这里供参考:

#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;
}

#3


2  

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.)

序列CTRL-ALT-DEL从其他键发出单独的硬件中断。这是最初完成的,因此即使其他键盘命令被冻结,也可以使用reboot命令。 (尽管MS-DOS中的终止驻留应用程序仍然可以捕获并处理中断。)

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.

我并不是说不可能捕获这个中断并修改它的行为。我不知道事实并非如此。但它并不像将钩子放入键盘处理代码那么简单。

#4


2  

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.

Winlogon只是在默认桌面上调用SetWindowsHookEx来捕获CAD。由于只有一个调用SetWindowsHookEx的线程可以取消注册该钩子,因此确保没有其他进程可以窃取它。此外,键盘挂钩仅适用于进程桌面。您可以尝试切换到新桌面并点击CAD。您可以在此处找到一些内部信息。

#5


1  

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.

您还可以安装各种键盘挂钩,以改变ctrl + alt + delete的功能。

You can read about the registry API here.

您可以在此处阅读有关注册表API的信息。

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.

如果你想按下ctrl alt delete时没有发生,请查看windows hooks和windows API挂钩。这些都不容易编码;如果你想要API挂钩,那么我建议这个库 - 你可能能够用经典的Windows钩子做到这一点。您需要编写自己的msgina.dll来严格挂钩此功能。如果你不是绝对不必切断对这个命令的任何响应(你可能没有),那么你很可能会使用更简单的方法。

#6


1  

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

这是对OP想要做的回应,而不是问题本身......

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)

实现目标的最简单方法是编写一个键盘过滤器驱动程序,它会丢弃所有输入。 (这实际上是禁用我能想到的所有输入的唯一正确方法,也是LogMeIn等产品使用的方法)

#1


15  

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.

首先,捕获Ctrl-Alt-Del(安全注意序列)并禁用它是两回事。尽管许多人有误解,但仍有可能禁用SAS。

Here are 3 ways to do it:

以下是3种方法:

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

    设置HKCU / Software / Microsoft / Windows / CurrentVersion / Policies / System / DisableTaskMgr = 1

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

    用您自己的msgina.dll替换或写一个键盘驱动程序。

  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"

    转到“开始”菜单,选择“运行”,然后键入“gpedit.msc”以运行组策略编辑器。查看用户配置|管理模板|系统,你会找到一个名为Ctrl + Alt + Del选项的部分 - “删除任务管理器”

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

为了捕获SAS,您可以编写GINA存根,创建键盘驱动程序或替换TaskMgr.exe

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

这些要求主要针对嵌入式系统,您可以控制WinXP图像的制作方式。

Reference: MSDN Mag Sept 2002

参考:MSDN Mag 2002年9月

#2


4  

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.

但是,CTRL + ALT + DEL(称为安全注意序列(SAS))无法通过通用的全局Windows Hook机制拦截。

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

无论情况如何,你必须拦截我所知道的SAS的选项只是一个:驱动程序。

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.

但它不需要是一个完整的设备驱动程序,它可以是一个更简单的过滤器驱动程序。您将需要学习如何进行内核开发,这不是那么简单,并且需要您进行,例如,使用两台机器进行内核调试。如果您希望在具有较新Windows的其他计算机上使用您的驱动程序,则需要签署驱动程序,因为Windows Vista x64和更新版本不会加载未签名的驱动程序,只允许这些操作系统的x86版本执行此操作。并且你将有可能获得一些有趣的BSOD。

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

键盘过滤器驱动程序的官方微软样本是kbfiltr样本。

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.

我已经开发了一个库,我称之为拦截,它允许一个人在使用设备驱动程序的功能时拦截来自普通用户模式程序的设备输入。它是一个小而简单的C api,它与我已经正确签名的驱动程序进行内部通信。

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

在使用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:

在我的网站上已有一个SAS拦截样本,您也可以在这里查看github。我会留在这里供参考:

#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;
}

#3


2  

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.)

序列CTRL-ALT-DEL从其他键发出单独的硬件中断。这是最初完成的,因此即使其他键盘命令被冻结,也可以使用reboot命令。 (尽管MS-DOS中的终止驻留应用程序仍然可以捕获并处理中断。)

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.

我并不是说不可能捕获这个中断并修改它的行为。我不知道事实并非如此。但它并不像将钩子放入键盘处理代码那么简单。

#4


2  

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.

Winlogon只是在默认桌面上调用SetWindowsHookEx来捕获CAD。由于只有一个调用SetWindowsHookEx的线程可以取消注册该钩子,因此确保没有其他进程可以窃取它。此外,键盘挂钩仅适用于进程桌面。您可以尝试切换到新桌面并点击CAD。您可以在此处找到一些内部信息。

#5


1  

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.

您还可以安装各种键盘挂钩,以改变ctrl + alt + delete的功能。

You can read about the registry API here.

您可以在此处阅读有关注册表API的信息。

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.

如果你想按下ctrl alt delete时没有发生,请查看windows hooks和windows API挂钩。这些都不容易编码;如果你想要API挂钩,那么我建议这个库 - 你可能能够用经典的Windows钩子做到这一点。您需要编写自己的msgina.dll来严格挂钩此功能。如果你不是绝对不必切断对这个命令的任何响应(你可能没有),那么你很可能会使用更简单的方法。

#6


1  

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

这是对OP想要做的回应,而不是问题本身......

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)

实现目标的最简单方法是编写一个键盘过滤器驱动程序,它会丢弃所有输入。 (这实际上是禁用我能想到的所有输入的唯一正确方法,也是LogMeIn等产品使用的方法)