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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2432262/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 14:06:39  来源:igfitidea点击:

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

cwindows

提问by Badr

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。有可能做到吗?

回答by Indy9000

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

  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"

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

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

  3. 转到“开始”菜单,选择“运行”,然后键入“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 月

回答by pepper_chico

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 版本才允许这样做。而且您将有在途中遇到一些有趣的蓝屏死机的风险。

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

键盘过滤器驱动程序的官方微软示例是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..., interceptdevice 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.

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

You must use an installerto 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;
}

回答by Jeffrey L Whitledge

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 序列从其他键发出单独的硬件中断。这样做最初是为了即使其他键盘命令被冻结,重启命令也可以使用。(尽管 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.

我并不是说不可能捕获此中断并修改其行为。我不知道它不是。但这不会像在键盘处理代码中加入钩子那么简单。

回答by ChristianWimmer

Winlogon just calls SetWindowsHookExon the default desktop to trap CAD. Since only a thread that called SetWindowsHookExcan 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。您可以在此处找到一些内部信息。

回答by Billy ONeal

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 correctway of disabling all input I can think of, and is the method used by products such as LogMeIn)

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

回答by IVlad

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
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 thislibrary - 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 hooking。那些不容易编码;如果您想要 API 挂钩,那么我建议使用这个库 - 但是您可以使用经典的 Windows 挂钩来做到这一点。您需要编写自己的 msgina.dll 来严格地挂钩此函数。如果您不是绝对必须切断对此命令的任何响应(而且您可能不需要),那么您很可能可以使用更简单的方法。