【问题标题】:How lock CTRL+ALT+DEL using SetWindowHookEx api?如何使用 SetWindowsHookEx api 锁定 CTRL+ALT+DEL?
【发布时间】:2016-11-12 19:56:17
【问题描述】:

下午好,

我需要使用SetWindowsHookEx 锁定CTRL+ALT+DEL 组合,今天我完成了一个代码,直到现在才起作用。

这段代码在一个注入到其他进程的dll(这个dll是我的软件)中执行。

那么,我如何调整下面的代码来工作?

const
WH_KEYBOARD_LL = 13;
LLKHF_ALTDOWN = $20;

type
KBDLLHOOKSTRUCT = record
vkCode: DWORD;
scanCode: DWORD;
flags: DWORD;
time: DWORD;
dwExtraInfo: Longint ;
end;

var
hhkLowLevelKybd : HHOOK;
FoldProc : LongInt;
hSASWnd : HWND;
hThread : Cardinal;

{$R *.dfm}

Function LowLevelKeyboardProc(nCode : Integer; wParam : Longint; var LParam: KBDLLHOOKSTRUCT) : Longint; stdcall;
var
fEatKeystroke : Boolean;
dwThreadId : Cardinal;
begin

If (nCode = HC_ACTION) Then
begin
If (wParam = WM_KEYDOWN) Or
(wParam = WM_SYSKEYDOWN) Or
(wParam = WM_KEYUP) Or
(wParam = WM_SYSKEYUP) Then
begin
fEatKeystroke :=
(((GetKeyState(VK_CONTROL) And $8000) <> 0) And
((LParam.flags And LLKHF_ALTDOWN ) <> 0) And
 (LParam.vkCode = VK_DELETE));

End;

If fEatKeystroke Then
Result := -1
Else
Result := CallNextHookEx(0, nCode, wParam, LongInt(@LParam));
End;

end;

////////// FormCreate event here ///////////

hhkLowLevelKybd := 0;
hhkLowLevelKybd := SetWindowsHookEx(WH_KEYBOARD_LL, @LowLevelKeyboardProc,
HInstance, 0);

end.

【问题讨论】:

  • Windows 不允许您拦截该组合键。在早期版本中这是可能的,但最近的版本在无法阻止的较低级别处理该组合键。这是一个安全问题。相关:stackoverflow.com/q/17103682/62576
  • 最简单的方法是从键盘上移除这 3 个键中的一个。
  • @Jerry Dodge,好的:D
  • 这是安全注意序列。一旦你读了它,你就会明白为什么你不能钩它。

标签: delphi setwindowshookex


【解决方案1】:

出于安全原因,Windows 不允许您拦截 Ctrl+Alt+Del。早期版本(Vista 之前的版本?)曾经通过替换 GINA DLL 来允许它,但多年来一直不允许。

该组合键称为secure attention sequence,作为登录过程的一部分,它保证是值得信赖的。

如果您的目标是只允许您的应用程序运行,则可以将其配置为在运行合适版本的 Windows 时以 kiosk 模式运行,如@LURD 提供的 TechNet 上的Set up a device for anyone to use (kiosk mode) 所示。

【讨论】:

    【解决方案2】:

    根据设计,不可能捕获或阻止 Ctrl+Alt+Del(安全注意序列)。但是有一个商业库可用(免责声明:我是作者)SasLibEx

    SasLibEx:一个可以模拟或阻止 Secure Attention 的库 序列 (Ctrl+Alt+Del) 但它甚至可以解锁一个 工作站或会话,无需输入或需要用户的 凭据(以及更多内容)

    请参阅此screencast 以获取演示。

    【讨论】:

    • 我看到你对WinSta and Secure Desktop 的理解很好,我希望你能通过this my another question here 提供帮助(如果可能的话)
    【解决方案3】:

    不可能。 Ctl-Alt-Del 被困在内核中,永远不会进入运行应用程序的用户模式空间。 我必须在信息亭系统(使用 Win XP 和 Vista)上执行此操作,并且我使用键盘过滤器驱动程序(在内核中运行)完成此操作,该驱动程序在按下键时交换扫描码。

    【讨论】:

      【解决方案4】:

      不是不可能,见以下代码:

      program Project1;
      
      {$APPTYPE CONSOLE}
      {$R *.res}
      
      uses
        SysUtils,
        Windows,
        Registry,
        vcl.Dialogs;
      
      procedure DisableCtrAltDel(boolState: Boolean);
      var
        SystemReg: TRegistry;
        Data: Array [1 .. 48] of Byte;
        i: Byte;
      begin
        try
      
          for i := 1 to 48 do
            Data[i] := $00;
      
          Data[9] := $09;
          Data[15] := $5B;
          Data[16] := $E0;
          Data[19] := $5C;
          Data[20] := $E0;
          Data[23] := $5D;
          Data[24] := $E0;
          Data[27] := $44;
          Data[31] := $1D;
          Data[35] := $38;
          Data[39] := $1D;
          Data[40] := $E0;
          Data[43] := $38;
          Data[44] := $E0;
      
          try
            SystemReg := TRegistry.Create;
            with SystemReg do
            begin
              RootKey := HKEY_LOCAL_MACHINE;
              OpenKey('\System\CurrentControlSet\Control\Keyboard Layout', True);
      
              if boolState then
      
                WriteBinaryData('Scancode Map', Data, SizeOf(Data))
              else
                DeleteValue('Scancode Map');
      
              MessageDlg('Restart Windows in order the changes to take effect!',
                mtInformation, [mbOK], 0);
              CloseKey;
            end;
          finally
            SystemReg.Free;
          end;
        except
          MessageDlg
            ('Error occurred while trying to disable ctrl+alt+del and Task Manager',
            mtWarning, [mbOK], 0);
        end;
      end;
      
      begin
        try
          DisableCtrAltDel(True);
        except
          on E: Exception do
            Writeln(E.ClassName, ': ', E.Message);
        end;
      
      end.
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-17
        • 2014-09-12
        • 2022-06-16
        • 1970-01-01
        • 2012-07-11
        • 1970-01-01
        相关资源
        最近更新 更多