Windows開機登入認證與Gina DLL

來源:互聯網
上載者:User

Windows的開機密碼認證模組一般是由Gina DLL完成的。在NT/2000中互動登陸支援是由WinLogon調用GINA DLL實現的,GINA DLL提供了一個互動介面為使用者登陸提供認證請求。

1.Gina原理
WinLogon會和GINA DLL進行互動,預設是MSGINA.DLL(在System32目錄下)。微軟同時也為我們提供了介面,我們可以自己編寫GINA DLL來代替MSGINA.DLL。

WinLogon初始化時會建立3個案頭:
(1) winlogon案頭:主要顯示Windows 安全等介面,如你按下CTRL+ALT+DEL,登陸的介面等
(2) 應用程式案頭:我們平時見到的那個有我的電腦的介面
(3) 螢幕保護裝置案頭:螢幕保護裝置顯示介面。

在預設情況下,GINA顯示登陸對話方塊,使用者輸入使用者名稱及密碼 。所以要獲得使用者名稱和密碼 ,則可以寫一個新的GINA DLL,其中提供介面調用msgina.dll的函數WlxLoggedOutSAS。

2.Gina DLL匯出函數

在NT/2000 中互動登陸支援是由WinLogon調用GINA DLL實現的,GINA DLL提供了一個互動介面為使用者登陸提供認證請求。GINA DLL要輸出下列函數(Winlogon會調用):

(1) WlxActivateUserShell:啟用使用者外殼程式。
(2) WlxDisplayLockedNotice:允許GINA DLL顯示鎖定資訊。
(3) WlxDisplaySASNotice:當沒有使用者登陸時,Winlogon調用此函數。
(4) WlxDisplayStatusMessage:Winlogon用一個狀態資訊調用此函數進行顯示。
(5) WlxGetStatusMessage:Winlogon 調用此函數擷取目前狀態資訊。
(6) WlxInitialize:針對指定的視窗位置進行GINA DLL初始化。
(7) WlxIsLockOk:驗證工作站正常鎖定。
(8) WlxIslogoffOk:驗證登出正常。
(9) WlxLoggedOnSAS:使用者已登陸並且工作站沒有被加鎖,如果此時接收到SAS事件,則Winlogon 調用此函數。
(10) WlxLoggedOutSAS:沒有使用者登陸,如果此時收到SAS事件,則Winlogon調用此函數。
(11) WlxLogoff:請求登出操作時通知GINA DLL。
(12) WlxNegotiate:表示當前的Winlogon版本是否能使用GINA DLL。
(13) WlxNetworkProviderLoad:在載入網路服務提供者收集了身份和認證資訊後,Winlogon 調用此函數。
(14) WlxRemoveStatusMessage:Winlogon調用此函數告訴GINA DLL停止顯示狀態資訊。
(15) WlxScreensaverNotify:允許GINA與螢幕保護裝置操作互動。
(16) WlxShutdown:在關閉之前Winlogon 調用此函數,允許GINA實現任何關閉任務,例如從讀卡機中退出智慧卡。
(17) WlxStartApplication:當系統需要在使用者的上下文中啟動應用程式時調用此函數。
(18) WlxWkstaLockedSAS:當工作站被鎖定,如果接收到一個SAS,則Winlogon調用此函數。
我們通過對上述的18個基本函數進行重寫,來實現USB身份認證系統的Windows登入身份認證。

3. Gina DLL原型代碼

// USBGina.cpp : 定義 DLL 應用程式的匯出函數。//#include "stdafx.h"#define REALGINA_PATH      TEXT("MSGINA.DLL")// Winlogon函數分配表PWLX_DISPATCH_VERSION_1_0 g_pWinlogon;// DLL地址HINSTANCE hDllInstance;// Winlogon的控制代碼HANDLE hGlobalWlx;// WLX_VERSION_1_0PFWLXNEGOTIATE                pfWlxNegotiate;PFWLXINITIALIZE               pfWlxInitialize;PFWLXDISPLAYSASNOTICE         pfWlxDisplaySASNotice;PFWLXLOGGEDOUTSAS             pfWlxLoggedOutSAS;PFWLXACTIVATEUSERSHELL        pfWlxActivateUserShell;PFWLXLOGGEDONSAS              pfWlxLoggedOnSAS;PFWLXDISPLAYLOCKEDNOTICE      pfWlxDisplayLockedNotice;PFWLXWKSTALOCKEDSAS           pfWlxWkstaLockedSAS;PFWLXISLOCKOK                 pfWlxIsLockOk;PFWLXISLOGOFFOK               pfWlxIsLogoffOk;PFWLXLOGOFF                   pfWlxLogoff;PFWLXSHUTDOWN                 pfWlxShutdown;// WLX_VERSION_1_1PFWLXSTARTAPPLICATION         pfWlxStartApplication  = NULL;PFWLXSCREENSAVERNOTIFY        pfWlxScreenSaverNotify = NULL;// WLX_VERSION_1_3PFWLXNETWORKPROVIDERLOAD      pfWlxNetworkProviderLoad  = NULL;PFWLXDISPLAYSTATUSMESSAGE     pfWlxDisplayStatusMessage = NULL;PFWLXGETSTATUSMESSAGE         pfWlxGetStatusMessage     = NULL;PFWLXREMOVESTATUSMESSAGE      pfWlxRemoveStatusMessage  = NULL;// DLL應用程式進入點BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved){    switch (ul_reason_for_call)    {        case DLL_PROCESS_ATTACH:            hDllInstance = hModule;        case DLL_THREAD_ATTACH:        case DLL_THREAD_DETACH:        case DLL_PROCESS_DETACH:            break;    }    return TRUE;}// 系統初始化,在WlxNegotiate中被調用BOOL MyInitialize(HINSTANCE hDll, DWORD dwWlxVersion){    // 系統初始化,從msgina.dll中HOOK WLX_VERSION_1_0中的函數    pfWlxNegotiate = (PFWLXNEGOTIATE) GetProcAddress(hDll, "WlxNegotiate");    if (!pfWlxNegotiate)    {        return FALSE;    }    pfWlxInitialize = (PFWLXINITIALIZE) GetProcAddress(hDll, "WlxInitialize");    if (!pfWlxInitialize)    {        return FALSE;    }    pfWlxDisplaySASNotice = (PFWLXDISPLAYSASNOTICE) GetProcAddress(hDll,        "WlxDisplaySASNotice");    if (!pfWlxDisplaySASNotice)    {        return FALSE;    }    pfWlxLoggedOutSAS = (PFWLXLOGGEDOUTSAS) GetProcAddress(hDll,        "WlxLoggedOutSAS");    if (!pfWlxLoggedOutSAS)    {        return FALSE;    }    pfWlxActivateUserShell = (PFWLXACTIVATEUSERSHELL) GetProcAddress(hDll,        "WlxActivateUserShell");    if (!pfWlxActivateUserShell)    {        return FALSE;    }    pfWlxLoggedOnSAS = (PFWLXLOGGEDONSAS) GetProcAddress(hDll, "WlxLoggedOnSAS");    if (!pfWlxLoggedOnSAS)    {        return FALSE;    }    pfWlxDisplayLockedNotice = (PFWLXDISPLAYLOCKEDNOTICE) GetProcAddress(hDll,        "WlxDisplayLockedNotice");    if (!pfWlxDisplayLockedNotice)    {        return FALSE;    }    pfWlxIsLockOk = (PFWLXISLOCKOK) GetProcAddress(hDll, "WlxIsLockOk");    if (!pfWlxIsLockOk)    {        return FALSE;    }    pfWlxWkstaLockedSAS = (PFWLXWKSTALOCKEDSAS) GetProcAddress(hDll,        "WlxWkstaLockedSAS");    if (!pfWlxWkstaLockedSAS)    {        return FALSE;    }    pfWlxIsLogoffOk = (PFWLXISLOGOFFOK) GetProcAddress(hDll, "WlxIsLogoffOk");    if (!pfWlxIsLogoffOk)    {        return FALSE;    }    pfWlxLogoff = (PFWLXLOGOFF) GetProcAddress(hDll, "WlxLogoff");    if (!pfWlxLogoff)    {        return FALSE;    }    pfWlxShutdown = (PFWLXSHUTDOWN) GetProcAddress(hDll, "WlxShutdown");    if (!pfWlxShutdown)    {        return FALSE;    }    // HOOK WLX_VERSION_1_1版本的新函數。    if (dwWlxVersion > WLX_VERSION_1_0)    {        pfWlxStartApplication = (PFWLXSTARTAPPLICATION) GetProcAddress(hDll,            "WlxStartApplication");        if (!pfWlxStartApplication)        {            return FALSE;        }        pfWlxScreenSaverNotify = (PFWLXSCREENSAVERNOTIFY) GetProcAddress(hDll,            "WlxScreenSaverNotify");        if (!pfWlxScreenSaverNotify)        {            return FALSE;        }    }    // HOOK WLX_VERSION_1_3版本的新函數    if (dwWlxVersion > WLX_VERSION_1_2)    {        pfWlxNetworkProviderLoad = (PFWLXNETWORKPROVIDERLOAD) GetProcAddress(hDll,            "WlxNetworkProviderLoad");        if (!pfWlxNetworkProviderLoad)        {            return FALSE;        }        pfWlxDisplayStatusMessage = (PFWLXDISPLAYSTATUSMESSAGE) GetProcAddress(hDll,            "WlxDisplayStatusMessage");        if (!pfWlxDisplayStatusMessage)        {            return FALSE;        }        pfWlxGetStatusMessage = (PFWLXGETSTATUSMESSAGE) GetProcAddress(hDll,            "WlxGetStatusMessage");        if (!pfWlxGetStatusMessage)        {            return FALSE;        }        pfWlxRemoveStatusMessage = (PFWLXREMOVESTATUSMESSAGE) GetProcAddress(hDll,            "WlxRemoveStatusMessage");        if (!pfWlxRemoveStatusMessage)        {            return FALSE;        }    }    // HOOK新版本的函數    // 所有的HOOK都成功    return TRUE;}BOOL WINAPI WlxNegotiate(DWORD dwWinlogonVersion, DWORD * pdwDllVersion){    HINSTANCE hDll = NULL;    if (!(hDll = LoadLibrary(REALGINA_PATH)))    {        return FALSE;    }    if(MyInitialize(hDll, dwWinlogonVersion) == TRUE)    {        return pfWlxNegotiate(dwWinlogonVersion, pdwDllVersion);    }    return FALSE;}BOOL WINAPI WlxInitialize(LPWSTR  lpWinsta, HANDLE  hWlx, PVOID   pvReserved,    PVOID   pWinlogonFunctions, PVOID * pWlxContext){    g_pWinlogon = (PWLX_DISPATCH_VERSION_1_0) pWinlogonFunctions;    hGlobalWlx = hWlx;    return pfWlxInitialize(lpWinsta, hWlx, pvReserved, pWinlogonFunctions, pWlxContext);}void WINAPI WlxDisplaySASNotice(PVOID pWlxContext){    pfWlxDisplaySASNotice(pWlxContext);    g_pWinlogon->WlxDialogBoxParam(hGlobalWlx, hDllInstance, (LPTSTR)        MAKEINTRESOURCE(IDD_LOGON_DLG), NULL, LogonDlgProc, 0);}int WINAPI WlxLoggedOutSAS(PVOID pWlxContext, DWORD dwSasType,    PLUID pAuthenticationId, PSID pLogonSid, PDWORD pdwOptions,    PHANDLE phToken, PWLX_MPR_NOTIFY_INFO pMprNotifyInfo, PVOID * pProfile){    // 用標準Windows的密碼方式登入    return pfWlxLoggedOutSAS(pWlxContext, dwSasType, pAuthenticationId, pLogonSid,        pdwOptions, phToken, pMprNotifyInfo, pProfile);}BOOL WINAPI WlxActivateUserShell (PVOID pWlxContext, PWSTR pszDesktopName,    PWSTR pszMprLogonScript, PVOID pEnvironment){    // 用標準Windows的密碼方式登入,調用MSGINA.DLL中的函數    return pfWlxActivateUserShell(pWlxContext, pszDesktopName, pszMprLogonScript,        pEnvironment);}int WINAPI WlxLoggedOnSAS (PVOID pWlxContext, DWORD dwSasType, PVOID pReserved){    return pfWlxLoggedOnSAS(pWlxContext, dwSasType, pReserved);}void WINAPI WlxDisplayLockedNotice(PVOID pWlxContext){    pfWlxDisplayLockedNotice(pWlxContext);    wcscpy(account.strUsername, TEXT(""));    wcscpy(account.strPassword, TEXT(""));    account.bLogonStatus = FALSE;    g_pWinlogon->WlxDialogBoxParam(hGlobalWlx, hDllInstance, (LPTSTR)        MAKEINTRESOURCE(IDD_LOGON_DLG), NULL, LogonDlgProc, 0);}BOOL WINAPI WlxIsLockOk(PVOID pWlxContext){    return pfWlxIsLockOk(pWlxContext);}int WINAPI WlxWkstaLockedSAS(PVOID pWlxContext, DWORD dwSasType){    return pfWlxWkstaLockedSAS(pWlxContext, dwSasType);}BOOL WINAPI WlxIsLogoffOk(PVOID pWlxContext){    return pfWlxIsLogoffOk(pWlxContext);}void WINAPI WlxLogoff(PVOID pWlxContext){    pfWlxLogoff(pWlxContext);}void WINAPI WlxShutdown(PVOID pWlxContext, DWORD ShutdownType){    pfWlxShutdown(pWlxContext, ShutdownType);}// WLX_VERSION_1_1版BOOL WINAPI WlxScreenSaverNotify(PVOID pWlxContext, BOOL * pSecure){    return pfWlxScreenSaverNotify(pWlxContext, pSecure);}BOOL WINAPI WlxStartApplication(PVOID pWlxContext, PWSTR pszDesktopName,    PVOID pEnvironment, PWSTR pszCmdLine){    return pfWlxStartApplication(pWlxContext, pszDesktopName, pEnvironment, pszCmdLine);}// WLX_VERSION_1_3版BOOL WINAPI WlxNetworkProviderLoad(PVOID pWlxContext, PWLX_MPR_NOTIFY_INFO    pNprNotifyInfo){    return pfWlxNetworkProviderLoad(pWlxContext, pNprNotifyInfo);}BOOL WINAPI WlxDisplayStatusMessage (PVOID pWlxContext, HDESK hDesktop,    DWORD dwOptions, PWSTR pTitle, PWSTR pMessage){    return pfWlxDisplayStatusMessage(pWlxContext, hDesktop, dwOptions, pTitle, pMessage);}BOOL WINAPI WlxGetStatusMessage(PVOID pWlxContext, DWORD * pdwOptions,    PWSTR pMessage, DWORD dwBufferSize){    return pfWlxGetStatusMessage(pWlxContext, pdwOptions, pMessage, dwBufferSize);}BOOL WINAPI WlxRemoveStatusMessage(PVOID pWlxContext){    return pfWlxRemoveStatusMessage(pWlxContext);}

4. Gina DLL安裝

(1) 添加註冊表

(2) 鍵名:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\

(3) CurrentVersion\Winlogon\

(4) 變數名:GinaDLL

(5) 變數類型:[REG_SZ]

(6) 內容:Yourname.dll

(7) 將Gina DLL(Yourname.dll)拷貝到系統目錄下(system32)。

(8) 重新啟動電腦, Gina DLL(Yourname.dll)就會運行。

5. 結語

以上,Gina DLL就完成,重啟之後就可以看到,儘管這個原型調用的是Windows的msgina.dll裡面的函數,但是事實上所有的函數已經被我們Hook了,在調用系統函數之前必然會經過我們的函數。以下是與本主題相關資訊:

(1)可以通過WlxLoggedOnSAS來屏蔽Windows作業系統下的Ctrl+Alt+Del。

(2)可以在WlxLoggedOutSAS中截獲使用者登入的使用者名稱以及密碼。

(3)通過此原型,可以實現一些個人化的開機認證,包括用指紋(例如ThinkPad膝上型電腦),以及特定的USB才能登入等等。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.