首先介紹一下Winlogon。Windows 2000/NT有三種系統(tǒng)狀態(tài):沒有用戶登錄狀態(tài)、用戶成功登錄狀態(tài)以及工作站鎖定狀態(tài)。Winlogon是Windows 2000/NT操作系統(tǒng)提供交互式登錄支持的組件。Winlogon有三個(gè)組成部分:可執(zhí)行文件winlogon.exe,提供圖形界面認(rèn)證功能的動(dòng)態(tài)庫 Gina Dll,以及一些網(wǎng)絡(luò)服務(wù)提供動(dòng)態(tài)庫Network Provider Dll。
??
winlogon.exe處理一些下層導(dǎo)出的接口函數(shù),而認(rèn)證策略是在Gina Dll中是獨(dú)立設(shè) 計(jì)的。在系統(tǒng)啟動(dòng)時(shí),Gina Dll被winlogon.exe裝載。Microsoft提供了一個(gè)默認(rèn)的Gina Dll——Winnt\system32\msgina.dll,提供了標(biāo)準(zhǔn)的用戶名、密碼認(rèn)證模式。Gina Dll是可替換的,用戶可以設(shè)計(jì)自己的Gina Dll,以提供其他如智能卡、視網(wǎng)膜、指紋或其他一些認(rèn)證機(jī)制。
開發(fā)自定義的Gina Dll。必須實(shí)現(xiàn)并導(dǎo)出與winlogon.exe交互的18個(gè)標(biāo)準(zhǔn)函數(shù)接口:
l BOOL WINAPI WlxNegotiate(DWORD dwWinLogonVersion, PDWORD pdwDllVersion)
// Winlogon.exe調(diào)用的gina dll中的第一個(gè)函數(shù)
// 使gina dll確認(rèn)是否支持當(dāng)前版本的Winlogon.exe
// 傳遞給winlogon.exe需要那個(gè)版本的接口函數(shù)
l BOOL WINAPI WlxInitialize(LPWSTR lpWinsta,
HANDLE hWlx,
PVOID pvReserved,
PVOID pWinlogonFunctions,
PVOID * pWlxContext
)
// 初始化,winlogon.exe向gina dll傳遞需要版本的接口函數(shù)分配表
l BOOL WINAPI WlxActivateUserShell(PVOID pWlxContext,
PWSTR pszDesktopName,
PWSTR pszMprLogonScript,
PVOID pEnvironment)
// 用戶登陸成功后,Winlogon.exe調(diào)用該函數(shù)啟動(dòng)用戶外殼程序
l VOID WINAPI WlxDisplayLockedNotice(PVOID pWlxContext)
// 當(dāng)系統(tǒng)處于鎖定狀態(tài)時(shí),Winlogon.exe調(diào)用該函數(shù)
// 顯示一些信息,如鎖定者、鎖定時(shí)間等
l VOID WINAPI WlxDisplaySASNotice(PVOID pWlxContext)
// 當(dāng)沒有任何用戶登陸時(shí),Winlogon.exe調(diào)用該函數(shù)顯示一些提示信息
// 可以根據(jù)用戶的動(dòng)作模擬SAS事件的發(fā)送
l BOOL WINAPI WlxDisplayStatusMessage(PVOID pWlxContext,
HDESK hDesktop,
DWORD dwOptions,
PWSTR pTitle,
PWSTR pMessage)
// 當(dāng)gina dll要顯示一些信息時(shí),Winlogon.exe調(diào)用該函數(shù)
// 直接返回TRUE表示信息已經(jīng)顯示
l BOOL WINAPI WlxGetStatusMessage(PVOID pWlxContext,
DWORD *pdwOptions,
PWSTR pMessage,
DWORD dwBufferSize)
// Winlogon.exe調(diào)用該函數(shù)得到gina dll顯示的狀態(tài)信息
// 直接返回TRUE表示信息已經(jīng)接收
l BOOL WINAPI WlxIsLockOk(PVOID pWlxContext)
// 在試圖鎖定工作站之前Winlogon.exe調(diào)用該函數(shù),判斷是否可以鎖定
// 直接返回FALSE表示不能鎖定
l BOOL WINAPI WlxIsLogoffOk(PVOID pWlxContext)
// 在試圖注銷時(shí)Winlogon.exe調(diào)用該函數(shù),判斷能否注銷
// 直接返回FALSE表示不能注銷
l int WINAPI WlxLoggedOnSAS(PVOID pWlxContext,
DWORD dwSasType,
PVOID pReserved)
// 當(dāng)系統(tǒng)處于登陸成功,沒有鎖定的狀態(tài)下
// Winlogon接收到SAS事件,于是調(diào)用該函數(shù)
// 現(xiàn)屏蔽所有事件,直接返回
l int WINAPI WlxLoggedOutSAS(PVOID pWlxContext,
DWORD dwSasType,
PLUID pAuthenticationId,
PSID pLogonSid,
PDWORD pdwOptions,
PHANDLE phToken,
PWLX_MPR_NOTIFY_INFO pMprNotifyInfo,
PVOID * pProfile)
// 在沒有任何一個(gè)用戶登陸的情況下,Winlogon.exe接收到SAS事件調(diào)//用該函數(shù)
l VOID WINAPI WlxLogoff(PVOID pWlxContext)
// Winlogon.exe調(diào)用該函數(shù),通知gina dll用戶注銷操作
// 允許gina dll做出相應(yīng)的處理
l BOOL WINAPI WlxNetworkProviderLoad(PVOID pWlxContext,
PWLX_MPR_NOTIFY_INFO pNprNotifyInfo)
// Winlogon.exe調(diào)用該函數(shù)收集有效的認(rèn)證信息
// 返回TRUE表示用戶被識(shí)別
l BOOL WINAPI WlxRemoveStatusMessage(PVOID pWlxContext)
// Winlogon.exe調(diào)用該函數(shù),告訴gina dll停止顯示狀態(tài)信息
// 直接返回TRUE表示信息已經(jīng)刪除
l BOOL WINAPI WlxScreenSaverNotify(PVOID pWlxContext, BOOL *pSecure)
// 在屏保程序啟動(dòng)前一瞬Winlogon.exe調(diào)用該函數(shù),允許gina dll同屏
//保程序交互
// 返回FALSE表示屏保程序不能啟動(dòng)
l VOID WINAPI WlxShutdown(PVOID pWlxContext, DWORD ShutdownType)
// 在系統(tǒng)關(guān)閉之前,Winlogon.exe調(diào)用該函數(shù)
// 允許gina dll處理一些系統(tǒng)關(guān)閉前的處理
l BOOL WINAPI WlxStartApplication(PVOID pWlxContext,
PWSTR pszDesktopName,
PVOID pEnvironment,
PWSTR pszCmdLine)
// 當(dāng)系統(tǒng)要求在用戶上下文中啟動(dòng)程序,Winlogon.exe調(diào)用該函數(shù)
// 這種情況發(fā)生在:瀏覽器非正常關(guān)閉需要重啟或需要啟動(dòng)擴(kuò)展的任務(wù)// 管理器
// 該接口gina dll可以選擇性實(shí)現(xiàn)
l int WINAPI WlxWkstaLockedSAS(PVOID pWlxContext, DWORD dwSasType)
// 在鎖定狀態(tài)下,Winlogon.exe接收到SAS事件調(diào)用該函數(shù)
其中WlxNegotiate是winlogon.exe調(diào)用的第一個(gè)接口函數(shù),進(jìn)行必要的版本判斷,隨后調(diào)用的是WlxInitialize,主要完成 winlogon.exe特定版本的函數(shù)分派表向Gina Dll的傳遞。最主要的是WlxLoggedOnSAS函數(shù),這個(gè)函數(shù)主要的功能是,當(dāng)winlogon在登錄成功狀態(tài)下,接收到SAS事件,于是調(diào)用這 個(gè)函數(shù)進(jìn)行SAS事件的識(shí)別以及進(jìn)行各事件的相應(yīng)處理。
由于現(xiàn)在只需屏蔽按下Ctrl+Alt+Del時(shí)系統(tǒng)不再彈出“Widows安全”對(duì)話框。并不需要改變用戶名、密碼這種標(biāo)準(zhǔn)的認(rèn)證模式,所以可以仍然使用msgina.dll中導(dǎo)出的函數(shù)接口,而對(duì)WlxLoggedOnSAS函數(shù)的實(shí)現(xiàn)進(jìn)行必要的改變。
int WINAPI WlxLoggedOnSAS(PVOID pWlxContext,
DWORD dwSasType,
PVOID pReserved)
{
if(bLock) //如果處于鎖定狀態(tài),現(xiàn)屏蔽所有事件,直接返回
return WLX_SAS_ACTION_NONE;
else
return theApp.MyWlxLoggedOnSAS(pWlxContext, dwSasType, pReserved);
//MyWlxLoggedOnSAS為默認(rèn)gina dll(msgina dll)中的WlxLoggedOnSAS
}
自定義Gina Dll的使用。比如開發(fā)的Gina Dll文件名為MyGina.dll。將該文件放到以下路徑:Winnt\system32。并修改注冊(cè)表,如下:
Key Name: \HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\ Winlogon
Value Name: GinaDLL
Value Type: [REG_SZ]
Value: MyGina.dll
重新啟動(dòng)計(jì)算機(jī)MyGina.dll即投入使用。