谁能用Delphi屏蔽Win2000的Alt+Ctrl+Del!分数任你要!
可另开贴送分!

解决方案 »

  1.   

    Win2K/NT下屏蔽Ctrl+Alt+Del的响应
    大家知道,Ctrl+Alt+Del是Win2k/NT操作系统默认的系统登录/注销组合键序列,系统级别很高。在应用程序中,想要屏蔽掉该键序列的响应或得到这个"按下"事件,难度是相当大的。本文介绍了一种简单易行的方法,实现在用户登录成功后,按下Ctrl+Alt+Del不再弹出"Windows安全"对话框。关键词:GINA(Graphical Identification aNd Authentication)
    SAS(Secure Attention Sequence)一. 开发原理
    首先介绍一下Winlogon。Windows 2000/NT有三种系统状态:没有用户登录状态、用户成功登录状态以及工作站锁定状态。Winlogon是Windows 2000/NT操作系统提供交互式登录支持的组件。Winlogon有三个组成部分:可执行文件winlogon.exe,提供图形界面认证功能的动态库Gina Dll,以及一些网络服务提供动态库Network Provider Dll。参考模型如下:
     
    winlogon.exe处理一些下层导出的接口函数,而认证策略是在Gina Dll中是独立设计的。在系统启动时,Gina Dll被winlogon.exe装载。Microsoft提供了一个默认的Gina Dll--Winnt\system32\msgina.dll,提供了标准的用户名、密码认证模式。Gina Dll是可替换的,用户可以设计自己的Gina Dll,以提供其他如智能卡、视网膜、指纹或其他一些认证机制。
    开发自定义的Gina Dll。必须实现并导出与winlogon.exe交互的18个标准函数接口,包括WlxNegotiate、WlxInitialize、WlxLoggedOnSAS等(其他函数接口请参考Msdn)。其中WlxNegotiate是winlogon.exe调用的第一个接口函数,进行必要的版本判断,随后调用的是WlxInitialize,主要完成winlogon.exe特定版本的函数分派表向Gina Dll的传递。笔者还要说明的是WlxLoggedOnSAS函数,这个函数主要的功能是,当winlogon在登录成功状态下,接收到SAS事件,于是调用这个函数进行SAS事件的识别以及进行各事件的相应处理。
    自定义Gina Dll的使用。比如开发的Gina Dll文件名为MyGina.dll。将该文件放到以下路径:Winnt\system32。并修改注册表,如下:
    Key Name: \HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\ Winlogon 
    Value Name: GinaDLL 
    Value Type: [REG_SZ]
    Value: MyGina.dll
    重新启动计算机MyGina.dll即投入使用。二. 应用实例
    应用要求:在用户登录成功状态下,按下Ctrl+Alt+Del时系统不再弹出"Widows安全"对话框。由于并不需要改变用户名、密码这种标准的认证模式,所以可以仍然使用msgina.dll中导出的函数接口,而对WlxLoggedOnSAS函数的实现进行必要的改变。
    开发环境:Windows 2000,PII 400
    开发工具:Microsoft Visual C++ 6.0
    开发步骤:
    1.新建项目,选择MFC AppWizard(dll),项目名输入为MyGina。按下"OK"后,选择Regular DLL with MFC statically linked,按下"Finish"。
    2.使用View->ClassWizard为CmyGinaApp增加InitInstance和ExitInstance两个函数的覆盖。注意在Stdafx.h中加入#include <Winwlx.h>。
    3.由于要导入msgina.dll的接口函数,所以在MyGina.h中定义接口函数变量类型,如下:
    typedef (WINAPI * NEGOTIATE)       (DWORD,PDWORD);
    typedef (WINAPI * INITIALIZE)      (LPWSTR,HANDLE,PVOID,PVOID,PVOID *);
    typedef (WINAPI * ACTIVATE_USHELL) (PVOID,PWSTR,PWSTR,PVOID);
    typedef (WINAPI * PARAM_PVOID)     (PVOID);
    typedef (WINAPI * DISP_STATUS)     (PVOID,HDESK,DWORD,PWSTR,PWSTR);
    typedef (WINAPI * GET_STATUS)      (PVOID,DWORD *,PWSTR,DWORD);
    typedef (WINAPI * LOGON_SAS)       (PVOID,DWORD,PVOID);
    typedef (WINAPI * LOGOUT_SAS)      (PVOID,DWORD,PLUID,PSID,PDWORD, PHANDLE,WLX_MPR_NOTIFY_INFO,PVOID *);
    typedef (WINAPI * NETWORK_LOAD)    (PVOID,PWLX_MPR_NOTIFY_INFO);
    typedef (WINAPI * SCR_SAVER)       (PVOID,BOOL  *);
    typedef (WINAPI * SHUT_DOWN)       (PVOID,DWORD);
    typedef (WINAPI * START_APP)       (PVOID,PWSTR,PVOID,PWSTR);
    typedef (WINAPI * LOCKED_SAS)      (PVOID,DWORD);
    并在类CmyGinaApp中定义成员变量,如下:
    private:
    HMODULE   hMsDll;
    public:
    NEGOTIATE         MyWlxNegotiate;
    INITIALIZE        MyWlxInitialize;
    ACTIVATE_USHELL   MyWlxActivateUserShell;
    PARAM_PVOID       MyWlxDisplayLockedNotice;
    PARAM_PVOID       MyWlxDisplaySASNotice;
    DISP_STATUS       MyWlxDisplayStatusMessage;
    GET_STATUS        MyWlxGetStatusMessage;
    PARAM_PVOID       MyWlxIsLockOk;
    PARAM_PVOID       MyWlxIsLogoffOk;
    LOGON_SAS         MyWlxLoggedOnSAS;
    LOGOUT_SAS        MyWlxLoggedOutSAS;
    PARAM_PVOID       MyWlxLogoff;
    NETWORK_LOAD      MyWlxNetworkProviderLoad;
    PARAM_PVOID       MyWlxRemoveStatusMessage;
    SCR_SAVER         MyWlxScreenSaverNotify;
    SHUT_DOWN         MyWlxShutdown;
    START_APP         MyWlxStartApplication;
    LOCKED_SAS        MyWlxWkstaLockedSAS;
    注意在MyGina.h中说明extern CMyGinaApp theApp;以便于程序其他地方对theApp的引用。
    4.在MyGina.cpp中,实现InitInstance如下:
    // 得到默认的gina dll
    if (hMsDll == NULL)
    {
    hMsDll = ::LoadLibrary("msgina.dll");
    }
    // 导入各个接口函数
    if (hMsDll != NULL)
    {
    MyWlxNegotiate = (NEGOTIATE)       GetProcAddress(hMsDll,"WlxNegotiate");
    MyWlxInitialize = (INITIALIZE)      GetProcAddress(hMsDll,"WlxInitialize");
    MyWlxActivateUserShell=(ACTIVATE_USHELL) GetProcAddress(hMsDll,"WlxActivateUserShell");
    MyWlxDisplayLockedNotice=(PARAM_PVOID) GetProcAddress(hMsDll,"WlxDisplayLockedNotice");
    MyWlxDisplaySASNotice  = (PARAM_PVOID)     GetProcAddress(hMsDll,"WlxDisplaySASNotice");
    MyWlxDisplayStatusMessage=(DISP_STATUS)   GetProcAddress(hMsDll,"WlxDisplayStatusMessage");
    MyWlxGetStatusMessage    = (GET_STATUS)      GetProcAddress(hMsDll,"WlxGetStatusMessage");
    MyWlxIsLockOk           = (PARAM_PVOID)     GetProcAddress(hMsDll,"WlxIsLockOk");
    MyWlxIsLogoffOk           = (PARAM_PVOID)     GetProcAddress(hMsDll,"WlxIsLogoffOk");
    MyWlxLoggedOnSAS        = (LOGON_SAS)       GetProcAddress(hMsDll,"WlxLoggedOnSAS");
    MyWlxLoggedOutSAS       = (LOGOUT_SAS)      GetProcAddress(hMsDll,"WlxLoggedOutSAS");
    MyWlxLogoff               = (PARAM_PVOID)     GetProcAddress(hMsDll,"WlxLogoff");
    MyWlxNetworkProviderLoad=(NETWORK_LOAD)GetProcAddress(hMsDll,"WlxNetworkProviderLoad");
    MyWlxRemoveStatusMessage=(PARAM_PVOID) GetProcAddress(hMsDll,"WlxRemoveStatusMessage");
    MyWlxScreenSaverNotify = (SCR_SAVER)    GetProcAddress(hMsDll,"WlxScreenSaverNotify");
    MyWlxShutdown             = (SHUT_DOWN)       GetProcAddress(hMsDll,"WlxShutdown");
    MyWlxStartApplication     = (START_APP)       GetProcAddress(hMsDll,"WlxStartApplication");
    MyWlxWkstaLockedSAS   = (LOCKED_SAS)     GetProcAddress(hMsDll,"WlxWkstaLockedSAS");
    }
    实现ExitInstance如下:
    // 卸载dll
    if (hMsDll != NULL)
    {
    ::FreeLibrary(hMsDll);
    hMsDll = NULL;
    }
    5.实现接口函数。由于本应用仍然保持msgina.dll的大部分操作,所以MyGina.dll的接口函数的实现较为简单。重点需要注意的是WlxLoggedOnSAS函数的实现。当在成功登录状态下,不管接收到什么SAS事件,该函数直接返回WLX_SAS_ACTION_NONE而不做其他处理。由于实现的函数较多(必须的18个),笔者仅列出代表性的五个,其余的依理类推。
    // Winlogon.exe调用的gina dll中的第一个函数
    // 使gina dll确认是否支持当前版本的Winlogon.exe
    // 传递给winlogon.exe需要那个版本的接口函数
    BOOL WINAPI WlxNegotiate(DWORD dwWinLogonVersion, PDWORD pdwDllVersion)
    {
    // 直接调用从msgina.dll中导入的函数
    return theApp.MyWlxNegotiate(dwWinLogonVersion,pdwDllVersion);
    }
    // 初始化,winlogon.exe向gina dll传递需要版本的接口函数分配表
    BOOL WINAPI WlxInitialize(LPWSTR    lpWinsta,
      HANDLE    hWlx,
      PVOID     pvReserved,
      PVOID     pWinlogonFunctions,
      PVOID *   pWlxContext
      )
    {
    // 直接调用从msgina.dll中导入的函数
    return theApp.MyWlxInitialize(lpWinsta,hWlx,pvReserved,pWinlogonFunctions,pWlxContext);
    }
    // 当系统处于锁定状态时,Winlogon.exe调用该函数
    // 显示一些信息,如锁定者、锁定时间等
    VOID WINAPI WlxDisplayLockedNotice(PVOID pWlxContext)
    {
    theApp.MyWlxDisplayLockedNotice(pWlxContext);
    }
    // 在系统关闭之前,Winlogon.exe调用该函数
    // 允许gina dll处理一些系统关闭前的处理
    VOID WINAPI WlxShutdown(PVOID pWlxContext, DWORD ShutdownType)
    {
    theApp.MyWlxShutdown(pWlxContext,ShutdownType);
    }
    // 当系统处于登陆成功,没有锁定的状态下
    // Winlogon接收到SAS事件,于是调用该函数
    // 现屏蔽所有事件,直接返回
    int WINAPI WlxLoggedOnSAS(PVOID pWlxContext,
      DWORD dwSasType,
      PVOID pReserved)
    {
    return WLX_SAS_ACTION_NONE;
    }
    6.将MyGina.dll中实现的所有接口函数,在MyGina.def中定义导出。
      

  2.   

    Win2K/NT下屏蔽Ctrl+Alt+Del的响应
    大家知道,Ctrl+Alt+Del是Win2k/NT操作系统默认的系统登录/注销组合键序列,系统级别很高。在应用程序中,想要屏蔽掉该键序列的响应或得到这个"按下"事件,难度是相当大的。本文介绍了一种简单易行的方法,实现在用户登录成功后,按下Ctrl+Alt+Del不再弹出"Windows安全"对话框。关键词:GINA(Graphical Identification aNd Authentication)
    SAS(Secure Attention Sequence)一. 开发原理
    首先介绍一下Winlogon。Windows 2000/NT有三种系统状态:没有用户登录状态、用户成功登录状态以及工作站锁定状态。Winlogon是Windows 2000/NT操作系统提供交互式登录支持的组件。Winlogon有三个组成部分:可执行文件winlogon.exe,提供图形界面认证功能的动态库Gina Dll,以及一些网络服务提供动态库Network Provider Dll。参考模型如下:
     
    winlogon.exe处理一些下层导出的接口函数,而认证策略是在Gina Dll中是独立设计的。在系统启动时,Gina Dll被winlogon.exe装载。Microsoft提供了一个默认的Gina Dll--Winnt\system32\msgina.dll,提供了标准的用户名、密码认证模式。Gina Dll是可替换的,用户可以设计自己的Gina Dll,以提供其他如智能卡、视网膜、指纹或其他一些认证机制。
    开发自定义的Gina Dll。必须实现并导出与winlogon.exe交互的18个标准函数接口,包括WlxNegotiate、WlxInitialize、WlxLoggedOnSAS等(其他函数接口请参考Msdn)。其中WlxNegotiate是winlogon.exe调用的第一个接口函数,进行必要的版本判断,随后调用的是WlxInitialize,主要完成winlogon.exe特定版本的函数分派表向Gina Dll的传递。笔者还要说明的是WlxLoggedOnSAS函数,这个函数主要的功能是,当winlogon在登录成功状态下,接收到SAS事件,于是调用这个函数进行SAS事件的识别以及进行各事件的相应处理。
    自定义Gina Dll的使用。比如开发的Gina Dll文件名为MyGina.dll。将该文件放到以下路径:Winnt\system32。并修改注册表,如下:
    Key Name: \HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\ Winlogon 
    Value Name: GinaDLL 
    Value Type: [REG_SZ]
    Value: MyGina.dll
    重新启动计算机MyGina.dll即投入使用。二. 应用实例
    应用要求:在用户登录成功状态下,按下Ctrl+Alt+Del时系统不再弹出"Widows安全"对话框。由于并不需要改变用户名、密码这种标准的认证模式,所以可以仍然使用msgina.dll中导出的函数接口,而对WlxLoggedOnSAS函数的实现进行必要的改变。
    开发环境:Windows 2000,PII 400
    开发工具:Microsoft Visual C++ 6.0
    开发步骤:
    1.新建项目,选择MFC AppWizard(dll),项目名输入为MyGina。按下"OK"后,选择Regular DLL with MFC statically linked,按下"Finish"。
    2.使用View->ClassWizard为CmyGinaApp增加InitInstance和ExitInstance两个函数的覆盖。注意在Stdafx.h中加入#include <Winwlx.h>。
    3.由于要导入msgina.dll的接口函数,所以在MyGina.h中定义接口函数变量类型,如下:
    typedef (WINAPI * NEGOTIATE)       (DWORD,PDWORD);
    typedef (WINAPI * INITIALIZE)      (LPWSTR,HANDLE,PVOID,PVOID,PVOID *);
    typedef (WINAPI * ACTIVATE_USHELL) (PVOID,PWSTR,PWSTR,PVOID);
    typedef (WINAPI * PARAM_PVOID)     (PVOID);
    typedef (WINAPI * DISP_STATUS)     (PVOID,HDESK,DWORD,PWSTR,PWSTR);
    typedef (WINAPI * GET_STATUS)      (PVOID,DWORD *,PWSTR,DWORD);
    typedef (WINAPI * LOGON_SAS)       (PVOID,DWORD,PVOID);
    typedef (WINAPI * LOGOUT_SAS)      (PVOID,DWORD,PLUID,PSID,PDWORD, PHANDLE,WLX_MPR_NOTIFY_INFO,PVOID *);
    typedef (WINAPI * NETWORK_LOAD)    (PVOID,PWLX_MPR_NOTIFY_INFO);
    typedef (WINAPI * SCR_SAVER)       (PVOID,BOOL  *);
    typedef (WINAPI * SHUT_DOWN)       (PVOID,DWORD);
    typedef (WINAPI * START_APP)       (PVOID,PWSTR,PVOID,PWSTR);
    typedef (WINAPI * LOCKED_SAS)      (PVOID,DWORD);
    并在类CmyGinaApp中定义成员变量,如下:
    private:
    HMODULE   hMsDll;
    public:
    NEGOTIATE         MyWlxNegotiate;
    INITIALIZE        MyWlxInitialize;
    ACTIVATE_USHELL   MyWlxActivateUserShell;
    PARAM_PVOID       MyWlxDisplayLockedNotice;
    PARAM_PVOID       MyWlxDisplaySASNotice;
    DISP_STATUS       MyWlxDisplayStatusMessage;
    GET_STATUS        MyWlxGetStatusMessage;
    PARAM_PVOID       MyWlxIsLockOk;
    PARAM_PVOID       MyWlxIsLogoffOk;
    LOGON_SAS         MyWlxLoggedOnSAS;
    LOGOUT_SAS        MyWlxLoggedOutSAS;
    PARAM_PVOID       MyWlxLogoff;
    NETWORK_LOAD      MyWlxNetworkProviderLoad;
    PARAM_PVOID       MyWlxRemoveStatusMessage;
    SCR_SAVER         MyWlxScreenSaverNotify;
    SHUT_DOWN         MyWlxShutdown;
    START_APP         MyWlxStartApplication;
    LOCKED_SAS        MyWlxWkstaLockedSAS;
    注意在MyGina.h中说明extern CMyGinaApp theApp;以便于程序其他地方对theApp的引用。
    4.在MyGina.cpp中,实现InitInstance如下:
    // 得到默认的gina dll
    if (hMsDll == NULL)
    {
    hMsDll = ::LoadLibrary("msgina.dll");
    }
    // 导入各个接口函数
    if (hMsDll != NULL)
    {
    MyWlxNegotiate = (NEGOTIATE)       GetProcAddress(hMsDll,"WlxNegotiate");
    MyWlxInitialize = (INITIALIZE)      GetProcAddress(hMsDll,"WlxInitialize");
    MyWlxActivateUserShell=(ACTIVATE_USHELL) GetProcAddress(hMsDll,"WlxActivateUserShell");
    MyWlxDisplayLockedNotice=(PARAM_PVOID) GetProcAddress(hMsDll,"WlxDisplayLockedNotice");
    MyWlxDisplaySASNotice  = (PARAM_PVOID)     GetProcAddress(hMsDll,"WlxDisplaySASNotice");
    MyWlxDisplayStatusMessage=(DISP_STATUS)   GetProcAddress(hMsDll,"WlxDisplayStatusMessage");
    MyWlxGetStatusMessage    = (GET_STATUS)      GetProcAddress(hMsDll,"WlxGetStatusMessage");
    MyWlxIsLockOk           = (PARAM_PVOID)     GetProcAddress(hMsDll,"WlxIsLockOk");
    MyWlxIsLogoffOk           = (PARAM_PVOID)     GetProcAddress(hMsDll,"WlxIsLogoffOk");
    MyWlxLoggedOnSAS        = (LOGON_SAS)       GetProcAddress(hMsDll,"WlxLoggedOnSAS");
    MyWlxLoggedOutSAS       = (LOGOUT_SAS)      GetProcAddress(hMsDll,"WlxLoggedOutSAS");
    MyWlxLogoff               = (PARAM_PVOID)     GetProcAddress(hMsDll,"WlxLogoff");
    MyWlxNetworkProviderLoad=(NETWORK_LOAD)GetProcAddress(hMsDll,"WlxNetworkProviderLoad");
    MyWlxRemoveStatusMessage=(PARAM_PVOID) GetProcAddress(hMsDll,"WlxRemoveStatusMessage");
    MyWlxScreenSaverNotify = (SCR_SAVER)    GetProcAddress(hMsDll,"WlxScreenSaverNotify");
    MyWlxShutdown             = (SHUT_DOWN)       GetProcAddress(hMsDll,"WlxShutdown");
    MyWlxStartApplication     = (START_APP)       GetProcAddress(hMsDll,"WlxStartApplication");
    MyWlxWkstaLockedSAS   = (LOCKED_SAS)     GetProcAddress(hMsDll,"WlxWkstaLockedSAS");
    }
    实现ExitInstance如下:
    // 卸载dll
    if (hMsDll != NULL)
    {
    ::FreeLibrary(hMsDll);
    hMsDll = NULL;
    }
    5.实现接口函数。由于本应用仍然保持msgina.dll的大部分操作,所以MyGina.dll的接口函数的实现较为简单。重点需要注意的是WlxLoggedOnSAS函数的实现。当在成功登录状态下,不管接收到什么SAS事件,该函数直接返回WLX_SAS_ACTION_NONE而不做其他处理。由于实现的函数较多(必须的18个),笔者仅列出代表性的五个,其余的依理类推。
    // Winlogon.exe调用的gina dll中的第一个函数
    // 使gina dll确认是否支持当前版本的Winlogon.exe
    // 传递给winlogon.exe需要那个版本的接口函数
    BOOL WINAPI WlxNegotiate(DWORD dwWinLogonVersion, PDWORD pdwDllVersion)
    {
    // 直接调用从msgina.dll中导入的函数
    return theApp.MyWlxNegotiate(dwWinLogonVersion,pdwDllVersion);
    }
    // 初始化,winlogon.exe向gina dll传递需要版本的接口函数分配表
    BOOL WINAPI WlxInitialize(LPWSTR    lpWinsta,
      HANDLE    hWlx,
      PVOID     pvReserved,
      PVOID     pWinlogonFunctions,
      PVOID *   pWlxContext
      )
    {
    // 直接调用从msgina.dll中导入的函数
    return theApp.MyWlxInitialize(lpWinsta,hWlx,pvReserved,pWinlogonFunctions,pWlxContext);
    }
    // 当系统处于锁定状态时,Winlogon.exe调用该函数
    // 显示一些信息,如锁定者、锁定时间等
    VOID WINAPI WlxDisplayLockedNotice(PVOID pWlxContext)
    {
    theApp.MyWlxDisplayLockedNotice(pWlxContext);
    }
    // 在系统关闭之前,Winlogon.exe调用该函数
    // 允许gina dll处理一些系统关闭前的处理
    VOID WINAPI WlxShutdown(PVOID pWlxContext, DWORD ShutdownType)
    {
    theApp.MyWlxShutdown(pWlxContext,ShutdownType);
    }
    // 当系统处于登陆成功,没有锁定的状态下
    // Winlogon接收到SAS事件,于是调用该函数
    // 现屏蔽所有事件,直接返回
    int WINAPI WlxLoggedOnSAS(PVOID pWlxContext,
      DWORD dwSasType,
      PVOID pReserved)
    {
    return WLX_SAS_ACTION_NONE;
    }
    6.将MyGina.dll中实现的所有接口函数,在MyGina.def中定义导出。
      

  3.   

    unit Main;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ExtCtrls, StdCtrls;type
      TMainForm = class(TForm)
        EnableBtn: TButton;
        DisableBtn: TButton;
        AboutBtn: TButton;
        ExitBtn: TButton;
        Bell1: TBevel;
        Image: TImage;
        procedure AboutBtnClick(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure EnableBtnClick(Sender: TObject);
        procedure DisableBtnClick(Sender: TObject);
        procedure ExitBtnClick(Sender: TObject);
        procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
        procedure FormDestroy(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      MainForm: TMainForm;implementationuses Hook;{$R *.dfm}type
      // Declaration from VC++ WINUSER.H
      //
      PKBDLLHOOKSTRUCT = ^KBDLLHOOKSTRUCT;
      KBDLLHOOKSTRUCT = record
        vkCode: DWORD;
        scanCode: DWORD;
        flags: DWORD;
        time: DWORD;
        dwExtraInfo: DWORD;
      end;const
      LLKHF_ALTDOWN  = KF_ALTDOWN shr 8;
      WH_KEYBOARD_LL = 13;var
      hhkNTKeyboard: HHOOK; // 钩子句柄// 低级键盘钩子回调函数
    //
    function LowLevelKeyboardFunc(nCode: Integer; w_Param: WPARAM;
      l_Param: LPARAM): LRESULT; stdcall;
    var
      blEatKeystroke: Boolean;
      p: PKBDLLHOOKSTRUCT;
    begin
      blEatKeystroke := False;
      if nCode = HC_ACTION then
      begin
        case w_Param of
          WM_KEYDOWN,
          WM_SYSKEYDOWN,
          WM_KEYUP,
          WM_SYSKEYUP:
            begin
               p := PKBDLLHOOKSTRUCT(l_Param);           // 进行按键过滤
               blEatKeystroke := (((p^.vkCode = VK_TAB) and
                                  ((p^.flags and LLKHF_ALTDOWN) <> 0)) or
                                  ((p^.vkCode = VK_ESCAPE) and
                                  ((p^.flags and LLKHF_ALTDOWN) <> 0)) or
                                  ((p^.vkCode = VK_ESCAPE) and
                                  ((GetKeyState(VK_CONTROL) and $8000) <> 0)) or
                                  ((p^.vkCode = VK_DELETE) and
                                  ((p^.flags and LLKHF_ALTDOWN) <> 0) and
                                  ((GetKeyState(VK_CONTROL) and $8000) <> 0)));
            end;
        end; // End of Case
      end;
      if blEatKeystroke then
      begin
        Result := 1;       // 捕获这些组合键,按键消息由自己处理,必须返回 1
        Hook.ShowHookInfo; // 显示一个窗口,你可以改为自己的处理代码
      end
      else
        // 其他的按键,交由别的线程处理(过滤)
        Result := CallNextHookEx(0, nCode, w_Param, l_Param);
    end;procedure TMainForm.AboutBtnClick(Sender: TObject);
    begin
      Application.MessageBox(
        PChar('Windows NT 键盘钩子演示程序'#13#10#13#10'作者:Phoenix2000,2001年7月。'),
        '关于本程序', 0);
    end;procedure TMainForm.FormCreate(Sender: TObject);
    begin
      hhkNTKeyboard := 0; // 钩子句柄初值
    end;procedure TMainForm.EnableBtnClick(Sender: TObject);
    begin
      // 挂上键盘钩子
      //
      hhkNTKeyboard := SetWindowsHookEx(WH_KEYBOARD_LL,
                                        LowLevelKeyboardFunc,
                                        HInstance, 0);
      if hhkNTKeyboard <> 0 then
        Application.MessageBox('系统键盘钩子已经启动了!', '信息', 64)
      else
        Application.MessageBox('无法启动系统键盘钩子!', '错误', 16);
    end;procedure TMainForm.DisableBtnClick(Sender: TObject);
    begin
      // 解除键盘钩子
      //
      if hhkNTKeyboard = 0 then
        Application.MessageBox('系统键盘钩子已经被禁止了!', '警告', 48)
      else
      begin
        UnhookWindowsHookEx(hhkNTKeyboard); // 卸载钩子
        hhkNTKeyboard := 0;
        Hook.CleanHookForm; // 此行代码与钩子无关,不要误解,是我自己的窗体清除
        Application.MessageBox('成功卸载系统键盘钩子!', '信息', 64)
      end;
    end;procedure TMainForm.ExitBtnClick(Sender: TObject);
    begin
      Close;
    end;procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    begin
      CanClose := (hhkNTKeyboard = 0);
      if not CanClose then
        Application.MessageBox('请先卸载系统键盘钩子,然后再退出本程序!', '警告', 48);
    end;procedure TMainForm.FormDestroy(Sender: TObject);
    begin
      if hhkNTKeyboard <> 0 then
      begin
        UnhookWindowsHookEx(hhkNTKeyboard);
        hhkNTKeyboard := 0;
      end;
      Hook.CleanHookForm;
    end;end.
      

  4.   

    http://www.csdn.net/magazine/source/11/s200111.doc
      

  5.   

    当你不需要让用户按Alt+Enter、Ctrl+Alt+Del、Ctrl+Esc等功能键的时候加入以下代码:
    Var
    temp:integer;
    begin
    SystemParametersInfo(Spi_screensaverrunning,1,@temp,0);
    end;
      当你要恢复功能键时用以下代码:
    Var
    Temp:integer;
    begin
    SystemParametersInfo(spi_screensaverrunning,0,@temp,0);
    end;
      

  6.   

    呵呵,谢谢
    厉害…………
    学习ing ……
      

  7.   

    我有delphi的源码,xp下面不能用
    http://www.iligia.com/public/download/tkhotkey/ligia_tkhotkey_source.rar
    记得给分
      

  8.   

    呵呵,大哥,下载一个Delphi超级猛料吧!!!
    你看了,如果还不会,那就不怪我了
    http://www.eping.net
      

  9.   

    对,建议下载一个超级猛料
    或者//作者 :韦覃武,jiangsheng//网上呢称:BCB_FANS(四大名捕之追杀令)(此为CSDN和www.driverdevelop.com之帐号)jiangsheng(此为CSDN帐号)//E-Mail :[email protected]//日期 :2002-10-20//2002-11-5 jingsheng修改//功能 :在2000下屏蔽Ctrl + Alt + Del组合键。(在Windows 2000 Professional SP3// 中文版平台下面测试通过)//原理 :采用远程线程注入技术,装载一个DLL到Winlogon进程,然后截获SAS窗口的窗// 口过程,接管WM_HOTKEY消息,以达到屏蔽Ctrl + Alt + Del之目的。//开发语言:Borland C++Builder 5.0 Patch2,Visual C++ 6.0 SP5//技术比较:关于在2000下面如何屏蔽Ctrl + Alt + Del组合键,一种常被提到的解决方法就// 是使用自己写的GINA去替换MSGINA.DLL,然后在WlxLoggedOnSAS里边直接返回// WLX_SAS_ACTION_NONE。嘿嘿,说到底这并不是真正地屏蔽了这个组合键,只是// 直接返回WLX_SAS_ACTION_NONE时,Winlogon进程又自动从"Winlogon"桌面切换// 回原来的"Default"桌面了,而不是显示安全对话框,所以看起来被屏蔽了:),// 使用那种方法明显地看到桌面在闪烁!但是使用本文的方法时,你不会看到任// 何闪烁!//鸣谢 :www.driverdevelop.com上的icube和lu0。//版权 :转载请注明原作者:)//---------------------------------------------------------------------------#include "stdafx.h"#include <tlhelp32.h>#include <lmerr.h>#include "Hook.h"//add by jiangsheng 2002-11-5#include "TaskKeyMgr.h"#include "Wrappers.h"//复制自MSDN杂志Windows XP Escape from DLL Hell with Custom Debugging and Instrumentation Tools and Utilities的代码extern BOOL Is_Terminal_Services () ;//复制自Platform SDK文档: Windows System Information /Verifying the System Version//end add by jiangsheng 2002-11-5//---------------------------------------------------------------------------//错误代码格式化函数//replaced by jiangsheng 2002-11-5//from Q149409 HOWTO: Get Message Text from Networking Error CodesCString __fastcall SysErrorMessage(DWORD dwLastError ){CString strRet(_T("Unknown error"));HMODULE hModule = NULL; // default to system sourceLPSTR MessageBuffer;DWORD dwBufferLength;DWORD dwFormatFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER |FORMAT_MESSAGE_IGNORE_INSERTS |FORMAT_MESSAGE_FROM_SYSTEM ;//// If dwLastError is in the network range,// load the message source.//if(dwLastError >= NERR_BASE && dwLastError <= MAX_NERR) {hModule = LoadLibraryEx(TEXT("netmsg.dll"),NULL,LOAD_LIBRARY_AS_DATAFILE);if(hModule != NULL)dwFormatFlags |= FORMAT_MESSAGE_FROM_HMODULE;}//// Call FormatMessage() to allow for message// text to be acquired from the system// or from the supplied module handle.//if(dwBufferLength = FormatMessageA(dwFormatFlags,hModule, // module to get message from (NULL == system)dwLastError,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language(LPSTR) &MessageBuffer,0,NULL)){//// Output message string on stderr.//strRet=CString(MessageBuffer,dwBufferLength);//// Free the buffer allocated by the system.//LocalFree(MessageBuffer);}//// If we loaded a message source, unload it.//if(hModule != NULL)FreeLibrary(hModule);return strRet;}//end replaced by jiangsheng 2002-11-5//---------------------------------------------------------------------------#ifdef UNICODELPCSTR LoadLibraryFuncStr = "LoadLibraryW";LPCSTR GetModuleHandleFuncStr = "GetModuleHandleW";#elseLPCSTR LoadLibraryFuncStr = "LoadLibraryA";LPCSTR GetModuleHandleFuncStr = "GetModuleHandleA";#endifLPCSTR FreeLibraryFuncStr = "FreeLibrary";LPCSTR GetProcAddressFuncStr = "GetProcAddress";LPCSTR GetLastErrorFuncStr = "GetLastError";//---------------------------------------------------------------------------//removed by jiangsheng 2002-11-5//const char* const RemoteDllName = "RemoteDll.Dll";//end removed by jiangsheng 2002-11-5LPCTSTR szRemoteProcessName = "Winlogon.exe";typedef HINSTANCE (WINAPI *PLOADLIBRARY)(LPCTSTR );typedef BOOL (WINAPI *PFREELIBRARY)(HINSTANCE);typedef HMODULE (WINAPI* PGETMODULEHANDLE)(LPCTSTR );typedef PVOID (WINAPI* PGETPROCADDRESS)(HINSTANCE,LPCSTR);typedef DWORD (WINAPI* PGETLASTERROR)(VOID);BOOL __fastcall EnablePrivilege(LPCTSTR lpszPrivilegeName,BOOL bEnable);DWORD __fastcall GetPIDFromName(LPCTSTR lpszProcName);//---------------------------------------------------------------------------typedef struct{PLOADLIBRARY pfnLoadLibrary;PGETLASTERROR pfnGetLastError;TCHAR szDllName[1024];DWORD dwReturnValue;} INJECTLIBINFO;typedef struct{PFREELIBRARY pfnFreeLibrary;PGETMODULEHANDLE pfnGetModuleHandle;PGETLASTERROR pfnGetLastError;DWORD dwReturnValue;TCHAR szDllName[1024];} DEINJECTLIBINFO;//---------------------------------------------------------------------------//远程线程,用来装载DLLstatic DWORD WINAPI ThreadFuncAttach(INJECTLIBINFO *pInfo){HINSTANCE hDll=NULL;pInfo->dwReturnValue = 0;hDll = (HINSTANCE)pInfo->pfnLoadLibrary(pInfo->szDllName);if(hDll == NULL)pInfo->dwReturnValue = pInfo->pfnGetLastError();return((DWORD)hDll);}//---------------------------------------------------------------------------//占位函数,用来计算ThreadFuncAttach的大小static void AfterThreadFuncAttach(void){}//---------------------------------------------------------------------------//远程线程,用来卸载DLLstatic DWORD WINAPI ThreadFuncDetach(DEINJECTLIBINFO *pInfo){HINSTANCE hDll = NULL;BOOL bResult=FALSE;BOOL bHasFoundModule = FALSE;pInfo->dwReturnValue = 0;//意味成功,如果这个值不是0,则是一个错误代码。while((hDll = pInfo->pfnGetModuleHandle(pInfo->szDllName)) != NULL){bHasFoundModule = TRUE;bResult = pInfo->pfnFreeLibrary(hDll);if(bResult == FALSE){pInfo->dwReturnValue = pInfo->pfnGetLastError();break;}}if(pInfo->dwReturnValue == 0 && !bHasFoundModule){pInfo->dwReturnValue = pInfo->pfnGetLastError();}return 1;}//---------------------------------------------------------------------------//占位函数,用来计算ThreadFuncDetach的大小static void AfterThreadFuncDetach(void){}//---------------------------------------------------------------------------//修改本进程的权限BOOL __fastcall EnablePrivilege(LPCTSTR lpszPrivilegeName,BOOL bEnable){HANDLE hToken;TOKEN_PRIVILEGES tp;LUID luid;if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES |TOKEN_QUERY | TOKEN_READ,&hToken))return FALSE;if(!LookupPrivilegeValue(NULL, lpszPrivilegeName, &luid))return TRUE;tp.PrivilegeCount = 1;tp.Privileges[0].Luid = luid;tp.Privileges[0].Attributes = (bEnable) ? SE_PRIVILEGE_ENABLED : 0;AdjustTokenPrivileges(hToken,FALSE,&tp,NULL,NULL,NULL);CloseHandle(hToken);return (GetLastError() == ERROR_SUCCESS);}//---------------------------------------------------------------------------
      

  10.   

    //通过进程名称得到进程的ID(这里使用方法Toolhelp函数,也可使用PSAPI)DWORD __fastcall GetPIDFromName(LPCTSTR lpszProcName){HANDLE hSnapshot;PROCESSENTRY32 ProcStruct;DWORD dwProcessID = -1;//added by jiangsheng 2002-11-8BOOL bIsTerminalServices=Is_Terminal_Services();if(bIsTerminalServices){//复制自MSDN杂志Windows XP Escape from DLL Hell with Custom Debugging and Instrumentation Tools and Utilities的代码//get current session IDCWTSWrapper WTS;if (WTS.IsValid()){DWORD dwCurSessionID = -1;LPTSTR pSessionInfo=NULL;DWORD dwBytes;if(WTS.WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE,WTS_CURRENT_SESSION,WTSSessionId, (LPTSTR*)&pSessionInfo, &dwBytes)){dwCurSessionID =*((DWORD*)pSessionInfo);// enumerate processesPWTS_PROCESS_INFO pProcessInfo = NULL;DWORD ProcessCount = 0;BOOL bFound;if (WTS.WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE, 0, 1,&pProcessInfo, &ProcessCount)){for (DWORD CurrentProcess = 0; CurrentProcess < ProcessCount; CurrentProcess++){CString strCurExePath(pProcessInfo[CurrentProcess].pProcessName);CString strRemoteProc(lpszProcName);strCurExePath.MakeLower();strRemoteProc.MakeLower();bFound = (strCurExePath.Find(strRemoteProc) != -1);if(bFound && dwCurSessionID==pProcessInfo[CurrentProcess].SessionId) {dwProcessID = pProcessInfo[CurrentProcess].ProcessId;break;}}}WTS.WTSFreeMemory(pSessionInfo);}}}else{//end added by jiangsheng 2002-11-8BOOL bResult;hSnapshot = CreateToolhelp32Snapshot((DWORD)TH32CS_SNAPPROCESS,0);ProcStruct.dwSize = sizeof(PROCESSENTRY32);bResult = Process32First(hSnapshot,&ProcStruct);while(bResult){BOOL bFound;CString strCurExePath(ProcStruct.szExeFile);CString strRemoteProc(lpszProcName);strCurExePath.MakeLower();strRemoteProc.MakeLower();bFound = (strCurExePath.Find(strRemoteProc) != -1);if(bFound){dwProcessID = ProcStruct.th32ProcessID;break;}bResult = Process32Next(hSnapshot,&ProcStruct);}CloseHandle(hSnapshot);}return dwProcessID;}//---------------------------------------------------------------------------// 插入代码//---------------------------------------------------------------------------//InjectFuncvoid __fastcall InjectFunc(){HANDLE hRemoteProcess=NULL;DWORD dwRemoteProcess=NULL;DWORD dwThreadSize=0;INJECTLIBINFO InjectLibInfo;PVOID pRemoteThread=NULL;PVOID pRemoteParam=NULL;DWORD dwWriten=0;DWORD dwRet=0;//提升本进程权限然后打开目的进程//当前用户必须具有调试权限EnablePrivilege(SE_DEBUG_NAME,true);dwRemoteProcess = GetPIDFromName(szRemoteProcessName);if(dwRemoteProcess == (DWORD)-1){MessageBox(NULL,_T("Failed to Query Process ID."),NULL,MB_OK | MB_APPLMODAL | MB_ICONWARNING);return;}hRemoteProcess = OpenProcess(PROCESS_ALL_ACCESS,false,dwRemoteProcess);if(hRemoteProcess == NULL){MessageBox(NULL,_T("Failed to Open Process. Err = ") + SysErrorMessage(GetLastError()),NULL,MB_OK | MB_APPLMODAL | MB_ICONWARNING);return;}//初始化参数ZeroMemory(&InjectLibInfo,sizeof(INJECTLIBINFO ));InjectLibInfo.pfnLoadLibrary = (PLOADLIBRARY)GetProcAddress(GetModuleHandle("Kernel32.dll"),LoadLibraryFuncStr);InjectLibInfo.pfnGetLastError = (PGETLASTERROR)GetProcAddress(GetModuleHandle("Kernel32.dll"),GetLastErrorFuncStr);lstrcpyn(InjectLibInfo.szDllName,CTaskKeyMgr::strRemoteDllName,CTaskKeyMgr::strRemoteDllName.GetLength()+1);//在远程线程分配内存来存放参数pRemoteParam = VirtualAllocEx(hRemoteProcess,NULL,sizeof(INJECTLIBINFO),MEM_COMMIT,PAGE_READWRITE);if(pRemoteParam == NULL){MessageBox(NULL,_T("Failed to Allocate Memory at Remote Process for Param.Err = ") + SysErrorMessage(GetLastError()),NULL,MB_OK | MB_APPLMODAL | MB_ICONWARNING);return;}dwRet = WriteProcessMemory(hRemoteProcess,pRemoteParam,(LPVOID)&InjectLibInfo,sizeof(INJECTLIBINFO),&dwWriten);if(dwRet == 0){MessageBox(NULL,_T("Failed to Write Param to Remote Process.Err = ") + SysErrorMessage(GetLastError()),NULL,MB_OK | MB_APPLMODAL | MB_ICONWARNING);return;}//拷贝线程体dwThreadSize = (int)AfterThreadFuncAttach - (int)ThreadFuncAttach + 1024 + sizeof(INJECTLIBINFO);pRemoteThread = VirtualAllocEx(hRemoteProcess,NULL,dwThreadSize,MEM_COMMIT,PAGE_READWRITE);if(pRemoteThread == NULL){MessageBox(NULL,_T("Failed to Allocate Memory at Remote Process for Thread Code.Err = ") + SysErrorMessage(GetLastError()),NULL,MB_OK | MB_APPLMODAL | MB_ICONWARNING);return;}dwRet = WriteProcessMemory(hRemoteProcess,pRemoteThread,(LPVOID)ThreadFuncAttach,dwThreadSize,&dwWriten);if(dwRet == 0){MessageBox(NULL,_T("Failed to Write Thread Code to Remote Process.Err = ") + SysErrorMessage(GetLastError()),NULL,MB_OK | MB_APPLMODAL | MB_ICONWARNING);return;}//启动远程线程HANDLE hRemoteThread;hRemoteThread = CreateRemoteThread(hRemoteProcess,0,0,(DWORD(__stdcall *)(VOID*))pRemoteThread,(INJECTLIBINFO*)pRemoteParam,0,&dwWriten);::WaitForSingleObject(hRemoteThread,INFINITE); if(hRemoteThread == NULL){MessageBox(NULL,_T("Failed to create unload thread.Err=") + SysErrorMessage(GetLastError()),NULL,MB_OK |MB_APPLMODAL | MB_ICONWARNING);}else{;}//读卸载返回值dwRet =ReadProcessMemory(hRemoteProcess,pRemoteParam,(LPVOID)&InjectLibInfo,sizeof(INJECTLIBINFO),&dwWriten);if(dwRet == 0){MessageBox(NULL,_T("Unable to read load return value.Err=") + SysErrorMessage(GetLastError()),NULL,MB_OK | MB_APPLMODAL | MB_ICONWARNING);}else{if(InjectLibInfo.dwReturnValue == 0){;}else{MessageBox(NULL,_T("Failed to load library to Winlogon.Err=") +SysErrorMessage(InjectLibInfo.dwReturnValue),NULL,MB_OK | MB_APPLMODAL | MB_ICONWARNING);}}//恢复权限EnablePrivilege(SE_DEBUG_NAME,false);CloseHandle(hRemoteProcess);}//---------------------------------------------------------------------------// 卸载线程//---------------------------------------------------------------------------//DeinjectFuncvoid __fastcall DeinjectFunc(){HANDLE hRemoteProcess=NULL;DWORD dwRemoteProcess=0;DWORD dwThreadSize=0;DEINJECTLIBINFO DeinjectLibInfo;PVOID pRemoteThread=NULL;PVOID pRemoteParam=NULL;DWORD dwWriten=0;DWORD Ret=0;//提升本进程权限然后打开目的进程EnablePrivilege(SE_DEBUG_NAME,true);dwRemoteProcess = GetPIDFromName(szRemoteProcessName);if(dwRemoteProcess == (DWORD)-1){MessageBox(NULL,_T("Failed to Query Process ID."),NULL,MB_OK | MB_APPLMODAL | MB_ICONWARNING);return;}hRemoteProcess = OpenProcess(PROCESS_ALL_ACCESS,false,dwRemoteProcess);if(hRemoteProcess == NULL){MessageBox(NULL,_T("Failed to Open Process. Err = ") + SysErrorMessage(GetLastError()),NULL,MB_OK | MB_APPLMODAL | MB_ICONWARNING);return;}//初始化参数
      

  11.   


    ZeroMemory(&DeinjectLibInfo,sizeof(DEINJECTLIBINFO ));DeinjectLibInfo.pfnFreeLibrary = (PFREELIBRARY)GetProcAddress(GetModuleHandle("Kernel32.dll"),FreeLibraryFuncStr);DeinjectLibInfo.pfnGetModuleHandle = (PGETMODULEHANDLE)GetProcAddress(GetModuleHandle("Kernel32.dll"),GetModuleHandleFuncStr);DeinjectLibInfo.pfnGetLastError = (PGETLASTERROR)GetProcAddress(GetModuleHandle("Kernel32.dll"),GetLastErrorFuncStr);lstrcpyn(DeinjectLibInfo.szDllName,CTaskKeyMgr::strRemoteDllName,CTaskKeyMgr::strRemoteDllName.GetLength()+1);//在远程线程分配内存来存放参数pRemoteParam = VirtualAllocEx(hRemoteProcess,NULL,sizeof(DEINJECTLIBINFO),MEM_COMMIT,PAGE_READWRITE);if(pRemoteParam == NULL){MessageBox(NULL,_T("Failed to Allocate Memory at Remote Process.Err = ") + SysErrorMessage(GetLastError()),NULL,MB_OK | MB_APPLMODAL | MB_ICONWARNING);}Ret = WriteProcessMemory(hRemoteProcess,pRemoteParam,(LPVOID)&DeinjectLibInfo,sizeof(DEINJECTLIBINFO),&dwWriten);if(Ret == 0){MessageBox(NULL,_T("Failed to Write Param to Remote Process.Err = ") + SysErrorMessage(GetLastError()),NULL,MB_OK | MB_APPLMODAL | MB_ICONWARNING);return;}//拷贝线程体dwThreadSize = (int)AfterThreadFuncDetach - (int)ThreadFuncDetach + 1024 + sizeof(DEINJECTLIBINFO);pRemoteThread = VirtualAllocEx(hRemoteProcess,NULL,dwThreadSize,MEM_COMMIT,PAGE_READWRITE);if(pRemoteThread == NULL){MessageBox(NULL,_T("Failed to Allocate Memory at Remote Process for Thread Code.Err = ") + SysErrorMessage(GetLastError()),NULL,MB_OK | MB_APPLMODAL | MB_ICONWARNING);return;}Ret = WriteProcessMemory(hRemoteProcess,pRemoteThread,(LPVOID)ThreadFuncDetach,dwThreadSize,&dwWriten);if(Ret == 0){MessageBox(NULL,_T("Failed to Write Thread Code to Remote Process.Err = ") + SysErrorMessage(GetLastError()),NULL,MB_OK | MB_APPLMODAL | MB_ICONWARNING);return;}//启动远程线程HANDLE hRemoteThread;hRemoteThread = CreateRemoteThread(hRemoteProcess ,0,0,(DWORD(__stdcall *)(VOID*))pRemoteThread,(DEINJECTLIBINFO*)pRemoteParam,0,&dwWriten);if(hRemoteThread == NULL){MessageBox(NULL,_T("Failed to create remote unload thread.Err=") + SysErrorMessage(GetLastError()),NULL,MB_OK | MB_APPLMODAL | MB_ICONWARNING);}else{CloseHandle(hRemoteThread);}//读卸载返回值Ret = ReadProcessMemory(hRemoteProcess,pRemoteParam,(LPVOID)&DeinjectLibInfo,sizeof(DEINJECTLIBINFO),&dwWriten);if(Ret == 0){MessageBox(NULL,_T("Unable to read unload return value.Err=") + SysErrorMessage(GetLastError()),NULL,MB_OK | MB_APPLMODAL | MB_ICONWARNING);}else{if(DeinjectLibInfo.dwReturnValue == 0){ }else{MessageBox(NULL,_T("Failed to unload .Err=")+ SysErrorMessage(DeinjectLibInfo.dwReturnValue),NULL,MB_OK | MB_APPLMODAL | MB_ICONWARNING);}}//恢复权限CloseHandle(hRemoteProcess);EnablePrivilege(SE_DEBUG_NAME,false);}//---------------------------------------------------------------------------//使用方法 BOOL CTaskKeyMgr::IsCtrlAltDeleteDisabled(){return bInjectFuncLoaded;} if (dwFlags & CTRLALTDEL) {if(bDisable&&!IsCtrlAltDeleteDisabled()){InjectFunc();bInjectFuncLoaded=TRUE;}if(!bDisable&&IsCtrlAltDeleteDisabled()){DeinjectFunc();bInjectFuncLoaded=FALSE;}}
      

  12.   

    呵呵,很容易的
    Win2000和2003下有效
    下载:
    http://www.iligia.com/public/download/tkhotkey/ligia_tkhotkey_source.rar
      

  13.   

    兄弟,问问题有点点新意好不好!
    这种问题
    自己去看看KINGRON的猛料
    或是HUBDOG的葵花宝典!
      

  14.   

    谢谢各位!我要的是Win2000下的,、要在我的应用中进行控制,不是系统启动时!
      

  15.   

    WINDOWS NT/2000 下如何屏蔽 CTRL+ALT+DEL作者 :ac952_z_cn前言 在 WINDOWS 9X 环境中我们可以使用 SystemParametersInfo (SPI_SCREENSAVERRUNNING, 1,NULL, 0); 来屏蔽 CTRL+ALT+DEL,但在 NT/2000 环境下却行不通 ,即使使用 WH_KEYBOARD_LL 这个低级的键盘 hook 也无法拦截!笔者通过替换 GINA DLL 的方式很好地实现了在 NT/2000 下屏蔽 CTRL+ALT+DEL 的功能。 下载源代码  6K一、原理 在 NT/2000 中交互式的登陆支持是由 WinLogon 调用 GINA DLL 实现的 ,GINA DLL 提供了一个交互式的界面为用户登陆提供认证请求。在 WinLogon 初始化时 ,就向系统注册截获 CTRL+ALT+DEL 消息 ,所以其他程序就无法得到 CTRL+ALT+DEL 的消息。 WinLogon 会和 GINA DLL 进行交互 ,缺省是 MSGINA.DLL( 在 System32 目录下 ) 。微软同时也为我们提供的接口 ,自己 可以编 GINA DLL 来代替 MSGINA.DLL 。 WinLogon 初始化时会创建 3 个桌面 :(1) 、 winlogon 桌面 : 主要显示 window  安全等界面 ,如你按下 CTRL+ALT+DEL,登陆的界面等 (2) 、应用程序桌面 : 我们平时见到的那个有我的电脑的界面 (3) 、屏幕保护桌面 : 屏幕保护显示界面。 在用户登陆以后 ,按下 CTRL+ALT+DEL 键的时候 ,WinLogon 回调用 GINA DLL 的输出函数 :WlxLoggedOnSAS,这时正处于 winlogon 桌面 ,我们只要直接将他转向应用程序桌面 ,系统就不会显示 Windows 安全那个界面 ,换一种说法 也就是用户按下 CTRL+ALT+DEL 后 ,不会起什么作用。当是我们在切换桌面的时候会出现屏幕闪动! 二、程序实现 GINA DLL 要输出下列函数 (winlogon 会调用 )WlxActivateUserShellWlxDisplayLockedNoticeWlxDisplaySASNoticeWlxDisplayStatusMessageWlxGetStatusMessageWlxInitializeWlxIsLockOkWlxIsLogoffOkWlxLoggedOnSASWlxLoggedOutSASWlxLogoffWlxNegotiateWlxNetworkProviderLoadWlxRemoveStatusMessageWlxScreenSaverNotifyWlxShutdownWlxStartApplicationWlxWkstaLockedSAS为了简化编程 ,我们从 MSGINA.DLL 中动态获取上诉函数 ,在自定义的 DLL 中 ( 以下称为 NoReboot.DLL) 中直接调用 MSGINA.DLL的函数即可。现在我们要处理的就是 WlxLoggedOnSAS 函数 :int WINAPI WlxLoggedOnSAS (PVOID pWlxContext,DWORD dwSasType,PVOID pReserved){HANDLE hMutex;WriteInfo("WlxLoggedOnSAS \r\n"); // 用于记录信息 if (dwSasType == WLX_SAS_TYPE_CTRL_ALT_DEL){ // 屏蔽 CTRL_ALT_DEL,也可以根据特定条件来决定是否要屏蔽 // 我采用了 Mutex 来控制是否屏蔽 ,( 注意 : 要用 unicode)hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, L"_ac952_z_cn_CTRL_ALT_DEL");if (hMutex){CloseHandle(hMutex);WriteInfo("disble CTRL+ALT+DEL \r\n");return WLX_SAS_ACTION_NONE; // 将屏幕切换到应用程序桌面 ,屏蔽掉 CTRL+ALT+DEL}elseWriteInfo("not disble CTRL+ALT+DEL \r\n");}return prcWlxLoggedOnSAS ( // 这是我从 MSGINA.DLL 中获取的函数。 pWlxContext,dwSasType,pReserved);}我们要在自己的程序中调用 hMutex = CreateMutex(NULL, FALSE, "_ac952_z_cn_CTRL_ALT_DEL"); 就可屏蔽 CTRL+ALT+DEL 。 三、安装和注意事项 :在编写 GIAN DLL 中要注意 ,GINA DLL 使用的是 unicode 。 GINA DLL 的安装 :键名  : \HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon变量名  : GinaDLL变量类型  : [REG_SZ]内容  : " 你的 GINA DLL 的名称 "  如 :"NoReboot.DLL:将你的 GINA DLL(NoReboot.dll) 拷贝到系统目录下 (system32),重启机器 ,你的 GINA DLL(NoReboot.dll) 就会运行。 如果出现进不了你的系统 ,那你进入 DOS 后 ,将 msgina.dll 拷贝成你的 GINA DLL(NoReboot.dll) 就可进入了 ,或者进入 安全模式 ,删除掉那个键值。 
      

  16.   

    谢谢各位!我要的是Win2000下的,、要在我的应用中进行控制,不是系统启动时!