** 关键词 ** ** **
Windows2000, VC++, C++Bulider, Visual Basic, HOOK, DLL
** 引言 ** ** **
在一些应用场合,比如基于 Windows2000 (以下简称 Win2K )下开发工控软件需要,为了增强系统安全性,需要对键盘事件进行监控、屏蔽。满足控制系统安全性要求。作为一个 Win2K 后台监控软件的编写,需要注意如下要点: HOOK( 键盘挂钩函数 ) , DLL , MsgINA.dll , Shell_NotifyIcon (托盘函数)。为了提高软件编写效率,可以采用混合编程方式,即采用 VC++/ C++Bulider 6.0 编写 DLL 文件 , 采用 Visual Basic 编写客户端程序。
** 1 ** ** HOOK ** ** 与 ** ** DLL ** ** 简介 ** ** **
** 1) ** ** HOOK **
HOOK 是一种反调函数。是 Windows 系统为应用程序提供用于监控系统各种事件消息的类中断程序。在系统消息机制里挂上用户自定义消息处理钩子( HOOK ),达到对消息的过滤。 Windows 系统本身提供数个 HOOK 函数,为实现在 Win2K/NT 平台下的键盘屏蔽,要采用低级键盘 HOOK, 即 WH_KEYBOARD_LL 。此 HOOK 函数可以屏蔽 Ctrl+Esc 、 Alt+Tab 、和 Alt+Esc 等系统功能键,在 WINNT SP3 后的操作系统中都是支持的。设置 HOOK 需要用到 SetWindowsHookEx () 函数,在程序退出后,必须用 UnhookWindowsHookEx () 函数卸载掉 HOOK 。
** 2) ** ** DLL ** ** 与 ** ** Msgina.dll **
DLL( 动态链结库 ) 是 Microsoft Windows 最重要组成之一。大多数与 Windows 相关程序,不是程式模块组模式,就是 动态链结库 模式。为实现对所有键盘事件的监控,必须将 HOOK函数放在DLL文件中。
Windows 本身就是由许多的 DLL 组成的,它所有的库模块也都设计成 DLL 。在 Win2K 在,为了屏蔽 Ctrl + Alt + Del 组合键,必须了解 Msgina.dll 。在 Win2K 系统中,微软采用 Winlogon 和 GINA-Graphical Identification and Authentication 提供交互式登录支持。登录成功后,按下 Ctrl + Alt + Del 组合键,系统将通过 Winlogon 调用 Msgina.dll 内部函数 WlxLoggedOnSAS 。所以要屏蔽 Ctrl + Alt + Del 组合键,则可以写一个新的 GINA.dll ,其中提供接口调用 Msgina.dll, 从而实现屏蔽。
** 3) ** ** Shell_NotifyIcon ** ** **
客户端程序应该运行在后台,所以可以将其最小化在系统托盘中。采用 Shell_NotifyIcon API 函数用来添加、删除、更改系统托盘区 (taskbar status area) 的图标。
** 2 ** ** 程序实现 ** ** **
在本文中,采用 VC++6. 开发系统 GINA DLL, C++Bulider 6.0 开发低层 HOOK DLL,VB6.0 开发客户端程序,实现混合编程。
** 1) ** ** 自定义 ** ** GINA ** ** 编写 ** ** **
因为自定义 GINA 编写资料较多,本文只简要介绍。自定义 GINA 可以采用 VC++6.0 开发。下面给出 Windows2000 的 Msgina 内部函数表。表中函数将在自定义 GINA 中导入。
函数名
|
说明
---|---
WlxActivateUserShell
|
激活用户外壳程序
WlxDisPlayLockedNotice
|
允许 GINA dll 显示锁定信息
WlxDisPlaySASNotice
|
当没有用户登录时, winlogon 调用此函数
WlxDisPlayStatusMessage
|
Winlogon 用一个状态信息调用此函数进行显示
WlxGetConsoleSwitchCredentials
|
Winlogon 调用此函数读取当前登录用户的信任信息,并透明的将它们传到目标会话
WlxGetStatusMessage
|
Winlogon 调用此函数获取当前状态信息
WlxIntialize
|
针对指定的窗口位置进行 GINA dll 初始化
WlxIsLockOk
|
验证工作站正常锁定
WlxIslogoffOk
|
验证注销正常
WlxLoggedOnSAS
|
用户已登录并且工作站没有被加锁,若此时接收到 SAS 事件,则 Winlogon 调用此函数
WlxLoggedOutSAS
|
没有用户登录,若此时接收到 SAS 事件,则 Winlogon 调用此函数
WlxLogoff
|
请求注销操作时通知 GINA dll
WlxNegotiate
|
表示当前的 winlogon 版本是否能使用 GINA dll
WlxNetworkProviderLoad
|
在加载网络服务提供程序收集了身份和认证信息后, Winlogon 调用此函数
WlxRemoveStatusMessage
|
Winlogon 调用此函数告诉 GINA dll 停止显示状态信息
WlxScreensaverNotify
|
允许 GINA 与屏幕保护操作交互
WlxShutdown
|
在关闭之前 Winlogon 调用此函数 , 允许 GINA 实现任何关闭任务,例如从读卡器中退出智能卡
WlxStartApplication
|
当系统需要在用户的上下文中启动应用程序时调用此函数
WlxWkstalockedSAS
|
当工作站被锁定,如果接收到一个 SAS ,则 Winlogon 调用此函数
我们需要注意的是 WlxLoggedOnSAS 函数。屏蔽 Ctrl + Alt + Del 组合键代码将在调用该函数时添加。我们采用读取注册表键值来判断是否屏蔽,而该键值将在客户端程序中被操作。
// 当系统处于登陆成功,没有锁定的状态下
// Winlogon 接收到 SAS 事件,于是调用该函数
int WINAPI WlxLoggedOnSAS(PVOID pWlxContext, DWORD dwSasType, PVOID pReserved)
{
HKEY hKey;
DWORD dwType=REG_DWORD; // 定义读取数据类型:双字节
char content[4]; // 所查询注册表键值的内容
DWORD dwLength=4;
// 打开注册表键
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\FCSKBLock\\KBConfig",
0,KEY_READ,&hKey)
==ERROR_SUCCESS)
{ // 读取 CtrlAltDel 键值
if(RegQueryValueEx(hKey,"CtrlAltDel",NULL,&dwType,(unsigned char *)content,&dwLength)
==ERROR_SUCCESS)
{
if(* content==1)
return WLX_SAS_ACTION_NONE; // 直接返回桌面程序,实现屏蔽
}
}
return theApp.MyWlxLoggedOnSAS(pWlxContext,dwSasType,pReserved ) ;
}
开发完成的自定义 GINA.dll 要放到 Wint\system32 文件夹中。并修改注册表:
<span style="FONT-SIZE: 10