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

时间:2010-03-12 11:11:34

标签: c windows

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

6 个答案:

答案 0 :(得分:15)

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

以下是3种方法:

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

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

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

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

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

    参考:MSDN Mag Sept 2002

答案 1 :(得分:4)

是的。

CTRL + ALT + DEL,称为Secure Attention Sequence (SAS),但不能通过常见的Global Windows Hook机制拦截。

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

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

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

现在,有一种更简单的方法来规避所有这些:使用一些与驱动程序通信的库来完成所有这些肮脏的工作。这就是我试图做的事情。

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

在使用API​​之前,您必须使用installer在系统上安装驱动程序。

在我的网站上已有一个SAS拦截示例,您也可以在github上查看here。我会把它留在这里作为参考:

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

答案 2 :(得分:2)

将钩子放入键盘系统是不行的,尽管有些人在说。

键盘系统通过发出特定的硬件中断来工作。操作系统捕获此中断并适当地响应它。这将是受键盘钩子影响的事情。

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

现在使用密钥序列登录的原因是因为这种行为。由于它发出一个单独的硬件中断,序列用于验证其他应用程序没有挂钩。这是为了防止欺骗登录提示。

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

答案 3 :(得分:2)

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

答案 4 :(得分:1)

为什么所有答案都说不可能?这是非常有可能的,例如,如果病毒已禁用它,如何启用它:

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

如何禁用它以及如何从代码中执行此操作我会让你弄清楚(提示:你可能想要编辑一些registry keys),因为这个问题很可疑。

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

您可以阅读有关注册表API here的信息。

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

答案 5 :(得分:1)

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

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