返回列表 发帖

[转帖]Win2K/NT下屏蔽Ctrl+Alt+Del的响应

Win2K/NT下屏蔽Ctrl+Alt+Del的响应 作者:陆其明 Email:luqiming@263.net 大家知道,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 。 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中定义导出。  

返回列表 回复 发帖