首先介紹一下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個標準函數接口:
l BOOL WINAPI WlxNegotiate(DWORD dwWinLogonVersion, PDWORD pdwDllVersion)
// Winlogon.exe調用的gina dll中的第一個函數
// 使gina dll確認是否支持當前版本的Winlogon.exe
// 傳遞給winlogon.exe需要那個版本的接口函數
l BOOL WINAPI WlxInitialize(LPWSTR lpWinsta,
HANDLE hWlx,
PVOID pvReserved,
PVOID pWinlogonFunctions,
PVOID * pWlxContext
)
// 初始化,winlogon.exe向gina dll傳遞需要版本的接口函數分配表
l BOOL WINAPI WlxActivateUserShell(PVOID pWlxContext,
PWSTR pszDesktopName,
PWSTR pszMprLogonScript,
PVOID pEnvironment)
// 用戶登陸成功后,Winlogon.exe調用該函數啟動用戶外殼程序
l VOID WINAPI WlxDisplayLockedNotice(PVOID pWlxContext)
// 當系統處于鎖定狀態時,Winlogon.exe調用該函數
// 顯示一些信息,如鎖定者、鎖定時間等
l VOID WINAPI WlxDisplaySASNotice(PVOID pWlxContext)
// 當沒有任何用戶登陸時,Winlogon.exe調用該函數顯示一些提示信息
// 可以根據用戶的動作模擬SAS事件的發送
l BOOL WINAPI WlxDisplayStatusMessage(PVOID pWlxContext,
HDESK hDesktop,
DWORD dwOptions,
PWSTR pTitle,
PWSTR pMessage)
// 當gina dll要顯示一些信息時,Winlogon.exe調用該函數
// 直接返回TRUE表示信息已經顯示
l BOOL WINAPI WlxGetStatusMessage(PVOID pWlxContext,
DWORD *pdwOptions,
PWSTR pMessage,
DWORD dwBufferSize)
// Winlogon.exe調用該函數得到gina dll顯示的狀態信息
// 直接返回TRUE表示信息已經接收
l BOOL WINAPI WlxIsLockOk(PVOID pWlxContext)
// 在試圖鎖定工作站之前Winlogon.exe調用該函數,判斷是否可以鎖定
// 直接返回FALSE表示不能鎖定
l BOOL WINAPI WlxIsLogoffOk(PVOID pWlxContext)
// 在試圖注銷時Winlogon.exe調用該函數,判斷能否注銷
// 直接返回FALSE表示不能注銷
l int WINAPI WlxLoggedOnSAS(PVOID pWlxContext,
DWORD dwSasType,
PVOID pReserved)
// 當系統處于登陸成功,沒有鎖定的狀態下
// Winlogon接收到SAS事件,于是調用該函數
// 現屏蔽所有事件,直接返回
l int WINAPI WlxLoggedOutSAS(PVOID pWlxContext,
DWORD dwSasType,
PLUID pAuthenticationId,
PSID pLogonSid,
PDWORD pdwOptions,
PHANDLE phToken,
PWLX_MPR_NOTIFY_INFO pMprNotifyInfo,
PVOID * pProfile)
// 在沒有任何一個用戶登陸的情況下,Winlogon.exe接收到SAS事件調//用該函數
l VOID WINAPI WlxLogoff(PVOID pWlxContext)
// Winlogon.exe調用該函數,通知gina dll用戶注銷操作
// 允許gina dll做出相應的處理
l BOOL WINAPI WlxNetworkProviderLoad(PVOID pWlxContext,
PWLX_MPR_NOTIFY_INFO pNprNotifyInfo)
// Winlogon.exe調用該函數收集有效的認證信息
// 返回TRUE表示用戶被識別
l BOOL WINAPI WlxRemoveStatusMessage(PVOID pWlxContext)
// Winlogon.exe調用該函數,告訴gina dll停止顯示狀態信息
// 直接返回TRUE表示信息已經刪除
l BOOL WINAPI WlxScreenSaverNotify(PVOID pWlxContext, BOOL *pSecure)
// 在屏保程序啟動前一瞬Winlogon.exe調用該函數,允許gina dll同屏
//保程序交互
// 返回FALSE表示屏保程序不能啟動
l VOID WINAPI WlxShutdown(PVOID pWlxContext, DWORD ShutdownType)
// 在系統關閉之前,Winlogon.exe調用該函數
// 允許gina dll處理一些系統關閉前的處理
l BOOL WINAPI WlxStartApplication(PVOID pWlxContext,
PWSTR pszDesktopName,
PVOID pEnvironment,
PWSTR pszCmdLine)
// 當系統要求在用戶上下文中啟動程序,Winlogon.exe調用該函數
// 這種情況發生在:瀏覽器非正常關閉需要重啟或需要啟動擴展的任務// 管理器
// 該接口gina dll可以選擇性實現
l int WINAPI WlxWkstaLockedSAS(PVOID pWlxContext, DWORD dwSasType)
// 在鎖定狀態下,Winlogon.exe接收到SAS事件調用該函數
其中WlxNegotiate是winlogon.exe調用的第一個接口函數,進行必要的版本判斷,隨后調用的是WlxInitialize,主要完成 winlogon.exe特定版本的函數分派表向Gina Dll的傳遞。最主要的是WlxLoggedOnSAS函數,這個函數主要的功能是,當winlogon在登錄成功狀態下,接收到SAS事件,于是調用這 個函數進行SAS事件的識別以及進行各事件的相應處理。
由于現在只需屏蔽按下Ctrl+Alt+Del時系統不再彈出“Widows安全”對話框。并不需要改變用戶名、密碼這種標準的認證模式,所以可以仍然使用msgina.dll中導出的函數接口,而對WlxLoggedOnSAS函數的實現進行必要的改變。
int WINAPI WlxLoggedOnSAS(PVOID pWlxContext,
DWORD dwSasType,
PVOID pReserved)
{
if(bLock) //如果處于鎖定狀態,現屏蔽所有事件,直接返回
return WLX_SAS_ACTION_NONE;
else
return theApp.MyWlxLoggedOnSAS(pWlxContext, dwSasType, pReserved);
//MyWlxLoggedOnSAS為默認gina dll(msgina dll)中的WlxLoggedOnSAS
}
自定義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即投入使用。